Jaffe & Carnevale 1999 code

Managing anatomically complex model cells with the CellBuilder. Importing morphometric data with NEURON's Import3D tool or Robert Cannon's CVAPP. Where to find detailed morphometric data.
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Jaffe & Carnevale 1999 code

Post by ted »

Corinne wrote:I would like to put the maximum epsp amplitudes in a vector so that I can take the .max and .min of the vector in order to automatically set the scale of my ShapePlot.
Why? Just iterate over all internal nodes to find the max and min. For a range variable called rangevar

Code: Select all

min = 1000
max = -min
forall for (x,0) {
  if (rangevar(x)>max) max = rangevar(x)
  if (rangevar(x)<min) min = rangevar(x)
}
Corinne
Posts: 38
Joined: Wed Feb 09, 2011 7:13 pm

Re: Jaffe & Carnevale 1999 code

Post by Corinne »

Hi Ted,

Sorry to rehash this again, but I think the max mechanism you posted on this thread on Sep 3 to find the maximum epsp isn't quite right. I didn't notice it before due to a bug I had in my code. I think the mechanism is finding the epsp amplitude at all segments of the dendritic tree at the last time step instead of finding the max epsp at every segment for all times. I realized this when I saw that my epsp amplitudes were dependent on my value of tstop and the values correspond to the voltage values at t=tstop. I am not quite sure how to get the max amp at each segment given by this mechanism over all time. I think this same concept will also affect your last post.

Thanks again for your guidance!
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Jaffe & Carnevale 1999 code

Post by ted »

You're right, that code is guaranteed to give incorrect results. I promise to never make another mistaek. The complete corrected mod file is

Code: Select all

NEURON {
  SUFFIX max
  RANGE v0, vepsp
}

ASSIGNED {
  v (millivolt)
  v0 (millivolt)
  vepsp (millivolt)
}

INITIAL {
  v0 = v
  vepsp = v - v0
}

AFTER SOLVE { 
  if ((v - v0) > vepsp) {
    vepsp = v - v0
  }
}
Note that this code will happily report the maximum depolarization caused by any perturbation of the cell, be it a spike or an injected current pulse or whatever. "depol" might be a better name for the RANGE variable vepsp.
Corinne
Posts: 38
Joined: Wed Feb 09, 2011 7:13 pm

Re: Jaffe & Carnevale 1999 code

Post by Corinne »

Hi Ted,

I am trying to alter the code you posted on this thread on August 31, 2011. For a synapse placed at every segment of the neuron, your code plots the distance of the synapse from the soma vs the resulting psp at the soma normalized by the maximal psp at the soma. Instead of normalizing by the maximal psp, I would like to divide by the psp at the location of the synapse, i.e. I want the ratio of dendritic to somatic psp amplitudes vs distance from to soma as the result of a synapse placed at every segment of the neuron. In order to do this, I need to find the local psp at every synapse. I have tried to incorporate this into the code you posted; however, I am having difficulty defining the vdend variable (as you defined a vsoma variable in the original code) because the location of vdend is changing unlike vsoma. Below is my altered code. I have put a *** in front of the lines that are new in order to try to incorporate the changes. Any help you could provide would be much appreciated. Thanks!

Code: Select all

load_file("nrngui.hoc")

TSTOP = 50 // long enough for even the slowest somatic epsp to peak
V_INIT = -70 // resting potential of model cell

load_file("Cell.hoc")

///// instrumentation

objref syn
soma syn = new AlphaSynapse(0) // make soma(0) the "reference point"
syn.onset = 1 // ms
syn.tau = 1 // ms
syn.gmax = 1e-4 // uS
syn.e = -80 // mV  negative reversal potential for inhibitory synapse

objref vsoma
vsoma = new Vector() // for recordings of vsoma
soma vsoma.record(&v(0)) // record soma.v(0) waveform
***// i don't think it makes sense to put vdend here because vdend changes location

///// simulation control code

tstop = TSTOP
v_init = V_INIT

***objref ampvecAtSoma, distvec, ampvecOnDend vdend
ampvecAtSoma = new Vector() // for soma psp amplitudes
***ampvecOnDend = new Vector() // for dend psp amplitudes
distvec = new Vector() // for synaptic distances from soma(0)
soma distance() // make soma(0) the origin for distance measurements

//this procedure is called for all segments and moves the synapse
//to that segment then runs the program to find the minimum voltage deflection
// and appends it to the end of the ampvecAtSoma
// $1 is 1 or -1 (specifies whether distance should be - or +)
//i.e. is syn on a basilar or an apical dendrite
// $2 is location of node in currently accessed section
***proc onepoint() { local vminSoma vminOnDend
***vdend = newVector()
***$2 vdend.record(&v(WHAT DO I PUT HERE? BECAUSE THE SEGMENT LOCATION OF THE INJECTION CHANGES) //NOT SURE IF THIS WILL WORK TO SPECIFY THE SECTION
syn.loc($2) // move syn to currentsection($2)
// print secname(), " ", $2 // to verify proper operation of program
 distvec.append($1*distance($2))
 run() 
 // assumes that cell was initialized to resting steady state!
 vminSoma = vsoma.min() - vsoma.x[0] // extract psp amplitude from waveform
 ampvecAtSoma.append(vminSoma) // add the minimum value to the end of the ampvecAtSoma vector
***vminOnDend = vdend.min() - vdend.x[0] // extract psp amplitude from waveform
***ampvecOnDend.append(vminOnDend) // add the minimum value to the end of the ampvecAtSoma vector
}
objref g // for Graph that shows results

proc allpoints() { local vmin
 // throw out old results  
 ampvecAtSoma = new Vector()
*** ampvecOnDend = new Vector()
 distvec = new Vector()
 // deal with all neurites
 printf("Working")
 soma for(x) {
 onepoint(1,x)
 printf(".") // indicate progress
 }
 forsec basilars for (x) if (x>0) {
 onepoint(-1,x)
 printf(".")
 }
 forsec apicals for (x) if (x>0) {
 onepoint(1,x)
 printf(".")
 }
 printf("done!\n")
 ***// divide psp at soma by amplitudes by psp at the local dendrite
 ***//ampvecAtSoma.div(ampvecAtDend)
 g = new Graph()
 ampvecAtSoma.mark(g, distvec, "O", 5) // medium small black filled circle
 g.exec_menu("View = plot") // autoscale axes
}

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

Re: Jaffe & Carnevale 1999 code

Post by ted »

The easiest way to do what you want is to use the max mechanism posted in my September 26 msg. The algorithm in pseudocode is

Code: Select all

for each section {
  for each internal node in this section {
    calculate the distance from this node to the soma and save it
    move the synaptic mechanism to this location
    run a simulation
    calculate the ratio soma.vepsp_max(x)/vepsp_max(x) and save it
  }
}
If the synaptic mechanism is hyperpolarizing, I would use a mechanism called min whose source code would differ from that of max in the following ways:
in the NEURON block

Code: Select all

  : SUFFIX max
  : RANGE v0, epsp
  SUFFIX min
  RANGE v0, ipsp
in the ASSIGNED block

Code: Select all

:  vepsp (millivolt)
  vipsp (millivolt)
in the INITIAL block

Code: Select all

:  vepsp = v - v0
  vipsp = v - v0
in the AFTER SOLVE block

Code: Select all

:  if ((v - v0) > vepsp) {
:    vepsp = v - v0
  if ((v - v0) < vipsp) {
    vipsp = v - v0
Corinne
Posts: 38
Joined: Wed Feb 09, 2011 7:13 pm

Re: Jaffe & Carnevale 1999 code

Post by Corinne »

Hi Ted,

Thanks, I thought of using the max mechanism (I am using a min version) you posted before; however, I was uncertain where to place it in the file when marching the synapse around. Because the mechanism calculates the psp at each point (segment) in the neuron as the result of a synapse, I think I would place it inside the onepoint procedure. But then, I would need to pull out the appropriate value at the segment where the current synapse is. I think I could do this by accessing the current segment and then only inserting the max mechanism at the accessed segment. So something like this:

At the bottom of the onepoint procedure:

Code: Select all

access $2
insert minv
vminOnDend = vipsp_minv
ampvecOnDend.append(vminOnDend) // add the minimum value to the end of the ampvecAtSoma vector
However, using access in this way doesn't work and I need to get the vipsp_min v for the correct segment not just the section. Can you provide guidance? Thanks!
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Jaffe & Carnevale 1999 code

Post by ted »

It's not complicated. Just install max (or min) into all sections. The pseudocode

Code: Select all

for each section {
  for each internal node in this section {
    . . .
    calculate the ratio soma.vipsp_min(x)/vipsp_min(x) and save it
  }
}
expressed in hoc is

Code: Select all

forall for (x,0) {
  . . .
  tmp = soma.vipsp_min(x)/vipsp_min(x)
}
Note that the numerator is amplitude at the soma (which is what you want), and the denominator is amplitude in the current segment of the currently accessed section (why? see Programmer's Reference documentation of forall) (which is also what you want, because that's the place to which you moved the synapse).
Corinne
Posts: 38
Joined: Wed Feb 09, 2011 7:13 pm

Re: Jaffe & Carnevale 1999 code

Post by Corinne »

Thanks Ted,

I worked your commands into the onepoint procedure. I wanted to do a sanity check to make sure everything was working. Checking the soma.vipsp_minv(0) was easy. I just used print statements and plotted the voltage trace at the soma while the program was iterating though the onepoint() procedure and made sure the values on the voltage plot matched those printed to the screen. In order to check the vipsp_vminv($s) values, I made matching a simulation via the gui where I place a synapse (matching the ones I use in my .hoc file) at different segments of the neuron and plot the voltage trace local to where I placed the synapse. I compared these values to what was coming out of my .hoc file. Interestingly, everything checked out except at bas.v(1) and ap.v(1). In these instances the voltage deflection I see via the gui code is slightly different than what is calculated by minv (i.e. voltage defection via gui simulation is 0.2547 and calculated out of minv I get 0.2439). Do you have any idea why this might be? Thanks!
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Jaffe & Carnevale 1999 code

Post by ted »

NEURON discretizes space with the central difference approximation. This means that an axial resistance lies in series between a section's 1 end and the nearest internal node, i.e. the "nsegth" node (which is located at 1-1/(2*nseg)). If a source of current is placed at 1, current flow through this resistor produces a voltage drop that rides on top of the voltage at the nearest internal node. min is a density mechanism, so vipsp_min(1) returns the value measured at the nsegth node, not the value at 1.
Corinne
Posts: 38
Joined: Wed Feb 09, 2011 7:13 pm

Re: Jaffe & Carnevale 1999 code

Post by Corinne »

I have another question with regard to this post.

I am making shape plots of the max PSP deflection at each point of a neuron caused by an inhibitory synapse. To calculate the deflection I use a mechanism:

minv.mod

Code: Select all

NEURON {
  SUFFIX minv
  RANGE v0, vipsp
}

ASSIGNED {
  v (millivolt)
  v0 (millivolt)
  vipsp (millivolt)
}

INITIAL {
  v0 = v
  vipsp = v - v0
}

AFTER SOLVE {
  if (v - v0 < vipsp) {
    vipsp = v - v0
  }
}


I insert this mechanism into my code via:

Code: Select all

forall insert minv
After I make the PlotShape() I want to scale the range of the plot automatically. To do this I need to calculate the minimum and maximum vipsp_minv values so I can set them as the limits. To do this I do:

Code: Select all

min = 1000
max = -min
forall for (x,0) {
  if (vipsp_minv(x)>max) max = vipsp_minv(x)
  if (vipsp_minv(x)<min) min = vipsp_minv(x)
sizePSPvector=sizePSPvector+1
}
Then I can use min and max to set the range of my shape plot:

Code: Select all

objref sh
sh = new PlotShape()
sh.variable("vipsp_minv")
sh.scale(min, max)
sh.exec_menu("Shape Plot") //brings out color
All of this works great. Now is where I am running into problems. I want to make another shape plot; only, in this one I would like to plot the same vipsp_minv values normalized by the maximal voltage deflection generated at the location of the synapse (this is equal to min since this is an inhibitory synapse). Basically I want to do the equivalent of:

Code: Select all

objref sh
sh = new PlotShape()
sh.variable("vipsp_minv/min")
sh.scale(0, 1)
sh.exec_menu("Shape Plot") //brings out color
The code above doesn't work. So, I am trying to put vipsp_minv/min in a vector or something so that I can put that variable into the sh.variable(" "). I have tried things like:

Code: Select all

objref normminv
normminv = new Vector(sizePSPvector)
i=-1
forall for (x ,0){
i=i+1
normminv.set(i, vipsp_minv(x)/min)
print i, x, vipsp_minv(x)/min, normminv.get(i)
}
However this does not put all the values (which I have confirmed are being calculated via the print statement) into the normminv variable. Can you suggest a way to do what I am trying to do?

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

Re: Jaffe & Carnevale 1999 code

Post by ted »

You're almost there. The documentation of the PlotShape's variable() method indicates that the plotted variable must be a range variable. This means it can't be an expression, or a value returned by a function, or the contents of a Vector. So where can you get such a range variable? Just revise your minv mechanism to give it a new RANGE variable that is declared as ASSIGNED

Code: Select all

NEURON {
  . . .
  RANGE vn : for "normalized v" or choose a more evocative name if you can imagine one
}
. . .
ASSIGNED
  . . .
  vn (1) : because it is dimensionless
}
. . .
INITIAL {
  . . .
  vn = 0
}
. . .
Then after your simulation is complete and you have determined min, execute
forall for (x,0) vn_minv(x) = vipsp_minv(x)/min
and vn_minv will be ready to be displayed in its own PlotShape graph.
Post Reply