def test_video2stim(): reload(image) reload(video) # Smoke-test example video from skvideo import datasets implant = implants.ArgusI() video.video2stim(datasets.bikes(), implant) with pytest.raises(OSError): video.video2stim('no-such-file.avi', implant)
def test_video2pulsetrain(): reload(stimuli) implant = implants.ArgusI() with pytest.raises(OSError): stimuli.video2pulsetrain('no-such-file.avi', implant) # Smoke-test example video from skvideo import datasets stimuli.video2pulsetrain(datasets.bikes(), implant)
def test_parse_pulse_trains(): # Specify pulse trains in a number of different ways and make sure they # are all identical after parsing # Create some p2p.implants argus = implants.ArgusI() simple = implants.ElectrodeArray('subretinal', 0, 0, 0, 0) pt_zero = utils.TimeSeries(1, np.zeros(1000)) pt_nonzero = utils.TimeSeries(1, np.random.rand(1000)) # Test 1 # ------ # Specify wrong number of pulse trains with pytest.raises(ValueError): stimuli.parse_pulse_trains(pt_nonzero, argus) with pytest.raises(ValueError): stimuli.parse_pulse_trains([pt_nonzero], argus) with pytest.raises(ValueError): stimuli.parse_pulse_trains([pt_nonzero] * (argus.num_electrodes - 1), argus) with pytest.raises(ValueError): stimuli.parse_pulse_trains([pt_nonzero] * 2, simple) # Test 2 # ------ # Send non-zero pulse train to specific electrode el_name = 'B3' el_idx = argus.get_index(el_name) # Specify a list of 16 pulse trains (one for each electrode) pt0_in = [pt_zero] * argus.num_electrodes pt0_in[el_idx] = pt_nonzero pt0_out = stimuli.parse_pulse_trains(pt0_in, argus) # Specify a dict with non-zero pulse trains pt1_in = {el_name: pt_nonzero} pt1_out = stimuli.parse_pulse_trains(pt1_in, argus) # Make sure the two give the same result for p0, p1 in zip(pt0_out, pt1_out): npt.assert_equal(p0.data, p1.data) # Test 3 # ------ # Smoke testing stimuli.parse_pulse_trains([pt_zero] * argus.num_electrodes, argus) stimuli.parse_pulse_trains(pt_zero, simple) stimuli.parse_pulse_trains([pt_zero], simple)
def test_ScoreboardModel(): # ScoreboardModel automatically sets `rho`: model = models.ScoreboardModel(engine='serial', xystep=5) npt.assert_equal(hasattr(model, 'rho'), True) # User can set `rho`: model.rho = 123 npt.assert_equal(model.rho, 123) model.build(rho=987) npt.assert_equal(model.rho, 987) # Zero in = zero out: implant = implants.ArgusI(stim=np.zeros(16)) npt.assert_almost_equal(model.predict_percept(implant), 0)
def test_image2pulsetrain(): # Range of values amp_min = 2 amp_max = 15 # Create a standard Argus I array implant = implants.ArgusI() # Create a small image with 1 pixel per electrode img = np.zeros((4, 4)) # An all-zero image should give us a really boring stimulation protocol pulses = stimuli.image2pulsetrain(img, implant, valrange=[amp_min, amp_max]) for pt in pulses: npt.assert_equal(pt.data.max(), amp_min) # Now put some structure in the image img[1, 1] = img[1, 2] = img[2, 1] = img[2, 2] = 0.75 expected_max = [amp_max, 0.75 * (amp_max - amp_min) + amp_min] for max_contrast, val_max in zip([True, False], expected_max): pt = stimuli.image2pulsetrain(img, implant, coding='amplitude', max_contrast=max_contrast, valrange=[amp_min, amp_max]) # Make sure we have one pulse train per electrode npt.assert_equal(len(pt), implant.num_electrodes) # Make sure the brightest electrode has `amp_max` npt.assert_almost_equal(np.max([p.data.max() for p in pt]), val_max) # Make sure the dimmest electrode has `amp_min` as max amplitude npt.assert_almost_equal(np.min([np.abs(p.data).max() for p in pt]), amp_min) # Invalid implant with pytest.raises(TypeError): stimuli.image2pulsetrain("rainbow_cat.jpg", np.zeros(10)) with pytest.raises(TypeError): e_array = implants.ElectrodeArray('epiretinal', 100, 0, 0) stimuli.image2pulsetrain("rainbow_cat.jpg", e_array) # Invalid image with pytest.raises(IOError): stimuli.image2pulsetrain("rainbow_cat.jpg", implants.ArgusI()) # Smoke-test RGB stimuli.image2pulsetrain(np.zeros((10, 10, 3)), implants.ArgusI()) # Smoke-test invert stimuli.image2pulsetrain(np.zeros((10, 10, 3)), implants.ArgusI(), invert=True) # Smoke-test normalize stimuli.image2pulsetrain(np.ones((10, 10, 3)) * 2, implants.ArgusI(), invert=True) # Smoke-test frequency coding stimuli.image2pulsetrain(np.zeros((10, 10, 3)), implants.ArgusI(), coding='frequency') # Invalid coding with pytest.raises(ValueError): stimuli.image2pulsetrain(np.zeros((10, 10)), implants.ArgusI(), coding='n/a') # Trigger an import error with mock.patch.dict("sys.modules", {"skimage": {}, "skimage.io": {}}): with pytest.raises(ImportError): reload(stimuli) stimuli.image2pulsetrain(img, implant)
def test_ArgusI(ztype, x, y, rot): # Create an ArgusI and make sure location is correct # Height `z` can either be a float or a list z = 100 if ztype == 'float' else np.ones(16) * 20 argus = implants.ArgusI(x, y, z=z, rot=rot) # Slots: npt.assert_equal(hasattr(argus, '__slots__'), True) npt.assert_equal(hasattr(argus, '__dict__'), False) # Coordinates of first electrode xy = np.array([-1200, -1200]).T # Rotate rot_rad = np.deg2rad(rot) R = np.array( [np.cos(rot_rad), -np.sin(rot_rad), np.sin(rot_rad), np.cos(rot_rad)]).reshape((2, 2)) xy = np.matmul(R, xy) # Then off-set: Make sure first electrode is placed # correctly npt.assert_almost_equal(argus['A1'].x, xy[0] + x) npt.assert_almost_equal(argus['A1'].y, xy[1] + y) # Make sure array center is still (x,y) y_center = argus['D1'].y + (argus['A4'].y - argus['D1'].y) / 2 npt.assert_almost_equal(y_center, y) x_center = argus['A1'].x + (argus['D4'].x - argus['A1'].x) / 2 npt.assert_almost_equal(x_center, x) # Check radii of electrodes for e in ['A1', 'A3', 'B2', 'C1', 'D4']: npt.assert_almost_equal(argus[e].r, 125) for e in ['A2', 'A4', 'B1', 'C2', 'D3']: npt.assert_almost_equal(argus[e].r, 250) # Check location of the tack tack = np.matmul(R, [-2000, 0]) tack = tuple(tack + [x_center, y_center]) # `h` must have the right dimensions with pytest.raises(ValueError): implants.ArgusI(x=-100, y=10, z=np.zeros(5)) with pytest.raises(ValueError): implants.ArgusI(x=-100, y=10, z=[1, 2, 3]) # Indexing must work for both integers and electrode names for use_legacy_names in [True, False]: argus = implants.ArgusI(use_legacy_names=use_legacy_names) for idx, (name, electrode) in enumerate(argus.electrodes.items()): npt.assert_equal(electrode, argus[idx]) npt.assert_equal(electrode, argus[name]) npt.assert_equal(argus["unlikely name for an electrode"], None) # Right-eye implant: xc, yc = 500, -500 argus_re = implants.ArgusI(eye='RE', x=xc, y=yc) npt.assert_equal(argus_re['D1'].x > argus_re['A1'].x, True) npt.assert_almost_equal(argus_re['D1'].y, argus_re['A1'].y) # need to adjust for reflection about y-axis # Left-eye implant: argus_le = implants.ArgusI(eye='LE', x=xc, y=yc) npt.assert_equal(argus_le['A1'].x > argus_le['D4'].x, True) npt.assert_almost_equal(argus_le['D1'].y, argus_le['A1'].y) # In both left and right eyes, rotation with positive angle should be # counter-clock-wise (CCW): for (x>0,y>0), decreasing x and increasing y for eye, el in zip(['LE', 'RE'], ['A1', 'D1']): before = implants.ArgusI(eye=eye) after = implants.ArgusI(eye=eye, rot=10) npt.assert_equal(after[el].x > before[el].x, True) npt.assert_equal(after[el].y > before[el].y, True) # Check naming scheme argus = implants.ArgusI(use_legacy_names=False) npt.assert_equal(argus.electrode_names[15], 'D4') npt.assert_equal(argus.electrode_names[0], 'A1') argus = implants.ArgusI(use_legacy_names=True) npt.assert_equal(argus.electrode_names[15], 'M1') npt.assert_equal(argus.electrode_names[0], 'L6') # Set a stimulus via dict: argus = implants.ArgusI(stim={'B3': 13}) npt.assert_equal(argus.stim.shape, (1, 1)) npt.assert_equal(argus.stim.electrodes, ['B3']) # Set a stimulus via array: argus = implants.ArgusI(stim=np.ones(16)) npt.assert_equal(argus.stim.shape, (16, 1)) npt.assert_almost_equal(argus.stim.data, 1)