GPLIB++
TimeSeriesComponent.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <functional>
3 #include <boost/bind.hpp>
4 #include <boost/numeric/conversion/cast.hpp>
5 #include "TimeSeriesComponent.h"
6 #include "FatalException.h"
7 #ifdef HAVEGSL
8 #include <gsl/gsl_spline.h>
9 #endif
10 
11 namespace gplib
12  {
13 
15  {
16  samplerate = 0.0;
17  }
18 
20  {
21  }
22 
24  data(source.data), samplerate(source.samplerate), name(source.name),
25  starttime(source.starttime)
26  {
27  }
28 
29  void TimeSeriesComponent::ShiftStart(const int npts)
30  {
31  //calculate the time_shift with microsecond precision
32  boost::posix_time::time_duration time_shift =
33  boost::posix_time::microseconds(boost::numeric_cast<unsigned int>(
34  npts * 1000000 / samplerate));
35  if (npts < 0) // if we want to remove something
36  {
37  if (static_cast<size_t> (abs(npts)) > data.size())
38  throw FatalException("Trying to shift by too many points. ");
39  // erase the data points
40  data.erase(data.begin(), data.begin() + abs(npts));
41  // correct the starttime with microsecond precision
42  starttime = starttime + time_shift;
43  }
44  else //we want to add something
45  {
46  data.insert(data.begin(), npts, 0);
47  starttime = starttime - time_shift;
48  }
49  }
50 
51  void TimeSeriesComponent::ShiftEnd(const int npts)
52  {
53  if (npts < 0)
54  {
55  if (static_cast<size_t> (abs(npts)) > data.size())
56  throw FatalException("Trying to cut too many points. ");
57  data.erase(data.end() + npts, data.end());
58  }
59  else
60  {
61  data.insert(data.end(), npts, 0);
62  }
63  }
64 
66  const TimeSeriesComponent& source)
67  {
68  if (this != &source)
69  {
70  this->samplerate = source.samplerate;
71  this->name = source.name;
72  this->starttime = source.starttime;
73  this->data.assign(source.data.size(), 0); //assign and copy clears old data
74  std::copy(source.data.begin(), source.data.end(),
75  this->data.begin());
76  }
77  return *this;
78  }
79 
80  //we want to make the dependency on gsl optional, so we only have this function
81  //if gsl exists
82 #ifdef HAVEGSL
83  void TimeSeriesComponent::Resample(const double newdt)
84  {
85  const size_t oldlength = data.size();
86  double *oldtime = new double[oldlength];
87  const double dt = GetDt();
88  double start = 0.0;
89  //we need time information for interpolation, the real starttime is irrelevant for this
90  for (size_t i = 0; i < oldlength; ++i)
91  {
92  oldtime[i] = start + i * dt;
93  }
94  //initialize the gsl interpolation routines
95  gsl_interp_accel *acc = gsl_interp_accel_alloc();
96  gsl_spline *spline = gsl_spline_alloc(gsl_interp_cspline, oldlength);
97  gsl_spline_init(spline, oldtime, &data[0], oldlength);
98  // calculate the lenght of the resampled timeseries
99  const size_t newlength = boost::numeric_cast<size_t>(oldlength * (dt
100  / newdt));
101  // clear old data
102  data.clear();
103  //create new timeseries
104  for (size_t i = 0; i < newlength; ++i)
105  {
106  data.push_back(gsl_spline_eval(spline, start + i * newdt, acc));
107  }
108  gsl_spline_free(spline);
109  gsl_interp_accel_free(acc);
110  samplerate = 1. / newdt;
111 
112  }
113 #endif //HAVEGSL
114 
116  {
117  std::transform(data.begin(), data.end(), data.begin(), boost::bind(
118  std::multiplies<double>(), factor, _1));
119  return *this;
120  }
121 
123  {
124  const double factor = 1. / numerator;
125  operator*=(factor);
126  return *this;
127  }
128 
130  {
131  std::transform(data.begin(), data.end(), data.begin(), boost::bind(
132  std::plus<double>(), shift, _1));
133  return *this;
134  }
135 
137  const TimeSeriesComponent &other)
138  {
139  std::transform(data.begin(), data.end(), other.data.begin(),
140  data.begin(), std::plus<double>());
141  return *this;
142  }
144  {
145  operator+=(-shift);
146  return *this;
147  }
148  //for this operator it is more efficient to reimplement it instead of calling += with -other
150  const TimeSeriesComponent &other)
151  {
152  std::transform(data.begin(), data.end(), other.data.begin(),
153  data.begin(), std::minus<double>());
154  return *this;
155  }
156  }
TimeSeriesComponent & operator+=(const double shift)
Add a constant shift to each element of the time series.
void ShiftStart(const int npts)
Shift the start of the recording by npts points.
void ShiftEnd(const int npts)
Shift the end of the recording by npts points.
TimeSeriesComponent & operator-=(const double shift)
Substract a constant shift from each element of the time series.
TimeSeriesComponent & operator/=(const double numerator)
Devide each element of the time series by a constant number.
TimeSeriesComponent is the base storage class for all types of time series data.
TimeSeriesComponent & operator*=(const double factor)
Multiply each element of the time series by a constant factor.
double GetDt() const
Return dt in s.
The basic exception class for all errors that arise in gplib.
TimeSeriesComponent & operator=(const TimeSeriesComponent &source)