Sorry this reply is so delayed.
At the heart of the coba model cell is a point process called SpikeOut that acts like a triggerable single electrode voltage clamp. This clamp is controlled by a state machine that is implemented by a set of conditional statements in the NET_RECEIVE block of the NMODL code that defines the point process:
Code: Select all
NET_RECEIVE(w) {
if (flag == 1) {
net_event(t)
net_send(refrac, 2)
v = vrefrac
g = grefrac
}else if (flag == 2) {
g = 0
}else if (flag == 3) {
WATCH (v > thresh) 1
}
}
The original SpikeOut has two states: OFF, during which it is waiting for a threshold crossing and the clamp's conductance g is 0 so it delivers no current, and ON, during which the clamp's conductance g is supposed to be large enough to force local membrane potential very close to vrefrac regardless of what other current sources (including synapses and voltage-gated currents) might be doing. Its INITIAL block contains the statements
g = 0
net_send(0, 3)
which makes the clamp's series resistance (1/g) infinite and launches a self-event with flag=3. The self-event returns at t=0, i.e. immediately, and activates the WATCH statement in the NET_RECEIVE block so that local v is monitored throughout the rest of the simulation.
Threshold crossing (v rising above thresh) launches a self-event with flag=1 that returns immediately. This causes execution of the contents of NET_RECEIVE's first conditional clause, i.e.
1. net_event(t) launches an "output event" that is picked up by whatever NetCons have this point process as their spike source
2. net_send(refrac, 2) launches a self-event with flag=2 that will return refrac ms in the future
3. g is increased to grefrac, and v is set equal to vrefrac.
Arrival of the self-event with flag=2 forces g back to 0, so the clamp delivers no more current to the segment to which it is attached.
Only a few changes are needed to accomplish your goal. The most important are in the NET_RECEIVE block
Code: Select all
NET_RECEIVE(w) {
if (flag == 1) {
net_event(t)
net_send(refrac*(1-p), 2)
: v = vrefrac
vrev = vrefrac0
g = grefrac
}else if (flag == 2) {
net_send(refrac*p, 3)
vrev = vrefrac1
}else if (flag == 3) {
g = 0
}else if (flag == 4) {
WATCH (v > thresh) 1
}
}
This new state machine has three states: OFF, during which the mechanism is waiting for a threshold crossing and the clamp delivers no current, ON0 during which the clamp's conductance g is large and the command potential is set to vrefrac0, and ON1 during which the command potential is set to vrefrac1. In addition to executing the WATCH statement, NEURON's event system must now trigger three state transitions--from OFF to ON0, from ON0 to ON1, and from ON1 back to OFF--so the new mechanism needs four different self-events: one that arrives at t=0 and has flag=4 that is used to execute the WATCH statement, and self-events with flags=1, 2, and 3 to drive the state transitions.
As with the original SpikeOut mechanism, the new one has a post-spike refractory interval whose duration is specified by the refrac parameter. A new parameter p is introduced that controls the fraction of the refractory
interval that is spent in the ON1 state. If p=0, the clamp's command potential stays equal to vrefrac0 for the entire refractory interval; if p=1, the command potential stays equal to vrefrac1 for the entire refractory interval.
I call the new mechanism XSpikeOut; its source code is contained in the file xspikeout.mod which is one of the files contained in
https://www.neuron.yale.edu/ftp/ted/neu ... ikeout.zip
Download and expand this file, compile the mod file, and use NEURON to execute init.hoc. This is a model of a single compartment cell with pas to which an IClamp and an instance of XSpikeOut have been attached. It includes a panel that makes it easy to change the XSpikeOut's parameters.
Notice that, in addition to the changes that give XSpikeOut its additional state and new parameters, I have also "bulletproofed" it, i.e. included code that traps nonsense parameter values.