Can IClamp be used in a for loop? Or can it be a vector?

Anything that doesn't fit elsewhere.
Post Reply
thisman

Can IClamp be used in a for loop? Or can it be a vector?

Post by thisman »

Hi Ted, Thanks for your last reply.
Assume I want to put a sequence of current clamps into a same point of a object, as well as the same amp and dur. The only difference is when (del) I put these inputs. I have tried two methods, for the first one I put stim in a for loop as below

Code: Select all

objectvar stim

proc do() { local i
  for i=0, 9 {
    axon stim = new IClamp(0.1)
    stim.del = 50*(i+1)
    stim.dur = 1
    stim.amp = 15
  }
}
but this program just put the last input into the object, which is when stim.del=500.
Then I tried to make stim as a vector, which looks like below

Code: Select all

objectvar stim
stim = new Vector()

proc do() { local i
  for i=0, 9 {
    axon stim.x[i] = new IClamp(0.1)
    stim.x[i].del = 50*(i+1)
    stim.x[i].dur = 1
    stim.x[i].amp = 15
  }
}
This time, there is no input at all.

I also tried "while", which gave me the same results.
Could you please tell me why? Thanks a lot!
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by ted »

I want to put a sequence of current clamps into a same point of a object
Are you simply trying to inject a sequence of current pulses?
thisman

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by thisman »

Yes, is there a simpler way?...
But the time when I want to put these current pulses into the object is fixed.
I will read these time from other file and put them in a vector.
thisman

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by thisman »

Or can I use the netcon.event method?

Code: Select all

objref tvec, f
tvec = new Vector()
f = new File()
f.ropen("temp.dat")
tvec.scanf(f)
f.ropen()

objref stim
axon stim = new IClamp(0.1)
stim.del = 0
stim.dur = 1
stim.amp = 15

objref nc, nil
axon nc = new NetCon(stim, nil)
for i=0, tvec.size-1 {
nc.event(tvec.x[i])
}
But this also just gave me one current pulse.
I read the programmer's reference, the explanation for netcon.event is too short and there is no example for it.
Could you please tell me how to use netcon.event?
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by ted »

thisman wrote:But the time when I want to put these current pulses into the object is fixed.
Go to the Documentation page of http://www.neuron.yale.edu and find the link to the FAQ list. In the FAQ list see these topics:

SEClamp and IClamp just deliver rectangular step waveforms. How can I make them produce an arbitrary waveform, e.g. something that I calculated or recorded from a real cell?

I just want a current clamp that will deliver a sequence of current pulses at regular intervals. Vector play seems like overkill for this.
thisman

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by thisman »

After read the topic
I just want a current clamp that will deliver a sequence of current pulses at regular intervals. Vector play seems like overkill for this.
I find I cannot use these "ipulse.mod" files, because they just can deliver one or more current pulses at "regular" intervals. While my spike times are independent with each other, which means all my intervals between pulses are irregular and independent with each other as well.
Topic
SEClamp and IClamp just deliver rectangular step waveforms. How can I make them produce an arbitrary waveform, e.g. something that I calculated or recorded from a real cell?
just tells how to make IClamp and VClamp wave form as any shape we want via "GUI". Although the webpage says
You could do this at the interpreter level by inserting the necessary hoc statements inside the main computational loop
it does not teach me how...(This is exactly what I want to learn). Since my simulation is really long and I will run it on the server machine in my department. I can not control the GUI on the server machine via my computer and it's inconvenience. Since the waveform of my current pulses is still rectangular(the amp and dur for all current pulses are same, the only change is the del that I can read from another file as a vector), I want to put the IClamp into the .hoc file then send it to the department machine.
One way that I can imagine to solve this question is use the netcon.event, but I am not sure how to construct a netcon for this purpose. Because I do not have a synapse, it is just a sequence of current pulses.
Or can I use
cvode.event(t, "statement", pointprocess, re_init)
I read about it in programmer's reference but I am not sure.
Thank you very much for your help again!
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by ted »

How many pulses will there be in an individual run? Dozens? Hundreds? Thousands?
thisman

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by thisman »

About 5,000 pulses for one simulation.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by ted »

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.
vjs347
Posts: 9
Joined: Mon Oct 26, 2015 4:10 pm

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by vjs347 »

Hey Ted,

I'm very new to Neuron Simulation. I'm trying to incorporate this snippet you posted in my code to stimulate a axonal node with IClamp inputs from a vector.

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()")
I'm getting this error,
bad stack access: expecting (double); really (char *)
/Applications/NEURON-7.4/nrn/x86_64/bin/nrniv: interpreter stack type error
in work2.hoc near line 115
nc.event("dopulse()")
^
NetCon[0].event("dopulse()")
Could you help me by telling why this error pops up? I will try to correct the issue if you can direct me in the right path.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by ted »

Ah, the dangers of posting untested code on the Forum. My apologies to all who tried to use netcon.event() to execute a procedure. That doesn't work--instead, it generates this error message
bad stack access: expecting (double); really (char *)
because netcon.event needs an argument that evaluates to a numerical value, not a string that is the name of a procedure.

For arbitrary waveforms create an IClamp with del = 0, dur = 1e9, and use the Vector class's play() method to drive its amp variable. If you want to generate a series of uniform pulses, see this item
I just want a current clamp that will deliver a sequence of current pulses at regular intervals.
in the FAQ list
http://www.neuron.yale.edu/neuron/faq/general-questions
vjs347
Posts: 9
Joined: Mon Oct 26, 2015 4:10 pm

Re: Can IClamp be used in a for loop? Or can it be a vector?

Post by vjs347 »

Thanks a lot Ted. It took me a while to figure out. But I finally got what I wanted. Sorry for the late response.
Post Reply