Skip to content

Commit

Permalink
Merge 40377cd into 35fd89f
Browse files Browse the repository at this point in the history
  • Loading branch information
legouee committed Nov 13, 2017
2 parents 35fd89f + 40377cd commit 6d1cc17
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 1 deletion.
2 changes: 2 additions & 0 deletions pyNN/nest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import logging

from pyNN.nest.cells import NativeCellType, native_cell_type
# Issue 506
from pyNN.nest.electrodes import NativeElectrodeType, native_electrode_type
from pyNN.nest.synapses import NativeSynapseType, native_synapse_type
from pyNN.nest.standardmodels.cells import *
from pyNN.nest.connectors import *
Expand Down
120 changes: 120 additions & 0 deletions pyNN/nest/electrodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""
Definition of NativeElectrodeType class for NEST.
"""

import numpy
import nest
from pyNN.standardmodels import electrodes, build_translations, StandardCurrentSource
from pyNN.common import Population, PopulationView, Assembly
from pyNN.parameters import ParameterSpace, Sequence
from pyNN.nest.simulator import state
from pyNN.nest.standardmodels.electrodes import NestCurrentSource
from pyNN.models import BaseCellType
from pyNN.nest.cells import NativeCellType
from pyNN.nest.cells import get_receptor_types
from pyNN.nest.cells import get_recordables
from . import conversion


def get_defaults(model_name):
valid_types = (int, float, Sequence)
defaults = nest.GetDefaults(model_name)
variables = defaults.get('recordables', [])
ignore = ['archiver_length', 'available', 'Ca', 'capacity', 'elementsize',
'frozen', 'instantiations', 'local', 'model', 'needs_prelim_update',
'recordables', 'state', 't_spike', 'tau_minus', 'tau_minus_triplet',
'thread', 'vp', 'receptor_types', 'events', 'global_id',
'element_type', 'type', 'type_id', 'has_connections', 'n_synapses',
'thread_local_id', 'node_uses_wfr', 'supports_precise_spikes',
'synaptic_elements'
]
default_params = {}
default_initial_values = {}
for name, value in defaults.items():
if name in variables:
default_initial_values[name] = value
return default_params, default_initial_values

# Native model non standard
def native_electrode_type(model_name):
"""
Return a new NativeElectrodeType subclass.
"""
assert isinstance(model_name, str)
default_parameters, default_initial_values = get_defaults(model_name)
receptor_types = get_receptor_types(model_name) # get_receptor_types imported from nest.cells.py
return type(model_name,
(NativeElectrodeType,),
{'nest_model': model_name,
'default_parameters': default_parameters,
'default_initial_values': default_initial_values,
'injectable': ("V_m" in default_initial_values),
'nest_name': {"on_grid": model_name, "off_grid": model_name},
})


# Should be usable with any NEST current generator
class NativeElectrodeType(NestCurrentSource):

_is_computed = True
_is_playable = True

def __init__(self, **parameters):
self._device = nest.Create(self)
self.cell_list = []
self.phase_given = 0.0 # required for PR #502
parameter_space = ParameterSpace(self.default_parameters,
self.get_schema(),
shape=(1,))
parameter_space.update(**parameters)
self.set_native_parameters(parameter_space)

def get_native_electrode_type(self):
# Call to the function native_electrode_type
return nest.GetDefaults(self.nest_model)["native_electrode_type"][name]

def get_receptor_type(self, name):
return nest.GetDefaults(self.nest_model)["receptor_types"][name]

def inject_into(self, cells):
# Call to the function inject_into from NestCurrentSource
super(NativeElectrodeType,self).inject_into([cells])

def _generate(self):
self.times = numpy.arange(self.start, self.stop, max(self.dt, simulator.state.dt))
self.times = numpy.append(self.times, self.stop)
self.amplitudes = self.mean + self.stdev * numpy.random.randn(len(self.times))
self.amplitudes[-1] = 0.0

def set_native_parameters(self, parameters):
parameters.evaluate(simplify=True)
for key, value in parameters.items():
if key == "amplitude_values":
assert isinstance(value, Sequence)
times = self._delay_correction(parameters["amplitude_times"].value)
amplitudes = value.value
ctr = next((i for i,v in enumerate(times) if v > state.dt), len(times)) - 1
if ctr >= 0:
times[ctr] = state.dt
times = times[ctr:]
amplitudes = amplitudes[ctr:]
for ind in range(len(times)):
times[ind] = self._round_timestamp(times[ind], state.dt)
nest.SetStatus(self._device, {key: amplitudes,
'amplitude_times': times})
elif key in ("start", "stop"):
nest.SetStatus(self._device, {key: self._delay_correction(value)})
#For NativeElectrodeType class
if key == "start" and type(self).__name__ == "NativeElectrodeType":
self._phase_correction(self.start, self.frequency, self.phase_given)
elif key == "frequency":
nest.SetStatus(self._device, {key: value})
self._phase_correction(self.start, self.frequency, self.phase_given)
elif key == "phase":
self.phase_given = value
self._phase_correction(self.start, self.frequency, self.phase_given)

elif not key == "amplitude_times":
nest.SetStatus(self._device, {key: value})
self.default_parameters[key] = value

1 change: 0 additions & 1 deletion pyNN/nest/standardmodels/electrodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,3 @@ class NoisyCurrentSource(NestCurrentSource, electrodes.NoisyCurrentSource):
('dt', 'dt')
)
nest_name = 'noise_generator'

65 changes: 65 additions & 0 deletions test/system/test_nest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@
except ImportError:
have_nest = False

# Issue 506
try:
import pyNN.nest as sim
import nest
except ImportError:
nest = False

try:
import unittest2 as unittest
except ImportError:
import unittest
from numpy.testing import assert_array_equal, assert_array_almost_equal


def test_scenarios():
for scenario in registry:
Expand Down Expand Up @@ -185,5 +198,57 @@ def test_tsodyks_markram_synapse():
assert_arrays_equal(tau_psc, numpy.arange(0.2, 0.7, 0.1))


# Issue 506
def test_ticket506():
""" Test of NativeElectrodeType class """
if not have_nest:
raise SkipTest
sim = pyNN.nest
sim.setup()
p1 = sim.Population(5, sim.IF_curr_exp(i_offset=0.1, v_thresh=-55.0, tau_refrac=5.0))
p1.record('v')
# Values for parameters
mean = 0.55
stdev=0.1
start=50.0
stop=450.0
# sim.native_electrode_type
electrode_type = sim.native_electrode_type('noise_generator')
noise = electrode_type(mean=mean*1000, std=stdev*1000, start=start, stop=stop, dt=0.1)
noiseElectrodeType = noise.inject_into(p1[0])
# sim.DCSource
steady = sim.DCSource(amplitude=mean, start=start, stop=stop)
noiseSteady = p1[1].inject(steady)
# sim.NoisyCurrentSource with dt=1.0
noise2 = sim.NoisyCurrentSource(mean=mean, stdev=stdev, start=start, stop=stop, dt=1.0)
noiseNoisyCurrentSource2 = p1[2].inject(noise2)
# sim.NoisyCurrentSource with dt=5
noise3 = sim.NoisyCurrentSource(mean=mean, stdev=stdev, start=start, stop=stop, dt=5)
noiseNoisyCurrentSource3 = p1[3].inject(noise3)
# sim.NoisyCurrentSource with dt=10
noise4 = sim.NoisyCurrentSource(mean=mean, stdev=stdev, start=start, stop=stop, dt=10)
noiseNoisyCurrentSource4 = p1[4].inject(noise4)

sim.run(500)

assert noiseElectrodeType == noiseSteady
assert noiseElectrodeType == noiseNoisyCurrentSource2
assert noiseElectrodeType == noiseNoisyCurrentSource3
assert noiseElectrodeType == noiseNoisyCurrentSource4


# Test native_electrode class
@unittest.skipUnless(nest, "Requires NEST")
class TestPopulation(unittest.TestCase):

def setUp(self):
sim.setup()
self.p = sim.Population(5, sim.IF_curr_exp(i_offset=0.1, v_thresh=-55.0, tau_refrac=5.0))

def test_create_native(self):
electrode_type = sim.native_electrode_type('noise_generator')
noise = electrode_type(mean=0.55, stdev=0.1, start=50.0, stop=450.0, dt=0.1)


if __name__ == '__main__':
data = test_random_seeds()

0 comments on commit 6d1cc17

Please sign in to comment.