Help exporting neuron geometry and voltages over time

Anything that doesn't fit elsewhere.
Post Reply
Grado

Help exporting neuron geometry and voltages over time

Post by Grado »

I am trying to export the voltage at each compartment of a 3d neuron geometry over time (100ms). The code I am using creates a physiologically realistic neuron model (Cortex Layer V), and I need to create a matrix of voltages at each compartment at each time point. Below is the basic matrix that I am trying to create.

0 1 2 3 4 5 ..... T
x1 y1 z1 d1 . . .
x2 y2 z2 d2 . .
. . . . .
. . . .
. . . .
xn yn zn dn

I am trying to split this into two parts. First, I am getting the position data into an array with the following code:

Code: Select all

num3d=0
forall { num3d=num3d+n3d() }
objref positionArray[num3d]

proc RECpositions() {
    i=0
    forall {
        for j=0,n3d()-1 {
            positionArray[i]=new Vector(4)
            positionArray[i].x[0]=x3d(j)
            positionArray[i].x[1]=y3d(j)
            positionArray[i].x[2]=z3d(j)
            positionArray[i].x[3]=diam3d(j)
            i=i+1
        }
    }
}

RECpositions()
This works pretty well.

Now I need to record the voltages at each position. I am trying to do something similar, but it is not working. This is what I have so far.

Code: Select all

objref voltageArray[num3d+1]
for i=0,num3d {voltageArray[i]=new Vector()}
proc RECvoltages() {
    voltageArray[0].record(&t)
    i=0
    forall {
        for j=0,n3d()-1 {
            i=i+1
            voltageArray[i].record(WHAT GOES HERE?)
        }
    }
}
My only question is, what do I put in the parenthesis of

Code: Select all

voltageArray[i].record()
in order to record the voltage at that 3d location? If I just put &v, I get the same voltage for every position of a given segment. Is this the best I can do, or can I get a specific voltage at each section?

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

Re: Help exporting neuron geometry and voltages over time

Post by ted »

Grado wrote:I am getting the position data into an array with the following code
Those are the locations at which the person who made the measurements decided, for whatever reason, to make a measurement. Maybe diameter changed, or maybe a neurite zigged or zagged this way or that. The number and locations of those "3d points" do not correspond directly to the locations at which NEURON computes the time course of membrane potential. The latter are segment centers. The number of segments (compartments) in a section is specified by a parameter called nseg, and each segment in that section will have length equal to 1/nseg * total length of the section. The number of segments that are used to approximate any given unbranched neurite is completely independent of the number of 3d points that define that neurite's geometry.

So the part of a neurite that is spanned by a segment may contain 0, 1, or more 3d points, and the neurite's centroid may change orientation at any 3d point. You can see that talking about the physical location of a segment's midpoint is indulging in a bit of a fiction. However, if the orientation doesn't change very much at any 3d point, then you might define a segment's midpoint as being a point along the neurite that is halfway along the centroid from one end of the segment to the other. Would that suit you?
Now I need to record the voltages at each position.
We'll get to that next.
Grado

Re: Help exporting neuron geometry and voltages over time

Post by Grado »

Yes that would suit me. I spent a while trying to decide if I needed the voltages at the sections, or at each 3d dimension, it looks like I made the wrong choice.
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Help exporting neuron geometry and voltages over time

Post by ted »

Time for a little clarity here. First, NEURON's use of the terms segment and section: A segment is a compartment. A section is an unbranched cable, and it may have more than one segment.

Second, what exactly do you need? Is it enough to know the membrane potential in each compartment (segment) of a model cell? If so, this will do the job.

Code: Select all

objref vlist, tvec
tvec = new Vector()
tvec.record(&t) // you're going to want this sooner or later
obfunc recallv() { localobj tmplist, tmpvec
  tmplist = new List()
  forall for (x,0) {
    tmpvec = new Vector()
    tmpvec.record(&v(x))
    tmplist.append(tmpvec)
  }
  return tmplist
}
vlist = recallv()
vlist will be a List whose elements are Vectors that capture the time course of membrane potential at every point in the model cell where membrane potential is calculated by numerical integration of the discretized cable equation.

Do you also have to know the relative position of that compartment's center along the centroid of the section, or the actual spatial (xyz) coordinates of the approximate compartment centers?
Grado

Re: Help exporting neuron geometry and voltages over time

Post by Grado »

Let me tell you a little about what I'm trying to accomplish. I am trying to model the extra cellular voltage around a spiking neuron using finite element modeling. To do this, I need the relative positions and voltages of as much of the neiron as I can get.

Therefore, I would like to get the position and voltage of every segment, not just each section.
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Help exporting neuron geometry and voltages over time

Post by ted »

Grado wrote:I am trying to model the extra cellular voltage around a spiking neuron using finite element modeling.
Presumably you want to calculate extracellular potential produced by neural activity. Recordings of transmembrane potential are useless for that. What you need is transmembrane current. Do you plan to treat the cell generated currents as point sources located at segment centers?
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Help exporting neuron geometry and voltages over time

Post by ted »

ted wrote:What you need is transmembrane current.
If your model's neurites use the extracellular mechanism, transmembrane current in mA/cm2 is a range variable called i_membrane. That means you'll have to multiply each segment's current density by segment area (hoc function area(x) returns the area of the segment in the currently accessed section that corresponds to x). If your model does not involve extracellular, and you are running a version of NEURON that is more recent than Dec. 11, 2014, you can instead use the range variable i_membrane_ which is in units of nA (nanoamps, not a current density)--see the Programmer's reference entry
https://www.neuron.yale.edu/neuron/stat ... _fast_imem
Grado

Re: Help exporting neuron geometry and voltages over time

Post by Grado »

So it sounds like I need a few things:

The coordinates at the center of each segment of each section
The surface area of each segment
The current density at each segment
Grado

Re: Help exporting neuron geometry and voltages over time

Post by Grado »

Or, it sounds like using i_membrane_ is more efficient than i_membrane. The documentation makes it sound like i_membrane_ is a part of NEURON 7.3 (which I have), but it doesn't seem to be working. I have tried putting the following code into the program, but I get the error "use_fast_imem() not a public member of CVode".

Code: Select all

objref cvode
cvode = new CVode()
cvode.use_fast_imem(1)
I downloaded and installed NEURON early this year (2015), however, when I start NEURON, I get this message

NEURON -- VERSION 7.3 ansi (1078:2b0c984183df) 2014-04-04
Duke, Yale, and the BlueBrain Project -- Copyright 1984-2014
See http://www.neuron.yale.edu/neuron/credits

Which tells me my version is from 2014. Do I need to update to a more recent version of NEURON for i_membrane_ to work?
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Help exporting neuron geometry and voltages over time

Post by ted »

Yes, it will be much easier to use i_membrane_. With regard to discovering where segment centers are located, the simplest approach is to treat each section's pt3d data as three piecewise linear functions of range, and use the Vector class's interpolate method to find the xyz values that correspond to normalized path lengths that are {(0.5+i)i/nseg for i=0,nseg-1) from the 0 end of each section. It is also useful to use a SectionList that holds all the sections that are of interest, and an NMODL-specified density mechanism to hold the results of interpolation.

Here's an NMODL-specified density mechanism, which is in a file called locus.mod:

Code: Select all

NEURON {
  SUFFIX locus
  RANGE x, y, z
}
PARAMETER {
  x = 0 (1) : spatial coords
  y = 0 (1)
  z = 0 (1)
}
Here's a procedure that calculates the xyz coordinates of a model cell's internal nodes. It expects that locus has been inserted into all sections of interest, that all sections have been interest have been discretized (i.e. that their nseg values have been asserted), and it expects to be called with an argument that is a SectionList to which all sections of interest have been appended:

Code: Select all

proc interploci() { local ii, nn, xr  localobj xx, yy, zz, length, xint, yint, zint, range
  // xx, yy, zz, length hold the original, irregularly spaced data
  // xint, yint, zint, range hold the interpolated data, and are spaced at regular intervals

  forsec $o1 {
    // get the data for the section
    nn = n3d()
    xx = new Vector(nn)
    yy = new Vector(nn)
    zz = new Vector(nn)
    length = new Vector(nn)

    for ii = 0,nn-1 {
      xx.x[ii] = x3d(ii)
      yy.x[ii] = y3d(ii)
      zz.x[ii] = z3d(ii)
      length.x[ii] = arc3d(ii)
    }

    // to use Vector class's .interpolate() 
    // must first scale the independent variable
    // i.e. normalize length along centroid
    length.div(length.x[nn-1])

    // initialize the destination "independent" vector
    range = new Vector(nseg)
    range.indgen(1/nseg)
    range.add(1/(2*nseg))

    // length contains the normalized distances of the pt3d points 
    // along the centroid of the section.  These are spaced at irregular intervals.
    // range contains the normalized distances of internal nodes
    // from the section's 0 end.  These are spaced at regular intervals.
    // Ready to interpolate.

    xint = new Vector(nseg) // hold coords of internal nodes
    yint = new Vector(nseg)
    zint = new Vector(nseg)

    xint.interpolate(range, length, xx)
    yint.interpolate(range, length, yy)
    zint.interpolate(range, length, zz)

    // for each internal node, assign the xyz values to x_locus, y_locus, z_locus
    for ii = 0, nseg-1 {
      xr = range.x[ii]
      x_locus(xr) = xint.x[ii]
      y_locus(xr) = yint.x[ii]
      z_locus(xr) = zint.x[ii]
    }
  }
}
After calling interploci with an appropriate argument, each segment's x_locus, y_locus, and z_locus range variables will equal the xyz coordinates of that segment's center.

Here's a test program that you can use to verify its proper operation:

Code: Select all

load_file("nrngui.hoc")
load_file("cell.hoc") // specification of model cell
  // whose sections have been appended to a List called "all"

define_shape() // do this before calculating segment centers!

forall insert locus
load_file("interploci.hoc")
interploci(all)

forsec all {
  print secname()
  for (x,0) print x, x_locus(x), y_locus(x), z_locus(x)
}
Be sure to read about define_shape in the Programmer's Reference! (also about any other features of hoc that you may not already know, e.g. Vector class's interpolate method).

You might try this with a toy model cell that has two or three sections of known length and orientation.
Post Reply