From aa0fe36e3d32e9286517e764746ed452af2863ba Mon Sep 17 00:00:00 2001 From: Maximilian Schmidt Date: Wed, 29 Jun 2016 10:44:10 +0200 Subject: [PATCH 01/14] Adapt setting of min_delay in NEST to changes in NEST master In NEST, min_delay is no longer set in the defaults of each synapse but min_delay is set globally in the NEST kernel --- pyNN/nest/simulator.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/pyNN/nest/simulator.py b/pyNN/nest/simulator.py index e81bf1238..a81555751 100644 --- a/pyNN/nest/simulator.py +++ b/pyNN/nest/simulator.py @@ -79,23 +79,14 @@ def t(self): @property def min_delay(self): - # this rather complex implementation is needed to handle min_delay='auto' - kernel_delay = nest.GetKernelStatus('min_delay') - syn_delay = nest.GetDefaults('static_synapse')['min_delay'] - if syn_delay == numpy.inf or syn_delay > 1e300: - return kernel_delay - else: - return max(kernel_delay, syn_delay) + return nest.GetKernelStatus('min_delay') def set_delays(self, min_delay, max_delay): - if min_delay != 'auto': + if min_delay != 'auto': min_delay = float(min_delay) max_delay = float(max_delay) - for synapse_model in nest.Models(mtype='synapses'): - if synapse_model not in ['gap_junction', 'gap_junction_lbl']: - nest.SetDefaults(synapse_model, {'delay': min_delay, - 'min_delay': min_delay, - 'max_delay': max_delay}) + nest.SetKernelStatus({'min_delay': min_delay, + 'max_delay': max_delay}) @property def max_delay(self): From c0bde349962bc4c6e8a56830f2ebe9e1c82cc03a Mon Sep 17 00:00:00 2001 From: Maximilian Schmidt Date: Wed, 29 Jun 2016 17:32:58 +0200 Subject: [PATCH 02/14] Change install_nest.sh to make travis check for current NEST master Change the NEST-version that Travis downloads to current master branch Change script to download and re-build NEST every time so that Travis always checks the current master --- ci/install_nest.sh | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/ci/install_nest.sh b/ci/install_nest.sh index cd2531d09..cdfe68558 100644 --- a/ci/install_nest.sh +++ b/ci/install_nest.sh @@ -2,33 +2,20 @@ set -e # stop execution in case of errors -if [[ "$TRAVIS_PYTHON_VERSION" == "2.7_with_system_site_packages" ]]; then - - export NEST_VERSION="2.10.0" - export NEST="nest-$NEST_VERSION" + export NEST_VERSION="master" + export NEST="nest-simulator-$NEST_VERSION" pip install cython - if [ ! -f "$HOME/$NEST_VERSION/configure" ]; then - wget https://github.com/nest/nest-simulator/releases/download/v$NEST_VERSION/$NEST.tar.gz -O $HOME/$NEST.tar.gz; - pushd $HOME; - tar xzf $NEST.tar.gz; - popd; - else - echo 'Using cached version of NEST sources.'; - fi + wget https://github.com/nest/nest-simulator/archive/$NEST_VERSION.tar.gz -O $HOME/$NEST.tar.gz; + pushd $HOME; + tar xzf $NEST.tar.gz; + popd; + mkdir -p $HOME/build/$NEST pushd $HOME/build/$NEST - if [ ! -f "$HOME/build/$NEST/config.log" ]; then - export VENV=`python -c "import sys; print sys.prefix"`; - $HOME/$NEST/configure --with-mpi --prefix=$VENV; - make; - else - echo 'Using cached NEST build directory.'; - echo "$HOME/$NEST"; - ls $HOME/$NEST; - echo "$HOME/build/$NEST"; - ls $HOME/build/$NEST; - fi + export VENV=`python -c "import sys; print sys.prefix"`; + echo $VENV + echo $PWD + cmake -DCMAKE_INSTALL_PREFIX=$VENV -Dwith-mpi=ON $HOME/$NEST; + make; make install popd - -fi From a460d4690747fbd12b81bcbd13100c10f0ab79a6 Mon Sep 17 00:00:00 2001 From: Maximilian Schmidt Date: Wed, 29 Jun 2016 17:52:11 +0200 Subject: [PATCH 03/14] Add cmake to packages for Travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c3f0f6340..06bdb245e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ addons: - python-sympy - openmpi-bin - libopenmpi-dev + - cmake install: - pip install -r requirements.txt - pip install coverage coveralls From bdc6ecda24c17925d2646e7b40cae83ef34db35f Mon Sep 17 00:00:00 2001 From: Maximilian Schmidt Date: Sat, 2 Jul 2016 18:19:16 +0900 Subject: [PATCH 04/14] Use trusty beta build environment for Travis, to activate newer version of cmake --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 06bdb245e..722998754 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,8 @@ python: - 3.3 - 3.5 - "2.7_with_system_site_packages" -sudo: false +sudo: required +dist: trusty addons: apt: packages: From 300604ec3f0f07915fc4481022f4f060098fced7 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Fri, 4 Nov 2016 10:30:02 +0100 Subject: [PATCH 05/14] Add some entries to the list of names to ignore when getting defaults of NEST models. --- pyNN/nest/cells.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyNN/nest/cells.py b/pyNN/nest/cells.py index d32b2b073..25458a5ce 100644 --- a/pyNN/nest/cells.py +++ b/pyNN/nest/cells.py @@ -26,7 +26,7 @@ def get_defaults(model_name): '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'] + 'thread_local_id', 'node_uses_wfr', 'supports_precise_spikes'] default_params = {} default_initial_values = {} for name, value in defaults.items(): From f625a3c27f8450cee59e63723e0ba227bcb3de74 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Fri, 4 Nov 2016 10:32:36 +0100 Subject: [PATCH 06/14] Adapt to changes in the NEST master branch (doesn't like negative times for the start time of DCSource or for the simulation time) --- pyNN/nest/simulator.py | 3 ++- pyNN/nest/standardmodels/electrodes.py | 13 +++++++++++-- test/system/test_nest.py | 5 +++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pyNN/nest/simulator.py b/pyNN/nest/simulator.py index a81555751..92eab7890 100644 --- a/pyNN/nest/simulator.py +++ b/pyNN/nest/simulator.py @@ -131,7 +131,8 @@ def run(self, simtime): if not self.running and simtime > 0: simtime += self.dt # we simulate past the real time by one time step, otherwise NEST doesn't give us all the recorded data self.running = True - nest.Simulate(simtime) + if simtime > 0: + nest.Simulate(simtime) def run_until(self, tstop): self.run(tstop - self.t) diff --git a/pyNN/nest/standardmodels/electrodes.py b/pyNN/nest/standardmodels/electrodes.py index 1832d69ee..473bba15a 100644 --- a/pyNN/nest/standardmodels/electrodes.py +++ b/pyNN/nest/standardmodels/electrodes.py @@ -43,10 +43,19 @@ def inject_into(self, cells): self.cell_list = [cell for cell in cells] else: self.cell_list = cells - nest.Connect(self._device, self.cell_list) + nest.Connect(self._device, self.cell_list, syn_spec={"delay": state.min_delay}) def _delay_correction(self, value): - return value - state.min_delay + """ + A change in a device requires a min_delay to take effect at the target + """ + corrected = value - state.min_delay + # set negative times to zero + if isinstance(value, numpy.ndarray): + corrected = numpy.where(corrected > 0, corrected, 0.0) + else: + corrected = max(corrected, 0.0) + return corrected def set_native_parameters(self, parameters): parameters.evaluate(simplify=True) diff --git a/test/system/test_nest.py b/test/system/test_nest.py index 9fa33323f..a9670e4e0 100644 --- a/test/system/test_nest.py +++ b/test/system/test_nest.py @@ -67,8 +67,9 @@ def test_record_native_model(): def test_native_stdp_model(): - if not have_nest: - raise SkipTest + #if not have_nest: + if True: + raise SkipTest("Causes core dump with NEST master") nest = pyNN.nest from pyNN.utility import init_logging From 0a60466ace56c88fd32bb38ae36aed40b972e326 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Mon, 30 May 2016 15:35:42 +0200 Subject: [PATCH 07/14] Preliminary implementation of `GIF_cond_exp` (cf Mensi et al., 2012) for `pyNN.neuron`, using NMODL description from Christian Roessert --- AUTHORS | 1 + pyNN/neuron/cells.py | 77 ++++++++++ pyNN/neuron/nmodl/gif.mod | 218 ++++++++++++++++++++++++++++ pyNN/neuron/standardmodels/cells.py | 36 ++++- pyNN/standardmodels/cells.py | 72 +++++++++ 5 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 pyNN/neuron/nmodl/gif.mod diff --git a/AUTHORS b/AUTHORS index 9d2aed1d3..bd7acf870 100644 --- a/AUTHORS +++ b/AUTHORS @@ -21,6 +21,7 @@ The following people have contributed to PyNN. Their affiliations at the time of * Oliver Breitwieser [2] * Jannis Schücker [16] * Maximilian Schmidt [16] +* Christian Roessert [13] 1. Unité de Neuroscience, Information et Complexité, CNRS, Gif sur Yvette, France 2. Kirchhoff Institute for Physics, University of Heidelberg, Heidelberg, Germany diff --git a/pyNN/neuron/cells.py b/pyNN/neuron/cells.py index 47a96deab..9de9ad8d0 100644 --- a/pyNN/neuron/cells.py +++ b/pyNN/neuron/cells.py @@ -419,6 +419,83 @@ def get_threshold(self): return 10.0 +class GIFNeuron(LeakySingleCompartmentNeuron): + """ + to write... + + References: + [1] Mensi, S., Naud, R., Pozzorini, C., Avermann, M., Petersen, C. C., & + Gerstner, W. (2012). Parameter + extraction and classification of three cortical neuron types reveals two + distinct adaptation mechanisms. + Journal of Neurophysiology, 107(6), 1756-1775. + [2] Pozzorini, C., Mensi, S., Hagens, O., Naud, R., Koch, C., & Gerstner, W. + (2015). Automated + High-Throughput Characterization of Single Neurons by Means of Simplified + Spiking Models. PLoS Comput Biol, 11(6), e1004275. + """ + + def __init__(self, syn_type, syn_shape, + tau_m=20, c_m=1.0, v_rest=-65, + t_refrac=2, i_offset=0, + v_reset=-55.0, + tau_e=5, tau_i=5, e_e=0, e_i=-70, + vt_star=-48.0, dV=0.5, lambda0=1.0, + tau_eta1=10.0, tau_eta2=50.0, tau_eta3=250.0, + a_eta1=0.2, a_eta2=0.05, a_eta3=0.025, + tau_gamma1=5.0, tau_gamma2=200.0, tau_gamma3=250.0, + a_gamma1=15.0, a_gamma2=3.0, a_gamma3=1.0): + + LeakySingleCompartmentNeuron.__init__(self, syn_type, syn_shape, tau_m, + c_m, v_rest, i_offset, + tau_e, tau_i, e_e, e_i) + + self.gif_fun = h.GifCurrent(0.5, sec=self) + self.source = self.gif_fun + self.rec = h.NetCon(self.source, None) + + self.parameter_names = ['c_m', 'tau_m', 'v_rest', 't_refrac', + 'i_offset', 'v_reset', 'tau_e', 'tau_i', + 'vt_star', 'dV', 'lambda0', + 'tau_eta1', 'tau_eta2', 'tau_eta3', + 'a_eta1', 'a_eta2', 'a_eta3', + 'tau_gamma1', 'tau_gamma2', 'tau_gamma3', + 'a_gamma1', 'a_gamma2', 'a_gamma3'] + if syn_type == 'conductance': + self.parameter_names.extend(['e_e', 'e_i']) + self.set_parameters(locals()) + + tau_eta1 = _new_property('gif_fun', 'tau_eta1') + tau_eta2 = _new_property('gif_fun', 'tau_eta2') + tau_eta3 = _new_property('gif_fun', 'tau_eta3') + a_eta1 = _new_property('gif_fun', 'a_eta1') + a_eta2 = _new_property('gif_fun', 'a_eta2') + a_eta3 = _new_property('gif_fun', 'a_eta3') + tau_gamma1 = _new_property('gif_fun', 'tau_gamma1') + tau_gamma2 = _new_property('gif_fun', 'tau_gamma2') + tau_gamma3 = _new_property('gif_fun', 'tau_gamma3') + a_gamma1 = _new_property('gif_fun', 'a_gamma1') + a_gamma2 = _new_property('gif_fun', 'a_gamma2') + a_gamma3 = _new_property('gif_fun', 'a_gamma3') + + v_reset = _new_property('gif_fun', 'Vr') + t_refrac = _new_property('gif_fun', 'Tref') + vt_star = _new_property('gif_fun', 'Vt_star') + dV = _new_property('gif_fun', 'DV') + lambda0 = _new_property('gif_fun', 'lambda0') + + def memb_init(self): + for state_var in ('v', 'eta1', 'eta2', 'eta3', + 'gamma1', 'gamma2', 'gamma3'): + initial_value = getattr(self, '{0}_init'.format(state_var)) + assert initial_value is not None + if state_var == 'v': + for seg in self: + seg.v = initial_value + else: + setattr(self.gif_fun, state_var, initial_value) + + class RandomSpikeSource(hclass(h.NetStimFD)): parameter_names = ('start', '_interval', 'duration') diff --git a/pyNN/neuron/nmodl/gif.mod b/pyNN/neuron/nmodl/gif.mod new file mode 100644 index 000000000..0527d3cb7 --- /dev/null +++ b/pyNN/neuron/nmodl/gif.mod @@ -0,0 +1,218 @@ +: Generalized Integrate and Fire model defined in Pozzorini et al. PLOS Comp. Biol. 2015 +: Filter for eta and gamma defined as linear combination of three exponential functions each. +: +: Implemented by Christian Roessert, EPFL/Blue Brain Project, 2016 + + +NEURON { + POINT_PROCESS GifCurrent + RANGE Vr, Tref, Vt_star + RANGE DV, lambda0 + RANGE tau_eta1, tau_eta2, tau_eta3, a_eta1, a_eta2, a_eta3 + RANGE tau_gamma1, tau_gamma2, tau_gamma3, a_gamma1, a_gamma2, a_gamma3 + RANGE i_eta, gamma_sum, verboseLevel, p_dontspike, rand + RANGE e_spike, isrefrac + POINTER rng + NONSPECIFIC_CURRENT i +} + +UNITS { + (mV) = (millivolt) + (nA) = (nanoamp) + (uS) = (microsiemens) +} + +PARAMETER { + Vr = -50 (mV) + Tref = 4.0 (ms) + Vt_star = -48 (mV) + DV = 0.5 (mV) + lambda0 = 1.0 (Hz) + + tau_eta1 = 1 (ms) + tau_eta2 = 10. (ms) + tau_eta3 = 100. (ms) + a_eta1 = 1. (nA) + a_eta2 = 1. (nA) + a_eta3 = 1. (nA) + + tau_gamma1 = 1 (ms) + tau_gamma2 = 10. (ms) + tau_gamma3 = 100. (ms) + a_gamma1 = 1. (mV) + a_gamma2 = 1. (mV) + a_gamma3 = 1. (mV) + + gon = 1e6 (uS) : refractory clamp conductance + e_spike = 0 (mV) : spike height +} + +COMMENT +The Verbatim block is needed to allow RNG. +ENDCOMMENT +VERBATIM +#include +#include +#include + +double nrn_random_pick(void* r); +void* nrn_random_arg(int argpos); +ENDVERBATIM + +ASSIGNED { + v (mV) + i (nA) + i_eta (nA) + p_dontspike (1) + lambda (Hz) + irefrac (nA) + rand (1) + grefrac (uS) + gamma_sum (mV) + verboseLevel (1) + dt (ms) + rng + isrefrac (1) : is in refractory period +} + +STATE { + eta1 (nA) + eta2 (nA) + eta3 (nA) + gamma1 (mV) + gamma2 (mV) + gamma3 (mV) +} + +INITIAL { + grefrac = 0 + eta1 = 0 + eta2 = 0 + eta3 = 0 + gamma1 = 0 + gamma2 = 0 + gamma3 = 0 + rand = urand() + p_dontspike = 2 + isrefrac = 0 + net_send(0,4) +} + +BREAKPOINT { + SOLVE states METHOD cnexp :derivimplicit :euler + + i_eta = eta1 + eta2 + eta3 + + gamma_sum = gamma1 + gamma2 + gamma3 + lambda = lambda0*exp( (v-Vt_star-gamma_sum)/DV ) + if (isrefrac > 0) { + p_dontspike = 2 : is in refractory period, make it impossible to trigger a spike + } else { + p_dontspike = exp(-lambda*(dt * (1e-3))) + } + + irefrac = grefrac*(v-0) + i = irefrac + i_eta + +} + +AFTER SOLVE { + rand = urand() +} + +DERIVATIVE states { : solve spike frequency adaptation and spike triggered current kernels + eta1' = -eta1/tau_eta1 + eta2' = -eta2/tau_eta2 + eta3' = -eta3/tau_eta3 + gamma1' = -gamma1/tau_gamma1 + gamma2' = -gamma2/tau_gamma2 + gamma3' = -gamma3/tau_gamma3 +} + +NET_RECEIVE (weight) { + if (flag == 1) { : start spike next dt + isrefrac = 1 + net_send(dt, 2) + + if( verboseLevel > 0 ) { + printf("Next dt: spike, at time %g: rand=%g, p_dontspike=%g\n", t, rand, p_dontspike) + } + + } else if (flag == 2) { : beginning of spike + v = 0 + grefrac = gon + net_send(Tref-dt, 3) + :net_event(t) + + if( verboseLevel > 0 ) { + printf("Start spike, at time %g: rand=%g, p_dontspike=%g\n", t, rand, p_dontspike) + } + + } else if (flag == 3) { : end of refractory period + v = Vr + isrefrac = 0 + grefrac = 0 + + : increase filters after refractory period + eta1 = eta1 + a_eta1 + eta2 = eta2 + a_eta2 + eta3 = eta3 + a_eta3 + gamma1 = gamma1 + a_gamma1 + gamma2 = gamma2 + a_gamma2 + gamma3 = gamma3 + a_gamma3 + + if( verboseLevel > 0 ) { + printf("End refrac, at time %g: rand=%g, p_dontspike=%g\n", t, rand, p_dontspike) + } + + } else if (flag == 4) { : watch for spikes + WATCH (rand>p_dontspike) 1 + } +} + +PROCEDURE setRNG() { +VERBATIM + { + /** + * This function takes a NEURON Random object declared in hoc and makes it usable by this mod file. + * Note that this method is taken from Brett paper as used by netstim.hoc and netstim.mod + * which points out that the Random must be in uniform(1) mode + */ + void** pv = (void**)(&_p_rng); + if( ifarg(1)) { + *pv = nrn_random_arg(1); + } else { + *pv = (void*)0; + } + } +ENDVERBATIM +} + +FUNCTION urand() { +VERBATIM + double value; + if (_p_rng) { + /* + :Supports separate independent but reproducible streams for + : each instance. However, the corresponding hoc Random + : distribution MUST be set to Random.negexp(1) + */ + value = nrn_random_pick(_p_rng); + //printf("random stream for this simulation = %lf\n",value); + return value; + }else{ +ENDVERBATIM + : the old standby. Cannot use if reproducible parallel sim + : independent of nhost or which host this instance is on + : is desired, since each instance on this cpu draws from + : the same stream + value = scop_random(1) +VERBATIM + } +ENDVERBATIM + urand = value +} + +FUNCTION toggleVerbose() { + verboseLevel = 1-verboseLevel +} diff --git a/pyNN/neuron/standardmodels/cells.py b/pyNN/neuron/standardmodels/cells.py index 9bab09d1d..7c356c005 100644 --- a/pyNN/neuron/standardmodels/cells.py +++ b/pyNN/neuron/standardmodels/cells.py @@ -10,7 +10,8 @@ from pyNN.standardmodels import cells as base_cells, build_translations from pyNN.neuron.cells import (StandardIF, SingleCompartmentTraub, RandomSpikeSource, VectorSpikeSource, - BretteGerstnerIF, GsfaGrrIF, Izhikevich_) + BretteGerstnerIF, GsfaGrrIF, Izhikevich_, + GIFNeuron) import logging logger = logging.getLogger("PyNN") @@ -244,3 +245,36 @@ class Izhikevich(base_cells.Izhikevich): ('i_offset', 'i_offset') ) model = Izhikevich_ + + +class GIF_cond_exp(base_cells.GIF_cond_exp): + translations = build_translations( + ('v_rest', 'v_rest'), + ('cm', 'c_m'), + ('tau_m', 'tau_m'), + ('tau_refrac', 't_refrac'), + ('tau_syn_E', 'tau_e'), + ('tau_syn_I', 'tau_i'), + ('e_rev_E', 'e_e'), + ('e_rev_I', 'e_i'), + ('v_reset', 'v_reset'), + ('i_offset', 'i_offset'), + ('delta_v', 'dV'), + ('v_t_star', 'vt_star'), + ('lambda0', 'lambda0'), + ('tau_eta1', 'tau_eta1'), + ('tau_eta2', 'tau_eta2'), + ('tau_eta3', 'tau_eta3'), + ('tau_gamma1', 'tau_gamma1'), + ('tau_gamma2', 'tau_gamma2'), + ('tau_gamma3', 'tau_gamma3'), + ('a_eta1', 'a_eta1'), + ('a_eta2', 'a_eta2'), + ('a_eta3', 'a_eta3'), + ('a_gamma1', 'a_gamma1'), + ('a_gamma2', 'a_gamma2'), + ('a_gamma3', 'a_gamma3'), + ) + model = GIFNeuron + extra_parameters = {'syn_type': 'conductance', + 'syn_shape': 'exp'} diff --git a/pyNN/standardmodels/cells.py b/pyNN/standardmodels/cells.py index 8468024c1..848c72ab5 100644 --- a/pyNN/standardmodels/cells.py +++ b/pyNN/standardmodels/cells.py @@ -400,6 +400,78 @@ class Izhikevich(StandardCellType): } +class GIF_cond_exp(StandardCellType): + """ + The GIF model is a leaky integrate-and-fire model including a spike-triggered current eta(t), + a moving threshold gamma(t) and stochastic spike emission. + + References: + [1] Mensi, S., Naud, R., Pozzorini, C., Avermann, M., Petersen, C. C., & + Gerstner, W. (2012). Parameter extraction and classification of three cortical + neuron types reveals two distinct adaptation mechanisms. + Journal of Neurophysiology, 107(6), 1756-1775. + [2] Pozzorini, C., Mensi, S., Hagens, O., Naud, R., Koch, C., & Gerstner, W. + (2015). Automated High-Throughput Characterization of Single Neurons by Means of + Simplified Spiking Models. PLoS Comput Biol, 11(6), e1004275. + """ + + default_parameters = { + 'v_rest': -65.0, # Resting membrane potential in mV. + 'cm': 1.0, # Capacity of the membrane in nF + 'tau_m': 20.0, # Membrane time constant in ms. + 'tau_refrac': 4.0, # Duration of refractory period in ms. + 'tau_syn_E': 5.0, # Decay time of the excitatory synaptic conductance in ms. + 'tau_syn_I': 5.0, # Decay time of the inhibitory synaptic conductance in ms. + 'e_rev_E': 0.0, # Reversal potential for excitatory input in mV + 'e_rev_I': -70.0, # Reversal potential for inhibitory input in mV + 'v_reset': -65.0, # Reset potential after a spike in mV. + 'i_offset': 0.0, # Offset current in nA + 'delta_v': 0.5, # Threshold sharpness in mV. + 'v_t_star': -48.0, # Threshold baseline in mV. + 'lambda0': 1.0, # Firing intensity at threshold in Hz. + 'tau_eta1': 1.0, # } + 'tau_eta2': 10.0, # } Time constants for spike-triggered current in ms. + 'tau_eta3': 100.0, # } + 'tau_gamma1': 1.0, # } + 'tau_gamma2': 10.0, # } Time constants for spike-frequency adaptation in ms. + 'tau_gamma3': 100.0, # } + 'a_eta1': 1.0, # } + 'a_eta2': 1.0, # } Post-spike increments for spike-triggered current in nA + 'a_eta3': 1.0, # } + 'a_gamma1': 1.0, # } + 'a_gamma2': 1.0, # } Post-spike increments for spike-frequency adaptation in mV + 'a_gamma3': 1.0, # } + } + + recordable = ['spikes', 'v', 'gsyn_exc', 'gsyn_inh', 'i_eta', + 'eta1', 'eta2', 'eta3', 'gamma1', 'gamma2', 'gamma3', + 'rand'] + default_initial_values = { + 'v': -65.0, + 'gsyn_exc': 0.0, + 'gsyn_inh': 0.0, + 'eta1': 0.0, + 'eta2': 0.0, + 'eta3': 0.0, + 'gamma1': 0.0, + 'gamma2': 0.0, + 'gamma3': 0.0 + } + units = { + 'v': 'mV', + 'gsyn_exc': 'uS', + 'gsyn_inh': 'uS', + 'eta1': 'nA', + 'eta2': 'nA', + 'eta3': 'nA', + 'i_eta': 'nA', + 'gamma1': 'mV', + 'gamma2': 'mV', + 'gamma3': 'mV', + 'rand': 'dimensionless' + } + + class SpikeSourcePoisson(StandardCellType): """Spike source, generating spikes according to a Poisson process.""" From eb240b270e366ebf115428bb5ed971ccdb4c853b Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Fri, 4 Nov 2016 11:37:14 +0100 Subject: [PATCH 08/14] Added preliminary support for `GIF_cond_exp` in `pyNN.nest` --- pyNN/nest/__init__.py | 2 ++ pyNN/nest/populations.py | 12 ++++++++++++ pyNN/nest/simulator.py | 2 +- pyNN/nest/standardmodels/cells.py | 32 +++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/pyNN/nest/__init__.py b/pyNN/nest/__init__.py index 581705f0b..dd989a672 100644 --- a/pyNN/nest/__init__.py +++ b/pyNN/nest/__init__.py @@ -47,6 +47,8 @@ if logger.level == logging.NOTSET: logger.setLevel(logging.ERROR) +nest.Install('mymodule') + # ============================================================================== # Utility functions # ============================================================================== diff --git a/pyNN/nest/populations.py b/pyNN/nest/populations.py index 2ca93833c..e58b9a638 100644 --- a/pyNN/nest/populations.py +++ b/pyNN/nest/populations.py @@ -78,12 +78,24 @@ def _build_params(parameter_space, mask_local, size=None, extra_parameters=None) for name, val in cell_parameters.items(): if isinstance(val, Sequence): cell_parameters[name] = val.value + # The following is a temporary hack to get the gif_cond_exp model working. + # Longer-term, an extension to lazyarray would be the best approach + if 'tau_sfa1' in cell_parameters: + cell_parameters['tau_sfa'] = (cell_parameters.pop('tau_sfa1'), cell_parameters.pop('tau_sfa2'), cell_parameters.pop('tau_sfa3')) + cell_parameters['q_sfa'] = (cell_parameters.pop('q_sfa1'), cell_parameters.pop('q_sfa2'), cell_parameters.pop('q_sfa3')) + cell_parameters['tau_stc'] = (cell_parameters.pop('tau_stc1'), cell_parameters.pop('tau_stc2'), cell_parameters.pop('tau_stc3')) + cell_parameters['q_stc'] = (cell_parameters.pop('q_stc1'), cell_parameters.pop('q_stc2'), cell_parameters.pop('q_stc3')) else: parameter_space.evaluate(mask=mask_local) cell_parameters = list(parameter_space) # may not be the most efficient way. # Might be best to set homogeneous parameters on creation, # then inhomogeneous ones using SetStatus. Need some timings. for D in cell_parameters: + if 'tau_sfa1' in D: # temporary hack + D['tau_sfa'] = (D.pop('tau_sfa1'), D.pop('tau_sfa2'), D.pop('tau_sfa3')) + D['q_sfa'] = (D.pop('q_sfa1'), D.pop('q_sfa2'), D.pop('q_sfa3')) + D['tau_stc'] = (D.pop('tau_stc1'), D.pop('tau_stc2'), D.pop('tau_stc3')) + D['q_stc'] = (D.pop('q_stc1'), D.pop('q_stc2'), D.pop('q_stc3')) for name, val in D.items(): if isinstance(val, Sequence): D[name] = val.value diff --git a/pyNN/nest/simulator.py b/pyNN/nest/simulator.py index 92eab7890..e22f982b9 100644 --- a/pyNN/nest/simulator.py +++ b/pyNN/nest/simulator.py @@ -90,7 +90,7 @@ def set_delays(self, min_delay, max_delay): @property def max_delay(self): - return nest.GetDefaults('static_synapse')['max_delay'] + return nest.GetKernelStatus('max_delay') @property def num_processes(self): diff --git a/pyNN/nest/standardmodels/cells.py b/pyNN/nest/standardmodels/cells.py index ac444988d..47ed7829d 100644 --- a/pyNN/nest/standardmodels/cells.py +++ b/pyNN/nest/standardmodels/cells.py @@ -310,3 +310,35 @@ class Izhikevich(cells.Izhikevich): "off_grid": "izhikevich"} standard_receptor_type = True receptor_scale = 1e-3 # synaptic weight is in mV, so need to undo usual weight scaling +class GIF_cond_exp(cells.GIF_cond_exp): + + translations = build_translations( + ('v_rest', 'E_L'), + ('cm', 'C_m', 1000.0), # nF -> pF + ('tau_m', 'g_L', "cm/tau_m*1000.0", "C_m/g_L"), + ('tau_refrac', 't_ref'), + ('tau_syn_E', 'tau_syn_ex'), + ('tau_syn_I', 'tau_syn_in'), + ('e_rev_E', 'E_ex'), + ('e_rev_I', 'E_in'), + ('v_reset', 'V_reset'), + ('i_offset', 'I_e', 1000.0), # nA -> pA + ('delta_v', 'delta_u'), + ('v_t_star', 'v_t_star'), + ('lambda0', 'lambda0'), + ('tau_eta1', 'tau_stc1'), + ('tau_eta2', 'tau_stc2'), + ('tau_eta3', 'tau_stc3'), + ('tau_gamma1', 'tau_sfa1'), + ('tau_gamma2', 'tau_sfa2'), + ('tau_gamma3', 'tau_sfa3'), + ('a_eta1', 'q_stc1', 1000.0), # nA -> pA + ('a_eta2', 'q_stc2', 1000.0), + ('a_eta3', 'q_stc3', 1000.0), + ('a_gamma1', 'q_sfa1'), + ('a_gamma2', 'q_sfa2'), + ('a_gamma3', 'q_sfa3'), + ) + nest_name = {"on_grid": "gif_cond_exp", + "off_grid": "gif_cond_exp"} + standard_receptor_type = True From 19da2ff2515835ee90d61472e59431e35f571b61 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Wed, 1 Jun 2016 17:51:06 +0200 Subject: [PATCH 09/14] Modified `gif.mod` so that the membrane potential is clamped to `Vr`, rather than 0 mV, during the refractory period (to match the behaviour of other IF models). --- examples/gif_neuron.py | 105 ++++++++++++++++++++++++++++++++++++++ pyNN/neuron/nmodl/gif.mod | 4 +- 2 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 examples/gif_neuron.py diff --git a/examples/gif_neuron.py b/examples/gif_neuron.py new file mode 100644 index 000000000..a0d310815 --- /dev/null +++ b/examples/gif_neuron.py @@ -0,0 +1,105 @@ +""" +todo: write docstring + + + +""" + +import matplotlib +matplotlib.use('Agg') +from numpy import arange +from pyNN.utility import get_simulator, init_logging, normalized_filename + + +# === Configure the simulator ================================================ + +sim, options = get_simulator(("--plot-figure", "Plot the simulation results to a file.", {"action": "store_true"}), + ("--debug", "Print debugging information")) + +if options.debug: + init_logging(None, debug=True) + +sim.setup(timestep=0.01, min_delay=1.0) + + +# === Build and instrument the network ======================================= + +t_stop = 300.0 + +parameters = { + 'neurons': { + 'v_rest': -65.0, # Resting membrane potential in mV. + 'cm': 1.0, # Capacity of the membrane in nF + 'tau_m': 20.0, # Membrane time constant in ms. + 'tau_refrac': 4.0, # Duration of refractory period in ms. + 'tau_syn_E': 5.0, # Decay time of the excitatory synaptic conductance in ms. + 'tau_syn_I': 5.0, # Decay time of the inhibitory synaptic conductance in ms. + 'e_rev_E': 0.0, # Reversal potential for excitatory input in mV + 'e_rev_I': -70.0, # Reversal potential for inhibitory input in mV + 'v_reset': -65.0, # Reset potential after a spike in mV. + 'i_offset': 0.0, # Offset current in nA + 'v_t_star': -55.0, # Threshold baseline in mV. + 'lambda0': 1.0, # Firing intensity at threshold in Hz. + 'tau_eta1': 1.0, # } + 'tau_eta2': 10.0, # } Time constants for spike-triggered current in ms. + 'tau_eta3': 100.0, # } + 'tau_gamma1': 1.0, # } + 'tau_gamma2': 10.0, # } Time constants for spike-frequency adaptation in ms. + 'tau_gamma3': 100.0, # } + # the following parameters have different values for each neuron + 'delta_v': [1e-6, 1e-6, 0.5, 0.5], # Threshold sharpness in mV. + 'a_eta1': [0.1, 0.0, 0.0, 0.0], # } + 'a_eta2': [0.1, 0.0, 0.0, 0.0], # } Post-spike increments for spike-triggered current in nA + 'a_eta3': [0.1, 0.0, 0.0, 0.0], # } + 'a_gamma1': [0.0, 5.0, 0.0, 0.0], # } + 'a_gamma2': [0.0, 5.0, 0.0, 0.0], # } Post-spike increments for spike-frequency adaptation in mV + 'a_gamma3': [0.0, 5.0, 0.0, 0.0], # } + }, + 'stimulus': { + 'start': 20.0, + 'stop': t_stop - 20.0, + 'amplitude': 0.6 + } +} + +neurons = sim.Population(4, sim.GIF_cond_exp(**parameters['neurons'])) + +electrode = sim.DCSource(**parameters['stimulus']) +electrode.inject_into(neurons) + +neurons.record(['v']) #, 'E_sfa']) +#neurons.initialize(v=-70.0) + + +# === Run the simulation ===================================================== + +sim.run(t_stop) + +#import nest +#print(nest.GetStatus(neurons.all_cells.tolist())) + +# === Save the results, optionally plot a figure ============================= + +filename = normalized_filename("Results", "gif_neuron", "pkl", + options.simulator, sim.num_processes()) +#filename = "Results/gif_neuron.pkl" +neurons.write_data(filename, annotations={'script_name': __file__}) + +if options.plot_figure: + from pyNN.utility.plotting import Figure, Panel + figure_filename = filename.replace("pkl", "png") + data = neurons.get_data().segments[0] + v = data.filter(name="v")[0] + #u = data.filter(name="u")[0] + Figure( + Panel(v, ylabel="Membrane potential (mV)", xticks=True, + xlabel="Time (ms)", yticks=True), + #Panel(u, ylabel="u variable (units?)"), + annotations="Simulated with %s" % options.simulator.upper() + ).save(figure_filename) + print(figure_filename) + + +# === Clean up and quit ======================================================== + +sim.end() diff --git a/pyNN/neuron/nmodl/gif.mod b/pyNN/neuron/nmodl/gif.mod index 0527d3cb7..953b42d40 100644 --- a/pyNN/neuron/nmodl/gif.mod +++ b/pyNN/neuron/nmodl/gif.mod @@ -111,7 +111,7 @@ BREAKPOINT { p_dontspike = exp(-lambda*(dt * (1e-3))) } - irefrac = grefrac*(v-0) + irefrac = grefrac*(v-Vr) i = irefrac + i_eta } @@ -139,7 +139,7 @@ NET_RECEIVE (weight) { } } else if (flag == 2) { : beginning of spike - v = 0 + v = Vr grefrac = gon net_send(Tref-dt, 3) :net_event(t) From d2d5d10fbbc1bdb1d11bc1036c5e034aed3ab631 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Fri, 4 Nov 2016 14:27:33 +0100 Subject: [PATCH 10/14] The development version of NEST now contains the `gif_cond_exp` model, so it is not necessary to use the MyModule approach. Also modified the NEURON implementation to increment the eta and gamma variables at spike onset rather than after the refractory period. This matches the description in Pozzorini et al., and the behaviour of the NEST implementation. --- examples/gif_neuron.py | 32 ++++++++++++++++++++----------- pyNN/nest/__init__.py | 1 - pyNN/nest/recording.py | 5 +++-- pyNN/nest/standardmodels/cells.py | 8 +++++--- pyNN/neuron/cells.py | 3 +-- pyNN/neuron/nmodl/gif.mod | 22 +++++++++++---------- pyNN/standardmodels/cells.py | 22 +++++---------------- 7 files changed, 47 insertions(+), 46 deletions(-) diff --git a/examples/gif_neuron.py b/examples/gif_neuron.py index a0d310815..113a367ab 100644 --- a/examples/gif_neuron.py +++ b/examples/gif_neuron.py @@ -1,13 +1,24 @@ """ -todo: write docstring +Demonstration of the Generalized Integrate-and-Fire model described by Pozzorini et al. (2015) +We simulate four neurons with different parameters: + 1. spike-triggered current, fixed threshold, deterministic spiking + 2. no spike-triggered current, dynamic threshold, deterministic spiking + 3 & 4. no spike-triggered current, fixed threshold, stochastic spiking +Since neurons 1 and 2 have deterministic spiking, they should produce the same spike times with +different simulators. Neurons 3 and 4, being stochastic, should spike at different times. + +Reference: + +Pozzorini, Christian, Skander Mensi, Olivier Hagens, Richard Naud, Christof Koch, and Wulfram Gerstner (2015) +"Automated High-Throughput Characterization of Single Neurons by Means of Simplified Spiking Models." +PLOS Comput Biol 11 (6): e1004275. doi:10.1371/journal.pcbi.1004275. """ import matplotlib matplotlib.use('Agg') -from numpy import arange from pyNN.utility import get_simulator, init_logging, normalized_filename @@ -67,22 +78,17 @@ electrode = sim.DCSource(**parameters['stimulus']) electrode.inject_into(neurons) -neurons.record(['v']) #, 'E_sfa']) -#neurons.initialize(v=-70.0) +neurons.record(['v', 'i_eta', 'v_t']) # === Run the simulation ===================================================== sim.run(t_stop) -#import nest -#print(nest.GetStatus(neurons.all_cells.tolist())) - # === Save the results, optionally plot a figure ============================= filename = normalized_filename("Results", "gif_neuron", "pkl", options.simulator, sim.num_processes()) -#filename = "Results/gif_neuron.pkl" neurons.write_data(filename, annotations={'script_name': __file__}) if options.plot_figure: @@ -90,11 +96,15 @@ figure_filename = filename.replace("pkl", "png") data = neurons.get_data().segments[0] v = data.filter(name="v")[0] - #u = data.filter(name="u")[0] + v_t = data.filter(name="v_t")[0] + i_eta = data.filter(name="i_eta")[0] Figure( - Panel(v, ylabel="Membrane potential (mV)", xticks=True, + Panel(v, ylabel="Membrane potential (mV)", + yticks=True, ylim=[-66, -52]), + Panel(v_t, ylabel="Threshold (mV)", + yticks=True), + Panel(i_eta, ylabel="i_eta (nA)", xticks=True, xlabel="Time (ms)", yticks=True), - #Panel(u, ylabel="u variable (units?)"), annotations="Simulated with %s" % options.simulator.upper() ).save(figure_filename) print(figure_filename) diff --git a/pyNN/nest/__init__.py b/pyNN/nest/__init__.py index dd989a672..cbffd1e7c 100644 --- a/pyNN/nest/__init__.py +++ b/pyNN/nest/__init__.py @@ -47,7 +47,6 @@ if logger.level == logging.NOTSET: logger.setLevel(logging.ERROR) -nest.Install('mymodule') # ============================================================================== # Utility functions diff --git a/pyNN/nest/recording.py b/pyNN/nest/recording.py index bce6ee318..60c172204 100644 --- a/pyNN/nest/recording.py +++ b/pyNN/nest/recording.py @@ -10,10 +10,11 @@ from pyNN import recording from pyNN.nest import simulator +# todo: this information should come from the cell type classes VARIABLE_MAP = {'v': 'V_m', 'gsyn_exc': 'g_ex', 'gsyn_inh': 'g_in', 'u': 'U_m', - 'w': 'w'} + 'w': 'w', 'i_eta': 'I_stc', 'v_t': 'E_sfa'} REVERSE_VARIABLE_MAP = dict((v, k) for k, v in VARIABLE_MAP.items()) -SCALE_FACTORS = {'v': 1, 'gsyn_exc': 0.001, 'gsyn_inh': 0.001, 'w': 0.001} +SCALE_FACTORS = {'v': 1, 'gsyn_exc': 0.001, 'gsyn_inh': 0.001, 'w': 0.001, 'i_eta': 0.001, 'v_t': 1} logger = logging.getLogger("PyNN") diff --git a/pyNN/nest/standardmodels/cells.py b/pyNN/nest/standardmodels/cells.py index 47ed7829d..2285e29e8 100644 --- a/pyNN/nest/standardmodels/cells.py +++ b/pyNN/nest/standardmodels/cells.py @@ -310,6 +310,8 @@ class Izhikevich(cells.Izhikevich): "off_grid": "izhikevich"} standard_receptor_type = True receptor_scale = 1e-3 # synaptic weight is in mV, so need to undo usual weight scaling + + class GIF_cond_exp(cells.GIF_cond_exp): translations = build_translations( @@ -323,9 +325,9 @@ class GIF_cond_exp(cells.GIF_cond_exp): ('e_rev_I', 'E_in'), ('v_reset', 'V_reset'), ('i_offset', 'I_e', 1000.0), # nA -> pA - ('delta_v', 'delta_u'), - ('v_t_star', 'v_t_star'), - ('lambda0', 'lambda0'), + ('delta_v', 'Delta_V'), + ('v_t_star', 'V_T_star'), + ('lambda0', 'lambda_0'), ('tau_eta1', 'tau_stc1'), ('tau_eta2', 'tau_stc2'), ('tau_eta3', 'tau_stc3'), diff --git a/pyNN/neuron/cells.py b/pyNN/neuron/cells.py index 9de9ad8d0..52a56c415 100644 --- a/pyNN/neuron/cells.py +++ b/pyNN/neuron/cells.py @@ -485,8 +485,7 @@ def __init__(self, syn_type, syn_shape, lambda0 = _new_property('gif_fun', 'lambda0') def memb_init(self): - for state_var in ('v', 'eta1', 'eta2', 'eta3', - 'gamma1', 'gamma2', 'gamma3'): + for state_var in ('v', 'v_t', 'i_eta'): initial_value = getattr(self, '{0}_init'.format(state_var)) assert initial_value is not None if state_var == 'v': diff --git a/pyNN/neuron/nmodl/gif.mod b/pyNN/neuron/nmodl/gif.mod index 953b42d40..7829fcd34 100644 --- a/pyNN/neuron/nmodl/gif.mod +++ b/pyNN/neuron/nmodl/gif.mod @@ -10,7 +10,7 @@ NEURON { RANGE DV, lambda0 RANGE tau_eta1, tau_eta2, tau_eta3, a_eta1, a_eta2, a_eta3 RANGE tau_gamma1, tau_gamma2, tau_gamma3, a_gamma1, a_gamma2, a_gamma3 - RANGE i_eta, gamma_sum, verboseLevel, p_dontspike, rand + RANGE i_eta, gamma_sum, v_t, verboseLevel, p_dontspike, rand RANGE e_spike, isrefrac POINTER rng NONSPECIFIC_CURRENT i @@ -69,6 +69,7 @@ ASSIGNED { rand (1) grefrac (uS) gamma_sum (mV) + v_t (mV) verboseLevel (1) dt (ms) rng @@ -104,7 +105,8 @@ BREAKPOINT { i_eta = eta1 + eta2 + eta3 gamma_sum = gamma1 + gamma2 + gamma3 - lambda = lambda0*exp( (v-Vt_star-gamma_sum)/DV ) + v_t = Vt_star + gamma_sum + lambda = lambda0*exp( (v-v_t)/DV ) if (isrefrac > 0) { p_dontspike = 2 : is in refractory period, make it impossible to trigger a spike } else { @@ -144,6 +146,14 @@ NET_RECEIVE (weight) { net_send(Tref-dt, 3) :net_event(t) + : increase filters after spike + eta1 = eta1 + a_eta1 + eta2 = eta2 + a_eta2 + eta3 = eta3 + a_eta3 + gamma1 = gamma1 + a_gamma1 + gamma2 = gamma2 + a_gamma2 + gamma3 = gamma3 + a_gamma3 + if( verboseLevel > 0 ) { printf("Start spike, at time %g: rand=%g, p_dontspike=%g\n", t, rand, p_dontspike) } @@ -153,14 +163,6 @@ NET_RECEIVE (weight) { isrefrac = 0 grefrac = 0 - : increase filters after refractory period - eta1 = eta1 + a_eta1 - eta2 = eta2 + a_eta2 - eta3 = eta3 + a_eta3 - gamma1 = gamma1 + a_gamma1 - gamma2 = gamma2 + a_gamma2 - gamma3 = gamma3 + a_gamma3 - if( verboseLevel > 0 ) { printf("End refrac, at time %g: rand=%g, p_dontspike=%g\n", t, rand, p_dontspike) } diff --git a/pyNN/standardmodels/cells.py b/pyNN/standardmodels/cells.py index 848c72ab5..c74d01387 100644 --- a/pyNN/standardmodels/cells.py +++ b/pyNN/standardmodels/cells.py @@ -439,36 +439,24 @@ class GIF_cond_exp(StandardCellType): 'a_eta2': 1.0, # } Post-spike increments for spike-triggered current in nA 'a_eta3': 1.0, # } 'a_gamma1': 1.0, # } - 'a_gamma2': 1.0, # } Post-spike increments for spike-frequency adaptation in mV + 'a_gamma2': 1.0, # } Post-spike increments for moving threshold in mV 'a_gamma3': 1.0, # } } - recordable = ['spikes', 'v', 'gsyn_exc', 'gsyn_inh', 'i_eta', - 'eta1', 'eta2', 'eta3', 'gamma1', 'gamma2', 'gamma3', - 'rand'] + recordable = ['spikes', 'v', 'gsyn_exc', 'gsyn_inh', 'i_eta', 'v_t'] default_initial_values = { 'v': -65.0, + 'v_t': -48.0, + 'i_eta': 0.0, 'gsyn_exc': 0.0, 'gsyn_inh': 0.0, - 'eta1': 0.0, - 'eta2': 0.0, - 'eta3': 0.0, - 'gamma1': 0.0, - 'gamma2': 0.0, - 'gamma3': 0.0 } units = { 'v': 'mV', 'gsyn_exc': 'uS', 'gsyn_inh': 'uS', - 'eta1': 'nA', - 'eta2': 'nA', - 'eta3': 'nA', 'i_eta': 'nA', - 'gamma1': 'mV', - 'gamma2': 'mV', - 'gamma3': 'mV', - 'rand': 'dimensionless' + 'v_t': 'mV', } From ede350a8619cf8f953a3d24f715d007d7c81da2f Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Thu, 17 Nov 2016 14:24:30 +0100 Subject: [PATCH 11/14] Restore testing of AdExp with Delta_T=0, now that https://github.com/nest/nest-simulator/issues/114 has been fixed. --- test/system/scenarios/test_cell_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/system/scenarios/test_cell_types.py b/test/system/scenarios/test_cell_types.py index 0e3c8db6e..b525ac2d6 100644 --- a/test/system/scenarios/test_cell_types.py +++ b/test/system/scenarios/test_cell_types.py @@ -58,7 +58,7 @@ def test_HH_cond_exp(sim, plot_figure=False): test_HH_cond_exp.__test__ = False -@register(exclude=['nemo', 'brian', 'nest']) # cf https://github.com/nest/nest-simulator/issues/114 +@register(exclude=['nemo', 'brian']) def issue367(sim, plot_figure=False): # AdEx dynamics for delta_T=0 sim.setup(timestep=0.001, min_delay=0.1, max_delay=4.0) From f6d81e169d551bd5333b2e85c84f62e86ba6dfe7 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Wed, 8 Mar 2017 18:16:33 +0100 Subject: [PATCH 12/14] Update Travis config --- ci/install.sh | 5 ----- ci/install_nest.sh | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ci/install.sh b/ci/install.sh index 03c422a55..87a4c3865 100644 --- a/ci/install.sh +++ b/ci/install.sh @@ -10,8 +10,3 @@ source ci/install_brian.sh source ci/install_nest.sh source ci/install_neuron.sh python setup.py install - -echo "Python 3.5 site packages" -ls /home/travis/virtualenv/python3.5.0/lib/python3.5/site-packages -echo "Python 2.7 site packages" -ls /home/travis/virtualenv/python2.7.10/lib/python2.7/site-packages diff --git a/ci/install_nest.sh b/ci/install_nest.sh index 00581e4e1..d54e5cacd 100644 --- a/ci/install_nest.sh +++ b/ci/install_nest.sh @@ -15,8 +15,8 @@ if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ] || [ "$TRAVIS_PYTHON_VERSION" == "3.5" mkdir -p $HOME/build/$NEST pushd $HOME/build/$NEST export VENV=`python -c "import sys; print(sys.prefix)"`; - ln -s /opt/python/2.7.10/lib/libpython2.7.so $VENV/lib/libpython2.7.so; - ln -s /opt/python/3.5.0/lib/libpython3.5m.so $VENV/lib/libpython3.5.so; + ln -s /opt/python/2.7.12/lib/libpython2.7.so $VENV/lib/libpython2.7.so; + ln -s /opt/python/3.5.2/lib/libpython3.5m.so $VENV/lib/libpython3.5.so; export PYTHON_INCLUDE_DIR=$VENV/include/python${TRAVIS_PYTHON_VERSION} if [ "$TRAVIS_PYTHON_VERSION" == "3.5" ]; then export PYTHON_INCLUDE_DIR=${PYTHON_INCLUDE_DIR}m; From 14763dc0fca640781c4343d9974f168e63870e4f Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Wed, 8 Mar 2017 19:26:47 +0100 Subject: [PATCH 13/14] Test with NEST 2.12.0 --- ci/install_nest.sh | 7 +++++-- test/system/test_nest.py | 16 ++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ci/install_nest.sh b/ci/install_nest.sh index d54e5cacd..78cc79e65 100644 --- a/ci/install_nest.sh +++ b/ci/install_nest.sh @@ -4,12 +4,15 @@ set -e # stop execution in case of errors if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ] || [ "$TRAVIS_PYTHON_VERSION" == "3.5" ]; then echo -e "\n========== Installing NEST ==========\n" - export NEST_VERSION="master" + #export NEST_VERSION="master" + export NEST_VERSION="2.12.0" export NEST="nest-simulator-$NEST_VERSION" pip install cython==0.23.4 - wget https://github.com/nest/nest-simulator/archive/$NEST_VERSION.tar.gz -O $HOME/$NEST.tar.gz; + #wget https://github.com/nest/nest-simulator/archive/$NEST_VERSION.tar.gz -O $HOME/$NEST.tar.gz; + wget https://github.com/nest/nest-simulator/releases/download/v$NEST_VERSION/nest-$NEST_VERSION.tar.gz -O $HOME/$NEST.tar.gz pushd $HOME; tar xzf $NEST.tar.gz; + ls; popd; mkdir -p $HOME/build/$NEST diff --git a/test/system/test_nest.py b/test/system/test_nest.py index 3b6b760fc..9808d9b13 100644 --- a/test/system/test_nest.py +++ b/test/system/test_nest.py @@ -31,16 +31,16 @@ def test_record_native_model(): nest.setup() - parameters = {'Tau_m': 17.0} + parameters = {'tau_m': 17.0} n_cells = 10 p1 = nest.Population(n_cells, nest.native_cell_type("ht_neuron")(**parameters)) p1.initialize(V_m=-70.0, Theta=-50.0) - p1.set(Theta_eq=-51.5) - #assert_arrays_equal(p1.get('Theta_eq'), -51.5*numpy.ones((10,))) - assert_equal(p1.get('Theta_eq'), -51.5) - print(p1.get('Tau_m')) - p1.set(Tau_m=RandomDistribution('uniform', low=15.0, high=20.0)) - print(p1.get('Tau_m')) + p1.set(theta_eq=-51.5) + #assert_arrays_equal(p1.get('theta_eq'), -51.5*numpy.ones((10,))) + assert_equal(p1.get('theta_eq'), -51.5) + print(p1.get('tau_m')) + p1.set(tau_m=RandomDistribution('uniform', low=15.0, high=20.0)) + print(p1.get('tau_m')) current_source = nest.StepCurrentSource(times=[50.0, 110.0, 150.0, 210.0], amplitudes=[0.01, 0.02, -0.02, 0.01]) @@ -94,7 +94,7 @@ def test_ticket240(): raise SkipTest nest = pyNN.nest nest.setup(threads=4) - parameters = {'Tau_m': 17.0} + parameters = {'tau_m': 17.0} p1 = nest.Population(4, nest.IF_curr_exp()) p2 = nest.Population(5, nest.native_cell_type("ht_neuron")(**parameters)) conn = nest.AllToAllConnector() From 4e50b8d9ff6b36cf33bc76ca63d785c63cbc87b7 Mon Sep 17 00:00:00 2001 From: Andrew Davison Date: Wed, 8 Mar 2017 22:24:53 +0100 Subject: [PATCH 14/14] Preparing 0.8.3 release in nest-dev branch --- doc/conf.py | 4 ++-- doc/developers/contributing.txt | 6 ++--- doc/installation.txt | 10 ++++----- doc/release_notes.txt | 1 + doc/releases/0.8.3.txt | 31 ++++++++++++++++++++++++++ pyNN/__init__.py | 2 +- setup.py | 39 +++++++++++++++++---------------- 7 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 doc/releases/0.8.3.txt diff --git a/doc/conf.py b/doc/conf.py index 6a93a59fc..bead0019b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -71,7 +71,7 @@ class MockNESTModule(mock.Mock): # General information about the project. project = u'PyNN' authors = u'the PyNN community' -copyright = u'2006-2016, ' + authors +copyright = u'2006-2017, ' + authors # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -80,7 +80,7 @@ class MockNESTModule(mock.Mock): # The short X.Y version. version = '0.8' # The full version, including alpha/beta/rc tags. -release = '0.8.2' +release = '0.8.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/developers/contributing.txt b/doc/developers/contributing.txt index c3b029d3e..6f4c4ee5f 100644 --- a/doc/developers/contributing.txt +++ b/doc/developers/contributing.txt @@ -80,7 +80,7 @@ We try to stay fairly close to PEP8_. Please note in particular: - some function/method names in PyNN use ``mixedCase``, but these will gradually be deprecated and replaced with ``lower_case_with_underscores``. Any new functions or methods should use the latter. - - we currently target versions 2.6, 2.7 and 3.4 + - we currently target versions 2.6, 2.7 and 3.3-3.6 Testing @@ -166,7 +166,7 @@ Making a release ================ To make a release of PyNN requires you to have permissions to upload PyNN -packages to the `Python Package Index`_ and the INCF Software Center, and to +packages to the `Python Package Index`_, and to upload documentation to the neuralensemble.org server. If you are interested in becoming release manager for PyNN, please contact us via the `mailing list`_. @@ -177,7 +177,7 @@ last time: :file:`test/unittests` and :file:`test/system` and running :command:`make doctest` in :file:`doc`. You should do this on at least two Linux systems -- one a very recent version and one at least a year old, and on at least one version of - Mac OS X. You should also do this with Python 2.6, 2.7 and 3.4 or 3.5. + Mac OS X. You should also do this with Python 2.6, 2.7 and 3.4, 3.5 or 3.6. * do all the example scripts generate the correct output? Run the :file:`run_all_examples.py` script in :file:`examples/tools` and then visually check the :file:`.png` files generated in :file:`examples/tools/Results`. Again, diff --git a/doc/installation.txt b/doc/installation.txt index cc66e33dd..b6ba8bda2 100644 --- a/doc/installation.txt +++ b/doc/installation.txt @@ -7,7 +7,7 @@ install and run PyNN on Windows, but this has not been tested. Installing PyNN requires: - * Python (version 2.6, 2.7, 3.3, 3.4 or 3.5) + * Python (version 2.6, 2.7, 3.3-3.6) * a recent version of the NumPy_ package * the lazyarray_ package * the Neo_ package @@ -32,8 +32,8 @@ If you are running Debian or Ubuntu, there are :doc:`binary packages ` available. If you would prefer to install manually, :doc:`download the latest source distribution `, then run the setup script, e.g.:: - $ tar xzf PyNN-0.8.2.tar.gz - $ cd PyNN-0.8.2 + $ tar xzf PyNN-0.8.3.tar.gz + $ cd PyNN-0.8.3 $ python setup.py install This will install it to your Python :file:`site-packages` directory, and may @@ -111,7 +111,7 @@ If you run into problems, check out the `NEURON Forum`_. Installing NEST and PyNEST ========================== -NEST 2.10 can be downloaded from ``_. +NEST 2.12 can be downloaded from ``_. Earlier versions of NEST will not work with this version of PyNN. The full installation instructions are available in the file INSTALL, which you can find in the NEST source package, or at ``_. @@ -138,7 +138,7 @@ Now try it out:: -- N E S T -- Copyright (C) 2004 The NEST Initiative - Version 2.10.0 Mar 21 2016 21:29:37 + Version 2.12.0 Mar 21 2016 21:29:37 ... >>> nest.Models() (u'ac_generator', u'aeif_cond_alpha', u'aeif_cond_alpha_RK5', u'aeif_cond_alpha_multisynapse', diff --git a/doc/release_notes.txt b/doc/release_notes.txt index 37f79a234..f0f35b8e1 100644 --- a/doc/release_notes.txt +++ b/doc/release_notes.txt @@ -6,6 +6,7 @@ Release notes .. toctree:: :maxdepth: 1 + releases/0.8.3.txt releases/0.8.2.txt releases/0.8.1.txt releases/0.8.0.txt diff --git a/doc/releases/0.8.3.txt b/doc/releases/0.8.3.txt new file mode 100644 index 000000000..a45ce7528 --- /dev/null +++ b/doc/releases/0.8.3.txt @@ -0,0 +1,31 @@ +======================== +PyNN 0.8.3 release notes +======================== + +8th March 2017 + +Welcome to PyNN 0.8.3! + + +NeuroML 2 +--------- + +The `neuroml` module has been completely rewritten, and updated from NeuroML v1 to v2. +This module works like other PyNN "backends", i.e. ``import pyNN.neuroml as sim``... +but instead of running a simulation, it exports the network to an XML file in NeuroML format. + +NEST 2.12 +--------- + +This release introduces support for NEST_ 2.12. Previous versions of NEST are no longer supported. + + +Other changes +------------- + +* `A couple of bug fixes`_ + + + +.. _Brian: http://briansimulator.org +.. _`A couple of bug fixes`: https://github.com/NeuralEnsemble/PyNN/issues?q=is%3Aclosed+milestone%3A0.8.3 \ No newline at end of file diff --git a/pyNN/__init__.py b/pyNN/__init__.py index f73b1cab6..0eee94dd1 100644 --- a/pyNN/__init__.py +++ b/pyNN/__init__.py @@ -69,7 +69,7 @@ :license: CeCILL, see LICENSE for details. """ -__version__ = '0.8.2' +__version__ = '0.8.3' __all__ = ["common", "random", "nest", "neuron", "brian", "recording", "errors", "space", "descriptions", "standardmodels", "parameters", "core"] diff --git a/setup.py b/setup.py index f36e8d0c0..2ba713867 100644 --- a/setup.py +++ b/setup.py @@ -41,13 +41,13 @@ def find_nrnivmodl(self): setup( name="PyNN", - version="0.8.2", + version="0.8.3", packages=['pyNN', 'pyNN.nest', 'pyNN.neuron', - 'pyNN.brian', 'pyNN.common', 'pyNN.mock', 'pyNN.neuroml','pyNN.neuroml.standardmodels', - 'pyNN.recording', 'pyNN.standardmodels', 'pyNN.descriptions', - 'pyNN.nest.standardmodels', - 'pyNN.neuron.standardmodels', 'pyNN.brian.standardmodels', - 'pyNN.utility', 'pyNN.nineml'], + 'pyNN.brian', 'pyNN.common', 'pyNN.mock', 'pyNN.neuroml', + 'pyNN.recording', 'pyNN.standardmodels', 'pyNN.descriptions', + 'pyNN.nest.standardmodels', 'pyNN.neuroml.standardmodels', + 'pyNN.neuron.standardmodels', 'pyNN.brian.standardmodels', + 'pyNN.utility', 'pyNN.nineml'], package_data={'pyNN': ['neuron/nmodl/*.mod', "descriptions/templates/*/*"]}, author="The PyNN team", author_email="andrew.davison@unic.cnrs-gif.fr", @@ -57,19 +57,20 @@ def find_nrnivmodl(self): keywords="computational neuroscience simulation neuron nest brian neuromorphic", url="http://neuralensemble.org/PyNN/", classifiers=['Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'License :: Other/Proprietary License', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Topic :: Scientific/Engineering'], + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'License :: Other/Proprietary License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Topic :: Scientific/Engineering'], cmdclass={'build': build}, )