def test_AxonMapModel():
    set_params = {'xystep': 2, 'engine': 'serial', 'rho': 432, 'axlambda': 2,
                  'n_axons': 9, 'n_ax_segments': 50,
                  'xrange': (-30, 30), 'yrange': (-20, 20),
                  'loc_od_x': 5, 'loc_od_y': 6}
    model = models.AxonMapModel()
    for param in set_params:
        npt.assert_equal(hasattr(model, param), True)

    # User can override default values
    for key, value in set_params.items():
        setattr(model, key, value)
        npt.assert_equal(getattr(model, key), value)
    model = models.AxonMapModel(**set_params)
    model.build(**set_params)
    for key, value in set_params.items():
        npt.assert_equal(getattr(model, key), value)

    # Zeros in, zeros out:
    implant = implants.ArgusII(stim=np.zeros(60))
    npt.assert_almost_equal(model.predict_percept(implant), 0)
    implant.stim = np.zeros(60)
    npt.assert_almost_equal(model.predict_percept(implant), 0)

    # Implant and model must be built for same eye:
    with pytest.raises(ValueError):
        implant = implants.ArgusII(eye='LE', stim=np.zeros(60))
        model.predict_percept(implant)
def test_AxonMapModel_predict_percept():
    model = models.AxonMapModel(xystep=1, axlambda=100, thresh_percept=0)
    model.build()
    # Single-electrode stim:
    img_stim = np.zeros(60)
    img_stim[47] = 1
    percept = model.predict_percept(implants.ArgusII(stim=img_stim))
    # Single bright pixel, rest of arc is less bright:
    npt.assert_equal(np.sum(percept > 0.9), 1)
    npt.assert_equal(np.sum(percept > 0.5), 2)
    npt.assert_equal(np.sum(percept > 0.1), 8)
    npt.assert_equal(np.sum(percept > 0.0001), 28)
    # Overall only a few bright pixels:
    npt.assert_almost_equal(np.sum(percept), 3.207, decimal=3)
    # Brightest pixel is in lower right:
    npt.assert_almost_equal(percept[18, 25], np.max(percept))
    # Top half is empty:
    npt.assert_almost_equal(np.sum(percept[:15, :]), 0)
    # Same for lower band:
    npt.assert_almost_equal(np.sum(percept[21:, :]), 0)

    # Full Argus II with small lambda: 60 bright spots
    model = models.AxonMapModel(engine='serial', xystep=1, rho=100,
                                axlambda=40)
    model.build()
    percept = model.predict_percept(implants.ArgusII(stim=np.ones(60)))
    # Most spots are pretty bright, but there are 2 dimmer ones (due to their
    # location on the retina):
    npt.assert_equal(np.sum(percept > 0.5), 58)
    npt.assert_equal(np.sum(percept > 0.275), 60)
def test_BaseModel_predict_percept():
    img_stim = np.zeros(60)
    model = ValidBaseModel(engine='serial',
                           xystep=5,
                           xrange=(-30, 30),
                           yrange=(-20, 20))
    # Model must be built first:
    with pytest.raises(models.NotBuiltError):
        model.predict_percept(implants.ArgusII())

    # But then must pass through ``predict_percept`` just fine
    model.build()
    percept = model.predict_percept(implants.ArgusII(stim=img_stim))
    npt.assert_equal(percept.shape, (9, 13))
    npt.assert_almost_equal(percept, 0)

    # Requires ProsthesisSystem object:
    with pytest.raises(TypeError):
        model.predict_percept(img_stim)

    # None in, None out:
    npt.assert_equal(model.predict_percept(implants.ArgusII(stim=None)), None)

    # `img_stim` must have right size:
    for shape in [(2, 60), (59, ), (2, 3, 4)]:
        with pytest.raises(ValueError):
            model.predict_percept(implants.ArgusII(stim=np.zeros(shape)))

    # Single-pixel percept:
    model = ValidBaseModel(engine='serial', xrange=(0.45, 0.45), yrange=(0, 0))
    model.build()
    percept = model.predict_percept(implants.ArgusII(stim=np.zeros(60)))
    npt.assert_equal(percept.shape, (1, 1))
    npt.assert_almost_equal(percept, 0)
Exemple #4
0
def test_BaseModel_fit():
    # Create a valid DataFrame
    X = get_dummy_data(nrows=3)

    # Model must be fitted first thing
    model = ValidBaseModel(engine='serial')
    npt.assert_equal(model._is_fitted, False)
    model.fit(X)
    npt.assert_equal(model._is_fitted, True)
    npt.assert_equal(hasattr(model, 'implant'), True)
    npt.assert_equal(hasattr(model, 'implant_type'), True)
    npt.assert_equal(isinstance(model.implant, model.implant_type), True)

    # `fit` only accepts DataFrame
    for XX in [42, [3.3, 1.1], np.array([[0]]), {'img': [[2]]}]:
        with pytest.raises(TypeError):
            model.fit(XX)
    yy = pd.DataFrame([{'img': [[2]]}, {'img': [[4]]}], index=[0, 1])
    for XX in [42, [3.3, 1.1], {'img': [[2]]}]:
        with pytest.raises(TypeError):
            model.fit(XX, y=yy)
    for yy in [42, [3.3, 1.1], {'img': [[2]]}]:
        with pytest.raises(TypeError):
            model.fit(X, y=yy)

    # We must pass an implant type, not an implant instance
    with pytest.raises(TypeError):
        model = ValidBaseModel(engine='serial', implant_type=p2pi.ArgusII())
        model.fit(X)
    with pytest.raises(TypeError):
        model = ValidBaseModel(engine='serial')
        model.set_params(implant_type=p2pi.ArgusII())
        model.fit(X)
    with pytest.raises(TypeError):
        model = ValidBaseModel(engine='serial')
        model.fit(X, implant_type=p2pi.ArgusII())

    # Implant rotation must be in radians:
    with pytest.raises(ValueError):
        model = ValidBaseModel(implant_rot=180)
        model.fit(X)

    # `fit_params` must take effect
    model = ValidBaseModel(engine='serial')
    model_params = model.get_params()
    for key, value in six.iteritems(model_params):
        npt.assert_equal(getattr(model, key), value)
        if isinstance(value, (int, float)):
            set_param = {key: 0.1234}
        elif isinstance(value, (list, set, tuple, np.ndarray)):
            set_param = {key: np.array([0, 0])}
        else:
            continue
        model.fit(X, **set_param)
        npt.assert_equal(getattr(model, key), set_param[key])
Exemple #5
0
def test_ScoreboardModel_predict_percept():
    model = models.ScoreboardModel(xystep=1, rho=100, thresh_percept=0)
    model.build()
    # Single-electrode stim:
    img_stim = np.zeros(60)
    img_stim[47] = 1
    percept = model.predict_percept(implants.ArgusII(stim=img_stim))
    # Single bright pixel, very small Gaussian kernel:
    npt.assert_equal(np.sum(percept > 0.9), 1)
    npt.assert_equal(np.sum(percept > 0.5), 1)
    npt.assert_equal(np.sum(percept > 0.1), 1)
    npt.assert_equal(np.sum(percept > 0.00001), 9)
    # Brightest pixel is in lower right:
    npt.assert_almost_equal(percept[18, 25], np.max(percept))

    # Full Argus II: 60 bright spots
    model = models.ScoreboardModel(engine='serial', xystep=1, rho=100)
    model.build()
    percept = model.predict_percept(implants.ArgusII(stim=np.ones(60)))
    npt.assert_equal(np.sum(np.isclose(percept, 0.9, rtol=0.1, atol=0.1)), 60)
def test_ArgusII(ztype, x, y, rot):
    # Create an ArgusII and make sure location is correct
    # Height `h` can either be a float or a list
    z = 100 if ztype == 'float' else np.ones(60) * 20
    argus = implants.ArgusII(x=x, y=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([-2587.5, -1437.5]).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['F1'].y + (argus['A10'].y - argus['F1'].y) / 2
    npt.assert_almost_equal(y_center, y)
    x_center = argus['A1'].x + (argus['F10'].x - argus['A1'].x) / 2
    npt.assert_almost_equal(x_center, x)

    # Make sure radius is correct
    for e in ['A1', 'B3', 'C5', 'D7', 'E9', 'F10']:
        npt.assert_almost_equal(argus[e].r, 112.5)

    # `h` must have the right dimensions
    with pytest.raises(ValueError):
        implants.ArgusII(x=-100, y=10, z=np.zeros(5))
    with pytest.raises(ValueError):
        implants.ArgusII(x=-100, y=100, z=[1, 2, 3])

    # Indexing must work for both integers and electrode names
    argus = implants.ArgusII()
    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.ArgusII(eye='RE', x=xc, y=yc)
    npt.assert_equal(argus_re['A10'].x > argus_re['A1'].x, True)
    npt.assert_almost_equal(argus_re['A10'].y, argus_re['A1'].y)

    # Left-eye implant:
    argus_le = implants.ArgusII(eye='LE', x=xc, y=yc)
    npt.assert_equal(argus_le['A1'].x > argus_le['A10'].x, True)
    npt.assert_almost_equal(argus_le['A10'].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'], ['F2', 'F10']):
        # By default, electrode 'F1' in a left eye has the same coordinates as
        # 'F10' in a right eye (because the columns are reversed). Thus both
        # cases are testing an electrode with x>0, y>0:
        before = implants.ArgusII(eye=eye)
        after = implants.ArgusII(eye=eye, rot=20)
        npt.assert_equal(after[el].x < before[el].x, True)
        npt.assert_equal(after[el].y > before[el].y, True)

    # Set a stimulus via dict:
    argus = implants.ArgusII(stim={'B7': 13})
    npt.assert_equal(argus.stim.shape, (1, 1))
    npt.assert_equal(argus.stim.electrodes, ['B7'])

    # Set a stimulus via array:
    argus = implants.ArgusII(stim=np.ones(60))
    npt.assert_equal(argus.stim.shape, (60, 1))
    npt.assert_almost_equal(argus.stim.data, 1)