3 #include <structmember.h> 9 #define M_PI (3.14159265358979323846) 27 extern PyObject*
nrn_ptr_richcmp(
void* self_ptr,
void* other_ptr,
int op);
107 extern PyObject*
nrnpy_forall(PyObject*
self, PyObject* args);
126 extern char* (*nrnpy_pysec_name_p_)(Section*);
128 extern Object* (*nrnpy_pysec_cell_p_)(Section*);
136 PyErr_SetString(PyExc_ReferenceError,
"can't access a deleted section");
140 static char buf[512];
144 char* cp = buf + strlen(buf);
149 sprintf(buf,
"__nrnsec_%p", sec);
158 PyObject* cell_weakref =
161 PyObject*
cell = PyWeakref_GetObject(cell_weakref);
165 }
else if (cell != Py_None) {
177 if (!PyObject_HasAttrString(obj,
"sec")) {
181 obj_sec = PyObject_GetAttrString(obj,
"sec");
183 result = PyObject_RichCompareBool(sec, obj_sec, Py_EQ);
192 PyObject*
cell = PyWeakref_GetObject(cell_weakref);
209 delete[]
self->name_;
211 Py_XDECREF(self->cell_weakref_);
212 if (self->sec_->prop) {
215 if (self->sec_->prop && !self->sec_->prop->dparam[0].sym) {
216 sec_free(self->sec_->prop->dparam[8].itm);
221 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
226 Py_XDECREF(self->pysec_);
227 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
232 Py_XDECREF(self->pysec_);
233 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
238 Py_XDECREF(self->pysec_);
239 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
244 Py_XDECREF(self->pymech_);
245 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
250 Py_XDECREF(self->pyseg_);
251 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
256 Py_XDECREF(self->pyseg_);
257 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
262 Py_XDECREF(self->pymech_);
263 ((PyObject*)
self)->ob_type->tp_free((PyObject*)
self);
278 static const char* kwlist[] = {
"name",
"cell",
NULL};
279 if (
self !=
NULL && !self->sec_) {
281 delete[]
self->name_;
284 self->cell_weakref_ = 0;
289 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|sO", (
char**)kwlist,
293 if (cell && cell != Py_None) {
294 self->cell_weakref_ = PyWeakref_NewRef(cell,
NULL);
295 if (!self->cell_weakref_) {
302 size_t n = strlen(name) + 1;
307 cell = PyObject_Str(cell);
309 Py_XDECREF(self->cell_weakref_);
315 str.
set_pyerr(PyExc_TypeError,
"cell name contains non ascii character");
318 char* cp = str.
c_str();
320 self->name_ =
new char[
n];
321 sprintf(self->name_,
"%s.%s", cp, name);
323 self->name_ =
new char[
n];
324 strcpy(self->name_, name);
337 if (
self !=
NULL && !self->pysec_) {
341 self->allseg_iter_ = 0;
342 self->pysec_ = pysec;
350 self = (
NPySecObj*)type->tp_alloc(type, 0);
358 return (PyObject*)
self;
372 return (PyObject*)
self;
383 if (!PyArg_ParseTuple(args,
"O!d",
psection_type, &pysec, &x)) {
386 if (x > 1.0 && x < 1.0001) {
389 if (x < 0. || x > 1.0) {
390 PyErr_SetString(PyExc_ValueError,
"segment position range is 0 <= x <= 1");
394 self = (
NPySegObj*)type->tp_alloc(type, 0);
399 Py_INCREF(self->pysec_);
401 return (PyObject*)
self;
416 Py_INCREF(self->pyseg_);
418 return (PyObject*)
self;
429 self->attr_from_sec_ = 0;
431 return (PyObject*)
self;
438 if (!PyArg_ParseTuple(args,
"O!d",
psection_type, &pysec, &x)) {
441 if (x > 1.0 && x < 1.0001) {
444 if (x < 0. || x > 1.0) {
445 PyErr_SetString(PyExc_ValueError,
"segment position range is 0 <= x <= 1");
450 Py_DECREF(self->pysec_);
452 self->pysec_ = pysec;
458 if (!o || o->ctemplate->sym != nrnpy_pyobj_sym_) {
469 if (o->ctemplate->sym !=nrnpy_pyobj_sym_) {
481 if (o->ctemplate->sym != nrnpy_pyobj_sym_) {
490 if (!(*psec)->prop) {
491 hoc_execerr_ext(
"nrn.Segment associated with deleted internal Section");
498 bool free_po =
false;
499 if (o->ctemplate->sym != nrnpy_pyobj_sym_) {
500 hoc_execerror(
"not a Python nrn.Segment, rxd.node, or other with a segment property", 0);
504 if (PyList_Check(po)) {
505 if (PyList_Size(po) != 1) {
506 hoc_execerror(
"If a list is supplied, it must be of length 1", 0);
508 PyObject* old_po = po;
510 po = PyList_GetItem(po, 0);
515 if (!PyObject_HasAttrString(po,
"segment")) {
519 hoc_execerror(
"not a Python nrn.Segment, rxd.node, or other with a segment property", 0);
523 po = PyObject_GetAttrString(obj,
"segment");
537 if (!(*psec)->prop) {
538 hoc_execerr_ext(
"nrn.Segment associated with deleted internal Section");
550 Py_XDECREF(self->pyseg_);
551 self->pyseg_ = pyseg;
571 Section*
sec =
self->sec_;
574 if (!PyArg_ParseTuple(args,
"i", &i0)) {
577 if (i0 < 0 || i0 >= sec->
npt3d) {
578 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
587 Section*
sec =
self->sec_;
590 Py_ssize_t
narg = PyTuple_GET_SIZE(args);
592 if (!PyArg_ParseTuple(args,
"i", &req)) {
597 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
605 Section*
sec =
self->sec_;
608 double x, y, z, diam;
609 Py_ssize_t
narg = PyTuple_GET_SIZE(args);
611 if (!PyArg_ParseTuple(args,
"id", &i, &diam)) {
614 if (i < 0 || i >= sec->
npt3d) {
615 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
620 else if (narg == 5) {
621 if (!PyArg_ParseTuple(args,
"idddd", &i, &x, &y, &z, &diam)) {
624 if (i < 0 || i >= sec->
npt3d) {
625 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
630 PyErr_SetString(PyExc_Exception,
"Wrong number of arguments\n");
637 Section*
sec =
self->sec_;
641 if (!PyArg_ParseTuple(args,
"idddd", &i, &x, &y, &z, &d)) {
644 if (i < 0 || i > sec->
npt3d) {
645 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
653 Section*
sec =
self->sec_;
657 if (!PyArg_ParseTuple(args,
"dddd", &x, &y, &z, &d)) {
665 Section*
sec =
self->sec_;
669 Py_ssize_t
narg = PyTuple_GET_SIZE(args);
673 if (!PyArg_ParseTuple(args,
"i", &style)) {
677 PyErr_SetString(PyExc_AttributeError,
"If exactly one argument, it must be 0.");
681 }
else if (narg == 4) {
684 if (!PyArg_ParseTuple(args,
"iddd", &style, &x, &y, &z)) {
690 PyErr_SetString(PyExc_Exception,
"Wrong number of arguments.");
703 Section*
sec =
self->sec_;
706 if (!PyArg_ParseTuple(args,
"i", &i)) {
710 if (i < 0 || i > n) {
711 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
714 return PyFloat_FromDouble((
double)sec->
pt3d[i].
x);
719 Section*
sec =
self->sec_;
722 if (!PyArg_ParseTuple(args,
"i", &i)) {
726 if (i < 0 || i > n) {
727 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
730 return PyFloat_FromDouble((
double)sec->
pt3d[i].
y);
735 Section*
sec =
self->sec_;
738 if (!PyArg_ParseTuple(args,
"i", &i)) {
742 if (i < 0 || i > n) {
743 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
746 return PyFloat_FromDouble((
double)sec->
pt3d[i].
z);
752 Section*
sec =
self->sec_;
755 if (!PyArg_ParseTuple(args,
"i", &i)) {
759 if (i < 0 || i > n) {
760 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
763 return PyFloat_FromDouble((
double)sec->
pt3d[i].
arc);
769 Section*
sec =
self->sec_;
772 if (!PyArg_ParseTuple(args,
"i", &i)) {
776 if (i < 0 || i > n) {
777 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
780 return PyFloat_FromDouble((
double)
fabs(sec->
pt3d[i].
d));
786 Section*
sec =
self->sec_;
789 if (!PyArg_ParseTuple(args,
"i", &i)) {
793 if (i < 0 || i > n) {
794 PyErr_SetString(PyExc_Exception,
"Arg out of range\n");
797 if (sec->
pt3d[i].
d < 0) {
815 char*
name =
new char[strlen(sname) + 100];
816 sprintf(name,
"%s(%g)", sname, pyseg->
x_);
827 sprintf(buf,
"__nrnsec_%p", self->sec_);
835 if (!PyArg_ParseTuple(args,
"O", &po)) {
838 if (PyCallable_Check(po) == 0) {
839 PyErr_SetString(PyExc_TypeError,
"argument must be a callable");
854 PyObject* arglist = Py_BuildValue(
"(O)",
self);
865 if (self->sec_->prop && self->sec_->prop->dparam[
PROP_PY_INDEX]._pvoid) {
872 if (!sec || !sec->
prop) {
897 return (PyObject*)seg;
909 Section* psec =
self->sec_->parentsec;
919 Section*
sec =
self->sec_;
921 Section* psec =
NULL;
945 return Py_BuildValue(
"d", x);
953 if (PyList_Append(sl, item) != 0) {
961 for (Section*
s = sec->
child;
s;
s =
s->sibling) {
970 Section*
const sec =
self->sec_;
972 PyObject*
const result = PyList_New(0);
984 for (Section*
s = sec->
child;
s;
s =
s->sibling) {
993 Section*
const sec =
self->sec_;
995 PyObject*
const result = PyList_New(0);
1003 Section*
sec =
self->sec_;
1006 PyObject*
result = PyList_New(0);
1016 if (self->cell_weakref_) {
1017 result = PyWeakref_GET_OBJECT(self->cell_weakref_);
1019 }
else if (self->sec_->prop && self->sec_->prop->dparam[6].obj) {
1020 result =
nrnpy_ho2po(self->sec_->prop->dparam[6].obj);
1042 void* other_ptr = (
void*)other;
1053 void* self_ptr = (
void*)(self->sec_);
1054 void* other_ptr = (
void*)other;
1056 void* self_ptr = (
void*)(self->sec_);
1057 other_ptr = (
void*)(((
NPySecObj*)other)->sec_);
1064 Py_INCREF(Py_NotImplemented);
1065 return Py_NotImplemented;
1070 if (PyArg_ParseTuple(args,
"O", &pysec)) {
1072 if (((
NPySecObj*)pysec)->sec_ == self->sec_) {
1091 if (self->prop_ &&
nrn_is_ion(self->prop_->type)) {
1101 result = (PyObject*)(self->pyseg_);
1110 if (sec && sec->
prop) {
1121 sprintf(buf,
"_ref_%s", self->sym_->name);
1128 PyErr_SetString(PyExc_ReferenceError,
"no Symbol");
1136 if (self->pymech_) {
1137 result = (PyObject*)self->pymech_;
1147 double parentx, childend;
1150 if (!PyArg_ParseTuple(args,
"O|dd", &p, &parentx, &childend)) {
1155 if (parentx == -1000.) {
1160 if (parentx != -1000.) {
1165 PyErr_SetString(PyExc_TypeError,
1166 "first arg not a nrn.Section or nrn.Segment");
1172 if (parentx > 1. || parentx < 0.) {
1173 PyErr_SetString(PyExc_ValueError,
"out of range 0 <= parentx <= 1.");
1176 if (childend != 0. && childend != 1.) {
1177 PyErr_SetString(PyExc_ValueError,
"child connection end must be 0 or 1");
1186 return (PyObject*)
self;
1192 PyObject *tpyobj, *tpyobj2;
1193 if (!PyArg_ParseTuple(args,
"s", &tname)) {
1196 if (PyArg_ParseTuple(args,
"O", &tpyobj)) {
1198 Py_INCREF((PyObject*)
self);
1199 tpyobj2 = PyObject_CallMethod(tpyobj,
"insert",
"O", (PyObject*)
self);
1201 if (tpyobj2 ==
NULL) {
1202 Py_DECREF((PyObject*)
self);
1204 PyErr_SetString(PyExc_TypeError,
"insert argument must be either a string or an object with an insert method");
1208 return (PyObject*)
self;
1211 PyErr_SetString(PyExc_TypeError,
"insert takes a single positional argument");
1214 PyObject* otype = PyDict_GetItemString(
pmech_types, tname);
1221 PyErr_SetString(PyExc_ValueError,
1222 "argument not a density mechanism name.");
1230 return (PyObject*)
self;
1236 if (!PyArg_ParseTuple(args,
"s", &tname)) {
1239 PyObject* otype = PyDict_GetItemString(
pmech_types, tname);
1246 PyErr_SetString(PyExc_ValueError,
1247 "argument not a density mechanism name.");
1255 return (PyObject*)
self;
1260 char* mechanism_name;
1262 if (!PyArg_ParseTuple(args,
"s", &mechanism_name)) {
1265 result =
has_membrane(mechanism_name, self->sec_) ? Py_True : Py_False;
1282 return (PyObject*)
self;
1290 if (segiter ==
NULL) {
1297 return (PyObject*)segiter;
1307 return (PyObject*)ai;
1312 self->allseg_iter_ = -1;
1313 return (PyObject*)
self;
1319 if (self->allseg_iter_ > n1) {
1328 seg->
pysec_ =
self->pysec_;
1329 Py_INCREF(self->pysec_);
1330 if (self->allseg_iter_ == -1) {
1332 }
else if (self->allseg_iter_ == n1) {
1335 seg->
x_ = (double(self->allseg_iter_) + 0.5) / ((double)n1);
1337 ++
self->allseg_iter_;
1338 return (PyObject*)seg;
1344 if (self->seg_iter_ >= n1) {
1353 seg->
pysec_ =
self->pysec_;
1354 Py_INCREF(self->pysec_);
1355 seg->
x_ = (double(self->seg_iter_) + 0.5) / ((double)n1);
1357 return (PyObject*)seg;
1361 Section*
sec =
self->pysec_->sec_;
1364 PyObject*
result = PyList_New(0);
1369 int err = PyList_Append(result, item);
1378 Section*
sec =
self->pysec_->sec_;
1386 Section*
sec =
self->pysec_->sec_;
1391 double x =
self->x_;
1393 if (x > 0. && x < 1.) {
1397 PyObject*
result = Py_BuildValue(
"d", a);
1403 return length * (d0 * d0 + d0 * d1 + d1 * d1);
1406 static inline double interpolate(
double x0,
double x1,
double y0,
double y1,
double xnew) {
1413 return y0 + (y1 - y0) * (xnew - x0) / (x1 - x0);
1422 while (right - left > 1) {
1423 int mid = (left +
right) / 2;
1434 Section*
sec =
self->pysec_->sec_;
1440 double x =
self->x_;
1443 if (x > 0. && x < 1.) {
1445 int nseg = sec->
nnode - 1;
1447 int iseg = x * nseg;
1448 double seg_left_arc = iseg * length;
1449 double seg_right_arc = (iseg + 1) * length;
1450 if (sec->
npt3d > 1) {
1452 double left_diam =
fabs(sec->
pt3d[i_left].
d);
1453 double right_diam =
fabs(sec->
pt3d[i_left + 1].
d);
1454 double left_arc = seg_left_arc;
1457 for (i = i_left + 1; i < sec->
npt3d && sec->
pt3d[
i].
arc < seg_right_arc; i++) {
1461 left_diam = right_diam;
1463 if (i < sec->npt3d) {
1475 double diam =
p->param[0];
1476 a =
M_PI * diam * diam / 4 * length;
1482 PyObject*
result = Py_BuildValue(
"d", a);
1488 Section*
sec =
self->pysec_->sec_;
1498 PyObject*
result = Py_BuildValue(
"d", ri);
1520 Section*
sec =
self->pysec_->sec_;
1522 PyErr_SetString(PyExc_ReferenceError,
"nrn.Segment can't access a deleted section");
1532 return (PyObject*)m;
1576 sprintf(buf,
"%s was not made to point to anything at %s(%g)", n,
1578 }
else if (err == 1) {
1579 sprintf(buf,
"%s, the mechanism does not exist at %s(%g)", n,
secname(sec),
1584 PyErr_SetString(PyExc_AttributeError, buf);
1601 Section*
sec =
self->sec_;
1608 name.
set_pyerr(PyExc_TypeError,
"attribute name must be a string");
1614 if (strcmp(n,
"L") == 0) {
1616 }
else if (strcmp(n,
"Ra") == 0) {
1617 result = Py_BuildValue(
"d",
nrn_ra(sec));
1618 }
else if (strcmp(n,
"nseg") == 0) {
1619 result = Py_BuildValue(
"i", sec->
nnode - 1);
1624 result = (PyObject*)r;
1635 result = Py_BuildValue(
"d", *d);
1638 }
else if (strcmp(n,
"rallbranch") == 0) {
1640 }
else if (strcmp(n,
"__dict__") == 0) {
1641 result = PyDict_New();
1642 int err = PyDict_SetItemString(result,
"L", Py_None);
1644 err = PyDict_SetItemString(result,
"Ra", Py_None);
1646 err = PyDict_SetItemString(result,
"nseg", Py_None);
1648 err = PyDict_SetItemString(result,
"rallbranch", Py_None);
1651 result = PyObject_GenericGetAttr((PyObject*)
self, pyname);
1659 Section*
sec =
self->sec_;
1661 PyErr_SetString(PyExc_ReferenceError,
"can't access a deleted section");
1670 name.
set_pyerr(PyExc_TypeError,
"attribute name must be a string");
1675 if (strcmp(n,
"L") == 0) {
1677 if (PyArg_Parse(value,
"d", &x) == 1 && x > 0.) {
1685 PyErr_SetString(PyExc_ValueError,
"L must be > 0.");
1688 }
else if (strcmp(n,
"Ra") == 0) {
1690 if (PyArg_Parse(value,
"d", &x) == 1 && x > 0.) {
1695 PyErr_SetString(PyExc_ValueError,
"Ra must be > 0.");
1698 }
else if (strcmp(n,
"nseg") == 0) {
1700 if (PyArg_Parse(value,
"i", &nseg) == 1 && nseg > 0 && nseg <= 32767) {
1703 PyErr_SetString(PyExc_ValueError,
"nseg must be an integer in range 1 to 32767");
1711 PyErr_SetString(PyExc_IndexError,
"missing index");
1719 }
else if (!PyArg_Parse(value,
"d", d)) {
1720 PyErr_SetString(PyExc_ValueError,
"bad value");
1727 }
else if (strcmp(n,
"rallbranch") == 0) {
1729 if (PyArg_Parse(value,
"d", &x) == 1 && x > 0.) {
1734 PyErr_SetString(PyExc_ValueError,
"rallbranch must be > 0");
1738 err = PyObject_GenericSetAttr((PyObject*)
self, pyname, value);
1754 m->
pyseg_ =
self->pyseg_;
1757 self->prop_ = p->
next;
1758 return (PyObject*)m;
1762 Section*
sec =
self->pyseg_->pysec_->sec_;
1764 PyErr_SetString(PyExc_ReferenceError,
"nrn.Mechanism can't access a deleted section");
1777 return (PyObject*)vmi;
1781 if (self->i_ >= self->msym_->s_varn) {
1793 return (PyObject*)r;
1797 Section*
sec =
self->pysec_->sec_;
1799 PyErr_SetString(PyExc_ReferenceError,
"nrn.Segment can't access a deleted section");
1807 name.
set_pyerr(PyExc_TypeError,
"attribute name must be a string");
1813 PyObject* otype =
NULL;
1814 PyObject* rv =
NULL;
1815 if (strcmp(n,
"v") == 0) {
1817 result = Py_BuildValue(
"d",
NODEV(nd));
1834 result = (PyObject*)m;
1847 result = (PyObject*)r;
1858 result = Py_BuildValue(
"d", *d);
1861 }
else if (strncmp(n,
"_ref_", 5) == 0) {
1862 if (strcmp(n + 5,
"v") == 0) {
1866 sym->
type == RANGEVAR) {
1875 result = (PyObject*)r;
1890 }
else if (strcmp(n,
"__dict__") == 0) {
1892 result = PyDict_New();
1893 int err = PyDict_SetItemString(result,
"v", Py_None);
1895 PyDict_SetItemString(result,
"diam", Py_None);
1897 PyDict_SetItemString(result,
"cm", Py_None);
1902 err = PyDict_SetItemString(result, pn, Py_None);
1907 result = PyObject_GenericGetAttr((PyObject*)
self, pyname);
1922 PyErr_SetString(PyExc_ValueError,
"must be a hoc pointer");
1926 PyErr_SetString(PyExc_AttributeError,
" For assignment, only POINTER var can have a _ref_ prefix");
1934 Section*
sec =
self->pysec_->sec_;
1936 PyErr_SetString(PyExc_ReferenceError,
"nrn.Segment can't access a deleted section");
1946 name.
set_pyerr(PyExc_TypeError,
"attribute name must be a string");
1951 if (strcmp(n,
"x") == 0) {
1954 if (PyArg_Parse(value,
"d", &x) == 1 && x > 0. && x <= 1.) {
1957 }
else if (x > 1. - 1
e-9) {
1963 PyErr_SetString(PyExc_ValueError,
"x must be in range 0. to 1.");
1970 sprintf(s,
"%s needs an index for assignment", sym->
name);
1971 PyErr_SetString(PyExc_IndexError, s);
1981 if (!PyArg_Parse(value,
"d", d)) {
1982 PyErr_SetString(PyExc_ValueError,
"bad value");
1989 }
else if (sym->
u.
rng.type == EXTRACELL && sym->
u.
rng.index == 0) {
1994 }
else if (strncmp(n,
"_ref_", 5) == 0) {
1996 if (rvsym && rvsym->
type == RANGEVAR) {
2003 err = PyObject_GenericSetAttr((PyObject*)
self, pyname, value);
2006 err = PyObject_GenericSetAttr((PyObject*)
self, pyname, value);
2013 int nlen = strlen(n);
2014 int mlen = strlen(m);
2015 int u = nlen - mlen - 1;
2016 if (u > 0 && n[u] ==
'_') {
2017 if (strcmp(n+(u+1), m) != 0) {
2020 strncpy(buf, n, sz);
2028 Section*
sec =
self->pyseg_->pysec_->sec_;
2030 PyErr_SetString(PyExc_ReferenceError,
"nrn.Mechanism can't access a deleted section");
2038 name.
set_pyerr(PyExc_TypeError,
"attribute name must be a string");
2045 int isptr = (strncmp(n,
"_ref_", 5) == 0);
2047 int mnamelen = strlen(mname);
2048 int bufsz = strlen(n) + mnamelen + 2;
2049 char *
buf =
new char[bufsz];
2051 strcpy(buf, isptr ? n + 5 : n);
2053 sprintf(buf,
"%s_%s", isptr ? n + 5 : n, mname);
2062 Py_INCREF(self->pyseg_);
2066 result = (PyObject*)r;
2074 result = Py_BuildValue(
"d", *px);
2077 }
else if (strcmp(n,
"__dict__") == 0) {
2078 result = PyDict_New();
2081 strcpy(buf,
s->name);
2083 int err = PyDict_SetItemString(result, buf, Py_None);
2087 result = PyObject_GenericGetAttr((PyObject*)
self, pyname);
2095 Section*
sec =
self->pyseg_->pysec_->sec_;
2097 PyErr_SetString(PyExc_ReferenceError,
"nrn.Mechanism can't access a deleted section");
2106 name.
set_pyerr(PyExc_TypeError,
"attribute name must be a string");
2112 int isptr = (strncmp(n,
"_ref_", 5) == 0);
2114 int mnamelen = strlen(mname);
2115 int bufsz = strlen(n) + mnamelen + 2;
2116 char *
buf =
new char[bufsz];
2118 strcpy(buf, isptr ? n + 5 : n);
2120 sprintf(buf,
"%s_%s", isptr ? n + 5 : n, mname);
2131 if (PyArg_Parse(value,
"d", &x) == 1) {
2134 PyErr_SetString(PyExc_ValueError,
"must be a double");
2143 err = PyObject_GenericSetAttr((PyObject*)
self, pyname, value);
2172 PyArg_ParseTuple(args,
"|d", &x);
2173 PyObject* segargs = Py_BuildValue(
"(O,d)",
self, x);
2192 PyErr_SetString(PyExc_ReferenceError,
"nrn.RangeVar can't access a deleted section");
2197 if (ix < 0 || ix >=
rv_len(
self)) {
2198 PyErr_SetString(PyExc_IndexError, r->
sym_->
name);
2212 result = Py_BuildValue(
"d", *d);
2220 PyErr_SetString(PyExc_ReferenceError,
"nrn.RangeVar can't access a deleted section");
2224 if (ix < 0 || ix >=
rv_len(
self)) {
2225 PyErr_SetString(PyExc_IndexError, r->
sym_->
name);
2239 if (!PyArg_Parse(value,
"d", &x)) {
2240 PyErr_SetString(PyExc_ValueError,
"bad value");
2247 if (!PyArg_Parse(value,
"d", d)) {
2248 PyErr_SetString(PyExc_ValueError,
"bad value");
2260 "Section name (same as hoc secname())"},
2262 "Section name (same as hoc secname())"},
2264 "Returns True if the section's membrane has this density mechanism.\nThis " 2265 "is not for point processes."},
2267 "childSection.connect(parentSection, [parentX], [childEnd]) " 2268 "or\nchildSection.connect(parentSegment, [childEnd])"},
2270 "section.insert(densityMechanismName) e.g. soma.insert('hh')"},
2272 "section.uninsert(densityMechanismName) e.g. soma.insert('hh')"},
2274 "section.push() makes it the currently accessed section. Should end with " 2275 "a corresponding hoc.pop_section()"},
2276 {
"allseg", (PyCFunction)
allseg, METH_VARARGS,
2277 "iterate over segments. Includes x=0 and x=1 zero-area nodes in the " 2279 {
"cell", (PyCFunction)
pysec2cell, METH_NOARGS,
2280 "Return the object that owns the Section. Possibly None."},
2281 {
"same", (PyCFunction)
pysec_same, METH_VARARGS,
2282 "sec1.same(sec2) returns True if sec1 and sec2 wrap the same NEURON " 2285 "Hoc accepts this name wherever a section is syntactically valid."},
2287 "disconnect from the parent section."},
2289 "Return the nrn.Segment specified by the connect method. Possibly None."},
2291 "Return the nrn.Segment this section connects to which is closer to the " 2292 "root. Possibly None. (same as parentseg unless parentseg.x == " 2293 "parentseg.sec.orientation()"},
2295 "Returns 0.0 or 1.0 depending on the x value closest to parent."},
2297 "Return list of child sections. Possibly an empty list"},
2299 "Return list of sections in the subtree rooted at this section (including this section)."},
2301 "Return list of all sections with a path to this section (including this section). The list has the important property that sections are in root to leaf order, depth-first traversal."},
2303 "Returns the number of 3D points."},
2305 "Returns the x coordinate of the ith 3D point."},
2307 "Returns the y coordinate of the ith 3D point."},
2309 "Returns the z coordinate of the ith 3D point."},
2311 "Returns the arc position of the ith 3D point."},
2313 "Returns the diam of the ith 3D point."},
2315 "Returns True or False depending on whether a spine exists at the ith 3D point."},
2317 "Removes the ith 3D point."},
2319 "Clears all 3D points. Optionally takes a buffer size."},
2321 "Insert the point (so it becomes the i'th point) to section. If i is equal to sec.n3d(), the point is appended (equivalent to sec.pt3dadd())"},
2323 "Change the i'th 3-d point info. If only two args then the second arg is the diameter and the location is unchanged."},
2325 "Add the 3d location and diameter point (or points in the second form) at the end of the current pt3d list. Assume that successive additions increase the arc length monotonically."},
2327 "Returns True if using a logical connection point, else False. With first arg 0 sets to no logical connection point. With first arg 1 and x, y, z arguments, sets the logical connection point. Return value includes the result of any setting."},
2328 {
"is_pysec", (PyCFunction)
is_pysec, METH_NOARGS,
2329 "Returns True if Section created from Python, False if created from HOC."},
2331 "Returns dict of info about Section contents."},
2336 "seg.point_processes() returns list of POINT_PROCESS instances in the " 2338 {
"node_index", (PyCFunction)
node_index1, METH_NOARGS,
2339 "seg.node_index() returns index of v, rhs, etc. in the _actual arrays of " 2340 "the appropriate NrnThread."},
2341 {
"area", (PyCFunction)
seg_area, METH_NOARGS,
2342 "Segment area (um2) (same as h.area(sec(x), sec=sec))"},
2343 {
"ri", (PyCFunction)
seg_ri, METH_NOARGS,
2344 "Segment resistance to parent segment (Megohms) (same as h.ri(sec(x), " 2346 {
"volume", (PyCFunction)
seg_volume, METH_NOARGS,
2347 "Segment volume (um3)"},
2356 char* s2 =
new char[strlen(s) + 1];
2362 cpstr(
"location in the section (segment containing x)")},
2369 "Mechanism name (same as hoc suffix for density mechanism)"},
2371 "Returns True if an ion mechanism"},
2373 "Returns the segment of the Mechanism instance"},
2378 "Range variable name name"},
2380 "Returns nrn.Mechanism of the RangeVariable instance"},
2388 PyErr_SetString(PyExc_TypeError,
"Section access unspecified");
2396 {
"cas",
nrnpy_cas, METH_VARARGS,
"Return the currently accessed section."},
2398 "Return iterator over all sections."},
2400 "Specify the nrn.Section.psection callback."},
2422 PyObject* modules = PyImport_GetModuleDict();
2423 if ((m = PyDict_GetItemString(modules,
"nrn")) !=
NULL && PyModule_Check(m)) {
2454 m = PyModule_Create(
2459 err = PyDict_SetItemString(modules,
"_neuron_section", m);
2464 PyModule_AddObject(m,
"Section", (PyObject*)psection_type);
2465 PyModule_AddObject(m,
"Segment", (PyObject*)psegment_type);
2493 err = PyDict_SetItemString(modules,
"nrn", m);
2529 s =
hoc_install(
"get_segment", OBFUNCTION, 0, &sl);
2547 PyDict_SetItemString(
pmech_types, s, Py_BuildValue(
"i", type));
void mech_insert1(Section *, int)
static int NPyRangeVar_init(NPyRangeVar *self, PyObject *args, PyObject *kwds)
static int pysec_cell_equals(Section *, Object *)
void nrnpy_pysecname2sec_remove(Section *sec)
static PyObject * NPySecObj_name(NPySecObj *self)
static PyObject * pysec_disconnect(NPySecObj *self)
PyObject_HEAD NPySecObj * pysec_
static PyTypeObject * pallseg_of_sec_iter_type
static int section_setattro(NPySecObj *self, PyObject *pyname, PyObject *value)
static PyObject * pymech_repr(PyObject *p)
static PyObject * NPySecObj_x3d(NPySecObj *self, PyObject *args)
Section *(* nrnpy_o2sec_p_)(Object *)
static PyObject * NPySecObj_y3d(NPySecObj *self, PyObject *args)
static PyObject * NPySecObj_pt3dclear(NPySecObj *self, PyObject *args)
void stor_pt3d(Section *sec, double x, double y, double z, double d)
static PyObject * mech_of_seg_next(NPyMechOfSegIter *self)
static int NPySegObj_init(NPySegObj *self, PyObject *args, PyObject *kwds)
static PyObject * NPySecObj_pt3dinsert(NPySecObj *self, PyObject *args)
static PyObject * hoc_internal_name(NPySecObj *self)
static int mech_setattro(NPyMechObj *self, PyObject *pyname, PyObject *value)
static PyObject * NPySecObj_spine3d(NPySecObj *self, PyObject *args)
static PyObject * seg_point_processes(NPySegObj *self)
static bool striptrail(char *buf, int sz, const char *n, const char *m)
struct Section * parentsec
void(* nrnpy_o2loc2_p_)(Object *, Section **, double *)
PyObject * nrnpy_hoc2pyobject(Object *)
static PyTypeObject * range_type
double nrn_arc_position(Section *sec, Node *node)
int prop_index(const Symbol *) const
static PyMemberDef NPyMechObj_members[]
static PyObject * seg_of_section_iter(NPySecObj *self)
double section_length(Section *)
static int rv_setitem(PyObject *self, Py_ssize_t ix, PyObject *value)
static PyObject * segment_getattro(NPySegObj *self, PyObject *pyname)
void mech_uninsert1(Section *, Symbol *)
static PyObject * pysec_children1(PyObject *const sl, Section *const sec)
Object *(* nrnpy_pysec_cell_p_)(Section *)
static PyObject * var_of_mech_next(NPyVarOfMechIter *self)
double * prop_pval(const Symbol *, int arrayindex=0) const
static PyMemberDef NPySegObj_members[]
static PyType_Spec nrnpy_SegmentType_spec
int can_change_morph(Section *)
static void NPyMechObj_dealloc(NPyMechObj *self)
static PyObject * NPySecObj_diam3d(NPySecObj *self, PyObject *args)
static PyObject * mech_of_segment_iter(NPySegObj *self)
static int arg_bisect_arc3d(Section *sec, int npt3d, double x)
void simpleconnectsection()
PyObject_HEAD NPySecObj * pysec_
static PyObject * nrnpy_set_psection(PyObject *self, PyObject *args)
static int NPyAllSegOfSecIter_init(NPyAllSegOfSecIter *self, PyObject *args, PyObject *kwds)
void nrn_pt3dremove(Section *sec, int i0)
static PyObject * NPySecObj_psection(NPySecObj *self)
int nrnpy_ho_eq_po(Object *, PyObject *)
short * nrn_is_artificial_
static void o2loc(Object *, Section **, double *)
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
static char * pysec_name(Section *)
static PyObject * pysec_children(NPySecObj *const self)
void nrn_length_change(Section *, double)
static NPyRangeVar * rvnew(Symbol *sym, NPySecObj *sec, double x)
Section * nrnpy_newsection(NPySecObj *)
static void rangevars_add(Symbol *sym)
Symbol * hoc_install(const char *, int, double, Symlist **)
int nrn_is_hocobj_ptr(PyObject *, double *&)
static PyTypeObject * pseg_of_sec_iter_type
static PyType_Spec nrnpy_SegOfSecIterType_spec
void nrn_diam_change(Section *)
struct Pt3d * logical_connection
void nrn_pt3dchange1(Section *sec, int i, double d)
static struct PyModuleDef nrnsectionmodule
PyObject * nrnpy_pushsec(PyObject *sec)
static PyObject * NPyRangeVar_name(NPyRangeVar *self)
static PyTypeObject * pmech_of_seg_iter_generic_type
static PyObject * pysec_richcmp(NPySecObj *self, PyObject *other, int op)
static void NPyVarOfMechIter_dealloc(NPyVarOfMechIter *self)
static PyObject * NPySecObj_pt3dstyle(NPySecObj *self, PyObject *args)
int(* nrnpy_ob_is_seg)(Object *)
static Object ** pp_get_segment(void *vptr)
static long pyseg_hash(PyObject *self)
static void nrnpy_unreg_mech(int)
void nrn_pt3dinsert(Section *sec, int i0, double x, double y, double z, double d)
static PyObject * var_of_mech_iter(NPyMechObj *self)
static void rv_noexist(Section *sec, const char *n, double x, int err)
static PyMethodDef NPyRangeVar_methods[]
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
static double cell(void *v)
static int NPySecObj_contains(PyObject *sec, PyObject *obj)
Object *(* nrnpy_seg_from_sec_x)(Section *, double x)
int const size_t const size_t n
HocStruct Symbol ** ppsym
static struct PyModuleDef nrnmodule
PyObject * nrn_hocobj_ptr(double *)
static PyObject * seg_area(NPySegObj *self)
static PyObject * pysec_same(NPySecObj *self, PyObject *args)
int nrn_pointer_assign(Prop *prop, Symbol *sym, PyObject *value)
static void NPySegObj_dealloc(NPySegObj *self)
static Object * seg_from_sec_x(Section *, double x)
void nrn_rangeconst(Section *sec, Symbol *s, double *pd, int op)
static PyObject * nrnpy_psection
Object * nrnpy_po2ho(PyObject *)
static PyObject * NPyMechObj_name(NPyMechObj *self)
double nrn_connection_position(Section *sec)
static PyObject * rv_getitem(PyObject *self, Py_ssize_t ix)
static char * cpstr(const char *s)
const char * secname(Section *sec)
static PyObject * pysec_subtree1(PyObject *const sl, Section *const sec)
static int segment_setattro(NPySegObj *self, PyObject *pyname, PyObject *value)
static void NPyAllSegOfSecIter_dealloc(NPyAllSegOfSecIter *self)
static PyObject * NPyRangeVar_mech(NPyRangeVar *self)
static double interpolate(double x0, double x1, double y0, double y1, double xnew)
static PyObject * NPySecObj_arc3d(NPySecObj *self, PyObject *args)
void nrn_pushsec(Section *sec)
void nrnpy_pysecname2sec_add(Section *sec)
PyObject_HEAD NPySecObj * pysec_
static double scaled_frustum_volume(double length, double d0, double d1)
void hoc_execerror(const char *, const char *)
PyObject_HEAD Section * sec_
static PyTypeObject * pvar_of_mech_iter_generic_type
static PyObject * NPyMechObj_is_ion(NPyMechObj *self)
static PyObject * seg_ri(NPySegObj *self)
static PyObject * NPySecObj_connect(NPySecObj *self, PyObject *args)
static PyObject * seg_volume(NPySegObj *self)
static PyObject * allseg(NPySecObj *self)
NPySecObj * newpysechelp(Section *sec)
double nrn_section_orientation(Section *sec)
Symbol * nrnpy_pyobj_sym_
Symlist * hoc_built_in_symlist
static void remake_pmech_types()
static PyObject * pysec_wholetree(NPySecObj *const self)
PyObject_HEAD NPyMechObj * pymech_
void(* nrnpy_o2loc_p_)(Object *, Section **, double *)
static PyType_Spec nrnpy_MechOfSegIterType_spec
Prop * nrn_mechanism(int type, Node *nd)
static PyObject * pysec2cell(NPySecObj *)
static PyObject * pysec_orientation(NPySecObj *self)
static PyObject * NPySecObj_pt3dremove(NPySecObj *self, PyObject *args)
static PyObject * pysec_repr(PyObject *p)
static PyObject * NPyMechObj_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyMethodDef NPyMechObj_methods[]
void section_ref(Section *)
static PyMethodDef NPySegObj_methods[]
PyObject * nrnpy_nrn(void)
static PyMethodDef nrnpy_methods[]
struct Symbol::@52::@53 rng
static PyObject * NPySecObj_uninsert(NPySecObj *self, PyObject *args)
PyObject_HEAD NPySegObj * pyseg_
#define PyString_FromString
PyTypeObject * hocobject_type
static PyType_Spec nrnpy_RangeType_spec
static int NPySecObj_init(NPySecObj *self, PyObject *args, PyObject *kwds)
short cpublic
Note: public is a reserved keyword.
static PyObject * NPySegObj_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static int ob_is_seg(Object *)
PyObject_HEAD NPySegObj * pyseg_
static PyObject * node_index1(NPySegObj *self)
static PyObject * seg_of_sec_next(NPySegOfSecIter *self)
static void NPyRangeVar_dealloc(NPyRangeVar *self)
static PyTypeObject * psegment_type
static Prop * mech_of_segment_prop(Prop *p)
static PyObject * NPySecObj_n3d(NPySecObj *self)
static PyObject * pyseg_repr(PyObject *p)
PyTypeObject * psection_type
void(* nrnpy_reg_mech_p_)(int)
PyObject * nrn_ptr_richcmp(void *self_ptr, void *other_ptr, int op)
void nrn_pt3dstyle1(Section *sec, double x, double y, double z)
static PyObject * NPySecObj_pt3dadd(NPySecObj *self, PyObject *args)
static PyObject * NPySecObj_pt3dchange(NPySecObj *self, PyObject *args)
PyObject * nrnpy_cas(PyObject *self, PyObject *args)
Symbol * hoc_table_lookup(const char *, Symlist *)
static PyObject * NPySecObj_z3d(NPySecObj *self, PyObject *args)
void nrn_change_nseg(Section *, int)
static PyObject * section_getattro(NPySecObj *self, PyObject *pyname)
PyObject * nrnpy_newsecobj(PyObject *self, PyObject *args, PyObject *kwds)
static Object * pysec_cell(Section *)
char *(* nrnpy_pysec_name_p_)(Section *)
static PyMethodDef NPySecObj_methods[]
PyObject_HEAD NPyMechObj * pymech_
static PyObject * pysec_trueparentseg(NPySecObj *self)
PyObject_HEAD NPyMechObj * pymech_
void nrn_disconnect(Section *sec)
double * nrnpy_rangepointer(Section *, Symbol *, double, int *)
double ** nrnpy_setpointer_helper(PyObject *pyname, PyObject *mech)
static PyObject * allseg_of_sec_iter(NPyAllSegOfSecIter *self)
int has_membrane(char *, Section *)
#define CHECK_SEC_INVALID(sec)
static PyObject * NPySecObj_insert(NPySecObj *self, PyObject *args)
void nrn_pt3dchange2(Section *sec, int i, double x, double y, double z, double diam)
static PyType_Spec nrnpy_MechanismType_spec
void nrn_area_ri(Section *sec)
void set_pyerr(PyObject *type, const char *message)
static PyType_Spec nrnpy_VarOfMechIterType_spec
static PyTypeObject * pmech_generic_type
int nrn_at_beginning(Section *sec)
void nrn_pt3dclear(Section *sec, int req)
PyObject * NPySecObj_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void NPyMechOfSegIter_dealloc(NPyMechOfSegIter *self)
Object * nrnpy_pyobject_in_obj(PyObject *)
PyObject * NPyAllSegOfSecIter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
void sec_free(hoc_Item *)
Object ** hoc_temp_objptr(Object *)
void section_unref(Section *)
static long pysec_hash(PyObject *self)
static PyObject * pysec_subtree(NPySecObj *const self)
static PyObject * newpyseghelp(Section *sec, double x)
static PyObject * NPySecObj_push(NPySecObj *self, PyObject *args)
static void nrnpy_reg_mech(int)
static Section * o2sec(Object *)
static PyObject * pysec_parentseg(NPySecObj *self)
static PyObject * NPySecObj_has_membrane(NPySecObj *self, PyObject *args)
Symbol * find(const char *rangevar)
static PyObject * NPySecObj_call(NPySecObj *self, PyObject *args)
static int NPyMechObj_init(NPyMechObj *self, PyObject *args, PyObject *kwds)
static PyObject * nrnmodule_
Section * nrn_noerr_access()
int(* nrnpy_pysec_cell_equals_p_)(Section *, Object *)
static PyObject * is_pysec(NPySecObj *self)
PyObject * nrnpy_ho2po(Object *)
void nrn_pt3dstyle0(Section *sec)
Node * node_exact(Section *sec, double x)
static void o2loc2(Object *o, Section **psec, double *px)
static PyObject * allseg_of_sec_next(NPyAllSegOfSecIter *self)
static PyObject * mech_getattro(NPyMechObj *self, PyObject *pyname)
static bool lappendsec(PyObject *const sl, Section *const s)
static PyType_Spec nrnpy_AllSegOfSecIterType_spec
static Py_ssize_t rv_len(PyObject *self)
cTemplate ** nrn_pnt_template_
static PyType_Spec nrnpy_SectionType_spec
static PyObject * NPyMechObj_segment(NPyMechObj *self)
static PyObject * NPyRangeVar_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static void NPySecObj_dealloc(NPySecObj *self)
static PyObject * pyseg_richcmp(NPySegObj *self, PyObject *other, int op)
static void NPySegOfSecIter_dealloc(NPySegOfSecIter *self)
PyObject * nrnpy_forall(PyObject *self, PyObject *args)