Accessing tpre and tpost from STDP mod file

Moderator: wwlytton

Post Reply
fabio
Posts: 3
Joined: Tue Oct 03, 2023 3:34 am

Accessing tpre and tpost from STDP mod file

Post by fabio »

Hello,
I am relatively new with NEURON, and I am using the STDP mod file created by M. Hines in a network.
For some reason, I need to get from the mod file to the main hoc file the presynaptic and the postsynaptic times (tpre and tpost, in the mod file).
I have no problem with tpre, since it is already inserted in the NET_RECEIVE block (NET_RECEIVE(w (uS), A, tpre (ms) ) {...) and in the correspondig FOR_NETCONS (FOR_NETCONS(w1, A1, tp) {..., where tp is already tpre). So I con get tpre for the netcons as w[2]. But I also need tpost.
How can I get it? I tried to insert it in the NET_RECEIVE and in the FOR_NETCONS blocks, by I get a segmentation violation error.
Any suggestion?
Thank you very much in advance.

All the best,
Fabio
ted
Site Admin
Posts: 6314
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Accessing tpre and tpost from STDP mod file

Post by ted »

The first step is for you to disclose the code of the mod file that you are actually using (either include it in your next post, or better yet provide a URL to where you found it). Statements like
"the STDP mod file created by so and so"
mean almost nothing because text files are fungible.
fabio
Posts: 3
Joined: Tue Oct 03, 2023 3:34 am

Re: Accessing tpre and tpost from STDP mod file

Post by fabio »

Thank you very much. You are right.

Here the code:

: STDP by Hines, changed to dual exponential (BPG 6-1-09)
: Modified by BPG 13-12-08
: Limited weights: max weight is wmax and min weight is wmin
: (initial weight is specified by netconn - usually set to wmin)
: Rhythmic GABAB suppresses conductance and promotes plasticity.
: When GABAB is low, conductance is high and plasticity is off.

NEURON {
POINT_PROCESS STDPE2
RANGE tau1, tau2, e, i, d, p, dtau, ptau, thresh, wmax, wmin
RANGE g, gbdel, gblen, gbint, gscale, factor,dM,dV,B,C
NONSPECIFIC_CURRENT i
}

UNITS {
(nA) = (nanoamp)
(mV) = (millivolt)
(uS) = (microsiemens)
}

PARAMETER {
tau1=.1 (ms) <1e-9,1e9>
tau2 = 10 (ms) <1e-9,1e9>
e = 0 (mV)
pi=3.14159
wmax = 0.0015 (uS)
:wmax = 0.005 (uS)
wmin = 0.0005 (uS) : not used - use netconn weight instead (BPG)
d = 8 : depression factor (multiplicative to prevent < 0)
p = 1.2 : potentiation factor (additive, non-saturating)

dM = -22 (ms)
dV= 5 (ms)
ptau = 10 (ms) : Nishiyama2000

:thresh = -20 (mV) : postsynaptic voltage threshold
thresh = -55 (mV) : postsynaptic voltage threshold
gbdel = 50 (ms) <1e-9,1e9> : initial GABAB off interval (ms)
gbint = 125 (ms) <1e-9,1e9> : GABAB off interval (ms)
gblen = 125 (ms) <1e-9,1e9> : GABAB on length (ms)
gscale = 0.4 : relative suppression by GABAB

}

ASSIGNED {
v (mV)
i (nA)
tpost (ms)
on
g (uS)
gs
factor
}

STATE {
C (uS)
B (uS)
}

INITIAL {
LOCAL tp
if (tau1/tau2 > .9999) {
tau1 = .9999*tau2
}
C = 0
B = 0
tp = (tau1*tau2)/(tau2 - tau1) * log(tau2/tau1)
factor = -exp(-tp/tau1) + exp(-tp/tau2)
factor = 1/factor
gs=1
on=0 : initially not plastic
tpost = -1e9
net_send(0, 1)
net_send(gbdel, 3) : initial GABAB off period
}

BREAKPOINT {
SOLVE state METHOD cnexp
g = B - C
i = g*gs*(v - e)

}

DERIVATIVE state {
C' = -C/tau1
B' = -B/tau2
}

NET_RECEIVE(w (uS), A, tpre (ms) ) {
INITIAL { A = 0 tpre = -1e9 }
if (flag == 0) { : presynaptic spike (after last post so depress)
: printf("entry flag=%g t=%g w=%g A=%g tpre=%g tpost=%g\n", flag, t, w, A, tpre, tpost)
: g = g + w + A : only for single exp (BPG)
C = C + (w + A)*factor
B = B + (w + A)*factor
:printf(" B %f\t C %f\t w %f\n",B, C, w)
tpre = t
if (on == 1) {
A = A * (1-(d*exp(-((tpost-t)-dM)^2/(2*dV*dV))) /(sqrt(2*pi)*dV))
}
}else if (flag == 2 && on == 1) { : postsynaptic spike
: printf("entry flag=%g t=%g tpost=%g\n", flag, t, tpost)
tpost = t
FOR_NETCONS(w1, A1, tp) { : also can hide NET_RECEIVE args
:printf("entry FOR_NETCONS w1=%g A1=%g tp=%g t=%g\n", w1, A1, tp, t)
A1 = A1 + (wmax-w1-A1)*p*exp((tp - t)/ptau)
}
} else if (flag == 1) { : flag == 1 from INITIAL block
: printf("entry flag=%g t=%g\n", flag, t)
WATCH (v > thresh) 2
}
else if (flag == 3) { : plasticity control
if (on == 0) { : start plasticity
on = 1
gs = gscale
net_send(gblen, 3)
}
else { : end burst
on = 0
gs = 1
net_send(gbint, 3)
}
}
}
ted
Site Admin
Posts: 6314
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Accessing tpre and tpost from STDP mod file

Post by ted »

The easy way to discover tpost is to attach a NetCon to the segment that has the instance of the STDPE2 class, and use that NetCon's record() method to capture local postsynaptic "spike times" to a Vector.

What's not so clear to me is how you are capturing the tpre values. Are you recording w[2] at each time step, then applying some kind of postprocessing to the resulting Vector (because most of the recorded t values will be irrelevant)? If so, how do you deal with a situation in which an STDPE2 instance receives events from more than one afferent stream at a particular time?
fabio
Posts: 3
Joined: Tue Oct 03, 2023 3:34 am

Re: Accessing tpre and tpost from STDP mod file

Post by fabio »

Thank you very much, your suggestions actually solved my problems.
About the way I capture the tpre values, I recorded it at each spike, up to now.
By the way, I will switch to the method you suggest also for tpre.
Thank you very much again.
ted
Site Admin
Posts: 6314
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Accessing tpre and tpost from STDP mod file

Post by ted »

I forgot to mention that the NetCon that monitors the postsynaptic potential should have the same threshold as is specified in the NMODL's WATCH statement. For STDPE2, that would be the value of the RANGE variable thresh.

For a synaptic mechanism S that can handle multiple input streams, the cleanest way to capture tpre is to record the spike times of each presynaptic neuron to its own Vector (so if N presynaptic neurons project to a given synapse, you'll have N Vectors). Then, after the end of the simulation, do this

for each neuron N that is presynaptic to S
create a new Vector V that holds a copy of N's recorded spike times
add the delay parameter of the {NetCon that projects from N to S} to the elements of V

and V will now hold the times at which synapse S received events generated by neuron N (which are called tpre in the NMODL file that defines S).

Of course you should make sure that the NetCons that monitor the presynaptic neurons all have the same thresold as the NetCons that deliver events to S.
Post Reply