Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit e8eeecb

Browse files
author
Jaquier Aurélien Tristan
committed
Merge branch 'lfpy' of https://github.com/alejoe91/BluePyOpt into cleaning
2 parents f785619 + 1c60a0c commit e8eeecb

15 files changed

+865
-4
lines changed

bluepyopt/ephys/objectives.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def __str__(self):
8585
"""String representation"""
8686

8787
return '( %s )' % self.features[0]
88-
88+
8989

9090
class SingletonWeightObjective(EFeatureObjective):
9191

bluepyopt/ephys/parameters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ class NrnPointProcessParameter(NrnParameter, DictMixin):
252252

253253
"""Parameter of a section"""
254254
SERIALIZED_FIELDS = ('name', 'value', 'frozen', 'bounds', 'param_name',
255-
'value_scaler', 'locations', 'param_name',
256-
'param_dependencies')
255+
'value_scaler', 'locations', 'param_name',
256+
'param_dependancies')
257257

258258
def __init__(
259259
self,

bluepyopt/ephys/parameterscalers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def __str__(self):
9292
class NrnSegmentSectionDistanceScaler(ParameterScaler, DictMixin):
9393

9494
"""Scaler based on distance from soma"""
95-
SERIALIZED_FIELDS = ('name', 'comment', 'distribution',
95+
SERIALIZED_FIELDS = ('name', 'comment', 'distribution',
9696
"distribution", "dist_param_names",
9797
"ref_sec", "ref_location",)
9898

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
"""Tests for ephys.extra_features_utils"""
2+
3+
import os
4+
5+
import numpy
6+
import pytest
7+
8+
from bluepyopt import ephys
9+
10+
11+
testdata_dir = os.path.join(
12+
os.path.dirname(os.path.abspath(__file__)), 'testdata'
13+
)
14+
waveforms_fpath = os.path.join(testdata_dir, 'mean_waveforms.dat')
15+
waveforms = numpy.loadtxt(waveforms_fpath)
16+
waveform = numpy.array([waveforms[0]])
17+
sampling_freq = 10000
18+
19+
20+
@pytest.mark.unit
21+
def test_peak_to_valley():
22+
"""ephys.extra_features_utils: Test peak_to_valley"""
23+
ptv = ephys.extra_features_utils.peak_to_valley(waveform, sampling_freq)
24+
assert len(ptv) == 1
25+
assert ptv[0] == pytest.approx(0.0013)
26+
27+
28+
@pytest.mark.unit
29+
def test_peak_trough_ratio():
30+
"""ephys.extra_features_utils: Test peak_trough_ratio"""
31+
ptratio = ephys.extra_features_utils.peak_trough_ratio(waveform)
32+
assert len(ptratio) == 1
33+
print(ptratio)
34+
assert ptratio[0] == pytest.approx(0.53804035)
35+
36+
37+
@pytest.mark.unit
38+
def test_halfwidth():
39+
"""ephys.extra_features_utils: Test halfwidth"""
40+
ret = ephys.extra_features_utils.halfwidth(waveform, sampling_freq, True)
41+
assert len(ret) == 3
42+
43+
hw = ephys.extra_features_utils.halfwidth(waveform, sampling_freq)
44+
assert len(hw) == 1
45+
assert hw[0] == pytest.approx(0.0015)
46+
47+
48+
@pytest.mark.unit
49+
def test_repolarization_slope():
50+
"""ephys.extra_features_utils: Test repolarization_slope"""
51+
ret = ephys.extra_features_utils.repolarization_slope(
52+
waveform, sampling_freq, True
53+
)
54+
assert len(ret) == 2
55+
56+
rslope = ephys.extra_features_utils.repolarization_slope(
57+
waveform, sampling_freq
58+
)
59+
assert len(rslope) == 1
60+
assert rslope[0] == pytest.approx(73.12572131)
61+
62+
63+
@pytest.mark.unit
64+
def test_recovery_slope():
65+
"""ephys.extra_features_utils: Test recovery_slope"""
66+
window = 0.7
67+
rslope = ephys.extra_features_utils.recovery_slope(
68+
waveform, sampling_freq, window=window
69+
)
70+
assert len(rslope) == 1
71+
assert rslope[0] == pytest.approx(-3.63355521)
72+
73+
74+
@pytest.mark.unit
75+
def test_peak_image():
76+
"""ephys.extra_features_utils: Test peak_image"""
77+
rel_peaks = ephys.extra_features_utils.peak_image(
78+
waveforms, sign="negative"
79+
)
80+
assert len(rel_peaks) == 209
81+
assert rel_peaks[0] == pytest.approx(0.06084468)
82+
83+
rel_peaks = ephys.extra_features_utils.peak_image(
84+
waveforms, sign="positive"
85+
)
86+
assert len(rel_peaks) == 209
87+
assert rel_peaks[0] == pytest.approx(0.10850117)
88+
89+
90+
@pytest.mark.unit
91+
def test_relative_amplitude():
92+
"""ephys.extra_features_utils: Test relative_amplitude"""
93+
rel_amp = ephys.extra_features_utils.relative_amplitude(
94+
waveforms, sign="negative"
95+
)
96+
assert len(rel_amp) == 209
97+
assert rel_amp[0] == pytest.approx(0.09513392)
98+
99+
rel_amp = ephys.extra_features_utils.relative_amplitude(
100+
waveforms, sign="positive"
101+
)
102+
assert len(rel_amp) == 209
103+
assert rel_amp[0] == pytest.approx(0.2135929)
104+
105+
106+
@pytest.mark.unit
107+
def test_peak_time_diff():
108+
"""ephys.extra_features_utils: Test peak_time_diff"""
109+
peak_t = ephys.extra_features_utils.peak_time_diff(
110+
waveforms, sampling_freq, sign="negative"
111+
)
112+
assert len(peak_t) == 209
113+
assert peak_t[0] == pytest.approx(0.0009)
114+
115+
peak_t = ephys.extra_features_utils.peak_time_diff(
116+
waveforms, sampling_freq, sign="positive"
117+
)
118+
assert len(peak_t) == 209
119+
assert peak_t[0] == pytest.approx(0.0007)
120+
121+
122+
@pytest.mark.unit
123+
def test__get_trough_and_peak_idx():
124+
"""ephys.extra_features_utils: Test _get_trough_and_peak_idx"""
125+
t_idx, p_idx = ephys.extra_features_utils._get_trough_and_peak_idx(
126+
waveform
127+
)
128+
assert t_idx == 102
129+
assert p_idx == 115
130+
131+
132+
@pytest.mark.unit
133+
def test_calculate_features():
134+
"""ephys.extra_features_utils: Test calculate_features"""
135+
feats = ephys.extra_features_utils.calculate_features(
136+
waveforms, sampling_freq
137+
)
138+
for feature_name in ephys.extra_features_utils.all_1D_features:
139+
assert feature_name in feats

bluepyopt/tests/test_ephys/test_features.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,72 @@ def test_eFELFeature_serialize():
246246
assert isinstance(deserialized, efeatures.eFELFeature)
247247
assert deserialized.stim_start == 700
248248
assert deserialized.recording_names == recording_names
249+
250+
251+
@pytest.mark.unit
252+
def test_extraFELFeature():
253+
"""ephys.efeatures: Testing extraFELFeature calculation"""
254+
import pandas as pd
255+
256+
somatic_recording_name = 'soma_response'
257+
recording_names = {'': 'lfp_response'}
258+
channel_ids = 0
259+
extrafel_feature_name = 'halfwidth'
260+
name = 'test_extraFELFeature'
261+
stim_start = 400
262+
stim_end = 1750
263+
fs = 10
264+
ms_cut = [10, 25]
265+
266+
# load responses from file
267+
testdata_dir = os.path.join(
268+
os.path.dirname(os.path.abspath(__file__)), 'testdata'
269+
)
270+
resp_fname = os.path.join(testdata_dir, 'lfpy_response_with_soma.pkl')
271+
responses_lst = pd.read_pickle(resp_fname)
272+
responses = {
273+
somatic_recording_name: responses_lst[0][1],
274+
recording_names['']: responses_lst[0][0],
275+
}
276+
277+
# compute for all electrodes
278+
efeature = efeatures.extraFELFeature(
279+
name=name,
280+
extrafel_feature_name=extrafel_feature_name,
281+
somatic_recording_name=somatic_recording_name,
282+
recording_names=recording_names,
283+
channel_ids=None,
284+
exp_mean=0.001,
285+
exp_std=0.001,
286+
stim_start=stim_start,
287+
stim_end=stim_end,
288+
fs=fs,
289+
ms_cut=ms_cut
290+
)
291+
292+
ret = efeature.calculate_feature(responses, raise_warnings=True)
293+
assert len(ret) == 209
294+
295+
# compute for 1 electrode
296+
efeature = efeatures.extraFELFeature(
297+
name=name,
298+
extrafel_feature_name=extrafel_feature_name,
299+
somatic_recording_name=somatic_recording_name,
300+
recording_names=recording_names,
301+
channel_ids=channel_ids,
302+
exp_mean=0.001,
303+
exp_std=0.001,
304+
stim_start=stim_start,
305+
stim_end=stim_end,
306+
fs=fs,
307+
ms_cut=ms_cut
308+
)
309+
310+
ret = efeature.calculate_feature(responses, raise_warnings=True)
311+
numpy.testing.assert_almost_equal(ret, 0.0015)
312+
313+
score = efeature.calculate_score(responses)
314+
numpy.testing.assert_almost_equal(score, 0.5)
315+
316+
assert efeature.name == name
317+
assert extrafel_feature_name in str(efeature)

bluepyopt/tests/test_ephys/test_models.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,17 @@ def test_CellModel_destroy():
180180
assert 0 == len(sim.neuron.h.CellModel_destroy)
181181

182182

183+
@pytest.mark.unit
184+
def test_lfpy_create_empty_template():
185+
"""ephys.models: Test creation of lfpy empty template"""
186+
template_name = 'FakeTemplate'
187+
hoc_template = ephys.models.LFPyCellModel.create_empty_template(
188+
template_name
189+
)
190+
sim.neuron.h(hoc_template)
191+
assert hasattr(sim.neuron.h, template_name)
192+
193+
183194
@pytest.mark.unit
184195
def test_lfpycellmodel():
185196
"""ephys.models: Test LFPyCellModel class"""
@@ -197,6 +208,97 @@ def test_lfpycellmodel():
197208
assert isinstance(model, ephys.models.LFPyCellModel)
198209

199210

211+
@pytest.mark.unit
212+
def test_lfpycellmodel_namecheck():
213+
"""ephys.models: Test LFPyCellModel class name checking"""
214+
215+
# Test valid name
216+
for name in ['test3', 'test_3']:
217+
ephys.models.LFPyCellModel(name, morph=test_morph, mechs=[])
218+
219+
# Test invalid names
220+
for name in ['3test', '', 'test$', 'test 3']:
221+
with pytest.raises(TypeError):
222+
ephys.models.LFPyCellModel(name, morph=test_morph, mechs=[])
223+
224+
225+
@pytest.mark.unit
226+
def test_load_lfpy_hoc_template():
227+
"""ephys.models: Test loading of hoc template with lfpy cell"""
228+
229+
template_name = 'test_load_hoc'
230+
hoc_string = ephys.models.LFPyCellModel.create_empty_template(
231+
template_name
232+
)
233+
ephys.models.HocCellModel.load_hoc_template(sim, hoc_string)
234+
assert hasattr(sim.neuron.h, template_name)
235+
236+
237+
@pytest.mark.unit
238+
def test_LFPyCellModel_create_empty_cell():
239+
"""ephys.models: Test create_empty_cell with lfpy cell"""
240+
template_name = 'create_empty_cell'
241+
cell = ephys.models.LFPyCellModel.create_empty_cell(template_name, sim)
242+
assert callable(cell)
243+
assert hasattr(sim.neuron.h, template_name)
244+
245+
246+
@pytest.mark.unit
247+
def test_LFPyCellModel_create_hoc():
248+
"""ephys.models: Test create_hoc with lfpy cell"""
249+
250+
morph0 = ephys.morphologies.NrnFileMorphology(
251+
simple_morphology_path,
252+
do_replace_axon=True
253+
)
254+
255+
cell_model = ephys.models.LFPyCellModel(
256+
'LFPyCellModel',
257+
morph=morph0,
258+
mechs=[],
259+
params=[]
260+
)
261+
262+
hoc_string = cell_model.create_hoc({})
263+
assert 'begintemplate LFPyCellModel' in hoc_string
264+
assert 'proc replace_axon()' in hoc_string
265+
cell_model_hoc = ephys.models.HocCellModel(
266+
'CellModelHOC',
267+
simple_morphology_path,
268+
hoc_string=hoc_string)
269+
270+
assert isinstance(cell_model_hoc, ephys.models.HocCellModel)
271+
272+
273+
@pytest.mark.unit
274+
def test_LFPyCellModel_destroy():
275+
"""ephys.models: Test LFPyCellModel destroy"""
276+
morph0 = ephys.morphologies.NrnFileMorphology(simple_morphology_path)
277+
cell_model0 = ephys.models.LFPyCellModel(
278+
'LFPyCellModel_destroy', morph=morph0, mechs=[], params=[]
279+
)
280+
morph1 = ephys.morphologies.NrnFileMorphology(simple_morphology_path)
281+
cell_model1 = ephys.models.LFPyCellModel(
282+
'LFPyCellModel_destroy', morph=morph1, mechs=[], params=[]
283+
)
284+
285+
assert not hasattr(sim.neuron.h, 'LFPyCellModel_destroy')
286+
287+
cell_model0.instantiate(sim=sim)
288+
assert hasattr(sim.neuron.h, 'LFPyCellModel_destroy')
289+
assert 1 == len(sim.neuron.h.LFPyCellModel_destroy)
290+
291+
cell_model1.instantiate(sim=sim)
292+
assert 2 == len(sim.neuron.h.LFPyCellModel_destroy)
293+
294+
# make sure cleanup works
295+
cell_model0.destroy(sim=sim)
296+
assert 1 == len(sim.neuron.h.LFPyCellModel_destroy)
297+
298+
cell_model1.destroy(sim=sim)
299+
assert 0 == len(sim.neuron.h.LFPyCellModel_destroy)
300+
301+
200302
@pytest.mark.unit
201303
def test_metaparameter():
202304
"""ephys.models: Test model with MetaParameter"""

0 commit comments

Comments
 (0)