openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
trace.cc
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // openCARP is an open cardiac electrophysiology simulator.
3 //
4 // Copyright (C) 2020 openCARP project
5 //
6 // This program is licensed under the openCARP Academic Public License (APL)
7 // v1.0: You can use and redistribute it and/or modify it in non-commercial
8 // academic environments under the terms of APL as published by the openCARP
9 // project v1.0, or (at your option) any later version. Commercial use requires
10 // a commercial license (info@opencarp.org).
11 //
12 // This program is distributed without any warranty; see the openCARP APL for
13 // more details.
14 //
15 // You should have received a copy of the openCARP APL along with this program
16 // and can find it online: http://www.opencarp.org/license
17 // ----------------------------------------------------------------------------
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 #include <stdbool.h>
24 #include "trace.h"
25 #include "basics.h"
26 
27 namespace limpet {
28 
30 
31 // internally used prototypes
32 bool IsEquDistSampling(trace *tr);
33 
34 
42 void
43 set_trace_amp(trace *tr, float val, float whenceforth )
44 {
45  for( int i=0; i<tr->N; i++ )
46  if( tr->dt*i >= whenceforth )
47  tr->s[i] = val;
48 }
49 
50 
62 int
63 mk_RRC_trace(trace *tr, float st, float delay, float clamp, float dur)
64 {
65  tr->N = 8;
66  tr->t = (double*)malloc(tr->N*sizeof(double));
67  tr->s = (float *)malloc(tr->N*sizeof(float ));
68  tr->t[0] = 0 ; tr->s[0] = 0 ;
69  tr->t[1] = 0.1 ; tr->s[1] = st ;
70  tr->t[2] = 1 ; tr->s[2] = st ;
71  tr->t[3] = 1.1 ; tr->s[3] = 0 ;
72  tr->t[4] = delay ; tr->s[4] = 0 ;
73  tr->t[5] = delay+0.1 ; tr->s[5] = clamp ;
74  tr->t[6] = delay+dur ; tr->s[6] = clamp ;
75  tr->t[7] = delay+dur+0.1 ; tr->s[7] = 0 ;
76  tr->eqdist = IsEquDistSampling(tr);
77  return 0;
78 }
79 
80 
89 int
90 read_trace(trace *tr, const char *name )
91 {
92  int err = 0;
93 
94  FILE *f;
95  if ( (f = fopen(name,"r")) != NULL ) {
96  int n;
97  char buf[128], *bufptr;
98  bufptr = fgets(buf,128,f);
99  sscanf( buf, "%d", &tr->N );
100  tr->t = (double*)malloc(tr->N*sizeof(double));
101  tr->s = (float *)malloc(tr->N*sizeof(float ));
102  for (int i=0;i<tr->N;i++)
103  n = fscanf( f, "%lf %f\n", tr->t+i, tr->s+i );
104  fclose(f);
105  tr->eqdist = IsEquDistSampling(tr);
106  } else {
107  log_msg(0, 3, 0, "Could not open stimulus pulse file %s for reading\n", name);
108  err++;
109  }
110 
111  return err;
112 }
113 
122 void
124 {
125  if(tr->t != NULL) free(tr->t);
126  if(tr->s != NULL) free(tr->s);
127 }
128 
129 
138 {
139  double dt_o = tr->t[1]-tr->t[0];
140  // differences in sampling should be less than 0.1%
141  double r_err = 0.001*dt_o;
142 
143  for (int i=1;i<tr->N-1;i++) {
144  double dt_n = tr->t[i+1]-tr->t[i];
145  if (dt_n-dt_o > r_err)
146  return false;
147  }
148  tr->dt = dt_o;
149  return true;
150 }
151 
152 
153 
162 void resample_trace(trace *tr, double dt )
163 {
164 
165  // interpolate to match dt
166  int N = (int)( (tr->t[tr->N-1]-tr->t[0])/dt )+1;
167  float *s = (float*)malloc(N*sizeof(float));
168  if (!tr->t) {
169  tr->t = (double*)malloc(tr->N*sizeof(double));
170  for (int i=0; i<tr->N;i++) tr->t[i] = i*tr->dt;
171  }
172 
173  interp1(tr->t,tr->s,tr->N,NULL,s,N,dt,_LINEAR_IP);
174 
175  free(tr->t);
176  free(tr->s);
177  tr->dt = dt;
178  tr->N = N;
179  tr->dur = dt*(N-1);
180  tr->s = s;
181  tr->t = NULL;
182 }
183 
194 double trace_duration(trace *tr, const char* f)
195 {
196  bool tr_read = false;
197 
198  // trace has not been read previously
199  if (!tr->s) {
200  if (f!=NULL) {
201  read_trace(tr, f);
202  tr_read = true;
203  } else
204  return -1.;
205  }
206 
207  double duration = 0;
208  if (tr->t)
209  duration = tr->t[tr->N-1]-tr->t[0];
210  else
211  duration = tr->N*tr->dt;
212 
213  if (tr_read) {
214  if (tr->s) free(tr->s);
215  if (tr->t) free(tr->t);
216  }
217  return duration;
218 }
219 
220 
235 void
236 interp1(const double *x, const float *y, int N, double *xi, float *yi, int NI, double dxi, IpMeth_t meth)
237 {
238  // initialize interpolation array
239  memset(yi,0,sizeof(float)*NI);
240 
241  // iterate over target array
242  for (int i=0; i<NI; i++) {
243 
244  // x-axis sample point
245  double xv = xi!=NULL?xi[i]:x[0]+i*dxi;
246 
247  // are we within input x-range?
248  if (xv < x[0] || xv > x[N-1])
249  continue;
250 
251  //binary search
252  int i1 = 0;
253  int i2 = N-1;
254  while(i2 > (i1+1)) {
255  int mid = (i2+i1)/2;
256  if (x[mid] <= xv) {
257  i1 = mid;
258  } else {
259  i2 = mid;
260  }
261  }
262 
263  switch (meth) {
264  case _LINEAR_IP:
265  yi[i] = y[i1] + (y[i2]-y[i1])/(x[i2]-x[i1])*(xv-x[i1]);
266  break;
267  case _NEAREST_IP:
268  if ((xi[i]-x[i1])>= (x[i2]-xi[i]))
269  yi[i] = y[i1];
270  else
271  yi[i] = y[i2];
272  break;
273  }
274  }
275 }
276 
277 } // namespace limpet
Basic utility structs and functions, mostly IO related.
#define log_msg(F, L, O,...)
Definition: filament.h:8
V clamp(const V val, const W start, const W end)
Clamp a value into an interval [start, end].
Definition: kdpart.hpp:132
int mk_RRC_trace(trace *tr, float st, float delay, float clamp, float dur)
make a trace for a repolarization reserve current calculation
Definition: trace.cc:63
double trace_duration(trace *tr, const char *f)
Definition: trace.cc:194
void resample_trace(trace *tr, double dt)
Definition: trace.cc:162
void free_trace(trace *tr)
Definition: trace.cc:123
void set_trace_amp(trace *tr, float val, float whenceforth)
change the amplitude of part of a trace
Definition: trace.cc:43
void interp1(const double *x, const float *y, int N, double *xi, float *yi, int NI, double dxi, IpMeth_t meth)
Definition: trace.cc:236
int read_trace(trace *tr, const char *name)
Definition: trace.cc:90
bool IsEquDistSampling(trace *tr)
Definition: trace.cc:137
enum limpet::ip_method IpMeth_t
@ _NEAREST_IP
Definition: trace.h:36
@ _LINEAR_IP
Definition: trace.h:36
manage input, output, resampling of traces
Definition: trace.h:25
double dt
sampling interval if equidistant samples
Definition: trace.h:30
double dur
duration
Definition: trace.h:29
bool eqdist
sampling intervals are equidistant
Definition: trace.h:31
float * s
samples
Definition: trace.h:28
int N
number of samples
Definition: trace.h:26
double * t
time vector
Definition: trace.h:27