NEURON
vrecord.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 #include <OS/list.h>
4 #include <OS/string.h>
5 #include <OS/math.h>
6 #if HAVE_IV
7 #include "ivoc.h"
8 #endif
9 #include "nrnoc2iv.h"
10 #include "ocobserv.h"
11 #include "ivocvect.h"
12 #include <stdio.h>
13 
14 #include "ocpointer.h"
15 #include "vrecitem.h"
16 #include "netcvode.h"
17 #include "cvodeobj.h"
18 
19 extern double t;
21 extern "C" Point_process* ob2pntproc(Object*);
22 
23 //Vector.play_remove()
24 void nrn_vecsim_remove(void* v) {
25  PlayRecord* pr;
26  while ((pr = net_cvode_instance->playrec_uses(v)) != 0) {
27  delete pr;
28  }
29 }
30 
31 void nrn_vecsim_add(void* v, bool record) {
32  IvocVect* yvec, *tvec, *dvec;
33  extern short* nrn_is_artificial_;
34  double* pvar = NULL;
35  char* s = NULL;
36  double ddt;
37  Object* ppobj = NULL;
38  int iarg = 0;
39 
40  yvec = (IvocVect*)v;
41 
42  if (hoc_is_object_arg(1)) {
43  iarg = 1;
44  ppobj = *hoc_objgetarg(1);
45  if (!ppobj || ppobj->ctemplate->is_point_ <= 0
46  || nrn_is_artificial_[ob2pntproc(ppobj)->prop->type]
47  ) {
48  hoc_execerror("Optional first arg is not a POINT_PROCESS", 0);
49  }
50  }
51  if (record == false && hoc_is_str_arg(iarg+1)) {//statement involving $1
52  // Vector.play("proced($1)", ...)
53  s = gargstr(iarg+1);
54  }else if (record == false && hoc_is_double_arg(iarg+1)) {// play that element
55  // Vector.play(index)
56  // must be a VecPlayStep and nothing else
57  VecPlayStep* vps = (VecPlayStep*)net_cvode_instance->playrec_uses(v);
58  if (vps) {
59  int j = (int)chkarg(iarg+1, 0., yvec->size()-1);
60  if (vps->si_) {
61  vps->si_->play_one(yvec->elem(j));
62  }
63  }
64  return;
65  }else{
66  // Vector.play(&SEClamp[0].amp1, ...)
67  // Vector.record(&SEClamp[0].i, ...)
68  pvar = hoc_pgetarg(iarg+1);
69  }
70  tvec = NULL;
71  dvec = NULL;
72  ddt = -1.;
73  int con = 0;
74  if (ifarg(iarg+2)) {
75  if (hoc_is_object_arg(iarg+2)) {
76  // Vector...(..., tvec)
77  tvec = vector_arg(iarg+2);
78  }else{
79  // Vector...(..., Dt)
80  ddt = chkarg(iarg+2, 1e-9, 1e10);
81  }
82  if (ifarg(iarg+3)) {
83  if (hoc_is_double_arg(iarg+3)) {
84  con = (int)chkarg(iarg+3, 0., 1.);
85  }else{
86  dvec = vector_arg(iarg+3);
87  con = 1;
88  }
89  }
90  }
91 
92 // tvec can be used for many record/play items
93 // if (tvec) { nrn_vecsim_remove(tvec); }
94  if (record) {
95  // yvec can be used only for one record (but many play)
96  if (yvec) { nrn_vecsim_remove(yvec); }
97  if (tvec) {
98  new VecRecordDiscrete(pvar, yvec, tvec, ppobj);
99  } else if (ddt > 0.) {
100  new VecRecordDt(pvar, yvec, ddt, ppobj);
101  } else if (pvar == &t) {
102  new TvecRecord(chk_access(), yvec, ppobj);
103  } else {
104  new YvecRecord(pvar, yvec, ppobj);
105  }
106  }else{
107  if (con) {
108  if (!tvec) {
109 hoc_execerror("Second argument of Vector.play in continuous mode must be a time vector", 0);
110  }
111  if (s) {
112  new VecPlayContinuous(s, yvec, tvec, dvec, ppobj);
113  }else{
114  new VecPlayContinuous(pvar, yvec, tvec, dvec, ppobj);
115  }
116  }else{
117  if (!tvec && ddt == -1.) {
118  chkarg(iarg+2, 1e-9, 1e10);
119  }
120  if (s) {
121  new VecPlayStep(s, yvec, tvec, ddt, ppobj);
122  }else{
123  new VecPlayStep(pvar, yvec, tvec, ddt, ppobj);
124  }
125  }
126  }
127 }
128 
129 VecPlayStep::VecPlayStep(double* pd, IvocVect* y, IvocVect* t, double dt, Object* ppobj) : PlayRecord(pd, ppobj) {
130 //printf("VecPlayStep\n");
131  init(y, t, dt);
132 }
133 
134 VecPlayStep::VecPlayStep(const char* s, IvocVect* y, IvocVect* t, double dt, Object* ppobj) : PlayRecord(&NODEV(chk_access()->pnode[0]), ppobj) {
135 //printf("VecPlayStep\n");
136  init(y, t, dt);
137  si_ = new StmtInfo(s);
138 }
139 
140 void VecPlayStep::init(IvocVect* y, IvocVect* t, double dt) {
141  y_ = y;
142  t_ = t;
143  dt_ = dt;
144  ObjObservable::Attach(y_->obj_, this);
145  if (t_) {
146  ObjObservable::Attach(t_->obj_, this);
147  }
148  e_ = new PlayRecordEvent();
149  e_->plr_ = this;
150  si_ = NULL;
151 }
152 
153 
155 //printf("~VecPlayStep\n");
156  ObjObservable::Detach(y_->obj_, this);
157  if (t_) {
158  ObjObservable::Detach(t_->obj_, this);
159  }
160  delete e_;
161  if (si_) {
162  delete si_;
163  }
164 }
165 
167 // printf("%s VecPlayStep disconnect\n", hoc_object_name(y_->obj_));
168  delete this;
169 }
170 
172  play_add(cv);
173 }
174 
176  current_index_ = 0;
177  NrnThread* nt = nrn_threads;
178  if (cvode_ && cvode_->nth_) {
179  nt = cvode_->nth_;
180  }
181  if (t_) {
182  if (t_->size() > 0) {
183  e_->send(t_->elem(0), net_cvode_instance, nt);
184  }
185  }else{
186  e_->send(0., net_cvode_instance, nt);
187  }
188 }
189 
190 void VecPlayStep::deliver(double tt, NetCvode* ns) {
191  NrnThread* nt = nrn_threads + ith_;
192  if (cvode_) {
194  if (cvode_->nth_) { nt = cvode_->nth_; }
195  }
196  if (si_) {
197  t = tt;
198  nrn_hoc_lock();
200  nrn_hoc_unlock();
201  }else{
202  *pd_ = y_->elem(current_index_++);
203  }
204  if (current_index_ < y_->size()) {
205  if (t_) {
206  if (current_index_ < t_->size()) {
207  e_->send(t_->elem(current_index_), ns, nt);
208  }
209  }else{
210  e_->send(tt + dt_, ns, nt);
211  }
212  }
213 }
214 
215 
217  printf("VecPlayStep ");
218  printf("%s.x[%d]\n", hoc_object_name(y_->obj_), current_index_);
219 }
220 
221 VecPlayContinuous::VecPlayContinuous(double* pd, IvocVect* y, IvocVect* t, IvocVect* discon, Object* ppobj) : PlayRecord(pd, ppobj) {
222 //printf("VecPlayContinuous\n");
223  init(y, t, discon);
224 }
225 
226 VecPlayContinuous::VecPlayContinuous(const char* s, IvocVect* y, IvocVect* t, IvocVect* discon, Object* ppobj) : PlayRecord(&NODEV(chk_access()->pnode[0]), ppobj) {
227 //printf("VecPlayContinuous\n");
228  init(y, t, discon);
229  si_ = new StmtInfo(s);
230 }
231 
233  y_ = y;
234  t_ = t;
235  discon_indices_ = discon;
236  ubound_index_ = 0;
237  last_index_ = 0;
238  ObjObservable::Attach(y_->obj_, this);
239  if (t_) {
240  ObjObservable::Attach(t_->obj_, this);
241  }
242  if (discon_indices_) {
244  }
245  e_ = new PlayRecordEvent();
246  e_->plr_ = this;
247  si_ = NULL;
248 }
249 
250 
252 //printf("~VecPlayContinuous\n");
253  ObjObservable::Detach(y_->obj_, this);
254  ObjObservable::Detach(t_->obj_, this);
255  if (discon_indices_) {
257  }
258  delete e_;
259  if (si_) {
260  delete si_;
261  }
262 }
263 
265 // printf("%s VecPlayContinuous disconnect\n", hoc_object_name(y_->obj_));
266  delete this;
267 }
268 
270  play_add(cv);
271 }
272 
274  NrnThread* nt = nrn_threads;
275  if (cvode_ && cvode_->nth_) {
276  nt = cvode_->nth_;
277  }
278  last_index_ = 0;
279  discon_index_ = 0;
280  if (discon_indices_) {
281  if (discon_indices_->size() > 0) {
283 //printf("play_init %d %g\n", ubound_index_, t_->elem(ubound_index_));
285  }else{
286  ubound_index_ = t_->size()-1;
287  }
288  }else{
289  ubound_index_ = 0;
291  }
292 }
293 
294 void VecPlayContinuous::deliver(double tt, NetCvode* ns) {
295  NrnThread* nt = nrn_threads + ith_;
296  if (cvode_) {
298  if (cvode_->nth_) { nt = cvode_->nth_; }
299  }
301  if (discon_indices_) {
302  if (discon_index_ < discon_indices_->size()) {
304 //printf("after deliver:send %d %g\n", ubound_index_, t_->elem(ubound_index_));
305  e_->send(t_->elem(ubound_index_), ns, nt);
306  }else{
307  ubound_index_ = t_->size() - 1;
308  }
309  }else{
310  if (ubound_index_ < t_->size() - 1) {
311  ubound_index_++;
312  e_->send(t_->elem(ubound_index_), ns, nt);
313  }
314  }
315  continuous(tt);
316 }
317 
318 
320  if (si_) {
321  t = tt;
322  nrn_hoc_lock();
323  si_->play_one(interpolate(tt));
324  nrn_hoc_unlock();
325  }else{
326  *pd_ = interpolate(tt);
327  }
328 }
329 
331  if (tt >= t_->elem(ubound_index_)) {
333  if (last_index_ == 0) {
334 //printf("return last tt=%g ubound=%g y=%g\n", tt, t_->elem(ubound_index_), y_->elem(last_index_));
335  return y_->elem(last_index_);
336  }
337  }else if (tt <= t_->elem(0)) {
338  last_index_ = 0;
339 //printf("return elem(0) tt=%g t0=%g y=%g\n", tt, t_->elem(0), y_->elem(0));
340  return y_->elem(0);
341  }else{
342  search(tt);
343  }
344  double x0 = y_->elem(last_index_-1);
345  double x1 = y_->elem(last_index_);
346  double t0 = t_->elem(last_index_ - 1);
347  double t1 = t_->elem(last_index_);
348 //printf("IvocVectRecorder::continuous tt=%g t0=%g t1=%g theta=%g x0=%g x1=%g\n", tt, t0, t1, (tt - t0)/(t1 - t0), x0, x1);
349  if (t0 == t1) { return (x0 + x1)/2.; }
350  return interp((tt - t0)/(t1 - t0), x0, x1);
351 #if 0
352  // dt
353  double theta = tt/dt_ - last_index_;
354  interp(theta, x0, x1);
355 #endif
356 }
357 
358 void VecPlayContinuous::search(double tt) {
359 // assert (tt > t_->elem(0) && tt < t_->elem(t_->size() - 1))
360  while ( tt < t_->elem(last_index_)) {
361  --last_index_;
362  }
363  while ( tt >= t_->elem(last_index_)) {
364  ++last_index_;
365  }
366 }
367 
369  printf("VecPlayContinuous ");
370  printf("%s.x[%d]\n", hoc_object_name(y_->obj_), last_index_);
371 }
372 
373 PlayRecordSave* VecPlayStep::savestate_save() {
374  return new VecPlayStepSave(this);
375 }
376 
378  curindex_ = ((VecPlayStep*)pr_)->current_index_;
379 }
381 }
383  check();
384  VecPlayStep* vps = (VecPlayStep*)pr_;
385  vps->current_index_ = curindex_;
386  if (curindex_ > 0) {
387  if (vps->si_) {
388  vps->si_->play_one(vps->y_->elem(curindex_ - 1));
389  }else{
390  *vps->pd_ = vps->y_->elem(curindex_ - 1);
391  }
392  }
393 }
395  fprintf(f, "%d\n", curindex_);
396 }
398  char buf[100];
399  nrn_assert(fgets(buf, 100, f));
400  nrn_assert(sscanf(buf, "%d\n", &curindex_) == 1);
401 }
402 
404  return new VecPlayContinuousSave(this);
405 }
406 
409  last_index_ = vpc->last_index_;
412 }
414 }
416  check();
418  vpc->last_index_ = last_index_;
421  vpc->continuous(t);
422 }
424  fprintf(f, "%d %d %d\n", last_index_, discon_index_, ubound_index_);
425 }
427  char buf[100];
428  nrn_assert(fgets(buf, 100, f));
429  nrn_assert(sscanf(buf, "%d %d %d\n", &last_index_, &discon_index_, &ubound_index_) == 3);
430 }
double interpolate(double tt)
Definition: vrecord.cpp:330
#define nrn_assert(ex)
Definition: nrnassrt.h:35
virtual ~VecPlayContinuousSave()
Definition: vrecord.cpp:413
virtual ~VecPlayStep()
Definition: vrecord.cpp:154
int hoc_is_str_arg(int narg)
Definition: code.cpp:741
IvocVect * y_
Definition: vrecitem.h:207
#define prop
Definition: md1redef.h:29
#define NODEV(n)
Definition: section.h:114
short * nrn_is_artificial_
Definition: cell_group.cpp:18
static void pnode(Prop *)
Definition: psection.cpp:47
size_t size() const
Definition: ivocvect.h:43
int hoc_is_double_arg(int narg)
Definition: code.cpp:733
void play_add(Cvode *)
Definition: netcvode.cpp:6062
VecPlayStepSave(PlayRecord *)
Definition: vrecord.cpp:377
PlayRecList * prl
Definition: savstate.cpp:439
char * hoc_object_name(Object *ob)
Definition: hoc_oop.cpp:84
Represent main neuron object computed by single thread.
Definition: multicore.h:58
PlayRecordEvent * e_
Definition: vrecitem.h:254
virtual void savestate_read(FILE *)
Definition: vrecord.cpp:426
#define v
Definition: md1redef.h:4
Object * obj_
Definition: ivocvect.h:86
void init(IvocVect *y, IvocVect *t, double dt)
Definition: vrecord.cpp:140
static void pr(N_Vector x)
virtual void pr()
Definition: vrecord.cpp:216
virtual void play_init()
Definition: vrecord.cpp:273
double * pd_
Definition: vrecitem.h:78
Point_process * ob2pntproc(Object *)
Definition: hocmech.cpp:88
void nrn_hoc_lock()
Definition: multicore.cpp:1064
#define con(arg1, arg2, arg3)
Definition: consist.cpp:15
#define e
Definition: passive0.cpp:24
#define gargstr
Definition: hocdec.h:14
static void Attach(Object *, Observer *)
Definition: ocobserv.cpp:20
double * hoc_pgetarg(int narg)
Definition: code.cpp:1604
void play_one(double)
Definition: ocpointer.cpp:163
double dt
Definition: init.cpp:123
double dt_
Definition: vrecitem.h:209
StmtInfo * si_
Definition: vrecitem.h:213
double t
Definition: init.cpp:123
void search(double tt)
Definition: vrecord.cpp:358
virtual PlayRecordSave * savestate_save()
Definition: vrecord.cpp:403
VecPlayContinuousSave(PlayRecord *)
Definition: vrecord.cpp:407
IvocVect * t_
Definition: vrecitem.h:248
static double check(double t, Daspk *ida)
Definition: nrndaspk.cpp:214
virtual void deliver(double t, NetCvode *)
Definition: vrecord.cpp:190
_CONST char * s
Definition: system.cpp:74
NrnThread * nrn_threads
Definition: multicore.cpp:45
#define printf
Definition: mwprefix.h:26
virtual void install(Cvode *)
Definition: vrecord.cpp:269
int
Definition: nrnmusic.cpp:71
virtual void play_init()
Definition: vrecord.cpp:175
VecPlayContinuous(double *, IvocVect *y, IvocVect *t, IvocVect *discon, Object *ppobj=nil)
Definition: vrecord.cpp:221
virtual void pr()
Definition: vrecord.cpp:368
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
void nrn_vecsim_remove(void *v)
Definition: vrecord.cpp:24
size_t j
fprintf(stderr, "Don't know the location of params at %p\, pp)
virtual void send(double deliverytime, NetCvode *, NrnThread *)
Definition: netcvode.cpp:3069
double & elem(int n)
Definition: ivocvect.h:31
virtual void savestate_read(FILE *)
Definition: vrecord.cpp:397
VecPlayStep(double *, IvocVect *y, IvocVect *t, double dt, Object *ppobj=nil)
Definition: vrecord.cpp:129
int ifarg(int)
Definition: code.cpp:1562
virtual PlayRecordSave * savestate_save()
Definition: vrecord.cpp:373
void nrn_hoc_unlock()
Definition: multicore.cpp:1072
void nrn_vecsim_add(void *v, bool record)
Definition: vrecord.cpp:31
NetCvode * net_cvode_instance
Definition: cvodestb.cpp:27
IvocVect * t_
Definition: vrecitem.h:208
Vect * vector_arg(int i)
Definition: ivocvect.cpp:332
IvocVect * y_
Definition: vrecitem.h:247
void init(IvocVect *y, IvocVect *t, IvocVect *tdiscon)
Definition: vrecord.cpp:232
virtual void savestate_write(FILE *)
Definition: vrecord.cpp:423
Definition: hocdec.h:226
Definition: cvodeobj.h:75
NrnThread * nth_
Definition: cvodeobj.h:200
double interp(double th, double x0, double x1)
Definition: vrecitem.h:239
Cvode * cvode_
Definition: vrecitem.h:80
virtual void install(Cvode *)
Definition: vrecord.cpp:171
void set_init_flag()
Definition: cvodeobj.cpp:790
int current_index_
Definition: vrecitem.h:210
void continuous(double tt)
Definition: vrecord.cpp:319
static void Detach(Object *, Observer *)
Definition: ocobserv.cpp:27
PlayRecord * plr_
Definition: vrecitem.h:38
char buf[512]
Definition: init.cpp:13
virtual void savestate_restore()
Definition: vrecord.cpp:415
PlayRecord * playrec_uses(void *)
Definition: netcvode.cpp:6009
int hoc_is_object_arg(int narg)
Definition: code.cpp:745
virtual void savestate_write(FILE *)
Definition: vrecord.cpp:394
virtual void disconnect(Observable *)
Definition: vrecord.cpp:166
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
virtual void deliver(double t, NetCvode *)
Definition: vrecord.cpp:294
virtual ~VecPlayStepSave()
Definition: vrecord.cpp:380
Section * chk_access(void)
Definition: cabcode.cpp:437
return NULL
Definition: cabcode.cpp:461
double chkarg(int, double low, double high)
Definition: code2.cpp:608
StmtInfo * si_
Definition: vrecitem.h:255
int ith_
Definition: vrecitem.h:81
virtual void savestate_restore()
Definition: vrecord.cpp:382
virtual ~VecPlayContinuous()
Definition: vrecord.cpp:251
IvocVect * discon_indices_
Definition: vrecitem.h:249
virtual void disconnect(Observable *)
Definition: vrecord.cpp:264
PlayRecordEvent * e_
Definition: vrecitem.h:212