NEURON
ndatclas.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <stdio.h>
3 #include <InterViews/resource.h>
4 #include "nrnoc2iv.h"
5 #include "classreg.h"
6 
7 #include "membfunc.h"
8 #include "parse.hpp"
9 extern Prop* prop_alloc(Prop**, int, Node*);
10 extern void single_prop_free(Prop*);
13 
14 /*
15 NrnProperty wrapping a Prop of type EXTRACELL has a problem with vext state
16 variables because those are not in the Prop.param array but in Node.ExtNode.
17 At the moment, knowing Prop* does not help with Node*. Note that
18 Node.ExtNode is not allocated by extcell_alloc(Prop*) but by
19 extcell_2d_alloc(Section*) when extracellular is inserted.
20 So, if NrnProperty is wrapping a "real" Prop, it is difficult to find
21 the Node to determine a pointer to vext[i].
22 And if NrnProperty is just wrapping a NrnProperty allocated Prop,
23 the vext states are not allocated. In most cases the issue was avoided
24 because the "user" of NrnProperty knew the Node*
25 
26 It is attractive to get rid of NrnProperty altogether. It is mostly used
27 for iterating over mechanism variables and there are already fairly direct
28 methods to do that. However, NrnProperty, since it calls the mechanism
29 allocation method, provides default PARAMETER values. Apart from the
30 issue of default PARAMETER values, NrnProperty could just wrap a
31 std::vector<double> param with a length that included PARAMETER, ASSIGNED,
32 and STATE (all the other defaults are 0.0). The advantage over
33 allocating a Prop is that the latter includes the extraneous
34 dparam as well as the full SoA and DataHandle apparatus. We could thread
35 the needle by allocating a Prop, copying the default PARAMETERS to the
36 std::vector, and destroying the Prop. Alternatively, the temporary Prop
37 allocation could be avoided by providing an additional mechanism method, e.g.
38 mech_param_defaults(mech_type, double* param) fill values starting at param
39 and avoid the side effect of SoA allocation (which increments
40 v_structure_change).
41 
42 */
43 
44 //----------------------------------------------------
45 /* static */ class NrnPropertyImpl {
46  friend class NrnProperty;
47  explicit NrnPropertyImpl(int mechtype);
48 
49  int iterator_;
50  int type_;
52  std::vector<double> params_{};
53 };
54 
56  : iterator_(-1)
57  , type_(mechtype)
58  , sym_(memb_func[mechtype].sym) {
59  // How many values. nrn_prop_param_size[EXTRACELL] is not all of them
60  // Nor if it is a HocMech.
61  // And nrn_prop_param_size does not include array sizes.
62  int ntotal{};
63  for (int i = 0; i < sym_->s_varn; ++i) {
64  Symbol* s = sym_->u.ppsym[i];
65  ntotal += hoc_total_array_data(s, nullptr);
66  }
67 
68  params_.resize(ntotal);
69  auto& param_default = *memb_func[mechtype].parm_default;
70  int ix = 0;
71  int i = 0;
72  for (auto val: param_default) {
73  Symbol* s = sym_->u.ppsym[i];
74  int n = hoc_total_array_data(s, nullptr);
75  for (int k = 0; k < n; ++k) {
76  params_[ix++] = val;
77  }
78  ++i;
79  }
80 }
81 
82 //---------------------------------------------------
83 /* static */ class SectionListImpl {
84  friend class SectionList;
86  struct hoc_Item* itr_;
87  struct hoc_Item* list_;
88 };
89 
90 //----------------------------------------------------
91 
94  if (!sym) {
96  }
97  if (sym) {
98  if (sym->type == MECHANISM) {
99  /*EMPTY*/
100  } else if (sym->type == TEMPLATE && sym->u.ctemplate->is_point_) {
102 
103  } else {
104  sym = 0;
105  }
106  }
107  if (sym) {
109  } else {
110  npi_ = NULL;
111  hoc_execerror(name, "is not a Mechanism or Point Process");
112  }
113 }
114 
116  if (npi_) {
117  delete npi_;
118  }
119 }
120 
121 const char* NrnProperty::name() const {
122  return npi_->sym_->name;
123 }
124 
125 int NrnProperty::type() const {
126  return npi_->type_;
127 }
128 
130  npi_->iterator_ = -1;
131  return next_var();
132 }
133 
135  if (npi_->iterator_ >= npi_->sym_->s_varn) {
136  return false;
137  } else {
138  return true;
139  }
140 }
141 
143  ++npi_->iterator_;
144  if (more_var()) {
145  return npi_->sym_->u.ppsym[npi_->iterator_];
146  } else {
147  return 0;
148  }
149 }
150 
152  return npi_->sym_->u.ppsym[i];
153 }
154 
155 static std::string strip_suffix(const char* name, const char* suffix) {
156  std::string s = name;
157  std::string suf{"_"};
158  suf += suffix;
159  s.resize(s.rfind(suf));
160  return s;
161 }
162 
163 bool NrnProperty::copy(bool to_prop, Prop* dest, Node* nd_dest, int vartype) {
164  assert(vartype != NRNPOINTER);
165  auto& x = npi_->params_;
166  Prop* p = dest;
167  if (!p || npi_->type_ != p->_type) {
168  return false;
169  }
170 
171  if (p->ob) {
172  Symbol* msym = memb_func[p->_type].sym;
173  auto const cnt = msym->s_varn;
174  // u.ppsym below are the right names but not the right symbols.
175  // Those symbols are in the p->ob->ctemplate->symtable
176  Symlist* symtab = p->ob->ctemplate->symtable;
177  int k = 0;
178  for (int i = 0; i < cnt; ++i) {
179  const Symbol* sym = msym->u.ppsym[i];
180  auto const jmax = hoc_total_array_data(sym, 0);
181  if (vartype == 0 || nrn_vartype(sym) == vartype) {
182  const std::string& s = strip_suffix(sym->name, msym->name);
183  sym = hoc_table_lookup(s.c_str(), symtab);
184  assert(sym);
185  auto const n = sym->u.rng.index;
186  auto const y = p->ob->u.dataspace[n].pval;
187  for (int j = 0; j < jmax; ++j) {
188  if (to_prop) {
189  y[j] = x[k + j];
190  } else {
191  x[k + j] = y[j];
192  }
193  }
194  }
195  k += jmax;
196  }
197  } else {
198  Symbol* msym = memb_func[p->_type].sym;
199  auto const cnt = msym->s_varn;
200  int k = 0;
201  for (int i = 0; i < cnt; ++i) {
202  const Symbol* sym = msym->u.ppsym[i];
203  auto const jmax = hoc_total_array_data(sym, 0);
204  if (vartype == 0 || nrn_vartype(sym) == vartype) {
205  auto const n = sym->u.rng.index;
206  for (int j = 0; j < jmax; ++j) {
207  if (p->_type == EXTRACELL && n == neuron::extracellular::vext_pseudoindex()) {
208  if (to_prop) {
209  nd_dest->extnode->v[j] = x[k + j];
210  } else {
211  x[k + j] = nd_dest->extnode->v[j];
212  }
213  } else {
214  if (to_prop) {
215  p->param_legacy(n + j) = x[k + j];
216  } else {
217  x[k + j] = p->param_legacy(n + j);
218  }
219  }
220  }
221  }
222  k += jmax;
223  }
224  }
225  return true;
226 }
227 
228 bool NrnProperty::copy_out(NrnProperty& np, int /* vartype */) {
229  const auto& psrc = npi_->params_;
230  auto& pdest = np.npi_->params_;
231  pdest = psrc;
232  return true;
233 }
234 
236  Symbol* rsym = nullptr;
237  int i, cnt;
238  cnt = npi_->sym_->s_varn;
239  for (i = 0; i < cnt; ++i) {
240  Symbol* sym = npi_->sym_->u.ppsym[i];
241  if (strcmp(sym->name, name) == 0) {
242  rsym = sym;
243  break;
244  }
245  }
246  return rsym;
247 }
248 
250  assert(s);
251  if (s->type != RANGEVAR && s->type != RANGEOBJ) {
252  hoc_execerror(s->name, "not a range variable");
253  }
254  double* raw = &npi_->params_[s->u.rng.index + index];
255  return static_cast<neuron::container::data_handle<double>>(raw);
256 }
257 
258 //--------------------------------------------------
260  sli_ = new SectionListImpl();
261  check_obj_type(ob, "SectionList");
262  sli_->ob_ = ob;
263  ++ob->refcount;
264  sli_->list_ = (struct hoc_Item*) ob->u.this_pointer;
265  sli_->itr_ = sli_->list_;
266 }
269  delete sli_;
270 }
272  sli_->itr_ = sli_->list_->next;
273  return next();
274 }
276  Section* sec;
277  if (sli_->itr_ == sli_->list_) {
278  sec = NULL;
279  } else {
280  sec = hocSEC(sli_->itr_);
281  sli_->itr_ = sli_->itr_->next;
282  }
283  return sec;
284 }
285 
287  Object* ob = sli_->ob_;
288  return ob;
289 }
Symbol * findsym(const char *rangevar)
Definition: ndatclas.cpp:235
NrnProperty(const char *)
Definition: ndatclas.cpp:92
virtual ~NrnProperty()
Definition: ndatclas.cpp:115
Symbol * var(int)
Definition: ndatclas.cpp:151
Symbol * first_var()
Definition: ndatclas.cpp:129
const char * name() const
Definition: ndatclas.cpp:121
int type() const
Definition: ndatclas.cpp:125
bool copy_out(NrnProperty &dest, int vartype=0)
Definition: ndatclas.cpp:228
Symbol * next_var()
Definition: ndatclas.cpp:142
bool more_var()
Definition: ndatclas.cpp:134
neuron::container::data_handle< double > pval(const Symbol *, int index)
Definition: ndatclas.cpp:249
NrnPropertyImpl * npi_
Definition: ndatclas.h:28
bool copy(bool to_prop, Prop *dest, Node *nd_dest, int vartype=0)
Definition: ndatclas.cpp:163
NrnPropertyImpl(int mechtype)
Definition: ndatclas.cpp:55
std::vector< double > params_
Definition: ndatclas.cpp:52
Symbol * sym_
Definition: ndatclas.cpp:51
SectionList(Object *)
Definition: ndatclas.cpp:259
SectionListImpl * sli_
Definition: ndatclas.h:40
virtual ~SectionList()
Definition: ndatclas.cpp:267
Object * nrn_object()
Definition: ndatclas.cpp:286
Section * next()
Definition: ndatclas.cpp:275
Section * begin()
Definition: ndatclas.cpp:271
Object * ob_
Definition: ndatclas.cpp:85
struct hoc_Item * itr_
Definition: ndatclas.cpp:86
struct hoc_Item * list_
Definition: ndatclas.cpp:87
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:48
#define cnt
Definition: tqueue.hpp:44
#define sec
Definition: md1redef.h:20
#define i
Definition: md1redef.h:19
static std::vector< double > param_default
Definition: extcelln.cpp:93
static RNG::key_type k
Definition: nrnran123.cpp:9
size_t hoc_total_array_data(const Symbol *s, Objectdata *obd)
Definition: hoc_oop.cpp:95
void check_obj_type(Object *obj, const char *type_name)
Definition: hoc_oop.cpp:2098
void hoc_dec_refcount(Object **pobj)
Definition: hoc_oop.cpp:1850
#define assert(ex)
Definition: hocassrt.h:24
#define hocSEC(q)
Definition: hoclist.h:87
#define NRNPOINTER
Definition: membfunc.hpp:83
#define EXTRACELL
Definition: membfunc.hpp:61
#define RANGEOBJ
Definition: model.h:124
const char * name
Definition: init.cpp:16
static int np
Definition: mpispike.cpp:25
void hoc_execerror(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:39
std::size_t vext_pseudoindex()
Definition: membfunc.h:150
static std::string strip_suffix(const char *name, const char *suffix)
Definition: ndatclas.cpp:155
Symlist * hoc_top_level_symlist
Definition: symdir.cpp:16
Prop * prop_alloc(Prop **, int, Node *)
Definition: treeset.cpp:671
void single_prop_free(Prop *)
Definition: treeset.cpp:718
Symlist * hoc_built_in_symlist
Definition: symbol.cpp:28
static char suffix[256]
Definition: nocpout.cpp:135
int const size_t const size_t n
Definition: nrngsl.h:10
size_t p
size_t j
s
Definition: multisend.cpp:521
short index
Definition: cabvars.h:11
std::vector< Memb_func > memb_func
Definition: init.cpp:145
int nrn_vartype(const Symbol *sym)
Definition: eion.cpp:503
#define NULL
Definition: spdefs.h:105
double * v
Definition: section_fwd.hpp:40
Definition: section.h:105
Extnode * extnode
Definition: section.h:199
Definition: hocdec.h:173
void * this_pointer
Definition: hocdec.h:178
int refcount
Definition: hocdec.h:174
union Object::@47 u
Definition: section.h:231
Definition: model.h:47
union Symbol::@28 u
Symbol ** ppsym
Definition: hocdec.h:125
struct Symbol::@45::@46 rng
short type
Definition: model.h:48
long subtype
Definition: model.h:49
cTemplate * ctemplate
Definition: hocdec.h:126
unsigned s_varn
Definition: hocdec.h:129
char * name
Definition: model.h:61
Definition: hocdec.h:75
Symlist * symtable
Definition: hocdec.h:148
int is_point_
Definition: hocdec.h:150
Symbol * sym
Definition: hoclist.h:39
hoc_Item * next
Definition: hoclist.h:44