Sounds like a perfect setting for use of the VecStim class. Create a new directory and copy the files called vecevent* from nrn_x.x/share/nrn/examples/nrniv/netcon into it. Examine the contents of vecevent.mod and vecevent.hoc and think about what this implies for your particular application.
Assuming that:
1. you have a program that is organized like this:
--model specification code (specifies biological properties that are represented)
--instrumentation code (specifies signal sources like synaptic mechanisms, SEClamps, IClamps, maybe Vector record, maybe some graphs etc.), where one of the IClamps is called stim, and this is the IClamp that you want use to deliver your 5000 current pulses
--control code (a run() statement, maybe statements that write results to output files etc.)
2. you have a file that contains the times at which you want current pulses to be delivered, and these times are sorted in increasing order
3. the pulse width is ton, and ton is shorter than the shortest interval between pulse start times
Given these assumptions, here's an outline of a first draft of what you need to do.
In the instrumentation code, after the statement that creates stim, insert the following:
Code: Select all
///// ensure that stim can deliver as many pulses as necessary, for as long as necessary
stim.del = 0
stim.dur = 1e9
stim.amp = 0
AMP = some_numerical_value_that_you_choose
///// procedure that, when called, starts or stops a pulse
pulseon = 0
proc dopulse() {
if (pulseon == 0) {
stim.amp = AMP
pulseon = 1
cvode.re_init() // because a parameter was changed
// launch an event that will turn pulse off after ton ms have elapsed
cvode.event(ton, "dopulse()")
} else {
stim.amp = 0
pulseon = 0
cvode.re_init() // because a parameter was changed
}
}
// the previous run may have stopped in the middle of a pulse
// so we must ensure that pulseon and stim.amp are both 0 at the start of each simulation
objref fih
fih = new FInitializeHandler("pulseon = 0 stim.amp = 0")
///// get pulse start times into a Vector
objref stimes
stimes = new Vector()
proc readvec() {
. . . statements that read the spike times from your file into stimes . . .
}
readvec()
///// use VecStim to play events into a NetCon that calls dopulse()
objref vs, nc, nil
vs = new VecStim()
vs.play(stimes)
nc = new NetCon(vs, nil)
nc.event("dopulse()")
This is only a first draft outline. You are going to want to read all about FInitializeHandler, the NetCon class's event() method, and the CVode class's event() method. After you have implemented and tested this code, you will probably want to change some things, like:
--how and where AMP is assigned a value. It's not very convenient to bury this assignment in the middle of a program. You might want to put this at the top of your program, or specify it on the command line when you launch NEURON, or read it from a file.
--how and where the name of the file that contains the pulse times is specified. You may have hard coded it as a specific character string in the middle of your program. It would be more convenient to use a string variable that is assigned a value at the start of your program, or pass the file name as an argument on the command line when you start NEURON.