Changeset 5

Show
Ignore:
Timestamp:
04/11/07 16:27:46 (2 years ago)
Author:
davison
Message:

Added get to nrnpy_hoc to efficiently retreive vars from hoc to python
Currently, double[n], Vectors and strings are supported.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/ivoc/ivocvect.h

    r1 r5  
    44// definition of vector classes from the gnu c++ class library 
    55#include <d_avec.h>   
     6 
    67 
    78#define ParentVect doubleAVec 
     
    5253extern char* vector_get_label(Vect*); 
    5354extern void vector_set_label(Vect*, char*); 
     55 
     56 
     57  // extern PyArrayObject* vector_numpy(Vect*); 
     58 
    5459} 
    5560 
  • trunk/src/nrnpython/Makefile.am

    r1 r5  
    44NRNPYTHON_INCLUDES = @NRNPYTHON_INCLUDES@ 
    55IV_INCLUDES = @IV_INCLUDE@ $(X_CFLAGS) 
    6 INCLUDES =  -I. -I$(nsrc)/nrniv -I$(nsrc)/ivoc -I$(nsrc)/nrnoc -I$(nsrc)/oc $(NRNPYTHON_INCLUDES) $(IV_INCLUDES) 
     6INCLUDES =  -I. -I$(nsrc)/nrniv -I$(nsrc)/ivoc -I$(nsrc)/nrnoc -I$(nsrc)/oc -I$(nsrc)/gnu $(NRNPYTHON_INCLUDES) $(IV_INCLUDES) 
    77AM_CPPFLAGS = -DOOP=1 -DCABLE=1 -DUSECVODE=1 -DUSEMATRIX=1 -DUSEBBS=1 
    88 
  • trunk/src/nrnpython/nrnpy_hoc.cpp

    r1 r5  
    33#include <nrnoc2iv.h> 
    44#include <ivoc.h> 
     5#include <ivocvect.h> 
     6#include <parse.h> 
     7 
     8#define PY_ARRAY_UNIQUE_SYMBOL _NEURON_arrayu 
     9//#define NO_IMPORT_ARRAY 
     10// Numeric Python header 
     11#include "numpy/arrayobject.h" 
     12 
     13// export NUMPY_INCLUDEPATH=`python -c "import numpy;print numpy.__path__[0]+'/core/include'"` 
     14// export CFLAGS="$CFLAGS -I$NUMPY_INCLUDEPATH" 
     15 
     16 
    517 
    618extern "C" { 
     19 
     20Symlist *hoc_built_in_symlist, *hoc_top_level_symlist; 
     21int hoc_total_array(Symbol *s); /* total number of elements in array pointer */ 
     22 
     23  //Symbol *hoc_table_lookup(const char *s, Symlist *tab); 
     24 
     25 
    726 
    827static PyObject* nrnexec(PyObject* self, PyObject* args) { 
    928        const char* cmd; 
    1029        if (!PyArg_ParseTuple(args, "s", &cmd)) { 
    11                 return NULL; 
     30          PyErr_SetString(PyExc_RuntimeError,"hoc.nrnexec error parsing args."); 
     31          return NULL; 
    1232        } 
    1333        boolean b = Oc::valid_stmt(cmd, 0); 
     
    1636 
    1737static  PyObject* hoc_ac(PyObject* self, PyObject* args) { 
    18         PyArg_ParseTuple(args, "|d", &hoc_ac_); 
    19         return Py_BuildValue("d", hoc_ac_); 
    20 
     38 
     39  if (!PyArg_ParseTuple(args, "|d", &hoc_ac_)) { 
     40        PyErr_SetString(PyExc_RuntimeError,"hoc.hoc_ac error parsing args."); 
     41        return NULL; 
     42  } 
     43 
     44  return Py_BuildValue("d", hoc_ac_); 
     45
     46 
     47static PyObject* hoc_gettype(PyObject* self, PyObject* args) { 
     48  const char* name; 
     49  if (!PyArg_ParseTuple(args, "s", &name)) { 
     50    PyErr_SetString(PyExc_RuntimeError,"hoc.get error parsing args."); 
     51    return NULL; 
     52  } 
     53 
     54  Symbol* sym; 
     55  sym = hoc_table_lookup(name, hoc_top_level_symlist); 
     56  if (!sym) { 
     57    sym = hoc_table_lookup(name, hoc_built_in_symlist); 
     58                 
     59    if (!sym) { 
     60      PyErr_SetString(PyExc_RuntimeError,"hoc.get hoc name not defined."); 
     61      return NULL; 
     62 
     63    } 
     64 
     65  } 
     66         
     67         
     68 
     69 
     70  // return type 
     71 
     72  return Py_BuildValue("i", sym->type); 
     73
     74 
     75 
     76static PyObject* PyObj_FromNrnObj(Object* obj) { 
     77 
     78  if (obj==NULL) { 
     79    printf("Warning: PyObj_FromNrnObj obj NULL\n"); 
     80    //return null; 
     81    Py_INCREF(Py_None); 
     82    return Py_None; 
     83  } 
     84   
     85 
     86  if (is_obj_type(obj,"Vector")) { 
     87    // we can deal with vectors 
     88    Vect* v = (Vect*)obj->u.this_pointer; 
     89    PyArrayObject*array = NULL; 
     90    int i,n = v->capacity(); 
     91 
     92    array = (PyArrayObject*)PyArray_FromDims(1,&n,PyArray_DOUBLE); 
     93    for (i=0;i<n;i++) { 
     94      *(double*)(array->data + i*array->strides[0]) = (*v)[i]; 
     95    } 
     96 
     97    return (PyObject*)array; 
     98 
     99  } 
     100 
     101  printf("Warning: PyObj_FromNrnObj cannot handle obj type, returning NULL\n"); 
     102  //return NULL; 
     103  Py_INCREF(Py_None); 
     104  return Py_None; 
     105   
     106
     107 
     108static PyObject* hoc_get(PyObject* self, PyObject* args) { 
     109        const char* name; 
     110        if (!PyArg_ParseTuple(args, "s", &name)) { 
     111          PyErr_SetString(PyExc_RuntimeError,"hoc.get error parsing args."); 
     112          return NULL; 
     113        } 
     114 
     115        Symbol* sym; 
     116        sym = hoc_table_lookup(name, hoc_top_level_symlist); 
     117        if (!sym) { 
     118                sym = hoc_table_lookup(name, hoc_built_in_symlist); 
     119 
     120                if (!sym) { 
     121                  PyErr_SetString(PyExc_RuntimeError,"hoc.get hoc name not defined."); 
     122                  return NULL; 
     123 
     124                } 
     125 
     126 
     127        } 
     128 
     129        // switch on type 
     130 
     131        PyObject *pObj = NULL; 
     132 
     133        if (sym->type == STRING) { 
     134          //printf("narg=%d",sym->narg); 
     135          //double * p = hoc_objectdata[sym->u.oboff].pval 
     136          pObj = PyString_FromString(*OPSTR(sym)); 
     137        } 
     138        else if (sym->type == VAR) { 
     139 
     140          if (ISARRAY(sym)) { 
     141 
     142            // Make a numpy array from an ndim NEURON array 
     143 
     144            int total = hoc_total_array(sym); 
     145            PyArrayObject* array = NULL; 
     146            int i; 
     147 
     148            Arrayinfo* a = sym->arayinfo; 
     149            double* p = OPVAL(sym); 
     150           
     151            if (a) { 
     152              PyObject* pDims = PyList_New(a->nsub); 
     153 
     154              for (i= a->nsub-1;i>=0;--i) { 
     155                PyList_SetItem(pDims,i,PyInt_FromLong(a->sub[i])); 
     156              } 
     157 
     158              // first contiguous, then reshape 
     159              array = (PyArrayObject*)PyArray_FromDims(1,&total,PyArray_DOUBLE); 
     160              if (array==NULL) { 
     161                PyErr_SetString(PyExc_RuntimeError,"hoc.get hoc error allocating array."); 
     162                return NULL; 
     163              } 
     164 
     165              // fill array memory 
     166 
     167              for (i=0;i<total;i++) { 
     168                *(double*)(array->data + i*array->strides[0]) = p[i]; 
     169              } 
     170 
     171              // return shaped array 
     172 
     173              pObj = (PyObject*)PyArray_Reshape(array,pDims); 
     174 
     175            } 
     176 
     177          } 
     178          else { 
     179            // VAR is not an array 
     180 
     181            pObj = PyFloat_FromDouble(*OPVAL(sym)); 
     182          } 
     183 
     184        } 
     185        else if (sym->type == OBJECTVAR) { 
     186 
     187          if (ISARRAY(sym)) { 
     188 
     189            // create numpy array of type 'O' (PyObjects) from NEURON OBJREF array 
     190 
     191            int total = hoc_total_array(sym); 
     192            PyArrayObject* array = NULL; 
     193            int i; 
     194 
     195            Arrayinfo* a = sym->arayinfo; 
     196 
     197            if (a) { 
     198              PyObject* pDims = PyList_New(a->nsub); 
     199 
     200              for (i= a->nsub-1;i>=0;--i) { 
     201                PyList_SetItem(pDims,i,PyInt_FromLong(a->sub[i])); 
     202              } 
     203 
     204 
     205              // first contiguous, then reshape 
     206 
     207              array = (PyArrayObject*)PyArray_FromDims(1,&total,PyArray_OBJECT); 
     208              if (array==NULL) { 
     209                PyErr_SetString(PyExc_RuntimeError,"hoc.get hoc error allocating array."); 
     210                return NULL; 
     211              } 
     212 
     213              // fill array memory 
     214 
     215              for (i=0;i<total;i++) { 
     216                *(PyObject**)(array->data + i*array->strides[0]) = PyObj_FromNrnObj(OPOBJ(sym)[i]); 
     217              } 
     218 
     219              // return shaped array 
     220 
     221              pObj = (PyObject*)PyArray_Reshape(array,pDims); 
     222               
     223              if (pObj==NULL) { 
     224                PyErr_SetString(PyExc_RuntimeError,"hoc.get hoc error reshaping array."); 
     225                return NULL; 
     226              } 
     227 
     228 
     229            } 
     230 
     231          } 
     232          else { 
     233            // return single object 
     234            pObj = PyObj_FromNrnObj(*OPOBJ(sym)); 
     235          } 
     236 
     237 
     238        } 
     239        else { 
     240                  PyErr_SetString(PyExc_RuntimeError,"hoc.get unsuported hoc type."); 
     241                  return NULL; 
     242        } 
     243 
     244 
     245        if (pObj==NULL) { 
     246                  PyErr_SetString(PyExc_RuntimeError,"hoc.get unexpected *pObj==NULL."); 
     247                  return NULL; 
     248        } 
     249 
     250        return Py_BuildValue("N", pObj); 
     251
     252 
     253 
     254 
    21255 
    22256static PyMethodDef HocMethods[] = { 
    23257        {"execute", nrnexec, METH_VARARGS, "Execute a hoc command, return 1 on success, 0 on failure." }, 
    24258        {"hoc_ac", hoc_ac, METH_VARARGS, "Get (or set) the scalar hoc_ac_." }, 
     259        {"get",hoc_get,METH_VARARGS,"Get hoc name and convert to a python data type"}, 
     260        {"gettype",hoc_get,METH_VARARGS,"Get hoc name type "}, 
    25261        {NULL, NULL, 0, NULL} 
    26262}; 
    27263 
    28264myPyMODINIT_FUNC nrnpy_hoc() { 
    29         Py_InitModule("hoc", HocMethods); 
    30 
     265  PyObject *m; 
     266  m = Py_InitModule("hoc", HocMethods); 
     267 
     268  if (m==NULL) { 
     269    PyErr_SetString(PyExc_RuntimeError,"nynpy.hoc failure on Py_InitModule."); 
     270    return; 
     271  } 
     272 
     273   
     274  /* we need the numeric array type */ 
     275  // setup for Numeric Python 
     276  import_array(); 
     277 
     278
     279 
    31280 
    32281}//end of extern c 
    33