Changeset 38

Show
Ignore:
Timestamp:
02/01/08 12:55:29 (1 year ago)
Author:
apdavison
Message:

Added more classes to source:/trunk/src/trunk/src/nrnpython/neuron/__init__.py

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/nrnpython/neuron/__init__.py

    r37 r38  
    11""" 
     2This is an updated version of the file neuron/__init__.py which is distributed 
     3with the NEURON distribution. The original file should be replaced with 
     4(a symlink to) this one. 
     5 
    26An attempt to make use of HocObjects more Pythonic, by wrapping them in Python 
    37classes with the same names as the Hoc classes, and adding various typical 
    48Python methods, such as __len__(). 
    59 
    6 $Id: neuron.py 18 2007-05-18 09:08:00Z apdavison
     10$Id
    711""" 
    812 
    913import hoc 
    10 from hoc import HocObject 
    11  
    12 h = hoc.HocObject() 
    13 h('obfunc newlist() { return new List() }')  
     14import nrn 
     15h  = hoc.HocObject() 
     16dt = h.dt 
     17 
     18h('obfunc new_IClamp() { return new IClamp($1) }') 
     19h('obfunc newlist() { return new List() }') 
    1420h('obfunc newvec() { return new Vector($1) }') 
    15  
    16  
    17 class List(object): 
     21h('obfunc new_NetConO() { return new NetCon($o1, $o2, $3, $4, $5) }') 
     22h('obfunc new_NetConP() { return new NetCon("&v($1)", $2, $3, $4, $5) }') 
     23h('obfunc new_File() { return new File() }') 
     24 
     25 
     26# ------------------------------------------------------------------------------ 
     27# Python classes and functions without a Hoc equivalent, mainly for internal 
     28# use within this file. 
     29# ------------------------------------------------------------------------------ 
     30 
     31class HocError(Exception): pass 
     32 
     33class Wrapper(object): 
     34    """Base class to provide attribute access for HocObjects.""" 
     35    def __getattr__(self, name): 
     36        try: 
     37            return self.__getattribute__(name) 
     38        except AttributeError: 
     39            return self.hoc_obj.__getattribute__(name) 
     40      
     41    def __setattr__(self, name, value): 
     42        try: 
     43            object.__setattr__(self, name, value) 
     44        except AttributeError: 
     45            self.hoc_obj.__setattr__(name, value) 
     46 
     47def new_point_process(name): 
     48    """ 
     49    Returns a Python-wrapped hoc class where the object needs to be associated 
     50    with a section. 
     51    """ 
     52    h('obfunc new_%s() { return new %s($1) }' % (name, name)) 
     53    class someclass(Wrapper): 
     54        def __init__(self, section, position=0.5): 
     55            assert 0 <= position <= 1 
     56            section.push() 
     57            self.hoc_obj = getattr(h, 'new_%s' % name)(position) 
     58            h.pop_section() 
     59    someclass.__name__ = name 
     60    return someclass 
     61 
     62def new_hoc_class(name): 
     63    """ 
     64    Returns a Python-wrapped hoc class where the object does not need to be 
     65    associated with a section. 
     66    """ 
     67    h('obfunc new_%s() { return new %s() }' % (name, name)) 
     68    class someclass(Wrapper): 
     69        def __init__(self): 
     70            self.hoc_obj = getattr(h, 'new_%s' % name)() 
     71    someclass.__name__ = name 
     72    return someclass 
     73 
     74# ------------------------------------------------------------------------------ 
     75# Python equivalents to Hoc functions 
     76# ------------------------------------------------------------------------------ 
     77 
     78xopen = h.xopen 
     79quit = h.quit 
     80 
     81def hoc_execute(hoc_commands, comment=None): 
     82    assert isinstance(hoc_commands,list) 
     83    if comment: 
     84        logging.debug(comment) 
     85    for cmd in hoc_commands: 
     86        logging.debug(cmd) 
     87        success = hoc.execute(cmd) 
     88        if not success: 
     89            raise HocError('Error produced by hoc command "%s"' % cmd) 
     90 
     91def hoc_comment(comment): 
     92    logging.debug(comment) 
     93 
     94def psection(section): 
     95    section.push() 
     96    h.psection() 
     97    h.pop_section() 
     98 
     99def init(): 
     100    h.dt = dt 
     101    h.finitialize() 
     102     
     103def run(tstop): 
     104    h('tstop = %g' % tstop) 
     105    h('while (t < tstop) { fadvance() }') 
     106 
     107# ------------------------------------------------------------------------------ 
     108# Python wrappers around Hoc objects 
     109# ------------------------------------------------------------------------------ 
     110 
     111ExpSyn = new_point_process('ExpSyn') 
     112ParallelContext = new_hoc_class('ParallelContext') 
     113NetStim = new_hoc_class('NetStim') 
     114 
     115class List(Wrapper): 
    18116     
    19117    def __init__(self): 
    20118        self.hoc_obj = h.newlist() 
    21119         
    22     def __getattr__(self,name): 
    23         return getattr(self.hoc_obj, name) 
    24      
    25120    def __len__(self): 
    26121        return self.count() 
    27122     
    28123     
    29 class Vector(object): 
     124class Vector(Wrapper): 
     125    n = 0 
    30126     
    31127    def __init__(self,arg=10): 
     128        self.name = 'vector%d' % Vector.n 
     129        Vector.n += 1 
     130        h('objref %s' % self.name) 
    32131        if isinstance(arg,int): 
    33             self.hoc_obj = h.newvec(arg) 
     132            h('%s = new Vector(%d)' % (self.name, arg)) 
     133            self.hoc_obj = getattr(h, self.name) 
    34134        elif isinstance(arg,list): 
    35             self.hoc_obj = h.newvec(len(arg)) 
     135            h('%s = new Vector(%d)' % (self.name, len(arg))) 
     136            self.hoc_obj = getattr(h, self.name) 
    36137            for i,x in enumerate(arg): 
    37138                self.x[i] = x 
    38          
    39     def __getattr__(self,name): 
    40         return getattr(self.hoc_obj, name) 
    41      
     139    
    42140    def __len__(self): 
    43141        return self.size() 
    44      
     142    
    45143    def __str__(self): 
    46144        tmp = self.printf() 
    47145        return '' 
    48      
     146    
    49147    def __repr__(self): 
    50148        tmp = self.printf() 
    51149        return '' 
    52  
    53150 
    54151    # allow array(Vector()) 
     
    56153    def __getitem__(self,i): 
    57154        return self.x[i] 
    58      
    59  
     155    
    60156    def __setitem__(self,i,y): 
    61157        self.x[i] = y 
     
    71167        for ii in xrange(i,j): 
    72168            self.x[ii] = iter.next() 
    73              
    74          
    75  
    76      
     169 
    77170    def tolist(self): 
    78171        return [self.x[i] for i in range(int(self.size()))] 
    79              
     172 
     173    def record(self, section, variable, position=0.5): 
     174        #ref = h.ref(variable) 
     175        #self.hoc_obj.record(ref) 
     176        section.push() 
     177        h('%s.record(&%s(%g))' % (self.name, variable, position)) 
     178        h.pop_section()                       
     179 
     180 
     181class IClamp(object): 
     182       
     183    def __init__(self, section, position=0.5, delay=0, dur=0, amp=0): 
     184        assert 0 <= position <= 1 
     185        section.push() 
     186        self.hoc_obj = h.new_IClamp(position) 
     187        h.pop_section() 
     188        self.delay = delay 
     189        self.dur = dur 
     190        self.amp = amp 
     191         
     192    def __getattr__(self, name): 
     193        if name == "delay": 
     194            return self.hoc_obj.__getattribute__('del') 
     195        elif name in ('amp', 'dur'): 
     196            return self.hoc_obj.__getattribute__(name) 
     197        else: 
     198            return self.__getattribute__(name) 
     199      
     200    def __setattr__(self, name, value): 
     201        if name == "delay": 
     202            self.hoc_obj.__setattr__('del', value) 
     203        elif name in ('amp', 'dur'): 
     204            self.hoc_obj.__setattr__(name, value) 
     205        else: 
     206            object.__setattr__(self, name, value) 
     207 
     208 
     209class NetCon(Wrapper): 
     210     
     211    def __init__(self, source, target, threshold=10, delay=1, weight=0, section=None, position=0.5): 
     212        if section: 
     213            section.push() 
     214            self.hoc_obj = h.new_NetConP(position, target, threshold, delay, weight) 
     215            h.pop_section() 
     216        else: 
     217            self.hoc_obj = h.new_NetConO(source, target, threshold, delay, weight) 
     218        self.section = section 
     219 
     220         
     221class File(Wrapper): 
     222    """Hoc file object with Python-like syntax added.""" 
     223     
     224    def __init__(self, name, mode='r'): 
     225        assert mode in ('r', 'w', 'a') 
     226        self.hoc_obj = h.new_File() 
     227        open_func = getattr(self.hoc_obj, "%sopen" % mode) 
     228        open_func(name) 
     229         
     230    def write(self, s): 
     231        pass 
     232         
     233open = File # just an alias