FFTDataContainer.cc
Go to the documentation of this file.
1 #include <utl/FFTDataContainer.h>
2 #include <utl/ErrorLogger.h>
3 
4 using namespace std;
5 
6 
7 // the specialisations of the template functions have to be defined in namespace utl
8 
9 namespace utl {
10 
11  template<>
12  void
14  const
15  {
16  const unsigned int np = fFrequencySpectrum.GetSize(); // number of points in frequency domain
17  const unsigned int n = (np - 1) * 2; // number of points in time domain
18 
19  if (!np) { // empty frequency spectrum
20  fUpToDateDomain = eBoth; // now both domains are up to date
21  WARNING("Warning: trying to do FFT on empty channel frequency spectrum!");
22  return;
23  }
24 
25  double* const f = FFTWdouble(n); // allocate memory through fftw, making sure it is correctly aligned
26  complex<double>* const g = FFTWComplex(np);
27 
28  fftwpp::crfft1d Backward(n, g, f); // "plan" fft^-1 through fftw
29 
30  // fill fftw array, normalising on the way - maybe implement a more efficient way through copying ("reverse adopt") in Trace
31  for (unsigned int i = 0; i < np; ++i)
32  g[i] = fFrequencySpectrum[i] * fFrequencySpectrum.GetBinning();
33  // should this explicitly "try" for exceptions?
34 
35  Backward.fft(g, f);
36 
37  fTimeSeries.Adopt(f, n); // fill result into our data structure
38  fTimeSeries.SetBinning(1. / (fFrequencySpectrum.GetBinning() * n));
39 
40  FFTWdelete(f/*, n*/);
41  FFTWdelete(g/*, np*/);
42 
43  fUpToDateDomain = eBoth; // now both domains are up to date
44  }
45 
46 
47  template<>
48  void
50  const
51  {
52  // check for an uneven number of samples and clip one sample if this is the case
53  unsigned int nop = fTimeSeries.GetSize(); // number of points in time domain
54  if ((nop / 2)*2 != nop) {
55  fTimeSeries.PopBack();
56  nop = fTimeSeries.GetSize();
57  }
58 
59  if (!nop) { // empty frequency spectrum
60  fUpToDateDomain = eBoth; // now both domains are up to date
61  WARNING("Warning: trying to do FFT on empty channel time series!");
62  return;
63  }
64 
65  const unsigned int n = fTimeSeries.GetSize(); // number of points in time domain
66  const unsigned int np = n/2 + 1; // number of points in frequency domain
67 
68  double* const f = FFTWdouble(n); // allocate memory through fftw, making sure it is correctly aligned
69  complex<double>* const g = FFTWComplex(np);
70 
71  fftwpp::rcfft1d Forward(n, f, g); // "plan" fft through fftw
72 
73  // fill fftw array, normalising on the way - maybe implement a more efficient way through copying ("reverse adopt") in Trace
74  for (unsigned int i = 0; i < n; ++i)
75  f[i] = fTimeSeries[i] * fTimeSeries.GetBinning();
76  // should this explicitly "try" for exceptions?
77 
78  Forward.fft(f, g);
79 
80  fFrequencySpectrum.Adopt(g, np); // fill result into our data structure
81  fFrequencySpectrum.SetBinning(0.5 / (fTimeSeries.GetBinning() * (np - 1)));
82 
83  FFTWdelete(f/*, n*/);
84  FFTWdelete(g/*, np*/);
85 
86  fUpToDateDomain = eBoth; // now both domains are up to date
87  }
88 
89 
90  template<>
91  void
93  const
94  {
95  const unsigned int np = fFrequencySpectrum.GetSize(); // number of points in frequency domain
96  const unsigned int n = (np - 1) * 2; // number of points in time domain
97 
98  if (!np) { // empty frequency spectrum
99  fUpToDateDomain = eBoth; // now both domains are up to date
100  WARNING("Warning: trying to do FFT on empty station frequency spectrum!");
101  return;
102  }
103 
104  double* const f = FFTWdouble(n); // allocate memory through fftw, making sure it is correctly aligned
105  complex<double>* const g = FFTWComplex(np);
106  Vector3D* const resultTimeSeries = new Vector3D[n]; // allocate temporary array of Vector3D to store the result time series
107 
108  fftwpp::crfft1d Backward(n, g, f); // "plan" fft^-1 through fftw
109 
110  // now do the three sub-ffts
111  for (int j = 0; j < 3; ++j) {
112  // fill fftw array, normalising on the way - maybe implement a more efficient way through copying ("reverse adopt") in Trace
113  for (unsigned int i = 0; i < np; ++i)
114  g[i] = fFrequencySpectrum[i][j] * fFrequencySpectrum.GetBinning();
115  // should this explicitly "try" for exceptions?
116  Backward.fft(g, f);
117  for (unsigned int i = 0; i < n; ++i)
118  resultTimeSeries[i][j] = f[i]; // fill result into our data structure
119  }
120  fTimeSeries.Adopt(resultTimeSeries, n);
121  fTimeSeries.SetBinning(1. / (fFrequencySpectrum.GetBinning() * n));
122 
123  FFTWdelete(f/*, n*/);
124  FFTWdelete(g/*, np*/);
125  delete[] resultTimeSeries;
126 
127  fUpToDateDomain = eBoth; // now both domains are up to date
128  }
129 
130 
131  // ORIGINAL SERIAL FUNCTION
132  template<>
133  void
135  const
136  {
137  // check for an uneven number of samples and clip one sample if this is the case
138  unsigned int nop = fTimeSeries.GetSize(); // number of points in time domain
139  if ((nop / 2)*2 != nop) {
140  fTimeSeries.PopBack();
141  nop = fTimeSeries.GetSize();
142  }
143 
144  if (!nop) { // empty frequency spectrum
145  fUpToDateDomain = eBoth; // now both domains are up to date
146  WARNING("Warning: trying to do FFT on empty station time series!");
147  return;
148  }
149 
150  const unsigned int n = fTimeSeries.GetSize(); // number of points in time domain
151  const unsigned int np = n/2 + 1; // number of points in frequency domain
152 
153  double* const f = FFTWdouble(n); // allocate memory through fftw, making sure it is correctly aligned
154  complex<double>* const g = FFTWComplex(np);
155  Vector3C* const resultSpectrum = new Vector3C[np]; // allocate temporary array of Vector3C to store the result spectrum
156 
157  fftwpp::rcfft1d Forward(n, f, g); // "plan" fft through fftw
158 
159  // now do the three sub-ffts
160  for (int j = 0; j < 3; ++j) {
161  // fill fftw array, normalising on the way - maybe implement a more efficient way through copying ("reverse adopt") in Trace
162  for (unsigned int i = 0; i < n; ++i)
163  f[i] = fTimeSeries[i][j] * fTimeSeries.GetBinning();
164  // should this explicitly "try" for exceptions?
165  Forward.fft(f, g);
166  for (unsigned int i = 0; i < np; ++i)
167  resultSpectrum[i][j] = g[i]; // fill result into our data structure
168  }
169  fFrequencySpectrum.Adopt(resultSpectrum, np);
170  fFrequencySpectrum.SetBinning(0.5 / (fTimeSeries.GetBinning() * (np - 1)));
171 
172  FFTWdelete(f/*, n*/);
173  FFTWdelete(g/*, np*/);
174  delete[] resultSpectrum;
175 
176  fUpToDateDomain = eBoth; // now both domains are up to date
177  }
178 
179 }
#define FFTWdouble
Definition: fftw++.h:94
void fft(Complex *in, Complex *out=NULL)
Definition: fftw++.h:414
constexpr double g
Definition: AugerUnits.h:200
#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
#define FFTWdelete
Definition: fftw++.h:95

, generated on Tue Sep 26 2023.