Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pynestml/codegeneration/nest_desktop_code_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ def _get_neuron_model_namespace(self, neuron: ASTModel) -> Dict:
namespace["nestml_version"] = pynestml.__version__
namespace["neuronName"] = neuron.get_name()
namespace["neuron"] = neuron
namespace["parameters"], namespace["state"] = PythonStandaloneTargetTools.get_neuron_parameters_and_state(neuron.file_path)
namespace["parameters"], namespace["state"] = PythonStandaloneTargetTools.get_neuron_numerical_initial_values(neuron.file_path)

return namespace
19 changes: 13 additions & 6 deletions pynestml/codegeneration/python_standalone_target_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
# You should have received a copy of the GNU General Public License
# along with NEST. If not, see <http://www.gnu.org/licenses/>.

from typing import Mapping, Tuple

import importlib
import multiprocessing
import os
Expand Down Expand Up @@ -65,23 +67,28 @@ def _get_model_parameters_and_state(cls, nestml_file_name: str):
parameters_list = [p for p in dir(neuron.Parameters_) if not "__" in p]
parameters = {p: getattr(neuron, "get_" + p)() for p in parameters_list}

internals_list = [p for p in dir(neuron.Variables_) if not "__" in p]
internals = {p: getattr(neuron, "get_" + p)() for p in internals_list}

if "ode_state_variable_name_to_index" in dir(neuron.State_):
state_list = neuron.State_.ode_state_variable_name_to_index.keys()
else:
state_list = [p for p in dir(neuron.State_) if not "__" in p]
state_vars = {p: getattr(neuron, "get_" + p)() for p in state_list}

return parameters, state_vars
return parameters, internals, state_vars

@classmethod
def get_neuron_parameters_and_state(cls, nestml_file_name: str) -> tuple[dict, dict]:
def get_neuron_numerical_initial_values(cls, nestml_file_name: str) -> Tuple[Mapping[str, float], Mapping[str, float], Mapping[str, float]]:
r"""
Get the parameters for the given neuron model. The code is generated for the model for Python standalone target
The parameters and state variables are then queried by creating the neuron in Python standalone simulator.
Get the numerical values of the parameters, internals, and state variables for the given neuron model.

Internally, code is generated for the model for the Python standalone target, and then the value is read off by instantiating the resulting code.

:param nestml_file_name: File name of the neuron model
:return: A dictionary of parameters and state variables
:return: Dictionaries mapping parameters, internals and state variables to their numerical initial values
"""
parameters, state = cls._get_model_parameters_and_state(nestml_file_name)
parameters, internals, state = cls._get_model_parameters_and_state(nestml_file_name)

if not parameters or not state:
Logger.log_message(None, -1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,29 +127,30 @@ class Neuron_{{neuronName}}(Neuron):
self.S_ = self.State_()
self.V_ = self.Variables_()
self.B_ = self.Buffers_()
self._timestep = timestep

{%- if parameter_vars_with_iv|length > 0 %}
{% if parameter_vars_with_iv|length > 0 %}
# initial values for parameters
{%- filter indent(4) %}
{%- for variable in parameter_vars_with_iv %}
{%- set variable_symbol = neuron.get_scope().resolve_to_symbol(variable.get_name(), SymbolKind.VARIABLE) %}
{%- include "directives_py/MemberInitialization.jinja2" %}
{%- endfor %}
{%- endfilter %}
{%- filter indent(4) %}
{%- for variable in parameter_vars_with_iv %}
{%- set variable_symbol = neuron.get_scope().resolve_to_symbol(variable.get_name(), SymbolKind.VARIABLE) %}
{%- include "directives_py/MemberInitialization.jinja2" %}
{%- endfor %}
{%- endfilter %}
{%- endif %}

{%- if neuron.get_state_symbols()|length > 0 %}
# initial values for internals
self.recompute_internal_variables(self._timestep)
{% if neuron.get_state_symbols()|length > 0 %}
# initial values for state variables
{%- filter indent(4) %}
{%- for variable_symbol in neuron.get_state_symbols() %}
{%- set variable = utils.get_variable_by_name(astnode, variable_symbol.get_symbol_name()) %}
{%- include "directives_py/MemberInitialization.jinja2" %}
{%- endfor %}
{%- endfilter %}
{%- filter indent(4) %}
{%- for variable_symbol in neuron.get_state_symbols() %}
{%- set variable = utils.get_variable_by_name(astnode, variable_symbol.get_symbol_name()) %}
{%- include "directives_py/MemberInitialization.jinja2" %}
{%- endfor %}
{%- endfilter %}
{%- endif %}

self._timestep = timestep
self.recompute_internal_variables(self._timestep)

def get_model(self) -> str:
return "{{neuronName}}"
Expand Down
Loading