saving vectors to file

NMODL and the Channel Builder.
Post Reply
fabien tell
Posts: 49
Joined: Mon Mar 25, 2013 1:36 pm
Location: france
Contact:

saving vectors to file

Post by fabien tell »

Hello,

I need to automatically (through a Gui) save results of simulation. In this case, I need to save as a text file , a vector which is teh second derivative of an action potential against the time.

I wrote this code which is launched after a compete run :

Code: Select all

// create objects to put Vectors : "spike": time course of v at soma, "deriv_1" : i-cap at the soma (first derivative of v)

objref icvec, d2, tvec, g2, fdv2
icvec = new Vector()
soma icvec.record(&i_cap(0.5)) // filling the object "icvec" with i_cap at the soma (0.5)  you may change
                                                //   it to get i-cap where you like
                                              // d2 will contain derivative of i_cap, g2 will plot that vs.time
d2 = new Vector()
tvec= new Vector()
fdv2= new File()                   // File to save vectors

tvec.record(&t) // I record the time 



proc postprocess() { // creation of a procedure called postprocess that calculate the dev of icvec and fill a file 


d2.deriv(icvec, dt) 
g2 = new Graph(0)
  d2.plot(g2, dt) // plot of d2 vs t
  g2.size(-0.5,0.5,-15,15)
  g2.view(-0.5, -15, 1, 30, 648, 296, 400.48, 300.32)
   g2.label(0.05, 0.9, "x: t", 2, 1, 0, 0, 2)
  g2.label(0.05, 0.75, "y: deriv_2", 2, 1, 0, 0, 3)
 g2.exec_menu("View = plot") // to autoscale the graph

fdv2.wopen("dv2.csv") // a file called dv2.csv will be created 
tvec.printf(fdv2)
d2.printf(fdv2) // actually I want a file with two columns: the time and the dv2 
fdv2.close()

}

//create a panel for launching analysis

{xpanel("analyse",1)
xbutton("analyze and save dV2 ", "postprocess()")
xpanel()

}
Actually, it works but I only get one column in the file which is the second derivative (d2) and I do not have the time (tvec). I understand from my code that I overwrite tvec with d2 but I do not know how to write both in the same file on two columns.

Thanks a lot

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

Re: saving vectors to file

Post by ted »

There are actually three problems. The first one is what you observed--if you use Vector.printf to print the contents of one vector to a file, then try to print the contents of a different vector to that same file, when all is finished the file will contain only the contents of the last vector that was printed. You could fix this problem by using the File class's printf method to print your two vectors to the file. Assuming that fil is an objref that points to an instance of the File class that you have opened for writing, you'll want something like this loop
for i=0,tvec.size()-1 fil.printf("%f\t %f\n",tvec.x, d2.x)

2/24/2017 Oops--this next statement is wrong, and consequently there is no need to omit printing of the tail end of both the time vector and d2. It turns out that by default, Vector deriv uses the central difference method, so the d2 vector will be exactly the same size as the original data vector. Sorry about this mistake, but the official documentation of Vector deriv didn't say what the default was, and I just assumed it would be the simplest, which is Euler. Will have this fixed in the documentation. --Ted
The second problem is that the way you are calling Vector.deriv will generate a d2 vector that is one element shorter than icvec, and consequently is also one element shorter than tvec. Forget about why for the moment (it's explained in the Programmer's Reference entry about the Vector class's deriv method)--just realize that, if your icvec contains N elements, you'll have only N-1 derivative values. This means that a simple loop like

Code: Select all

for i=0,tvec.size()-1 fil.printf("%f\t %f\n",tvec.x[i], d2.x[i])
is going to generate a run time error because tvec has more elements than d2 does.

What can you do about that? It's up to you. You could change the loop to

Code: Select all

for i=0,tvec.size()-2 fil.printf("%f\t %f\n",tvec.x[i], d2.x[i])
(notice the 2 in tvec.size()-2. Or you could use the central difference method to calculate the derivative, and the problem will vanish. The calculated derivative will also be more accurate, but, as the Programmer's Method notes, differentiation of a vector by the central difference method produces a result that cannot be integrated to reproduce the original vector.

The third problem is that your output file will not be a .csv file because the numerical values will not be separated by commas. That's easy to fix: add them to File.printf's format string.
fabien tell
Posts: 49
Joined: Mon Mar 25, 2013 1:36 pm
Location: france
Contact:

Re: saving vectors to file

Post by fabien tell »

Dear Ted,

Thanks a lot for you prompt answer. If I understand well, I could use the same procedure to fill a file with three or more vectors assuming that I take into account the length problem you mentioned. For example, I could record in the same file the time, the action potential v trace , its first and second derivative.

Something like this

Code: Select all

for i=0,tvec.size()-2 fil.printf("%f\t %f\n",tvec.x[i], icvec.x[i], d2.x[i])
should I add something like %f\?
ted wrote:The third problem is that your output file will not be a .csv file because the numerical values will not be separated by commas. That's easy to fix: add them to File.printf's format string.
Yes , I noticed that but it is because my spreadsheet program does'nt easily open *.dat files.

Thanks a lot

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

Re: saving vectors to file

Post by ted »

The Programmer's Reference documentation of the File class's printf method
https://www.neuron.yale.edu/neuron/stat ... rintf.html
contains more details and an example. hoc's printf is based closely on the C language's printf, so you'll find more examples in any good reference to the C standard library (there must be at least one or two online).

You might not have to insert commas. Many spreadsheet programs are rather stupid about file name extensions, but often they have very flexible tools for importing data which may even be smart enough to treat whitespace as a "field delimiter" (separator between adjacent numerical values on the same line).
fabien tell
Posts: 49
Joined: Mon Mar 25, 2013 1:36 pm
Location: france
Contact:

Re: saving vectors to file

Post by fabien tell »

Thanks you Ted,

I managed to make it work. Th only minor problem I have is that I have to launch the simulation with init and run button, otherwise the file is empty.For example, I used to reinitialize the number of segments every time I altered geometry with a basic procedure

Code: Select all

proc geom_nseg() {
  forsec all { nseg = int((L/(0.01*lambda_f(100))+.999)/2)*2 + 1  }
I called it after every geometrical changes with :

Code: Select all

proc update_seg() { // a procedure that launch geom-nseg and run the simulation 
geom_nseg()

}

// create a panel to launch update _seg 
{xpanel("update seg",1)
xbutton("update seg", "update_seg()")
xpanel()
}
In my first version I had added run() just after :

Code: Select all

proc update_seg() { // a procedure that launch geom-nseg and run the simulation 
geom_nseg()

run()
}
So every time I recalculated the number of segment, the simulation was launched but in this case if I ran the postprocess procedure, the file was empty. I just suppressed the run () command in the updata_seg procedure and started the simulation with the init and run button. I t works while it is not very elegant. I s there a command to activate directly init and run form a procedure?


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

Re: saving vectors to file

Post by ted »

fabien tell wrote:I managed to make it work. Th only minor problem I have is that I have to launch the simulation with init and run button, otherwise the file is empty. For example, I used to reinitialize the number of segments every time I altered geometry with a basic procedure

Code: Select all

proc geom_nseg() {
  forsec all { nseg = int((L/(0.01*lambda_f(100))+.999)/2)*2 + 1  }
I called it after every geometrical changes with :

Code: Select all

proc update_seg() { // a procedure that launch geom-nseg and run the simulation 
geom_nseg()
Changing a section's nseg may destroy existing nodes and create new ones. That will break vector recording of range variables from the nodes that no longer exist, and of course nothing will be recorded from the new nodes that have been created. If you change a section's nseg, the safest policy is to discard the Vectors that recorded from it, then create new ones and set up whatever vector recording you need.
In my first version I had added run() just after :

Code: Select all

proc update_seg() { // a procedure that launch geom-nseg and run the simulation 
geom_nseg()

run()
}
So every time I recalculated the number of segment, the simulation was launched but in this case if I ran the postprocess procedure, the file was empty. I just suppressed the run () command in the updata_seg procedure and started the simulation with the init and run button. I t works while it is not very elegant. I s there a command to activate directly init and run form a procedure?
Yes. It is called run(). Unless, of course, the button labeled Init & Run does something other than call run(). Save the panel that contains the Init & Run button to a .ses file, then examine the .ses file to discover what clicking on that button will do. You should find this statement:
xbutton("Init & Run","run()")
Read the Programmer's Reference documentation about xbutton and you'll see that the first argument is the label that appears on the button, and the second argument is the statement that will be executed when you click on the button. If instead you find out that the second argument is something else, then that something else is what you have to call.
fabien tell
Posts: 49
Joined: Mon Mar 25, 2013 1:36 pm
Location: france
Contact:

Re: saving vectors to file

Post by fabien tell »

Thanks again Ted,

That's what I thought for the init and run button.

You wrote
Changing a section's nseg may destroy existing nodes and create new ones. That will break vector recording of range variables from the nodes that no longer exist, and of course nothing will be recorded from the new nodes that have been created. If you change a section's nseg, the safest policy is to discard the Vectors that recorded from it, then create new ones and set up whatever vector recording you need.
However, it works if after changing a section's nseg , I run the simulation with "init and run" but not
if I run it with the run() command embedded in the update_seg() procedure.
That's why I was surprised.

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

Re: saving vectors to file

Post by ted »

To say anything more about this, I'd have to be able to reproduce the problem myself.
If you zip up just the files that are needed to run your program and email them to
ted dot carnevale at yale dot edu
I'll try to find out what's going wrong and how to fix it.
Post Reply