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