diff --git a/coreneuron/apps/main1.cpp b/coreneuron/apps/main1.cpp index 98e9ed79f..9d362cb91 100644 --- a/coreneuron/apps/main1.cpp +++ b/coreneuron/apps/main1.cpp @@ -185,13 +185,6 @@ void nrn_init_and_load_data(int argc, report_mem_usage("After MPI_Init"); } - // initialise default coreneuron parameters - initnrn(); - - // set global variables - // precedence is: set by user, globals.dat, 34.0 - celsius = corenrn_param.celsius; - #if CORENEURON_ENABLE_GPU if (!corenrn_param.gpu && corenrn_param.cell_interleave_permute == 2) { fprintf(stderr, @@ -218,9 +211,6 @@ void nrn_init_and_load_data(int argc, // full path of files.dat file std::string filesdat(corenrn_param.datpath + "/" + corenrn_param.filesdat); - // read the global variable names and set their values from globals.dat - set_globals(corenrn_param.datpath.c_str(), (corenrn_param.seed >= 0), corenrn_param.seed); - // set global variables for start time, timestep and temperature if (!corenrn_embedded) { t = checkPoints.restore_time(); @@ -514,8 +504,19 @@ extern "C" void mk_mech_init(int argc, char** argv) { out.close(); } - // reads mechanism information from bbcore_mech.dat + // initialise default coreneuron parameters + initnrn(); + + // set global variables + // precedence is: set by user, globals.dat, 34.0 + celsius = corenrn_param.celsius; + + // read the global variable names and set their values from globals.dat + // some global variables need to be read before the ion_reg to initialize + // properly the in-built ion mechanisms + set_globals(corenrn_param.datpath.c_str(), (corenrn_param.seed >= 0), corenrn_param.seed); + // reads mechanism information from bbcore_mech.dat mk_mech((corenrn_param.datpath).c_str()); } @@ -527,6 +528,11 @@ extern "C" int run_solve_core(int argc, char** argv) { std::vector> spikes_population_name_offset; bool reports_needs_finalize = false; + + // read agin the global variables to set the global variables defined by + // the mod files' mechanisms + set_globals(corenrn_param.datpath.c_str(), (corenrn_param.seed >= 0), corenrn_param.seed); + if (!corenrn_param.is_quiet()) { report_mem_usage("After mk_mech"); } diff --git a/coreneuron/io/global_vars.cpp b/coreneuron/io/global_vars.cpp index 128a1cdb9..3976d6831 100644 --- a/coreneuron/io/global_vars.cpp +++ b/coreneuron/io/global_vars.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "coreneuron/utils/randoms/nrnran123.h" #include "coreneuron/nrnconf.h" @@ -28,6 +29,8 @@ using N2V = std::map; static N2V* n2v; +extern std::unordered_map nrn_ion_init; + void hoc_register_var(DoubScal* ds, DoubVec* dv, VoidFunc*) { if (!n2v) { n2v = new N2V(); @@ -74,6 +77,9 @@ void set_globals(const char* path, bool cli_global_seed, int cli_global_seed_val } } } + if (static_cast(name).find("ion") != std::string::npos) { + nrn_ion_init[name] = *val; + } delete[] val; val = nullptr; } @@ -114,6 +120,9 @@ void set_globals(const char* path, bool cli_global_seed, int cli_global_seed_val nrn_assert(it->second.first == 0); *(it->second.second) = val; } + if (static_cast(name).find("ion") != std::string::npos) { + nrn_ion_init[name] = val; + } } else if (sscanf(line, "%[^[][%d]\n", name, &n) == 2) { if (strcmp(name, "0") == 0) { break; diff --git a/coreneuron/mechanism/eion.cpp b/coreneuron/mechanism/eion.cpp index 8bb167cf7..254223268 100644 --- a/coreneuron/mechanism/eion.cpp +++ b/coreneuron/mechanism/eion.cpp @@ -60,6 +60,15 @@ double nrn_ion_charge(int type) { return global_charge(type); } +std::unordered_map nrn_ion_init = { + {"nai0_na_ion", DEF_nai}, + {"nao0_na_ion", DEF_nao}, + {"ki0_k_ion", DEF_ki}, + {"ko0_k_ion", DEF_ko}, + {"cai0_ca_ion", DEF_cai}, + {"cao0_ca_ion", DEF_cao}, +}; + void ion_reg(const char* name, double valence) { char buf[7][50]; #define VAL_SENTINAL -10000. @@ -109,22 +118,30 @@ void ion_reg(const char* name, double valence) { sprintf(buf[1], "%so0_%s", name, buf[0]); if (strcmp("na", name) == 0) { na_ion = mechtype; - global_conci(mechtype) = DEF_nai; - global_conco(mechtype) = DEF_nao; + global_conci(mechtype) = nrn_ion_init["nai0_na_ion"]; + global_conco(mechtype) = nrn_ion_init["nao0_na_ion"]; global_charge(mechtype) = 1.; } else if (strcmp("k", name) == 0) { k_ion = mechtype; - global_conci(mechtype) = DEF_ki; - global_conco(mechtype) = DEF_ko; + global_conci(mechtype) = nrn_ion_init["ki0_k_ion"]; + global_conco(mechtype) = nrn_ion_init["ko0_k_ion"]; global_charge(mechtype) = 1.; } else if (strcmp("ca", name) == 0) { ca_ion = mechtype; - global_conci(mechtype) = DEF_cai; - global_conco(mechtype) = DEF_cao; + global_conci(mechtype) = nrn_ion_init["cai0_ca_ion"]; + global_conco(mechtype) = nrn_ion_init["cao0_ca_ion"]; global_charge(mechtype) = 2.; } else { - global_conci(mechtype) = DEF_ioni; - global_conco(mechtype) = DEF_iono; + if (nrn_ion_init[static_cast(buf[0])]) { + global_conci(mechtype) = nrn_ion_init[static_cast(buf[0])]; + } else { + global_conci(mechtype) = DEF_ioni; + } + if (nrn_ion_init[static_cast(buf[1])]) { + global_conco(mechtype) = nrn_ion_init[static_cast(buf[1])]; + } else { + global_conco(mechtype) = DEF_iono; + } global_charge(mechtype) = VAL_SENTINAL; } }