Skip to content

Commit b3d9791

Browse files
committed
parameterize test, single file
1 parent b58cb36 commit b3d9791

File tree

2 files changed

+43
-142
lines changed

2 files changed

+43
-142
lines changed

testsuite/pytests/sli2py_neurons/test_iaf_psc_exp_ps.py

Lines changed: 0 additions & 97 deletions
This file was deleted.

testsuite/pytests/sli2py_neurons/test_iaf_psc_exp_ps_lossless.py renamed to testsuite/pytests/sli2py_neurons/test_iaf_psc_exp_ps_neurons.py

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# test_iaf_psc_exp_ps_lossless.py
3+
# test_iaf_psc_exp_ps_neurons.py
44
#
55
# This file is part of NEST.
66
#
@@ -20,19 +20,13 @@
2020
# along with NEST. If not, see <http://www.gnu.org/licenses/>.
2121

2222
"""
23-
Synopsis: (test_iaf_psc_exp_ps_lossless) run -> compares response to current step with analytical
24-
solution and tests lossless spike detection
23+
Synopsis: (test_iaf_psc_exp_ps_neurons) run -> compares response to current step with analytical
24+
solution for both iaf_psc_exp_ps and iaf_psc_exp_ps_lossless and tests lossless spike
25+
detection for iaf_psc_exp_ps_lossless.
2526
26-
Description:
27-
test_iaf_psc_exp_ps_lossless.py is an overall test of the iaf_psc_exp_ps_lossless model connected
28-
to some useful devices.
29-
30-
The first part of this test is exactly the same as test_iaf_psc_exp_ps,
31-
demonstrating the numerical equivalency of both models in usual conditions.
32-
The only difference between the models, which is tested in the second part,
33-
is the detection of double threshold crossings during a simulation step
34-
(so the membrane potential is again below V_th at the end of the step)
35-
by the lossless model.
27+
In the first part of the test, a DC current is injected into the neuron using a current generator
28+
device. The membrane potential is recorder, and compared to the expected analytical solution,
29+
with a spike happening off-grid.
3630
3731
The second part tests whether the lossless spike detection algorithm [1] is
3832
working correctly.
@@ -53,15 +47,14 @@
5347
regions_algorithm.py which they used to generate Fig. 6. Here you can adjust the
5448
parameters as wished and obtain the respective regions.
5549
56-
5750
References:
5851
[1] Krishnan J, Porta Mana P, Helias M, Diesmann M and Di Napoli E
5952
(2018) Perfect Detection of Spikes in the Linear Sub-threshold
6053
Dynamics of Point Neurons. Front. Neuroinform. 11:75.
6154
doi: 10.3389/fninf.2017.00075
6255
6356
Author: Jeyashree Krishnan, 2017, and Christian Keup, 2018
64-
SeeAlso: test_iaf_psc_exp, test_iaf_psc_exp_ps
57+
SeeAlso: test_iaf_psc_exp
6558
"""
6659

6760
import nest
@@ -70,34 +63,9 @@
7063
import pytest
7164

7265

73-
def test_precise_spiking_dc_input():
74-
dt = 0.1
75-
dc_amp = 1000.0
76-
77-
nest.ResetKernel()
78-
nest.set(resolution=dt, local_num_threads=1)
79-
80-
dc_gen = nest.Create("dc_generator", {"amplitude": dc_amp})
81-
nrn = nest.Create("iaf_psc_exp_ps_lossless", 1)
82-
vm = nest.Create("voltmeter", {"interval": 0.1})
83-
84-
syn_spec = {"synapse_model": "static_synapse", "weight": 1.0, "delay": dt}
85-
nest.Connect(dc_gen, nrn, syn_spec=syn_spec)
86-
nest.Connect(vm, nrn, syn_spec=syn_spec)
87-
88-
nest.Simulate(8.0)
89-
90-
times = vm.get("events", "times")
91-
times -= dt # account for delay to multimeter
92-
93-
tau_m = nrn.get("tau_m")
94-
R = tau_m / nrn.get("C_m")
95-
theta = nrn.get("V_th")
96-
E_L = nrn.get("E_L")
97-
98-
# array for analytical solution
66+
def compute_analytical_solution(times, theta, V_reset, t_ref, E_L, tau_m, R, dc_amp, dt):
9967
V_m_analytical = np.empty_like(times)
100-
V_m_analytical[:] = nrn.get("E_L")
68+
V_m_analytical[:] = E_L
10169

10270
# first index for which the DC current is received by neuron.
10371
# DC current will be integrated from this time step
@@ -121,13 +89,44 @@ def test_precise_spiking_dc_input():
12189
# set refractory potential
12290
# first index after spike, offset by time at which DC current arrives
12391
crossing_ind = int(exact_spiketime // dt + 1) + start_index
124-
num_ref = int(nrn.get("t_ref") / dt)
125-
V_m_analytical[crossing_ind : crossing_ind + num_ref] = nrn.get("V_reset")
92+
num_ref = int(t_ref / dt)
93+
V_m_analytical[crossing_ind : crossing_ind + num_ref] = V_reset
12694

12795
# rise after refractory period
12896
num_inds = len(times) - crossing_ind - num_ref
12997
V_m_analytical[crossing_ind + num_ref :] = vm_soln_offset[:num_inds]
98+
return V_m_analytical
99+
100+
101+
@pytest.mark.parametrize("model", ["iaf_psc_exp_ps", "iaf_psc_exp_ps_lossless"])
102+
def test_iaf_psc_exp_ps_dc_input(model):
103+
dt = 0.1
104+
dc_amp = 1000.0
105+
nest.ResetKernel()
106+
nest.set(resolution=dt, local_num_threads=1)
130107

108+
dc_gen = nest.Create("dc_generator", {"amplitude": dc_amp})
109+
nrn = nest.Create(model, 1)
110+
vm = nest.Create("voltmeter", {"interval": 0.1})
111+
112+
syn_spec = {"synapse_model": "static_synapse", "weight": 1.0, "delay": dt}
113+
nest.Connect(dc_gen, nrn, syn_spec=syn_spec)
114+
nest.Connect(vm, nrn, syn_spec=syn_spec)
115+
116+
nest.Simulate(8.0)
117+
118+
times = vm.get("events", "times")
119+
times -= dt # account for delay to multimeter
120+
121+
tau_m = nrn.get("tau_m")
122+
R = tau_m / nrn.get("C_m")
123+
theta = nrn.get("V_th")
124+
E_L = nrn.get("E_L")
125+
V_reset = nrn.get("V_reset")
126+
t_ref = nrn.get("t_ref")
127+
128+
V_m_analytical = compute_analytical_solution(times, theta, V_reset, t_ref, E_L, tau_m, R, dc_amp, dt)
129+
# array for analytical solution
131130
nptest.assert_array_almost_equal(V_m_analytical, vm.get("events", "V_m"))
132131

133132

@@ -190,7 +189,6 @@ def test_lossless_spike_detection():
190189
time_nospike = sr_nospike.events["times"]
191190
time_missingspike = sr_missingspike.events["times"]
192191
time_spike = sr_spike.events["times"]
193-
print(time_nospike)
194192
assert len(time_nospike) == 0
195193
assert time_missingspike == pytest.approx(4.01442)
196194
assert time_spike == pytest.approx(4.00659)

0 commit comments

Comments
 (0)