FFTDataContainerAlgorithm.cc
Go to the documentation of this file.
1 #include <utl/FFTDataContainerAlgorithm.h>
2 #include <utl/Math.h>
3 
4 
5 using namespace std;
6 
7 // the specialisations of the template functions have to be defined in namespace utl
8 namespace utl {
9 
11  template<>
12  void
13  FFTDataContainerAlgorithm::HilbertTransform(FFTDataContainer<Trace, double, complex<double> >& container)
14  {
15  // Get the time series
16  Trace<double>& timeseries = container.GetTimeSeries();
17  const unsigned int n = timeseries.GetSize(); // number of points in time and frequency domain
18 
19  if (!n) { // empty frequency spectrum
20  WARNING("Warning: trying to do a Hilbert transform on an empty time series!");
21  return;
22  }
23 
24  complex<double>* const fftin = FFTWComplex(n); // allocate memory through fftw, making sure it is correctly aligned
25  complex<double>* const fftout = FFTWComplex(n);
26 
27  fftwpp::fft1d Forward(n, -1, fftin, fftout); // plan fft through fftw
28  fftwpp::fft1d Backward(n, 1, fftout, fftin); // plan fft^-1 through fftw
29 
30  for (unsigned int i = 0; i < n; ++i) {
31  fftin[i].real(timeseries[i]);
32  fftin[i].imag(0.);
33  }
34  Forward.fft(fftin, fftout);
35 
36  for (unsigned int i = 0; i < n; ++i) {
37  double tmp;
38  if (i < (n / 2)) {
39  tmp = imag(fftout[i]);
40  fftout[i].imag(-real(fftout[i]));
41  } else {
42  tmp = -imag(fftout[i]);
43  fftout[i].imag(real(fftout[i]));
44  }
45  fftout[i].real(tmp);
46  }
47 
48  Backward.fft(fftout, fftin);
49 
50  for (unsigned int i = 0; i < n; ++i)
51  timeseries[i] = real(fftin[i])/n;
52 
53  FFTWdelete(fftin/*, n*/);
54  FFTWdelete(fftout/*, n*/);
55  }
56 
58  template<>
59  void
60  FFTDataContainerAlgorithm::HilbertTransform(FFTDataContainer<Trace, Vector3D, Vector3C>& container)
61  {
62  // Get the time series
63  Trace<Vector3D>& timeseries = container.GetTimeSeries();
64  const unsigned int n = timeseries.GetSize(); // number of points in time and frequency domain
65 
66  if (!n) { // empty frequency spectrum
67  WARNING("Warning: trying to do a Hilbert envelope on an empty time series!");
68  return;
69  }
70 
71  std::complex<double>* const fftin = FFTWComplex(n); // allocate memory through fftw, making sure it is correctly aligned
72  std::complex<double>* const fftout = FFTWComplex(n);
73 
74  fftwpp::fft1d Forward(n, -1, fftin, fftout); // fft through fftw
75  fftwpp::fft1d Backward(n, 1, fftout, fftin); // fft^-1 through fftw
76 
77  for (unsigned int j = 0; j < 3; ++j) {
78 
79  for (unsigned int i = 0; i < n; ++i) {
80  fftin[i].real(timeseries[i][j]);
81  fftin[i].imag(0.);
82  }
83  Forward.fft(fftin, fftout);
84 
85  for (unsigned int i = 0; i < n; ++i) {
86  double tmp;
87  if (i < (n / 2)) {
88  tmp = imag(fftout[i]);
89  fftout[i].imag(-real(fftout[i]));
90  } else {
91  tmp = -imag(fftout[i]);
92  fftout[i].imag(real(fftout[i]));
93  }
94  fftout[i].real(tmp);
95  }
96 
97  Backward.fft(fftout, fftin);
98 
99  for (unsigned int i = 0; i < n; ++i)
100  timeseries[i][j] = real(fftin[i])/n;
101 
102  }
103 
104  FFTWdelete(fftin/*, n*/);
105  FFTWdelete(fftout/*, n*/);
106  }
107 
109  template<>
110  void
111  FFTDataContainerAlgorithm::HilbertEnvelope(FFTDataContainer<Trace, double, complex<double> >& container)
112  {
113  FFTDataContainer<Trace, double, complex<double> > transformedContainter = container;
114 
115  HilbertTransform(transformedContainter);
116  Trace<double>& timeseries =container.GetTimeSeries();
117  Trace<double>& transformedTimeseries =transformedContainter.GetTimeSeries();
118  const unsigned int n = timeseries.GetSize();
119  for (unsigned int i = 0; i < n; ++i)
120  timeseries[i] = sqrt(Sqr(timeseries[i]) + Sqr(transformedTimeseries[i]));
121  }
122 
124  template<>
125  void
126  FFTDataContainerAlgorithm::HilbertEnvelope(FFTDataContainer<Trace, Vector3D, Vector3C>& container)
127  {
128 
129  FFTDataContainer<Trace, Vector3D, Vector3C> transformedContainter = container;
130 
131  HilbertTransform(transformedContainter);
132 
133  Trace<Vector3D>& timeseries = container.GetTimeSeries();
134  const unsigned int n = timeseries.GetSize();
135  Trace<Vector3D>& transformedTimeseries =transformedContainter.GetTimeSeries();
136  // could also be done on GPU
137  for (unsigned int j = 0; j < 3; ++j) {
138  for (unsigned int i = 0; i < n; ++i) {
139  timeseries[i][j] = sqrt(Sqr(timeseries[i][j]) + Sqr(transformedTimeseries[i][j]));
140  }
141  }
142  }
143 
144 }
constexpr T Sqr(const T &x)
void fft(Complex *in, Complex *out=NULL)
Definition: fftw++.h:414
C< T > & GetTimeSeries()
read out the time series (write access)
SizeType GetSize() const
Definition: Trace.h:156
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
Template class for a data container that offers and takes both time series and corresponding frequenc...
#define FFTWComplex
Definition: fftw++.h:93
Template class for a FADC data or calibrated data container. Use the typedefs (TraceD, TraceI, etc.) defined in Trace-fwd.h.
Definition: Trace-fwd.h:19
#define FFTWdelete
Definition: fftw++.h:95

, generated on Tue Sep 26 2023.