functions in NMODL

NMODL and the Channel Builder.
Post Reply
neuromau
Posts: 97
Joined: Mon Apr 20, 2009 7:02 pm

functions in NMODL

Post by neuromau »

Hello, I want to make a function in NMODL that I can call from NMODL and hoc. I tried something, but it gives me an odd result when I call it from NMODL. I suspect I'm mixing up ints and doubles somehow, but I'm not sure what to do.

First I made an NMODL function that is callable from hoc:

Code: Select all

NEURON {
  SUFFIX nothing
}

FUNCTION get_x_pos1(binSizeX) {
	get_x_pos1 =  binSizeX/2.0
}
Then I wrote some other NMODL code to install as a vector method (and also included a second definition of my function of interest for comparison):

Code: Select all

VERBATIM
# include <stdlib.h>
# include <stdio.h>
# include <math.h>
ENDVERBATIM

NEURON {
	SUFFIX nothing
}

VERBATIM
extern double* vector_vec();
extern int vector_capacity();
extern void* vector_arg();
ENDVERBATIM

VERBATIM

static double get_x_pos2 (double binSizeX) {
	double pos;
	pos =  binSizeX/2.0;
	return pos;
}

static double testconn (void* vv) {
  double finalconn, ny,  *x, *y;

	/* Get hoc vectors into c arrays */
	finalconn = vector_instance_px(vv, &x); // x is an array corresponding
											// to the placeholder vector
											// of connections to make

	ny = vector_arg_px(1, &y);
	
	/* Parameters from the param array
	y[0] binSizeX 
	*/

	x [0] = get_x_pos1(y[0]);
	x [1] = get_x_pos2(y[0]);
	return finalconn;

}
ENDVERBATIM

PROCEDURE install_testconn () {
	VERBATIM
	install_vector_method("testconn", testconn);
	ENDVERBATIM
}
Then in hoc, I compared the output of my function of interest called from hoc, to my function of interest and the comparison function called from NMODL:

Code: Select all

load_file("nrngui.hoc")

install_testconn()

binSizeX = 10.00

print "from hoc, use function of interest: ", get_x_pos1(binSizeX)

objref mypos, params

mypos = new Vector(2)

params = new Vector(1)
params.x[0] = binSizeX

mypos.testconn(params)

print "from NMODL, use function of interest: ", mypos.x[0], ", use comparison: ", mypos.x[1]

quit()
Calling the function of interest from hoc is fine, and calling the comparison function from NMODL is fine, but calling the function of interest from NMODL gives a different result:
from hoc, use function of interest: 5
from NMODL, use function of interest: 1.0761011e+09 , use comparison: 5
Not sure how to fix my "function of interest" definition so it works in NMODL? Note that "binSizeX" is an integer in this example but that may not be the case in my working code. Thanks!
hines
Site Admin
Posts: 1607
Joined: Wed May 18, 2005 3:32 pm

Re: functions in NMODL

Post by hines »

In compiling your mod file referencing get_x _pos, I see

Code: Select all

vec.c:172:12: warning: implicit declaration of function 'get_x_pos1' is invalid
      in C99 [-Wimplicit-function-declaration]
   x [0] = get_x_pos1(y[0]);           ^
So the problem is that get_x_pos was not declared and so treated as though it returns an integer instead of a double. In your first VERBATIM block you need the statement

Code: Select all

  extern double get_x_pos(double x);
neuromau
Posts: 97
Joined: Mon Apr 20, 2009 7:02 pm

Re: functions in NMODL

Post by neuromau »

Great, thanks Michael!

For some reason my mknrndll output did not report anything like
warning: implicit declaration of function 'get_x_pos1' is invalid
in C99 [-Wimplicit-function-declaration]
.

I made the update and now both functions are returning the same number in NMODL. Just for others' reference, my updated NMODL vector method code now says:

Code: Select all

    VERBATIM
    # include <stdlib.h>
    # include <stdio.h>
    # include <math.h>
    ENDVERBATIM

    NEURON {
       SUFFIX nothing
    }

    VERBATIM
    extern double* vector_vec();
    extern int vector_capacity();
    extern void* vector_arg();
    extern double get_x_pos1(double x);
    ENDVERBATIM

    VERBATIM

    static double get_x_pos2 (double binSizeX) {
       double pos;
       pos =  binSizeX/2.0;
       return pos;
    }

    static double testconn (void* vv) {
      double finalconn, ny,  *x, *y;

       /* Get hoc vectors into c arrays */
       finalconn = vector_instance_px(vv, &x); // x is an array corresponding
                                     // to the placeholder vector
                                     // of connections to make

       ny = vector_arg_px(1, &y);
       
       /* Parameters from the param array
       y[0] binSizeX
       */

       x [0] = get_x_pos1(y[0]);
       x [1] = get_x_pos2(y[0]);
       return finalconn;

    }
    ENDVERBATIM

    PROCEDURE install_testconn () {
       VERBATIM
       install_vector_method("testconn", testconn);
       ENDVERBATIM
    }
hines
Site Admin
Posts: 1607
Joined: Wed May 18, 2005 3:32 pm

Re: functions in NMODL

Post by hines »

Different compilers have different warnings set. I was using clang on Mavericks. Also the 1078 version of NEURON on
http://www.neuron.yale.edu/ftp/neuron/versions/alpha/
which replaces a lot of the old K&R code with ANSI-C so as to eliminate most warnings.
Post Reply