2 #include <../../nrnconf.h>
25 for (p1 =
s, p2 = b; *p1; ++p1, ++p2) {
49 #define symlist hoc_symlist
97 "prior to version 5.3 the section stack would not have been properly popped\n\
98 and the currently accessed section would have been ",
144 if (
sec->prop &&
sec->prop->dparam[0].sym) {
145 printf(
"pushsec %s\n",
sec->prop->dparam[0].sym->name);
147 printf(
"pushsec unnamed or deleted section\n");
169 static void free_point_process(
void) {
180 printf(
"clear_sectionlist not fixed yet, doing nothing\n");
184 free_point_process();
186 if (
s->type == SECTION) {
190 free((
char *)
s->arayinfo);
213 if (sym->
type == SECTION) {
216 for (
i = 0;
i < total; ++
i) {
225 "First time declaration of Section %s in %s "
226 "must happen at command level (not in method)",
247 for (
i=0;
i<ndim;
i++) {
printf(
"[%d]",
s->arayinfo->sub[
i]);}
248 printf(
" is a section name\n");
254 if (
auto* o =
sec->prop->dparam[6].get<
Object*>(); o) {
269 if (
auto o =
sec->prop->dparam[6].get<
Object*>(); o) {
306 for (
i = 0;
i < size; ++
i) {
344 "delete_section takes no positional arguments and deletes the HOC currently accessed "
345 "section. If using Python, did you mean a named arg of the form, sec=section?",
365 auto* sym =
sec->prop->dparam[0].get<
Symbol*>();
367 hoc_execerror(
"Cannot delete an unnamed hoc section", (
char*) 0);
369 auto* ob =
sec->prop->dparam[6].get<
Object*>();
370 auto i =
sec->prop->dparam[5].get<
int>();
372 pitm = ob->u.dataspace[sym->u.oboff].psecitm +
i;
402 if (
sec->recalc_area_ &&
sec->npt3d) {
403 sec->prop->dparam[2] =
sec->pt3d[
sec->npt3d - 1].arc;
405 double x =
sec->prop->dparam[2].get<
double>();
408 sec->prop->dparam[2] = x;
414 return (
sec->prop->dparam[3].get<
double>() ? 0 : 1);
418 return sec->prop->dparam[7].get<
double>();
464 execerror(
"Section access unspecified", (
char*) 0);
469 execerror(
"Accessing a deleted section", (
char*) 0);
504 if (
sec->parentsec) {
505 if (
sec->parentsec->child ==
sec) {
506 sec->parentsec->child =
sec->sibling;
509 for (
s =
sec->parentsec->child;
s;
s =
s->sibling) {
510 if (
s->sibling ==
sec) {
511 s->sibling =
sec->sibling;
520 if (
sec->parentsec) {
531 if (
sec->parentsec) {
533 s =
sec->parentsec->child;
536 sec->parentsec->child =
sec;
539 for (;
s->sibling;
s =
s->sibling) {
541 sec->sibling =
s->sibling;
555 for (scnt = 0, ch =
sec->child; ch; ++scnt, ch = ch->
sibling) {
571 "disconnect takes no positional arguments and disconnects the HOC currently accessed "
572 "section. If using Python, did you mean a named arg of the form, sec=section? Or you "
573 "can use section.disconnect().",
584 for (
i = 0,
j =
sec->nnode - 2;
i <
j; ++
i, --
j) {
587 sec->pnode[
i]->sec_node_index_ =
i;
596 Node* oldpnode =
sec->parentnode;
618 Node* oldpnode =
sec->parentnode;
623 if (d1 != 0. && d1 != 1.) {
626 if (d2 < 0. || d2 > 1.) {
629 if (
sec->parentsec) {
632 " had previously been connected to parent %s(%g)\n",
641 pd =
sec->prop->dparam;
645 sec->parentsec = parent;
657 }
else if (oldpnode) {
693 if (
s->cpublic == 2) {
702 if (
s->type != SECTION) {
716 printf(
"accessing %s with index %d\n",
s->name, access_index);
777 if (
n < 12 || strncmp(
s,
"__nrnsec_0x", 11) != 0) {
780 if (sscanf(
s + 9,
"%p", &vp) != 1) {
797 hoc_execerror(
"Section associated with internal name does not exist:",
s);
799 hoc_warning(
"Section associated with internal name does not exist:",
s);
829 hoc_execerror(
"section in the object was deleted", (
char*) 0);
872 for (
i =
n - 1;
i >= 0;
i--) {
879 if (!
sec->parentsec) {
880 nd =
sec->parentnode;
902 int type =
s->subtype;
913 hoc_warning(
"Not allowed to uninsert ions at this time",
s->name);
917 for (
i = 0;
i <
n; ++
i) {
918 mnext =
sec->pnode[
i]->prop;
924 for (m = mnext; m; m = mnext) {
953 for (
i = 0;
i <
n;
i++) {
957 sec->pnode[
i]->v() = *pd;
969 if (
sec->recalc_area_ && op != 0) {
974 for (
i = 0;
i <
n;
i++) {
982 sec->recalc_area_ = 1;
987 if (
s->u.rng.index == 0) {
1040 for (m = nd->
prop; m; m = m->
next) {
1056 "%s mechanism not inserted in section %s\n",
1085 auto*
const s = (
hoc_pc++)->sym;
1086 auto const pd = hoc_pop_handle<double>();
1115 if (
sec->recalc_area_ && op != 0) {
1127 sec->recalc_area_ = 1;
1132 if (
s->u.rng.type ==
EXTRACELL &&
s->u.rng.index == 0) {
1140 short i, i1, i2, di;
1142 double y1, y2, x1, x2, x, dx, thet, y;
1155 hoc_execerror(
"range variable notation r(x1:x2) requires",
" x1 > x2");
1162 if (
s->u.rng.type ==
VINDEX) {
1163 if (x1 == 0. || x1 == 1.) {
1171 if (x2 == 1. || x2 == 0.) {
1179 for (
i = i1;
i != i2;
i += di) {
1181 x = ((double)
i + .5) / (
sec->nnode - 1);
1185 thet = (x - x1) / dx;
1186 if (thet >= -1e-9 && thet <= 1. + 1e-9) {
1187 y = y1 * (1. - thet) + y2 * thet;
1207 for (
i = i1;
i != i2;
i += di) {
1209 x = ((double)
i + .5) / (
sec->nnode - 1);
1213 thet = (x - x1) / dx;
1214 if (thet >= -1e-9 && thet <= 1. + 1e-9) {
1215 y = y1 * (1. - thet) + y2 * thet;
1224 sec->recalc_area_ = 1;
1228 if (
s->u.rng.type ==
EXTRACELL &&
s->u.rng.index == 0) {
1232 if (x1 == 0. || x1 == 1.) {
1243 if (x2 == 1. || x2 == 0.) {
1259 if (
s->u.rng.type ==
VINDEX) {
1280 if (
s->u.rng.type ==
VINDEX) {
1290 "cvode.use_fast_imem(1) has not been executed so i_membrane_ does not exist", 0);
1313 if (
s->u.rng.type ==
VINDEX) {
1315 return nd->v_handle();
1320 return nd->sav_rhs_handle();
1343 if (
s->u.rng.type ==
VINDEX) {
1354 "cvode.use_fast_imem(1) has not been executed so i_membrane_ does not exist", 0);
1411 if (x < 0. || x > 1.) {
1412 hoc_execerror(
"range variable domain is 0<=x<=1", (
char*) 0);
1414 n = (double) (
sec->nnode - 1);
1420 if (
sec->prop->dparam[3].get<
double>()) {
1431 return sec->nnode - 1;
1433 }
else if (x == 1.) {
1435 return sec->nnode - 1;
1450 switch (sym->
u.
rng.type) {
1452 return (
double)
sec->nnode - 1;
1454 return sec->prop->dparam[sym->
u.
rng.index].get<
double>();
1464 switch (sym->
u.
rng.type) {
1466 return &(
sec->prop->dparam[sym->
u.
rng.index].literal_value<
double>());
1485 fprintf(stderr,
"requesting %s.nseg=%d but the maximum value is 32767.\n",
secname(
sec),
n);
1486 hoc_warning(
"nseg too large, setting to 1.", (
char*) 0);
1491 if (
sec->nnode ==
n + 1) {
1496 int nold =
sec->nnode;
1500 sec->recalc_area_ = 1;
1505 for (
i = 0;
i <
n;
i++) {
1515 switch (sym->
u.
rng.type) {
1523 if (sym->
u.
rng.index == 2) {
1526 *pd =
hoc_opasgn(op,
sec->prop->dparam[2].get<
double>(), *pd);
1528 sec->prop->dparam[2] = *pd;
1531 sec->recalc_area_ = 1;
1538 sec->recalc_area_ = 1;
1539 sec->prop->dparam[sym->
u.
rng.index] = *pd;
1542 if (sym->
u.
rng.index == 7) {
1553 return sec->prop->dparam[1].get<
double>();
1557 return sec->prop->dparam[3].get<
double>();
1567 sec->parentnode->sec_node_index_ = 0;
1568 sec->parentnode->sec =
sec;
1570 if (
sec->pnode[0]->extnode) {
1579 for (psec =
sec->parentsec; psec; psec = psec->
parentsec) {
1603 for (
sec =
s, psec =
sec->parentsec; psec;
sec = psec, psec =
sec->parentsec) {
1605 fprintf(stderr,
"%s connection to ",
secname(
s));
1606 fprintf(stderr,
"%s will form a loop\n",
secname(
s->parentsec));
1613 if (x == 1. || x == 0.) {
1621 if (true_parent == (
Section*) 0) {
1622 if (
sec->parentnode) {
1653 if (
sec->nnode < 1) {
1655 " has no segments");
1661 if (!
sec->parentsec) {
1675 static char name[512];
1677 if (
auto*
s =
sec->prop->dparam[0].get<
Symbol*>();
s) {
1678 auto indx =
sec->prop->dparam[5].get<
int>();
1679 auto* ob =
sec->prop->dparam[6].get<
Object*>();
1705 static char buf[256];
1708 strncmp(
name,
"__nrnsec_0x", 11) != 0) {
1729 static char name[200];
1731 auto indx =
sec->prop->dparam[5].get<
int>();
1732 auto* ob =
sec->prop->dparam[6].get<
Object*>();
1759 if (
sec->parentnode ==
node) {
1764 x = ((double) inode + .5) / ((double)
sec->nnode - 1.);
1775 static char buf1[200];
1793 *pdx = l / ((double)
n);
1798 #define PI 3.14159265358979323846
1807 if (x <= 0. || x >= 1.) {
1808 x = (x < 0.) ? 0. : x;
1809 x = (x > 1.) ? 1. : x;
1810 if (
sec->prop->dparam[3].get<
double>()) {
1846 if (
s->type == TEMPLATE) {
1876 if (
sec->pnode[0]->extnode) {
1887 using std::runtime_error::runtime_error;
1900 sec->pnode[inode]->extnode->v +
indx};
1912 if (
p.is_invalid_handle()) {
1913 throw VoidPointerError(std::string(
s->name) +
" wasn't made to point to anything");
1952 static char buf[100];
1961 #define relative(pc) (pc + (pc)->i)
1971 Item *qsec, *first, *last;
1985 first = first->prev) {
2008 for (qsec = first; qsec != last;) {
2013 if (!std::regex_match(
secname(
sec), pattern)) {
2065 for (
p =
sec->pnode[0]->prop;
p;
p =
p->next) {
2066 if (strcmp(
memb_func[
p->_type].sym->name, mechanism_name) == 0) {
2092 static char*
buf = (
char*) 0;
2095 buf =
static_cast<char*
>(
emalloc(256 *
sizeof(
char)));
2107 size_t n = (size_t) vp;
2108 if (
sizeof(
void*) == 8) {
2109 size_t maxvoid2dbl = ((size_t) 1) << 53;
2111 printf(
"sizeof void*, size_t, and double = %zd, %zd, %zd\n",
2112 sizeof(
void*),
sizeof(
size_t),
sizeof(
double));
2113 printf(
"(double)((1<<53) - 1)=%.20g\n", (
double)(maxvoid2dbl - 1));
2114 printf(
"(double)((1<<53) + 0)=%.20g\n", (
double)(maxvoid2dbl));
2115 printf(
"(double)((1<<53) + 1)=%.20g\n", (
double)(maxvoid2dbl + 1));
2116 printf(
"(size_t)(vp) = %zd\n",
n);
2118 if (
n > maxvoid2dbl) {
2119 hoc_execerror(mes,
"pointer too large to be represented by a double");
2121 }
else if (
sizeof(
void*) > 8) {
2122 hoc_execerror(mes,
"not implemented for sizeof(void*) > 8");
2210 sec->prop->dparam[8].get<
hoc_Item*>()->itemtype != SECTION) {
2227 if (sym && sym->
cpublic == 2) {
2235 if (sym->
type == SECTION) {
2256 char *str,
buf[100];
2267 if (sscanf(str,
"%[^[][%d",
buf, &
indx) == 2) {
void section_exists(void)
Object *(* nrnpy_pysec_cell_p_)(Section *)
int segment_limits(double *pdx)
double nrn_section_orientation(Section *sec)
const char * secname(Section *sec)
name of section (for use in error messages)
void hoc_sec_internal_push(void)
static double chk_void2dbl(void *vp, const char *mes)
void nrn_change_nseg(Section *sec, int n)
void delete_section(void)
void oc_save_cabcode(int *a1, int *a2)
neuron::container::generic_data_handle nrnpy_dprop(Symbol *s, int indx, Section *sec, short inode, int *err)
returns location of property symbol, return nullptr instead of hoc_execerror
static int range_vec_indx(Symbol *s)
static void nrn_remove_sibling_list(Section *sec)
void mech_uninsert1(Section *sec, Symbol *s)
static Section * secstack[NSECSTACK+1]
static void nrn_add_sibling_list(Section *sec)
double * nrn_vext_pd(Symbol *s, int indx, Node *nd)
void rangeobjevalmiddle(void)
int hoc_execerror_messages
static void connectsec_impl(Section *parent, Section *sec)
void sec_access_pop(void)
static int skip_secstack_check
int node_index_exact(Section *sec, double x)
return -1 if x at connection end, nnode-1 if at other end
void rangevarevalpointer()
static void nrn_rootnode_alloc(Section *sec)
Node * node_ptr(Section *sec, double x, double *parea)
void nrn_pushsec(Section *sec)
void nrn_parent_info(Section *s)
double nrn_arc_position(Section *sec, Node *node)
void parent_connection(void)
Prop * hoc_getdata_range(int type)
int has_membrane(char *mechanism_name, Section *sec)
double cable_prop_eval(Symbol *sym)
Section * nrn_trueparent(Section *sec)
void simpleconnectsection(void)
Prop * nrn_mechanism(int type, Node *nd)
void cable_prop_assign(Symbol *sym, double *pd, int op)
void setup_topology(void)
void range_interpolate(void)
void morph_alloc(Prop *p)
void forall_section(void)
double nrn_ra(Section *sec)
void nrn_rangeconst(Section *sec, Symbol *s, neuron::container::data_handle< double > pd, int op)
static Section * new_section(Object *ob, Symbol *sym, int i)
double section_length(Section *sec)
int node_index(Section *sec, double x)
returns nearest index to x
neuron::container::generic_data_handle nrnpy_rangepointer(Section *sec, Symbol *s, double d, int *err, int idx)
return nullptr if failure instead of hoc_execerror and return pointer to the 0 element if an array
int nrn_sec2cell_equals(Section *sec, Object *obj)
void connectsection(void)
double nrn_connection_position(Section *sec)
static char * escape_bracket(const char *s)
int nrn_exists(Symbol *s, Node *node)
Section * nrn_noerr_access(void)
return 0 if no accessed section
int(* nrnpy_pysec_cell_equals_p_)(Section *, Object *)
static Section * Sec_access(void)
void keep_nseg_parm(void)
static void reverse_sibling_list(Section *sec)
neuron::container::data_handle< double > dprop(Symbol *s, int indx, Section *sec, short inode)
returns location of property symbol
void range_interpolate_single(void)
int arc0at0(Section *sec)
void sec_access_push(void)
void sec_access_object(void)
Section * nrn_sec_pop(void)
static double ncp_abs(Section *sec)
neuron::container::generic_data_handle dprop_impl(Prop *m, Symbol *s, int indx, Section *sec, short inode)
Object * nrn_sec2cell(Section *sec)
int nrn_get_mechtype(const char *mechname)
void section_orientation(void)
void new_sections(Object *ob, Symbol *sym, Item **pitm, int size)
Prop * nrn_mechanism_check(int type, Section *sec, int inode)
returns prop given mech type, section, and inode error if mech not at this position
double nrn_diameter(Node *nd)
void hoc_level_pushsec(Section *sec)
turn off section stack fixing (in case of return, continue, break in a section statement) between exp...
const char * sec_and_position(Section *sec, Node *nd)
neuron::container::data_handle< double > nrn_rangepointer(Section *sec, Symbol *s, double d)
void oc_restore_cabcode(int *a1, int *a2)
void ob_sec_access_push(hoc_Item *qsec)
char *(* nrnpy_pysec_name_p_)(Section *)
void parent_section(void)
void nrn_disconnect(Section *sec)
char * hoc_section_pathname(Section *sec)
Node * node_exact(Section *sec, double x)
like node_index but give proper node when x is 0 or 1 as well as in between
void mech_insert1(Section *sec, int type)
static char * objectname(void)
Section * section_new(Symbol *sym)
Creates a new section and registers with the global section list.
static void reverse_nodes(Section *sec)
double * cable_prop_eval_pointer(Symbol *sym)
static Datum * pdprop(Symbol *s, int indx, Section *sec, short inode)
Section * nrn_section_exists(char *name, int indx, Object *cell)
const char * nrn_sec2pysecname(Section *sec)
int nrn_at_beginning(Section *sec)
static void free_clamp(void)
Symbol * hoc_table_lookup(const char *, Symlist *)
void clear_sectionlist(void)
Datum * nrn_prop_datum_alloc(int type, int count, Prop *p)
int nrn_is_valid_section_ptr(void *v)
void extcell_2d_alloc(Section *sec)
void extcell_node_create(Node *nd)
double chkarg(int, double low, double high)
static void free_stim(void)
char * hoc_object_pathname(Object *ob)
void hoc_pushstr(char **d)
void hoc_execerr_ext(const char *fmt,...)
printf style specification of hoc_execerror message.
Object * nrn_nmodlrandom_wrap(Prop *prop, Symbol *sym)
size_t hoc_total_array_data(const Symbol *s, Objectdata *obd)
int hoc_arayinfo_install(Symbol *sp, int nsub)
void hoc_pushpx(double *d)
void hoc_pushobj(Object **d)
void hoc_freearay(Symbol *sp)
void * hoc_sec_internal_name2ptr(const char *s, int eflag)
int hoc_is_str_arg(int narg)
Objectdata * hoc_objectdata
void hoc_assign_str(char **cpp, const char *buf)
double hoc_opasgn(int op, double dest, double src)
int hoc_is_double_arg(int narg)
void hoc_retpushx(double x)
char * hoc_object_name(Object *ob)
void * hoc_pysec_name2ptr(const char *s, int)
void hoc_install_object_data_index(Symbol *sp)
size_t hoc_total_array(Symbol *s)
Symbol * hoc_lookup(const char *)
char * hoc_araystr(Symbol *sym, int index, Objectdata *obd)
void hoc_push_object(Object *d)
void hoc_push(neuron::container::generic_data_handle handle)
char ** hoc_pgargstr(int narg)
Objectdata * hoc_objectdata_restore(Objectdata *obdsav)
Objectdata * hoc_objectdata_save(void)
bool is_array(const Symbol &sym)
constexpr auto range_sec(hoc_List *iterable)
Object ** hoc_objgetarg(int)
Symlist * hoc_top_level_symlist
int hoc_araypt(Symbol *, int)
int state_discon_allowed_
void hoc_execerror(const char *s1, const char *s2)
static void * emalloc(size_t size)
void hoc_warning(const char *s1, const char *s2)
constexpr do_not_search_t do_not_search
Model & model()
Access the global Model instance.
int Sprintf(char(&buf)[N], const char *fmt, Args &&... args)
Redirect sprintf to snprintf if the buffer size can be deduced.
Prop * prop_alloc(Prop **, int, Node *)
void single_prop_free(Prop *)
void nrn_relocate_old_points(Section *oldsec, Node *oldnode, Section *sec, Node *node)
void nrn_area_ri(Section *sec)
void section_ref(Section *)
int can_change_morph(Section *)
void section_unref(Section *)
void sec_free(hoc_Item *)
void nrn_diam_change(Section *)
void nrn_seg_or_x_arg(int iarg, Section **psec, double *px)
void nrn_length_change(Section *, double)
static Node * node(Object *)
int const size_t const size_t n
std::vector< Memb_func > memb_func
Object ** hoc_objpop()
Pop pointer to object pointer and return top elem from stack.
Objectdata * hoc_top_level_data
Item * lappendsec(List *list, Section *sec)
Item * insertsec(Item *item, Section *sec)
static double done(void *v)
static double cell(void *v)
static void pnode(Prop *)
Section * nrnpy_pysecname2sec(const char *name)
void node_alloc(Section *, short)
Section * sec_alloc()
Allocate a new Section object.
auto param_handle_legacy(int legacy_index)
struct Symbol::@45::@46 rng
union hoc_Item::@48 element
container::Node::storage & node_data()
Access the structure containing the data of all Nodes.
Non-template stable handle to a generic value.
void mark_as_unsorted()
Tell the container it is no longer sorted.
static void free_syn(void)
int Fprintf(FILE *stream, const char *fmt, Args... args)
int Printf(const char *fmt, Args... args)