Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 483f9d9

Browse files
pramodkiomaganaris
andauthored
Add SEClamp support in CoreNEURON (#381)
* Add SEClamp support in CoreNEURON - add svclmp.mod mod file from NEURON - update registeration callbacks - expose at_time in the header file * Fixed compilation issue for GPU with at_time and updated NMODL commit * Added definition of at_time in nrnoc_ml.ispc * Small fix for at_time declaration outside ispc Co-authored-by: Ioannis Magkanaris <iomagkanaris@gmail.com>
1 parent a3797b9 commit 483f9d9

File tree

5 files changed

+124
-5
lines changed

5 files changed

+124
-5
lines changed

coreneuron/mechanism/mech/cfile/cabvars.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ extern void capacitance_reg(void), _passive_reg(void),
3232
#if EXTRACELLULAR
3333
extracell_reg_(void),
3434
#endif
35-
_stim_reg(void), _hh_reg(void), _netstim_reg(void), _expsyn_reg(void), _exp2syn_reg(void);
35+
_stim_reg(void), _hh_reg(void), _netstim_reg(void), _expsyn_reg(void), _exp2syn_reg(void), _svclmp_reg(void);
3636

3737
static void (*mechanism[])(void) = {/* type will start at 3 */
3838
capacitance_reg, _passive_reg,
3939
#if EXTRACELLULAR
4040
/* extracellular requires special handling and must be type 5 */
4141
extracell_reg_,
4242
#endif
43-
_stim_reg, _hh_reg, _expsyn_reg, _netstim_reg, _exp2syn_reg, 0};
43+
_stim_reg, _hh_reg, _expsyn_reg, _netstim_reg, _exp2syn_reg, _svclmp_reg, 0};
4444

4545
} // namespace coreneuron
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
TITLE svclmp.mod
2+
COMMENT
3+
Single electrode Voltage clamp with three levels.
4+
Clamp is on at time 0, and off at time
5+
dur1+dur2+dur3. When clamp is off the injected current is 0.
6+
The clamp levels are amp1, amp2, amp3.
7+
i is the injected current, vc measures the control voltage)
8+
Do not insert several instances of this model at the same location in order to
9+
make level changes. That is equivalent to independent clamps and they will
10+
have incompatible internal state values.
11+
The electrical circuit for the clamp is exceedingly simple:
12+
vc ---'\/\/`--- cell
13+
rs
14+
15+
Note that since this is an electrode current model v refers to the
16+
internal potential which is equivalent to the membrane potential v when
17+
there is no extracellular membrane mechanism present but is v+vext when
18+
one is present.
19+
Also since i is an electrode current,
20+
positive values of i depolarize the cell. (Normally, positive membrane currents
21+
are outward and thus hyperpolarize the cell)
22+
ENDCOMMENT
23+
24+
INDEPENDENT {t FROM 0 TO 1 WITH 1 (ms)}
25+
26+
DEFINE NSTEP 3
27+
28+
NEURON {
29+
POINT_PROCESS SEClamp
30+
ELECTRODE_CURRENT i
31+
RANGE dur1, amp1, dur2, amp2, dur3, amp3, rs, vc, i
32+
}
33+
34+
UNITS {
35+
(nA) = (nanoamp)
36+
(mV) = (millivolt)
37+
(uS) = (microsiemens)
38+
}
39+
40+
41+
PARAMETER {
42+
rs = 1 (megohm) <1e-9, 1e9>
43+
dur1 (ms) amp1 (mV)
44+
dur2 (ms) <0,1e9> amp2 (mV)
45+
dur3 (ms) <0,1e9> amp3 (mV)
46+
}
47+
48+
ASSIGNED {
49+
v (mV) : automatically v + vext when extracellular is present
50+
i (nA)
51+
vc (mV)
52+
tc2 (ms)
53+
tc3 (ms)
54+
on
55+
}
56+
57+
INITIAL {
58+
tc2 = dur1 + dur2
59+
tc3 = tc2 + dur3
60+
on = 0
61+
}
62+
63+
BREAKPOINT {
64+
SOLVE icur METHOD after_cvode
65+
vstim()
66+
}
67+
68+
PROCEDURE icur() {
69+
if (on) {
70+
i = (vc - v)/rs
71+
}else{
72+
i = 0
73+
}
74+
}
75+
76+
COMMENT
77+
The SOLVE of icur() in the BREAKPOINT block is necessary to compute
78+
i=(vc - v(t))/rs instead of i=(vc - v(t-dt))/rs
79+
This is important for time varying vc because the actual i used in
80+
the implicit method is equivalent to (vc - v(t)/rs due to the
81+
calculation of di/dv from the BREAKPOINT block.
82+
The reason this works is because the SOLVE statement in the BREAKPOINT block
83+
is executed after the membrane potential is advanced.
84+
85+
It is a shame that vstim has to be called twice but putting the call
86+
in a SOLVE block would cause playing a Vector into vc to be off by one
87+
time step.
88+
ENDCOMMENT
89+
90+
PROCEDURE vstim() {
91+
on = 1
92+
if (dur1) {at_time(dur1)}
93+
if (dur2) {at_time(tc2)}
94+
if (dur3) {at_time(tc3)}
95+
if (t < dur1) {
96+
vc = amp1
97+
}else if (t < tc2) {
98+
vc = amp2
99+
}else if (t < tc3) {
100+
vc = amp3
101+
}else {
102+
vc = 0
103+
on = 0
104+
}
105+
icur()
106+
}
107+

coreneuron/mechanism/membfunc.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,11 @@ extern void hoc_malchk(void); /* just a stub */
196196
extern void* hoc_Emalloc(size_t);
197197

198198
} // namespace coreneuron
199+
200+
/*
201+
* at_time function declared outside of coreneuron namespace
202+
* because it can be also called from ISPC code. That's also
203+
* the reason for extern "C".
204+
*/
205+
#pragma acc routine seq
206+
extern "C" int at_time(coreneuron::NrnThread*, double);

coreneuron/mechanism/nrnoc_ml.ispc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,7 @@ struct NrnThread {
166166
void* mapping;
167167
};
168168

169-
extern uniform double ispc_celsius;
169+
extern uniform double ispc_celsius;
170+
171+
extern "C"
172+
int at_time(NrnThread* nt, varying double te);

coreneuron/network/cvodestb.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,12 @@ void fixed_play_continuous(NrnThread* nt) {
105105
}
106106
}
107107

108-
int at_time(NrnThread* nt, double te) {
108+
} // namespace coreneuron
109+
110+
extern "C" int at_time(coreneuron::NrnThread* nt, double te) {
109111
double x = te - 1e-11;
110112
if (x <= nt->_t && x > (nt->_t - nt->_dt)) {
111113
return 1;
112114
}
113115
return 0;
114116
}
115-
} // namespace coreneuron

0 commit comments

Comments
 (0)