Skip to content

Commit

Permalink
Merge 44004b3 into 2a98441
Browse files Browse the repository at this point in the history
  • Loading branch information
legouee committed Nov 21, 2017
2 parents 2a98441 + 44004b3 commit dcc8f8c
Show file tree
Hide file tree
Showing 4 changed files with 178 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
119 changes: 119 additions & 0 deletions pyNN/nest/electrodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""
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 = []
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 @@ -172,4 +172,3 @@ class NoisyCurrentSource(NestCurrentSource, electrodes.NoisyCurrentSource):
('dt', 'dt')
)
nest_name = 'noise_generator'

57 changes: 57 additions & 0 deletions test/system/test_nest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
except ImportError:
have_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 +191,56 @@ 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*1000, std=0.1*1000, start=50.0, stop=450.0, dt=0.1)

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

0 comments on commit dcc8f8c

Please sign in to comment.