Calculating steady state transfer impedance

Anything that doesn't fit elsewhere.
Post Reply
Aman_Aberra
Posts: 8
Joined: Wed Jun 24, 2015 9:40 am

Calculating steady state transfer impedance

Post by Aman_Aberra »

Hi,

I want to use NEURON's Impedance class to calculate steady state transfer impedances from every dendritic or axonal compartment to the soma for a number of cell models. To make sure I'm doing this correctly, I wanted to generate plots identical to the histograms of transfer impedance in Fig. 4 of the 1996 Mainen and Sejnowski Nature paper using their cortical cell models on ModelDB. I believe for their paper they actually injected long current pulses in the soma and recording the membrane potential in every dendritic compartment to get each compartment's transfer impedance (Z=V/I), and then incremented the histogram bin for each impedance by that compartment's surface area. My approach has been to compute transfer(x) and area(x) in every dendritic compartment while setting loc() to the soma, which I think is the equivalent measurement, but so far both the impedance and area measurements appear to be different. I'm currently loading their cell models with extracellular to use for stimulation with extracellular fields, and I left the axon attached for these measurements, although when I deleted the initial segment and ran it I got the same results. I normally initialize to steady state, so I tried just initializing to the default v_init from the models and this also had no effect. Otherwise, I don't think I've made any other changes to the original models in the way I run them.

Here's my code:

Code: Select all

// For Transfer Impedance between soma and dendrites in Mainen cells (cellids 1-4)
proc measureImpDendMain() { localobj local_sect
	local_sect = $o1
	access local_sect.sec
	strdef local_sect_name
	local_sect_name = secname()	
	freq = $2 
	imp = new Impedance()
	local_sect.sec imp.loc(0.5)
	Zvec = new Vector() // transfer impedances (MOhm)	
	Avec = new Vector() // compartment surface areas (µm^2)
	Dvec = new Vector() // compartment diameters (µm)
	//forall if(issection("dend.*") && !issection(local_sect_name) ){		 
	//forall if(issection("a.*") && !issection(local_sect_name) ){		 
	forsec dendritic_only if(!issection(local_sect_name)) {
		for(x,0) {
			imp.compute(freq)
			Zvec.append(imp.transfer(x))
			//Avec.append(L/nseg)
			Avec.append(area(x))
			Dvec.append(diam(x))
		}		
	}	
}
(I've omitted code for writing vectors to files)
And here's a comparison of their figure and my results:
My results
Image
Mainen 1996 Fig. 4
Image

Any suggestions for figuring this out would be appreciated
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Calculating steady state transfer impedance

Post by ted »

Didn't see any figures so I can't comment on any differences you might have found.

Big hints to simplify and speed up your use of Impedance:
1. It is only necessary to create an Impedance class instance ONCE.
2. A single call of Impedance.compute calculates all values for all existing internal nodes.

Consider this toy example, which presumes the existence of a model cell that has a section called soma:

Code: Select all

// always a good idea to finitialize before computing impedance
v_init=-65
finitialize(v_init)

objref zz
zz = new Impedance()
FREQ = 0 // Hz
WHERE = 0.5 // location in the soma that is the reference point
soma distance(0, WHERE)  // sets origin for distance calculations

proc calcZ() {
  soma zz.loc(WHERE)  // sets origin for impedance calculations
  zz.compute(FREQ, 1) // takes the impedance contributions of 
                      // gating state differential equations into account
                      // but requires mechanisms to be compatible with CVODE
  print "x distance(x) input(x) input_phase(x) transfer(x) transfer_phase(x) ratio(x)"
  forall {
    print secname()
    for (x) print x, distance(x), zz.input(x), zz.input_phase(x), zz.transfer(x), zz.transfer_phase(x), zz.ratio(x)
  }
}

calcZ()
Other suggestions:
Call "access" only once. Using more than one access statement is asking for trouble. Don't do it. "access abuse"
can leave you confused about the identity of the currently accessed section, and the default section. Use section stack notation to specify the currently accessed section. See this thread for further discussion:
https://www.neuron.yale.edu/phpBB2/view ... t=301#p825
Aman_Aberra
Posts: 8
Joined: Wed Jun 24, 2015 9:40 am

Re: Calculating steady state transfer impedance

Post by Aman_Aberra »

Thanks for the reply. It looks like the images didn't attach correctly, here are the links:
My results:
http://imgur.com/lIuT1Sf
Mainen figure:
http://imgur.com/r24TR7J

I got essentially the opposite trend from the paper, with the largest cell, the L5 pyramidal cell, possessing the lowest transfer impedances, and the smallest cell, L3 Aspiny Stellate, possessing the highest transfer impedances. I think the areas match up to the Mainen figure, estimating from the area under the curves, and I've checked that the total area in my histograms matches a direct calculation in NEURON like this:

Code: Select all

 total_area = 0
forsec dendritic_only for(x,0) total_area+= area(x)
So I think I must be calculating a different impedance measure from the one in their paper, but based on their description, I would think my proc does the same thing. This is their wording exactly:
"The steady-state transfer impedance (Z) from the soma to each simulated dendritic compartment was calculated by injecting a small current step (I) in the soma and measuring the resulting (passive) steady-state voltage change (V) in the dendritic compartment (Z=V/I)..."

Another thing I just thought is I didn't make the models passive by removing the channels. I initially thought that since the Impedance calculation doesn't take into account differential gating states, the result shouldn't be different. I'll try making them passive now, but do you think this could be the cause?
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Calculating steady state transfer impedance

Post by ted »

The Impedance class's compute() method generates what is equivalent to "small signal" measures of impedance. If there is no second argument, or if the second argument is not equal to 1, all active conductances are constant, with values equal to whatever they are when compute() is called. That's different from what Mainen & Sejnowski did--their time-domain approach allows active conductances to change, i.e. is more similar to calling compute() with a second argument equal to 1. If your model includes extracellular, you won't be able to do that (see the documentation of Impedance.compute() https://www.neuron.yale.edu/neuron/stat ... ce.compute).
Another thing I just thought is I didn't make the models passive by removing the channels.
That isn't going to make your approach more similar to what Mainen and Sejnowski did. By calling compute() without a second argument you treated all voltage-gated conductances as if they were constant conductances. Mainen and Sejnowski didn't do that--they not only preserved voltage gated conductances, they allowed them to change during the simulation.
Aman_Aberra
Posts: 8
Joined: Wed Jun 24, 2015 9:40 am

Re: Calculating steady state transfer impedance

Post by Aman_Aberra »

I see, I thought when they said they measured the "resulting (passive) steady-state voltage change..." that meant removing the active conductances from the model.

I tried just doing their same simulation by injecting a 0.01 nA current in the soma for 100 ms and calculating the impedance of each compartment (leaving in active conductances and the axon), but I'm getting plots that look similar to the results from using the Impedance class. For example, for the L3 Pyramidal cell (Fig. 1c), the transfer impedances in the paper were between 10-15 MOhm, but I'm getting impedances of 80-100 MOhm when initialized to steady state (same as Impedance class calculation). Trying some other changes, I get impedances of 50-75 MOhm when initialized to -70 mV (default), and 32-46 MOhm after deleting the axon. The impedances also seem to be sensitive to the amplitude of the current injection. I guess I should expect that because of the non-linear conductances, but I thought it shouldn't vary too much with small variations around low amplitude currents.

Without the axon, initializing the cell to -70 mV, and with a 0.05 nA current injection gives dendritic transfer impedances between 70-90 MOhm. I would think they'd include the amplitude in the caption of the figure if it was that important to the results, so I'm not sure what to make of this. I even tried just running the model from ModelDB with no modifications to do this test, and I got the same results as when I load the cell within my code.

Thanks for the help so far, Ted
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Calculating steady state transfer impedance

Post by ted »

Well, at least you've found that the Impedance class's frequency domain results and your own time domain small signal results are similar. I would tend to believe the Impedance class's results.
The impedances also seem to be sensitive to the amplitude of the current injection.
As they should be, if active currents are present, because sustained depolarization activates the delayed rectifier.
Post Reply