You can assign your data to a numpy array, get a pointer to the numpy array using neuron.numpy_element_ref, send that pointer to all point processes (this is fast... there's no copying of data), and then have the point process read from the array using a single VERBATIM line.
Our driving Python program:
Code: Select all
import numpy
from neuron import h, numpy_element_ref
soma = h.Section(name='soma')
dend = h.Section(name='dend')
pps = [h.ARRAY_TEST(seg) for seg in [soma(0.5), dend(0.5)]]
# generate 200 data points
data = numpy.random.random(200)
# grab the pointer to the data
ptr = numpy_element_ref(data, 0)
# tell each pp about the pointer
for pp in pps:
pp._ref_foo = ptr
soma(0.5).v = 14
dend(0.5).v = -43
# have the point process do its thing
h.fadvance()
# for each point process, print the segment, the value calculated, and the value
# if we do the lookup ourselves
for pp in pps:
print(pp.get_segment(), pp.val, data[int(pp.get_segment().v) + 100])
The MOD file it uses:
Code: Select all
NEURON {
POINT_PROCESS ARRAY_TEST
POINTER foo
RANGE val
}
UNITS {
(mV) = (millivolt)
}
ASSIGNED {
v (mV)
foo
val (1)
}
BREAKPOINT {
VERBATIM
val = _p_foo[(int) _v + 100];
ENDVERBATIM
}
You can put the VERBATIM block wherever you need to do the lookup. The main thing to know about that line is that if the POINTER variable is called foo, then inside the VERBATIM block, the C pointer is called _p_foo. Likewise regular (non-pointer) variables get prefixed with an _, hence voltage becomes _v. Here I'm casting voltage to an int simply so that the array lookup has an integer offset.
Running the code shows matching values from NEURON doing the lookups and from Python doing the lookups:
Code: Select all
soma(0.5) 0.28198634180594195 0.28198634180594195
dend(0.5) 0.47065239091128874 0.47065239091128874
(The data is random, so your values may vary.)