NEURON
point.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/nrnoc/point.cpp,v 1.13 1999/03/23 16:12:09 hines Exp */
3 
4 /* modl description via modlreg calls point_register_mech() and
5 saves the pointtype as later argument to create and loc */
6 
7 #include <stdlib.h>
8 #include "section.h"
9 #include "membfunc.h"
10 #include "parse.hpp"
11 
12 
13 extern char* pnt_map;
14 extern Symbol** pointsym; /*list of variable symbols in s->u.ppsym[k]
15  with number in s->s_varn */
16 
17 extern short* nrn_is_artificial_;
18 extern "C" {
19 extern double loc_point_process(int, void *);
20 } // extern "C"
21 extern Prop* prop_alloc(Prop**, int, Node*);
22 
23 static int cppp_semaphore = 0; /* connect point process pointer semaphore */
24 static double** cppp_pointer;
25 static void free_one_point(Point_process* pnt);
26 static void create_artcell_prop(Point_process* pnt, short type);
27 
29 void (*nrnpy_o2loc_p_)(Object*, Section**, double*);
30 void (*nrnpy_o2loc2_p_)(Object*, Section**, double*);
31 
32 extern "C" void* create_point_process(int pointtype, Object* ho)
33 {
34  Point_process* pp;
35  pp = (Point_process*)emalloc(sizeof(Point_process));
36  pp->node = 0;
37  pp->sec = 0;
38  pp->prop = 0;
39  pp->ob = ho;
40  pp->presyn_ = 0;
41  pp->nvi_ = 0;
42  pp->_vnt = 0;
43 
44  if (nrn_is_artificial_[pointsym[pointtype]->subtype]) {
45  create_artcell_prop(pp, pointsym[pointtype]->subtype);
46  return pp;
47  }
48  if (ho && ho->ctemplate->steer && ifarg(1)) {
49  loc_point_process(pointtype, (void*)pp);
50  }
51  return (void*)pp;
52 }
53 
55 {
56  void* v;
57  extern Object* hoc_new_object(Symbol*, void*);
58  extern Object* hoc_new_opoint(int);
59  Object* ob;
61  int pointtype;
62  assert(sym->type == MECHANISM && memb_func[sym->subtype].is_point);
63  pointtype = pnt_map[sym->subtype];
64  if (memb_func[sym->subtype].hoc_mech) {
65  ob = hoc_new_opoint(sym->subtype);
66  }else{
67  hoc_push_frame(sym, 0);
68  v = create_point_process(pointtype, nullptr);
69  hoc_pop_frame();
70  sym = hoc_table_lookup(sym->name, hoc_built_in_symlist);
71  ob = hoc_new_object(sym, v);
72  ((Point_process*)v)->ob = ob;
73  }
74  return ob;
75 }
76 
77 extern "C" void destroy_point_process(void* v)
78 {
79  // might be NULL if error handling because of error in construction
80  if (v) {
81  Point_process* pp = (Point_process*)v;
82  free_one_point(pp);
83  free(pp);
84  }
85 }
86 
88 {
89  extern Prop* prop_alloc_disallow(Prop** pp, short type, Node* nd);
90  extern Prop* prop_alloc(Prop**, int, Node*);
91  extern Section* nrn_pnt_sec_for_need_;
92  Prop* p;
93  double x;
94 
95  assert(!nrn_is_artificial_[pointsym[pointtype]->subtype]);
96  x = nrn_arc_position(sec, node);
97  /* the problem the next fragment overcomes is that POINTER's become
98  invalid when a point process is moved (dparam and param were
99  allocated but then param was freed and replaced by old param) The
100  error that I saw, then, was when a dparam pointed to a param --
101  useful to give default value to a POINTER and then the param was
102  immediately freed. This was the tip of the iceberg since in general
103  when one moves a point process, some pointers are valid and
104  some invalid and this can only be known by the model in its
105  CONSTRUCTOR. Therefore, instead of copying the old param to
106  the new param (and therefore invalidating other pointers as in
107  menus) we flag the allocation routine for the model to
108  1) not allocate param and dparam, 2) don't fill param but
109  do the work for dparam (fill pointers for ions),
110  3) execute the constructor normally.
111  */
112  if (pnt->prop) {
113  nrn_point_prop_ = pnt->prop;
114  }else{
115  nrn_point_prop_ = (Prop*)0;
116  }
117  nrn_pnt_sec_for_need_ = sec;
118  if (x == 0. || x == 1.) {
119  p = prop_alloc_disallow(&(node->prop), pointsym[pointtype]->subtype, node);
120  }else{
121  p = prop_alloc(&(node->prop), pointsym[pointtype]->subtype, node);
122  }
123  nrn_pnt_sec_for_need_ = (Section*)0;
124 
125  nrn_point_prop_ = (Prop*)0;
126  if (pnt->prop) {
127  pnt->prop->param = (double*)0;
128  pnt->prop->dparam = (Datum*)0;
129  free_one_point(pnt);
130  }
131  nrn_sec_ref(&pnt->sec, sec);
132  pnt->node = node;
133  pnt->prop = p;
134  pnt->prop->dparam[0].pval = &NODEAREA(node);
135  pnt->prop->dparam[1]._pvoid = (void*)pnt;
136  if (pnt->ob) {
137  if (pnt->ob->observers) {
138  hoc_obj_notify(pnt->ob);
139  }
140  if (pnt->ob->ctemplate->observers) {
141  hoc_template_notify(pnt->ob, 2);
142  }
143  }
144 }
145 
146 static void create_artcell_prop(Point_process* pnt, short type) {
147  Prop* p = (Prop*)0;
148  nrn_point_prop_ = (Prop*)0;
149  pnt->prop = prop_alloc(&p, type, (Node*)0);
150  pnt->prop->dparam[0].pval = (double*)0;
151  pnt->prop->dparam[1]._pvoid = (void*)pnt;
152  if (pnt->ob) {
153  if (pnt->ob->observers) {
154  hoc_obj_notify(pnt->ob);
155  }
156  if (pnt->ob->ctemplate->observers) {
157  hoc_template_notify(pnt->ob, 2);
158  }
159  }
160 }
161 
162 void nrn_relocate_old_points(Section* oldsec, Node* oldnode, Section* sec, Node* node)
163 {
164  Point_process* pnt;
165  Prop* p, *pn;
166  if (oldnode) for (p = oldnode->prop; p; p = pn) {
167  pn = p->next;
168  if (memb_func[p->type].is_point) {
169  pnt = (Point_process*)p->dparam[1]._pvoid;
170  if (oldsec == pnt->sec) {
171  if (oldnode == node) {
172  nrn_sec_ref(&pnt->sec, sec);
173  }else{
174 #if 0
175 double nrn_arc_position();
176 char* secname();
177 printf("relocating a %s to %s(%d)\n",
178 memb_func[p->type].sym->name,
179 secname(sec), nrn_arc_position(sec, node)
180 );
181 #endif
183  pnt_map[p->type], pnt, sec, node
184  );
185  }
186  }
187  }
188  }
189 }
190 
191 void nrn_seg_or_x_arg(int iarg, Section** psec, double* px) {
192  if (hoc_is_double_arg(iarg)) {
193  *px = chkarg(iarg, 0., 1.);
194  *psec = chk_access();
195  }else{
196  Object* o = *hoc_objgetarg(iarg);
197  *psec = (Section*)0;
198  if (nrnpy_o2loc_p_) {
199  (*nrnpy_o2loc_p_)(o, psec, px);
200  }
201  if (!(*psec)) {
202  assert(0);
203  }
204  }
205 }
206 
207 void nrn_seg_or_x_arg2(int iarg, Section** psec, double* px) {
208  if (hoc_is_double_arg(iarg)) {
209  *px = chkarg(iarg, 0., 1.);
210  *psec = chk_access();
211  }else{
212  Object* o = *hoc_objgetarg(iarg);
213  *psec = (Section*)0;
214  if (nrnpy_o2loc2_p_) {
215  (*nrnpy_o2loc2_p_)(o, psec, px);
216  }
217  if (!(*psec)) {
218  assert(0);
219  }
220  }
221 }
222 
223 extern "C" double loc_point_process(int pointtype, void* v)
224 {
225  Point_process* pnt = (Point_process*)v;
226  double x;
227  Section *sec;
228  Node *node;
229 
230  if (nrn_is_artificial_[pointsym[pointtype]->subtype]) {
231  hoc_execerror("ARTIFICIAL_CELLs are not located in a section", (char*)0);
232  }
233  nrn_seg_or_x_arg(1, &sec, &x);
234  node = node_exact(sec, x);
235  nrn_loc_point_process(pointtype, pnt, sec, node);
236  return x;
237 }
238 
239 extern "C" double get_loc_point_process(void* v)
240 {
241 #if METHOD3
242  extern int _method3;
243 #endif
244  double x;
245  Point_process *pnt = (Point_process*)v;
246  Section* sec;
247 
248  if (pnt->prop == (Prop *)0) {
249  hoc_execerror("point process not located in a section", (char*)0);
250  }
251  if (nrn_is_artificial_[pnt->prop->type]) {
252  hoc_execerror("ARTIFICIAL_CELLs are not located in a section", (char*)0);
253  }
254  sec = pnt->sec;
255  x = nrn_arc_position(sec, pnt->node);
256  hoc_level_pushsec(sec);
257  return x;
258 }
259 
260 extern "C" double has_loc_point(void* v)
261 {
262  Point_process *pnt = (Point_process*)v;
263  return (pnt->sec != 0);
264 }
265 
267 {
268  static double dummy;
269  double* pd;
270  if (pnt->prop == (Prop *)0) {
271  if (nrn_inpython_ == 1) { /* python will handle the error */
272  hoc_warning("point process not located in a section", (char*)0);
273  nrn_inpython_ = 2;
274  return NULL;
275  }else{
276  hoc_execerror("point process not located in a section", (char*)0);
277  }
278  }
279  if (sym->subtype == NRNPOINTER) {
280  pd = (pnt->prop->dparam)[sym->u.rng.index + index].pval;
281  if (cppp_semaphore) {
282  ++cppp_semaphore;
283  cppp_pointer = &((pnt->prop->dparam)[sym->u.rng.index + index].pval);
284  pd = &dummy;
285  }else if(!pd) {
286 #if 0
287  hoc_execerror(sym->name, "wasn't made to point to anything");
288 #else
289  return (double*)0;
290 #endif
291  }
292  }else{
293  if (pnt->prop->ob) {
294  pd = pnt->prop->ob->u.dataspace[sym->u.rng.index].pval + index;
295  }else{
296  pd = pnt->prop->param + sym->u.rng.index + index;
297  }
298  }
299 /*printf("point_process_pointer %s pd=%lx *pd=%g\n", sym->name, pd, *pd);*/
300  return pd;
301 }
302 
303 extern "C" void steer_point_process(void* v) /* put the right double pointer on the stack */
304 {
305  Symbol* sym;
306  int index;
307  Point_process *pnt = (Point_process*)v;
308  sym = hoc_spop();
309  if (ISARRAY(sym)) {
310  index = hoc_araypt(sym, SYMBOL);
311  }else{
312  index = 0;
313  }
314  hoc_pushpx(point_process_pointer(pnt, sym, index));
315 }
316 
317 void nrn_cppp(void) {
318  cppp_semaphore = 1;
319 }
320 
322  if (cppp_semaphore != 2) {
323  cppp_semaphore = 0;
324  hoc_execerror("not a point process pointer", (char*)0);
325  }
326  cppp_semaphore = 0;
327  *cppp_pointer = hoc_pxpop();
328  hoc_nopop();
329 }
330 
331 #if VECTORIZE
332 extern "C" int v_structure_change;
333 #endif
334 
335 static void free_one_point(Point_process* pnt) /* must unlink from node property list also */
336 {
337  Prop *p, *p1;
338 
339  p = pnt->prop;
340  if (!p) {
341  return;
342  }
343  if (!nrn_is_artificial_[p->type]) {
344  p1 = pnt->node->prop;
345  if (p1 == p) {
346  pnt->node->prop = p1->next;
347  }else for (; p1; p1 = p1->next) {
348  if (p1->next == p) {
349  p1->next = p->next;
350  break;
351  }
352  }
353  }
354 #if VECTORIZE
355  {
356  v_structure_change = 1;
357  }
358 #endif
359  if (p->param) {
360  if (memb_func[p->type].destructor) {
361  memb_func[p->type].destructor(p);
362  }
364  nrn_prop_data_free(p->type, p->param);
365  }
366  if (p->dparam) {
368  }
369  free(p);
370  pnt->prop = (Prop *)0;
371  pnt->node = (Node *)0;
372  if (pnt->sec) {section_unref(pnt->sec);}
373  pnt->sec = (Section *)0;
374 }
375 
376 void clear_point_process_struct(Prop* p) /* called from prop_free */
377 {
378  Point_process* pnt;
379  pnt = (Point_process*)p->dparam[1]._pvoid;
380  if (pnt) {
381  free_one_point(pnt);
382  if (pnt->ob) {
383  if (pnt->ob->observers) {
384  hoc_obj_notify(pnt->ob);
385  }
386  if (pnt->ob->ctemplate->observers) {
387  hoc_template_notify(pnt->ob, 2);
388  }
389  }
390  } else {
391  if (p->ob) {
392  hoc_obj_unref(p->ob);
393  }
394  if (p->param) {
396  nrn_prop_data_free(p->type, p->param);
397  }
398  if (p->dparam) {
400  }
401  free(p);
402  }
403 }
404 
406 {
407  if (ob) {
408  return ob->ctemplate->is_point_ != 0;
409  }
410  return 0;
411 }
412 
o
Definition: seclist.cpp:180
void nrn_loc_point_process(int pointtype, Point_process *pnt, Section *sec, Node *node)
Definition: point.cpp:87
void hoc_nopop()
double * point_process_pointer(Point_process *pnt, Symbol *sym, int index)
Definition: point.cpp:266
void nrn_relocate_old_points(Section *oldsec, Node *oldnode, Section *sec, Node *node)
Definition: point.cpp:162
Definition: hocdec.h:84
void hoc_obj_notify(Object *ob)
Definition: ocobserv.cpp:14
int param_size
Definition: section.h:217
double * param
Definition: section.h:218
#define assert(ex)
Definition: hocassrt.h:26
void nrn_cppp(void)
Definition: point.cpp:317
short type
Definition: cabvars.h:10
void nrn_prop_data_free(int type, double *pd)
Definition: cxprop.cpp:287
void * _vnt
Definition: section.h:269
void * _pvoid
Definition: hocdec.h:186
static int pointtype
Definition: init.cpp:470
Prop * prop_alloc_disallow(Prop **pp, short type, Node *nd)
Definition: treeset.cpp:716
void * create_point_process(int pointtype, Object *ho)
Definition: point.cpp:32
short * nrn_is_artificial_
Definition: init.cpp:231
int nrn_inpython_
Definition: hoc.cpp:37
if(status)
short type
Definition: model.h:58
void hoc_template_notify(Object *ob, int message)
Definition: ocobserv.cpp:42
double * pval
Definition: hocdec.h:180
int hoc_is_double_arg(int narg)
Definition: code.cpp:733
double nrn_arc_position(Section *sec, Node *node)
Definition: cabcode.cpp:1880
Object * hoc_new_opoint(int)
Definition: hocmech.cpp:153
void
#define NRNPOINTER
Definition: nocpout.cpp:100
int is_point_process(Object *ob)
Definition: point.cpp:405
size_t p
double * hoc_pxpop(void)
Definition: code.cpp:827
void notify_freed_val_array(double *p, size_t size)
Definition: ivoc.cpp:104
char * name
Definition: model.h:72
Object * ob
Definition: section.h:224
Memb_func * memb_func
Definition: init.cpp:161
nd
Definition: treeset.cpp:893
static double dummy
Definition: ocptrvector.cpp:27
Object * nrn_new_pointprocess(Symbol *sym)
Definition: point.cpp:54
Object * hoc_new_object(Symbol *, void *)
Definition: hoc_oop.cpp:465
#define v
Definition: md1redef.h:4
static double ** cppp_pointer
Definition: point.cpp:24
Section * nrn_pnt_sec_for_need_
Definition: treeset.cpp:633
void clear_point_process_struct(Prop *p)
Definition: point.cpp:376
#define SYMBOL
Definition: model.h:102
void hoc_level_pushsec(Section *sec)
Definition: cabcode.cpp:2375
void * hoc_mech
Definition: membfunc.h:54
Node * node
Definition: section.h:263
short type
Definition: section.h:215
char * pnt_map
Definition: init.cpp:166
int v_structure_change
Definition: point.cpp:332
Pvmp destructor
Definition: membfunc.h:37
void * observers
Definition: hocdec.h:241
Symbol * sym
Definition: membfunc.h:38
void(* nrnpy_o2loc_p_)(Object *, Section **, double *)
Definition: point.cpp:29
void * presyn_
Definition: section.h:267
void nrn_sec_ref(Section **, Section *)
Definition: solve.cpp:569
Symbol * hoc_spop(void)
double * pval
Definition: hocdec.h:217
Objectdata * dataspace
Definition: hocdec.h:230
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1998
void(* nrnpy_o2loc2_p_)(Object *, Section **, double *)
Definition: point.cpp:30
Prop * prop
Definition: section.h:264
#define printf
Definition: mwprefix.h:26
void nrn_prop_datum_free(int type, Datum *ppd)
Definition: cxprop.cpp:294
const char * secname(Section *sec)
Definition: cabcode.cpp:1787
void hoc_warning(const char *, const char *)
#define ISARRAY(arg)
Definition: hocdec.h:163
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
Section * sec
Definition: section.h:262
Definition: model.h:57
void nrn_seg_or_x_arg2(int iarg, Section **psec, double *px)
Definition: point.cpp:207
Symbol ** pointsym
Definition: init.cpp:164
Definition: section.h:213
char * emalloc(unsigned n)
Definition: list.cpp:189
Object * ob
Definition: section.h:266
Symlist * hoc_built_in_symlist
Definition: symbol.cpp:39
Prop * prop_alloc(Prop **, int, Node *)
Definition: treeset.cpp:688
int ifarg(int)
Definition: code.cpp:1562
double has_loc_point(void *v)
Definition: point.cpp:260
void nrn_seg_or_x_arg(int iarg, Section **psec, double *px)
Definition: point.cpp:191
Datum * dparam
Definition: section.h:219
double loc_point_process(int, void *)
Definition: point.cpp:223
long subtype
Definition: model.h:59
struct Symbol::@52::@53 rng
static void create_artcell_prop(Point_process *pnt, short type)
Definition: point.cpp:146
void steer_point_process(void *v)
Definition: point.cpp:303
void connect_point_process_pointer(void)
Definition: point.cpp:321
Definition: hocdec.h:226
void hoc_push_frame(Symbol *, int)
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:60
long subtype
Definition: init.cpp:122
Prop * nrn_point_prop_
Definition: point.cpp:28
int is_point
Definition: membfunc.h:53
void * nvi_
Definition: section.h:268
struct Prop * next
Definition: section.h:214
sec
Definition: solve.cpp:885
static int cppp_semaphore
Definition: point.cpp:23
void hoc_pushpx(double *d)
Definition: code.cpp:702
void destroy_point_process(void *v)
Definition: point.cpp:77
double get_loc_point_process(void *v)
Definition: point.cpp:239
union Symbol::@18 u
union Object::@54 u
static Node * node(Object *)
Definition: netcvode.cpp:318
void section_unref(Section *)
Definition: solve.cpp:552
Definition: section.h:132
Definition: hocdec.h:176
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
void hoc_pop_frame(void)
Section * chk_access(void)
Definition: cabcode.cpp:437
return NULL
Definition: cabcode.cpp:461
int hoc_araypt(Symbol *, int)
Node * node_exact(Section *sec, double x)
Definition: cabcode.cpp:1956
double chkarg(int, double low, double high)
Definition: code2.cpp:608
short index
Definition: cabvars.h:11
#define NODEAREA(n)
Definition: section.h:115
struct Prop * prop
Definition: section.h:151
static void free_one_point(Point_process *pnt)
Definition: point.cpp:335