Skip to content

Commit 83e4909

Browse files
authored
Improved getting of numerical initial values (#1272)
1 parent c3d7932 commit 83e4909

File tree

3 files changed

+31
-23
lines changed

3 files changed

+31
-23
lines changed

pynestml/codegeneration/nest_desktop_code_generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,6 @@ def _get_neuron_model_namespace(self, neuron: ASTModel) -> Dict:
6969
namespace["nestml_version"] = pynestml.__version__
7070
namespace["neuronName"] = neuron.get_name()
7171
namespace["neuron"] = neuron
72-
namespace["parameters"], namespace["state"] = PythonStandaloneTargetTools.get_neuron_parameters_and_state(neuron.file_path)
72+
namespace["parameters"], namespace["state"] = PythonStandaloneTargetTools.get_neuron_numerical_initial_values(neuron.file_path)
7373

7474
return namespace

pynestml/codegeneration/python_standalone_target_tools.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
# You should have received a copy of the GNU General Public License
2020
# along with NEST. If not, see <http://www.gnu.org/licenses/>.
2121

22+
from typing import Mapping, Tuple
23+
2224
import importlib
2325
import multiprocessing
2426
import os
@@ -65,23 +67,28 @@ def _get_model_parameters_and_state(cls, nestml_file_name: str):
6567
parameters_list = [p for p in dir(neuron.Parameters_) if not "__" in p]
6668
parameters = {p: getattr(neuron, "get_" + p)() for p in parameters_list}
6769

70+
internals_list = [p for p in dir(neuron.Variables_) if not "__" in p]
71+
internals = {p: getattr(neuron, "get_" + p)() for p in internals_list}
72+
6873
if "ode_state_variable_name_to_index" in dir(neuron.State_):
6974
state_list = neuron.State_.ode_state_variable_name_to_index.keys()
7075
else:
7176
state_list = [p for p in dir(neuron.State_) if not "__" in p]
7277
state_vars = {p: getattr(neuron, "get_" + p)() for p in state_list}
7378

74-
return parameters, state_vars
79+
return parameters, internals, state_vars
7580

7681
@classmethod
77-
def get_neuron_parameters_and_state(cls, nestml_file_name: str) -> tuple[dict, dict]:
82+
def get_neuron_numerical_initial_values(cls, nestml_file_name: str) -> Tuple[Mapping[str, float], Mapping[str, float], Mapping[str, float]]:
7883
r"""
79-
Get the parameters for the given neuron model. The code is generated for the model for Python standalone target
80-
The parameters and state variables are then queried by creating the neuron in Python standalone simulator.
84+
Get the numerical values of the parameters, internals, and state variables for the given neuron model.
85+
86+
Internally, code is generated for the model for the Python standalone target, and then the value is read off by instantiating the resulting code.
87+
8188
:param nestml_file_name: File name of the neuron model
82-
:return: A dictionary of parameters and state variables
89+
:return: Dictionaries mapping parameters, internals and state variables to their numerical initial values
8390
"""
84-
parameters, state = cls._get_model_parameters_and_state(nestml_file_name)
91+
parameters, internals, state = cls._get_model_parameters_and_state(nestml_file_name)
8592

8693
if not parameters or not state:
8794
Logger.log_message(None, -1,

pynestml/codegeneration/resources_python_standalone/point_neuron/@NEURON_NAME@.py.jinja2

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,29 +127,30 @@ class Neuron_{{neuronName}}(Neuron):
127127
self.S_ = self.State_()
128128
self.V_ = self.Variables_()
129129
self.B_ = self.Buffers_()
130+
self._timestep = timestep
130131

131-
{%- if parameter_vars_with_iv|length > 0 %}
132+
{% if parameter_vars_with_iv|length > 0 %}
132133
# initial values for parameters
133-
{%- filter indent(4) %}
134-
{%- for variable in parameter_vars_with_iv %}
135-
{%- set variable_symbol = neuron.get_scope().resolve_to_symbol(variable.get_name(), SymbolKind.VARIABLE) %}
136-
{%- include "directives_py/MemberInitialization.jinja2" %}
137-
{%- endfor %}
138-
{%- endfilter %}
134+
{%- filter indent(4) %}
135+
{%- for variable in parameter_vars_with_iv %}
136+
{%- set variable_symbol = neuron.get_scope().resolve_to_symbol(variable.get_name(), SymbolKind.VARIABLE) %}
137+
{%- include "directives_py/MemberInitialization.jinja2" %}
138+
{%- endfor %}
139+
{%- endfilter %}
139140
{%- endif %}
140141

141-
{%- if neuron.get_state_symbols()|length > 0 %}
142+
# initial values for internals
143+
self.recompute_internal_variables(self._timestep)
144+
{% if neuron.get_state_symbols()|length > 0 %}
142145
# initial values for state variables
143-
{%- filter indent(4) %}
144-
{%- for variable_symbol in neuron.get_state_symbols() %}
145-
{%- set variable = utils.get_variable_by_name(astnode, variable_symbol.get_symbol_name()) %}
146-
{%- include "directives_py/MemberInitialization.jinja2" %}
147-
{%- endfor %}
148-
{%- endfilter %}
146+
{%- filter indent(4) %}
147+
{%- for variable_symbol in neuron.get_state_symbols() %}
148+
{%- set variable = utils.get_variable_by_name(astnode, variable_symbol.get_symbol_name()) %}
149+
{%- include "directives_py/MemberInitialization.jinja2" %}
150+
{%- endfor %}
151+
{%- endfilter %}
149152
{%- endif %}
150153

151-
self._timestep = timestep
152-
self.recompute_internal_variables(self._timestep)
153154

154155
def get_model(self) -> str:
155156
return "{{neuronName}}"

0 commit comments

Comments
 (0)