Creating a grid of electrodes

This example shows how to use ElectrodeGrid.

Most current electrode arrays arrange their electrodes in a 2D grid.

Creating a rectangular grid

To create a rectangular grid, we need to specify:

  • The shape of the grid, passed as a tuple containing the desired number of rows and columns
  • The electrode-to-electrode spacing in microns
  • The (x, y) location of the center of the array
  • The rotation angle rot of the grid in degrees, where positive angles rotate all electrodes in the array in a counter-clockwise fashion on the retinal surface.

We can also specify:

  • A naming convention names for the rows and columns in the grid. For example, to label rows alphabetically and columns numerically, we would pass a tuple ('A', '1'). To label both alphabetically, we would pass ('A', 'A').
  • An electrode type etype, which must be a subclass of Electrode. By default, PointSource is chosen.
  • Any additional parameters that should be passed to the Electrode constructor, such as a radius r for DiskElectrode.

Let’s say we want to create a 2x3 rectangular grid of PointSource objects, each electrode spaced 500 microns apart, and the whole grid should be centered over the fovea:

from pulse2percept.models import AxonMapModel
from numpy import pi
from pulse2percept.implants import DiskElectrode
from pulse2percept.implants import ElectrodeGrid

grid = ElectrodeGrid((2, 3), 500)

We can access individual electrodes by indexing into grid:

The first electrode:

grid[0]

Out:

PointSource(activated=True, name='A1', x=-500.0, y=-250.0,
            z=0.0)

The first electrode by name:

grid['A1']

Out:

PointSource(activated=True, name='A1', x=-500.0, y=-250.0,
            z=0.0)

Accessing the x-coordinate of the first electrode:

grid[0].x

Out:

-500.0

Showing all electrodes:

grid[:]

Out:

[PointSource(activated=True, name='A1', x=-500.0, y=-250.0,
            z=0.0), PointSource(activated=True, name='A2', x=0.0, y=-250.0,
            z=0.0), PointSource(activated=True, name='A3', x=500.0, y=-250.0,
            z=0.0), PointSource(activated=True, name='B1', x=-500.0, y=250.0,
            z=0.0), PointSource(activated=True, name='B2', x=0.0, y=250.0,
            z=0.0), PointSource(activated=True, name='B3', x=500.0, y=250.0,
            z=0.0)]

We can iterate over all electrodes as if we were dealing with a dictionary:

Out:

A1 PointSource(activated=True, name='A1', x=-500.0, y=-250.0,
            z=0.0)
A2 PointSource(activated=True, name='A2', x=0.0, y=-250.0,
            z=0.0)
A3 PointSource(activated=True, name='A3', x=500.0, y=-250.0,
            z=0.0)
B1 PointSource(activated=True, name='B1', x=-500.0, y=250.0,
            z=0.0)
B2 PointSource(activated=True, name='B2', x=0.0, y=250.0,
            z=0.0)
B3 PointSource(activated=True, name='B3', x=500.0, y=250.0,
            z=0.0)

To make a grid of DiskElectrode objects, we need to explicitly specify the electrode type (etype) and the radius to use (r):

# 11x13 grid, 100-um disk electrodes spaced 500um apart:
disk_grid = ElectrodeGrid((11, 13), 500, etype=DiskElectrode, r=100)

disk_grid[:]

Out:

[DiskElectrode(activated=True, name='A1', r=100.0,
              x=-3000.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A2', r=100.0,
              x=-2500.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A3', r=100.0,
              x=-2000.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A4', r=100.0,
              x=-1500.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A5', r=100.0,
              x=-1000.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A6', r=100.0, x=-500.0,
              y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A7', r=100.0, x=0.0,
              y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A8', r=100.0, x=500.0,
              y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A9', r=100.0, x=1000.0,
              y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A10', r=100.0,
              x=1500.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A11', r=100.0,
              x=2000.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A12', r=100.0,
              x=2500.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='A13', r=100.0,
              x=3000.0, y=-2500.0, z=0.0), DiskElectrode(activated=True, name='B1', r=100.0,
              x=-3000.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B2', r=100.0,
              x=-2500.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B3', r=100.0,
              x=-2000.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B4', r=100.0,
              x=-1500.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B5', r=100.0,
              x=-1000.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B6', r=100.0, x=-500.0,
              y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B7', r=100.0, x=0.0,
              y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B8', r=100.0, x=500.0,
              y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B9', r=100.0, x=1000.0,
              y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B10', r=100.0,
              x=1500.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B11', r=100.0,
              x=2000.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B12', r=100.0,
              x=2500.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='B13', r=100.0,
              x=3000.0, y=-2000.0, z=0.0), DiskElectrode(activated=True, name='C1', r=100.0,
              x=-3000.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C2', r=100.0,
              x=-2500.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C3', r=100.0,
              x=-2000.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C4', r=100.0,
              x=-1500.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C5', r=100.0,
              x=-1000.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C6', r=100.0, x=-500.0,
              y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C7', r=100.0, x=0.0,
              y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C8', r=100.0, x=500.0,
              y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C9', r=100.0, x=1000.0,
              y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C10', r=100.0,
              x=1500.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C11', r=100.0,
              x=2000.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C12', r=100.0,
              x=2500.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='C13', r=100.0,
              x=3000.0, y=-1500.0, z=0.0), DiskElectrode(activated=True, name='D1', r=100.0,
              x=-3000.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D2', r=100.0,
              x=-2500.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D3', r=100.0,
              x=-2000.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D4', r=100.0,
              x=-1500.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D5', r=100.0,
              x=-1000.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D6', r=100.0, x=-500.0,
              y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D7', r=100.0, x=0.0,
              y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D8', r=100.0, x=500.0,
              y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D9', r=100.0, x=1000.0,
              y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D10', r=100.0,
              x=1500.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D11', r=100.0,
              x=2000.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D12', r=100.0,
              x=2500.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='D13', r=100.0,
              x=3000.0, y=-1000.0, z=0.0), DiskElectrode(activated=True, name='E1', r=100.0,
              x=-3000.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E2', r=100.0,
              x=-2500.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E3', r=100.0,
              x=-2000.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E4', r=100.0,
              x=-1500.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E5', r=100.0,
              x=-1000.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E6', r=100.0, x=-500.0,
              y=-500.0, z=0.0), DiskElectrode(activated=True, name='E7', r=100.0, x=0.0,
              y=-500.0, z=0.0), DiskElectrode(activated=True, name='E8', r=100.0, x=500.0,
              y=-500.0, z=0.0), DiskElectrode(activated=True, name='E9', r=100.0, x=1000.0,
              y=-500.0, z=0.0), DiskElectrode(activated=True, name='E10', r=100.0,
              x=1500.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E11', r=100.0,
              x=2000.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E12', r=100.0,
              x=2500.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='E13', r=100.0,
              x=3000.0, y=-500.0, z=0.0), DiskElectrode(activated=True, name='F1', r=100.0,
              x=-3000.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F2', r=100.0,
              x=-2500.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F3', r=100.0,
              x=-2000.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F4', r=100.0,
              x=-1500.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F5', r=100.0,
              x=-1000.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F6', r=100.0, x=-500.0,
              y=0.0, z=0.0), DiskElectrode(activated=True, name='F7', r=100.0, x=0.0,
              y=0.0, z=0.0), DiskElectrode(activated=True, name='F8', r=100.0, x=500.0,
              y=0.0, z=0.0), DiskElectrode(activated=True, name='F9', r=100.0, x=1000.0,
              y=0.0, z=0.0), DiskElectrode(activated=True, name='F10', r=100.0,
              x=1500.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F11', r=100.0,
              x=2000.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F12', r=100.0,
              x=2500.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='F13', r=100.0,
              x=3000.0, y=0.0, z=0.0), DiskElectrode(activated=True, name='G1', r=100.0,
              x=-3000.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G2', r=100.0,
              x=-2500.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G3', r=100.0,
              x=-2000.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G4', r=100.0,
              x=-1500.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G5', r=100.0,
              x=-1000.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G6', r=100.0, x=-500.0,
              y=500.0, z=0.0), DiskElectrode(activated=True, name='G7', r=100.0, x=0.0,
              y=500.0, z=0.0), DiskElectrode(activated=True, name='G8', r=100.0, x=500.0,
              y=500.0, z=0.0), DiskElectrode(activated=True, name='G9', r=100.0, x=1000.0,
              y=500.0, z=0.0), DiskElectrode(activated=True, name='G10', r=100.0,
              x=1500.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G11', r=100.0,
              x=2000.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G12', r=100.0,
              x=2500.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='G13', r=100.0,
              x=3000.0, y=500.0, z=0.0), DiskElectrode(activated=True, name='H1', r=100.0,
              x=-3000.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H2', r=100.0,
              x=-2500.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H3', r=100.0,
              x=-2000.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H4', r=100.0,
              x=-1500.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H5', r=100.0,
              x=-1000.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H6', r=100.0, x=-500.0,
              y=1000.0, z=0.0), DiskElectrode(activated=True, name='H7', r=100.0, x=0.0,
              y=1000.0, z=0.0), DiskElectrode(activated=True, name='H8', r=100.0, x=500.0,
              y=1000.0, z=0.0), DiskElectrode(activated=True, name='H9', r=100.0, x=1000.0,
              y=1000.0, z=0.0), DiskElectrode(activated=True, name='H10', r=100.0,
              x=1500.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H11', r=100.0,
              x=2000.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H12', r=100.0,
              x=2500.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='H13', r=100.0,
              x=3000.0, y=1000.0, z=0.0), DiskElectrode(activated=True, name='I1', r=100.0,
              x=-3000.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I2', r=100.0,
              x=-2500.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I3', r=100.0,
              x=-2000.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I4', r=100.0,
              x=-1500.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I5', r=100.0,
              x=-1000.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I6', r=100.0, x=-500.0,
              y=1500.0, z=0.0), DiskElectrode(activated=True, name='I7', r=100.0, x=0.0,
              y=1500.0, z=0.0), DiskElectrode(activated=True, name='I8', r=100.0, x=500.0,
              y=1500.0, z=0.0), DiskElectrode(activated=True, name='I9', r=100.0, x=1000.0,
              y=1500.0, z=0.0), DiskElectrode(activated=True, name='I10', r=100.0,
              x=1500.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I11', r=100.0,
              x=2000.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I12', r=100.0,
              x=2500.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='I13', r=100.0,
              x=3000.0, y=1500.0, z=0.0), DiskElectrode(activated=True, name='J1', r=100.0,
              x=-3000.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J2', r=100.0,
              x=-2500.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J3', r=100.0,
              x=-2000.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J4', r=100.0,
              x=-1500.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J5', r=100.0,
              x=-1000.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J6', r=100.0, x=-500.0,
              y=2000.0, z=0.0), DiskElectrode(activated=True, name='J7', r=100.0, x=0.0,
              y=2000.0, z=0.0), DiskElectrode(activated=True, name='J8', r=100.0, x=500.0,
              y=2000.0, z=0.0), DiskElectrode(activated=True, name='J9', r=100.0, x=1000.0,
              y=2000.0, z=0.0), DiskElectrode(activated=True, name='J10', r=100.0,
              x=1500.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J11', r=100.0,
              x=2000.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J12', r=100.0,
              x=2500.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='J13', r=100.0,
              x=3000.0, y=2000.0, z=0.0), DiskElectrode(activated=True, name='K1', r=100.0,
              x=-3000.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K2', r=100.0,
              x=-2500.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K3', r=100.0,
              x=-2000.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K4', r=100.0,
              x=-1500.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K5', r=100.0,
              x=-1000.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K6', r=100.0, x=-500.0,
              y=2500.0, z=0.0), DiskElectrode(activated=True, name='K7', r=100.0, x=0.0,
              y=2500.0, z=0.0), DiskElectrode(activated=True, name='K8', r=100.0, x=500.0,
              y=2500.0, z=0.0), DiskElectrode(activated=True, name='K9', r=100.0, x=1000.0,
              y=2500.0, z=0.0), DiskElectrode(activated=True, name='K10', r=100.0,
              x=1500.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K11', r=100.0,
              x=2000.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K12', r=100.0,
              x=2500.0, y=2500.0, z=0.0), DiskElectrode(activated=True, name='K13', r=100.0,
              x=3000.0, y=2500.0, z=0.0)]

Note

You can also specify a list of radii, one value for each electrode in the grid.

We can visualize the grid by using its plot method:

plot electrode grid

Out:

<AxesSubplot:xlabel='x (microns)', ylabel='y (microns)'>

Creating a hexagonal grid

To create a hexagonal grid instead, all we need to do is change the grid type from ‘rect’ (default) to ‘hex’:

hex_grid = ElectrodeGrid((11, 13), 500, type='hex', etype=DiskElectrode, r=100)

hex_grid.plot()
plot electrode grid

Out:

<AxesSubplot:xlabel='x (microns)', ylabel='y (microns)'>

The following example centers the grid on (x,y) = (-600um, 200 um), z=150um away from the retinal surface, and rotates it clockwise by 45 degrees (note the minus sign):

offset_grid = ElectrodeGrid((11, 13), 500, type='hex', x=-600, y=200, z=150,
                            rot=-45, etype=DiskElectrode, r=100)

Note

Clockwise/counter-clockwise rotations refer to rotations on the retinal surface (that is, as if seen on a fundus photograph).

We can also plot the grid on top of a map of retinal nerve fiber bundles:

plot electrode grid

Out:

<AxesSubplot:xlabel='x (microns)', ylabel='y (microns)'>

Total running time of the script: ( 0 minutes 0.690 seconds)

Gallery generated by Sphinx-Gallery