Problem in putting detailed morphology into a template

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.
Post Reply
Randy

Problem in putting detailed morphology into a template

Post by Randy » Thu Nov 12, 2009 9:39 pm

Asingle neuron model based on a detailed morphology works well (I adopt it from ModelDB). However, when I tried to put it into a template (because I want to buit a network), the interpreter showed the following error:

itGHK mechanism not inserted in section soma
nrniv:
in C:/nrn70/TC_Randy/TC_Detailed_Randy.hoc near line 154
^
TC[0].localize(1.7e-058.5e-058.5e-05 , , )
TC[0].init( )

the template code is (only related parts are showed):

begintemplate TC

public soma, dend1, dend2, dend3, dend4, dend5, dend6, dend7, dend8, dend9, dend10, dend11
create soma, dend1[1], dend2[1], dend3[1], dend4[1], dend5[1], dend6[1], dend7[1], dend8[1], dend9[1], dend10[1], dend11[1]

proc init() {
xopen("tc200.geo") // read geometry file
G_pas = 3.79e-5
E_pas = -76.5

forall { // insert passive current everywhere
insert pas
g_pas = G_pas
e_pas = E_pas
cm = 0.88
Ra = 173
L = L
}
soma {
insert pas
g_pas = G_pas
cm = 0.88
insert hh2 // insert fast spikes
ena = 50
ek = -100
vtraub_hh2 = -52
gnabar_hh2 = 0.1
gkbar_hh2 = 0.1
}
forall {
insert itGHK // T-current everywhere
cai = 2.4e-4
cao = 2
eca = 120
shift_itGHK = -1 // screening charge shift + 3 mV error
gcabar_itGHK = 0.0002
qm_itGHK = 2.5
qh_itGHK = 2.5
insert cad // calcium diffusion everywhere
depth_cad = 0.1
kt_cad = 0 // no pump
kd_cad = 1e-4
taur_cad = 5
cainf_cad = 2.4e-4
}
xopen("loc200.oc") // load procedures for localizing T-current
localize(1.7e-5, 8.5e-5, 8.5e-5)
}

endtemplate TC

It looks like the 'for all' code doesn't work at all...

I promise the .geo file has no problem because it works pretty well in a single neuron model.

I really don't understand what the problem is...

Thank you!

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

Re: Problem in putting detailed morphology into a template

Post by ted » Fri Nov 13, 2009 2:40 pm

I wonder if forall is iterating over anything. To find out, try inserting a
forall print secname()
statement at the beginning of proc init() and see what happens when you create a single instance of your cell.

forall is slower than using forsec, which is why I'd give each instance of the class its own "all" objref that is initialized _before_ geometry or biophysical properties are assigned.

Code: Select all

public all
objref all
proc subsets() { local i
  objref all
  all = new SectionList()
  soma all.append()
  // now append all the other sections to all
  for i=0, 1 {
    dend1[i] all.append()
    dend2[i] all.append()
    . . . etc . . .
  }
}
Then for anything that is to be assigned to all sections, I'd use forsec all.

Randy

Re: Problem in putting detailed morphology into a template

Post by Randy » Thu Nov 19, 2009 2:37 am

thank you! your suggestion is really helpful~

i tried "forall print secname()" and a weired thing happened... before I open .geo file, this statement gives out all section names correctly. but after .geo file is open and interpreted, it gives out nothing. so i think this explains my problem last time. it seems that .geo file kills all sections... but why?

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

Re: Problem in putting detailed morphology into a template

Post by ted » Thu Nov 19, 2009 9:35 am

I'll have to see your code to discover the cause of the problems you're having. Zip up just enough hoc, ses, and mod files to reproduce the problem, and send the file to me
ted dot carnevale at yale dot edu
If you are unsure about what to send and what not to send, please see
What to include in a zip file, and what to leave out
http://www.neuron.yale.edu/phpBB/viewto ... f=28&t=560

mxc
Posts: 2
Joined: Sun Sep 08, 2013 12:32 pm

Re: Problem in putting detailed morphology into a template

Post by mxc » Mon Sep 23, 2013 3:01 pm

Hi. I was wondering whether there was a solution to the problem discussed in this post. I have a similar issue now.

What I'm trying to do is create a template for a detailed neuron, taken from Mainen and Sejnowski 1996. Putting each of these neurons in a template will allow me to create a small network comprising various numbers of these 4 cell exemplars. I downloaded the Mainen code from modelDB and made some minor adjustments, which all worked fine. However, when I try to turn it into a template, it doesn't work. There are no errors when loading the .hoc file, but I get the following error when trying to call the template.

Code: Select all

oc>objref c
oc>c=new L5pyr_cell_template()
/opt/nrn/i686/bin/nrniv: nil object is not a SectionList
 near line 2
 ^
        L5pyr_cell_template[0].init_cell()
      L5pyr_cell_template[0].init()
I believe the problem may arise from calling the external script that defines the geometry ("patdemo/cells/j4a.hoc" from the modelDB zip file). Closer inspection reveals that the neuron was in fact created. This was confirmed with shape plots and topology(). However, topology() reveals the following:

Code: Select all

|-|       L5pyr_cell_template[0].myelin[3](0-1)
|-|       L5pyr_cell_template[0].myelin[4](0-1)
|-|       L5pyr_cell_template[0].node[0](0-1)
|-|       L5pyr_cell_template[0].node[1](0-1)
|-|       L5pyr_cell_template[0].node[2](0-1)
|-|       L5pyr_cell_template[0].node[3](0-1)
|-|       L5pyr_cell_template[0].node[4](0-1)
|-|       soma(0-1)
  `|       dend1[0](0-1)
    `|       dend1[1](0-1)
      `|       dend1[2](0-1)
      `|       dend1[3](0-1)
        `|       dend1[4](0-1)
        `|       dend1[5](0-1)
I cut out most of the lines, but the idea is that it seems that the neuron pieces created within the template file (node, meylin, etc.) are part of the template object, but the pieces created in the external file are not part of the template. Running "forall print secname()" suggests the same. Thus, one possible but unsatisfying solution would be to incorporate the j4a.hoc code into the template hoc file. This is a less preferred option, though, because it is slightly less elegant and wouldn't help me understand what is going wrong.

I'm super-new to NEURON, so I guess this is a simple syntax matter that I'm not aware of (I also consulted the book, but couldn't find the problem). If anything comes to mind as being the likely culprit, please let me know. The full code with both files is several thousand lines long, so I won't post it here, but could email it.

Thanks in advance!

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

Re: Problem in putting detailed morphology into a template

Post by ted » Mon Sep 23, 2013 6:36 pm

Hmm, almost 4 years since this thread was last active. I don't seem to find anything about the exact answer to the original question, but it probably wouldn't pertain to your particular case anyway.

From the response you got to topology(), it looks like your template is severely mangled. It's hard to write cell class templates properly--there are lots of purely administrative issues to keep track of, that have nothing to do with the conceptual model of the cell that you are trying to implement. Your best bet is to
import the morphology into a CellBuilder (on the Management page click on the Import radio button, then on the gray Import button; to clean up the image click on "Turn off indexed name display").
Then use that CellBuilder to manage subsets, specify the discretization strategy (d_lambda rule!) and biophysical properties, and finally save it to a session file.
Exit NEURON.
Then restart NEURON and open the CellBuilder's session file. Turn on "Continuous Create" and test the model cell to make sure it works properly (can it reproduce the figure shown in the paper?).
When you're satisfied that it does, export a template from the CellBuilder--on the Management page
click on Cell Type
then change the classname to whatever you prefer
finally click on "Save hoc code in file" (you may have to drag the lower edge of the CellBuilder down a bit to expose this button).

That will save you a lot of time and effort, and the resulting hoc code will be correct and human-readable.

mxc
Posts: 2
Joined: Sun Sep 08, 2013 12:32 pm

Re: Problem in putting detailed morphology into a template

Post by mxc » Tue Sep 24, 2013 10:19 am

Hi Ted. Thanks for your clear and quick reply. I followed your instructions, but only *almost* perfectly replicated the original figures. I spent some time double-checking all of the biophysics, and they all match perfectly in my template and the original modelDB files. The lengths and diameters, however, seem to be inconsistent. I can't quite figure out where the problem is, because some segments have the correct L/diam ("correct" meaning that my template and the original file have the same value to ~5 decimal places), other segments are slightly off (e.g., 10.39 vs. 12.85), and yet other segments are way off (3.5 vs. 40).

I tried to visually match the coordinates and diameters from the .hoc files, but I don't get the mapping there. For example, what I assume is the dend1 piece in the original file:

Code: Select all

    1 4
   -54.8      6.5      -25      3.5
     -49      5.2    -24.3      3.5
   -44.5        7    -23.7      3.5
   -42.8      7.2    -24.5      3.5
Is different from what I thought should be the corresponding dend1 piece in my template (from the neuron imported via the GUI):

Code: Select all

  dend1 {pt3dclear()
	pt3dadd(17.5, 0, 0, 3.7642)
	pt3dadd(23.5883, -1.36462, 0.734798, 3.7642)
	pt3dadd(28.312, 0.524855, 1.36462, 3.7642)
	pt3dadd(30.0965, 0.734797, 0.524855, 3.7642)
  }
Could I trouble you for some insight into this?

Another thing, which may or may not be related. I may have discovered a minor bug in NEURON concerning exporting exporting Cell Type. There were initially errors in the exported .hoc file, which stemmed from, for example, the following:

Code: Select all

proc shape3d_20() {
  dend11[72] {  }
Every time there was an empty proc shape3d_X, there was a missing end-curly-bracket. By manually inserting an end-curly-bracket, all the errors stopped and everything seems to be fine (except that the lengths/diameters are sometimes wrong... again, I'm not sure if these are related issues).

I hope this is clear enough for you to diagnose the problem. Thanks again in advance for your help.

Mike

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

Re: Problem in putting detailed morphology into a template

Post by ted » Tue Sep 24, 2013 12:23 pm

mxc wrote:The lengths and diameters, however, seem to be inconsistent. I can't quite figure out where the problem is, because some segments
The segment length for any section depends on that section's discretization parameter nseg. If the CellBuilder uses the d_lambda rule for spatial discretization, segment lengths will probably be different from those assigned by Mainend & Sejnowski. If you want to ensure identical segment lengths, you'll have to resort to manual entry of each section's nseg in the CellBuilder.
I tried to visually match the coordinates and diameters from the .hoc files
Not sure what you mean. Were you manually entering the lengths and diameters of each section into the CellBuilder's Geometry page?
For example, what I assume is the dend1 piece in the original file:
Associating a particular neurite in the original model implementation with its counterpart after importation into the CellBuilder can be difficult, because (quoting the message from the CellBuilder)
"Importing 3-D geometry will change the names of
indexed sections to conform to the
CellBuilder's indexing policy.
(Section names without indices will stay the same.)
This means that most section names at the top level
will change RIGHT NOW!"

Anyway, back to your statement--
For example, what I assume is the dend1 piece in the original file:

Code: Select all

    1 4
   -54.8      6.5      -25      3.5
     -49      5.2    -24.3      3.5
   -44.5        7    -23.7      3.5
   -42.8      7.2    -24.5      3.5
Is different from what I thought should be the corresponding dend1 piece in my template (from the neuron imported via the GUI):

Code: Select all

  dend1 {pt3dclear()
	pt3dadd(17.5, 0, 0, 3.7642)
	pt3dadd(23.5883, -1.36462, 0.734798, 3.7642)
	pt3dadd(28.312, 0.524855, 1.36462, 3.7642)
	pt3dadd(30.0965, 0.734797, 0.524855, 3.7642)
  }
Note that the code used by Mainen & Sejnowski "adjusted" neurite lengths and diameters in order to take the area contributed by spines into account--see proc add_spines() in demofig1.hoc. I don't recall who introduced this hideous practice*, but from time to time it flares up like a herpetic rash. IMO it is far better to leave anatomical values alone and instead scale the values of the relevant membrane-associated density parameters: specific membrane capacitance in uF/cm2 and ion channel densities in S/cm2. That is, if a particular neurite's spines are thought to contribute an additional 50% to its surface area above and beyond the area that one would calculate from its diameter and length, just multiply that neurite's specific membrane capacitance and ion channel densities by 1.5.

OK, off my soapbox and back to your model cell.

The point is that L5 pyramidal cells have spiny dendrites, so all actual lengths and diameters of dendrites are "adjusted" and this will be reflected in the arguments to the pt3dadd() statements. If you wanted to use the original anatomical measurements, I suppose you could copy demofig1.hoc to mydemofig1.hoc, then edit the latter file and change this statement

Code: Select all

  if (!aspiny) add_spines(dendritic_only,spine_dens)
to

Code: Select all

  print "not mangling dendrite lengths and diameters"
  print "remember to apply appropriate scale factors to dendritic cm and ion channel densities"
  // if (!aspiny) add_spines(dendritic_only,spine_dens)
Then you'd be able to use NEURON to launch mydemofig1.hoc, and proceed to select a cell and import its morphology into a CellBuilder.

But if you wanted to duplicate the M&S results, you'd have to increase each dendrite's cm and ion channel densities by a factor that depends on its length. This procedure will do it:

Code: Select all

// account for area added by spines
proc scaledens() { local factor, secarea
  secarea = 0 // will contain total area
  for (x,0) secarea += area(x)
  factor = L * spine_dens * spine_area / secarea + 1 // effect of spines on section area
  for (x,0) {
    cm(x) *= factor
    and other statements to adjust channel densities
    e.g. if gca is present
    gca(x) *= factor    
  }
}
forsec "dend" scaledens()
*--The idea was to increase the actual surface area by increasing both length and diameter in such a way that the electrotonic length of the neurite wasn't affected. Complications arise if actual diameter or actual membrane properties change along the length of the neurite. Even if there are no complications, the result is a cell that looks pecuilar because there's no guarantee that each neurite will be stretched by the same amount, and it turns out that they never are. Furthermore, the resulting morphology distortion makes the model cell completely unsuitable for studies that involve placement of synapes according to any kind of rule related to spine density per unit surface area or unit length. Also, the fact that ion channel densities are not uniform but vary with location can make it difficult to justify applying the same diameter and length scale factors along the entire length of neurites with significant lengths. Fortunately this scheme seems to have largely fallen out of use--except that you now have to deal with it.
Another thing, which may or may not be related. I may have discovered a minor bug in NEURON concerning exporting exporting Cell Type. There were initially errors in the exported .hoc file, which stemmed from, for example, the following:

Code: Select all

proc shape3d_20() {
  dend11[72] {  }
Every time there was an empty proc shape3d_X, there was a missing end-curly-bracket. By manually inserting an end-curly-bracket, all the errors stopped
Haven't seen that before. Reproduced it myself just now. That definitely needs fixing. Thanks for the bug report.

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

Re: Problem in putting detailed morphology into a template

Post by ted » Tue Sep 24, 2013 6:12 pm

OK, Michael Hines came up with a fix for the unmatched curly bracket problem. It's described here
http://www.neuron.yale.edu/hg/neuron/nr ... dbdad6bdad
The simplest thing to do is just patch
share/lib/hoc/celbild/celtopol.hoc
or if you prefer just edit that file, and change

Code: Select all

                                nline = 0
                                is3d += 1
$o1.printf("  }\n}\nproc shape3d_%d() {\n  %s {", is3d, tstr)
to

Code: Select all

//                              nline = 0
                                nline = 1
                                is3d += 1
$o1.printf("  }\n}\nproc shape3d_%d() {\n  %s {", is3d, tstr)

Hyeon
Posts: 15
Joined: Thu Jul 19, 2012 3:43 am

Re: Problem in putting detailed morphology into a template

Post by Hyeon » Tue Aug 12, 2014 10:24 pm

Hi. I have a difficulty to making the template of cell.
My problem is same with Randy. It seems that the section dend1, dend2, … , dend11 disappear, after xopen(“tc200.geo”).
Did Randy find a solution for this problem?
I don’t know what the problem is…
My code is below.
Thank you for your help you can give me.

My code is below.
//===========================================================
begintemplate mTC // create a new template object

public all
public soma, dend1, dend2, dend3, dend4, dend5, dend6, dend7, dend8, dend9, dend10, dend11
create soma, dend1[1], dend2[1], dend3[1], dend4[1], dend5[1], dend6[1], dend7[1], dend8[1], dend9[1], dend10[1], dend11[1]
objectvar all

//----------------------------------------------------------------------------
// create multi-compartment geometry and insert currents
//----------------------------------------------------------------------------

proc init() {

all = new SectionList()
xopen("cells/tc200.geo") // read geometry file

corrD = 1 // no dendritic surface correction
G_pas = 3.79e-5
E_pas = -76.5 // within 3 mV error

soma all.append()

for j=0,0 {dend1[j] all.append()}
for j=0,2 {dend2[j] all.append()}
for j=0,12 {dend3[j] all.append()}
for j=0,20 {dend4[j] all.append()}
for j=0,0 {dend5[j] all.append()}
for j=0,30 {dend6[j] all.append()}
for j=0,8 {dend7[j] all.append()}
for j=0,32 {dend8[j] all.append()}
for j=0,46 {dend9[j] all.append()}
for j=0,26 {dend10[j] all.append()}
for j=0,18 {dend11[j] all.append()}

forsec all{print secname()}

forsec all { // insert passive current everywhere
insert pas
g_pas = G_pas * corrD
e_pas = E_pas
cm = 0.88 * corrD
Ra = 173
L = L
}
soma {
g_pas = G_pas
cm = 0.88

insert hh2 // insert fast spikes
ena = 50
ek = -100
vtraub_hh2 = -52
gnabar_hh2 = 0.1
gkbar_hh2 = 0.1
}
forsec all {
insert itGHK // T-current everywhere
cai = 2.4e-4
cao = 2
eca = 120
shift_itGHK = -1 // screening charge shift + 3 mV error
gcabar_itGHK = corrD * 0.0002
qm_itGHK = 2.5
qh_itGHK = 2.5

insert cad // calcium diffusion everywhere
depth_cad = 0.1 * corrD
kt_cad = 0 // no pump
kd_cad = 1e-4
taur_cad = 5
cainf_cad = 2.4e-4
}
xopen("loc200.oc") // load procedures for localizing T-current
// low density proximal, high distal, to match volt-clamp of intact cells
localize(1.7e-5,corrD*8.5e-5,corrD*8.5e-5)
}
endtemplate mTC

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

Re: Problem in putting detailed morphology into a template

Post by ted » Wed Aug 13, 2014 8:20 pm

First, this is not a good idea

Code: Select all

for j=0,0 {dend1[j] all.append()}
for j=0,2 {dend2[j] all.append()}
for j=0,12 {dend3[j] all.append()}
for j=0,20 {dend4[j] all.append()}
for j=0,0 {dend5[j] all.append()}
for j=0,30 {dend6[j] all.append()}
for j=0,8 {dend7[j] all.append()}
for j=0,32 {dend8[j] all.append()}
for j=0,46 {dend9[j] all.append()}
for j=0,26 {dend10[j] all.append()}
for j=0,18 {dend11[j] all.append()}
because it requires you to bury a bunch of "magic numbers" in your template. Guarnteed to fail if you counted incorrectly, and it doesn't generalize at all. Why not use an iterator like forsec?
forsec "dend" all.append()

Next a question: how do you know that the sections don't exist?
What happens when you execute
objref cell
cell = new mTC
forsec cell.all print secname()
?

Finally, debugging can be difficult so it is often a good idea to simplify the problem. Make a "toy" template designed for a model cell with just two sections called soma and dend, and make a "toy" geometry file that defines the properties of just those two sections. Put no biophysical specification whatsoever in the template or in the geometry file. If you can't get the toy template to work, you're never going to be able to make the more complex template to work.

If you find that the toy template works properly, then increase the compexity of the geometry file by adding a second dendrite (give the two dendrites identical base names, something like this:

Code: Select all

create soma, dend[2]
for i=0,1 dend[i](0) connect soma(1)
soma {
  geometry specification
}
for i=0,1 dend[i] {
  geometry specification
}
and see if the template still works. If it doesn't, figure out why and fix it.

Now you're ready to add another group of dendrites. Make a new template and a new geometry file that will construct a model
that has soma, dend1, and dend2. Get that working before you move on to anything more complex.

Post Reply