Exporting rangeVar into .dat file

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
tine
Posts: 10
Joined: Thu Jan 13, 2011 2:18 pm

Exporting rangeVar into .dat file

Post by tine »

Dear all,

I have two questions relating Rangevar.

1) I want to save the values plotted in the rangevar plot into a data file, using hoc coding. Currently I have this piece of code:

before run() and after defining the cell's morphology and electrophysiology

Code: Select all

// Make range variable and put it into vector
objectvar rvp
rvp = new RangeVarPlot("v")
soma rvp.end(1)
apic[79] rvp.begin(1)
//rvp.origin(11.387)
objref yspacevect, disspacevect
yspacevect=new Vector()
disspacevect=new Vector()
rvp.to_vector(yspacevect,disspacevect)
print "yspacevector is ", yspacevect
print "disspacevector is ", disspacevect 
after run()

Code: Select all

objref savdata2,tempmatrix2
savdata2=new File()
savdata2.wopen("dataspaceplot.dat")
savdata2.printf("distance y\n")

tempmatrix2=new Matrix()
tempmatrix2.resize(disspacevect.size(),2)
tempmatrix2.setcol(0,disspacevect)
tempmatrix2.setcol(1,yspacevect)
tempmatrix2.fprint(savdata2,"%g")
savdata2.close()
At the moment it only saves the values of the first time step. How can I change my code that it records all the time steps (yspacevect with multiple columns with each column one data point)?

2) My second question is how to show the measured rangevar on a space plot defined in the session file, such that if you rerun the simulation you can see from which sections the rangevariable consists.

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

Re: Exporting rangeVar into .dat file

Post by ted »

A couple of comments. First, range variable plots iterate from the 0 to the 1 end of each section on a path, so make sure that the 0 end of each child section is attached to its parent.

Code: Select all

soma rvp.end(1)
apic[79] rvp.begin(1)
makes the origin distal and the termination proximal. If the path includes the soma, you're going to want the origin to be soma(0) and the termination to be apic[79](1). If the path does not actually include the soma, then your task will be slightly easier if the origin is the 0 end of the section that attaches to the soma, not soma(1).
I want to save the values plotted in the rangevar plot into a data file, using hoc coding. Currently I have this piece of code:

before run() and after defining the cell's morphology and electrophysiology
. . .
after run()
. . .
At the moment it only saves the values of the first time step.
Not quite. It saves values after the end of the run, which may be many time steps after the first time steps.
How can I change my code that it records all the time steps
You need a custom run() procedure that appends results to the output file after initialization and closes the file after the end of the run, and a custom advance() procedure that appends results to the output file after each fadvance(). Here is a skeleton of what the solution will look like:

Code: Select all

proc run() {
  stdinit()
  open_output_file()
  continuerun(tstop)
  close_output_file()
}

proc open_output_file() {
  // open the output file
  // append values to file
  // leave the file open 
}

proc close_output_file() {
  // close the output file
}

proc advance() {
  fadvance()
  // if output file is open, append values to it
  // note: by testing for an open output file, you avoid generating an error message
  // if you ever decide to explore by doing some single steps or continuerun
  // after the end of a "formal" simulation
}
Add the bits that I have omitted "as an exercise to the reader," then put this code in a separate file from the rest of your stuff, and use a load_file() statement to read it after everything else has been read.
My second question is how to show the measured rangevar on a space plot defined in the session file, such that if you rerun the simulation you can see from which sections the rangevariable consists.
Build a SectionList that contains the sections that are in the path, then create a Shape and use the Shape class's color_list() method to highlight those sections. You can build the SectionList manually if there are only a few sections in the path and they are easy to identify with the section browser that you can bring up with
NEURON Main Menu / Tools / Distributed Mechanisms / Viewers / Shape Name

Otherwise you may prefer to build the list algorithmically. You already know the name of the path's origin section (most proximal section) and terminal section (most distal section). For the sake of illustration, this bit of code assumes that the origin section is dendrite_1[8] and the terminal section is dendrite_1[13] (substitute with whatever you need):

Code: Select all

// start at termination and walk backward from child to parent until we reach origin
strdef origin
dendrite_1[8] origin = secname() // so we can tell when we have reached the origin of the path

objref this // the section to be checked to see if it is the origin
dendrite_1[13] this = new SectionRef()

objref path // will be the SectionList that contains the sections in the path

proc trace_to_origin() {
  path = new SectionList()
  this.sec path.append() // add termination to the list
  while (isorigin(this)!=1) { // if this is not the origin
    this = parsr(this) // go to the parent
    this.sec path.append() // and add parent to the list
  }
}

func isorigin() { local x  // return 1 if $o1.sec is the origin of the path
// $o1.sec print secname() // if you want to see it working
  $o1.sec x=issection(origin)
  return x
}

obfunc parsr() { localobj tobj // return SectionRef of parent of $o1.sec
  $o1.parent tobj = new SectionRef()
  return tobj
}

trace_to_origin()
forsec path print secname() // just to show that it worked

// now color the sections in path
objref ps
ps = new PlotShape()
ps.color_list(path,2) // make them red
Note that this code will fail if the path includes a section that does not have a true parent, i.e. if the section's parent_conection is equal to the parent's section_orientation (for more information see documentation of the SectionRef class's trueparent() method in the Programmer's Reference).
tine
Posts: 10
Joined: Thu Jan 13, 2011 2:18 pm

Re: Exporting rangeVar into .dat file

Post by tine »

Thanks a lot for the answers. Your answer to the second question was easy to implement and is working fine.

For the first question, saving the data in a big matrix, I still have some difficulties.

Code: Select all

objref savdata2,tempmatrix2

proc open_outputfile_RangeVar(){
    tempmatrix2=new Matrix()
    tempmatrix2.resize(disspacevect.size(),int(tstop/dt)+1)
    tempmatrix2.setcol(0,disspacevect)
}

proc close_outputfile_RangeVar(){
    savdata2=new File()
    savdata2.wopen("dataspaceplottest.dat")
    savdata2.printf("distance y\n")
    tempmatrix2.fprint(savdata2,"%-g")
    savdata2.close()
}

proc advance(){
  fadvance()
  rvp.to_vector(yspacevect,disspacevect)
  tempmatrix2.setcol(int(t/dt)+1,yspacevect)
}

proc run(){
  stdinit()
  open_outputfile_RangeVar()
  continuerun(tstop)
  //frecord.init() neccessary ??
  //cvode.re_init() neccessary??
  close_outputfile_RangeVar()
}

The matrix is formed with the right dimensions and put in the requested dat file without warnings, but is I open the dat file all the values are not seperated: -650-70 instead off -650 -70. Off course Matlab interpreted this as one big string in stead of individual numbers. Where is my wrong thinking? Can I ask Neuron to seperate the columns with a tab, semi-column or space?

Thanks a lot.
ted
Site Admin
Posts: 6300
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Exporting rangeVar into .dat file

Post by ted »

tine wrote:Your answer to the second question was easy to implement and is working fine.
A caveat: the method I presented requires that the path from origin to termination pass from parent to child for each section along the path.

Now that I re-examine the documentation of the RangeVarPlot class, I see something that would have saved some time and effort, and which works even if the path changes direction i.e. starts out by going from child to parent, before turning around and coming back down from parent to a different child: the list() method
http://www.neuron.yale.edu/neuron/stati ... .html#list
So if there is a range variable plot called rvp that originates in dendrite_1[8] and terminates in dendrite_1[13], it is enough to do

Code: Select all

objref path
path = new SectionList()
rvp.list(path)
and presto! the first element in path will refer to dendrite_1[8], the last element will refer to dendrite_1[13], and the other elements will refer, in proper sequence--from parent to child--to the sections that lie between dendrite_1[8] and dendrite_1[13]. Much cleaner than what I wrote in my previous post, which generated a SectionList in which the sequence was from child to parent.
For the first question, saving the data in a big matrix, I still have some difficulties.
and others are lurking; more about those later.
The matrix is formed with the right dimensions and put in the requested dat file without warnings, but is I open the dat file all the values are not seperated: -650-70 instead off -650 -70.
So change the format string. You'll find a brief discussion of options available in hoc here
http://www.neuron.yale.edu/neuron/stati ... tml#printf
but the fact that you asked about it suggests that you'll want to read more than what the Programmer's Reference provides. Any decent reference on C or C++ (of which there are probably several on line) should contain a more complete discussion of format strings with examples.

Now the difficulties to which I referred above.

Deferring actual file output until after completion of the run is OK as long as storage allows. However, if you're going to do that, you're probably better off taking advantage of the Vector class's record() method instead of using hoc statements to move data around at each fadvance(). Also, using int(t/dt) to calculate the column index is going to run into roundoff error at some point, with the result that you'll either skip columns, or overwrite columns that already contained data.

Here's how to avoid these problems.

After model setup but before calling run, set up Vector record at every internal node along the path of sections, starting with the most proximal section in your range variable plot and moving out to the most distal.

Code: Select all

objref path
path = new SectionList()
rvp.list(path)

objref veclist

proc buildveclist() { localobj tobj
  forsec path { // iterate over each section along the path
    for (x,0) { // iterate over each internal node in the current section
      tobj = new Vector()
      tobj.record(&v(x)) // or whatever other range variable you want to capture
      veclist.append(tobj)
    }
  }
}

buildveclist()
Now you have a set of Vectors that will capture the time course of v at each internal node along the path. You only need a custom run procedure, and a procedure that writes results to a file after the end of the run.

Code: Select all

proc run() {
  stdinit()
  continuerun(tstop)
  save_results()
}

proc save_results() { local i, j
  . . . open output file . . .
  // there are veclist.count() Vectors
  // the number of values in each Vector is veclist.o(0).size--
  // one value for each point in time at which a solution was computed
  for i=0,veclist.o(0).size-1 { // iterate over each point in time
    for j=0,veclist.count()-1 { // iterate over each point in space
      . . . print veclist.o(j).x[i] to the file . . .
    }
    . . . print \n to the file . . .
  }
  . . . close output file . . .
}
That's it. No tinkering with proc advance(). The only drawback is that printing one datum at a time via hoc is not as fast as printing a whole block of numbers at once. You could speed things up by assembling a Matrix out of the recorded Vectors, but that doubles storage requirements. My preference would be to write out one Vector at a time (each row corresponds to the entire time course at a particular point in space)

Code: Select all

  for i=0,veclist.count()-1 { // iterate over each point in space
    . . . use the Vector class's printf() method to print veclist.o(i) to the file . . .
    . . . print \n to the file . . .
  }
  . . . close output file . . .
Post Reply