Skip to content

Commit 2a7c21f

Browse files
author
C.A.P. Linssen
committed
allow inline expressions as postsynaptic third-factor
1 parent 80afc62 commit 2a7c21f

File tree

4 files changed

+24
-10
lines changed

4 files changed

+24
-10
lines changed

doc/running/running_nest.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ Additionally, if the synapse requires it, specify the ``"post_ports"`` entry to
276276
"post_ports": ["post_spikes",
277277
["I_post_dend", "I_dend"]]}]})
278278
279-
This specifies that the neuron ``iaf_psc_exp_dend`` has to be generated paired with the synapse ``third_factor_stdp``, and that the input ports ``post_spikes`` and ``I_post_dend`` in the synapse are to be connected to the postsynaptic partner. For the ``I_post_dend`` input port, the corresponding variable in the (postsynaptic) neuron is called ``I_dend``.
279+
This specifies that the neuron ``iaf_psc_exp_dend`` has to be generated paired with the synapse ``third_factor_stdp``, and that the input ports ``post_spikes`` and ``I_post_dend`` in the synapse are to be connected to the postsynaptic partner. For the ``I_post_dend`` input port, the corresponding variable in the (postsynaptic) neuron is called ``I_dend``. Note that inline expressions in the postsynaptic neuron can also be used, referred to by name analogous to a state variable.
280280

281281
To prevent the NESTML code generator from moving specific variables from synapse into postsynaptic neuron, the code generation option ``strictly_synaptic_vars`` may be used (see https://nestml.readthedocs.io/en/latest/pynestml.transformers.html#pynestml.transformers.synapse_post_neuron_transformer.SynapsePostNeuronTransformer).
282282

pynestml/codegeneration/nest_code_generator.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,14 @@ def _get_synapse_model_namespace(self, synapse: ASTModel) -> Dict:
583583
namespace["state_vars_that_need_continuous_buffering_transformed"] = [xfrm.get_neuron_var_name_from_syn_port_name(port_name, removesuffix(synapse.paired_neuron.unpaired_name, FrontendConfiguration.suffix), removesuffix(synapse.paired_neuron.paired_synapse.get_name().split("__with_")[0], FrontendConfiguration.suffix)) for port_name in synapse.paired_neuron.state_vars_that_need_continuous_buffering]
584584
namespace["state_vars_that_need_continuous_buffering_transformed_iv"] = {}
585585
for var_name, var_name_transformed in zip(namespace["state_vars_that_need_continuous_buffering"], namespace["state_vars_that_need_continuous_buffering_transformed"]):
586-
namespace["state_vars_that_need_continuous_buffering_transformed_iv"][var_name] = self._nest_printer.print(synapse.paired_neuron.get_initial_value(var_name_transformed))
586+
if synapse.paired_neuron.get_initial_value(var_name_transformed) is None:
587+
if var_name_transformed in [sym.name for sym in synapse.paired_neuron.get_inline_expression_symbols()]:
588+
# the postsynaptic variable is actually an inline expression: initial value is 0
589+
namespace["state_vars_that_need_continuous_buffering_transformed_iv"][var_name] = "0"
590+
else:
591+
raise Exception("State variable \"" + str(var_name_transformed) + "\" was not found in the neuron model \"" + synapse.paired_neuron.name + "\"")
592+
else:
593+
namespace["state_vars_that_need_continuous_buffering_transformed_iv"][var_name] = self._nest_printer.print(synapse.paired_neuron.get_initial_value(var_name_transformed))
587594

588595
namespace["continuous_post_ports"] = []
589596
if "neuron_synapse_pairs" in FrontendConfiguration.get_codegen_opts().keys():
@@ -705,8 +712,13 @@ def _get_neuron_model_namespace(self, neuron: ASTModel) -> Dict:
705712
namespace["state_vars_that_need_continuous_buffering_transformed_iv"] = {}
706713
for var_name, var_name_transformed in zip(namespace["state_vars_that_need_continuous_buffering"], namespace["state_vars_that_need_continuous_buffering_transformed"]):
707714
if neuron.get_initial_value(var_name_transformed) is None:
708-
raise Exception("State variable \"" + str(var_name_transformed) + "\" was not found in the neuron model \"" + neuron.name + "\"")
709-
namespace["state_vars_that_need_continuous_buffering_transformed_iv"][var_name] = self._nest_printer.print(neuron.get_initial_value(var_name_transformed))
715+
if var_name_transformed in [sym.name for sym in neuron.get_inline_expression_symbols()]:
716+
# the postsynaptic variable is actually an inline expression: initial value is 0
717+
namespace["state_vars_that_need_continuous_buffering_transformed_iv"][var_name] = "0"
718+
else:
719+
raise Exception("State variable \"" + str(var_name_transformed) + "\" was not found in the neuron model \"" + neuron.name + "\"")
720+
else:
721+
namespace["state_vars_that_need_continuous_buffering_transformed_iv"][var_name] = self._nest_printer.print(neuron.get_initial_value(var_name_transformed))
710722
else:
711723
namespace["state_vars_that_need_continuous_buffering"] = []
712724
if "extra_on_emit_spike_stmts_from_synapse" in dir(neuron):

pynestml/codegeneration/resources_nest/point_neuron/common/NeuronHeader.jinja2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ private:
879879
// -------------------------------------------------------------------------
880880
// Getters/setters for inline expressions
881881
// -------------------------------------------------------------------------
882-
882+
public: // XXX REMOVE -- use friend class instead?
883883
{% filter indent(2, True) -%}
884884
{%- for equations_block in neuron.get_equations_blocks() %}
885885
{%- for inline_expr in equations_block.get_inline_expressions() %}
@@ -890,6 +890,7 @@ private:
890890
{% endfor %}
891891
{%- endfor %}
892892
{%- endfilter %}
893+
private: // XXX REMOVE
893894

894895
// -------------------------------------------------------------------------
895896
// Getters/setters for input buffers

tests/nest_tests/traub_cond_multisyn_test.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ def test_traub_cond_multisyn(self):
8686
else:
8787
nest.SetStatus(multimeter[1], {"record_from": record_from,
8888
"interval": dt})
89-
# {"AMPA": 1, "NMDA": 2, "GABA_A": 3, "GABA_B": 4}
90-
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 1}) # AMPA
91-
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 2}) # NMDA
92-
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 3}) # GABAA
93-
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": 4}) # GABAB
89+
90+
receptor_types = nest.GetStatus(neuron2, "receptor_types")[0]
91+
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": receptor_types["AMPA"]}) # AMPA
92+
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": receptor_types["NMDA"]}) # NMDA
93+
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": receptor_types["GABAA"]}) # GABAA
94+
nest.Connect(neuron1, neuron2, syn_spec={"receptor_type": receptor_types["GABAB"]}) # GABAB
9495

9596
if NESTTools.detect_nest_version().startswith("v2"):
9697
nest.Connect([multimeter[0]], neuron1, "one_to_one")

0 commit comments

Comments
 (0)