Page 1 of 1

net_send call in NET_RECEIVE

Posted: Tue Apr 17, 2018 4:43 am
by Krishna Chaitanya
Hi,

I am working with a mod file with all the parameters and values to simulate a simple point process model.

I find that I have to call net_send(0,1) twice for the mod file to work. The initial call net_send(0,1) in the INITIAL block takes you to WATCH statement block but after resetting, I had to make another net_send(0,1) call to make the model work.

I am not sure what is the problem. If I remove net_send(0,1) in the NET_RECEIVE block, it stops showing action potentials.

Code: Select all

NEURON {
	POINT_PROCESS Random
	RANGE el, gl, freqcount, istim, ie, gexc, ginh, Eex, EIn, Cm, tau_synE, tau_synI, thresh, thresh1, Vr, fflag
}

UNITS {
	(nA)=(nanoamp)
	(pA)=(picoamp)
	(mV)=(millivolt)
	(mM)=(milli/liter)
	(umho)=(micromho)
	(pF)=(picofarad)
	(nS)=(nanosiemens)
	(uS) = (microsiemens)
}

PARAMETER {
	el=-50	(mV)
	gl=1	(nS)
	istim=0	(pA)	
	ie=9	(pA)
	Eex=0	(mV)
	EIn=-70	(mV)
	Cm=5	(pF)
	thresh=-42	(mV)
	thresh1=20 (mV)
	Vr=-60	(mV)
	tau_synE=0.5(ms)
	tau_synI=10	(ms)
	freqcount=0
	fflag=1
}

ASSIGNED {
	il		(pA)
	iexc	(pA)
	iinh	(pA)
}

STATE { 
	vv 	(mV)
	gexc	(nS)
	ginh	(nS)
}

INITIAL {
	vv=-50	(mV)
	gexc=0	(nS)
	ginh=0	(nS)
	net_send(0,1)
}

BREAKPOINT {
	SOLVE states METHOD derivimplicit	
}

DERIVATIVE states {
	vv'=(gl*(el-vv)+istim+ie)/Cm
	gexc'=-gexc/tau_synE
	ginh'=-ginh/tau_synI
}

NET_RECEIVE (u (uS)) {
	:printf("While entereing NET_RECEIVE block, value found is %g\n", flag)
	if (flag == 1) {
		WATCH (vv>thresh) 2
		:printf("print")
		:printf("the time here is %g\n", t)
	} else if (flag == 2) {
		WATCH (vv>thresh1) 3
		vv=30
		freqcount=freqcount+1
		:printf("The time in the second flag statement is %g\n", t)
	} else if (flag == 3) {
		net_event(t)
		net_send(0, 1)
		vv=Vr
		:net_send(0, 1)
		:printf("The time in the third flag statement is %g\n", t)
	} 
}
Please advise on how to proceed. Thank you.

Re: net_send call in NET_RECEIVE

Posted: Wed Apr 18, 2018 10:45 am
by ted
First, I should mention that an NMODL file that specifies a POINT_PROCESS or ARTIFICIAL_CELL adds a new class to NEURON. You're calling your new class Random, but NEURON has a built-in class called Random. It's not a good idea to set up a collision in name space, and NEURON doesn't seem to like it, either--if I put your mod file in an empty directory and compile it, then execute
nrngui
NEURON exits immediately after announcing

Code: Select all

Additional mechanisms from files
 foo.mod
So change the name of your new class to something else.

About your question:
A POINT_PROCESS or ARTIFICIAL_CELL can be associated with only a single threshold detector. When your mechanism detects that vv has risen above thresh, it changes the threshold to thresh1 and leaves it there until something forces it to return the threshold to thresh. That's why the net_send statement is needed.

Re: net_send call in NET_RECEIVE

Posted: Thu Apr 19, 2018 4:05 am
by Krishna Chaitanya
Hi Ted,

Thank you very much for explaining clearly. I have changed the name of the mod file as you have told. I understood that in the NET_RECEIVE block, I cannot give two WATCH statements without the net_send statement to force the threshold for bringing the membrane potential back to the resting voltage (Vr).

I tried to add absolute refractory period to the NET_RECEIVE block, but the mod file does not accept that. I am not sure where I am going wrong. Here's the code:

Code: Select all

NEURON {
  POINT_PROCESS Stce
  NONSPECIFIC_CURRENT i
  RANGE el, gl, freqcount, istim, ie, gexc, ginh, Eex, EIn, Cm, tau_synE, tau_synI, thresh, thresh1, Vr, tpre, fflag
  RANGE refrac, thresh2
}

UNITS {
  (nA) = (nanoamp)
  (nS) = (nanosiemens)
  (pA) = (picoamp)
  (pF) = (picofarad)
  (mV) = (millivolt)
  (S) = (siemens)
  (uS) = (microS)
  (um) = (micron)
  (uf) = (microfarad)
}

PARAMETER {
  el = -50	(mV)
  gl = 1	(nS)
  istim = 50	(pA)
  ie = 9	(pA)
  Eex = 0	(mV)
  EIn = -70	(mV)
  Cm = 5	(pF)
  refrac = 1.59 (ms)
  thresh = -42	(mV)
  thresh1 = 20	(mV)
  thresh2 = 30	(mV)
  Vr = -60	(mV)
  tau_synE = 0.5	(ms)
  tau_synI = 10	(ms)
  freqcount = 0
  tpre = 0
  fflag = 1
}

ASSIGNED {
  i (nA)
  isrefrac (1)
}

STATE {
  vv (mV)
  gexc	(nS)
  ginh	(nS)
}

BREAKPOINT {
:  SOLVE states METHOD cnexp
: use derivimplicit because u' is coupled to v, which is another state
  SOLVE states METHOD cnexp
  i = (0.001)*(istim+ie)
  if (isrefrac) {
	:i=(0.001)*(-12.9)
	:printf("the value of i is %g\n", i)
	:gl=0
	:i=0
  }
}

DERIVATIVE states {
	vv'=(gl*(el-vv)+(1000)*(i))/Cm
}

INITIAL {
  vv = -50
  gexc = 0
  ginh = 0
  isrefrac = 0
  net_send(0, 2)
}

NET_RECEIVE(w) {
  if (flag == 1 && t-tpre>=1.59) {
		net_event(t)
		tpre=t
		if (refrac>0) {
			printf("t in the if condition refrac is %g\n", t)
			net_send(refrac, 3)
			isrefrac = 1
		}
		:net_send(0, 3)
		freqcount=freqcount+1
		vv=Vr
  }else if (flag == 2) {
		WATCH(vv>thresh)1
  }else if (flag == 3) {
		printf("t in the flag3 condition is %g\n", t)
		isrefrac = 0
  }
}

Can you kindly let me know the mistake I am making here?

Re: net_send call in NET_RECEIVE

Posted: Wed Apr 25, 2018 5:22 am
by Krishna Chaitanya
Hi,

Can anyone kindly help me overcome this problem?

Please let me know how to solve this.

Thank you.

Re: net_send call in NET_RECEIVE

Posted: Mon May 07, 2018 11:21 am
by ted
The best way to implement a refractory period is with events. Indeed, events are also the best way to implement a "cosmetic spike" because, unlike your present implementation, (1) the "spike" will have a fixed duration independent of dt, and (2) there will be no need to move the "threshold" back and forth. You might find some hints in the source code for IntFire1--see nrn/src/nrnoc/intfire1.mod (if you didn't install NEURON from source code or the latest development code, you'll want to download and expand the .tar.gz file).