diff --git a/README.rst b/README.rst index b6c9a9ad..92a6f868 100644 --- a/README.rst +++ b/README.rst @@ -37,21 +37,12 @@ However, interactions between the device electronics and the retinal neurophysiology result in perceptual distortions that may severely limit the quality of the generated visual experience: -.. raw:: html - -
-
- Predicted percept -
-
- Input stimulus -
-
- .. image:: https://raw.githubusercontent.com/pulse2percept/pulse2percept/master/doc/_static/boston-train-combined.gif :align: center :alt: Input stimulus and predicted percept +*(left: input stimulus, right: predicted percept)* + Built on the NumPy and SciPy stacks, `pulse2percept`_ provides an open-source implementation of a number of computational models for state-of-the-art `visual prostheses`_ (also known as the 'bionic eye'), diff --git a/doc/index.rst b/doc/index.rst index 328e734e..ef60f013 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -48,14 +48,14 @@ pulse2percept |version| documentation .. include:: ../README.rst :start-line: 28 - :end-line: 79 + :end-line: 70 Installation ============ .. include:: ../README.rst - :start-line: 82 - :end-line: 101 + :start-line: 73 + :end-line: 92 Detailed instructions for different platforms can be found in our :ref:`Installation Guide `. diff --git a/doc/install.rst b/doc/install.rst index 1e2b78ce..63d28e6a 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -161,8 +161,8 @@ Dependencies ------------ .. include:: ../README.rst - :start-line: 115 - :end-line: 148 + :start-line: 105 + :end-line: 139 Obtaining the latest code from GitHub ------------------------------------- @@ -217,7 +217,8 @@ Obtaining the latest code from GitHub Building pulse2percept ---------------------- -Assuming you are still in the root directory of the git clone, type: +Assuming you are still in the root directory of the git clone, type +(note the ``.``): .. code-block:: bash diff --git a/doc/users/release_notes.rst b/doc/users/release_notes.rst index 2b429fe3..ec31a90e 100644 --- a/doc/users/release_notes.rst +++ b/doc/users/release_notes.rst @@ -9,7 +9,7 @@ Release Notes pulse2percept 0.4.3 is the last release to support Python 2.7 and 3.4. pulse2percept 0.5+ require **Python 3.5 or newer**. -v0.6.0 (2020, planned) +v0.6.0 (2020-05-05) ---------------------- Highlights @@ -19,7 +19,8 @@ Highlights * New implants: :py:class:`~pulse2percept.implants.BVA24` (:pull:`161`) * New models: :py:class:`~pulse2percept.models.ScoreboardModel` (:pull:`96`), :py:class:`~pulse2percept.models.AxonMapModel` (:pull:`96`), - :py:class:`~pulse2percept.models.Nanduri2012Model` (:pull:`168`) + :py:class:`~pulse2percept.models.Nanduri2012Model` (:pull:`168`), + :py:class:`~pulse2percept.models.Horsager2009Model` (:pull:`180`) * New stimuli: :py:class:`~pulse2percept.stimuli.BiphasicPulseTrain`, :py:class:`~pulse2percept.stimuli.AsymmetricBiphasicPulse`, :py:class:`~pulse2percept.stimuli.AsymmetricBiphasicPulseTrain` @@ -57,13 +58,18 @@ Backward-incompatible changes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Times are now specified in milliseconds. -* The ``TimeSeries`` object is deprecated. Please use - :py:class:`~pulse2percept.stimuli.Stimulus` instead. * The ``Simulation`` object has been removed. Please directly :ref:`instantiate a model ` instead. * ``pulse2percept.retina``: use :py:mod:`~pulse2percept.models` instead * ``pulse2percept.files``: use :py:mod:`~pulse2percept.io` instead +Deprecations +^^^^^^^^^^^^ + +* ``TimeSeries``: use :py:class:`~pulse2percept.stimuli.Stimulus` instead +* Old pulses got renamed to ``LegacyMonophasicPulse``, ``LegacyBiphasicPulse`` + and ``LegacyPulseTrain`` + v0.5.2 (2020-02-25) ------------------- diff --git a/pulse2percept/datasets/horsager2009.py b/pulse2percept/datasets/horsager2009.py index 4dd18488..38f50363 100644 --- a/pulse2percept/datasets/horsager2009.py +++ b/pulse2percept/datasets/horsager2009.py @@ -1,5 +1,4 @@ """`load_horsager2009`, `VariableDuration`""" -import numpy as np from os.path import dirname, join try: diff --git a/pulse2percept/models/base.py b/pulse2percept/models/base.py index be1b2c5f..fbefca6f 100644 --- a/pulse2percept/models/base.py +++ b/pulse2percept/models/base.py @@ -8,7 +8,7 @@ from ..implants import ProsthesisSystem from ..stimuli import Stimulus from ..percepts import Percept -from ..utils import PrettyPrint, Frozen, FreezeError, GridXY, parfor, bisect +from ..utils import PrettyPrint, Frozen, FreezeError, GridXY, bisect class NotBuiltError(ValueError, AttributeError): diff --git a/pulse2percept/models/tests/test_horsager2009.py b/pulse2percept/models/tests/test_horsager2009.py index faa071d3..b8c39473 100644 --- a/pulse2percept/models/tests/test_horsager2009.py +++ b/pulse2percept/models/tests/test_horsager2009.py @@ -3,7 +3,7 @@ import pytest from pulse2percept.implants import ProsthesisSystem, PointSource -from pulse2percept.stimuli import Stimulus, BiphasicPulse, BiphasicPulseTrain +from pulse2percept.stimuli import BiphasicPulse, BiphasicPulseTrain from pulse2percept.percepts import Percept from pulse2percept.models import Horsager2009Model, Horsager2009Temporal from pulse2percept.utils import FreezeError @@ -74,8 +74,6 @@ def test_Horsager2009Model(): with pytest.raises(FreezeError): model.rho = 100 - -def test_Horsager2009Model(): # Model and TemporalModel give the same result for amp, freq in zip([136.02, 120.35, 57.71], [5, 15, 225]): stim = BiphasicPulseTrain(freq, amp, 0.075, interphase_dur=0.075, diff --git a/pulse2percept/stimuli/pulse_trains.py b/pulse2percept/stimuli/pulse_trains.py index 47aa50d7..c1fa0b3e 100644 --- a/pulse2percept/stimuli/pulse_trains.py +++ b/pulse2percept/stimuli/pulse_trains.py @@ -2,8 +2,6 @@ import numpy as np import copy import logging -from scipy.interpolate import interp1d - from . import MIN_AMP from .base import TimeSeries, Stimulus diff --git a/pulse2percept/stimuli/pulses.py b/pulse2percept/stimuli/pulses.py index e9231708..999c4085 100644 --- a/pulse2percept/stimuli/pulses.py +++ b/pulse2percept/stimuli/pulses.py @@ -219,7 +219,7 @@ class AsymmetricBiphasicPulse(Stimulus): If True, will deliver the cathodic pulse phase before the anodic one. electrode : { int | string }, optional, default: 0 Optionally, you can provide your own electrode name. - dt : float, optional, default: 1e-3 ms + dt : float, optional, default: 1e-6 ms Sampling time step (ms); defines the duration of the signal edge transitions. @@ -245,7 +245,7 @@ class AsymmetricBiphasicPulse(Stimulus): def __init__(self, amp1, amp2, phase_dur1, phase_dur2, interphase_dur=0, delay_dur=0, stim_dur=None, cathodic_first=True, - electrode=None, dt=1e-3): + electrode=None, dt=1e-6): if phase_dur1 <= 0: raise ValueError("'phase_dur1' must be greater than 0.") if phase_dur2 <= 0: diff --git a/pulse2percept/stimuli/tests/test_pulse_trains.py b/pulse2percept/stimuli/tests/test_pulse_trains.py index 79c0fe27..ba02ff75 100644 --- a/pulse2percept/stimuli/tests/test_pulse_trains.py +++ b/pulse2percept/stimuli/tests/test_pulse_trains.py @@ -153,7 +153,7 @@ def test_BiphasicTripletTrain(amp, interphase_dur, delay_dur, cathodic_first): pt = BiphasicTripletTrain(freq, amp, phase_dur, interphase_dur=interphase_dur, delay_dur=delay_dur, stim_dur=stim_dur, - cathodic_first=cathodic_first, dt=1e-6) + cathodic_first=cathodic_first, dt=dt) for i in range(n_pulses): t_win = i * window_dur npt.assert_almost_equal(pt[0, t_win], 0) diff --git a/pulse2percept/utils/optimize.py b/pulse2percept/utils/optimize.py index 2ae3cc64..63cd3c9c 100644 --- a/pulse2percept/utils/optimize.py +++ b/pulse2percept/utils/optimize.py @@ -2,7 +2,7 @@ import logging -def bisect(y_target, func, args=[], kwargs={}, x_lo=0, x_hi=1, +def bisect(y_target, func, args=None, kwargs=None, x_lo=0, x_hi=1, x_tol=1e-6, y_tol=1e-3, max_iter=100): """Binary search (bisection method) to find `x` value that gives `y_target` @@ -38,10 +38,19 @@ def bisect(y_target, func, args=[], kwargs={}, x_lo=0, x_hi=1, the conventional bisection method. """ - assert x_lo < x_hi - assert x_tol > 0 - assert y_tol > 0 - assert max_iter > 0 + if x_lo >= x_hi: + raise ValueError("x_lo (%f) must be lower than x_hi " + "(%f)." % (x_lo, x_hi)) + if x_tol <= 0: + raise ValueError("x_tol (%f) must be greater than zero." % x_tol) + if y_tol <= 0: + raise ValueError("y_tol (%f) must be greater than zero." % y_tol) + if max_iter <= 0: + raise ValueError("max_iter (%d) must be greater than zero." % max_iter) + if args is None: + args = [] + if kwargs is None: + kwargs = {} n_iter = 1 while n_iter < max_iter: diff --git a/pulse2percept/utils/tests/test_optimize.py b/pulse2percept/utils/tests/test_optimize.py index 71d0dcfb..ed2d8d16 100644 --- a/pulse2percept/utils/tests/test_optimize.py +++ b/pulse2percept/utils/tests/test_optimize.py @@ -1,5 +1,6 @@ import numpy as np import numpy.testing as npt +import pytest from pulse2percept.utils import bisect @@ -12,3 +13,12 @@ def test_bisect(): max_iter=100) decimal = int(np.abs(np.log10(y_tol))) - 1 npt.assert_almost_equal(func(x_mid), y_target, decimal=decimal) + + with pytest.raises(ValueError): + bisect(0, func, x_lo=1, x_hi=0) + with pytest.raises(ValueError): + bisect(0, func, x_tol=-1) + with pytest.raises(ValueError): + bisect(0, func, y_tol=-1) + with pytest.raises(ValueError): + bisect(0, func, max_iter=0) diff --git a/pulse2percept/version.py b/pulse2percept/version.py index 31d8e4c9..ef7eb44d 100644 --- a/pulse2percept/version.py +++ b/pulse2percept/version.py @@ -1 +1 @@ -__version__ = '0.6.0.dev0' +__version__ = '0.6.0'