Accessing External libraries though include or exec()
Accessing External libraries though include or exec()
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.
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.
-
- Site Admin
- Posts: 6305
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: Accessing External libraries though include or exec()
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
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()
Thanks, I didn't see anything about VERBATIM in the docs but it works great.
-
- Site Admin
- Posts: 6305
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: Accessing External libraries though include or exec()
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:
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:
This feature allows NEURON to be used as a (very) "poor man's C development environment."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.
Re: Accessing External libraries though include or exec()
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?
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()
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
bar.mod
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)
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()
I'm having some trouble passing a vector instead of a scalar.
foo.hoc
testv.mod
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.
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]
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
}
Re: Accessing External libraries though include or exec()
A good example of casting pointers in a mod file is in nrn/src/nrnoc/pattern.mod
The relevant idioms are
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()
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
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.
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
*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.
-
- Site Admin
- Posts: 6305
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: Accessing External libraries though include or exec()
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:
Here's vecevent.mod. Note how PROCEDURE play references the elements of evec.
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
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
}