How to make a function written in C available to hoc

Particularly useful chunks of hoc and/or NMODL code. May be pedestrian or stunningly brilliant, may make you gasp or bring tears to your eyes, but always makes you think "I wish I had written that; I'm sure going to steal it."
Post Reply
ted
Site Admin
Posts: 6287
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

How to make a function written in C available to hoc

Post by ted »

How can you make a function written in C available to hoc? Just put it in a mod file and compile the mod file. And if you declare
SUFFIX nothing
in the NEURON block of the mod file, none of the GUI menus will be changed--but the function will still be available to hoc.

For example, suppose you wanted to add cosh to hoc. cosh is part of the C library, so the mod file can be very simple.

Code: Select all

: dummy.mod
: Makes a function written in C available to hoc
NEURON {
  SUFFIX nothing
}
: call it gcosh to avoid naming conflicts
FUNCTION gcosh(z) {
  gcosh = cosh(z)
}
Compile this with mknrndll (or nrnivmodl for UNIX/Linux users), then test to confirm that it works.

Code: Select all

$ nrngui
 . . .
Additional mechanisms from files
 dummy.mod
oc>gcosh(2)
        3.7621957 
oc>(exp(2)+exp(-2))/2
        3.7621957 
oc>
So far so good, but a more convincing test would be to write a cosh function in hoc and then do a visual comparison against the results generated by gcosh() over a range of arguments.

The Grapher is a good tool for this kind of task. The following hoc file defines proc cosh(), then loads the ses file for a Grapher that is configured to plot cosh(x) and gcosh(x) over the range [-3,3].*

Code: Select all

load_file("nrngui.hoc")

func cosh() {
        return (exp($1) + exp(-$1))/2
}

load_file("grapher.ses")
Grapher[0].doplt()
And here's grapher.ses:

Code: Select all

load_file("grapher.hoc")}
{
ocbox_=new Grapher(1)

ocbox_.info("x","x", "", -3, 3, 0, 10, 100, -3, 3)
{
save_window_=ocbox_.g
save_window_.size(-3,3,0,10)
scene_vector_[2] = save_window_
ocbox_.g = save_window_
save_window_.save_name("ocbox_.g")
save_window_.xexpr("x", 0)
save_window_.addexpr("cosh(x)", 1, 3, 0.148243, 0.933506, 2)
save_window_.addexpr("gcosh(x)", 2, 1, 0.148243, 0.895213, 2)
}
ocbox_ = ocbox_.vbox
ocbox_.map("Grapher", 0, 105, 308.16, 437.76)
}
objref ocbox_
//End Grapher

objectvar scene_vector_[1]
{doNotify()}
*--To learn how to configure and use a Grapher, see http://www.neuron.yale.edu/neuron/stati ... apher.html
Post Reply