I'm glad you have chosen NEURON for your work, and that you have found the NEURON Forum to be helpful.
That's good use of a custom xpanel to display and control stimulus parameters. Also nice control of the position (and scaling) of the graph.
Instead of debugging your code, I will use this occasion to address the task of how to modify code that works.
Before modifying code that works, it is best to identify what needs to be changed and what should be left unaltered. In this particular case, the stuff that needs to be changed is in the file stim.hoc, but not everything in that file needs to be changed. The part that should be left unaltered is the part that attaches the stimulus vector to is_xtra--i.e. everything from
ATTACHED__ = 0
to the end of proc attach_stim(). As per the comment in the original version of attach_stim(), is_xtra is GLOBAL, so it is only necessary to execute the Vector play statement one time.
This raises the side issue of whether it is a good idea to start introducing new variable names for stuff that already exists, e.g. the stimlus Vector stim_amp and its associated time Vector stim_time, procedure names, whatever else. It is usually a bad idea to start renaming things unless there is a compelling reason to do so. For one thing, it is possible that a variable declared and used in one file may be reused somewhere else. For another, it encourages confusion on the part of the programmer. Nontrivial programs often have more names than a Russian novel (even if programs doesn't force one to deal with unfamiliar diminutives, and variables are never called by their patronymics). Better to avoid arbitrary expansion of the name space.
"Well, I didn't want any of my new stuff to conflict with stuff that was in the original stim.hoc."
Fine, but the way to avoid such a conflict is to
1. copy the original initxstim.hoc to initbp.hoc
2. in initbp.hoc change the line
load_file("stim.hoc") // extracellular stimulus
to
// load_file("stim.hoc") // extracellular stimulus
load_file("stimbp.hoc") // biphasic stimulus
Then you can either
(1) copy the original stim.hoc to stimbp.hoc and make your changes in stimbp.hoc,
or, since you have already put some time & effort into your own code, you might want to
(2) rename your own stimulus code file as stimbp.hoc and work on its contents.
Returning to what parts of stim.hoc need to be changed--
The code you present can be easily modified for execution as a standalone program. Just comment out proc attachStim(), and also the line in proc setStim() that calls attachStim(). Then use NEURON to execute it, and play with the latency, pulse width, and interpulse interval.
And you will discover that noninteger values for any of these parameters results in ugly and unanticipated distortions of the stimulus. For example, specify a biphasic stimulus with latency 0.01 ms, pulse width 0.01 ms, and interpulse interval 0.01 ms, and what you get instead is a triangle wave that starts 0 ms, peaks at 1 ms, has an opposite peak at 3 ms, and ends at 4 ms.
proc stimWaveform() is far more complex than it has to be, and it expresses an algorithm that is doomed to fail grotesquely.
It's much easier to steal the proc stim_waveform() from the original stim.hoc and modify it. To see what is necessary, sketch a biphasic waveform and identify each point at which the waveform makes a sudden change of direction. Then place a dot at the origin and imagine another dot at time = 1 ms after the end of the biphasic waveform, stim = 0.* These are the 10 points whose coordinates you must append to the time and stimulus vectors. For a monophasic stimulus, the first 2 and the last 6 points all have stim values of 0. For a biphasic stimulus, the first 2, 5th and 6th, and 9th and 10th have stim values of 0.
You could modify stim_waveform() so that it constructs a complete biphasic waveform, then if BIPHASIC is 0, it sets the 7th and 8th stim values to 0. Or you could write more clever code that appends just enough points to each vector as needed for a monophasic or a biphasic waveform.
*--The last point at time = 1 ms after the end of the biphasic waveform, stim = 0, is necessary because of how NEURON now (version 6.2 and later) deals with interpolated Vector play--see
http://www.neuron.yale.edu/neuron/stati ... .html#play
So you need to give the waveform a flat tail or else NEURON will extrapolate an infinitely large third phase of the stimulus waveform. Talk about grotesque failures.
And to avoid the same, I must now modify the distributed code for stim_waveform() for the same reason--it will become
Code: Select all
proc stim_waveform() {
// this uses interpolated play
// index 0 1 2 3 4 5
// stim vec 0, 0, 1, 1, 0 0
// time vec 0, DEL, DEL, DEL+DUR, DEL+DUR, DEL+DUR+1
// really 0, $1, $1, $1+$2, $1+$2, $1+$2+1
// first the stim vector
stim_amp.resize(6)
stim_amp.fill(0)
stim_amp.x[2]=1
stim_amp.x[3]=1
stim_amp.mul($3)
// now the time vector
stim_time.resize(6)
stim_time.x[1]=$1
stim_time.x[2]=$1
stim_time.x[3]=$1+$2
stim_time.x[4]=$1+$2
stim_time.x[4]=$1+$2+1
}