openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
signals.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
2 // SPDX-License-Identifier: Apache-2.0
3 
12 #ifndef SIGNAL
13 #define SIGNAL
14 
15 #include <string>
16 #include <assert.h>
17 #include <math.h>
18 #include <iostream>
19 #include <fstream>
20 #include <algorithm>
21 #include <iomanip>
22 #include <sstream>
23 
24 #include "SF_vector.h"
25 namespace opencarp {
26 namespace sig {
27 
28 typedef double sReal;
29 
30 // trailing underscore added to avoid clash with bidomain.h
31 // Stimulation.c needs to be modified to make use of traces as used in here
33 
34 template<typename V>
35 V mod(const V& a, const V& b)
36 {
37  return (a % b + b) % b;
38 }
39 
43  public:
45  bool header_on;
46  std::string header;
47  std::string col_sep;
48  int fmt_id;
50 
51  time_trace_ffmt() : time_trace_ffmt( true, false, "", " ", 1)
52  {}
53 
54  time_trace_ffmt(bool num_samples_on_, bool header_on_, std::string header_, std::string col_sep_)
55  : time_trace_ffmt(num_samples_on_, header_on_, header_, col_sep_, 1 )
56  {}
57 
58  time_trace_ffmt(bool num_samples_on_, bool header_on_, std::string header_, std::string col_sep_, int fmt_id_)
59  : num_samples_on(num_samples_on_), header_on(header_on_), header(header_), col_sep(col_sep_), fmt_id(fmt_id_)
60  {
61  // default column width is 8
62  colw = {8, 8};
63  }
64 
65  int parse_header(std::ifstream& inpf);
66 };
67 
70 inline int time_trace_ffmt::parse_header(std::ifstream& inpf)
71 {
72  int err = 0;
73 
74  // assume no comment, data section starts at the beginning
75  std::streampos start_of_data = inpf.beg;
76 
77  // read in first line
78  std::string line{};
79  std::getline(inpf,line);
80 
81  // comment line?
82  std::size_t found_hash = line.find_first_of("#");
83  if(found_hash != std::string::npos)
84  {
85  // keep reading comment lines
86  start_of_data = inpf.tellg();
87  }
88  else
89  {
90  // no header, check for number of samples
91  sReal t, f;
92  size_t items = sscanf(line.c_str(),"%lf %lf", &t, &f);
93 
94  if(items != 2)
95  {
96  // line holds number of samples
97  int num_samples{0};
98  size_t item = sscanf(line.c_str(),"%d", &num_samples);
99  if(!item)
100  err = -1;
101  else {
102  num_samples_on = true;
103  // put back
104  //for(size_t i=0; i<line.size(); i++)
105  //inpf.unget();
106  }
107  }
108  else
109  {
110  // we found a time value pair
111  num_samples_on = false;
112  }
113 
114  // set stream pointer back to start of data section
115  inpf.seekg(start_of_data,inpf.beg);
116  }
117  return err;
118 }
119 
128  public:
129  std::string label;
130  std::string t_unit;
131  std::string f_unit;
136  bool fade;
137 
138  // constructors
139 
141  time_trace() : time_trace( 1000., 10.0e-3, 0.0)
142  {}
143 
145  time_trace(sReal _dt) : time_trace(1000., _dt, 0.)
146  {}
147 
149  time_trace(sReal _duration, sReal _dt) : time_trace(_duration, _dt, 0.)
150  {}
151 
152  time_trace(sReal _duration, sReal _dt, sReal _rtOff, std::string _label) :
153  time_trace(_duration, _dt, _rtOff, _label, "", "")
154  {}
155 
157  time_trace(sReal _duration, sReal _dt, sReal _rtOff) : time_trace(_duration, _dt, _rtOff, "", "", "")
158  {}
159 
161  time_trace(sReal _duration, sReal _dt, sReal _rtOff, std::string _label, std::string _t_unit, std::string _f_unit)
162  {
163  dt = _dt;
164  rtOff = _rtOff;
165  int N = ceil(_duration/dt) + 1;
166 
167  f.assign(N, 0.0);
168  t.resize(N);
169 
170  sReal ct = 0;
171  for(size_t i=0; i<t.size(); i++) {
172  t[i] = ct;
173  ct += dt;
174  }
175 
176  set_labels(_label, _t_unit, _f_unit);
177  }
178 
180  {
181  label = in.label;
182  t_unit = in.t_unit;
183  f_unit = in.f_unit;
184  f = in.f;
185  t = in.t;
186  dt = in.dt;
187  rtOff = in.rtOff;
188  fade = in.fade;
189 
190  return *this;
191  }
192 
195  {
196  *this = a;
197  }
198 
200  time_trace(const time_trace& a, sReal val) : time_trace(a)
201  {
202  // use standard copy constructor and initialize signal with constant value
203  std::fill(f.begin(), f.end(), val);
204  }
205 
207  std::string format_file_header(const time_trace_ffmt ffmt_spec);
208 
209 
211  void operator *= (const time_trace& a);
212  void operator *= (const sReal s);
213  void operator += (const sReal a);
214  void operator += (const time_trace& a);
215  void operator <<= (int delta);
216  void operator >>= (int delta);
217 
218  // member functions
219  void set_labels(std::string _label)
220  {
221  label = _label;
222  }
223 
224  void set_labels(std::string _label, std::string _t_unit, std::string _f_unit)
225  {
226  label = _label;
227  setUnits(_t_unit, _f_unit);
228  }
229 
230  void setUnits(std::string _t_unit, std::string _f_unit)
231  {
232  t_unit = _t_unit;
233  f_unit = _f_unit;
234  }
235 
236  void resize(int numSamples)
237  {
238  t.resize(numSamples);
239  f.resize(numSamples);
240  }
241 
243  {
244  //return f.back();
245  return t[t.size()-1];
246  }
247 
248  size_t len() const
249  {
250  return t.size();
251  }
252 
254  {
255  for(std::size_t i=0; i<len(); i++)
256  t[i] += rtOff;
257 
258  rtOff = 0.;
259 
260  return t[0];
261  }
262 
264  {
265  rtOff = t[0];
266  for(std::size_t i=0; i<len(); i++)
267  t[i] -= rtOff;
268 
269  return -rtOff;
270  }
271 
272  // signal processing
273 
282  {
283  for(std::size_t i=0; i<len()-1; i++)
284  f[i] = f[i+1] - f[i];
285 
286  // last sample has no difference
287  f[len()-1] = 0.;
288 
289  return f;
290  }
291 
300  {
301  auto dFdt = f;
302 
303  int N = len();
304  int end = N-1;
305 
306  // take forward/backward difference at left/right edge
307  dFdt[0] = (f[1] - f[0]) / (t[1] - t[0]);
308  dFdt[end] = (f[end] - f[end-1]) / (t[end] - t[end-1]);
309 
310  // take centered differences on interior points
311  for(int i=1; i<end-1; i++)
312  {
313  sReal fdF = (f[i ] - f[i-1]) / (t[i ] - t[i-1]);
314  sReal bdF = (f[i+1] - f[i ]) / (t[i+1] - t[i ]);
315 
316  dFdt[i] = (fdF + bdF) * 0.5;
317  }
318 
319  // overwrite f
320  f = dFdt;
321 
322  return f;
323  }
324 
325  // time trace I/O
326  int read_trace(const std::string fname);
327  int read_trace(const std::string fname, bool unitize);
328 
329  int write_trace();
330  int write_trace(const std::string fname);
331  int write_trace(const std::string fname, time_trace_ffmt ffmt_spec);
332 
333 
334  // shift operations
335  size_t timeShift(sReal t_shift)
336  {
337  int dI = t_shift/dt;
338 
339  return dI;
340  }
341 
342 
343  // scaling functions
344 
347  void unitize()
348  {
349  assert(len()>0);
350 
351  sReal _mn = f[0];
352  sReal _mx = f[0];
353 
354  for (std::size_t i=1;i<len();i++) {
355  if (f[i] > _mx)
356  _mx = f[i];
357  else
358  if (f[i] < _mn)
359  _mn = f[i];
360  }
361 
362  //pair<SF::vector<int>::iterator, SF::vector<int>::iterator> mnmx;
363  //eal __mx, __mn;
364  //auto mnmx = std::minmax_element(f.begin(),f.end());
365  //__mn = nmx.first;
366  //__mx = mnmx.second;
367 
368  sReal unsc = fabs(_mx)>=fabs(_mn) ? 1./fabs(_mx):1./fabs(_mn);
369 
370  for (std::size_t i=0;i<len();i++)
371  f[i] *= unsc;
372 
373  }
374 
375 
376  // interpolation functions
377 
385  {
386  sReal dt_o = t[1] - t[0];
387 
388  // differences in sampling should be less than 0.1%
389  sReal r_err = 0.001*dt_o;
390 
391  for (std::size_t i=1; i<len()-1; i++) {
392  sReal dt_n = t[i+1] - t[i];
393  if ( (dt_n - dt_o) > r_err)
394  return false;
395  }
396 
397  return true;
398  }
399 
403  {
404  if(_t < t[0])
405  return fade ? 0. : f[0];
406 
407  if(_t > t.back())
408  return fade ? 0. : f.back();
409 
410  int i = 0;
411  while(t[i] <= _t) i++;
412 
413  sReal K = (f[i] - f[i-1]) / (t[i] - t[i-1]);
414  sReal fval = f[i-1] + K * (_t - t[i-1]);
415 
416  return fval;
417  }
418 
419  void resample(time_trace& trc)
420  {
421  for(std::size_t i=0; i<trc.len(); i++)
422  trc.f[i] = fval_t(trc.t[i]);
423  }
424 
425  void resample(time_trace& trc, IpMeth_t meth)
426  {
427  interp1(trc, meth);
428  }
429 
440  void
442  {
443 
444  // iterate over target array
445  for (std::size_t i=0; i<trc.len(); i++) {
446 
447  // data point to interpolate on
448  sReal _t = trc.t[i];
449 
450  // are we within input x-range?
451  if ( (_t < t[0]) || (_t > t.back()) )
452  continue;
453 
454  //binary search
455  int i1 = 0;
456  int i2 = len()-1;
457  while(i2 > (i1+1)) {
458  int mid = (i2+i1)/2;
459  if (t[mid] <= _t) {
460  i1 = mid;
461  } else {
462  i2 = mid;
463  }
464  }
465 
466  switch (meth) {
467  case _LINEAR_IP:
468  trc.f[i] = f[i1] + (f[i2]-f[i1])/(t[i2]-t[i1])*(_t-t[i1]);
469  break;
470  case _NEAREST_IP:
471  if ((trc.t[i]-t[i1]) >= (t[i2]-trc.t[i]))
472  trc.f[i] = f[i1];
473  else
474  trc.f[i] = f[i2];
475  break;
476  }
477  }
478  }
479 
480 };
481 
482 
485 {
486  assert( len() == a.len() );
487 
488  for(size_t i=0; i<len(); i++)
489  f[i] *= a.f[i];
490 }
491 
492 
493 inline void time_trace::operator *= (const sReal s)
494 {
495  for(auto & v : f) v *= s;
496 }
497 
498 inline void time_trace::time_trace::operator += (const sReal a)
499 {
500  for(auto & v : f) v += a;
501 }
502 
503 
505 {
506  assert( len() == a.len() );
507 
508  for(size_t i=0; i<len(); i++)
509  f[i] += a.f[i];
510 }
511 
512 inline void time_trace::operator <<= (int delta)
513 {
514  bool ring = delta < 0; // ring shift?
515  int N = len();
516 
517  if(ring)
518  delta = -delta;
519 
520  // ring buffer shift
521  SF::vector<sReal>tmp = f;
522  for(int i=0; i<N; i++)
523  f[mod((i-delta),N)] = tmp[i];
524 
525  // not ring, override
526  if(!ring)
527  for(std::size_t i=len()-delta;i<len();i++)
528  f[i] = 0.;
529 }
530 
531 inline void time_trace::operator >>= (int delta)
532 {
533  bool ring = delta < 0;
534  int N = len();
535 
536  if(ring)
537  delta = -delta;
538 
539  // ring buffer shift
540  SF::vector<sReal>tmp = f;
541  for(int i=0; i<N; i++)
542  f[mod((i+delta),N)] = tmp[i];
543 
544  // not ring, override
545  if(!ring)
546  for(int i=0;i<delta;i++)
547  f[i] = 0.;
548 }
549 
552 inline std::string time_trace::format_file_header(const time_trace_ffmt ffmt_spec)
553 {
554  std::ostringstream sheader_;
555 
556  if(ffmt_spec.header_on)
557  {
558  // write trace header comment section, for now this is empty
559  sheader_ << "# " << ffmt_spec.header << std::endl;
560 
561  // in this case we also print the format identifier
562  sheader_ << "# version = " << ffmt_spec.fmt_id << std::endl;
563 
564  // write column table header
565  sheader_ << "#" << std::endl;
566  sheader_ << "# TABLE_HEAD" << std::endl;
567  sheader_ << "# A = time" << std::endl;
568  sheader_ << "# B = " << label << std::endl;
569  sheader_ << "# [" << std::setw(ffmt_spec.colw[0]) << "A" << "]";
570  sheader_ << "[" << std::setw(ffmt_spec.colw[1]) << "B" << "]" << std::endl;
571  sheader_ << "# [" << std::setw(ffmt_spec.colw[0]) << t_unit << "]";
572  sheader_ << "[" << std::setw(ffmt_spec.colw[1]) << f_unit << "]" << std::endl;
573  sheader_ << "#" << std::endl;
574  sheader_ << "# DATA" << std::endl;
575  }
576 
577  if(ffmt_spec.num_samples_on)
578  // first line holds # of samples
579  sheader_ << len() << std::endl;
580 
581  std::string sheader = sheader_.str();
582 
583  return sheader;
584 }
585 
586 
589 /*
590 sReal duration(const std::string fname)
591 {
592  time_trace tmp;
593 
594  int err = tmp.read_trace(fname);
595 
596  return !err ? tmp.t.back() : -1;
597 }
598 */
599 
608 inline int time_trace::read_trace(std::string fname)
609 {
610  int err = 0;
611 
612  std::ifstream inpf(fname);
613 
614  // If we couldn't open the output file stream for writing
615  if (!inpf)
616  {
617  // Print an error and exit
618  std::cerr << "Trace file " << fname << " could not be opened for reading!" << std::endl;
619  err = -1;
620  }
621  else {
622 
623  time_trace_ffmt tt_ffmt{};
624 
625  tt_ffmt.parse_header(inpf);
626 
627  // first line holds # of samples
628  int numSamples{0};
629  if(tt_ffmt.num_samples_on)
630  {
631  inpf >> numSamples;
632 
633  // adjust signal buffer size
634  resize(numSamples);
635  }
636 
637  // read time/sample pairs
638  int i = 0;
639  while( inpf >> t[i] >> f[i] )
640  i++;
641 
642  if(tt_ffmt.num_samples_on)
643  {
644  if(i<numSamples || i<2)
645  err = -2;
646  }
647 
648  inpf.close();
649  }
650 
651  if(err)
652  return err;
653 
654  // fill trace data
655  // get units from comments header, if available
656  // set label from filename
657  // resample file according to given dt
658 
659  return err;
660 }
661 
662 
668 inline int time_trace::read_trace(std::string fname, bool _unitize)
669 {
670  int err = read_trace(fname);
671 
672  if(!err && _unitize)
673  unitize();
674 
675  return err;
676 }
677 
687 {
688  return write_trace(label + ".trc");
689 }
690 
691 
701 inline int time_trace::write_trace(const std::string fname)
702 {
703  time_trace_ffmt ffmt_spec;
704  int err = write_trace(fname, ffmt_spec);
705 
706  return err;
707 }
708 
718 inline int time_trace::write_trace(const std::string fname, time_trace_ffmt ffmt_spec)
719 {
720  int err = 0;
721 
722  std::ofstream outf(fname);
723 
724  // If we couldn't open the output file stream for writing
725  if (!outf) {
726  // Print an error and exit
727  std::cerr << "Trace file " << fname << " could not be opened for writing!" << std::endl;
728  err = -1;
729  }
730  else {
731  if(ffmt_spec.header_on)
732  {
733  // write trace file header
734  outf << format_file_header(ffmt_spec); //ffmt_spec.header_string(len());
735  }
736 
737  // write number of samples in file
738  if(ffmt_spec.num_samples_on)
739  outf << len() << std::endl;
740 
741  // data section
742  // write time/sample pairs
743  outf << std::fixed;
744  for(std::size_t i=0; i<len(); i++)
745  {
746  outf << std::setw(ffmt_spec.colw[0]+3) << std::setprecision(3) << t[i] << ffmt_spec.col_sep;
747  outf << std::setw(ffmt_spec.colw[1]+1) << std::setprecision(6) << f[i] << std::endl;
748  }
749  outf.close();
750  }
751 
752  return err;
753 }
754 
755 // define time_trace arithmetics
756 inline time_trace operator * (const time_trace& a, const time_trace& b)
757 {
758  assert( a.len() == b.len() );
759 
760  time_trace _mult = a;
761 
762  for(std::size_t i=0; i<a.len(); i++)
763  _mult.f[i] = a.f[i] * b.f[i];
764 
765  return _mult;
766 }
767 
768 inline time_trace operator / (const time_trace& a, const time_trace& b)
769 {
770  assert( a.len() == b.len() );
771 
772  time_trace _div = a;
773 
774  for(std::size_t i=0; i<a.len(); i++)
775  _div.f[i] = a.f[i] / b.f[i];
776 
777  return _div;
778 }
779 
780 inline time_trace operator + (const time_trace& a, const time_trace& b)
781 {
782  assert( a.len() == b.len() );
783 
784  time_trace _add = a;
785  for(std::size_t i=0; i<a.len(); i++)
786  _add.f[i] = a.f[i] + b.f[i];
787 
788  return _add;
789 }
790 
791 inline time_trace operator - (const time_trace& a, const time_trace& b)
792 {
793  assert( a.len() == b.len() );
794 
795  time_trace _sub = a;
796  for(std::size_t i=0; i<a.len(); i++)
797  _sub.f[i] = a.f[i] - b.f[i];
798 
799  return _sub;
800 }
801 
802 // truncated exponential pulse definition
803 class Pulse
804 {
805  public:
807  float strength;
808  double d1;
809  float tau_edge;
810  float tau_plat;
811  float s2r;
812  float bias;
813  bool constant;
814 
815  // constructor
817  {
818  duration = 1.0;
819  strength = 1.0;
820  d1 = 1.0;
821  tau_edge = 0.1;
822  tau_plat = 1000.0;
823  s2r = 0.0;
824  bias = 0.0;
825  constant = false;
826  }
827 
828  //waveForm defineWave(
829 };
830 
831 // action potential foot definition
832 class APfoot
833 {
834  public:
838 
839  // constructor
841  {
842  tau_f = 0.25;
843  A = 1.00;
844  B = -80.0;
845  }
846 };
847 
848 // step function
849 class Step {
850  public:
852  bool rise;
853 
854  // constructor
856  {
857  trig = 0;
858  rise = true;
859  }
860 };
861 
862 // sine waves
863 class sineWave {
864  public:
866  float phase;
867 
869  {
870  frq = 1.;
871  phase = 0.;
872  }
873 
874  sineWave(sReal _frq, sReal _phase) : frq(_frq)
875  {
876  phase = _phase;
877  }
878 };
879 
880 // abstract trace sampling function
882  public:
883  virtual SF::vector<sReal> & sample (time_trace &trc) = 0;
884 };
885 
886 
895 {
896  public:
898 
899  constFunc(sReal _val) : val(_val)
900  {}
901 
903  {
904  for(std::size_t i=0; i<trc.len(); i++)
905  trc.f[i] = val;
906 
907  return trc.f;
908  }
909 };
910 
916 class stepFunc : public sampleTraceFunc
917 {
918 
919  public:
921 
922  stepFunc(Step _pars) : pars(_pars)
923  {}
924 
926  {
927  sReal off = pars.rise ? 1. : 0.;
928  sReal on = pars.rise ? 0. : 1.;
929  for(std::size_t i=0; i<trc.t.size(); i++)
930  trc.f[i] = trc.t[i] < pars.trig ? on : off;
931 
932  return trc.f;
933  }
934 };
935 
938 class sineFunc : public sampleTraceFunc
939 {
940  public:
942 
943  sineFunc(sineWave _pars) : pars(_pars)
944  {}
945 
947  {
948  sReal phase_shift = pars.phase/180*M_PI;
949  for(std::size_t i=0; i<trc.len(); i++)
950  trc.f[i] = sin(2*M_PI*pars.frq*trc.t[i] + phase_shift);
951 
952  return trc.f;
953  }
954 };
955 
959 {
960  public:
962 
963  APfootFunc(APfoot _pars) : pars(_pars)
964  {}
965 
967  {
968  for(std::size_t i=0; i<trc.len(); i++)
969  trc.f[i] = pars.A*exp(trc.t[i]/pars.tau_f) + pars.B;
970 
971  return trc.f;
972  }
973 };
974 
978 {
979  public:
981 
983  {}
984 
986  {
987  double t0 = 0.;
988  double t1 = t0 + pars.d1 - 5*pars.tau_edge;
989  //double t2 = t0 + pars.d1;
990 
991  // first phase exponential rise and plateau
992  time_trace zero(trc);
993  //zero = 0.;
994  time_trace phase_0 = zero;
995 
996  for(std::size_t i=0; i<trc.t.size(); i++)
997  {
998  sReal f0 = pars.tau_edge ? -expm1(-(trc.t[i]-t0)/pars.tau_edge):1.;
999  sReal fp = exp(-(trc.t[i]-t0)/pars.tau_plat);
1000 
1001  phase_0.f[i]= f0*fp*pars.strength;
1002  }
1003 
1004  // end of plateau, exponential decay
1005  time_trace eps_0 = zero;
1006  time_trace eps_1 = zero;
1007 
1008  // step function
1009  Step stepPars;
1010  stepPars.trig = t1;
1011  stepPars.rise = false;
1012 
1013  // eps+, falling eps function 1 | 0
1014  stepFunc eps(stepPars);
1015  eps.sample(eps_0);
1016 
1017  // eps-, rising eps function 0 | 1
1018  eps.pars.rise = true;
1019  eps.sample(eps_1);
1020 
1021  // final falling phase
1022  time_trace phase_1 = zero;
1023  int i1 = int(t1/trc.dt);
1024  sReal f0 = phase_0.f[i1];
1025  for(std::size_t i=i1; i<trc.len(); i++)
1026  phase_1.f[i] = f0*exp(-(trc.t[i]-t1)/pars.tau_edge);
1027 
1028  // assemble pulse components
1029  time_trace pulse = phase_0 * eps_0 + phase_1 * eps_1;
1030  // this does not work, lvalue is time_trace &
1031  //trc = phase_0 * eps_0 + phase_1 * eps_1;
1032  trc = pulse;
1033 
1034  // add bias
1035  trc += pars.bias;
1036 
1037  return trc.f;
1038  }
1039 };
1040 
1044 {
1045  public:
1047 
1049  {}
1050 
1052  {
1053  // create first phase
1054  monophasicTruncExpFunc cdmFunc1(pars);
1055  cdmFunc1.sample(trc);
1056 
1057  // create second phase, determine tilt
1058  if(pars.s2r == 0.)
1059  {
1060  int ph1_i1 = int((pars.d1 - 5*pars.tau_edge)/trc.dt);
1061  pars.strength = -trc.f[ph1_i1];
1062  }
1063  else
1065 
1066  time_trace ph2(trc);
1067  //ph2 = 0.;
1068  monophasicTruncExpFunc cdmFunc2(pars);
1069  cdmFunc2.sample(ph2);
1070 
1071  // shift phase 2 relative to phase 1
1072  ph2 >>= (pars.d1 - 5*pars.tau_edge)/trc.dt;
1073 
1074  trc += ph2;
1075 
1076  return trc.f;
1077  }
1078 };
1079 
1080 } // namespace sig
1081 } // namespace opencarp
1082 
1083 #endif
1084 
#define M_PI
Definition: ION_IF.h:57
The vector class and related algorithms.
size_t size() const
The current size of the vector.
Definition: SF_vector.h:89
void resize(size_t n)
Resize a vector.
Definition: SF_vector.h:194
const T * end() const
Pointer to the vector's end.
Definition: SF_vector.h:113
void assign(InputIterator s, InputIterator e)
Assign a memory range.
Definition: SF_vector.h:146
T & back()
Definition: SF_vector.h:129
const T * begin() const
Pointer to the vector's start.
Definition: SF_vector.h:101
action potential foot pulse
Definition: signals.h:959
virtual SF::vector< sReal > & sample(time_trace &trc)
Definition: signals.h:966
APfootFunc(APfoot _pars)
Definition: signals.h:963
sReal B
baseline offset
Definition: signals.h:837
sReal tau_f
time constant of AP foot
Definition: signals.h:835
sReal A
change in delta Vm over tau_f
Definition: signals.h:836
float s2r
strength of subpulse relative to leading pulse (biphasic pulse)
Definition: signals.h:811
sReal duration
pulse duration, default is 1 ms
Definition: signals.h:806
float tau_plat
time constant governing plateau of pulse
Definition: signals.h:810
float tau_edge
time constant for leading/trailing edges
Definition: signals.h:809
float bias
constant term to add to stimulus waveform
Definition: signals.h:812
bool constant
constant value for all time
Definition: signals.h:813
float strength
pulse amplitude, default is unit strength
Definition: signals.h:807
double d1
duration of first sub-pulse in [ms] (zero with monophasic pulse)
Definition: signals.h:808
biphasic truncated exponentials (capacitive discharge)
Definition: signals.h:1044
virtual SF::vector< sReal > & sample(time_trace &trc)
Definition: signals.h:1051
constant function
Definition: signals.h:895
virtual SF::vector< sReal > & sample(time_trace &trc)
Definition: signals.h:902
constFunc(sReal _val)
Definition: signals.h:899
monophasic truncated exponentials (capacitive discharge)
Definition: signals.h:978
virtual SF::vector< sReal > & sample(time_trace &trc)
Definition: signals.h:985
virtual SF::vector< sReal > & sample(time_trace &trc)=0
sineFunc(sineWave _pars)
Definition: signals.h:943
virtual SF::vector< sReal > & sample(time_trace &trc)
Definition: signals.h:946
sineWave(sReal _frq, sReal _phase)
Definition: signals.h:874
float phase
phase in degree
Definition: signals.h:866
sReal frq
freq in [kHz]
Definition: signals.h:865
step function
Definition: signals.h:917
virtual SF::vector< sReal > & sample(time_trace &trc)
Definition: signals.h:925
stepFunc(Step _pars)
Definition: signals.h:922
manage trace format
Definition: signals.h:42
bool header_on
turn on header output
Definition: signals.h:45
time_trace_ffmt(bool num_samples_on_, bool header_on_, std::string header_, std::string col_sep_, int fmt_id_)
Definition: signals.h:58
bool num_samples_on
turn on # of samples output
Definition: signals.h:44
int parse_header(std::ifstream &inpf)
parse trace header from file
Definition: signals.h:70
time_trace_ffmt(bool num_samples_on_, bool header_on_, std::string header_, std::string col_sep_)
Definition: signals.h:54
std::string col_sep
column separator, either " " or ","
Definition: signals.h:47
std::string header
header
Definition: signals.h:46
SF::vector< int > colw
width of columns
Definition: signals.h:49
int fmt_id
format identifier
Definition: signals.h:48
Time tracing class.
Definition: signals.h:127
void set_labels(std::string _label)
Definition: signals.h:219
time_trace(sReal _dt)
prescribe dt only, default duration is 1000. ms
Definition: signals.h:145
void resize(int numSamples)
Definition: signals.h:236
time_trace(sReal _duration, sReal _dt)
prescribe duration and sampling, use default real time offset
Definition: signals.h:149
bool fade
signal fades to zero after end or remains at final amplitude
Definition: signals.h:136
time_trace(sReal _duration, sReal _dt, sReal _rtOff, std::string _label, std::string _t_unit, std::string _f_unit)
full constructor, prescribe all members
Definition: signals.h:161
bool IsEquDistSampling()
check whether time trace is sampled with constant sampling interval
Definition: signals.h:384
void resample(time_trace &trc, IpMeth_t meth)
Definition: signals.h:425
sReal fval_t(sReal _t)
retrieve value of a function at a given time t
Definition: signals.h:402
void interp1(time_trace &trc, IpMeth_t meth)
interpolate a time trace
Definition: signals.h:441
std::string label
descriptive label of signal
Definition: signals.h:129
void unitize()
scale signal to unity strength
Definition: signals.h:347
void set_labels(std::string _label, std::string _t_unit, std::string _f_unit)
Definition: signals.h:224
time_trace(sReal _duration, sReal _dt, sReal _rtOff, std::string _label)
Definition: signals.h:152
SF::vector< sReal > t
time axis
Definition: signals.h:133
SF::vector< sReal > & gradient()
Definition: signals.h:299
void resample(time_trace &trc)
Definition: signals.h:419
std::string format_file_header(const time_trace_ffmt ffmt_spec)
IO format file header from format specifciation and given time trace.
Definition: signals.h:552
size_t timeShift(sReal t_shift)
Definition: signals.h:335
void operator<<=(int delta)
Definition: signals.h:512
SF::vector< sReal > & diff()
Definition: signals.h:281
std::string t_unit
unit of time axis
Definition: signals.h:130
sReal dt
temporal discretization of trace, if regularly sampled
Definition: signals.h:134
time_trace(sReal _duration, sReal _dt, sReal _rtOff)
Definition: signals.h:157
SF::vector< sReal > f
store function values of trace
Definition: signals.h:132
time_trace(const time_trace &a, sReal val)
copy constructor with setting of constant signal value
Definition: signals.h:200
sReal rtOff
real time offset of time axis
Definition: signals.h:135
std::string f_unit
unit of signal
Definition: signals.h:131
void setUnits(std::string _t_unit, std::string _f_unit)
Definition: signals.h:230
int write_trace()
write traces to file
Definition: signals.h:686
time_trace & operator=(const time_trace &in)
Definition: signals.h:179
void operator>>=(int delta)
Definition: signals.h:531
int read_trace(const std::string fname)
determine duration of a signal stored in file
Definition: signals.h:608
void operator*=(const time_trace &a)
overloaded operators
Definition: signals.h:484
size_t len() const
< length of trace in samples
Definition: signals.h:248
time_trace()
use defaults only, 1000 ms duration, 10 us sampling interval, no real time offset
Definition: signals.h:141
time_trace(const time_trace &a)
copy constructor with setting of constant signal value
Definition: signals.h:194
void operator+=(const sReal a)
double sReal
Definition: signals.h:28
V mod(const V &a, const V &b)
Definition: signals.h:35
time_trace operator*(const time_trace &a, const time_trace &b)
Definition: signals.h:756
time_trace operator+(const time_trace &a, const time_trace &b)
Definition: signals.h:780
time_trace operator-(const time_trace &a, const time_trace &b)
Definition: signals.h:791
time_trace operator/(const time_trace &a, const time_trace &b)
Definition: signals.h:768
enum opencarp::sig::ip_method IpMeth_t