recording currents

Anything that doesn't fit elsewhere.
maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

recording currents

Post by maria.kesa » Mon Jan 11, 2016 1:07 pm

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

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

Re: recording currents

Post by ted » Mon Jan 11, 2016 5:28 pm

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.
maria.kesa wrote:How would you record GABA, AMPA and NMDA currents going through a 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 example

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)
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.

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Tue Jan 12, 2016 1:21 pm

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

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

Re: recording currents

Post by ted » Tue Jan 12, 2016 5:58 pm

Delightful. At least the number of files is countable.
maria.kesa wrote:The synapses not stemming from external stimulation are defined here https://senselab.med.yale.edu/modeldb/S ... oCells.hoc
Don't the synapses that receive inputs from external sources contribute to the LFP?

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)
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."

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Fri Jan 15, 2016 9:31 am

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

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Sat Jan 16, 2016 10:42 am

I made the following code

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)
The statement

Code: Select all

 if ($o1.object(i).inmda)
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

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Sat Jan 16, 2016 12:58 pm

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.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Sat Jan 16, 2016 2:38 pm

How do you check the type of an object?

Thanks,
Maria

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Sat Jan 16, 2016 3:29 pm

When I try to record from the external stimulation, I use the following code

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)
}
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

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

Re: recording currents

Post by ted » Mon Jan 18, 2016 4:54 pm

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 line

Code: Select all

  GLOBAL isampa
as the last statement in the NEURON block of each synaptic mechanism.
In each ampaergic mechanism's PARAMETER block, insert this

Code: Select all

  isampa = 1 : do not change this!
as the last statement,
and in each gabaergic mechanism's PARAMETER block, insert this

Code: Select all

  isampa = 0 : do not change this!
as 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

Code: Select all

load_file("setup_isynrecording.hoc")
Finally, create a new hoc file called setup_isynrecording.hoc that contains the following statements:

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)
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.

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Tue Jan 19, 2016 11:15 am

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

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

Re: recording currents

Post by ted » Tue Jan 19, 2016 12:07 pm

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.

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Wed Jan 20, 2016 3:43 pm

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

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

Re: recording currents

Post by ted » Thu Jan 21, 2016 12:27 pm

It looks like I can't even run the simulation on a cluster because the current implementation is so memory intensive.
You might try using the Neuroscience Gateway Portal http://www.nsgportal.org/, which offers free CPU time on high performance computing hardware.
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.
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.*

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.

maria.kesa
Posts: 36
Joined: Thu Nov 12, 2015 10:45 am

Re: recording currents

Post by maria.kesa » Thu Jan 21, 2016 1:41 pm

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.

Post Reply