MWE for apparent bug discovered by PyNN format

When Python is the interpreter, what is a good
design for the interface to the basic NEURON
concepts.

Moderator: hines

Post Reply
Tom Close
Posts: 18
Joined: Wed Sep 05, 2012 11:59 pm

MWE for apparent bug discovered by PyNN format

Post by Tom Close » Tue Mar 10, 2015 10:44 pm

Hi,

I am getting a strange bug when using the built-in PyNN Izhikevich model (outside of PyNN), which I assume is caused by a buffer overrun somewhere in the NEURON Python interface. The following snippet is a MWE

Code: Select all

import neuron
import pylab as plt
from neuron import h, nrn, load_mechanisms
from math import pi
from os import path


def _new_property(obj_hierarchy, attr_name):
    def set(self, value):
        obj = reduce(getattr, [self] + obj_hierarchy.split('.'))
        setattr(obj, attr_name, value)

    def get(self):
        obj = reduce(getattr, [self] + obj_hierarchy.split('.'))
        return getattr(obj, attr_name)

    return property(fset=set, fget=get)


class Izhikevich(nrn.Section):
    """docstring"""

    def __init__(self):
        nrn.Section.__init__(self)
        self.seg = self(0.5)
        self.source_section = self
        self.L = 10
        self.seg.diam = 10 / pi
        self.c_m = 1.0
        self.izh = h.Izhikevich1(0.5, sec=self)
        self.source = self.izh

        # Comment out this line or replace with 'self.izh.a = 0.2' or replace
        # the property name with a name that isn't in the izhikevich class
        # like 'self.e = 0.02'
        self.a = 0.02
#         self.izh.a = 0.2
#         self.e = 0.02

    a = _new_property('izh', 'a)
#     e = _new_property('izh', 'a')

load_mechanisms(path.join(path.dirname(__file__), '1'))

# Comment out this line and it works regardless
load_mechanisms(path.join(path.dirname(__file__), '2'))


sec = Izhikevich()
stim = h.IClamp(1.0, sec=sec)
stim.delay = 1
stim.dur = 100
stim.amp = 0.2
rec_t = neuron.h.Vector()
rec_t.record(neuron.h._ref_t)
rec_v = neuron.h.Vector()
rec_v.record(sec(0.5)._ref_v)
neuron.h.finitialize(-60)
neuron.init()
neuron.run(5)
plt.plot(rec_t, rec_v)
plt.show()
where the modfile Izhikevich1.mod is stored in a sub-directory named '1' in the same directory as the pyNEURON code, and Izhikevich2.mod (an identical file just with

Code: Select all

POINT_PROCESS Izhikevich2
) is stored in a sub-directory named '2'.

Code: Select all

NEURON {
    POINT_PROCESS Izhikevich1
    RANGE a, b, c, d, u, uinit, vthresh
    NONSPECIFIC_CURRENT i
}

UNITS {
    (mV) = (millivolt)
    (nA) = (nanoamp)
    (nF) = (nanofarad)
}

INITIAL {
    u = uinit
    net_send(0, 1)
}

PARAMETER {
    a       = 0.02 (/ms)
    b       = 0.2  (/ms)
    c       = -65  (mV)   : reset potential after a spike
    d       = 2    (mV/ms)
    vthresh = 30   (mV)   : spike threshold
    Cm      = 0.001  (nF)
    uinit   = -14  (mV/ms)
}

ASSIGNED {
    v (mV)
    i (nA)
}

STATE { 
    u (mV/ms)
}

BREAKPOINT {
    SOLVE states METHOD cnexp  : derivimplicit
    i = -Cm * (0.04*v*v + 5*v + 140 - u)
    :printf("t=%f, v=%f u=%f, i=%f, dv=%f, du=%f\n", t, v, u, i, 0.04*v*v + 5*v + 140 - u, a*(b*v-u))
}

DERIVATIVE states {
    u' = a*(b*v - u) 
}

NET_RECEIVE (weight (mV)) {
    if (flag == 1) {
        WATCH (v > vthresh) 2
    } else if (flag == 2) {
        net_event(t)
        v = c
        u = u + d
    } else { : synaptic activation
        v = v + weight
    }
}
If you comment out the lines I have marked in the pyNEURON code or replace them with my suggestions, the model behaves as it should. However, leaving it as it is I consistently get

Code: Select all

NameError: b, the mechanism does not exist at PySec_0x*(0.5)
.

I guess setting properties on objects that inherit from nrn.Section isn't a good idea but perhaps it points to a more serious bug somewhere in the interface

(NB: Andrew was getting this bug within PyNN and worked-around it by renaming 'a' to 'a_', but when I tried to use the model outside of PyNN and import my own mechanisms afterwards I ran into it again with the 'b' parameter)

Tom Close
Posts: 18
Joined: Wed Sep 05, 2012 11:59 pm

Re: MWE for apparent bug discovered by PyNN format

Post by Tom Close » Tue Mar 10, 2015 10:46 pm

Sorry, that should have been

Code: Select all

NameError: a, the mechanism does not exist at PySec_0x*(0.5)
(I reproduced this behaviour for both 'a' and 'b' and I assume it would occur for all parameters used in the izhikevich model)

Tom Close
Posts: 18
Joined: Wed Sep 05, 2012 11:59 pm

Re: MWE for apparent bug discovered by PyNN format

Post by Tom Close » Wed Mar 11, 2015 12:18 am

renaming the parameters in the mod file doesn't seem to help. Are 'a', 'b', 'c', 'd' hard-coded somewhere?

hines
Site Admin
Posts: 1571
Joined: Wed May 18, 2005 3:32 pm

Re: MWE for apparent bug discovered by PyNN format

Post by hines » Wed Mar 11, 2015 3:41 pm

Thanks. The bug is fixed in
http://neuron.yale.edu/hg/neuron/nrn/rev/ec1b0af97c71
The bug occurred for the combination of nrn_load_dll that loads a POINT_PROCESS and a subclass of nrn.Section that sets a name that is the same as a range variable declared in that POINT_PROCESS. The actual error is that those point process range variable names were being added to the list of possible SUFFIX mechanism range variable names.
ALthough there were some quite bizarre consequences of this bug that are not entirely understood, I don't think it is worth trying for a thorough understanding of exactly why things
went wrong after the bug was activated (ie. why there was no error if the two load_mechanism lines were reversed..)
Anyway, it would also be an error if you tried to declare gnabar_hh (or any other density mechanism range variable name) in a subclass of a Section. Those names can only be
used if the appropriate mechanism name is inserted.

Tom Close
Posts: 18
Joined: Wed Sep 05, 2012 11:59 pm

Re: MWE for apparent bug discovered by PyNN format

Post by Tom Close » Fri Mar 13, 2015 7:47 pm

Thanks Michael, I will let Andrew know so that he can rename 'a_' back to 'a' in the next release of PyNN :)

Post Reply