NEURON
datapath.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <stdio.h>
3 #include <InterViews/resource.h>
4 #include <OS/string.h>
5 #include <OS/table.h>
6 #include <OS/list.h>
7 #include "hoclist.h"
8 #include <nrnpython_config.h>
9 #if HAVE_IV
10 #include "graph.h"
11 #endif
12 #include "datapath.h"
13 #include "ivocvect.h"
14 
15 #if !defined(CABLE)
16 // really belongs in vector.cpp but this is convenient since it will be
17 // present in ivoc but not in nrniv
18 void nrn_vecsim_add(void*, bool) {printf("nrn_vecsym_add implemented in nrniv\n");}
19 void nrn_vecsim_remove(void*) {printf("nrn_vecsym_remove implemented in nrniv\n");}
20 #if HAVE_IV
21 void graphLineRecDeleted(GraphLine*){}
22 void Graph::simgraph(){}
25 #endif
26 // another hack so ivoc will have these names which nrniv gets elsewhere
28 void bbs_done(){}
29 void bbs_handle(){}
31 
32 #ifdef WIN32
33 void* dll_lookup(struct DLL*, const char*){return NULL;}
34 struct DLL* dll_load(const char*){return NULL;}
35 #endif
36 #endif
37 
38 #if CABLE
39 #include "nrnoc2iv.h"
40 #include "membfunc.h"
41 #else
42 #include "oc2iv.h"
43 #endif
44 
45 #include "parse.hpp"
49 
50 /*static*/ class PathValue {
51 public:
52  PathValue();
53  ~PathValue();
56  double original;
57  char* str;
58 };
60  path = NULL;
61  str = NULL;
62  sym = NULL;
63 }
65  if (path) {
66  delete path;
67  }
68 }
69 
70 declareTable(PathTable, void*, PathValue*);
71 implementTable(PathTable, void*, PathValue*);
72 declarePtrList(StringList, char);
73 implementPtrList(StringList, char);
74 
75 
77 private:
78  friend class HocDataPaths;
79  HocDataPathImpl(int, int);
80  ~HocDataPathImpl();
81 
82  void search();
83  void found(double*, const char*, Symbol*);
84  void found(char**, const char*, Symbol*);
85  PathValue* found_v(void*, const char*, Symbol*);
86 
87  void search(Objectdata*, Symlist*);
88  void search_vectors();
89 #if CABLE
90  void search_pysec();
91  void search(Section*);
92  void search(Node*, double x);
93  void search(Point_process*, Symbol*);
94  void search(Prop*, double x);
95 #endif
96 private:
97  PathTable* table_;
98  StringList strlist_;
99  int size_, count_, found_so_far_;
101 };
102 
103 #define sentinal 123456789.e15
104 
106 
107 HocDataPaths::HocDataPaths(int size, int pathstyle) {
108  if (!sym_vec) {
109  sym_vec = hoc_table_lookup("Vector", hoc_built_in_symlist);
110 #if CABLE
111  sym_v = hoc_table_lookup("v", hoc_built_in_symlist);
112  sym_vext = hoc_table_lookup("vext", hoc_built_in_symlist);
113  sym_rallbranch = hoc_table_lookup("rallbranch", hoc_built_in_symlist);
114  sym_L = hoc_table_lookup("L", hoc_built_in_symlist);
115  sym_Ra = hoc_table_lookup("Ra", hoc_built_in_symlist);
116 #endif
117  }
118  impl_ = new HocDataPathImpl(size, pathstyle);
119 }
120 
122  delete impl_;
123 }
124 
126  return impl_->pathstyle_;
127 }
128 
129 void HocDataPaths::append(double* pd) {
130 // printf("HocDataPaths::append\n");
131  PathValue* pv;
132  if (pd && !impl_->table_->find(pv, (void*)pd)) {
133  impl_->table_->insert((void*)pd, new PathValue);
134  ++impl_->count_;
135  }
136 }
137 
139 // printf("HocDataPaths::search\n");
140  impl_->search();
141  if (impl_->count_ > impl_->found_so_far_) {
142 // printf("HocDataPaths:: didn't find paths to all the pointers\n");
143 // this has proved to be too often a false alarm since most panels are
144 // in boxes controlled by objects which have no reference but are
145 // deleted when the window is closed
146  }
147 }
148 
150  assert(impl_->pathstyle_ != 2);
151 // printf("HocDataPaths::retrieve\n");
152  PathValue* pv;
153  if (impl_->table_->find(pv, (void*)pd)) {
154  return pv->path;
155  }else{
156  return NULL;
157  }
158 }
159 
161 // printf("HocDataPaths::retrieve\n");
162  PathValue* pv;
163  if (impl_->table_->find(pv, (void*)pd)) {
164  return pv->sym;
165  }else{
166  return NULL;
167  }
168 }
169 
170 void HocDataPaths::append(char** pd) {
171 // printf("HocDataPaths::append\n");
172  PathValue* pv;
173  if (*pd && !impl_->table_->find(pv, (void*)pd)) {
174  pv = new PathValue;
175  pv->str = *pd;
176  impl_->table_->insert((void*)pd, pv);
177  ++impl_->count_;
178  }
179 }
180 
182 // printf("HocDataPaths::retrieve\n");
183  PathValue* pv;
184  if (impl_->table_->find(pv, (void*)pd)) {
185  return pv->path;
186  }else{
187  return NULL;
188  }
189 
190 }
191 
192 /*------------------------------*/
193 HocDataPathImpl::HocDataPathImpl(int size, int pathstyle) {
194  pathstyle_ = pathstyle;
195  table_ = new PathTable(size);
196  size_ = size;
197  count_ = 0;
198  found_so_far_ = 0;
199 }
200 
202  for (TableIterator(PathTable) i(*table_); i.more(); i.next()) {
203  PathValue* pv = i.cur_value();
204  delete pv;
205  }
206  delete table_;
207 }
208 
210  found_so_far_ = 0;
211  if (table_) {
212  for (TableIterator(PathTable) i(*table_); i.more(); i.next()) {
213  PathValue* pv = i.cur_value();
214  if (pv->str) {
215  char** pstr = (char**)i.cur_key();
216  *pstr = NULL;
217  }else{
218  double* pd = (double*)i.cur_key();
219  pv->original = *pd;
220  *pd = sentinal;
221  }
222  }
223  }
224  if (pathstyle_ > 0) {
225  search(hoc_top_level_data, hoc_built_in_symlist);
226  search(hoc_top_level_data, hoc_top_level_symlist);
227  }else{
228  search(hoc_top_level_data, hoc_top_level_symlist);
229  search(hoc_top_level_data, hoc_built_in_symlist);
230  }
231 #if CABLE
232  if (found_so_far_ < count_) {
233  search_pysec();
234  }
235 #endif
236  if (found_so_far_ < count_) {
237  search_vectors();
238  }
239  if (table_) {
240  for (TableIterator(PathTable) i(*table_); i.more(); i.next()) {
241  PathValue* pv = i.cur_value();
242  if (pv->str) {
243  char** pstr = (char**)i.cur_key();
244  *pstr = pv->str;
245  }else{
246  double* pd = (double*)i.cur_key();
247  *pd = pv->original;
248  }
249  }
250  }
251 }
252 
253 PathValue* HocDataPathImpl::found_v(void* v, const char* buf, Symbol* sym) {
254  PathValue* pv;
255  if (pathstyle_ != 2) {
256  char path[500];
257  CopyString cs("");
258  long i, cnt;
259  int len = 0;
260  cnt = strlist_.count();
261  for (i=0; i< cnt; ++i) {
262  sprintf(path, "%s%s.", cs.string(), strlist_.item(i));
263  cs = path;
264  }
265  sprintf(path, "%s%s", cs.string(), buf);
266  if (!table_->find(pv, v)) {
267  hoc_warning("table lookup failed for pointer for-", path);
268  return NULL;
269  }
270  if (!pv->path) {
271  pv->path = new CopyString(path);
272  pv->sym = sym;
273  ++found_so_far_;
274  }
275 //printf("HocDataPathImpl::found %s\n", path);
276  }else{
277  if (!table_->find(pv, v)) {
278  hoc_warning("table lookup failed for pointer for-", sym->name);
279  return NULL;
280  }
281  if (!pv->sym) {
282  pv->sym = sym;
283  ++found_so_far_;
284  }
285  }
286  return pv;
287 }
288 
289 void HocDataPathImpl::found(double* pd, const char* buf, Symbol* sym) {
290  PathValue* pv = found_v((void*)pd, buf, sym);
291  if (pv) {
292  *pd = pv->original;
293  }
294 }
295 
296 void HocDataPathImpl::found(char** pstr, const char* buf, Symbol* sym) {
297  PathValue* pv = found_v((void*)pstr, buf,sym);
298  if (pv) {
299  *pstr = pv->str;
300  }else{
301  hoc_assign_str(pstr, "couldn't find");
302  }
303 }
304 
306  Symbol* sym;
307  int i, total;
308  char buf[200];
309  CopyString cs("");
310  if (sl) for (sym = sl->first; sym; sym = sym->next) {
311  if (sym->cpublic != 2) {
312  switch (sym->type) {
313  case VAR: {
314  double* pd;
315  if (sym->subtype == NOTUSER) {
316  pd = object_pval(sym, od);
317  total = hoc_total_array_data(sym, od);
318  }else if (sym->subtype == USERDOUBLE) {
319  pd = sym->u.pval;
320  total = 1;
321  }else{
322  break;
323  }
324  for (i=0; i < total; ++i) {
325  if (pd[i] == sentinal) {
326 sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od));
327  cs = buf;
328  found(pd + i, cs.string(), sym);
329  }
330  }
331  }
332  break;
333  case STRING: {
334  char** pstr = object_pstr(sym, od);
335  if (*pstr == NULL) {
336  sprintf(buf, "%s", sym->name);
337  cs = buf;
338  found(pstr, cs.string(), sym);
339  }
340  }
341  break;
342  case OBJECTVAR: {
343  if (pathstyle_ > 0) { break; }
344  Object** obp = object_pobj(sym, od);
345  total = hoc_total_array_data(sym, od);
346  for (i=0; i < total; ++i) if (obp[i] && ! obp[i]->recurse) {
347  cTemplate* t = (obp[i])->ctemplate;
348  if (!t->constructor) {
349  // not the this pointer
350  if (obp[i]->u.dataspace != od) {
351 sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od));
352 cs = buf;
353 strlist_.append((char*)cs.string());
354 obp[i]->recurse = 1;
355 search(obp[i]->u.dataspace, obp[i]->ctemplate->symtable);
356 obp[i]->recurse = 0;
357 strlist_.remove(strlist_.count()-1);
358  }
359  }else{
360  /* point processes */
361 #if CABLE
362  if (t->is_point_) {
363 sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od));
364 cs = buf;
365 strlist_.append((char*)cs.string());
366 search((Point_process*)obp[i]->u.this_pointer, sym);
367 strlist_.remove(strlist_.count()-1);
368  }
369 #endif
370  /* seclists, object lists */
371  }
372  }
373  }
374  break;
375 #if CABLE
376  case SECTION: {
377  total = hoc_total_array_data(sym, od);
378  for (i=0; i < total; ++i) {
379  hoc_Item** pitm = object_psecitm(sym, od);
380  if (pitm[i]) {
381 sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od));
382  cs = buf;
383  strlist_.append((char*)cs.string());
384  search(hocSEC(pitm[i]));
385  strlist_.remove(strlist_.count()-1);
386  }
387  }
388  }
389  break;
390 #endif
391  case TEMPLATE: {
392  cTemplate* t = sym->u.ctemplate;
393  hoc_Item* q;
394  ITERATE (q, t->olist) {
395  Object* obj = OBJ(q);
396  sprintf(buf, "%s[%d]", sym->name, obj->index);
397  cs = buf;
398  strlist_.append((char*)cs.string());
399  if (!t->constructor) {
400  search(obj->u.dataspace, t->symtable);
401  }else{
402 #if CABLE
403  if (t->is_point_) {
404 search((Point_process*)obj->u.this_pointer, sym);
405  }
406 #endif
407  }
408  strlist_.remove(strlist_.count()-1);
409  }
410  }
411  break;
412  }
413  }
414  }
415 }
416 
418  int i, cnt;
419  char buf[200];
420  CopyString cs("");
421  cTemplate* t = sym_vec->u.ctemplate;
422  hoc_Item* q;
423  ITERATE (q, t->olist) {
424  Object* obj = OBJ(q);
425  sprintf(buf, "%s[%d]", sym_vec->name, obj->index);
426  cs = buf;
427  strlist_.append((char*)cs.string());
428  Vect* vec = (Vect*)obj->u.this_pointer;
429  int size = vec->size();
430  double* pd = vector_vec(vec);
431  for (i=0; i < size; ++i) {
432  if (pd[i] == sentinal) {
433  sprintf(buf, "x[%d]", i);
434  found(pd + i, buf, sym_vec);
435  }
436  }
437  strlist_.remove(strlist_.count()-1);
438  }
439 }
440 
441 #if CABLE
442 
443 void HocDataPathImpl::search_pysec() {
444 #if USE_PYTHON
445  CopyString cs("");
446  hoc_Item* qsec;
448  if (sec->prop && sec->prop->dparam[PROP_PY_INDEX]._pvoid) {
449  cs = secname(sec);
450  strlist_.append((char*)cs.string());
451  search(sec);
452  strlist_.remove(strlist_.count()-1);
453  }
454  }
455 #endif
456 }
457 
459  if (sec->prop->dparam[2].val == sentinal) {
460  found(&sec->prop->dparam[2].val, "L", sym_L);
461  }
462  if (sec->prop->dparam[4].val == sentinal) {
463  found(&sec->prop->dparam[4].val, "rallbranch", sym_rallbranch);
464  }
465  if (sec->prop->dparam[7].val == sentinal) {
466  found(&sec->prop->dparam[7].val, "Ra", sym_Ra);
467  }
468  if (!sec->parentsec && sec->parentnode) {
469  search(sec->parentnode, sec->prop->dparam[1].val);
470  }
471  for (int i = 0; i < sec->nnode; ++i) {
472  search(sec->pnode[i], nrn_arc_position(sec, sec->pnode[i]));
473  }
474 }
475 void HocDataPathImpl::search(Node* nd, double x) {
476  char buf[100];
477  int i, cnt;
478  CopyString cs("");
479  if (NODEV(nd) == sentinal) {
480  sprintf(buf, "v(%g)", x);
481  found(&NODEV(nd), buf, sym_v);
482  }
483 
484 #if EXTRACELLULAR
485  if (nd->extnode) {
486  int i;
487  for (i=0; i < nlayer; ++i) {
488  if (nd->extnode->v[i] == sentinal) {
489  if (i == 0) {
490  sprintf(buf, "vext(%g)", x);
491  }else{
492  sprintf(buf, "vext[%d](%g)", i, x);
493  }
494  found(&(nd->extnode->v[i]), buf, sym_vext);
495  }
496  }
497  }
498 #endif
499 
500  Prop* p;
501  for (p = nd->prop; p; p = p->next) {
502  if (!memb_func[p->type].is_point) {
503  search(p, x);
504  }
505  }
506 }
507 
509  if (pp->prop) {
510  search(pp->prop, -1);
511  }
512 }
513 
514 void HocDataPathImpl::search(Prop* prop, double x) {
515  char buf[200];
516  int type = prop->type;
517  Symbol* sym = memb_func[type].sym;
518  Symbol* psym;
519  double* pd;
520  int i, imax, k=0, ir, kmax = sym->s_varn;
521 
522  for (k=0; k < kmax; ++k) {
523  psym = sym->u.ppsym[k];
524  if (psym->subtype == NRNPOINTER) { continue; }
525  ir = psym->u.rng.index;
526  if (memb_func[type].hoc_mech) {
527  pd = prop->ob->u.dataspace[ir].pval;
528  }else{
529  pd = prop->param + ir;
530  }
531  imax = hoc_total_array_data(psym, 0);
532  for (i=0; i < imax; ++i) {
533  if (pd[i] == sentinal) {
534 if (x < 0) {
535  sprintf(buf, "%s%s", psym->name, hoc_araystr(psym, i, 0));
536 }else{
537  sprintf(buf, "%s%s(%g)", psym->name, hoc_araystr(psym, i, 0), x);
538 }
539  found(pd + i, buf, psym);
540  }
541  }
542  }
543 }
544 
545 #endif
struct DLL * dll_load(char *filename)
Definition: dll.cpp:330
int bbs_poll_
Definition: datapath.cpp:27
declarePtrList(StringList, char)
Definition: hocdec.h:84
double * v
Definition: section.h:195
size_t hoc_total_array_data(Symbol *s, Objectdata *obd)
Definition: hoc_oop.cpp:106
double * param
Definition: section.h:218
struct Prop * prop
Definition: section.h:62
#define assert(ex)
Definition: hocassrt.h:26
short type
Definition: cabvars.h:10
short nnode
Definition: section.h:41
HocDataPathImpl(int, int)
Definition: datapath.cpp:193
String * retrieve(double *)
Definition: datapath.cpp:149
#define hocSEC(q)
Definition: hoclist.h:66
struct Node * parentnode
Definition: section.h:50
#define prop
Definition: md1redef.h:29
declareTable(PathTable, void *, PathValue *)
#define NODEV(n)
Definition: section.h:114
#define Vect
Definition: ivocvect.h:14
short type
Definition: model.h:58
void search()
Definition: datapath.cpp:138
struct Section * parentsec
Definition: section.h:42
static Symbol * sym_vec
Definition: datapath.cpp:105
void nrn_vecsim_remove(void *)
Definition: datapath.cpp:19
#define ITERATE(itm, lst)
Definition: model.h:25
double nrn_arc_position(Section *sec, Node *node)
Definition: cabcode.cpp:1880
Symlist * symtable
Definition: hocdec.h:196
#define NRNPOINTER
Definition: nocpout.cpp:100
void * this_pointer
Definition: hocdec.h:231
size_t p
static Symbol * sym_vext
Definition: datapath.cpp:105
CopyString * path
Definition: datapath.cpp:54
Object ** object_pobj(Symbol *sym, Objectdata *od)
Definition: oc2iv.h:48
void found(double *, const char *, Symbol *)
Definition: datapath.cpp:289
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:134
static Symbol * sym_Ra
Definition: datapath.cpp:105
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
void append(double *)
Definition: datapath.cpp:129
#define v
Definition: md1redef.h:4
virtual ~HocDataPaths()
Definition: datapath.cpp:121
void nrnbbs_context_wait()
Definition: datapath.cpp:30
static philox4x32_key_t k
Definition: nrnran123.cpp:11
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
hoc_List * olist
Definition: hocdec.h:203
short type
Definition: section.h:215
const char * string() const
Definition: string.h:139
PathValue * found_v(void *, const char *, Symbol *)
Definition: datapath.cpp:253
unsigned s_varn
Definition: hocdec.h:157
Symlist * hoc_top_level_symlist
Definition: code2.cpp:662
void hoc_assign_str(char **cpp, const char *buf)
Definition: code.cpp:2337
Symbol * sym
Definition: membfunc.h:38
sl
Definition: seclist.cpp:186
double * object_pval(Symbol *sym, Objectdata *od)
Definition: oc2iv.h:39
#define NOTUSER
Definition: hocdec.h:91
implementTable(PathTable, void *, PathValue *)
HocStruct Symbol ** ppsym
Definition: hocdec.h:149
double * pval
Definition: hocdec.h:217
static Symbol * sym_L
Definition: datapath.cpp:105
Objectdata * dataspace
Definition: hocdec.h:230
hoc_Item ** object_psecitm(Symbol *sym, Objectdata *od)
Definition: oc2iv.h:51
Prop * prop
Definition: section.h:264
#define printf
Definition: mwprefix.h:26
const char * secname(Section *sec)
Definition: cabcode.cpp:1787
void hoc_warning(const char *, const char *)
#define CopyString
Definition: _defines.h:2
void search_vectors()
Definition: datapath.cpp:417
#define STRING
Definition: bbslsrv.cpp:9
#define PROP_PY_INDEX
Definition: section.h:211
PathTable * table_
Definition: datapath.cpp:97
#define cnt
Definition: spt2queue.cpp:19
#define ForAllSections(sec)
Definition: section.h:317
void *(* constructor)(struct Object *)
Definition: hocdec.h:206
double * pval
Definition: hocdec.h:136
#define USERDOUBLE
Definition: hocdec.h:93
Definition: model.h:57
Definition: section.h:213
int is_point_
Definition: hocdec.h:198
void * dll_lookup(struct DLL *Pdll, char *name)
Definition: dll.cpp:733
Symlist * hoc_built_in_symlist
Definition: symbol.cpp:39
void record_uninstall()
#define nlayer
Definition: section.h:187
HocStruct Symbol * next
Definition: hocdec.h:161
#define TableIterator(Table)
Definition: table.h:38
Datum * dparam
Definition: section.h:219
static Symbol * sym_rallbranch
Definition: datapath.cpp:105
Symbol * sym
Definition: datapath.cpp:55
long subtype
Definition: model.h:59
struct Symbol::@52::@53 rng
#define OBJ(q)
Definition: hoclist.h:67
HocDataPaths(int=1000, int pathstyle=0)
Definition: datapath.cpp:107
short cpublic
Note: public is a reserved keyword.
Definition: hocdec.h:125
double original
Definition: datapath.cpp:56
Definition: hocdec.h:226
HocStruct cTemplate * ctemplate
Definition: hocdec.h:151
Symbol * retrieve_sym(double *)
Definition: datapath.cpp:160
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:60
#define i
Definition: md1redef.h:12
char ** object_pstr(Symbol *sym, Objectdata *od)
Definition: oc2iv.h:45
int is_point
Definition: membfunc.h:53
char * str
Definition: datapath.cpp:57
double * vector_vec(Vect *v)
Definition: ivocvect.cpp:271
struct Prop * next
Definition: section.h:214
~PathValue()
Definition: datapath.cpp:64
Definition: string.h:34
sec
Definition: solve.cpp:885
short recurse
Definition: hocdec.h:242
char buf[512]
Definition: init.cpp:13
struct Node ** pnode
Definition: section.h:51
#define imax
implementPtrList(StringList, char)
char * hoc_araystr(Symbol *sym, int index, Objectdata *obd)
Definition: code.cpp:2354
union Symbol::@18 u
void bbs_handle()
Definition: datapath.cpp:29
union Object::@54 u
static Symbol * pv[4]
Definition: partial.cpp:80
double t
Definition: init.cpp:123
Definition: section.h:132
StringList strlist_
Definition: datapath.cpp:98
size_t q
double val
Definition: hocdec.h:177
void nrn_vecsim_add(void *, bool)
Definition: datapath.cpp:18
int index
Definition: hocdec.h:228
void record_install()
void simgraph()
return NULL
Definition: cabcode.cpp:461
#define sentinal
Definition: datapath.cpp:103
struct Extnode * extnode
Definition: section.h:160
static Symbol * sym_v
Definition: datapath.cpp:105
void bbs_done()
Definition: datapath.cpp:28
HocDataPathImpl * impl_
Definition: datapath.h:23
struct Prop * prop
Definition: section.h:151
HocStruct Symbol * first
Definition: hocdec.h:85