def test_ElectrodeGrid(gtype): # Must pass in tuple/list of (rows, cols) for grid shape: with pytest.raises(TypeError): ElectrodeGrid("badinstantiation") with pytest.raises(TypeError): ElectrodeGrid(OrderedDict({'badinstantiation': 0})) with pytest.raises(ValueError): ElectrodeGrid([0], 10) with pytest.raises(ValueError): ElectrodeGrid([1, 2, 3], 10) with pytest.raises(TypeError): ElectrodeGrid({'1': 2}, 10) # Must pass in valid Electrode type: with pytest.raises(TypeError): ElectrodeGrid((2, 3), 10, type=gtype, etype=ElectrodeArray) with pytest.raises(TypeError): ElectrodeGrid((2, 3), 10, type=gtype, etype="foo") # Must pass in valid Orientation value: with pytest.raises(ValueError): ElectrodeGrid((2, 3), 10, type=gtype, orientation="foo") with pytest.raises(TypeError): ElectrodeGrid((2, 3), 10, type=gtype, orientation=False) # Must pass in radius `r` for grid of DiskElectrode objects: gshape = (4, 5) spacing = 100 grid = ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, r=13) for e in grid.values(): npt.assert_almost_equal(e.r, 13) grid = ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, r=np.arange(1, np.prod(gshape) + 1)) for i, e in enumerate(grid.values()): npt.assert_almost_equal(e.r, i + 1) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, radius=10) # Number of radii must match number of electrodes with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, radius=[2, 13, 14]) # Only DiskElectrode needs r, not PointSource: with pytest.raises(TypeError): ElectrodeGrid(gshape, spacing, type=gtype, r=10) # Must pass in radius `r` for grid of DiskElectrode objects: gshape = (4, 5) spacing = 100 with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, radius=10) # Number of radii must match number of electrodes with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, radius=[2, 13]) # Must pass in valid grid type: with pytest.raises(TypeError): ElectrodeGrid(gshape, spacing, type=DiskElectrode) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, type='unknown') # Verify spacing is correct: grid = ElectrodeGrid(gshape, spacing, type=gtype, etype=DiskElectrode, r=30) npt.assert_almost_equal(np.sqrt((grid['A1'].x - grid['A2'].x) ** 2 + (grid['A1'].y - grid['A2'].y) ** 2), spacing) npt.assert_almost_equal(np.sqrt((grid['A1'].x - grid['B1'].x) ** 2 + (grid['A1'].y - grid['B1'].y) ** 2), spacing) grid = ElectrodeGrid(gshape, spacing, type=gtype, orientation='vertical', etype=DiskElectrode, r=30) npt.assert_almost_equal(np.sqrt((grid['B1'].x - grid['B2'].x) ** 2 + (grid['B1'].y - grid['B2'].y) ** 2), spacing) npt.assert_almost_equal(np.sqrt((grid['A1'].x - grid['B1'].x) ** 2 + (grid['A1'].y - grid['B1'].y) ** 2), spacing) # A valid 2x5 grid centered at (0, 500): x, y = 0, 500 radius = 30 egrid = ElectrodeGrid(gshape, spacing, x=x, y=y, type='rect', etype=DiskElectrode, r=radius) npt.assert_equal(egrid.shape, gshape) npt.assert_equal(egrid.n_electrodes, np.prod(gshape)) # Make sure different electrodes have different coordinates: npt.assert_equal(len(np.unique([e.x for e in egrid.values()])), gshape[1]) npt.assert_equal(len(np.unique([e.y for e in egrid.values()])), gshape[0]) # Make sure the average of all x-coordinates == x: # (Note: egrid has all electrodes in a dictionary, with (name, object) # as (key, value) pairs. You can get the electrode names by iterating over # egrid.keys(). You can get the electrode objects by iterating over # egrid.values().) npt.assert_almost_equal(np.mean([e.x for e in egrid.values()]), x) # Same for y: npt.assert_almost_equal(np.mean([e.y for e in egrid.values()]), y) # Test whether egrid.z is set correctly, when z is a constant: z = 12 egrid = ElectrodeGrid(gshape, spacing, z=z, type=gtype, etype=DiskElectrode, r=radius) for i in egrid.values(): npt.assert_equal(i.z, z) # and when every electrode has a different z: z = np.arange(np.prod(gshape)) egrid = ElectrodeGrid(gshape, spacing, z=z, type=gtype, etype=DiskElectrode, r=radius) x = -1 for i in egrid.values(): npt.assert_equal(i.z, x + 1) x = i.z # TODO display a warning when rot > 2pi (meaning it might be in degrees). # I think we did this somewhere in the old Argus code # TODO test rotation, making sure positive angles rotate CCW egrid1 = ElectrodeGrid((2, 2), spacing, type=gtype, etype=DiskElectrode, r=radius) egrid2 = ElectrodeGrid((2, 2), spacing, rot=np.deg2rad(10), type=gtype, etype=DiskElectrode, r=radius) npt.assert_equal(egrid1["A1"].x < egrid2["A1"].x, True) npt.assert_equal(egrid1["A1"].y > egrid2["A1"].y, True) npt.assert_equal(egrid1["B2"].x > egrid2["B2"].x, True) npt.assert_equal(egrid1["B2"].y < egrid2["B2"].y, True) # Smallest possible grid: egrid = ElectrodeGrid((1, 1), spacing, type=gtype, etype=DiskElectrode, r=radius) npt.assert_equal(egrid.shape, (1, 1)) npt.assert_equal(egrid.n_electrodes, 1) # Grid has same size as 'names': egrid = ElectrodeGrid((1, 2), spacing, type=gtype, names=('C1', '4')) npt.assert_equal(egrid[0, 0], egrid['C1']) npt.assert_equal(egrid[0, 1], egrid['4']) # Can't have a zero-sized grid: with pytest.raises(ValueError): egrid = ElectrodeGrid((0, 0), spacing, type=gtype) with pytest.raises(ValueError): egrid = ElectrodeGrid((5, 0), spacing, type=gtype) # Invalid naming conventions: with pytest.raises(ValueError): egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=[1]) with pytest.raises(ValueError): egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=[]) with pytest.raises(TypeError): egrid = ElectrodeGrid(gshape, spacing, type=gtype, names={1}) with pytest.raises(TypeError): egrid = ElectrodeGrid(gshape, spacing, type=gtype, names={}) with pytest.raises(TypeError): ElectrodeGrid(gshape, spacing, names={'1': 2}) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, names=('A', '1', 'A')) with pytest.raises(TypeError): ElectrodeGrid(gshape, spacing, names=(1, 'A')) with pytest.raises(TypeError): ElectrodeGrid(gshape, spacing, names=('A', 1)) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, names=('A', '~')) with pytest.raises(ValueError): ElectrodeGrid(gshape, spacing, names=('~', 'A')) # Test all naming conventions: gshape = (2, 3) egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=('A', '1')) # print([e for e in egrid.keys()]) npt.assert_equal([e for e in egrid.keys()], ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']) egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=('1', 'A')) # print([e for e in egrid.keys()]) # egrid = ElectrodeGrid(shape, names=('A', '1')) npt.assert_equal([e for e in egrid.keys()], ['A1', 'B1', 'C1', 'A2', 'B2', 'C2']) egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=('1', '1')) # print([e for e in egrid.keys()]) npt.assert_equal([e for e in egrid.keys()], ['11', '12', '13', '21', '22', '23']) egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=('A', 'A')) # print([e for e in egrid.keys()]) npt.assert_equal([e for e in egrid.keys()], ['AA', 'AB', 'AC', 'BA', 'BB', 'BC']) # Still starts at A: egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=('B', '1')) npt.assert_equal([e for e in egrid.keys()], ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']) egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=('A', '2')) npt.assert_equal([e for e in egrid.keys()], ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']) # test unique names egrid = ElectrodeGrid(gshape, spacing, type=gtype, names=['53', '18', '00', '81', '11', '12']) npt.assert_equal([e for e in egrid.keys()], ['53', '18', '00', '81', '11', '12']) # Slots: npt.assert_equal(hasattr(egrid, '__slots__'), True) npt.assert_equal(hasattr(egrid, '__dict__'), False)
def test_ElectrodeGrid(): # Must pass in tuple/list of (rows, cols) for grid shape: with pytest.raises(TypeError): ElectrodeGrid("badinstantiation") with pytest.raises(TypeError): ElectrodeGrid(coll.OrderedDict({'badinstantiation': 0})) with pytest.raises(ValueError): ElectrodeGrid([0]) with pytest.raises(ValueError): ElectrodeGrid([1, 2, 3]) with pytest.raises(TypeError): ElectrodeGrid((2, 3), etype=ElectrodeArray) with pytest.raises(TypeError): ElectrodeGrid((2, 3), etype="foo") # A valid 2x5 grid centered at (0, 500): shape = (2, 3) x, y = 0, 500 spacing = 100 egrid = ElectrodeGrid(shape, x=x, y=y, spacing=spacing) npt.assert_equal(egrid.shape, shape) npt.assert_equal(egrid.n_electrodes, np.prod(shape)) npt.assert_equal(egrid.x, x) npt.assert_equal(egrid.y, y) npt.assert_almost_equal(egrid.spacing, spacing) # Make sure different electrodes have different coordinates: npt.assert_equal(len(np.unique([e.x for e in egrid.values()])), shape[1]) npt.assert_equal(len(np.unique([e.y for e in egrid.values()])), shape[0]) # Make sure the average of all x-coordinates == x: # (Note: egrid has all electrodes in a dictionary, with (name, object) # as (key, value) pairs. You can get the electrode names by iterating over # egrid.keys(). You can get the electrode objects by iterating over # egrid.values().) npt.assert_almost_equal(np.mean([e.x for e in egrid.values()]), x) # Same for y: npt.assert_almost_equal(np.mean([e.y for e in egrid.values()]), y) # Test whether egrid.z is set correctly, when z is a constant: z = 12 egrid = ElectrodeGrid(shape, z=z) npt.assert_equal(egrid.z, z) for i in egrid.values(): npt.assert_equal(i.z, z) # and when every electrode has a different z: z = np.arange(np.prod(shape)) egrid = ElectrodeGrid(shape, z=z) npt.assert_equal(egrid.z, z) x = -1 for i in egrid.values(): npt.assert_equal(i.z, x + 1) x = i.z # TODO display a warning when rot > 2pi (meaning it might be in degrees). # I think we did this somewhere in the old Argus code # TODO test rotation, making sure positive angles rotate CCW egrid1 = ElectrodeGrid(shape=(2, 2)) egrid2 = ElectrodeGrid(shape=(2, 2), rot=np.deg2rad(10)) npt.assert_equal(egrid1["A1"].x < egrid2["A1"].x, True) npt.assert_equal(egrid1["A1"].y > egrid2["A1"].y, True) npt.assert_equal(egrid1["B2"].x > egrid2["B2"].x, True) npt.assert_equal(egrid1["B2"].y < egrid2["B2"].y, True) # Smallest possible grid: egrid = ElectrodeGrid((1, 1)) npt.assert_equal(egrid.shape, (1, 1)) npt.assert_equal(egrid.n_electrodes, 1) # Can't have a zero-sized grid: with pytest.raises(ValueError): egrid = ElectrodeGrid((0, 0)) with pytest.raises(ValueError): egrid = ElectrodeGrid((5, 0)) # Invalid naming conventions: with pytest.raises(ValueError): egrid = ElectrodeGrid(shape, names=[1]) with pytest.raises(ValueError): egrid = ElectrodeGrid(shape, names=[]) with pytest.raises(TypeError): egrid = ElectrodeGrid(shape, names={1}) with pytest.raises(TypeError): egrid = ElectrodeGrid(shape, names={}) # Test all naming conventions: egrid = ElectrodeGrid(shape, names=('A', '1')) # print([e for e in egrid.keys()]) npt.assert_equal([e for e in egrid.keys()], ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']) egrid = ElectrodeGrid(shape, names=('1', 'A')) # print([e for e in egrid.keys()]) # egrid = ElectrodeGrid(shape, names=('A', '1')) npt.assert_equal([e for e in egrid.keys()], ['A1', 'B1', 'C1', 'A2', 'B2', 'C2']) # egrid = ElectrodeGrid(shape, names=('A', '1')) # npt.assert_equal([e for e in egrid.keys()], # ['A1', 'A1', 'C1', 'A2', 'B2', 'C2']) egrid = ElectrodeGrid(shape, names=('1', '1')) # print([e for e in egrid.keys()]) npt.assert_equal([e for e in egrid.keys()], ['11', '12', '13', '21', '22', '23']) egrid = ElectrodeGrid(shape, names=('A', 'A')) # print([e for e in egrid.keys()]) npt.assert_equal([e for e in egrid.keys()], ['AA', 'AB', 'AC', 'BA', 'BB', 'BC']) # rows and columns start at values other than A or 1 egrid = ElectrodeGrid(shape, names=('B', '1')) npt.assert_equal([e for e in egrid.keys()], ['B1', 'B2', 'B3', 'C1', 'C2', 'C3']) egrid = ElectrodeGrid(shape, names=('A', '2')) npt.assert_equal([e for e in egrid.keys()], ['A2', 'A3', 'A4', 'B2', 'B3', 'B4']) # test unique names egrid = ElectrodeGrid(shape, names=['53', '18', '00', '81', '11', '12']) npt.assert_equal([e for e in egrid.keys()], ['53', '18', '00', '81', '11', '12'])