C API

Initialization

int nrn_init(int argc, const char **argv)

Initialize the NEURON environment. This function must be called before using any other NEURON API functions. The initialization sets up the NEURON interpreter and internal data structures.

Parameters:
  • argc – Argument count (should be at least 1, the name of the program)

  • argv – Argument vector (length should be one longer than argc and end with nullptr).

Returns:

0 on success, non-zero on failure.

Usage Pattern:

This function is called at the beginning of a NEURON session. The arguments are passed to the NEURON simulator as if it was launched with that argv. The first argument is typically the program name (e.g., “NEURON”). Some error messages may include the program name.

Example:

static std::array<const char*, 4> argv = {"NEURON", "-nogui", "-nopython", nullptr};

if (nrn_init(3, argv.data()) != 0) {
    // handle initialization error
}
void nrn_stdout_redirect(int (*myprint)(int, char*))

Redirect NEURON’s stdout to a custom print function. This allows capturing NEURON’s output and redirecting it to alternative destinations (e.g., Jupyter notebook or MATLAB command window).

Parameters:
  • myprint – Function pointer for custom printing. The function should accept two parameters: stream (1 for stdout, other values for stderr) and the message string.

Example:

int my_print_func(int stream, char* msg) {
    if (stream == 1) {
        printf("[STDOUT] %s", msg);
    } else {
        printf("[STDERR] %s", msg);
    }
    return 0;
}

nrn_stdout_redirect(my_print_func);

Sections

Section *nrn_section_new(const char *name)

Create a new Section with the given name. Sections are the fundamental building blocks of NEURON morphologies, representing cable segments of neurons. HOC functions can see the Section name but they cannot be referred to directly in HOC like a Section created in HOC (i.e., they do not occupy the HOC namespace). The returned Section pointer is used in subsequent operations to reference the Section.

Parameters:
  • name – Name of the new Section (must be unique within the model).

Returns:

Pointer to the newly created Section object.

C Usage:

Section* soma = nrn_section_new("soma");
Section* dendrite = nrn_section_new("dendrite");

Python Equivalent:

from neuron import n
soma = n.Section('soma')
dendrite = n.Section('dendrite')
void nrn_section_connect(Section *child_sec, double child_x, Section *parent_sec, double parent_x)

Connect a child Section to a parent Section at specified locations. This defines the topological structure of the neuron. Typically, dendrites and axons are connected to the soma, and further branches are connected to primary dendrites. That is, the 0 end of the child is usually connected to the 1 end of the parent.

Parameters:
  • child_sec – Pointer to the child Section to be connected.

  • child_x – Connection point on child Section (must be either 0 or 1, but typically 0).

  • parent_sec – Pointer to the parent Section.

  • parent_x – Connection point on parent Section (any value between 0 and 1, but typically 1).

C Usage:

// Connect beginning of dendrite to end of soma
nrn_section_connect(dendrite, 0.0, soma, 1.0);

Python Equivalent:

# Connect beginning of dendrite to end of soma
dendrite.connect(soma(1))
void nrn_section_length_set(Section *sec, double length)

Set the length of a Section in microns.

Parameters:
  • sec – Pointer to the Section.

  • length – Length in microns.

C Usage:

nrn_section_length_set(soma, 20.0);    // Set soma length to 20 μm
nrn_section_length_set(dendrite, 100.0); // Set dendrite length to 100 μm

Python Equivalent:

soma.L = 20    # Set soma length to 20 μm
dendrite.L = 100   # Set dendrite length to 100 μm
double nrn_section_length_get(Section *sec)

Get the length of a Section in microns.

Parameters:
  • sec – Pointer to the Section.

Returns:

Length of the Section in microns.

C Usage:

double length = nrn_section_length_get(soma);

Python Equivalent:

length = soma.L  # Get soma length
double nrn_section_Ra_get(Section *sec)

Get the axial resistance (Ra) of a Section in ohm⋅cm. Ra represents the resistance of the cytoplasm along the length of the Section. Lower values indicate better electrical connectivity.

Parameters:
  • sec – Pointer to the Section.

Returns:

Axial resistance in ohm⋅cm.

C Usage:

double Ra = nrn_section_Ra_get(soma);

Note

Ra and rallbranch are Section level properties; they are not range variables and do not vary within a Section.

void nrn_section_Ra_set(Section *sec, double val)

Set the axial resistance (Ra) of a Section in ohm⋅cm.

Parameters:
  • sec – Pointer to the Section.

  • val – Axial resistance value in ohm⋅cm.

C Usage:

nrn_section_Ra_set(soma, 100.0);  // Set axial resistance to 100 ohm⋅cm

Python Equivalent:

soma.Ra = 100  # Set axial resistance to 100 ohm⋅cm
double nrn_section_rallbranch_get(const Section *sec)

Get the Rallbranch value of a Section. This is used in models with branching corrections.

Parameters:
  • sec – Pointer to the Section.

Returns:

Rallbranch value.

Note

Ra and rallbranch are Section level properties; they are not range variables and do not vary within a Section.

void nrn_section_rallbranch_set(Section *sec, double val)

Set the Rallbranch value of a Section.

Parameters:
  • sec – Pointer to the Section.

  • val – Rallbranch value to set.

char const *nrn_secname(Section *sec)

Get the name of a Section.

Parameters:
  • sec – Pointer to the Section.

Returns:

Null-terminated string containing the Section name.

Usage Pattern:

Used for debugging, logging, or displaying Section information. Inside of a loop, this is sometimes used to identify the Section category (e.g., does the Section name start with dend? If so, maybe we have a special rule for how to handle dendrites), but that effect could also be obtained by using a SectionList.

Once a Section has been created, its name cannot be changed.

C Usage:

const char* name = nrn_secname(soma);

Python Equivalent:

name = str(soma)
void nrn_section_push(Section *sec)

Push a Section onto the Section stack, making it the currently accessed Section. Many NEURON operations work on the currently accessed Section.

Parameters:
  • sec – Pointer to the Section to push.

Usage Pattern:

Used when you need to perform operations that require a Section to be “currently accessed.” Always pair with nrn_section_pop() to restore the previous state.

A call to a NEURON function from Python with a sec= effectively pushes the Section, runs the function, and then pops the Section.

C Usage:

nrn_section_push(soma);           // Make soma current
// Perform operations on the soma
nrn_section_pop();                // Restore previous Section
void nrn_section_pop(void)

Pop the top Section from the Section stack, restoring the previously accessed Section.

Usage Pattern:

Always used after nrn_section_push() to restore the Section stack state.

void nrn_mechanism_insert(Section *sec, const Symbol *mechanism)

Insert a density mechanism into a Section.

Parameters:
  • sec – Pointer to the target Section.

  • mechanism – Symbol representing the mechanism to insert.

Usage Pattern: Used to add biophysical properties to Sections. Density mechanisms are present at all locations within the Section, but their properties (when specified as RANGE) may vary within the Section. Built-in mechanisms include ‘pas’ (passive) and ‘hh’ (Hodgkin-Huxley). Others are available from many sources, including ModelDB and Channelpedia.

C Usage:

Symbol* pas_symbol = nrn_symbol("pas");
nrn_mechanism_insert(soma, pas_symbol);  // Insert passive mechanism

Symbol* hh_symbol = nrn_symbol("hh");
nrn_mechanism_insert(soma, hh_symbol);   // Insert Hodgkin-Huxley mechanism

Python Equivalent:

soma.insert('pas')  # Insert passive mechanism; or alternatively soma.insert(n.pas)
soma.insert('hh')   # Insert Hodgkin-Huxley mechanism

See also

nrn_symbol()

nrn_Item *nrn_allsec(void)

Get all Sections in the current model.

Returns:

Pointer to a nrn_Item containing the list of all Sections.

Usage Pattern:

Used with nrn_sectionlist_iterator_new() to iterate over all Sections in the model, often for applying operations globally or for analysis purposes. This is equivalent to using n.allsec() in Python and shares the same caveats. In particular, future versions of the model may introduce new Sections whose properties would be different, so consider using specifically chosen SectionLists instead of looping over all Sections.

C Usage:

nrn_Item* all_sections = nrn_allsec();
// Use iterator to process all sections
SectionListIterator* iter = nrn_sectionlist_iterator_new(all_sections);
while (!nrn_sectionlist_iterator_done(iter)) {
    Section* sec = nrn_sectionlist_iterator_next(iter);
    // Process Section
}
nrn_sectionlist_iterator_free(iter);

Python Equivalent:

for sec in n.allsec():
    # Process Section
    pass
nrn_Item *nrn_sectionlist_data(const Object *obj)

Given a NEURON SectionList object, return a nrn_Item* that can be used to loop over the Sections.

Parameters:
  • obj – Pointer to a SectionList object.

Returns:

nrn_Item* suitable for iteration.

The nrn_Item* returned can be used for loops in the same way as the all_sections variable in the example in nrn_allsec().

bool nrn_section_is_active(const Section *sec)

Check if a Section is active (exists and is valid).

Parameters:
  • sec – Pointer to the Section to check.

Returns:

true if the Section is active, false otherwise.

Usage Pattern:

Used for validation before performing operations on Sections, especially when Sections might have been deleted or are from external sources. Inactive Sections might arise if the Section has been explicitly deleted but is referenced in a SectionList. Each iteration over a SectionList checks for inactive Sections and removes them (they are not returned). Only after there are no references to a deleted Section will its memory be freed.

void nrn_section_ref(Section *sec)

Increase the Section’s reference count. Sections with active references will not be free’d from memory.

Parameters:
  • sec – Pointer to the Section to reference.

void nrn_section_unref(Section *sec)

Decrease the Section’s reference count. Sections with active references will not be free’d from memory.

Parameters:
  • sec – Pointer to the Section to unreference.

Section *nrn_cas(void)

Get the currently accessed Section (top of the Section stack).

Returns:

Pointer to the currently accessed Section, or NULL if stack is empty.

Usage Pattern:

Used to determine which Section is currently active for operations that depend on the Section stack state.

C Usage:

Section* current_sec = nrn_cas();  // Get currently accessed Section

Python Equivalent:

current_sec = n.cas()  # Get currently accessed Section

Segments

int nrn_nseg_get(const Section *sec)

Get the number of segments in a Section. Segments are computational compartments within a Section used for numerical integration.

Parameters:
  • sec – Pointer to the Section.

Returns:

Number of segments in the Section.

Usage Pattern:

The number of segments determines the spatial resolution of the simulation. More segments provide higher accuracy but increase computational cost. The number of segments is sometimes set based on the d-lambda rule.

C Usage:

int n_segments = nrn_nseg_get(soma);

Python Equivalent:

n_segments = soma.nseg  # Get number of segments
void nrn_nseg_set(Section *sec, int nseg)

Set the number of segments in a Section.

Parameters:
  • sec – Pointer to the Section.

  • nseg – Number of segments to set (must be ≥ 1).

Usage Pattern:

Typically set based on the d-lambda rule or manual specification for accuracy. Common values are 1, 3, 5, etc. (We recommend using odd numbers for nseg, so that there is always a node centered around the Section center. With an even number of segments, the center node would be at the border between two segments.)

C Usage:

nrn_nseg_set(soma, 1);     // Single compartment
nrn_nseg_set(dendrite, 5); // Five compartments

Python Equivalent:

soma.nseg = 1     # Single compartment
dendrite.nseg = 5 # Five compartments
void nrn_segment_diam_set(Section *sec, double x, double diam)

Set the diameter of a segment (specified as normalized position x along the Section).

Parameters:
  • sec – Pointer to the Section.

  • x – Normalized position along Section (0.0 to 1.0).

  • diam – Diameter in microns.

Usage Pattern:

Used to define the morphological shape of Sections. The diameter can vary along the length of a Section to model tapering dendrites or axons.

C Usage:

// Set at specific location
nrn_segment_diam_set(soma, 0.5, 25.0);  // Set diameter at middle to 25 μm

// Set diameter for all of dend uniformly
int nseg = nrn_nseg_get(dend);
for (int i = 0; i < nseg; i++) {
    double x = (i + 0.5) / nseg;
    nrn_segment_diam_set(dend, x, 10.0); // Set each segment diameter to 10 μm
}

Python Equivalent:

# Set at specific location
soma(0.5).diam = 25   # Set diameter at middle of Section

# Set diameter everywhere
dend.diam = 10

Warning

Setting segment diameters will have no effect if 3d points have been specified for that Section via pt3dadd. To allow diameter specification after that, first call pt3dclear to remove the 3d points.

double nrn_segment_diam_get(Section *sec, double x)

Get the diameter of a segment at normalized position x along the Section.

Parameters:
  • sec – Pointer to the Section.

  • x – Normalized position along Section (0.0 to 1.0).

Returns:

Diameter in microns at the specified position.

C Usage:

double diameter = nrn_segment_diam_get(soma, 0.5);  // Get diameter at middle

Python Equivalent:

diameter = soma(0.5).diam  # Get diameter at middle of Section
void nrn_rangevar_push(Symbol *sym, Section *sec, double x)

Push a range variable for a Section at position x onto the NEURON stack. Range variables are properties that can vary along the length of a Section.

Parameters:
  • sym – Symbol representing the range variable.

  • sec – Pointer to the Section.

  • x – Normalized position along Section (0.0 to 1.0).

Usage Pattern:

Push a range variable when it is the argument to a NEURON function/method call. For memory safety, use functions like this instead of passing around raw pointers.

Example:

// Push the range variable for soma(0.5).v onto the stack
// Assumes soma is a Section* and we wish to record the voltage at 0.5 over time
Symbol* sym = nrn_symbol("v");
nrn_rangevar_push(sym, soma, 0.5);

// Now you can use this pushed variable in a method call
// For example, assume vec is a NEURON Vector Object*
nrn_method_call(vec, "record", 1);  // Call record method with 1 argument (the pushed range variable)
double nrn_rangevar_get(Symbol *sym, Section *sec, double x)

Get the value of a range variable at position x in a Section.

Parameters:
  • sym – Symbol representing the range variable.

  • sec – Pointer to the Section.

  • x – Normalized position along Section (0.0 to 1.0).

Returns:

Value of the range variable at the specified position.

Usage Pattern:

Used to read spatially distributed properties such as: - g_pas: passive conductance - m_hh: sodium channel gating variable - v: membrane voltage

C Usage:

// Get membrane voltage
Symbol* v_sym = nrn_symbol("v");
double voltage = nrn_rangevar_get(v_sym, soma, 0.5);

Python Equivalent:

# Get membrane voltage
voltage = soma(0.5).v
void nrn_rangevar_set(Symbol *sym, Section *sec, double x, double value)

Set the value of a range variable at position x in a Section.

Parameters:
  • sym – Symbol representing the range variable.

  • sec – Pointer to the Section.

  • x – Normalized position along Section (0.0 to 1.0).

  • value – Value to set for the range variable.

Usage Pattern:

Used to configure biophysical properties of Sections, such as: - Setting channel densities - Configuring passive properties - Initializing membrane voltages

C Usage:

// Set initial voltage
Symbol* v_sym = nrn_symbol("v");
nrn_rangevar_set(v_sym, soma, 0.5, -65.0);  // mV

// Set passive conductance at all segments of dend
Symbol* g_pas_sym = nrn_symbol("g_pas");
int nseg = nrn_nseg_get(dend);
for (int i = 0; i < nseg; i++) {
    double x = (i + 0.5) / nseg;
    nrn_rangevar_set(g_pas_sym, dend, x, 0.001); // 0.001 S/cm²
}

Python Equivalent:

# Set initial voltage at the center of the soma
soma(0.5).v = -65  # mV

# Set passive conductance at all segments of dend
for seg in dend:
    seg.g_pas = 0.001  # S/cm²

Functions, objects, and the stack

Symbol *nrn_symbol(const char *name)

Get a symbol by name from NEURON’s symbol table. Symbols represent variables, functions, mechanisms, and other named entities in NEURON.

Parameters:
  • name – Name of the symbol to lookup.

Returns:

Pointer to the Symbol object, or NULL if not found.

Usage Pattern:

Used to access NEURON built-in functions, variables, and mechanisms by name. Symbols only need to be looked up once; the returned pointer can be reused.

C Usage:

// Access built-in NEURON functions
Symbol* finitialize_sym = nrn_symbol("finitialize");
nrn_double_push(-65.0);  // Push voltage argument
nrn_function_call(finitialize_sym, 1);  // Initialize membrane voltage

Symbol* fadvance_sym = nrn_symbol("fadvance");
nrn_function_call(fadvance_sym, 0);  // Advance simulation by one time step

Python Equivalent:

# Access built-in NEURON functions
n.finitialize(-65)  # Initialize membrane voltage
n.fadvance()        # Advance simulation by one time step
void nrn_symbol_push(Symbol *sym)

Push a symbol onto the HOC execution stack.

Parameters:
  • sym – Pointer to the symbol to push.

int nrn_symbol_type(const Symbol *sym)

Get the type of a symbol (e.g., function, variable, mechanism).

Parameters:
  • sym – Pointer to the symbol.

Returns:

Integer representing the symbol type.

Usage Pattern:

Used to determine what kind of entity a symbol represents before performing type-specific operations. For example, the MATLAB interface uses this as part of dynamically generating the interface.

int nrn_symbol_subtype(const Symbol *sym)

Get the subtype of a symbol, providing more detailed classification.

Parameters:
  • sym – Pointer to the symbol.

Returns:

Integer representing the symbol subtype.

The meanings of the symbol subtype code depends on the symbol type. For example, t is a built-in double variable and has a different subtype than a user-created double variable.

double *nrn_symbol_dataptr(const Symbol *sym)

Get a pointer to the data for a symbol (for variables).

Parameters:
  • sym – Pointer to the symbol.

Returns:

Pointer to the symbol’s data, or NULL if not applicable.

Usage Pattern:

Provides direct access to variable data for efficient reading/writing. e.g., use this for getting/setting the value of t (time).

bool nrn_symbol_is_array(const Symbol *sym)

Check if a symbol represents an array.

Parameters:
  • sym – Pointer to the symbol.

Returns:

true if the symbol is an array, false otherwise.

Usage Pattern:

Used to determine if special array access methods are needed. For example, VClamp objects have an array of amp values.

void nrn_double_push(double val)

Push a double value onto the NEURON execution stack.

Parameters:
  • val – Double value to push.

Usage Pattern:

Used when preparing arguments for function/method calls.

double nrn_double_pop(void)

Pop a double value from the NEURON stack.

Returns:

Double value from the top of the stack.

Usage Pattern:

Used to retrieve function/method return values.

void nrn_double_ptr_push(double *addr)

Push a pointer to a double onto the stack.

Parameters:
  • addr – Pointer to double to push.

Usage Pattern:

Used for passing references to variables that can be modified by functions. These pointers can be to variables from NEURON or to local variables.

double *nrn_double_ptr_pop(void)

Pop a pointer to a double from the stack.

Returns:

Pointer to double from the top of the stack.

Warning

Using pointers risks dereferencing invalid memory if the pointer is not valid. Prefer other strategies for memory safety.

void nrn_str_push(char **str)

Push a string onto the stack.

Parameters:
  • str – Pointer to string pointer to push.

C++ Usage:

// Load stdrun.hoc using the NEURON API
std::string filename = "stdrun.hoc";
char* cstr = const_cast<char*>(filename.c_str());
nrn_str_push(&cstr);
Symbol* load_file_sym = nrn_symbol("load_file");
nrn_function_call(load_file_sym, 1);

Python Equivalent:

# Load stdrun.hoc using the NEURON API (Python version)
n.load_file("stdrun.hoc")
char **nrn_str_pop(void)

Pop a string from the stack.

Returns:

Pointer to string pointer from the top of the stack.

Usage Pattern:

Used to retrieve function/method return values.

void nrn_int_push(int i)

Push an integer onto the stack.

Parameters:
  • i – Integer value to push.

Warning

Most NEURON functions expect doubles not ints and may fail if an int is pushed instead.

int nrn_int_pop(void)

Pop an integer from the stack.

Returns:

Integer value from the top of the stack.

Usage Pattern:

Used to retrieve function/method return values.

Warning

Most NEURON functions when accessed through the API return doubles not ints and may fail if an int is pushed instead. This is true even for functions that return an integer value in Python.

void nrn_object_push(Object *obj)

Push an object onto the stack.

Parameters:
  • obj – Pointer to object to push.

Usage Pattern:

Used when passing objects as arguments to functions or methods.

Object *nrn_object_pop(void)

Pop an object from the stack.

Returns:

Pointer to object from the top of the stack.

Usage Pattern:

Used to retrieve function/method return values. Use nrn_stack_type() to check the type before popping, or use the type of the function/method to know the expected return type in advance.

nrn_stack_types_t nrn_stack_type(void)

Get the type of the value on top of the stack without removing it.

Returns:

Enumeration value indicating the stack top type.

Usage Pattern:

Used for type checking before popping values to ensure correct handling.

char const *nrn_stack_type_name(nrn_stack_types_t id)

Get the name of a stack type as a human-readable string.

Parameters:
  • id – Stack type enumeration value.

Returns:

String representation of the stack type.

Object *nrn_object_new(Symbol *sym, int narg)

Create a new object instance of the type represented by the symbol.

Parameters:
  • sym – Symbol representing the object class/type.

  • narg – Number of constructor arguments on the stack.

Returns:

Pointer to the newly created object.

Usage Pattern:

Used to instantiate NEURON objects like Vector, NetCon, SEClamp, etc. Constructor arguments must be pushed onto the stack before calling.

C Usage:

// Create NEURON Vector with 100 elements
Symbol* vec_sym = nrn_symbol("Vector");
nrn_double_push(100);
Object* vec = nrn_object_new(vec_sym, 1);

// Create current clamp at soma
Symbol* iclamp_sym = nrn_symbol("IClamp");
nrn_object_push((Object*)soma);  // Push soma as object
nrn_double_push(0.0);            // Push location (0.0)
Object* iclamp = nrn_object_new(iclamp_sym, 2);

Python Equivalent:

# Create NEURON objects
vec = n.Vector(100)           # Vector with 100 elements
iclamp = n.IClamp(soma(0))    # Current clamp at soma
Symbol *nrn_method_symbol(const Object *obj, const char *name)

Get a method symbol from an object by name.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the method to lookup.

Returns:

Pointer to the method symbol, or NULL if not found.

Usage Pattern:

Used to access object methods dynamically; essential for method calls. See nrn_method_call() for an example.

void nrn_method_call(Object *obj, Symbol *method_sym, int narg)

Call a method on a NEURON object.

Parameters:
  • obj – Pointer to the object.

  • method_sym – Symbol representing the method to call.

  • narg – Number of arguments on the stack.

Usage Pattern:

Used to invoke object methods. Arguments must be pushed onto the stack before calling. Return values (if any) are left on the stack.

C Usage:

// Resize vector to 200 elements
Symbol* resize_method = nrn_method_symbol(vec, "resize");
nrn_double_push(200);
nrn_method_call(vec, resize_method, 1);
Object* returned_obj = nrn_object_pop();

// Fill vector with zeros
Symbol* fill_method = nrn_method_symbol(vec, "fill");
nrn_double_push(0.0);
nrn_method_call(vec, fill_method, 1);
Object* returned_obj2 = nrn_object_pop();

// Get vector size
Symbol* size_method = nrn_method_symbol(vec, "size");
nrn_method_call(vec, size_method, 0);
double length = nrn_double_pop();

Python Equivalent:

vec.resize(200)     # Resize vector to 200 elements
vec.fill(0)         # Fill vector with zeros
length = vec.size() # Get vector size

Warning

This function raises a C++ exception on error which cannot be caught in pure C. An exception-free variant for use in C is nrn_method_call_nothrow().

void nrn_function_call(Symbol *sym, int narg)

Call a function by symbol.

Parameters:
  • sym – Symbol representing the function to call.

  • narg – Number of arguments on the stack.

Usage Pattern:

Used to call global functions and built-in NEURON functions. Arguments must be prepared on the stack before calling.

C Usage:

// Call finitialize(-65)
Symbol* finitialize_sym = nrn_symbol("finitialize");
nrn_double_push(-65.0);  // Push argument
nrn_function_call(finitialize_sym, 1);
// Call fadvance()
Symbol* fadvance_sym = nrn_symbol("fadvance");
nrn_function_call(fadvance_sym, 0);

Python Equivalent:

n.finitialize(-65)  # Initialize membrane voltage
n.fadvance()        # Advance simulation by one time step

Warning

This function raises a C++ exception on error which cannot be caught in pure C. An exception-free variant for use in C is nrn_function_call_nothrow().

int nrn_method_call_nothrow(Object *obj, Symbol *method_sym, int narg, char *error_msg, size_t error_msg_size)

Call a method on a NEURON object without throwing exceptions.

Parameters:
  • obj – Pointer to the object.

  • method_sym – Symbol representing the method to call.

  • narg – Number of arguments on the stack.

  • error_msg – Buffer to store error message if call fails.

  • error_msg_size – Size of the error message buffer.

Returns:

0 on success, non-zero on error.

Usage Pattern:

Used to invoke object methods with error handling. Arguments must be pushed onto the stack before calling. Return values (if any) are left on the stack. Unlike nrn_method_call(), this function returns an error code instead of throwing exceptions, making it suitable for use in pure C code or via ctypes.

C Usage:

char error_buffer[256];

// Resize vector to 200 elements
Symbol* resize_method = nrn_method_symbol(vec, "resize");
nrn_double_push(200);
int result = nrn_method_call_nothrow(vec, resize_method, 1,
                                     error_buffer, sizeof(error_buffer));
if (result != 0) {
    fprintf(stderr, "Resize failed: %s\n", error_buffer);
    return -1;
}
Object* returned_obj = nrn_object_pop();

// Fill vector with zeros
Symbol* fill_method = nrn_method_symbol(vec, "fill");
nrn_double_push(0.0);
result = nrn_method_call_nothrow(vec, fill_method, 1,
                                 error_buffer, sizeof(error_buffer));
if (result != 0) {
    fprintf(stderr, "Fill failed: %s\n", error_buffer);
    return -1;
}
Object* returned_obj2 = nrn_object_pop();

// Get vector size
Symbol* size_method = nrn_method_symbol(vec, "size");
result = nrn_method_call_nothrow(vec, size_method, 0,
                                 error_buffer, sizeof(error_buffer));
if (result != 0) {
    fprintf(stderr, "Size method failed: %s\n", error_buffer);
    return -1;
}
double length = nrn_double_pop();

Python Equivalent:

vec.resize(200)     # Resize vector to 200 elements
vec.fill(0)         # Fill vector with zeros
length = vec.size() # Get vector size
int nrn_function_call_nothrow(Symbol *sym, int narg, char *error_msg, size_t error_msg_size)

Call a function by symbol without throwing exceptions.

Parameters:
  • sym – Symbol representing the function to call.

  • narg – Number of arguments on the stack.

  • error_msg – Buffer to store error message if call fails.

  • error_msg_size – Size of the error message buffer.

Returns:

0 on success, non-zero on error.

Usage Pattern:

Used to call global functions and built-in NEURON functions with error handling. Arguments must be prepared on the stack before calling. Unlike nrn_function_call(), this function returns an error code instead of throwing exceptions, making it suitable for use in pure C code or via ctypes.

C Usage:

char error_buffer[256];

// Call finitialize(-65)
Symbol* finitialize_sym = nrn_symbol("finitialize");
nrn_double_push(-65.0);  // Push argument
int result = nrn_function_call_nothrow(finitialize_sym, 1,
                                       error_buffer, sizeof(error_buffer));
if (result != 0) {
    fprintf(stderr, "finitialize failed: %s\n", error_buffer);
    return -1;
}
// Call fadvance()
Symbol* fadvance_sym = nrn_symbol("fadvance");
result = nrn_function_call_nothrow(fadvance_sym, 0,
                                   error_buffer, sizeof(error_buffer));
if (result != 0) {
    fprintf(stderr, "fadvance failed: %s\n", error_buffer);
    return -1;
}

Python Equivalent:

n.finitialize(-65)  # Initialize membrane voltage
n.fadvance()        # Advance simulation by one time step
void nrn_object_ref(Object *obj)

Increment the reference count of an object.

Parameters:
  • obj – Pointer to the object.

Usage Pattern:

Used for memory management. When storing object pointers, increment the reference count to prevent premature deletion. Decrement when done.

Note

Objects are automatically deleted when their reference count reaches zero. Always match nrn_object_ref() with a corresponding nrn_object_unref() call to prevent memory leaks.

void nrn_object_unref(Object *obj)

Decrement the reference count of an object. When the count reaches zero, the object is automatically deleted.

Parameters:
  • obj – Pointer to the object.

Usage Pattern:

Used for memory management. Always match with previous nrn_object_ref() calls to prevent segmentation faults from premature deletion.

See also

nrn_object_ref()

char const *nrn_class_name(const Object *obj)

Get the class name of an object.

Parameters:
  • obj – Pointer to the object.

Returns:

String containing the class name.

Usage Pattern:

Used for type identification, debugging, and polymorphic operations.

C Usage:

const char* class_name = nrn_class_name(obj);

Python Equivalent:

class_name = obj.hname().split('[')[0]
bool nrn_prop_exists(const Object *obj)

Check if properties exist for an object. Properties might not exist if the object is a point process that has not been placed into a Section.

Parameters:
  • obj – Pointer to the object.

Returns:

true if the object has properties, false otherwise.

Usage Pattern:

Used for validation before attempting property access operations (getting/setting). Attempting to access properties (e.g., an IClamp object’s amp) of a point process that has not been placed into a Section will result in a segmentation fault (so check with this function first).

double nrn_distance(Section *sec0, double x0, Section *sec1, double x1)

Compute the distance between two points in potentially different sections along the neuron. This calculates the path length through the dendritic tree between the specified points.

Parameters:
  • sec0 – Pointer to the first Section.

  • x0 – Normalized position in first Section (0.0 to 1.0).

  • sec1 – Pointer to the second Section.

  • x1 – Normalized position in second Section (0.0 to 1.0).

Returns:

Distance in microns along the morphological path.

Usage Pattern:

Used for spatial analysis, determining non-uniform ion channel conductances (e.g., in CA1 Pyramidal neurons the A current might increase with distance from the soma), calculating electrotonic distance, or determining the morphological distance between synapses and recording sites.

C Usage:

// Calculate distance from soma center to dendrite tip
double dist = nrn_distance(soma, 0.5, dendrite, 1.0);

Python Equivalent:

# Calculate distance from soma center to dendrite tip
dist = n.distance(soma(0.5), dendrite(1.0))

Note

This function exists to avoid having to set a global reference point when using distance().

Shape Plot

ShapePlotInterface *nrn_get_plotshape_interface(Object *ps)

Get the shape plot interface from a PlotShape object. This provides access to the internal plotting data and configuration.

Parameters:
  • ps – Pointer to a PlotShape object.

Returns:

Pointer to the ShapePlotInterface.

Usage Pattern:

Used by plotting functions to extract morphological and variable data for visualization. The specific data may be queried with other functions, described below.

C Usage:

Symbol* plotshape_sym = nrn_symbol("PlotShape");
Object* ps = nrn_object_new(plotshape_sym, 0);

// Set variable to plot
char const* var_name = "v";
Symbol* variable_method = nrn_method_symbol(ps, "variable");
nrn_str_push((char**)&var_name);
nrn_method_call(ps, variable_method, 1);

// Extract plot data
ShapePlotInterface* spi = nrn_get_plotshape_interface(ps);

Python Equivalent:

ps = n.PlotShape(False)
ps.variable('v')     # Set variable to plot
# Data extraction would need custom implementation
Object *nrn_get_plotshape_section_list(ShapePlotInterface *spi)

Get the Section list from a shape plot interface.

Parameters:
  • spi – Pointer to the ShapePlotInterface.

Returns:

Pointer to the Object representing the Section list.

const char *nrn_get_plotshape_varname(ShapePlotInterface *spi)

Get the variable name used in a shape plot.

Parameters:
  • spi – Pointer to the ShapePlotInterface.

Returns:

String containing the variable name.

float nrn_get_plotshape_low(ShapePlotInterface *spi)

Get the lower bound for color scaling in a shape plot.

Parameters:
  • spi – Pointer to the ShapePlotInterface.

Returns:

Lower bound value for color mapping.

float nrn_get_plotshape_high(ShapePlotInterface *spi)

Get the upper bound for color scaling in a shape plot.

Parameters:
  • spi – Pointer to the ShapePlotInterface.

Returns:

Upper bound value for color mapping.

Miscellaneous

int nrn_hoc_call(char const *command)

Execute a HOC command string. HOC is NEURON’s built-in scripting language.

Parameters:
  • command – Null-terminated string containing the HOC command.

Returns:

Status code

Usage Pattern:

Provides a way to execute arbitrary NEURON/HOC commands from C code. Useful for operations not directly exposed through the C API.

C Usage:

nrn_hoc_call("topology()");           // Display topology
nrn_hoc_call("forall psection()");    // Print all sections
nrn_hoc_call("celsius = 37");         // Set temperature

Python Equivalent:

n('topology()')           # Display topology
n('forall psection()')    # Print all sections
n.celsius = 37            # Set temperature

Note

When constructing language bindings for NEURON, support for nrn_hoc_call is an important function, because it allows you to see the effects of each newly added feature and it provides a validation comparison.

SectionListIterator *nrn_sectionlist_iterator_new(nrn_Item *my_sectionlist)

Create a new Section list iterator for traversing a list of sections.

Parameters:
  • my_sectionlist – Pointer to the Section list data.

Returns:

Pointer to the new SectionListIterator.

Usage Pattern:

Used to iterate over collections of sections efficiently. Essential for operations that need to process all sections or subsets.

See nrn_allsec() for an example of iterating over all sections.

void nrn_sectionlist_iterator_free(SectionListIterator *sl)

Free a Section list iterator and release associated resources.

Parameters:
  • sl – Pointer to the SectionListIterator to free.

Usage Pattern:

Always call after finishing Section list iteration to prevent memory leaks.

See nrn_allsec() for an example of iterating over all sections.

Section *nrn_sectionlist_iterator_next(SectionListIterator *sl)

Get the next Section from a Section list iterator.

Parameters:
  • sl – Pointer to the SectionListIterator.

Returns:

Pointer to the next Section.

Usage Pattern:

Used in loops to process each Section in a list sequentially.

Before calling, check with nrn_sectionlist_iterator_done() to ensure there are more sections to process.

See nrn_allsec() for an example of iterating over all sections.

int nrn_sectionlist_iterator_done(SectionListIterator *sl)

Check if the Section list iterator has finished iterating.

Parameters:
  • sl – Pointer to the SectionListIterator.

Returns:

Non-zero if iteration is complete, 0 otherwise.

Usage Pattern:

Used as a loop termination condition.

Example iteration pattern:

SectionListIterator* iter = nrn_sectionlist_iterator_new(section_list);
while (!nrn_sectionlist_iterator_done(iter)) {
    Section* sec = nrn_sectionlist_iterator_next(iter);
    // Process Section
}
nrn_sectionlist_iterator_free(iter);
SymbolTableIterator *nrn_symbol_table_iterator_new(Symlist *my_symbol_table)

Create a new symbol table iterator for traversing symbols.

Parameters:
  • my_symbol_table – Pointer to the symbol table.

Returns:

Pointer to the new SymbolTableIterator.

Usage Pattern:

Used to iterate over NEURON’s symbol tables to discover available functions, variables, and mechanisms. This allows language bindings to dynamically discover the NEURON interface, including user-defined functions added during runtime.

C++ Usage:

// Retrieve the global and top-level symbol tables
auto global_symtable = nrn_global_symbol_table();
auto top_level_symtable = nrn_top_level_symbol_table();
std::string result;

// Iterate over both symbol tables
for (auto symtable : {global_symtable, top_level_symtable}) {
    // Create an iterator for the current symbol table
    auto iter = nrn_symbol_table_iterator_new(symtable);

    // Loop through all symbols in the table
    while (!nrn_symbol_table_iterator_done(iter)) {
        // Get symbol
        Symbol* sym = nrn_symbol_table_iterator_next(iter);

        // Retrieve the symbol name and its type/subtype
        const char* name = nrn_symbol_name(sym);
        int type = nrn_symbol_type(sym);
        int subtype = nrn_symbol_subtype(sym);

        std::cout << "Symbol: " << name
                << ", Type: " << type
                << ", Subtype: " << subtype << std::endl;
    }

    // Free the iterator after use
    nrn_symbol_table_iterator_free(iter);
}
void nrn_symbol_table_iterator_free(SymbolTableIterator *st)

Free a symbol table iterator.

Parameters:
  • st – Pointer to the SymbolTableIterator to free.

See nrn_symbol_table_iterator_new() for example usage.

Symbol *nrn_symbol_table_iterator_next(SymbolTableIterator *st)

Get the next symbol from a symbol table iterator.

Parameters:
  • st – Pointer to the SymbolTableIterator.

Returns:

Pointer to the next Symbol.

Be sure to check with nrn_symbol_table_iterator_done() before calling; this does not return NULL when done.

See nrn_symbol_table_iterator_new() for example usage.

int nrn_symbol_table_iterator_done(SymbolTableIterator *st)

Check if the symbol table iterator has finished iterating.

Parameters:
  • st – Pointer to the SymbolTableIterator.

Returns:

Non-zero if iteration is complete, 0 otherwise.

See nrn_symbol_table_iterator_new() for example usage.

int nrn_vector_capacity(const Object *vec)

Get the capacity (allocated size) of a vector object.

Parameters:
  • vec – Pointer to the Vector object.

Returns:

Capacity of the vector.

Usage Pattern:

Used for memory management and optimization when working with vectors.

double *nrn_vector_data(Object *vec)

Get direct access to the data array of a vector object.

Parameters:
  • vec – Pointer to the Vector object.

Returns:

Pointer to the internal data array.

Usage Pattern:

Provides efficient access to vector data for bulk operations without going through the object interface.

In language bindings, it may be possible to use this pointer to create a more native view into the data (e.g., in Python, a numpy array can be initialized from a pointer and a size, so the numpy array can directly be used to work with the Vector’s data).

C Usage:

double* vec_data = nrn_vector_data(vec);  // Get vector data pointer

// directly access elements
for (int i = 0; i < 100; i++) {
    vec_data[i] = i * 0.1;  // Set values
}
double nrn_property_get(const Object *obj, const char *name)

Get a property value from an object by name.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the property.

Returns:

Value of the property.

Usage Pattern:

Used to read object properties dynamically by name. Essential for generic property access.

C Usage:

double amp = nrn_property_get(iclamp, "amp");      // Get current clamp amplitude
double dur = nrn_property_get(iclamp, "dur");      // Get current clamp duration

Python Equivalent:

amp = iclamp.amp      # Get current clamp amplitude
dur = iclamp.dur      # Get current clamp duration
double nrn_property_array_get(const Object *obj, const char *name, int i)

Get a value from a property array by index.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the property array.

  • i – Index into the array (0-based).

Returns:

Value at the specified index.

Usage Pattern:

Used for properties that are arrays.

C Usage:

double amp0 = nrn_property_array_get(vclamp, "amp", 0);  // Get first amplitude
double amp1 = nrn_property_array_get(vclamp, "amp", 1);  // Get second amplitude

Python Equivalent:

amp0 = vclamp.amp[0]  # Get first amplitude
amp1 = vclamp.amp[1]  # Get second amplitude
void nrn_property_set(Object *obj, const char *name, double value)

Set a property value on an object.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the property.

  • value – Value to set.

C Usage:

nrn_property_set(iclamp, "amp", 0.1);      // Set current amplitude to 0.1 nA
nrn_property_set(iclamp, "del", 100.0);    // Set delay to 100 ms

Python Equivalent:

iclamp.amp = 0.1      # Set current amplitude to 0.1 nA
iclamp.delay = 100    # Set delay to 100 ms
void nrn_property_array_set(Object *obj, const char *name, int i, double value)

Set a value in a property array.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the property array.

  • i – Index into the array (0-based).

  • value – Value to set at the specified index.

void nrn_property_push(Object *obj, const char *name)

Push a property value onto the NEURON stack.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the property.

Usage Pattern:

This allows the equivalent of the Python vec.play(iclamp._ref_amp, tvec, True) which is how NEURON can implement non-square-wave current clamps. Here iclamp._ref_amp is a reference to the amp property of the IClamp object.

void nrn_property_array_push(Object *obj, const char *name, int i)

Push a property array element onto the NEURON stack.

Parameters:
  • obj – Pointer to the object.

  • name – Name of the property array.

  • i – Index into the array (0-based).

char const *nrn_symbol_name(const Symbol *sym)

Get the name of a symbol as a string.

Parameters:
  • sym – Pointer to the symbol.

Returns:

String containing the symbol name.

Usage Pattern:

Used for debugging, introspection, and dynamic symbol handling.

See nrn_symbol_table_iterator_new() for an example of iterating over symbols, which uses this function to get the symbol names.

Symlist *nrn_symbol_table(const Symbol *sym)

Get the symbol table that contains a symbol.

Parameters:
  • sym – Pointer to the symbol.

Returns:

Pointer to the containing symbol table.

Symlist *nrn_global_symbol_table(void)

Get the global symbol table containing built-in NEURON functions and variables.

Returns:

Pointer to the global symbol table.

See nrn_symbol_table_iterator_new() for an example of iterating over the global symbol table.

Symlist *nrn_top_level_symbol_table(void)

Get the top-level symbol table containing user-defined symbols.

Returns:

Pointer to the top-level symbol table.

int nrn_symbol_array_length(const Symbol *sym)

Get the length of a symbol array.

Parameters:
  • sym – Pointer to the symbol.

Returns:

Length of the array, or 1 for non-arrays.

void nrn_register_function(void (*proc)(), const char *func_name, int type)

Register a C function to be callable from NEURON/HOC.

Parameters:
  • proc – Pointer to the C function.

  • func_name – Name by which the function will be known in NEURON.

  • type – Function type identifier.

Usage Pattern:

Used to extend NEURON with custom C functions that can be called from HOC; for example, the MATLAB interface uses this to provide an nrn_matlab function to HOC. Furtherore, this allows callback functions into a language binding, allowing, for example, callbacks in CVode.event() or FInitializeHandler.

The function should end by calling nrn_hoc_ret() and pushing its result to the stack.

void nrn_hoc_ret(void)

Return from a HOC function call.

Usage Pattern:

Used in custom functions registered with nrn_register_function() to signal completion of execution.

Parameter-reading functions

Object **nrn_objgetarg(int arg)

Get an object argument from the NEURON stack during function execution.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

Pointer to pointer to the object argument.

Usage Pattern:

Used in custom functions registered with NEURON to access object arguments passed from NEURON/HOC.

If it is not known that there is an argument at the specified index, use nrn_ifarg() to check before calling this function.

If the type of the argument is not known in advance, use nrn_is_object_arg() to check before calling this function.

Example:

// In a custom function
Object** obj_ptr = nrn_objgetarg(1);  // Get first object argument
if (obj_ptr && *obj_ptr) {
    // Use the object
}
char *nrn_gargstr(int arg)

Get a string argument from the NEURON stack during function execution.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

Pointer to the string argument.

Usage Pattern:

Used in custom functions registered with NEURON to access string arguments passed from NEURON/HOC.

If it is not known that there is an argument at the specified index, use nrn_ifarg() to check before calling this function.

If the type of the argument is not known in advance, use nrn_is_str_arg() to check before calling this function.

Example:

char* filename = nrn_gargstr(1);  // Get first string argument
double *nrn_getarg(int arg)

Get a double argument from the NEURON stack during function execution.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

Pointer to the double argument.

Usage Pattern:

Used in custom functions registered with NEURON to access double arguments passed from NEURON/HOC.

If it is not known that there is an argument at the specified index, use nrn_ifarg() to check before calling this function.

If the type of the argument is not known in advance, use nrn_is_double_arg() to check before calling this function.

Example:

double value = *nrn_getarg(1);  // Get first double argument
FILE *nrn_obj_file_arg(int i)

Get a file argument from the HOC stack during function execution.

Parameters:
  • i – Argument index (1-indexed).

Returns:

Pointer to the FILE object.

Usage Pattern:

Used when custom functions need to work with file objects passed from NEURON/HOC.

bool nrn_ifarg(int arg)

Check if an argument exists at the specified position.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

true if argument exists, false otherwise.

Usage Pattern:

Used to implement optional parameters in custom functions.

Example:

if (nrn_ifarg(2)) {
    // Second argument was provided
    optional_param = *nrn_getarg(2);
} else {
    // Use default value
    optional_param = default_value;
}
bool nrn_is_object_arg(int arg)

Check if an argument is an object.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

true if argument is an object, false otherwise.

bool nrn_is_str_arg(int arg)

Check if an argument is a string.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

true if argument is a string, false otherwise.

bool nrn_is_double_arg(int arg)

Check if an argument is a double.

Parameters:
  • arg – Argument index (1-indexed).

Returns:

true if argument is a double, false otherwise.

bool nrn_is_pdouble_arg(int arg)

Check if an argument is a pointer to double (reference parameter).

Parameters:
  • arg – Argument index (1-indexed).

Returns:

true if argument is a pointer to double, false otherwise.

Common Usage Patterns

Creating and Connecting Sections:

// Create sections
Section* soma = nrn_section_new("soma");
Section* dendrite = nrn_section_new("dendrite");

// Set properties
nrn_section_length_set(soma, 20.0);     // 20 μm
nrn_section_length_set(dendrite, 100.0); // 100 μm

// Connect dendrite to soma
nrn_section_connect(dendrite, 0.0, soma, 1.0);

Working with Objects and Methods:

// Get Vector class symbol
Symbol* vec_sym = nrn_symbol("Vector");

// Create Vector with 100 elements
nrn_double_push(100);
Object* vec = nrn_object_new(vec_sym, 1);

// Call Vector.fill(0)
Symbol* fill_method = nrn_method_symbol(vec, "fill");
nrn_double_push(0.0);
nrn_method_call(vec, fill_method, 1);

Memory Management:

// When storing object pointers
nrn_object_ref(obj);    // Increment reference count

// When done with object
nrn_object_unref(obj);  // Decrement reference count