Page 1 of 1

Record and fadvance instead of run

Posted: Wed Dec 30, 2020 2:41 pm
by fkolbl
Hi,

I try to run a simulation step by step, using 'fadvance()' with a loop instead of 'run()'. Here is a minimal code of what I am trying to do :

Code: Select all

import neuron
from neuron import h
h.load_file('stdrun.hoc')
import numpy as np

v_init = -65

axon1 = h.Section(name='U_axon')
axon1.L = 5000
axon1.diam = 1
axon1.nseg = 100
axon1.insert('pas')
axon1.insert('hh')
	
h.define_shape()

h.tstop = 2
h.celsius = 33       	
h.finitialize(v_init)  
h.v_init=v_init
h.dt = 0.001
h.fcurrent()

timeVector = h.Vector()
timeVector.record(h._ref_t)
#neuron.h.run()
while h.t < h.tstop:
	h.fadvance()
t = np.array(timeVector)
print(t)


by the end of the example there is nothing recorded in the variable 't', it is an empty numpy array...if I comment the while and the content of the loop to replace it with the 'run', I get the correct time vector... What did I miss so that the steps (and all possible other variables) are not stored by using fadvance ?

I thank you in advance for your time and consideration.
all the best

Re: Record and fadvance instead of run

Posted: Wed Dec 30, 2020 5:24 pm
by ramcdougal
Vectors must be initialized after calling record before advancing. Your other code works with h.run() because a run is basically an h.finitialize(h.v_init) combined with an h.continuerun(h.tstop).

The solution is to declare your timeVector before the h.finitialize call, i.e. something like:

Code: Select all

timeVector = h.Vector()
timeVector.record(h._ref_t)
h.finitialize(v_init)
# ...
while h.t < h.tstop:
    h.fadvance()
A few other suggestions:
  • You probably don't need to do each individual h.fadvance() separately. As written, your while loop is equivalent to h.continuerun(h.tstop).
  • Also, note that every vector has a .as_numpy() method which returns a numpy array mapping to the same memory (so changes to one are seen in the other). If you need a copy, do what you're doing, but you almost never need a copy (and, honestly, Vector objects mostly just work where a numpy array would work, especially in 7.7+).
  • It's better to use an odd value for nseg, if for no other reason than because it makes the center segment axon(0.5) unambiguous.
  • Consider using e.g. from neuron.units import mV, ms, um and using those values to make the meaning of the numbers clearer (e.g. h.tstop = 2 * ms, v_init = -65 * mV, axon1.L = 5000 * um)
  • Assuming you're running 7.7+, you can combine the record and declaration onto one line: timeVector = h.Vector().record(h._ref_t)

Re: Record and fadvance instead of run

Posted: Thu Dec 31, 2020 11:23 am
by fkolbl
Hello,
thank you very much for your fast and clear answer, all the comment on the code that will be really helpful. It seems to me that h.continuerun() is what I will use. I am avoiding run since I add an extracellular potential which has a relatively high frequency and when using play I have to compute a large array which fills the RAM for almost nothing... basically I will make a loop with a time of run of the stimulus sampling frequency. I was initially inspired by a code in hoc doing almost the same with fadvance on modelDB.

all the best and again thank you !