File: impedance.rst

package info (click to toggle)
neuron 8.2.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,760 kB
  • sloc: cpp: 149,571; python: 58,465; ansic: 50,329; sh: 3,510; xml: 213; pascal: 51; makefile: 35; sed: 5
file content (346 lines) | stat: -rwxr-xr-x 12,980 bytes parent folder | download | duplicates (3)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
.. _impedanc:

         
Impedance
---------



.. class:: Impedance

        For calculating input and transfer impedances at an instant of time 
        Usage involves first defining a location either 
        for the current stimulus or else the voltage measuring electrode, then 
        computing the global transfer and input impedance function 
        at a particular	frequency, then retrieving values of the complex 
        transfer and input impedance at particular locations. 
         
        The default calculation (the only calculation prior to version 5.3) 
        is defined by di/dv only. i.e it assumes conductances depend only 
        locally on v and does not take into account the impedance contributions of gating state 
        differential equations. Specifically, the cable equation, 
        c*dv/dt = i(v), 
        where the d2v/dx2 compartmental terms are in i, yields the linearized impedance 
        matrix 
        [(jwc - di/dv)v = i0 ] * exp(jwt) 
        The di/dv terms, apart from the axial terms, 
        are defined by the current calculation in the BREAKPOINT 
        blocks of the membrane mechanisms. 
         
        In version 5.3 the calculation was extended to take into account effects of 
        other gating states. The calculation is currently limited to systems that can 
        be solved with the CVode method but can be extended to systems solvable by 
        the DASPK method. ie. currently one cannot deal with the extracellular mechanism 
        or :class:`LinearMechanism`. It would be easy to implement the LinearMechanism extension 
        and that would be the only way one could handle non-local interactions such 
        as gap junctions. The extension takes into account not only di/dv but also 
        di/ds, ds'/dv and ds'/ds contributions to the impedance where s are all the 
        other states of the membrane mechanisms. i.e the system can be written 

        .. code-block::
            none

            	|c 0| * d/dt |v| = |i(v,s)| 
            	|0 1|        |s|   |f(v,x)| 

        which is formally similar to the original. 
        E.g. the hh mechanism has a sodium 
        channel defined by 

        .. code-block::
            none

            	ina = gnabar*m^3*h*(v - ena) 
            	m' = (minf - m)/mtau 
            	h' = (hinf - h)/htau 

        the only thing contributed (one compartment) by the default method is 

        .. code-block::
            none

            	(jwc + gnabar*m^3*h) * v = i0 

        but the full linearized method contributes a matrix of terms like 

        .. code-block::
            none

            	(jwc + gnabar*m^3*h)   gnabar*3*m^2*h*(v-ena)   gnabar*m^3*(v-ena) 
            	-d((minf - m)/mtau)/dv (jw - 1/mtau) 
            	-d((hinf - h)/htau)/dv                          (jw - 1/htau) 

        associated with the vector of states (v, m, h) 
         
        The extended full impedance calculation is invoked with an extra argument 
        to the :meth:`Impedance.compute` function. One should also review the 
        :meth:`Impedance.deltafac` method which defines the accuracy of the calculation. 
         

----



.. method:: Impedance.loc


    Syntax:
        ``.loc(x, sec=section)``


    Description:
        A fixed current stimulus or voltage electrode location 
        at position 0<=x<=1 of the specified section. 
        This is needed for the transfer impedance calculation. Note that 
        transfer impedances obey the relation 
        \ ``v(x)/i(loc) == v(loc)/i(x)`` where *loc* is the fixed location and 
        x ranges over every position of every section. 

         

----



.. method:: Impedance.compute


    Syntax:
        ``.compute(freq)``

        ``.compute(freq, 1)``
        
        ``.compute(freg, 1, maxiter=500)``


    Description:
        Transfer impedance between location specified above and any other 
        location is computed. Also the input impedance at all locations 
        is computed -- \ ``v(x)/i(x)`` 
        Frequency specified in Hz. 
        All membrane conductances are computed and used in the 
        calculation as if \ :func:`fcurrent()` was called. 
        The compute call is expensive but as a rule of thumb is not 
        as expensive as \ :func:`fadvance()`. 
         
        Since version 5.3, when the second argument is 1, an extended impedance 
        calculation is performed which takes into account the effect of 
        differential gating states. ie. the linearized cy' = f(y) system is used 
        where y is all the membrane potentials plus all the states in KINETIC and 
        DERIVATIVE blocks of membrane mechanisms. Currently, the system must 
        be computable with the Cvode method, i.e.extracellular and 
        LinearMechanism are not allowed. See :meth:`Impedance.deltafac` 
         
        Note that the extended impedance calculation may involve a singular matrix 
        because of the negative resistance contributions of excitable channels. 

        If the extended impedance calculation has been chosen (second arg = 1)
        then parallel gap junction effects will be taken into account.
        But for parallel gap junctions, there are several qualifications:

        One and only one rank can have a stimulus location. :meth:`Impedance.loc`
        can be used with an arg of -1 to remove the stimulus location on
        a rank.

        Every rank must participate in the call to compute (because of the use of
	MPI collective calls to carry out the impedance calculation). Note that only the
        freq arg value on the rank that has a location matters. If not all ranks have the
        second arg value of 1, the machine will hang in an MPI collective call.

        Not more than 5 types of gap junction POINT_PROCESS mechanisms can be instantiated.
        If any POINT_PROCESS instance participates in a gap junction
        (via :meth:`ParallelContext.target_var`) then all instances of that type
        must participate in gap junctions.

        Only :meth:`Impedance.transfer` and :meth:`Impedance.transfer_phase` can be used
        to access the impedance values.
        Ranks do not have to participate in the calls to the those two
        methods since no MPI collective calls are involved. After
        :meth:`Impedance.compute` is called, the transfer impedance is available at any
        cell location and multiple calls from a rank are allowed. Note that if the stimulus
        location is at location x and the transfer impedance is obtained at location x and
        y, the input impedance is known only at location x (equal to the transfer impedance)
        and the voltage ratio is known only at x and y. Note that the voltage ratio at
        x is trivially 1.0, and the voltage at y, given that x is voltage clamped to a 1mV
        sine wave with freq, is transfer(y)/transfer(x) . Unfortunately this is the opposite
        of the definition given for :meth:`Impedance.ratio` which voltage clamped y
        and recorded at x. I regret
        the original convention which was an artifact of
        :meth:`Impedance.compute` with args (freq, 0) calculating at one time, not only all the transfer
        impedances, but also all the input impedances at every location.  The problem with
        the original convention for :meth:`Impedance.ratio`, and also with
        :meth:`Impedance.input`, when the second :meth:`Impedance.compute` arg is 1,
        is that their use necessitates a solve with a moved input stimulus location
        specified by their argument. This is very inconvenient in a parallel context, as
        that solve would require the participation of all the ranks where all the args except
        one would have to be -1.  An error message will be generated if one attempts to use the
        ratio or input methods in the context of parallel gap junctions when nhost > 1.

        Impedance calculations with parallel gap junctions use the
        Jacobi iterative method to solve the linear matrix equation.
        This method converges linearly and the number of iterations
        required is proportional to the gap junction strength. Up to 500 iterations
        are allowed before an error message is generated. Iteration stops when no state
        changes more than 1e-9 after an iteration. It is expected that the number of
        iterations will be quite modest with realistic gap junction conductances (a dozen
        or so). A third argument to .compute specifies the maximum number of iterations
        (default 500).


    .. warning::
         
        There are many limitations to the extended linearization of the 
        complete system. It basically handles only voltage sensitive 
        density channels where the gating states are defined by 
        DERIVATIVE or KINETIC blocks. Prominent limitations are: 
         
        extracellular mechanism not allowed. 
         
        LinearMechanism not allowed. 
         
        Because we are not doing the complete full df/dy calculation, there 
        may be interactions between states that are not computed.
        An example is  where ion concentration 
        equations are voltage sensitive in one mechanism and then the ionic 
        current is concentration sensitive in another mechanism. ie. the 
        typical way NEURON deals with ionic concentration coupling to current 
        is not handled. 
         

         

----



.. method:: Impedance.transfer


    Syntax:
        ``.transfer(x, sec=section)``


    Description:
        absolute amplitude of the transfer impedance between the position 
        specified in the \ ``loc(x)`` call above and 0<=x<=1 of the
        specified section at the freq specified by a previous 
        compute(freq). The value returned can be thought of as either 
        \ ``|v(loc)/i(x)| or |v(x)/i(loc)|`` 
        Probably the more useful way of thinking about it is to assume 
        a current stimulus of 1nA injected at x and the voltage in mV 
        recorded at loc. 
         
        Return value has the units of 
        Megohms and can be thought of as the amplitude of the voltage (mV) 
        at one location	that would result from the injection of 1nA at the 
        other. 

         

----



.. method:: Impedance.input


    Syntax:
        ``.input(x, sec=section)``


    Description:
        absolute amplitude of \ ``v(x)/i(x)`` of the specified section 

         

----



.. method:: Impedance.ratio


    Syntax:
        ``.ratio(x)``


    Description:
        \ ``|v(loc)/v(x)|`` Think of it as voltage clamping to 1mV at x at some 
        frequency and recording the voltage at loc. 

         

----



.. method:: Impedance.transfer_phase


    Syntax:
        ``.transfer_phase(x)``


    Description:
        phase of transfer impedance. The phase is modulo 2Pi in the range 
        -Pi to +Pi so as one moves away from the loc remember that the 
        actual phase can become less than -Pi. If the amplitude is very 
        small the phase may be inaccurate and cannot be computed at all 
        if the amplitude is 0. 

         

----



.. method:: Impedance.input_phase


    Syntax:
        ``.input_phase(x)``


    Description:
        phase of input impedance. 
         
        Note: Impedance makes heavy use of memory since four complex 
        vectors are allocated with size equal to the total number of 
        segments. After compute is called two of these vectors holds 
        the input and transfer impedance for a given loc, freq, and 
        neuron state. Because 
        of the way results of calculations are stored it is very efficient 
        to access amp and phase; reasonably efficient to change freq or loc, 
        and inefficient to vary neuron state, eg, diameters. The last case 
        implies at least the overhead of a call like \ :func:`fcurrent()`.(actually 
        the present implementation calls \ :func:`fcurrent()` on every \ ``compute()`` call 
        but that could be fixed if increased performance was needed). 

         

----



.. method:: Impedance.deltafac


    Syntax:
        ``fac = imp.deltafac()``

        ``fac = imp.deltafac(fac)``


    Description:
        Gets or sets and gets the factor used in computing the numerical derivatives 
        during calculation of the extended full impedance. Jacobian elements are 
        calculated via the formula ``f(s+delta) - f(s))/delta`` where 
        delta is defined by fac * the state tolerance scale factor for cvode. 
        Note that default state tolerance scale factors are 1.0 except when 
        specifically declared in mod files or changed by calling 
        :meth:`CVode.atolscale`. The default delta factor is 0.001 which is consistent 
        with the factor used by the default impedance calculation. Note that the 
        factor for the default impedance calculation cannot be changed.