Page 1 of 1
Accessing External libraries though include or exec()
Posted: Wed May 12, 2010 2:09 pm
by aluchko
I was looking for a way I could access external code from a hoc file.
One option would be some kind of interface whereby I could include a C or other kind of library than call those functions through some kind of wrapper.
Another option would be something similar to an exec() whereby I could wrap my external library in a small program than send data back and forth through a pipe.
Unfortunately I haven't been able to find anything in the docs.
If there's no other option I could re-build neuron with the functions built in, or just write a program that drove its own instance of neuron, but I'd rather use one of the two approaches above.
Re: Accessing External libraries though include or exec()
Posted: Thu May 13, 2010 12:56 pm
by ted
The way to make external libraries available to hoc is by using a VERBATIM block in an NMODL file to add a new function to hoc. Take a look at the following threads and then tell me if you need further information.
Adding C code in a model file
http://www.neuron.yale.edu/phpBB/viewto ... =16&t=1194
How to access C function (random, srandom..) in NMODL files?
http://www.neuron.yale.edu/phpBB/viewto ... f=16&t=292
Re: Accessing External libraries though include or exec()
Posted: Fri May 14, 2010 11:43 pm
by aluchko
Thanks, I didn't see anything about VERBATIM in the docs but it works great.
Re: Accessing External libraries though include or exec()
Posted: Sat May 15, 2010 11:33 am
by ted
Here's what I do when I'm looking for a particular topic or keyword but can't find it in the alphabetical index to the Programmer's Reference and don't know where to look in the "usual tutorials and other documentation"--
go to NEURON's WWW page
http://www.neuron.yale.edu/ and do a Google search.
In the case of the word VERBATIM, searching for
VERBATIM -php
returns a bunch of hits, the second of which is to the Programmer's Reference page about NMODL. (the -php blocks out a bunch of stuff in the Forum)
http://www.neuron.yale.edu/neuron/stati ... nmodl.html
Buried in that page, near the very end, in the discussion of INITIAL, is this sentence:
Since NMODL produces a c file, it is possible for the highly motivated to modify that file in order to do something implementation dependent. In this regard, the VERBATIM block can be used to place c code within the model description file.
This feature allows NEURON to be used as a (very) "poor man's C development environment."
Re: Accessing External libraries though include or exec()
Posted: Thu May 20, 2010 1:13 am
by aluchko
So I can write the C code I need in a mod, and I can call these C functions from a hoc.
But I then need to have that C code call a function I defined in a hoc file and I'm not sure how to do this.
Is there a way to call hoc functions from a MODL file?
Re: Accessing External libraries though include or exec()
Posted: Thu May 20, 2010 3:33 pm
by hines
Here is a small example you can modify by analogy. See nrn/src/ivoc/oc2iv.h for a list of useful
functions prototypes that deal with the interpreter.
I left out error checking in the example.
foo.hoc
Code: Select all
func foo() {
return $1*$1
}
print bar(5)
print bar(10)
bar.mod
Code: Select all
NEURON { SUFFIX nothing }
VERBATIM
extern hoc_pushx(double);
extern double hoc_call_func(Symbol* sym, int narg);
extern Symbol* hoc_lookup(const char*);
ENDVERBATIM
FUNCTION bar(arg) {
VERBATIM {
Symbol* s = hoc_lookup("foo");
hoc_pushx(_larg);
_lbar = hoc_call_func(s, 1);
}
ENDVERBATIM
}
Re: Accessing External libraries though include or exec()
Posted: Tue May 25, 2010 5:20 pm
by aluchko
I'm having some trouble passing a vector instead of a scalar.
foo.hoc
Code: Select all
func blah() {localobj lvec
printf("args %g\n", numarg())
print argtype(1)
lvec=$o1
return 1
}
objref vec
vec=new Vector(1)
vec.x[0]=1
testv(vec)
print vec.x[0]
testv.mod
Code: Select all
NEURON {
POINTER vecP
SUFFIX nothing
}
PARAMETER {
vecP=0
}
VERBATIM
extern int vector_capacity(void* vv);
extern void* vector_arg(int iarg);
extern hoc_pushobj(Object**);
extern hoc_push_object(Object*);
extern hoc_pushx(double);
extern double hoc_call_func(Symbol* sym, int narg);
extern Symbol* hoc_lookup(const char*);
ENDVERBATIM
PROCEDURE testv() {
VERBATIM
void** vv = (void**)_p_vecP;
// void ** vv = vector_arg(1);
int size = vector_capacity(vv);
printf("setVec.size=%d\n",size);
vv[0]=3;
Symbol* s = hoc_lookup("blah");
// hoc_pushobj(vv);
hoc_push_object(&vv);
hoc_call_func(s,1);
ENDVERBATIM
}
I'm able to access the Vect fine in testv(), but when I than try to access the object in blah() I get a segmentation fault. Ideally I'd like to be able to return a Vector from testv though the docs seem to indicate that only a double is possible (
http://www.neuron.yale.edu/neuron/stati ... l#Function), however I could work around this latter limitation.
Re: Accessing External libraries though include or exec()
Posted: Wed May 26, 2010 8:58 pm
by hines
A good example of casting pointers in a mod file is in nrn/src/nrnoc/pattern.mod
The relevant idioms are
Code: Select all
POINTER ptr
...
VERBATIM
#define VCAST void** vp = (void**)(&(_p_ptr))
...
PROCEDURE foo() {
VERBATIM
VCAST; void* vec = *vp;
vec = vector_arg(1);
...
Re: Accessing External libraries though include or exec()
Posted: Thu May 27, 2010 2:53 pm
by aluchko
hines, thanks for the pointer though I'm not sure what I'm supposed to be looking at in pattern.mod. I'm already able to cast the incoming argument to a vector, the problem is when I then try to pass the resulting Vector back to the hoc function blah() I get a segfault when I try to use the Vector in blah.
I tried modifying testv() to be more in line with the code you suggested but with no improvement
Code: Select all
PROCEDURE testv() {
VERBATIM
VCAST; void* vec = *vp;
vec = vector_arg(1);
Symbol* s = hoc_lookup("blah");
printf("vec is %i, vp is %i\n",vec,vp);
hoc_push_object(vp);
hoc_call_func(s,1);
ENDVERBATIM
One thing I don't quite understand is the use of void* vec= *vp.
*vp ends up being null in my code, though it looks like it could get set through things like _hoc_setdata. Either way I don't see the point in assigning vec = *vp only to reassign vec to vector_arg(1) in the very next line.
Re: Accessing External libraries though include or exec()
Posted: Thu May 27, 2010 3:41 pm
by ted
The associated hoc code would help. Here's another example that might be useful:
nrn/examples/nrniv/netcon contains vecevent.hoc, vecevent.ses, and vecevent.mod
vecevent.ses is a session file that recreates a model constructed with the Network Builder. This model consists of a single instance of the VecStim class. The VecStim class is a class of artificial spiking cell whose spike times are specified by the elements in a Vector.
vecevent.hoc illustrates the usage of a VecStim object; here's the file with my comments:
Code: Select all
load_file("nrngui.hoc")
load_file("vecevent.ses") // the VecStim object will be called vs_VecStim[0]
objref evec
evec = new Vector(100) // will hold times at which the VecStim should generate an event
evec.indgen // evec's elements are now 0, 1 . . . 99
vs_VecStim[0].pp.play(evec) // the VecStim object generates events at t = 0, 1 . . . 99 ms
Here's vecevent.mod. Note how PROCEDURE play references the elements of evec.
Code: Select all
: Vector stream of events
NEURON {
ARTIFICIAL_CELL VecStim
}
ASSIGNED {
index
etime (ms)
space
}
INITIAL {
index = 0
element()
if (index > 0) {
net_send(etime - t, 1)
}
}
NET_RECEIVE (w) {
if (flag == 1) {
net_event(t)
element()
if (index > 0) {
net_send(etime - t, 1)
}
}
}
VERBATIM
extern double* vector_vec();
extern int vector_capacity();
extern void* vector_arg();
ENDVERBATIM
PROCEDURE element() {
VERBATIM
{ void* vv; int i, size; double* px;
i = (int)index;
if (i >= 0) {
vv = *((void**)(&space));
if (vv) {
size = vector_capacity(vv);
px = vector_vec(vv);
if (i < size) {
etime = px[i];
index += 1.;
}else{
index = -1.;
}
}else{
index = -1.;
}
}
}
ENDVERBATIM
}
PROCEDURE play() {
VERBATIM
void** vv;
vv = (void**)(&space);
*vv = (void*)0;
if (ifarg(1)) {
*vv = vector_arg(1);
}
ENDVERBATIM
}