Executing multiple continuerun statements in run block with parameter changes

Moderator: wwlytton

Post Reply
Krishna Chaitanya
Posts: 53
Joined: Wed Jan 18, 2012 12:25 am
Location: University of Pavia

Executing multiple continuerun statements in run block with parameter changes

Post by Krishna Chaitanya » Wed Dec 13, 2017 11:43 pm

Hi,

I have been trying to use multiple continuerun() statements inside run block to simulate the mossy fiber on and off conditions.

In my case, I would like to run the simulation for 5 seconds and for each second, the activated mossy fibers (spikegenerators) will be different. The end parameter of the spikegenerator was toggled on and off in each second. However, when I try to change parameters using switchon and switchoff functions, I fail to get them working unless I use stdinit() for each second.

I understood that in each second, stdinit() can't be used but the simulation wouldn't work without it.

This is the code I have been trying to use:

Code: Select all

tstop=1000
proc run() {
      stdinit()
      continuerun($1)
}
setupsimtime=0
for i=0, numact-1 {
        setupsimtime=setupsimtime+tstop
	switchon()//switching on certain set of mossy fibers
	run()
	switchoff()//switching off activated mossy fibers
}
Kindly help me in understand how I can circumvent this problem.

Thank you.

ted
Site Admin
Posts: 5169
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Executing multiple continuerun statements in run block with parameter changes

Post by ted » Thu Dec 14, 2017 12:21 pm

Are you trying to execute a single simulation that consists of a sequence of intervals
interval 0 from t = 0 to t0
interval 1 from t = t0 to t1
interval 2 from t = t1 to t2
etc.
with different "activated mossy fibers" in each interval?

Krishna Chaitanya
Posts: 53
Joined: Wed Jan 18, 2012 12:25 am
Location: University of Pavia

Re: Executing multiple continuerun statements in run block with parameter changes

Post by Krishna Chaitanya » Thu Dec 14, 2017 12:46 pm

Hi Ted,

Yes. I am trying to do multiple continuerun statements for activating different mossy fibers in each run.

Kindly let me know how can I solve this?

Thank you.

Krishna Chaitanya
Posts: 53
Joined: Wed Jan 18, 2012 12:25 am
Location: University of Pavia

Re: Executing multiple continuerun statements in run block with parameter changes

Post by Krishna Chaitanya » Thu Dec 14, 2017 12:53 pm

Hi Ted,

This is a single simulation with different set of mossy fibers being activated at different intervals.

Kindly let me know how can I solve this?

Thank you.

ted
Site Admin
Posts: 5169
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Executing multiple continuerun statements in run block with parameter changes

Post by ted » Fri Dec 15, 2017 10:35 am

The most appropriate solution depends on details that have not been discussed.
Do the presynaptic spike events happen at random times, or at regular intervals?
Are they generated by NetStims during a run, or are the event times calculated before the simulation begins and then "played back" by VecStims?

Krishna Chaitanya
Posts: 53
Joined: Wed Jan 18, 2012 12:25 am
Location: University of Pavia

Re: Executing multiple continuerun statements in run block with parameter changes

Post by Krishna Chaitanya » Fri Dec 15, 2017 12:22 pm

Hi Ted,

Sorry for not mentioning the spikegenerator properties.

Yes. The presynaptic events happen at random times. I have used a random function to generate events between t and t+DUR.

I have not used NetStim and VecStim to play the spike events.

objref rand_mos
rand_mos=new Random()
mossyfiber.spikegen.start=rand_mos.uniform(t, t+DUR)
mossyfiber.spikegen.end=1e5//to turn on the required mossy fibers.
after the run
mossyfiber.spikegen.end=0//turn off the activated mossy fibers.

Thank you.

ted
Site Admin
Posts: 5169
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Executing multiple continuerun statements in run block with parameter changes

Post by ted » Sun Dec 17, 2017 11:58 pm

I have no idea what a mossyfiber.spikegen is. There are many possible traps for the unwary when it comes to simulations involving pseudorandom event sequences and sequence generators. If you're using something that I know about, such as VecStims driven by precalculated sequences, or NetStims, I can provide specific guidance, but I can't tell you much about something I've never heard of. That said, I am suspicious that the excerpt you provided

objref rand_mos
. . .
mossyfiber.spikegen.end=0//turn off the activated mossy fibers.

does not do what you want it to, and has unwanted side effects.

NetStims could be a useful way to do what you want--just take advantage of the fact that an input event with weight > 0 or < 0 can turn a NetStim on or off. Pair each NetStim with its own pseudorandom number generator and you can have as many statistically independent event streams as is practical. But those event times are governed by the negative exponential distribution, and nothing prevents a NetStim from generating one or more events that will be delivered at the "wrong time"--that is, during an interval when its particular event stream is supposed to be silent. You could prevent such events from affecting their target synapses by changing the intervening NetCons' weights to 0--although that has the side-effect of altering the statistics of the event streams.

VecStims driven by precalculated sequences seems statistically cleaner to me. For each VecStim, fill a Vector with a sequence of event times that have the desired mean ISI, then shift the event times as needed to create alternating event-free and event-rich epochs. No lost events, and within every event-rich epoch the statistics are correct. A recursive algorithm could do this nicely. The downside is the storage required for the events, and the time required to set up the Vectors. Still, it would work nicely if the Vectors aren't too big and there aren't many of them.

The proc run() etc. example you provided repeatedly calls stdinit(), which does a lot of things you don't really want to happen. Also it breaks the built-in proc run(), which interferes with debugging and further program development. Instead it is better to make a completely new proc and keep the for loop in that proc, like so:

Code: Select all

// $1 is how many epochs
// each epoch is 2*$2 long
proc epochrun() { local i
  running_ = 1
  tstop = 2*$1*$2 // in case some other code needs tstop
  stdinit()
  for i=0,$1 {
    switchon()
    continuerun(t+$2)
    switchoff()
    continuerun(t+$2)
  }
}

Krishna Chaitanya
Posts: 53
Joined: Wed Jan 18, 2012 12:25 am
Location: University of Pavia

Re: Executing multiple continuerun statements in run block with parameter changes

Post by Krishna Chaitanya » Thu Dec 28, 2017 8:33 am

Hi Ted,

I have tried your advice but I couldn't turn the stimulus on after I called stdinit(). Somehow, the stimulus is turning on only when it is called before stdinit(). When I try to use it after the stdinit() call, it doesn't work. Is there a reason that the <proc> functionality doesn't work when called after the stdinit()?

Kindly let me know.

ted
Site Admin
Posts: 5169
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Executing multiple continuerun statements in run block with parameter changes

Post by ted » Thu Dec 28, 2017 12:48 pm

We have reached the point where it is necessary to get into the details of what switchon() and switchoff() do. Can you provide a toy example program?

Krishna Chaitanya
Posts: 53
Joined: Wed Jan 18, 2012 12:25 am
Location: University of Pavia

Re: Executing multiple continuerun statements in run block with parameter changes

Post by Krishna Chaitanya » Fri Dec 29, 2017 5:29 am

Hi Ted,

I am providing the scripts of each file I used. The scripts are as follows:
1) Pregen.mod (SpikeGenerator mod file).
2) adex.hoc (template creation of spikegenerator)
3) cells_test.hoc (creating the cells)
4) modifycheckmoss.hoc (main file for changing the file parameters during run)

Code: Select all

: $Id: pregen.mod,v 1.3 2000/05/16 11:16:56 hines Exp $
: comments at end

NEURON	{ 
  POINT_PROCESS SpikeGenerator
  RANGE y
  RANGE fast_invl, slow_invl, burst_len, start, end,delay
  RANGE noise
}

PARAMETER {
	fast_invl	= 10 (ms)	: time between spikes in a burst (msec)
	slow_invl	= 0 (ms)	: burst period (msec)
: actually, above is interburst period in conformity with original version
: see
	burst_len	= 10		: burst length (# spikes)
	start		= 50 (ms)	: start of first interburst interval
	end		= 1e10 (ms)	: time to stop bursting
	noise		= 0		: amount of randomeaness (0.0 - 1.0)
	delay		= 4
}

ASSIGNED {
	y
	burst
	event (ms)
	burst_off (ms)
	burst_on (ms)
	toff (ms)
	on
}

:PROCEDURE seed(x) {
	:set_seed(x)
:}

INITIAL {
	on = 1
	toff = 1e9
	y = -90
	burst = 0
	event = start - slow_invl
	:
	event_time()
	while (on == 1 && event < 0) {
		event_time()
	}
	if (on == 1) {
		net_send(event, 1)
	}
}	

FUNCTION interval(mean (ms)) (ms) {
	if (mean <= 0.) {
		mean = .01 (ms) : I would worry if it were 0.
		: since mean is a local variable, if the number it is set
		: to is dimensionless, mean will be dimensionless.
	}
	if (noise == 0) {
		interval = mean
	}else{
		interval = (1. - noise)*mean + noise*(mean*exprand(1)+delay) : (delay+noise*mean*exprand(1))
	}
}

PROCEDURE event_time() {
	if (slow_invl == 0 || (burst != 0. && burst_len > 1)) {
		event = event + interval(fast_invl)
		if (event > burst_on + burst_off) {
			burst = 0.
		}
	}else{
		burst = 1.
: if slow_invl from beginning of burst to beginning of burst
:		event = event + interval(slow_invl - (burst_len-1)*fast_invl)
: use following if slow_invl is interburst interval
		event = event + interval(slow_invl)
		burst_on = event
		burst_off = interval((burst_len - 1)*fast_invl)-1e-6
	}
	if (event > end) {
		on = 0
	}
}

NET_RECEIVE (w) {
:printf("Pregen receive t=%g flag=%g\n", t, flag) 
	if (flag == 1 && on == 1) {
		y = 20
		net_event(t)
		event_time()
		net_send(event - t, 1)
		net_send(.1, 2)
	}
	if (flag == 2) {
		y = -90
	}
}

COMMENT
Presynaptic spike generator
---------------------------

This mechanism has been written to be able to use synapses in a single
neuron receiving various types of presynaptic trains.  This is a "fake"
presynaptic compartment containing a fast spike generator.  The trains
of spikes can be either periodic or noisy (Poisson-distributed), and 
either tonic or bursting.

Parameters;
   noise: 	between 0 (no noise-periodic) and 1 (fully noisy)
   fast_invl: 	fast interval, mean time between spikes (ms)
   slow_invl:	slow interval, mean burst silent period (ms), 0=tonic train
   burst_len: 	mean burst length (nb. spikes)

Written by Z. Mainen, modified by A. Destexhe, The Salk Institute

Modified by Michael Hines for use with CVode

Modified by Michael Hines to use logical event style with NET_RECEIVE
ENDCOMMENT

Code: Select all

begintemplate spikeGen
public dummyspikegen, synspikegen, nclist3, spkrecord, x, y, z, position
create dummyspikegen
public synspikegen, connect2target, sumconnect, mfgocconnect
objref synspikegen, nclist3, spkrecord

proc init() {
	topol() 
	create dummyspikegen
	dummyspikegen {
		diam=1.2
		spkrecord=new Vector()
		nclist3=new List()
		synspikegen=new SpikeGenerator(0.5)
		synspikegen.start=20//rand_start.uniform(20, 1000)
		synspikegen.burst_len=1
		synspikegen.fast_invl=2
		synspikegen.slow_invl=1e10
		synspikegen.end=0
		x=y=z=0
		sumconnect=0
		mfgocconnect=0
	}
}

proc topol() {
	dummyspikegen {pt3dclear() pt3dadd(0, 0, 0, 1.2) pt3dadd(0, 0, 0, 1.2)}
}

proc position() {local i
	dummyspikegen for i=0, n3d()-1 {
		pt3dchange(i, $1-x+x3d(i), $2-y+y3d(i), $3-z+z3d(i), diam3d(i))
	}
	x=$1 y=$2 z=$3
}

obfunc connect2target() {localobj nc
	dummyspikegen nc=new NetCon(&synspikegen.y, $o1) 
	nc.threshold=10
	if(numarg()==2) {$o2=nc}
	return nc
}

endtemplate spikeGen

Code: Select all

//{xopen("calc_cells_volume.hoc")}
xopen("adex.hoc")

nmossy=612

objref mossycells
{
	mossycells=new List()
}

func moscellAppend() {
	mossycells.append($o1)
	return mossycells.count()-1
}

objref mf_start_rand
mf_start_rand=new Random()

func round() {
	if ($1>0) {
		return int($1+0.5)
	}else {
		return int($1-0.5)
	}
}

proc mkcells() {local k localobj cell, nc, nil
	for k=0, nmossy-1 {
		cell=new spikeGen(0.5)
		cell.synspikegen.start=round(mf_start_rand.uniform(20, 700))
		printf("The object here is so, so and so...\n")
		moscellAppend(cell)
	}
}
mkcells()

Code: Select all

xopen("cells_test.hoc")
v_init=-70

objref moss_idvec, moss_tvec
moss_tvec=new Vector()
moss_idvec=new Vector()

proc spikerecord() {localobj nil, nc_moss

	for j=0, mossycells.count-1 {
		nc_moss=mossycells.object(j).connect2target(nil)
		nc_moss.record(moss_tvec, moss_idvec, j)
	}
}
spikerecord()

tstop=1000

objref g, g1, g2, g3, g4, g5, g6, g7
newPlotV()
g5=graphItem
g5.erase_all()
g5.addvar("mossycells.object(0).synspikegen.y")

printf("\n\n Simulating Cells....\n\n")
objref granulefil
granulefil=new File()
dt=0.025
objref cvode
cvode=new CVode()
cvode.atol(0.001)
cvode_active(1)
cvode.use_local_dt(1)
cvode.use_daspk(1)

half_mos=int(mossycells.count/2)
for i=0, half_mos-1 {
	//mossycells.object(i).synspikegen.end=1e5
	mossycells.object(i).synspikegen.fast_invl=33.33
	mossycells.object(i).synspikegen.slow_invl=33.33
}

proc run() {//half mossy fibers with transient and rest half with sustained component - POT Simulation
	stdinit()

	for j=half_mos, mossycells.count-1 {
		mossycells.object(j).synspikegen.end=1e5
		mossycells.object(j).synspikegen.fast_invl=5
		mossycells.object(j).synspikegen.slow_invl=5
	}
	continuerun(5)

	for j=half_mos, mossycells.count-1 {
		mossycells.object(j).synspikegen.end=1e5
		mossycells.object(j).synspikegen.fast_invl=200
		mossycells.object(j).synspikegen.slow_invl=200
	}
	continuerun(tstop)
}
run()
I hope I made it clear. If not, kindly let me know.

Thank you.

Post Reply