Re: Modeling dynamic extracellular fields
Posted: Sat Apr 21, 2012 11:51 pm
You're working awfully hard at this. Let me ask you a question, the answer to which might make the task easier.
The hoc idiom for this is
But there may be a better approach, depending on your answer to my question above.
This block of codeattempts to position your stimulus waveform in time, right? It is far more efficient to take advantage of this fact:
"What does that mean?"
Well, for example, a pulse with amplitude 1 that arises from a baseline of 0 at t = 1 ms, and falls back to 0 at t = 2 ms, is specified by a tvec, vsrc pair with these contents:This will produce the same waveform regardless of whether dt is 1, 0.5, 0.1, or 0.025 ms (allowing, of course, for roundoff error--unless you are using adaptive integration, in which case the transitions will be at the exact times specified).
So you only need to
read your precomputed waveform into tvec and vsrc
add the "del" parameter to all elements of tvec
insert a "flat" segment at the very start and very end of your stimulus
"What's this 'flat' segment stuff?"
You want the field to be unchanged for the first del ms, right? and you also want it to stop changing after the end of your precomputed waveform, right? If there is a j such that
tvec.x[j+1] > tvec.x[j]
but
vsrc.x[j+1] == vsrc.x[j]
then the extracellular field will remain constant over the time interval tvec.x[j]..tvec.x[j+1]
And if these two points are the last two data points in your "stimulus waveform," Vector play will simply repeat the same vsrc.x value again and again for all t > tvec.x[j+1].
"Great. How do I do that?"
In semi-pseudocode:
In a separate thread I already suggested that you rethink these statements
for ii=0,del/dt + NtimeStepsStim + TimeAfterStim/dt - 1 { // LOOP through each time point
if (ii<=del/dt || ii>del/dt+NtimeStepsStim) {
and maybe some others.
edited by NTC at 12:09 PM EDT on 4/22/2012
Is the extracellular medium purely resistive and linear?Qroid_montreal wrote:I'm using Matlab to generate extracellular potential traces as a function of xyz location and time.
Right, because each pass through the loop in proc attach_stim() asserts stim_amp.play(&e_extracellular(x).... So the same Vector (stim_amp) will be played into all e_extracellular instances. The brute force fix is to revise the contents of the loop so that it does this (in pseudocode):looking at the space plots of e_extracellular, only the last line in the text file is being used and this is being applied to every segment identically
Code: Select all
for each section that has extracellular {
for each internal node of the current section {
create a new Vector
fill this with new data
play it into the current e_extracellular(x)
append it to a List
}
}
Code: Select all
objref veclist
veclist = new List() // so any top-level reference to veclist
// that is executed before the following proc is called
// does not complain that veclist is not a List
proc whatever() { localobj tmpvec
forall {
if (ismembrane("extracellular")) {
for (x,0) { // omit the zero area nodes (i.e. at 0 and 1)
tmpvec = new Vector()
. . . fill tmpvec with new data . . .
. . . play tmpvec into e_extracellular(x) . . .
veclist.append(tmpvec)
}
}
}
}
This block of code
Code: Select all
// when to start and stop stimulation?
del = .5 // start at del ms
TimeAfterStim = 10 // time after stimulation
tstop=del + dt*NtimeStepsStim + TimeAfterStim // stop
objref stim_amp, stim_time
stim_amp = new Vector()
stim_time = new Vector()
NtimeSteps = (del + dt*NtimeStepsStim + TimeAfterStim)/dt // total number of time points in simulation
// be careful that NtimeSteps is rounded-to-nearest-integer.
// since resize(n) floors n, use n+0.5.
// NB floor(n+0.5) is equivalent to round(n).
stim_amp.resize(NtimeSteps+0.5)
stim_time.resize(NtimeSteps+0.5)
(see the Programmer's Reference entry on the Vector class's play() method).On fadvance a transfer will take place if t will be (after the fadvance increment) equal or greater than the associated time of the next index.
"What does that mean?"
Well, for example, a pulse with amplitude 1 that arises from a baseline of 0 at t = 1 ms, and falls back to 0 at t = 2 ms, is specified by a tvec, vsrc pair with these contents:
Code: Select all
index tvec vsrc
0 0 0
1 1 0
2 1 1
3 2 1
4 2 0
5 3 0
So you only need to
read your precomputed waveform into tvec and vsrc
add the "del" parameter to all elements of tvec
insert a "flat" segment at the very start and very end of your stimulus
"What's this 'flat' segment stuff?"
You want the field to be unchanged for the first del ms, right? and you also want it to stop changing after the end of your precomputed waveform, right? If there is a j such that
tvec.x[j+1] > tvec.x[j]
but
vsrc.x[j+1] == vsrc.x[j]
then the extracellular field will remain constant over the time interval tvec.x[j]..tvec.x[j+1]
And if these two points are the last two data points in your "stimulus waveform," Vector play will simply repeat the same vsrc.x value again and again for all t > tvec.x[j+1].
"Great. How do I do that?"
In semi-pseudocode:
Code: Select all
increase the size of both Vectors by 2
rotate the contents of both Vectors one element "to the right"
tvec.x[0] = 0
tvec.x[size-1] = tvec.x[size-2] + 1 // size is the size of the resized tvec and vsrc
vsrc.x[0] = vsrc.x[1] // so the segment from tvec.x[0] to tvec.x[1] is flat
vsrc.x[size-1] = vsrc.x[size-2] + 1 // ditto for the segment from tvec.x[size-2] to tvec.x[size-1]
for ii=0,del/dt + NtimeStepsStim + TimeAfterStim/dt - 1 { // LOOP through each time point
if (ii<=del/dt || ii>del/dt+NtimeStepsStim) {
and maybe some others.
edited by NTC at 12:09 PM EDT on 4/22/2012