Total charge

NMODL and the Channel Builder.
Post Reply
kahinou

Total charge

Post by kahinou »

Hello,

I'm working on a small model (neuron with soma, axon and 3 dendrites) and one of the questions that I am trying to get an answer to is about computing the total charge of a section in a hoc.file, using the formula:
inf
Q = integral I*dt, where I is the total current flowing in that given section
0

I tried to use the method in http://www.neuron.yale.edu/phpBB/viewto ... 179e#p3915

but it didn't work - error messages- and I am not sure whether it's valid in this case.

Any help will be appreciated.
Thanks in advance
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Total charge

Post by ted »

it didn't work - error messages
In the absence of any information about how you tried the method described in that link, or what the error message was, I cannot make any useful suggestions about what might have gone wrong or how to fix it.
computing the total charge of a section
Presumably you want an integral of the section's membrane current. Here's an outline of what you need to do.

Code: Select all

first set up the model cell
create a Vector and make it record t
insert the extracellular mechanism into each section of interest
for each section of interest {
  for each segment in that section {
    create a Vector and make that Vector record that segment's i_membrane
  }
}
run a simulation
for each section of interest {
  create a "net current Vector" // that is, a Vector that will hold
    // the time course of that section's total membrane current
  for each segment in the section {
    multiply the corresponding current Vector by the segment's area
    add the scaled current Vector to the "net current Vector"
  }
}
for each section of interest {
  integrate that section's "net current Vector"
}
Implementation suggestions:
1. In developing the necessary code to implement the above algorithm, follow the principles of modular organization, incremental development, and repeated cycles of revision and testing. It will help if each major "for" loop is implemented as a procedure or function. Make sure that each new procedure or function works properly before you move on to creating the next one.
2. If every section in a cell is a "section of interest," use forall to iterate over all sections. If not, create a SectionList, append the sections of interest to it, and then use forsec SectionList.
3. Don't bother recording i_membrane at the 0 or 1 nodes, because those locations have no associated area and don't contribute to membrane current. Record only at the internal nodes. Use for (x,0) to iterate over a section's internal nodes.
4. Do not try to manage the Vectors as a so-called "array of vectors" (also called "subscripted objrefs" or "objref names with numerical indices"). Instead, use Lists.
5. The area in um2 associated with node x of the currently accessed section is area(x).

Here is an implementation of the first major "for" loop that follows the above recommendations. It assumes that you are interested in the total membrane currents of all sections, and it allows each section to have a different value for nseg.

Code: Select all

// returns a List whose elements are 
// the current vectors that belong to the currently accessed section
obfunc make_iveclist() { localobj tmpvec, tmplist
  tmplist = new List()
  for (x,0) {
    tmpvec = new Vector()
    tmpvec.record(&i_membrane(x))
    tmplist.append(tmpvec)
  }
  return tmplist
}
// returns a List whose elements are 
// the current Vector lists of the sections of interest
obfunc make_list_of_iveclists() { localobj tmplist
  tmplist = new List()
  forall tmplist.append(make_iveclist())
  return tmplist
}
objref list_of_iveclists
list_of_iveclists = make_list_of_iveclists()
Now we have to do this

Code: Select all

for each section of interest {
  create a "net current Vector" // that is, a Vector that will hold
    // the time course of that section's total membrane current
  for each segment in the section {
    multiply the corresponding current Vector by the segment's area
    add the scaled current Vector to the "net current Vector"
  }
}
and here is an implementation

Code: Select all

// $o1 is the currently accessed section's iveclist
// returns a Vector that contains
// the total membrane current of the currently accessed section
obfunc make_inetvec() { local i  localobj tmpvec
  i = 0 // index of the element in $o1 that is the current vector
    // that corresponds to the first internal node
    // of the currently accessed section
  tmpvec = new Vector($o1.o(i).count) // tmpvec is automatically filled with 0s
  for (x,0) {
    $o1.o(i).mul(area(x)/100) // current in mA/cm2 * area in um2 * 0.01 = nA
    tmpvec.add($o1)
    i+=1 // index of the next node's current vector in $o1
  }
  return tmpvec
}
obfunc make_list_of_inetvecs() { local i  localobj tmplist
  i = 0 // index of the first section's iveclist in the list_of_iveclists
  tmplist = new List()
  forall {
    tmplist.append( make_inetvec(list_of_iveclists.o(i)) ) // pass make_inetvec
      // the iveclist that corresponds to the currently accessed section
    i+=1 // index for next section's iveclist in the list_of_iveclists
  }
  return tmplist
}
objref list_of_inetvecs
list_of_inetvecs = make_list_of_inetvecs()
I think all that code should work properly, but strongly suggest testing of each procedure and function before relying on it. That testing is "left as an exercise for the reader," as is this last part

Code: Select all

for each section of interest {
  integrate that section's "net current Vector"
}
kahinou

Re: Total charge

Post by kahinou »

Thank you very much. I will adapt the algorithm to my situation and give you feedback.
kahinou

Re: Total charge

Post by kahinou »

I have a couple of questions before I complete my implementation:
4. Do not try to manage the Vectors as a so-called "array of vectors" (also called "subscripted objrefs" or "objref names with numerical indices"). Instead, use Lists
- Why do you use a list of vectors and a list of Vector lists? Do I need to do that if I focus on one dendrite (all segments) for exemple?

Code: Select all

obfunc make_iveclist() { localobj tmpvec, tmplist
  tmplist = new List()
  for (x,0) {
    tmpvec = new Vector()
    tmpvec.record(&i_membrane(x))
    tmplist.append(tmpvec)
  }
  return tmplist
- Print tmplist returns
undefined variable tmplist
Is that because tmplist is defined as a local objref within obfunc?

Thank you in advance
ted
Site Admin
Posts: 6299
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Total charge

Post by ted »

Good questions.
kahinou wrote:Why do you use a list
Managing a collection of objects is a common task. Using lists allows one to write code that works regardless of the number of objects that must be managed.
kahinou wrote:Why do you use . . . a list of Vector lists?
If a cell has more than one section, and each section may have a different nseg, how does one write code that manages the Vectors associated with each section regardless of how many sections there are and how many segments in each section?
Do I need to do that if I focus on one dendrite (all segments) for exemple?
There is no need to write code that is any more complex than necessary. That said, the model cell that you described has more than one section.
- Print tmplist returns
undefined variable tmplist
Is that because tmplist is defined as a local objref within obfunc?
First, that would be
print tmplist
not
Print tmplist
Now for your question: you're probably familiar with the idea of "the scope of a variable." A token that is declared to be a local or localobj inside a procedure or function will exist only inside that procedure or function. If
print tmplist
is executed outside of the proc or func that declared it to be a localobj, hoc produces an "undefined variable" message.
Post Reply