recording currents
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
recording currents
Hello,
How would you record GABA, AMPA and NMDA currents going through a cell population? I need it as an approximation to the LFP. Really don't know where to start.
Thank you,
Maria
How would you record GABA, AMPA and NMDA currents going through a cell population? I need it as an approximation to the LFP. Really don't know where to start.
Thank you,
Maria
-
- Site Admin
- Posts: 6299
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: recording currents
Just to make sure we understand each other, this would be a good time to review chapter 5 of the NEURON Book, especially 5.6 How to specify biophysical properties. It would also be a good idea to review chapter 10, especially the parts about synaptic transmission.
captures the time course of the current generated by an ExpSyn instance in the pair of Vectors tvec and ivec.
To make any more specific recommendations, such as sensible ways to manage a large number of object instances, I would have to see the source code that defines your cell population.
Presumably you want to record the time course of synaptic currents. In NEURON, synapses are generally implemented as "point processes." A point process is an object that is attached to a particular location on a cell, and can generate a localized transmembrane current; the units of that current are nanoamperes. You will need to know the name of each objref that points to a synaptic mechanism, and the name of the current that the synaptic mechanism generates. Then you can use Vector record to capture the time course of the synaptic current(s) in which you are interested. For examplemaria.kesa wrote:How would you record GABA, AMPA and NMDA currents going through a cell population?
Code: Select all
create soma
objref syn
soma syn = new ExpSyn(0.5) // attaches a new instance of ExpSyn to middle of soma
objref tvec, ivec
tvec = new Vector()
tvec.record(&t)
ivec = new Vector()
ivec.record(&syn.i)
To make any more specific recommendations, such as sensible ways to manage a large number of object instances, I would have to see the source code that defines your cell population.
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
Dear Ted,
Thank you for your reply!
I'm working on a model of lateral amygdala https://senselab.med.yale.edu/modeldb/S ... del=150288
The cells are defined in this file https://senselab.med.yale.edu/modeldb/S ... n_file.hoc
The synapses not stemming from external stimulation are defined here https://senselab.med.yale.edu/modeldb/S ... oCells.hoc
I would appreciate any recommendations and help that you could give:-)
Thank you,
Maria
Thank you for your reply!
I'm working on a model of lateral amygdala https://senselab.med.yale.edu/modeldb/S ... del=150288
The cells are defined in this file https://senselab.med.yale.edu/modeldb/S ... n_file.hoc
The synapses not stemming from external stimulation are defined here https://senselab.med.yale.edu/modeldb/S ... oCells.hoc
I would appreciate any recommendations and help that you could give:-)
Thank you,
Maria
-
- Site Admin
- Posts: 6299
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: recording currents
Delightful. At least the number of files is countable.
First, a comment: it is useful to keep instrumentation code (such as code that sets up Vector recording) separate from model specification code (code that specifies the anatomical and biophysical properties that are represented by the model). Everything that follows is intended to be executed AFTER model setup is complete, but before any statement that initializes the model's states or advances the solution in time.
If all synaptic mechanisms produce currents that are called i, and each instance of a synaptic mechanism is appended to a List, then it's very easy to iterate over that list and set up Vector recording. Example: if the list that contains the synaptic mechanism instances is called synlist, then this will do the job:
But that's not possible for the model you're studying, because every mod file for a synaptic mechanism (every mod file that contains NET_RECEIVE) either produces a current called igaba or two currents called inmda and iampa. It's going to be a minor nuisance to deal with that. So I ask: for your particular application, is it now, or will it be in the future, important to fractionate the currents that a particular synaptic mechanism generates? I suspect that the answer is "yes."
Don't the synapses that receive inputs from external sources contribute to the LFP?maria.kesa wrote:The synapses not stemming from external stimulation are defined here https://senselab.med.yale.edu/modeldb/S ... oCells.hoc
First, a comment: it is useful to keep instrumentation code (such as code that sets up Vector recording) separate from model specification code (code that specifies the anatomical and biophysical properties that are represented by the model). Everything that follows is intended to be executed AFTER model setup is complete, but before any statement that initializes the model's states or advances the solution in time.
If all synaptic mechanisms produce currents that are called i, and each instance of a synaptic mechanism is appended to a List, then it's very easy to iterate over that list and set up Vector recording. Example: if the list that contains the synaptic mechanism instances is called synlist, then this will do the job:
Code: Select all
objref synivecs // will be a List that contains the Vectors to which the synaptic currents are recorded
synivecs = new List()
// $o1 is a list that contains the synaptic mechanisms whose currents are to be recorded
obfunc makesyniveclist() { local i localobj tmplist, tmpvec
tmplist = new List()
for i=0,$o1.count()-1 {
tmpvec = new Vector()
tmpvec.record(&$o1.i)
tmplist.append(tmpvec)
}
return tmplist
}
synivecs = makesyniveclist(synlist)
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
Thank you, Ted!
Yes, we will need to fractionate the currents and you're right the external spike trains, coming from the cortex and thalamus, must also be recorded for the LFP.
I would appreciate any further help.
Maria
Yes, we will need to fractionate the currents and you're right the external spike trains, coming from the cortex and thalamus, must also be recorded for the LFP.
I would appreciate any further help.
Maria
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
I made the following code
The statement
doesn't work as I want it to. My question is, how do you make the if condition so that only the synapses with that specific currents are recorded?
Btw, I get the following error
inmda not a public member of interD2pyrD_STFD
/usr/local/nrn/x86_64/bin/nrniv: interD2pyrD_STFD inmda
in LA_model_main_file.hoc near line 488
synivecs = makesyniveclist(InternalsynList)
^
makesyniveclist(List[2010])
initcode failed with 1 left
oc>
Thanks, Maria
Code: Select all
objref synivecs // will be a List that contains the Vectors to which the synaptic currents are recorded
synivecs = new List()
// $o1 is a list that contains the synaptic mechanisms whose currents are to be recorded
obfunc makesyniveclist() { local i localobj tmplist, tmpvec
tmplist = new List()
for i=0,$o1.count()-1 {
tmpvec = new Vector()
if ($o1.object(i).inmda){
tmpvec.record(&$o1.object(i).inmda)
tmplist.append(tmpvec)
}
}
return tmplist
}
synivecs = makesyniveclist(InternalsynList)
Code: Select all
if ($o1.object(i).inmda)
Btw, I get the following error
inmda not a public member of interD2pyrD_STFD
/usr/local/nrn/x86_64/bin/nrniv: interD2pyrD_STFD inmda
in LA_model_main_file.hoc near line 488
synivecs = makesyniveclist(InternalsynList)
^
makesyniveclist(List[2010])
initcode failed with 1 left
oc>
Thanks, Maria
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
I tried to search all sorts of resources for how to place a conditional for checking whether a variable is a public member of the point process and I can't find anything. Would really appreciate your help.
Maria
Maria
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
How do you check the type of an object?
Thanks,
Maria
Thanks,
Maria
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
When I try to record from the external stimulation, I use the following code
I get the error
/usr/local/nrn/x86_64/bin/nrniv: syntax error
in LA_model_main_file.hoc near line 495
tonevec=new Vector()
I don't understand what I'm doing wrong. I would appreciate if you helped me with this task:-)
Maria
Code: Select all
objref tone2LAPrecord
tone2LAPrecord = new List()
for i=0, 799 {
objref tonevec
tonevec=new Vector()
tonevec.record(&tone2LAPsyn[i].inmda)
tone2LAPrecord.append(tonevec)
}
/usr/local/nrn/x86_64/bin/nrniv: syntax error
in LA_model_main_file.hoc near line 495
tonevec=new Vector()
I don't understand what I'm doing wrong. I would appreciate if you helped me with this task:-)
Maria
-
- Site Admin
- Posts: 6299
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: recording currents
Looks like you had a good time over the weekend . . . not.
There are many ways to accomplish what you want to do, and each has its pros and cons. Which you choose is up to you.
The quick and dirty method would be to add a new GLOBAL variable to each NMODL-defined synaptic mechanism.
Insert the lineas the last statement in the NEURON block of each synaptic mechanism.
In each ampaergic mechanism's PARAMETER block, insert thisas the last statement,
and in each gabaergic mechanism's PARAMETER block, insert thisas the last statement.
Then find the place in the hoc code where model setup is complete, but a simulation run has not yet been done. At this point insert the statement
Finally, create a new hoc file called setup_isynrecording.hoc that contains the following statements:Just be sure that the conditional statement uses "double equal signs", i.e. ==
Some might prefer an approach that avoids making any changes whatsoever to the existing source code. For example, you could have code that checks the name of the base class of each synaptic instance, and uses that to determine whether it is ampaergic or gabaergic. This would involve routine but tedious programming that used NEURON's String class and StringFunctions. All very tidy and academic, because it wouldn't involve any change whatsoever to the original authors' source code. Some might find that satisfying, especially if they have the time to do it and are being paid by the hour, but you'd have to deal with 42 different class names. Just thinking about it gives me a migraine.
There are many ways to accomplish what you want to do, and each has its pros and cons. Which you choose is up to you.
The quick and dirty method would be to add a new GLOBAL variable to each NMODL-defined synaptic mechanism.
Insert the line
Code: Select all
GLOBAL isampa
In each ampaergic mechanism's PARAMETER block, insert this
Code: Select all
isampa = 1 : do not change this!
and in each gabaergic mechanism's PARAMETER block, insert this
Code: Select all
isampa = 0 : do not change this!
Then find the place in the hoc code where model setup is complete, but a simulation run has not yet been done. At this point insert the statement
Code: Select all
load_file("setup_isynrecording.hoc")
Code: Select all
objref ampaivecs, nmdaivecs, gabaivecs
ampaivecs = new List() // members will be Vectors that record all ampaergic currents
nmdaivecs = new List() // etc.
gabaivecs = new List()
proc makeiveclists() { local i localobj tmpvec, tmpobj
ampaivecs = new List()
nmdaivecs = new List()
gabaivecs = new List()
for i=0,$o1.count()-1 {
tmpobj = $o1.o(i)
if (tmpobj.isampa == 1) {
tmpvec = new Vector()
tmpvec.record(&tmpobj.iampa)
ampaivecs.append(tmpvec)
tmpvec = new Vector()
tmpvec.record(&tmpobj.inmda)
nmdaivecs.append(tmpvec)
} else {
tmpvec = new Vector()
tmpvec.record(&tmpobj.igaba)
gabaivecs.append(tmpvec)
}
}
}
makeiveclists(synlist)
Some might prefer an approach that avoids making any changes whatsoever to the existing source code. For example, you could have code that checks the name of the base class of each synaptic instance, and uses that to determine whether it is ampaergic or gabaergic. This would involve routine but tedious programming that used NEURON's String class and StringFunctions. All very tidy and academic, because it wouldn't involve any change whatsoever to the original authors' source code. Some might find that satisfying, especially if they have the time to do it and are being paid by the hour, but you'd have to deal with 42 different class names. Just thinking about it gives me a migraine.
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
Dear Ted,
Thank you!
When I set the NEURON block to GLOBAL isampa, the code didn't work. The error said that it couldn't find the isampa variable. When I changed GLOBAL to RANGE, it worked.
Thanks,
Maria
Thank you!
When I set the NEURON block to GLOBAL isampa, the code didn't work. The error said that it couldn't find the isampa variable. When I changed GLOBAL to RANGE, it worked.
Thanks,
Maria
-
- Site Admin
- Posts: 6299
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: recording currents
Yes, defining isampa to be a RANGE variable is the only thing that will work. Forgot about that; sorry about the mistake.
Explanation for all who are interested (anyone who wants to develop expertise in using mod files should be interested):
An NMODL GLOBAL doesn't belong to any individual instance of a mechanism, so the syntax for accessing a range variable fails--you can't use the point process syntax objref.variablename or the density mechanism syntax variablename_suffix(range). Instead, an NMODL GLOBAL is accessed with this syntax
variablename_mechanismname
where mechanismname is either the name of the point process class itself (NOT the name of an objref that points to an instance of that class), or the SUFFIX of a density mechanism.
Explanation for all who are interested (anyone who wants to develop expertise in using mod files should be interested):
An NMODL GLOBAL doesn't belong to any individual instance of a mechanism, so the syntax for accessing a range variable fails--you can't use the point process syntax objref.variablename or the density mechanism syntax variablename_suffix(range). Instead, an NMODL GLOBAL is accessed with this syntax
variablename_mechanismname
where mechanismname is either the name of the point process class itself (NOT the name of an objref that points to an instance of that class), or the SUFFIX of a density mechanism.
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
Dear Ted,
How would you implement the LFP summation over all the synapses in a memory efficient way. It looks like I can't even run the simulation on a cluster because the current implementation is so memory intensive.
I need to sum all of the absolute values of all of the currents at the synapses at every time step to get one number per time step. How would you do it?
Thanks,
Maria
How would you implement the LFP summation over all the synapses in a memory efficient way. It looks like I can't even run the simulation on a cluster because the current implementation is so memory intensive.
I need to sum all of the absolute values of all of the currents at the synapses at every time step to get one number per time step. How would you do it?
Thanks,
Maria
-
- Site Admin
- Posts: 6299
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: recording currents
You might try using the Neuroscience Gateway Portal http://www.nsgportal.org/, which offers free CPU time on high performance computing hardware.It looks like I can't even run the simulation on a cluster because the current implementation is so memory intensive.
Recording all synaptic currents, then doing elementwise vector sums with Vector.add after the simulation would be faster than iterating over all synapses at each time step--potentially much faster. Also, you said you wanted to know whether the currents are gabaergic, ampaergic, or nmdaergic. At the very least, you need to know whether each current is excitatory or inhibitory, because excitatory and inhibitory synapses tend to have different spatial locations over the cell surface--and that means they make different contributions to the LFP. And you should probably differentiate between synapses attached to pyramidal cells and synapses attached to interneurons. In fact, you might want to ignore synapses that are attached to interneurons. Depending on the connectivity of your network, that alone could reduce storage requirements significantly.*maria.kesa wrote:How would you implement the LFP summation over all the synapses in a memory efficient way. It looks like I can't even run the simulation on a cluster because the current implementation is so memory intensive.
I need to sum all of the absolute values of all of the currents at the synapses at every time step to get one number per time step.
Another issue that needs to be addressed, if you plan to run simulations on parallel hardware, is the fact that the code on each host can only deal with synaptic currents generated by cells on itself. So whether you capture each synapse's current to its own Vector(s), or calcualte a running sum of all synaptic currents on each host, you're going to have to gather all that data after the end of a simulation to a single host and add it all up there.
So think about these issues
1. does it make sense to omit currents generated by synapses attached to interneurons?
2. generating a running sum is potentially much slower than recording all currents to Vectors
3. parallel simulation will require gathering all data from the different hosts after the end of the simulation
and let me know what you want to do.
--Ted
*--A much larger reduction of storage requirements might be possible if the network involves a lot of convergence onto synapses that are electrotonically close to each other, and each synaptic instance can handle multiple afferent streams. Indeed, proc ConnectTwoCells() does not exploit this strategy, even though all synapses are attached either to soma(0.9) or dend(0.9). Instead, a new synaptic instance is created for each {presynaptic source -> postsynaptic target} pair. But maybe that's because the synaptic mechanisms can't handle multiple input streams--at least, the few synaptic mod files that I've examined are implemented in a way that is absolutely unable to handle multiple input streams. I think that problem is fixable, but it would involve significant effort, and you'd have to prove that revising the synaptic mechanisms didn't break anything, which means you'd have to compare results (spike times would be sufficient) produced by the author's original code with results generated by your code.
An unrelated issue is the use of misleading variable names, e.g. variables called g_nmda, g_ampa, and g_gaba aren't the actual synaptic conductances from which the synaptic currents are calculated. That's bound to cause confusion when somebody who is interested in synaptic conductances tries reusing this model in the future.
-
- Posts: 36
- Joined: Thu Nov 12, 2015 10:45 am
Re: recording currents
Dear Ted,
I was using the NSG cluster and it ran out of memory when recording the vectors.
I was just using one node for the simulation.
We're working with a rough approximation to the LFP, where we treat all of the synaptic currents equally, just take their absolute value and add together. We should also include the interneurons.
I was using the NSG cluster and it ran out of memory when recording the vectors.
I was just using one node for the simulation.
We're working with a rough approximation to the LFP, where we treat all of the synaptic currents equally, just take their absolute value and add together. We should also include the interneurons.