Skip to content

Commit

Permalink
remove deprecated files; use relative imports in tests; test only Pyt…
Browse files Browse the repository at this point in the history
…hon 3.6

fix variable name clashes in tests

fix flake errors
  • Loading branch information
Michael Beyeler committed Feb 20, 2018
1 parent e41b761 commit e4ee165
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 465 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Expand Up @@ -21,8 +21,6 @@ addons:
- ffmpeg

python:
- '2.7'
- '3.5'
- '3.6'

before_install:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -35,7 +35,8 @@ corresponds to the predicted perceptual experience of a patient:
If you use pulse2percept in a scholary publication, please cite as:
> M Beyeler, GM Boynton, I Fine, A Rokem (2017). pulse2percept: A Python-based
> simulation framework for bionic vision. Proceedings of the 16th Python in
> Science Conference, 81-88. doi: 10.25080/shinma-7f4c6e7-00c.
> Science Conference, p.81-88,
> doi:[10.25080/shinma-7f4c6e7-00c](https://doi.org/10.25080/shinma-7f4c6e7-00c).
Or use the following BibTex:
```
Expand Down
102 changes: 0 additions & 102 deletions pulse2percept/files.py
@@ -1,7 +1,4 @@
import subprocess
import numpy as np
import scipy.io as sio
import os
import logging

from pulse2percept import utils
Expand Down Expand Up @@ -467,105 +464,6 @@ def save_video_sidebyside(videofile, percept, savefile, fps=30,
libav_path=libav_path)


@utils.deprecated(alt_func='p2p.files.save_video', deprecated_version='0.2',
removed_version='0.3')
def savemoviefiles(filestr, data, path='savedImages/'):
"""Saves a brightness movie to .npy, .mat, and .avi format
Parameters
----------
filestr : str
Name of the resulting files without file type (suffix .npy, .mat
or .avi will be appended)
data : array
A 3-D NumPy array containing the data, such as the `data` field of
a utils.TimeSeries object
path : str, optional
Path to directory where files should be saved.
Default: savedImages/
"""
np.save(path + filestr, data) # save as npy
sio.savemat(path + filestr + '.mat', dict(mov=data)) # save as matfile
npy2movie(path + filestr + '.avi', data) # save as avi


@utils.deprecated(alt_func='p2p.files.save_video', deprecated_version='0.2',
removed_version='0.3')
def npy2movie(filename, movie, rate=30):
"""Saves a NumPy array to .avi on Windows
Creates avi files will work on a 64x Windows as well as a PC provided
that the ffmpeg folder is included in the right location.
Most uptodate version of ffmpeg can be found here:
https://ffmpeg.zeranoe.com/builds/win64/static/
Used instructions from here with modifications:
http://adaptivesamples.com/how-to-install-ffmpeg-on-windows
Parameters
----------
filename : str
File name of .avi movie to be produced
movie : array
A 3-D NumPy array containing the data, such as the `data` field of
a utils.TimeSeries object
rate : float, optional, default: 30
Frame rate.
"""
if os.name != 'nt':
raise OSError("npy2movie only works on Windows.")

try:
from PIL import Image
except ImportError:
raise ImportError("You do not have PIL installed.")

cmdstring = ('ffmpeg.exe',
'-y',
'-r', '%d' % rate,
'-f', 'image2pipe',
'-vcodec', 'mjpeg',
'-i', 'pipe:',
'-vcodec', 'libxvid',
filename
)
logging.getLogger(__name__).info(filename)
p = subprocess.Popen(cmdstring, stdin=subprocess.PIPE, shell=False)

for i in range(movie.shape[-1]):
im = Image.fromarray(np.uint8(scale(movie[:, :, i], 0, 255)))
p.stdin.write(im.tobytes('jpeg', 'L'))

p.stdin.close()


@utils.deprecated(alt_func='p2p.stimuli.image2pulsetrain',
deprecated_version='0.2', removed_version='0.3')
def scale(inarray, newmin=0.0, newmax=1.0):
"""Scales an image such that its lowest value attains newmin and
it's highest value attains newmax.
written by Ione Fine, based on code from Rick Anthony
Parameters
----------
inarray : array
The input array
newmin : float, optional, default: 0.0
The desired lower bound of values in `inarray`.
newmax : float, optional, default: 1.0
The desired upper bound of values in `inarray`.
"""

oldmin = inarray.min()
oldmax = inarray.max()

delta = (newmax - newmin) / (oldmax - oldmin)
outarray = delta * (inarray - oldmin) + newmin
return outarray


def find_files_like(datapath, pattern):
"""Finds files in a folder whose name matches a pattern
Expand Down
55 changes: 0 additions & 55 deletions pulse2percept/stimuli.py
Expand Up @@ -5,7 +5,6 @@
"""
import numpy as np
from scipy import interpolate as spi
import six
import copy
import logging
Expand Down Expand Up @@ -465,48 +464,6 @@ def video2pulsetrain(filename, implant, framerate=20,
return video


@utils.deprecated('p2p.stimuli.video2pulsetrain', removed_version='0.3')
class Movie2Pulsetrain(utils.TimeSeries):
"""Is used to create pulse-train stimulus based on luminance over time from
a movie"""

def __init__(self, rflum, tsample, fps=30.0, amp_transform='linear',
amp_max=60, freq=20, pulse_dur=.5 / 1000.,
interphase_dur=.5 / 1000.,
pulsetype='cathodicfirst', stimtype='pulsetrain'):
"""
Parameters
----------
rflum : 1D array
Values between 0 and 1
tsample : suggest TemporalModel.tsample
"""
if tsample <= 0:
raise ValueError("tsample must be a non-negative float.")

# set up the individual pulses
pulse = BiphasicPulse(pulsetype, pulse_dur, tsample,
interphase_dur)
# set up the sequence
dur = rflum.shape[-1] / fps

if stimtype == 'pulsetrain':
interpulsegap = np.zeros(int(round((1.0 / freq) / tsample)) -
len(pulse.data))
ppt = []
for j in range(0, int(np.ceil(dur * freq))):
ppt = np.concatenate((ppt, interpulsegap), axis=0)
ppt = np.concatenate((ppt, pulse.data), axis=0)

ppt = ppt[0:int(round(dur / tsample))]
intfunc = spi.interp1d(np.linspace(0, len(rflum), len(rflum)),
rflum)

amp = intfunc(np.linspace(0, len(rflum), len(ppt)))
data = amp * ppt * amp_max
utils.TimeSeries.__init__(self, tsample, data)


def parse_pulse_trains(stim, implant):
"""Parse input stimulus and convert to list of pulse trains
Expand Down Expand Up @@ -567,15 +524,3 @@ def parse_pulse_trains(stim, implant):
pt = copy.deepcopy(stim)

return pt


@utils.deprecated(deprecated_version='0.2', removed_version='0.3')
def retinalmovie2electrodtimeseries(rf, movie):
"""Calculates the luminance over time for each electrodes receptive field.
"""
rflum = np.zeros(movie.shape[-1])
for f in range(movie.shape[-1]):
tmp = rf * movie[:, :, f]
rflum[f] = np.mean(tmp)

return rflum
25 changes: 14 additions & 11 deletions pulse2percept/tests/test_api.py
Expand Up @@ -2,36 +2,39 @@
import numpy.testing as npt
import pytest

import pulse2percept as p2p
from .. import api as p2p
from .. import implants
from .. import stimuli
from .. import utils


def test_Simulation___init__():
implant = p2p.implants.Electrode("epiretinal", 10, 0, 0, 0)
implant = implants.Electrode("epiretinal", 10, 0, 0, 0)
with pytest.raises(TypeError):
p2p.Simulation(implant)


def test_Simulation_pulse2percept():
implant = p2p.implants.ElectrodeArray("epiretinal", 10, 0, 0, 0)
implant = implants.ElectrodeArray("epiretinal", 10, 0, 0, 0)
sim = p2p.Simulation(implant, engine='serial')
sim.set_optic_fiber_layer(x_range=[0, 0], y_range=[0, 0])
pt = p2p.stimuli.BiphasicPulse('cathodicfirst', 0.45 / 1000, 0.005 / 1000)
pt = stimuli.BiphasicPulse('cathodicfirst', 0.45 / 1000, 0.005 / 1000)
sim.pulse2percept(pt)
sim.pulse2percept(pt, layers=['GCL'])
sim.pulse2percept(pt, layers=['INL'])

# PulseTrain must have the same tsample as (implicitly set up) GCL
pt = p2p.stimuli.BiphasicPulse("cathodicfirst", 0.1, 0.001)
pt = stimuli.BiphasicPulse("cathodicfirst", 0.1, 0.001)
with pytest.raises(ValueError):
sim.pulse2percept(pt)

pt = p2p.stimuli.BiphasicPulse("cathodicfirst", 0.1, 0.005 / 1000)
pt = stimuli.BiphasicPulse("cathodicfirst", 0.1, 0.005 / 1000)
with pytest.raises(ValueError):
sim.pulse2percept(pt, layers=['GCL', 'invalid'])


def test_Simulation_set_optic_fiber_layer():
sim = p2p.Simulation(p2p.implants.ArgusI(), engine='serial')
sim = p2p.Simulation(implants.ArgusI(), engine='serial')

# Invalid grid ranges
with pytest.raises(ValueError):
Expand Down Expand Up @@ -59,7 +62,7 @@ def test_Simulation_set_optic_fiber_layer():
npt.assert_equal(sim.ofl.y_range, y_range)

# Smoke test
implant = p2p.implants.ElectrodeArray('epiretinal', 10, 0, 0, 0)
implant = implants.ElectrodeArray('epiretinal', 10, 0, 0, 0)
sim = p2p.Simulation(implant, engine='serial')
sim.set_optic_fiber_layer(x_range=0, y_range=0)
sim.set_optic_fiber_layer(x_range=[0, 0], y_range=[0, 0])
Expand All @@ -74,7 +77,7 @@ def model_cascade(self, inval):
return inval

# Smoke test custom model
implant = p2p.implants.ElectrodeArray('epiretinal', 10, 0, 0, 0)
implant = implants.ElectrodeArray('epiretinal', 10, 0, 0, 0)
sim = p2p.Simulation(implant, engine='serial')
sim.set_optic_fiber_layer(x_range=0, y_range=0)

Expand Down Expand Up @@ -108,7 +111,7 @@ def model_cascade(self, inval):
with pytest.raises(ValueError):
sim.set_ganglion_cell_layer('unknown-model')
with pytest.raises(ValueError):
sim.set_ganglion_cell_layer(p2p.implants.ArgusII())
sim.set_ganglion_cell_layer(implants.ArgusII())


def test_get_brightest_frame():
Expand All @@ -121,7 +124,7 @@ def test_get_brightest_frame():
tsdata[1, 1, idx] = 2.0

# Make sure function returns the right frame
ts = p2p.utils.TimeSeries(1, tsdata)
ts = utils.TimeSeries(1, tsdata)
brightest = p2p.get_brightest_frame(ts)
npt.assert_equal(brightest.data.max(), tsdata.max())
npt.assert_equal(brightest.data, tsdata[:, :, idx])
51 changes: 2 additions & 49 deletions pulse2percept/tests/test_files.py
@@ -1,7 +1,6 @@
import numpy as np
import numpy.testing as npt
import pytest
import os
try:
# Python 3
from unittest import mock
Expand All @@ -15,8 +14,8 @@
except ImportError:
pass

from pulse2percept import files
from pulse2percept import utils
from .. import files
from .. import utils


def test_set_skvideo_path():
Expand Down Expand Up @@ -195,52 +194,6 @@ def test_save_video_sidebyside():
'invalid.avi')


def test_savemoviefiles():
# This function is deprecated

if os.name != 'nt':
# If not on Windows, this should break
with pytest.raises(OSError):
files.savemoviefiles('invalid.avi', np.zeros(10), path='./')
else:
# Trigger an import error
with mock.patch.dict("sys.modules", {"PIL": {}}):
with pytest.raises(ImportError):
files.savemoviefiles('invalid.avi', np.zeros(10), path='./')

# smoke test
with pytest.warns(UserWarning):
files.savemoviefiles('invalid.avi', np.zeros(10), path='./')


def test_npy2movie():
# This function is deprecated

if os.name != 'nt':
# If not on Windows, this should break
with pytest.raises(OSError):
files.npy2movie("invalid.avi", np.zeros(10), rate=30)
else:
# Trigger an import error
with mock.patch.dict("sys.modules", {"PIL": {}}):
with pytest.raises(ImportError):
files.npy2movie("invalid.avi", np.zeros(10), rate=30)

# smoke test
with pytest.raises(UserWarning):
files.npy2movie("invalid.avi", np.zeros(10), rate=30)


def test_scale():
# This function is deprecated
inarray = np.random.rand(100)
for newmin in [0.0, -0.5]:
for newmax in [1.0, 10.0]:
scaled = files.scale(inarray, newmin=newmin, newmax=newmax)
npt.assert_almost_equal(scaled.min(), newmin)
npt.assert_almost_equal(scaled.max(), newmax)


def test_find_files_like():
# Not sure how to check a valid pattern match, because we
# don't know in which directory the test suite is
Expand Down

0 comments on commit e4ee165

Please sign in to comment.