diff --git a/pyNN/nest/connectors.py b/pyNN/nest/connectors.py index f8cc95a9..da62e810 100644 --- a/pyNN/nest/connectors.py +++ b/pyNN/nest/connectors.py @@ -116,7 +116,7 @@ def synapse_parameters(self, projection): if ( name == "weight" and projection.receptor_type == 'inhibitory' - and self.post.conductance_based + and projection.post.conductance_based ): # NEST wants negative values for inhibitory weights, # even if these are conductances diff --git a/pyNN/nest/projections.py b/pyNN/nest/projections.py index 8934d63c..c4579c58 100644 --- a/pyNN/nest/projections.py +++ b/pyNN/nest/projections.py @@ -16,7 +16,7 @@ from ..space import Space from ..parameters import simplify from . import simulator -from .standardmodels.synapses import StaticSynapse +from .standardmodels.synapses import StaticSynapse, TsodyksMarkramSynapse from .conversion import make_sli_compatible logger = logging.getLogger("PyNN") @@ -123,7 +123,7 @@ def _connect(self, rule_params, syn_params): Create connections by calling nest. Connect on the presynaptic and postsynaptic population with the parameters provided by params. """ - if 'tsodyks' in self.nest_synapse_model: + if isinstance(self.synapse_type, TsodyksMarkramSynapse): translations = self.post.local_cells[0].celltype.translations if self.receptor_type == 'inhibitory': param_name = translations['tau_syn_I']['translated_name'] @@ -131,8 +131,8 @@ def _connect(self, rule_params, syn_params): param_name = translations['tau_syn_E']['translated_name'] else: raise NotImplementedError() - syn_params.update( - {'tau_psc': nest.GetStatus([self.nest_connections[0, 1]], param_name)}) + tau_psc = nest.GetStatus(self.post.node_collection, param_name) + syn_params.update({'tau_psc': tau_psc[0] if len(set(tau_psc)) == 1 else list(tau_psc)}) syn_params.update({'synapse_label': self.nest_synapse_label}) nest.Connect(self.pre.node_collection, @@ -272,9 +272,16 @@ def _convergent_connect(self, presynaptic_indices, postsynaptic_index, syn_dict.update({'weight': weights, 'delay': delays}) if postsynaptic_cell.celltype.standard_receptor_type: +<<<<<<< issue810 + # For the standard TsodyksMarkramSynapse, copy "tau_psc" from the + # post-synaptic neuron's tau_syn so they stay consistent. For + # native_synapse_type, the user-supplied tau_psc is left untouched. + if isinstance(self.synapse_type, TsodyksMarkramSynapse): +======= # For Tsodyks-Markram synapses models we set the "tau_psc" parameter to match # the relevant "tau_syn" parameter from the post-synaptic neuron. if 'tsodyks' in self.nest_synapse_model and hasattr(postsynaptic_cell.celltype, 'translations'): +>>>>>>> master translations = postsynaptic_cell.celltype.translations if self.receptor_type == 'inhibitory': param_name = translations['tau_syn_I']['translated_name'] diff --git a/test/system/test_nest.py b/test/system/test_nest.py index 64dd05c3..fcba9a16 100644 --- a/test/system/test_nest.py +++ b/test/system/test_nest.py @@ -191,6 +191,77 @@ def test_tsodyks_markram_synapse(): assert_array_equal(tau_psc, np.arange(0.2, 0.7, 0.1)) +def test_native_tsodyks_synapse_convergent_connect(): + """native_synapse_type tsodyks_synapse via _convergent_connect preserves user tau_psc (issue #810).""" + if not have_nest: + pytest.skip("nest not available") + import nest + sim = pyNN.nest + sim.setup() + spike_source = sim.Population(1, sim.SpikeSourceArray(spike_times=np.arange(10, 100, 10))) + neurons = sim.Population(5, sim.IF_cond_exp(e_rev_I=-75, tau_syn_I=np.arange(0.2, 0.7, 0.1))) + synapse_type = sim.native_synapse_type('tsodyks_synapse')( + U=0.04, tau_rec=100.0, tau_fac=1000.0, weight=10.0, delay=0.5, tau_psc=5.0) + connector = sim.AllToAllConnector() + prj = sim.Projection(spike_source, neurons, connector, + receptor_type='inhibitory', + synapse_type=synapse_type) + connections = nest.GetConnections( + nest.NodeCollection(list(prj._sources)), + synapse_model=prj.nest_synapse_model) + tau_psc = np.array(nest.GetStatus(connections, 'tau_psc')) + assert_array_equal(tau_psc, [5.0] * 5) + sim.end() + + +def test_native_tsodyks_synapse_native_connect(): + """native_synapse_type tsodyks_synapse via _connect (NativeRNG) preserves user tau_psc (issue #810).""" + if not have_nest: + pytest.skip("nest not available") + import nest + sim = pyNN.nest + sim.setup() + spike_source = sim.Population(1, sim.SpikeSourceArray(spike_times=np.arange(10, 100, 10))) + neurons = sim.Population(5, sim.IF_cond_exp(e_rev_I=-75, tau_syn_I=3.0)) + synapse_type = sim.native_synapse_type('tsodyks_synapse')( + U=0.04, tau_rec=100.0, tau_fac=1000.0, weight=10.0, delay=0.5, tau_psc=5.0) + rng = sim.NativeRNG(seed=1234) + connector = sim.FixedProbabilityConnector(p_connect=1.0, rng=rng) + prj = sim.Projection(spike_source, neurons, connector, + receptor_type='inhibitory', + synapse_type=synapse_type) + connections = nest.GetConnections( + nest.NodeCollection(list(prj._sources)), + synapse_model=prj.nest_synapse_model) + tau_psc = np.array(nest.GetStatus(connections, 'tau_psc')) + assert_array_equal(tau_psc, [5.0] * 5) + sim.end() + + +def test_native_tsodyks2_synapse(): + """native_synapse_type tsodyks2_synapse creates projection without error (issue #810).""" + if not have_nest: + pytest.skip("nest not available") + import nest + sim = pyNN.nest + sim.setup() + spike_source = sim.Population(1, sim.SpikeSourceArray(spike_times=np.arange(10, 100, 10))) + neurons = sim.Population(5, sim.IF_cond_exp()) + synapse_type = sim.native_synapse_type('tsodyks2_synapse')( + U=0.04, tau_rec=100.0, tau_fac=1000.0, weight=10.0, delay=0.5) + connector = sim.AllToAllConnector() + prj = sim.Projection(spike_source, neurons, connector, + receptor_type='excitatory', + synapse_type=synapse_type) + connections = nest.GetConnections( + nest.NodeCollection(list(prj._sources)), + synapse_model=prj.nest_synapse_model) + assert len(connections) == 5 + U_vals = np.array(nest.GetStatus(connections, 'U')) + assert_array_equal(U_vals, [0.04] * 5) + sim.end() + + def test_native_electrode_types(): """ Test of NativeElectrodeType class. (See issue #506)""" if not have_nest: