-
Notifications
You must be signed in to change notification settings - Fork 3
/
xtra.mod
148 lines (127 loc) · 4.21 KB
/
xtra.mod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
: $Id: xtra.mod,v 1.4 2014/08/18 23:15:25 ted Exp ted $
COMMENT
This mechanism is intended to be used in conjunction
with the extracellular mechanism. Pointers specified
at the hoc level must be used to connect the
extracellular mechanism's e_extracellular and i_membrane
to this mechanism's ex and im, respectively.
xtra does three useful things:
1. Serves as a target for Vector.play() to facilitate
extracellular stimulation. Assumes that one has initialized
a Vector to hold the time sequence of the stimulus current.
This Vector is to be played into the GLOBAL variable is
(GLOBAL so only one Vector.play() needs to be executed),
which is multiplied by the RANGE variable rx ("transfer
resistance between the stimulus electrode and the local
node"). This product, called ex in this mechanism, is the
extracellular potential at the local node, i.e. is used to
drive local e_extracellular.
2. Reports the contribution of local i_membrane to the
total signal that would be picked up by an extracellular
recording electrode. This is computed as the product of rx,
i_membrane (called im in this mechanism), and the surface area
of the local segment, and is reported as er. The total
extracellularly recorded potential is the sum of all er_xtra
over all segments in all sections, and is to be computed at
the hoc level, e.g. with code like
func fieldrec() { local sum
sum = 0
forall {
if (ismembrane("xtra")) {
for (x,0) sum += er_xtra(x)
}
}
return sum
}
Bipolar recording, i.e. recording the difference in potential
between two extracellular electrodes, can be achieved with no
change to either this NMODL code or fieldrec(); the values of
rx will reflect the difference between the potentials at the
recording electrodes caused by the local membrane current, so
some rx will be negative and others positive. The same rx
can be used for bipolar stimulation.
Multiple monopolar or bipolar extracellular recording and
stimulation can be accommodated by changing this mod file to
include additional rx, er, and is, and changing fieldrec()
to a proc.
3. Allows local storage of xyz coordinates interpolated from
the pt3d data. These coordinates are used by hoc code that
computes the transfer resistance that couples the membrane
to extracellular stimulating and recording electrodes.
Prior to NEURON 5.5, the SOLVE statement in the BREAKPOINT block
used METHOD cvode_t so that the adaptive integrators wouldn't miss
the stimulus. Otherwise, the BREAKPOINT block would have been called
_after_ the integration step, rather than from within cvodes/ida,
causing this mechanism to fail to deliver a stimulus current
when the adaptive integrator is used.
With NEURON 5.5 and later, this mechanism abandons the BREAKPOINT
block and uses the two new blocks BEFORE BREAKPOINT and
AFTER SOLVE, like this--
BEFORE BREAKPOINT { : before each cy' = f(y,t) setup
ex = is*rx*(1e6)
}
AFTER SOLVE { : after each solution step
er = (10)*rx*im*area
}
This ensures that the stimulus potential is computed prior to the
solution step, and that the recorded potential is computed after.
ENDCOMMENT
NEURON {
SUFFIX xtra
RANGE rx, er
RANGE x, y, z,LFPtemp
GLOBAL is,LFP
POINTER im, ex:
}
PARAMETER {
: default transfer resistance between stim electrodes and axon
rx = 1 (megohm) : mV/nA
x = 0 (1) : spatial coords
y = 0 (1)
z = 0 (1)
}
ASSIGNED {
v (millivolts)
is (milliamp)
ex (millivolts)
im (milliamp/cm2)
er (microvolts)
area (micron2)
LFP (millivolts)
LFPtemp(millivolts)
}
INITIAL {
ex = is*rx*(1e6)
er = (10)*rx*im*area
LFP = LFP + er
LFPtemp=LFP
: this demonstrates that area is known
: UNITSOFF
: printf("area = %f\n", area)
: UNITSON
}
: Use BREAKPOINT for NEURON 5.4 and earlier
: BREAKPOINT {
: SOLVE f METHOD cvode_t
: }
:
: PROCEDURE f() {
: : 1 mA * 1 megohm is 1000 volts
: : but ex is in mV
: ex = is*rx*(1e6)
: er = (10)*rx*im*area
: }
: With NEURON 5.5 and later, abandon the BREAKPOINT block and PROCEDURE f(),
: and instead use BEFORE BREAKPOINT and AFTER SOLVE
BEFORE BREAKPOINT { : before each cy' = f(y,t) setup
ex = is*rx*(1e6)
LFP = 0
LFPtemp=LFP
:print LFPtemp
}
AFTER SOLVE { : after each solution step
er = (10)*rx*im*area
LFP = LFP + er
LFPtemp=LFP
:print LFPtemp
}