8 #include <catch2/catch_test_macros.hpp>
21 using namespace nmodl;
22 using namespace visitor;
24 using namespace test_utils;
40 SymtabVisitor(
false).visit_program(*ast);
43 ConstantFolderVisitor().visit_program(*ast);
44 InlineVisitor().visit_program(*ast);
45 LocalVarRenameVisitor().visit_program(*ast);
46 SymtabVisitor(
true).visit_program(*ast);
49 SympyConductanceVisitor().visit_program(*ast);
52 CheckParentVisitor().check_ast(*ast);
65 SymtabVisitor().visit_program(*ast);
74 SymtabVisitor v_symtab;
75 v_symtab.visit_program(node);
78 SympyConductanceVisitor v_sympy1;
79 v_sympy1.visit_program(node);
80 v_symtab.visit_program(node);
81 v_sympy1.visit_program(node);
82 v_symtab.visit_program(node);
85 SympyConductanceVisitor v_sympy2;
86 v_sympy2.visit_program(node);
87 v_symtab.visit_program(node);
88 v_sympy1.visit_program(node);
89 v_symtab.visit_program(node);
90 v_sympy2.visit_program(node);
91 v_symtab.visit_program(node);
94 SCENARIO(
"Addition of CONDUCTANCE using SympyConductance visitor",
"[visitor][solver][sympy]") {
97 GIVEN(
"breakpoint block containing VERBATIM statement") {
98 std::string nmodl_text = R
"(
101 USEION ca READ eca WRITE ica
102 RANGE gCabar, gCa, ica
105 CONDUCTANCE gCa USEION ca
106 SOLVE states METHOD cnexp
114 std::string breakpoint_text = R"(
116 CONDUCTANCE gCa USEION ca
117 SOLVE states METHOD cnexp
130 GIVEN(
"breakpoint block containing IF/ELSE block") {
131 std::string nmodl_text = R
"(
134 USEION ca READ eca WRITE ica
135 RANGE gCabar, gCa, ica
138 CONDUCTANCE gCa USEION ca
139 SOLVE states METHOD cnexp
149 std::string breakpoint_text = R"(
151 CONDUCTANCE gCa USEION ca
152 SOLVE states METHOD cnexp
167 GIVEN(
"ion current, existing CONDUCTANCE hint & var") {
168 std::string nmodl_text = R
"(
171 USEION ca READ eca WRITE ica
172 RANGE gCabar, gCa, ica
182 gCabar = 0.00001 (S/cm2)
206 CONDUCTANCE gCa USEION ca
207 SOLVE states METHOD cnexp
222 std::string breakpoint_text = R"(
224 CONDUCTANCE gCa USEION ca
225 SOLVE states METHOD cnexp
235 GIVEN(
"ion current, no CONDUCTANCE hint, existing var") {
236 std::string nmodl_text = R
"(
239 USEION ca READ eca WRITE ica
240 RANGE gCabar, gCa, ica
250 gCabar = 0.00001 (S/cm2)
274 SOLVE states METHOD cnexp
289 std::string breakpoint_text = R"(
291 CONDUCTANCE gCa USEION ca
292 SOLVE states METHOD cnexp
297 THEN("Add CONDUCTANCE hint using existing var") {
302 GIVEN(
"ion current, no CONDUCTANCE hint, no existing var") {
303 std::string nmodl_text = R
"(
306 USEION ca READ eca WRITE ica
317 gCabar = 0.00001 (S/cm2)
340 SOLVE states METHOD cnexp
341 ica = (gCabar*m*m*h)*(v-eca)
354 std::string breakpoint_text = R"(
357 CONDUCTANCE g_ca_0 USEION ca
358 g_ca_0 = gCabar*h*pow(m, 2)
359 SOLVE states METHOD cnexp
360 ica = (gCabar*m*m*h)*(v-eca)
363 THEN("Add CONDUCTANCE hint with new local var") {
368 GIVEN(
"2 ion currents, 1 CONDUCTANCE hint, 1 existing var") {
369 std::string nmodl_text = R
"(
372 USEION ca READ eca WRITE ica
373 USEION na READ ena WRITE ina
374 RANGE gCabar, gNabar, ica, ina
384 gCabar = 0.00001 (S/cm2)
385 gNabar = 0.00005 (S/cm2)
410 CONDUCTANCE gCa USEION ca
411 SOLVE states METHOD cnexp
414 ina = (gNabar*m*h)*(v-eca)
427 std::string breakpoint_text = R"(
430 CONDUCTANCE g_na_0 USEION na
432 CONDUCTANCE gCa USEION ca
433 SOLVE states METHOD cnexp
436 ina = (gNabar*m*h)*(v-eca)
439 THEN("Add 1 CONDUCTANCE hint with new local var") {
444 GIVEN(
"2 ion currents, no CONDUCTANCE hints, 1 existing var") {
445 std::string nmodl_text = R
"(
448 USEION ca READ eca WRITE ica
449 USEION na READ ena WRITE ina
450 RANGE gCabar, gNabar, ica, ina
460 gCabar = 0.00001 (S/cm2)
461 gNabar = 0.00005 (S/cm2)
486 SOLVE states METHOD cnexp
489 ina = (gNabar*m*h)*(v-eca)
502 std::string breakpoint_text = R"(
505 CONDUCTANCE g_na_0 USEION na
506 CONDUCTANCE gCa USEION ca
508 SOLVE states METHOD cnexp
511 ina = (gNabar*m*h)*(v-eca)
514 THEN("Add 2 CONDUCTANCE hints, 1 with existing var, 1 with new local var") {
519 GIVEN(
"2 ion currents, no CONDUCTANCE hints, no existing vars") {
520 std::string nmodl_text = R
"(
523 USEION ca READ eca WRITE ica
524 USEION na READ ena WRITE ina
525 RANGE gCabar, gNabar, ica, ina
535 gCabar = 0.00001 (S/cm2)
536 gNabar = 0.00005 (S/cm2)
561 SOLVE states METHOD cnexp
562 ica = (gCabar*m*m*h)*(v-eca)
563 ina = (gNabar*m*h)*(v-eca)
576 std::string breakpoint_text = R"(
579 CONDUCTANCE g_na_0 USEION na
580 CONDUCTANCE g_ca_0 USEION ca
581 g_ca_0 = gCabar*h*pow(m, 2)
583 SOLVE states METHOD cnexp
584 ica = (gCabar*m*m*h)*(v-eca)
585 ina = (gNabar*m*h)*(v-eca)
588 THEN("Add 2 CONDUCTANCE hints with 2 new local vars") {
593 GIVEN(
"1 ion current, 1 nonspecific current, no CONDUCTANCE hints, no existing vars") {
594 std::string nmodl_text = R
"(
597 USEION ca READ eca WRITE ica
598 NONSPECIFIC_CURRENT ihcn
609 gCabar = 0.00001 (S/cm2)
634 SOLVE states METHOD cnexp
635 ica = (gCabar*m*m*h)*(v-eca)
636 ihcn = (0.1235*m*h)*(v-eca)
649 std::string breakpoint_text = R"(
653 CONDUCTANCE g_ca_0 USEION ca
654 g_ca_0 = gCabar*h*pow(m, 2)
656 SOLVE states METHOD cnexp
657 ica = (gCabar*m*m*h)*(v-eca)
658 ihcn = (0.1235*m*h)*(v-eca)
661 THEN("Add 2 CONDUCTANCE hints with 2 new local vars") {
666 GIVEN(
"1 ion current, 1 nonspecific current, no CONDUCTANCE hints, 1 existing var") {
667 std::string nmodl_text = R
"(
670 USEION ca READ eca WRITE ica
671 NONSPECIFIC_CURRENT ihcn
672 RANGE gCabar, ica, gihcn
682 gCabar = 0.00001 (S/cm2)
708 SOLVE states METHOD cnexp
710 ica = (gCabar*m*m*h)*(v-eca)
724 std::string breakpoint_text = R"(
728 CONDUCTANCE g_ca_0 USEION ca
729 g_ca_0 = gCabar*h*pow(m, 2)
730 SOLVE states METHOD cnexp
732 ica = (gCabar*m*m*h)*(v-eca)
736 THEN("Add 2 CONDUCTANCE hints, 1 using existing var, 1 with new local var") {
743 "2 ion currents, 1 nonspecific current, no CONDUCTANCE hints, indirect relation between "
745 std::string nmodl_text = R
"(
748 POINT_PROCESS ProbAMPANMDA
749 RANGE tau_r_AMPA, tau_d_AMPA, tau_r_NMDA, tau_d_NMDA
750 RANGE Use, u, Dep, Fac, u0, mg, NMDA_ratio
751 RANGE i, i_AMPA, i_NMDA, g_AMPA, g_NMDA, g, e
752 NONSPECIFIC_CURRENT i, i_AMPA,i_NMDA
754 RANGE synapseID, verboseLevel
757 tau_r_AMPA = 0.2 (ms) : dual-exponential conductance profile
758 tau_d_AMPA = 1.7 (ms) : IMPORTANT: tau_r < tau_d
759 tau_r_NMDA = 0.29 (ms) : dual-exponential conductance profile
760 tau_d_NMDA = 43 (ms) : IMPORTANT: tau_r < tau_d
761 Use = 1.0 (1) : Utilization of synaptic efficacy (just initial values! Use, Dep and Fac are overwritten by BlueBuilder assigned values)
762 Dep = 100 (ms) : relaxation time constant from depression
763 Fac = 10 (ms) : relaxation time constant from facilitation
764 e = 0 (mV) : AMPA and NMDA reversal potential
765 mg = 1 (mM) : initial concentration of mg2+
767 gmax = .001 (uS) : weight conversion factor (from nS to uS)
768 u0 = 0 :initial value of u, which is the running value of Use
769 NMDA_ratio = 0.71 (1) : The ratio of NMDA to AMPA
786 A_AMPA : AMPA state variable to construct the dual-exponential profile - decays with conductance tau_r_AMPA
787 B_AMPA : AMPA state variable to construct the dual-exponential profile - decays with conductance tau_d_AMPA
788 A_NMDA : NMDA state variable to construct the dual-exponential profile - decays with conductance tau_r_NMDA
789 B_NMDA : NMDA state variable to construct the dual-exponential profile - decays with conductance tau_d_NMDA
792 SOLVE state METHOD cnexp
794 g_AMPA = gmax*(B_AMPA-A_AMPA) :compute time varying conductance as the difference of state variables B_AMPA and A_AMPA
795 g_NMDA = gmax*(B_NMDA-A_NMDA) * mggate :compute time varying conductance as the difference of state variables B_NMDA and A_NMDA and mggate kinetics
797 i_AMPA = g_AMPA*(v-e) :compute the AMPA driving force based on the time varying conductance, membrane potential, and AMPA reversal
798 i_NMDA = g_NMDA*(v-e) :compute the NMDA driving force based on the time varying conductance, membrane potential, and NMDA reversal
802 A_AMPA' = -A_AMPA/tau_r_AMPA
803 B_AMPA' = -B_AMPA/tau_d_AMPA
804 A_NMDA' = -A_NMDA/tau_r_NMDA
805 B_NMDA' = -B_NMDA/tau_d_NMDA
808 std::string breakpoint_text = R"(
813 SOLVE state METHOD cnexp
815 g_AMPA = gmax*(B_AMPA-A_AMPA) :compute time varying conductance as the difference of state variables B_AMPA and A_AMPA
816 g_NMDA = gmax*(B_NMDA-A_NMDA) * mggate :compute time varying conductance as the difference of state variables B_NMDA and A_NMDA and mggate kinetics
818 i_AMPA = g_AMPA*(v-e) :compute the AMPA driving force based on the time varying conductance, membrane potential, and AMPA reversal
819 i_NMDA = g_NMDA*(v-e) :compute the NMDA driving force based on the time varying conductance, membrane potential, and NMDA reversal
823 THEN("Add 3 CONDUCTANCE hints, using existing vars") {
829 GIVEN(
"1 nonspecific current, no CONDUCTANCE hints, many eqs & a function involved") {
830 std::string nmodl_text = R
"(
832 GLOBAL tau_r_AMPA, E_AMPA
833 RANGE tau_d_AMPA, gmax_AMPA
835 GLOBAL tau_r_NMDA, tau_d_NMDA, E_NMDA
837 RANGE Use, Dep, Fac, Nrrp, u
838 RANGE tsyn, unoccupied, occupied
841 GLOBAL ljp_VDCC, vhm_VDCC, km_VDCC, mtau_VDCC, vhh_VDCC, kh_VDCC, htau_VDCC
842 RANGE gca_bar_VDCC, ica_VDCC
843 GLOBAL gamma_ca_CR, tau_ca_CR, min_ca_CR, cao_CR
844 GLOBAL tau_GB, gamma_d_GB, gamma_p_GB, rho_star_GB, tau_Use_GB, tau_effca_GB
845 RANGE theta_d_GB, theta_p_GB
847 RANGE enable_GB, depress_GB, potentiate_GB
848 RANGE Use_d_GB, Use_p_GB
849 GLOBAL p_gen_RW, p_elim0_RW, p_elim1_RW
850 RANGE enable_RW, synstate_RW
851 GLOBAL mg, scale_mg, slope_mg
852 RANGE vsyn, NMDA_ratio, synapseID, selected_for_report, verbose
853 NONSPECIFIC_CURRENT i
858 (uS) = (microsiemens)
865 FARADAY = (faraday) (coulomb)
867 R = (k-mole) (joule/degC)
880 FUNCTION nernst(ci(mM), co(mM), z) (mV) {
881 nernst = (1000) * R * (celsius + 273.15) / (z*FARADAY) * log(co/ci)
884 LOCAL Eca_syn, mggate, i_AMPA, gmax_NMDA, i_NMDA, Pf_NMDA, gca_bar_abs_VDCC, gca_VDCC
885 g_AMPA = (1e-3)*gmax_AMPA*(B_AMPA-A_AMPA)
886 i_AMPA = g_AMPA*(v-E_AMPA)
887 gmax_NMDA = gmax_AMPA*NMDA_ratio
888 mggate = 1 / (1 + exp(slope_mg * -(v)) * (mg / scale_mg))
889 g_NMDA = (1e-3)*gmax_NMDA*mggate*(B_NMDA-A_NMDA)
890 i_NMDA = g_NMDA*(v-E_NMDA)
891 Pf_NMDA = (4*cao_CR) / (4*cao_CR + (1/1.38) * 120 (mM)) * 0.6
892 ica_NMDA = Pf_NMDA*g_NMDA*(v-40.0)
893 gca_bar_abs_VDCC = gca_bar_VDCC * 4(um2)*PI*(3(1/um3)/4*volume_CR*1/PI)^(2/3)
894 gca_VDCC = (1e-3) * gca_bar_abs_VDCC * m_VDCC * m_VDCC * h_VDCC
895 Eca_syn = FARADAY*nernst(cai_CR, cao_CR, 2)
896 ica_VDCC = gca_VDCC*(v-Eca_syn)
898 i = i_AMPA + i_NMDA + ica_VDCC
901 std::string breakpoint_text = R"(
903 LOCAL Eca_syn, mggate, i_AMPA, gmax_NMDA, i_NMDA, Pf_NMDA, gca_bar_abs_VDCC, gca_VDCC, nernst_in_0, g__0
905 g__0 = (0.001*gmax_NMDA*mg*scale_mg*slope_mg*(A_NMDA-B_NMDA)*(E_NMDA-v)*exp(slope_mg*v)-0.001*gmax_NMDA*scale_mg*(A_NMDA-B_NMDA)*(mg+scale_mg*exp(slope_mg*v))*exp(slope_mg*v)+(g_AMPA+gca_VDCC)*pow(mg+scale_mg*exp(slope_mg*v), 2))/pow(mg+scale_mg*exp(slope_mg*v), 2)
906 g_AMPA = 1e-3*gmax_AMPA*(B_AMPA-A_AMPA)
907 i_AMPA = g_AMPA*(v-E_AMPA)
908 gmax_NMDA = gmax_AMPA*NMDA_ratio
909 mggate = 1/(1+exp(slope_mg*-v)*(mg/scale_mg))
910 g_NMDA = 1e-3*gmax_NMDA*mggate*(B_NMDA-A_NMDA)
911 i_NMDA = g_NMDA*(v-E_NMDA)
912 Pf_NMDA = (4*cao_CR)/(4*cao_CR+0.7246376811594204*120(mM))*0.6
913 ica_NMDA = Pf_NMDA*g_NMDA*(v-40.0)
914 gca_bar_abs_VDCC = gca_bar_VDCC*4(um2)*PI*(3(1/um3)/4*volume_CR*1/PI)^0.6666666666666666
915 gca_VDCC = 1e-3*gca_bar_abs_VDCC*m_VDCC*m_VDCC*h_VDCC
917 LOCAL ci_in_0, co_in_0, z_in_0
921 nernst_in_0 = 1000*R*(celsius+273.15)/(z_in_0*FARADAY)*log(co_in_0/ci_in_0)
923 Eca_syn = FARADAY*nernst_in_0
924 ica_VDCC = gca_VDCC*(v-Eca_syn)
926 i = i_AMPA+i_NMDA+ica_VDCC
929 THEN("Add 1 CONDUCTANCE hint using new var") {