From f8b4f52b33e3be47ce48f4e833eec780ef18c208 Mon Sep 17 00:00:00 2001 From: WillemWybo Date: Tue, 7 Nov 2023 16:03:31 +0100 Subject: [PATCH 1/2] initial work to make voltage initialization user-configurable --- ...mpartmentcurrents_@NEURON_NAME@.cpp.jinja2 | 131 +++++++----- ...compartmentcurrents_@NEURON_NAME@.h.jinja2 | 196 ++++++++---------- .../compartmental_model_test.py | 5 +- .../resources/cm_default.nestml | 6 + 4 files changed, 177 insertions(+), 161 deletions(-) diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 index 98626fc96..28621d8bb 100644 --- a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 @@ -103,11 +103,11 @@ nest::{{ion_channel_name}}{{cm_unique_suffix}}::{{ion_channel_name}}{{cm_unique_ // channel parameter {{variable_type -}} {%- set variable = variable_info["ASTVariable"] %} {%- set rhs_expression = variable_info["rhs_expression"] %} -,{{- variable.name }}({{ printer_no_origin.print(rhs_expression) -}}) +, {{- variable.name }}({{ printer_no_origin.print(rhs_expression) -}}) {%- endfor %} {} -nest::{{ion_channel_name}}{{cm_unique_suffix}}::{{ion_channel_name}}{{cm_unique_suffix}}(const DictionaryDatum& channel_params) +nest::{{ion_channel_name}}{{cm_unique_suffix}}::{{ion_channel_name}}{{cm_unique_suffix}}( const DictionaryDatum& channel_params ) {%- for pure_variable_name, variable_info in channel_info["States"].items() %} // state variable {{pure_variable_name -}} @@ -121,61 +121,74 @@ nest::{{ion_channel_name}}{{cm_unique_suffix}}::{{ion_channel_name}}{{cm_unique_ // channel parameter {{variable_type -}} {%- set variable = variable_info["ASTVariable"] %} {%- set rhs_expression = variable_info["rhs_expression"] %} -,{{- variable.name }}({{ printer_no_origin.print(rhs_expression) -}}) +, {{- variable.name }}({{ printer_no_origin.print(rhs_expression) -}}) {%- endfor %} // update {{ion_channel_name}} channel parameters { - {%- for variable_type, variable_info in channel_info["Parameters"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set dynamic_variable = render_dynamic_channel_variable_name(variable_type, ion_channel_name) %} //have to remove??????????? - // {{ion_channel_name}} channel parameter {{dynamic_variable }} - if( channel_params->known( "{{variable.name}}" ) ) - {{variable.name}} = getValue< double >( channel_params, "{{variable.name}}" ); - {%- endfor %} + {%- for variable_type, variable_info in channel_info["Parameters"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + if( channel_params->known( "{{variable.name}}" ) ) + {{variable.name}} = getValue< double >( channel_params, "{{variable.name}}" ); + {%- endfor %} + if( channel_params->known( "V_init" ) ) + v_init = getValue< double >( channel_params, "V_init" ); } void -nest::{{ion_channel_name}}{{cm_unique_suffix}}::append_recordables(std::map< Name, double* >* recordables, - const long compartment_idx) +nest::{{ion_channel_name}}{{cm_unique_suffix}}::append_recordables( std::map< Name, double* >* recordables, const long compartment_idx ) { // add state variables to recordables map {%- for pure_variable_name, variable_info in channel_info["States"].items() %} {%- set variable = variable_info["ASTVariable"] %} ( *recordables )[ Name( "{{variable.name}}" + std::to_string(compartment_idx) )] = &{{variable.name}}; {%- endfor %} - ( *recordables )[ Name( "i_tot_{{ion_channel_name}}" + std::to_string(compartment_idx) )] = &i_tot_{{ion_channel_name}}; + ( *recordables )[ Name( "i_tot_{{ion_channel_name}}" + std::to_string(compartment_idx) )] = &i_tot_{{ion_channel_name}}; +} + +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +void nest::{{ion_channel_name}}{{cm_unique_suffix}}::calibrate() +{%- else %} +void nest::{{ion_channel_name}}{{cm_unique_suffix}}::pre_run_hook() +{%- endif %} +{ + // initialize all state variables with their asymptotic value for `v_init` + // For now, they are initialized at 0., but this should change + {%- for pure_variable_name, variable_info in channel_info["States"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; + {%- endfor %} } std::pair< double, double > nest::{{ion_channel_name}}{{cm_unique_suffix}}::f_numstep(const double v_comp{% for ode in channel_info["Dependencies"]["concentrations"] %}, double {{ode.lhs.name}}{% endfor %} {% for inline in channel_info["Dependencies"]["receptors"] %}, double {{inline.variable_name}}{% endfor %} {% for inline in channel_info["Dependencies"]["channels"] %}, double {{inline.variable_name}}{% endfor %}) { - double g_val = 0., i_val = 0.; + double g_val = 0., i_val = 0.; - if({%- for key_zero_param in channel_info["RootInlineKeyZeros"] %} {{ key_zero_param }} > 1e-9 && {%- endfor %} true ){ - {% if channel_info["ODEs"].items()|length %} double {{ printer_no_origin.print(channel_info["time_resolution_var"]) }} = Time::get_resolution().get_ms(); {% endif %} + if({%- for key_zero_param in channel_info["RootInlineKeyZeros"] %} {{ key_zero_param }} > 1e-9 && {%- endfor %} true ){ + {% if channel_info["ODEs"].items()|length %}double {{ printer_no_origin.print(channel_info["time_resolution_var"]) }} = Time::get_resolution().get_ms(); {% endif %} - {%- for ode_variable, ode_info in channel_info["ODEs"].items() %} - {%- for propagator, propagator_info in ode_info["transformed_solutions"][0]["propagators"].items() %} - double {{ propagator }} = {{ printer_no_origin.print(propagator_info["init_expression"]) }}; - {%- endfor %} - {%- for state, state_solution_info in ode_info["transformed_solutions"][0]["states"].items() %} - {{state}} = {{ printer_no_origin.print(state_solution_info["update_expression"]) }}; - {%- endfor %} + {%- for ode_variable, ode_info in channel_info["ODEs"].items() %} + {%- for propagator, propagator_info in ode_info["transformed_solutions"][0]["propagators"].items() %} + double {{ propagator }} = {{ printer_no_origin.print(propagator_info["init_expression"]) }}; {%- endfor %} + {%- for state, state_solution_info in ode_info["transformed_solutions"][0]["states"].items() %} + {{state}} = {{ printer_no_origin.print(state_solution_info["update_expression"]) }}; + {%- endfor %} + {%- endfor %} - {%- set inline_expression = channel_info["root_expression"] %} - {%- set inline_expression_d = channel_info["inline_derivative"] %} - // compute the conductance of the {{ion_channel_name}} channel - this->i_tot_{{ion_channel_name}} = {{ printer_no_origin.print(inline_expression.get_expression()) }}; - // derivative - double d_i_tot_dv = {{ printer_no_origin.print(inline_expression_d) }}; - - g_val = - d_i_tot_dv / 2.; - i_val = this->i_tot_{{ion_channel_name}} - d_i_tot_dv * v_comp / 2.; - } - return std::make_pair(g_val, i_val); + {%- set inline_expression = channel_info["root_expression"] %} + {%- set inline_expression_d = channel_info["inline_derivative"] %} + // compute the conductance of the {{ion_channel_name}} channel + i_tot_{{ion_channel_name}} = {{ printer_no_origin.print(inline_expression.get_expression()) }}; + // derivative + double d_i_tot_dv = {{ printer_no_origin.print(inline_expression_d) }}; + g_val = - d_i_tot_dv / 2.; + i_val = i_tot_{{ion_channel_name}} - d_i_tot_dv * v_comp / 2.; + } + return std::make_pair(g_val, i_val); } {%- for function in channel_info["Functions"] %} @@ -183,9 +196,8 @@ std::pair< double, double > nest::{{ion_channel_name}}{{cm_unique_suffix}}::f_nu {%- endfor %} double nest::{{ion_channel_name}}{{cm_unique_suffix}}::get_current_{{ion_channel_name}}(){ - return this->i_tot_{{ion_channel_name}}; + return i_tot_{{ion_channel_name}}; } - // {{ion_channel_name}} channel end /////////////////////////////////////////////////////////// {% endfor %} //////////////////////////////////////////////////////////////////////////////// @@ -214,6 +226,8 @@ nest::{{synapse_name}}{{cm_unique_suffix}}::{{synapse_name}}{{cm_unique_suffix}} if( receptor_params->known( "{{param_name}}" ) ) {{param_name}} = getValue< double >( receptor_params, "{{param_name}}" ); {%- endfor %} + if( receptor_params->known( "V_init" ) ) + v_init = getValue< double >( receptor_params, "V_init" ); } void @@ -222,16 +236,16 @@ nest::{{synapse_name}}{{cm_unique_suffix}}::append_recordables(std::map< Name, d {%- for convolution, convolution_info in synapse_info["convolutions"].items() %} ( *recordables )[ Name( "{{convolution_info["kernel"]["name"]}}" + std::to_string(syn_idx) )] = &{{convolution}}; {%- endfor %} - ( *recordables )[ Name( "i_tot_{{synapse_name}}" + std::to_string(syn_idx) )] = &i_tot_{{synapse_name}}; + ( *recordables )[ Name( "i_tot_{{synapse_name}}" + std::to_string(syn_idx) )] = &i_tot_{{synapse_name}}; } + {%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} void nest::{{synapse_name}}{{cm_unique_suffix}}::calibrate() {%- else %} void nest::{{synapse_name}}{{cm_unique_suffix}}::pre_run_hook() {%- endif %} { - const double {{render_time_resolution_variable(synapse_info)}} = Time::get_resolution().get_ms(); // set propagators to ode toolbox returned value @@ -317,10 +331,9 @@ std::pair< double, double > nest::{{synapse_name}}{{cm_unique_suffix}}::f_numste } {%- endfor %} - double nest::{{synapse_name}}{{cm_unique_suffix}}::get_current_{{synapse_name}}(){ - return this->i_tot_{{synapse_name}}; - } - +double nest::{{synapse_name}}{{cm_unique_suffix}}::get_current_{{synapse_name}}(){ + return this->i_tot_{{synapse_name}}; +} // {{synapse_name}} synapse end /////////////////////////////////////////////////////////// {%- endfor %} @@ -366,13 +379,15 @@ nest::{{ concentration_name }}{{cm_unique_suffix}}::{{ concentration_name }}{{cm {%- endfor %} // update {{ concentration_name }} concentration parameters { - {%- for variable_type, variable_info in concentration_info["Parameters"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set dynamic_variable = render_dynamic_channel_variable_name(variable_type, concentration_name) %} //have to remove??????????? - // {{ concentration_name }} concentration parameter {{dynamic_variable }} - if( concentration_params->known( "{{variable.name}}" ) ) - {{variable.name}} = getValue< double >( concentration_params, "{{variable.name}}" ); - {%- endfor %} + {%- for variable_type, variable_info in concentration_info["Parameters"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set dynamic_variable = render_dynamic_channel_variable_name(variable_type, concentration_name) %} + // {{ concentration_name }} concentration parameter {{dynamic_variable }} + if( concentration_params->known( "{{variable.name}}" ) ) + {{variable.name}} = getValue< double >( concentration_params, "{{variable.name}}" ); + {%- endfor %} + if( concentration_params->known( "{{ concentration_name }}_init" ) ) + {{ concentration_name }}_init = getValue< double >( concentration_params, "{{ concentration_name }}_init" ); } void @@ -384,7 +399,22 @@ nest::{{ concentration_name }}{{cm_unique_suffix}}::append_recordables(std::map< {%- set variable = variable_info["ASTVariable"] %} ( *recordables )[ Name( "{{variable.name}}" + std::to_string(compartment_idx) )] = &{{variable.name}}; {%- endfor %} - ( *recordables )[ Name( "{{concentration_name}}" + std::to_string(compartment_idx) )] = &{{concentration_name}}; + ( *recordables )[ Name( "{{concentration_name}}" + std::to_string(compartment_idx) )] = &{{concentration_name}}; +} + +{%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} +void nest::{{synapse_name}}{{cm_unique_suffix}}::calibrate() +{%- else %} +void nest::{{synapse_name}}{{cm_unique_suffix}}::pre_run_hook() +{%- endif %} +{ + // states + {%- for pure_variable_name, variable_info in concentration_info["States"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; + {%- endfor %} + {{ concentration_name }} = {{ concentration_name }}_init; } void nest::{{ concentration_name }}{{cm_unique_suffix}}::f_numstep(const double v_comp{% for ode in concentration_info["Dependencies"]["concentrations"] %}, double {{ode.lhs.name}}{% endfor %} @@ -412,6 +442,5 @@ void nest::{{ concentration_name }}{{cm_unique_suffix}}::f_numstep(const double double nest::{{concentration_name}}{{cm_unique_suffix}}::get_concentration_{{concentration_name}}(){ return this->{{concentration_name}}; } - // {{concentration_name}} concentration end /////////////////////////////////////////////////////////// {% endfor %} diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 index 508d3331b..73729dcdd 100644 --- a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 @@ -41,59 +41,51 @@ namespace nest class {{ion_channel_name}}{{cm_unique_suffix}}{ private: - // states - {%- for pure_variable_name, variable_info in channel_info["States"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} - {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - - // parameters - {%- for pure_variable_name, variable_info in channel_info["Parameters"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} - {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - - // ion-channel root-inline value - double i_tot_{{ion_channel_name}} = 0; + // states + {%- for pure_variable_name, variable_info in channel_info["States"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; + {%- endfor %} + + // parameters + {%- for pure_variable_name, variable_info in channel_info["Parameters"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; + {%- endfor %} + + // initial voltage + double v_init = -75.; + + // ion-channel root-inline value + double i_tot_{{ion_channel_name}} = 0; public: - // constructor, destructor - {{ion_channel_name}}{{cm_unique_suffix}}(); - {{ion_channel_name}}{{cm_unique_suffix}}(const DictionaryDatum& channel_params); - ~{{ion_channel_name}}{{cm_unique_suffix}}(){}; + // constructor, destructor + {{ion_channel_name}}{{cm_unique_suffix}}(); + {{ion_channel_name}}{{cm_unique_suffix}}(const DictionaryDatum& channel_params); + ~{{ion_channel_name}}{{cm_unique_suffix}}(){}; - // initialization channel + // initialization channel {%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} - void calibrate() { + void calibrate(); {%- else %} - void pre_run_hook() { + void pre_run_hook(); {%- endif %} - // states - {%- for pure_variable_name, variable_info in channel_info["States"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} - {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - }; - void append_recordables(std::map< Name, double* >* recordables, - const long compartment_idx); - - // numerical integration step - std::pair< double, double > f_numstep( const double v_comp{% for ode in channel_info["Dependencies"]["concentrations"] %}, double {{ode.lhs.name}}{% endfor %}{% if channel_info["Dependencies"]["receptors"]|length %} - {% endif %}{% for inline in channel_info["Dependencies"]["receptors"] %}, double {{inline.variable_name}}{% endfor %}{% if channel_info["Dependencies"]["channels"]|length %} - {% endif %}{% for inline in channel_info["Dependencies"]["channels"] %}, double {{inline.variable_name}}{% endfor %}); - - // function declarations - -{%- for function in channel_info["Functions"] %} - {{ function_declaration.FunctionDeclaration(function) }}; -{%- endfor %} + void append_recordables( std::map< Name, double* >* recordables, const long compartment_idx ); - // root_inline getter - double get_current_{{ion_channel_name}}(); + // numerical integration step + std::pair< double, double > f_numstep( const double v_comp{% for ode in channel_info["Dependencies"]["concentrations"] %}, double {{ode.lhs.name}}{% endfor %}{% if channel_info["Dependencies"]["receptors"]|length %} + {% endif %}{% for inline in channel_info["Dependencies"]["receptors"] %}, double {{inline.variable_name}}{% endfor %}{% if channel_info["Dependencies"]["channels"]|length %} + {% endif %}{% for inline in channel_info["Dependencies"]["channels"] %}, double {{inline.variable_name}}{% endfor %}); + {%- for function in channel_info["Functions"] %} + {{ function_declaration.FunctionDeclaration(function) -}}; + {%- endfor %} + + // root_inline getter + double get_current_{{ion_channel_name}}(); }; {% endfor %} @@ -135,21 +127,22 @@ private: double {{param_name}}; {%- endfor %} - // states - {%- for pure_variable_name, variable_info in synapse_info["States"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} + // initialization voltage: + double v_init = 0.; + + // states + {%- for pure_variable_name, variable_info in synapse_info["States"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - double i_tot_{{synapse_name}} = 0; + {%- endfor %} + double i_tot_{{synapse_name}} = 0; // user declared internals in order they were declared, initialized via pre_run_hook() or calibrate() {%- for internal_name, internal_declaration in synapse_info["internals_used_declared"] %} double {{internal_name}}; {%- endfor %} - - // spike buffer RingBuffer* {{synapse_info["buffer_name"]}}_; @@ -185,11 +178,10 @@ public: // function declarations {%- for function in synapse_info["Functions"] %} {{ function_declaration.FunctionDeclaration(function, "") -}}; - {% endfor %} - // root_inline getter - double get_current_{{synapse_name}}(); + // root_inline getter + double get_current_{{synapse_name}}(); }; @@ -201,57 +193,53 @@ public: class {{ concentration_name }}{{cm_unique_suffix}}{ private: - // parameters - {%- for pure_variable_name, variable_info in concentration_info["Parameters"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} - {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - - // states - {%- for pure_variable_name, variable_info in concentration_info["States"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} - {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - - // concentration value (root-ode state) - double {{concentration_name}} = 0; + // parameters + {%- for pure_variable_name, variable_info in concentration_info["Parameters"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; + {%- endfor %} + + // states + {%- for pure_variable_name, variable_info in concentration_info["States"].items() %} + {%- set variable = variable_info["ASTVariable"] %} + {%- set rhs_expression = variable_info["rhs_expression"] %} + {{ render_variable_type(variable) }} {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; + {%- endfor %} + + // concentration initialization + {{ concentration_name }}_init = 0.; + + // concentration value (root-ode state) + double {{concentration_name}} = 0; public: - // constructor, destructor - {{ concentration_name }}{{cm_unique_suffix}}(); - {{ concentration_name }}{{cm_unique_suffix}}(const DictionaryDatum& concentration_params); - ~{{ concentration_name }}{{cm_unique_suffix}}(){}; + // constructor, destructor + {{ concentration_name }}{{cm_unique_suffix}}(); + {{ concentration_name }}{{cm_unique_suffix}}(const DictionaryDatum& concentration_params); + ~{{ concentration_name }}{{cm_unique_suffix}}(){}; - // initialization channel + // initialization channel {%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} - void calibrate() { + void calibrate() { {%- else %} - void pre_run_hook() { + void pre_run_hook() { {%- endif %} - // states - {%- for pure_variable_name, variable_info in concentration_info["States"].items() %} - {%- set variable = variable_info["ASTVariable"] %} - {%- set rhs_expression = variable_info["rhs_expression"] %} - {{ variable.name }} = {{ printer_no_origin.print(rhs_expression) }}; - {%- endfor %} - }; - void append_recordables(std::map< Name, double* >* recordables, - const long compartment_idx); - - // numerical integration step - void f_numstep( const double v_comp{% for ode in concentration_info["Dependencies"]["concentrations"] %}, double {{ode.lhs.name}}{% endfor %}{% if concentration_info["Dependencies"]["receptors"]|length %} - {% endif %}{% for inline in concentration_info["Dependencies"]["receptors"] %}, double {{inline.variable_name}}{% endfor %}{% if concentration_info["Dependencies"]["channels"]|length %} - {% endif %}{% for inline in concentration_info["Dependencies"]["channels"] %}, double {{inline.variable_name}}{% endfor %}); - - // function declarations + void append_recordables(std::map< Name, double* >* recordables, + const long compartment_idx); + + // numerical integration step + void f_numstep( const double v_comp{% for ode in concentration_info["Dependencies"]["concentrations"] %}, double {{ode.lhs.name}}{% endfor %}{% if concentration_info["Dependencies"]["receptors"]|length %} + {% endif %}{% for inline in concentration_info["Dependencies"]["receptors"] %}, double {{inline.variable_name}}{% endfor %}{% if concentration_info["Dependencies"]["channels"]|length %} + {% endif %}{% for inline in concentration_info["Dependencies"]["channels"] %}, double {{inline.variable_name}}{% endfor %}); + + // function declarations {%- for function in concentration_info["Functions"] %} - {{ function_declaration.FunctionDeclaration(function) }}; + {{ function_declaration.FunctionDeclaration(function) }}; {%- endfor %} - // root_ode getter - double get_concentration_{{concentration_name}}(); + // root_ode getter + double get_concentration_{{concentration_name}}(); }; {% endfor %} @@ -275,7 +263,7 @@ private: std::vector < {{synapse_name}}{{cm_unique_suffix}} > {{synapse_name}}_syns_; {% endfor %} - //concentrations + //concentrations {% with %} {%- for concentration_name, concentration_info in conc_info.items() %} {{concentration_name}}{{cm_unique_suffix}} {{concentration_name}}{{concentration_suffix}}; @@ -321,7 +309,6 @@ public: // initialization of synapses {%- for synapse_name, synapse_info in syns_info.items() %} - // initialization of {{synapse_name}} synapses for( auto syn_it = {{synapse_name}}_syns_.begin(); syn_it != {{synapse_name}}_syns_.end(); ++syn_it ) @@ -417,15 +404,6 @@ public: std::pair< double, double > gi(0., 0.); double g_val = 0.; double i_val = 0.; -{%- for synapse_name, synapse_info in syns_info.items() %} - double {{synapse_name}}{{channel_suffix}}current_sum = 0; - for( auto syn_it = {{synapse_name}}_syns_.begin(); - syn_it != {{synapse_name}}_syns_.end(); - ++syn_it ) - { - {{synapse_name}}{{channel_suffix}}current_sum += syn_it->get_current_{{synapse_name}}(); - } -{% endfor %} {%- for concentration_name, concentration_info in conc_info.items() %} // computation of {{ concentration_name }} concentration diff --git a/tests/nest_compartmental_tests/compartmental_model_test.py b/tests/nest_compartmental_tests/compartmental_model_test.py index 619c9a7bb..e4ffc2e0e 100644 --- a/tests/nest_compartmental_tests/compartmental_model_test.py +++ b/tests/nest_compartmental_tests/compartmental_model_test.py @@ -519,4 +519,7 @@ def test_compartmental_model(self): if __name__ == "__main__": - unittest.main() + # unittest.main() + cmt = CMTest() + cmt.test_compartmental_model() + diff --git a/tests/nest_compartmental_tests/resources/cm_default.nestml b/tests/nest_compartmental_tests/resources/cm_default.nestml index f57d28903..cee73ad5a 100644 --- a/tests/nest_compartmental_tests/resources/cm_default.nestml +++ b/tests/nest_compartmental_tests/resources/cm_default.nestml @@ -143,10 +143,16 @@ neuron cm_default: g_norm_AN_NMDA real = 1. / ( -exp( -tp_AN_NMDA / tau_r_AN_NMDA ) + exp( -tp_AN_NMDA / tau_d_AN_NMDA ) ) input: + + + spikes_AMPA <- spike spikes_GABA <- spike spikes_NMDA <- spike spikes_AN <- spike output: + + + spike From 5a631a17d4db1738b57cfc0713b1a7fc388ccffa Mon Sep 17 00:00:00 2001 From: WillemWybo Date: Tue, 7 Nov 2023 16:38:36 +0100 Subject: [PATCH 2/2] fix compilation issues --- .../cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 | 10 +++++----- .../cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 index 28621d8bb..0463b057c 100644 --- a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.cpp.jinja2 @@ -131,7 +131,7 @@ nest::{{ion_channel_name}}{{cm_unique_suffix}}::{{ion_channel_name}}{{cm_unique_ {{variable.name}} = getValue< double >( channel_params, "{{variable.name}}" ); {%- endfor %} if( channel_params->known( "V_init" ) ) - v_init = getValue< double >( channel_params, "V_init" ); + V_init = getValue< double >( channel_params, "V_init" ); } void @@ -151,7 +151,7 @@ void nest::{{ion_channel_name}}{{cm_unique_suffix}}::calibrate() void nest::{{ion_channel_name}}{{cm_unique_suffix}}::pre_run_hook() {%- endif %} { - // initialize all state variables with their asymptotic value for `v_init` + // initialize all state variables with their asymptotic value for `V_init` // For now, they are initialized at 0., but this should change {%- for pure_variable_name, variable_info in channel_info["States"].items() %} {%- set variable = variable_info["ASTVariable"] %} @@ -227,7 +227,7 @@ nest::{{synapse_name}}{{cm_unique_suffix}}::{{synapse_name}}{{cm_unique_suffix}} {{param_name}} = getValue< double >( receptor_params, "{{param_name}}" ); {%- endfor %} if( receptor_params->known( "V_init" ) ) - v_init = getValue< double >( receptor_params, "V_init" ); + V_init = getValue< double >( receptor_params, "V_init" ); } void @@ -403,9 +403,9 @@ nest::{{ concentration_name }}{{cm_unique_suffix}}::append_recordables(std::map< } {%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} -void nest::{{synapse_name}}{{cm_unique_suffix}}::calibrate() +void nest::{{ concentration_name }}{{cm_unique_suffix}}::calibrate() {%- else %} -void nest::{{synapse_name}}{{cm_unique_suffix}}::pre_run_hook() +void nest::{{ concentration_name }}{{cm_unique_suffix}}::pre_run_hook() {%- endif %} { // states diff --git a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 index 73729dcdd..64589b78a 100644 --- a/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 +++ b/pynestml/codegeneration/resources_nest_compartmental/cm_neuron/cm_compartmentcurrents_@NEURON_NAME@.h.jinja2 @@ -56,7 +56,7 @@ private: {%- endfor %} // initial voltage - double v_init = -75.; + double V_init = -75.; // ion-channel root-inline value double i_tot_{{ion_channel_name}} = 0; @@ -128,7 +128,7 @@ private: {%- endfor %} // initialization voltage: - double v_init = 0.; + double V_init = 0.; // states {%- for pure_variable_name, variable_info in synapse_info["States"].items() %} @@ -208,7 +208,7 @@ private: {%- endfor %} // concentration initialization - {{ concentration_name }}_init = 0.; + double {{ concentration_name }}_init = 0.; // concentration value (root-ode state) double {{concentration_name}} = 0; @@ -221,9 +221,9 @@ public: // initialization channel {%- if nest_version.startswith("v2") or nest_version.startswith("v3.1") or nest_version.startswith("v3.2") or nest_version.startswith("v3.3") %} - void calibrate() { + void calibrate(); {%- else %} - void pre_run_hook() { + void pre_run_hook(); {%- endif %} void append_recordables(std::map< Name, double* >* recordables, const long compartment_idx);