LAL  7.5.0.1-ec27e42
TimeFreqFFT.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Duncan Brown, Jolien Creighton, Kipp Cannon, Patrick Brady, Tania Regimbau
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #ifndef _TIMEFREQFFT_H
21 #define _TIMEFREQFFT_H
22 
23 #include <lal/LALDatatypes.h>
24 #include <lal/ComplexFFT.h>
25 #include <lal/RealFFT.h>
26 #include <lal/Window.h>
27 
28 #if defined(__cplusplus)
29 extern "C" {
30 #elif 0
31 } /* so that editors will match preceding brace */
32 #endif
33 
34 /**
35  * \defgroup TimeFreqFFT_h Header TimeFreqFFT_h
36  * \ingroup lal_fft
37  *
38  * \brief Performs real-to-complex, complex-to-real FFTs and average power spectrum estimation.
39  *
40  * ### Synopsis ###
41  *
42  * \code
43  * #include <lal/TimeFreqFFT.h>
44  * \endcode
45  *
46  * Perform time-to-frequency and frequency-to-time fast Fourier
47  * transforms. Also provides a function to compute mean and median power
48  * spectra with user specified windowning.
49  *
50  * ### Description ###
51  *
52  * The routines LALTimeFreqRealFFT() and LALTimeFreqComplexFFT()
53  * transform time series \f$h_j\f$, \f$0\le j<n\f$, into a frequency series
54  * \f$\tilde{h}_k\f$. For LALTimeFreqRealFFT(),
55  * \f[
56  * \tilde{h}_k = \Delta t \times H_k \;
57  * \mbox{for } 0\le k\le\lfloor n/2\rfloor
58  * \f]
59  * The packing covers the range from dc (inclusive) to Nyquist (inclusive if
60  * \f$n\f$ is even).
61  * For LALTimeFreqComplexFFT(),
62  * \f[
63  * \tilde{h}_k = \Delta t \left\{
64  * \begin{array}{ll}
65  * H_{k+\lfloor(n+1)/2\rfloor} &
66  * \mbox{for } 0\le k<\lfloor n/2\rfloor, \\
67  * H_{k-\lfloor n/2\rfloor} &
68  * \mbox{for } \lfloor n/2\rfloor\le k<n. \\
69  * \end{array}
70  * \right.
71  * \f]
72  * The packing covers the range from negative Nyquist (inclusive if \f$n\f$ is
73  * even) up to (but not including) positive Nyquist.
74  * Here \f$H_k\f$ is the DFT of \f$h_j\f$:
75  * \f[
76  * H_k = \sum_{j=0}^{n-1} h_j e^{-2\pi ijk/n}.
77  * \f]
78  * The units of \f$\tilde{h}_k\f$ are equal to the units of \f$h_j\f$ times seconds.
79  *
80  * The routines LALFreqTimeRealFFT() and LALFreqTimeComplexFFT()
81  * perform the inverse transforms from \f$\tilde{h}_k\f$ back to \f$h_j\f$. This is
82  * done by shuffling the data, performing the reverse DFT, and multiplying by
83  * \f$\Delta f\f$.
84  *
85  * The routine LALREAL4AverageSpectrum() uses Welch's method to compute
86  * the average power spectrum of the time series stored in the input structure
87  * \c tSeries and return it in the output structure \c fSeries. A
88  * Welch PSD estimate is defined by an FFT length, overlap length, choice of
89  * window function and averaging method. These are specified in the
90  * parameter structure; the FFT length is obtained from the length of the
91  * \c REAL4Window in the parameters.
92  *
93  * On entry the parameter structure \c params must contain a valid
94  * \c REAL4Window, an integer that determines the overlap as described
95  * below and a forward FFT plan for transforming data of the specified
96  * window length into the time domain. The method used to compute the
97  * average must also be set.
98  *
99  * If the length of the window is \f$N\f$, then the FFT length is defined to be
100  * \f$N/2-1\f$. The input data of length \f$M\f$ is divided into \f$i\f$ segments which
101  * overlap by \f$o\f$, where
102  * \f{equation}{
103  * i = \frac{M-o}{N-o}.
104  * \f}
105  *
106  * The PSD of each segment is obtained. The Welch PSD estimate is the average
107  * of these \f$i\f$ sub-estimates. The average is computed using the mean or
108  * median method, as specified in the parameter structure.
109  *
110  * Note: the return PSD estimate is a one-sided power spectral density
111  * normalized as defined in the conventions document. When the averaging
112  * method is choosen to be mean and the window type Hann, the result is the
113  * same as returned by the LDAS datacondAPI <tt>psd()</tt> action for a real
114  * sequence without detrending.
115  *
116  * ### Operating Instructions ###
117  *
118  * \code
119  * const UINT4 n = 65536;
120  * const REAL4 dt = 1.0 / 16384.0;
121  * static LALStatus status; compute average power spectrum
122  * static REAL4TimeSeries x;
123  * static COMPLEX8FrequencySeries X;
124  * static COMPLEX8TimeSeries z;
125  * static COMPLEX8FrequencySeries Z;
126  * RealFFTPlan *fwdRealPlan = NULL;
127  * RealFFTPlan *revRealPlan = NULL;
128  * ComplexFFTPlan *fwdComplexPlan = NULL;
129  * ComplexFFTPlan *revComplexPlan = NULL;
130  *
131  * LALSCreateVector( &status, &x.data, n );
132  * LALCCreateVector( &status, &X.data, n / 2 + 1 );
133  * LALCCreateVector( &status, &z.data, n );
134  * LALCCreateVector( &status, &Z.data, n );
135  * LALCreateForwardRealFFTPlan( &status, &fwdRealPlan, n, 0 );
136  * LALCreateReverseRealFFTPlan( &status, &revRealPlan, n, 0 );
137  * LALCreateForwardComplexFFTPlan( &status, &fwdComplexPlan, n, 0 );
138  * LALCreateReverseComplexFFTPlan( &status, &revComplexPlan, n, 0 );
139  *
140  * x.f0 = 0;
141  * x.deltaT = dt;
142  * x.sampleUnits = lalMeterUnit;
143  * strncpy( x.name, "x", sizeof( x.name ) );
144  *
145  * z.f0 = 0;
146  * z.deltaT = dt;
147  * z.sampleUnits = lalVoltUnit;
148  * strncpy( z.name, "z", sizeof( z.name ) );
149  *
150  * <assign data>
151  *
152  * LALTimeFreqRealFFT( &status, &X, &x, fwdRealPlan );
153  * LALFreqTimeRealFFT( &status, &x, &X, revRealPlan );
154  * LALTimeFreqComplexFFT( &status, &Z, &z, fwdComplexPlan );
155  * LALFreqTimeComplexFFT( &status, &z, &Z, revComplexPlan );
156  *
157  * LALDestroyRealFFTPlan( &status, &fwdRealPlan );
158  * LALDestroyRealFFTPlan( &status, &revRealPlan );
159  * LALDestroyComplexFFTPlan( &status, &fwdComplexPlan );
160  * LALDestroyComplexFFTPlan( &status, &revComplexPlan );
161  * LALCDestroyVector( &status, &Z.data );
162  * LALCDestroyVector( &status, &z.data );
163  * LALCDestroyVector( &status, &X.data );
164  * LALSDestroyVector( &status, &x.data );
165  * \endcode
166  *
167  * ### Notes ###
168  *
169  * <ol>
170  * <li> The routines do not presently work properly with heterodyned data,
171  * i.e., the original time series data should have \c f0 equal to zero.
172  * </li></ol>
173  *
174  */
175 /** @{ */
176 
177 /** UNDOCUMENTED */
178 typedef struct
179 tagLALPSDRegressor
180 {
181  unsigned average_samples;
182  unsigned median_samples;
183  unsigned n_samples;
186 }
188 
189 /*
190  *
191  * XLAL Functions
192  *
193  */
196  const REAL4TimeSeries *tser,
197  const REAL4FFTPlan *plan
198  );
199 
201  REAL4TimeSeries *tser,
202  const COMPLEX8FrequencySeries *freq,
203  const REAL4FFTPlan *plan
204  );
205 
208  const REAL8TimeSeries *tser,
209  const REAL8FFTPlan *plan
210  );
211 
213  REAL8TimeSeries *tser,
214  const COMPLEX16FrequencySeries *freq,
215  const REAL8FFTPlan *plan
216  );
217 
220  const COMPLEX8TimeSeries *tser,
221  const COMPLEX8FFTPlan *plan
222  );
223 
225  COMPLEX8TimeSeries *tser,
226  const COMPLEX8FrequencySeries *freq,
227  const COMPLEX8FFTPlan *plan
228  );
229 
232  const COMPLEX16TimeSeries *tser,
233  const COMPLEX16FFTPlan *plan
234  );
235 
237  COMPLEX16TimeSeries *tser,
238  const COMPLEX16FrequencySeries *freq,
239  const COMPLEX16FFTPlan *plan
240  );
241 
243  REAL4FrequencySeries *periodogram,
244  const REAL4TimeSeries *tseries,
245  const REAL4Window *window,
246  const REAL4FFTPlan *plan
247  );
248 
250  REAL8FrequencySeries *periodogram,
251  const REAL8TimeSeries *tseries,
252  const REAL8Window *window,
253  const REAL8FFTPlan *plan
254  );
255 
257  REAL4FrequencySeries *spectrum,
258  const REAL4TimeSeries *tseries,
259  UINT4 seglen,
260  UINT4 stride,
261  const REAL4Window *window,
262  const REAL4FFTPlan *plan
263  );
264 
266  REAL8FrequencySeries *spectrum,
267  const REAL8TimeSeries *tseries,
268  UINT4 seglen,
269  UINT4 stride,
270  const REAL8Window *window,
271  const REAL8FFTPlan *plan
272  );
273 
275 
277 
279  REAL4FrequencySeries *spectrum,
280  const REAL4TimeSeries *tseries,
281  UINT4 seglen,
282  UINT4 stride,
283  const REAL4Window *window,
284  const REAL4FFTPlan *plan
285  );
286 
288  REAL8FrequencySeries *spectrum,
289  const REAL8TimeSeries *tseries,
290  UINT4 seglen,
291  UINT4 stride,
292  const REAL8Window *window,
293  const REAL8FFTPlan *plan
294  );
295 
297  REAL4FrequencySeries *spectrum,
298  const REAL4TimeSeries *tseries,
299  UINT4 seglen,
300  UINT4 stride,
301  const REAL4Window *window,
302  const REAL4FFTPlan *plan
303  );
304 
306  REAL8FrequencySeries *spectrum,
307  const REAL8TimeSeries *tseries,
308  UINT4 seglen,
309  UINT4 stride,
310  const REAL8Window *window,
311  const REAL8FFTPlan *plan
312  );
313 
315  REAL4FrequencySeries *spectrum,
316  REAL4 lowfreq,
317  UINT4 seglen,
318  UINT4 trunclen,
319  REAL4FFTPlan *fwdplan,
320  REAL4FFTPlan *revplan
321  );
322 
324  REAL8FrequencySeries *spectrum,
325  REAL8 lowfreq,
326  UINT4 seglen,
327  UINT4 trunclen,
328  REAL8FFTPlan *fwdplan,
329  REAL8FFTPlan *revplan
330  );
331 
333  REAL4TimeSeries *strain,
334  COMPLEX8FrequencySeries *transfer
335  );
336 
338  REAL4TimeSeries *strain,
339  REAL4TimeSeries *transfer
340  );
341 
343  COMPLEX8FrequencySeries *fseries,
344  const REAL4FrequencySeries *psd
345  );
346 
348  COMPLEX16FrequencySeries *fseries,
349  const REAL8FrequencySeries *psd
350 );
351 
353  const REAL8Window *window,
354  const REAL8FFTPlan *plan
355 );
356 
359  unsigned average_samples,
360  unsigned median_samples
361 );
362 
363 void
366 );
367 
368 void
371 );
372 
375  unsigned average_samples
376 );
377 
379  const LALPSDRegressor *r
380 );
381 
383  const LALPSDRegressor *r
384 );
385 
388  unsigned median_samples
389 );
390 
392  const LALPSDRegressor *r
393 );
394 
395 int
398  const COMPLEX16FrequencySeries *sample
399 );
400 
403  const LALPSDRegressor *r
404 );
405 
406 int
409  const REAL8FrequencySeries *psd,
410  unsigned weight
411 );
412 
413 
414 /** @} */
415 
416 #if 0
417 { /* so that editors will match succeeding brace */
418 #elif defined(__cplusplus)
419 }
420 #endif
421 
422 #endif /* _TIMEFREQFFT_H */
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
float REAL4
Single precision real floating-point number (4 bytes).
static const INT4 r
Definition: Random.c:82
unsigned XLALPSDRegressorGetAverageSamples(const LALPSDRegressor *r)
Return the average_samples of a LALPSDRegressor object.
void XLALPSDRegressorReset(LALPSDRegressor *r)
Reset a LALPSDRegressor object to the newly-allocated state.
LALPSDRegressor * XLALPSDRegressorNew(unsigned average_samples, unsigned median_samples)
Allocate and initialize a LALPSDRegressor object.
REAL8 XLALMedianBias(UINT4 nn)
compute the median bias * See arXiv: gr-qc/0509116 appendix B for details
int XLALREAL4ModifiedPeriodogram(REAL4FrequencySeries *periodogram, const REAL4TimeSeries *tseries, const REAL4Window *window, const REAL4FFTPlan *plan)
Compute a "modified periodogram," i.e., the power spectrum of a windowed time series.
REAL4TimeSeries * XLALRespFilt(REAL4TimeSeries *strain, COMPLEX8FrequencySeries *transfer)
Apply transfer function to time series.
Definition: Convolution.c:55
int XLALPSDRegressorAdd(LALPSDRegressor *r, const COMPLEX16FrequencySeries *sample)
Update a LALPSDRegressor object from a frequency series object.
REAL8FrequencySeries * XLALPSDRegressorGetPSD(const LALPSDRegressor *r)
Retrieve a copy of the current PSD estimate.
REAL8Sequence * XLALREAL8WindowTwoPointSpectralCorrelation(const REAL8Window *window, const REAL8FFTPlan *plan)
Compute the two-point spectral correlation function for a whitened frequency series from the window a...
int XLALCOMPLEX16FreqTimeFFT(COMPLEX16TimeSeries *tser, const COMPLEX16FrequencySeries *freq, const COMPLEX16FFTPlan *plan)
Definition: TimeFreqFFT.c:388
int XLALREAL8AverageSpectrumWelch(REAL8FrequencySeries *spectrum, const REAL8TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL8Window *window, const REAL8FFTPlan *plan)
Use Welch's method to compute the average power spectrum of a time series.
int XLALREAL4AverageSpectrumMedian(REAL4FrequencySeries *spectrum, const REAL4TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL4Window *window, const REAL4FFTPlan *plan)
Median Method: use median average rather than mean.
void XLALPSDRegressorFree(LALPSDRegressor *r)
Free all memory associated with a LALPSDRegressor object.
int XLALREAL8AverageSpectrumMedian(REAL8FrequencySeries *spectrum, const REAL8TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL8Window *window, const REAL8FFTPlan *plan)
Median Method: use median average rather than mean.
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *tser, const REAL8FFTPlan *plan)
Definition: TimeFreqFFT.c:117
int XLALPSDRegressorSetAverageSamples(LALPSDRegressor *r, unsigned average_samples)
Change the average_samples of a LALPSDRegressor object.
unsigned XLALPSDRegressorGetMedianSamples(const LALPSDRegressor *r)
Return the median_samples of a LALPSDRegressor object.
int XLALPSDRegressorSetPSD(LALPSDRegressor *r, const REAL8FrequencySeries *psd, unsigned weight)
Initialize the running average of a LALPSDRegressor to the given PSD, and record it has having counte...
int XLALPSDRegressorSetMedianSamples(LALPSDRegressor *r, unsigned median_samples)
Change the median_samples of a LALPSDRegressor object.
COMPLEX16FrequencySeries * XLALWhitenCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *fseries, const REAL8FrequencySeries *psd)
Double-precision version of XLALWhitenCOMPLEX8FrequencySeries().
int XLALREAL8ModifiedPeriodogram(REAL8FrequencySeries *periodogram, const REAL8TimeSeries *tseries, const REAL8Window *window, const REAL8FFTPlan *plan)
Compute a "modified periodogram," i.e., the power spectrum of a windowed time series.
unsigned XLALPSDRegressorGetNSamples(const LALPSDRegressor *r)
Return the number of frequency series samples over which the running average has been computed.
REAL8 XLALLogMedianBiasGeometric(UINT4 nn)
Geometric mean median bias factor.
REAL4TimeSeries * XLALREAL4Convolution(REAL4TimeSeries *strain, REAL4TimeSeries *transfer)
SHOULD Convolve two time series, but doesn't.
Definition: Convolution.c:146
int XLALCOMPLEX8FreqTimeFFT(COMPLEX8TimeSeries *tser, const COMPLEX8FrequencySeries *freq, const COMPLEX8FFTPlan *plan)
Definition: TimeFreqFFT.c:261
COMPLEX8FrequencySeries * XLALWhitenCOMPLEX8FrequencySeries(COMPLEX8FrequencySeries *fseries, const REAL4FrequencySeries *psd)
Normalize a COMPLEX8 frequency series to a REAL4 average PSD.
int XLALREAL8SpectrumInvertTruncate(REAL8FrequencySeries *spectrum, REAL8 lowfreq, UINT4 seglen, UINT4 trunclen, REAL8FFTPlan *fwdplan, REAL8FFTPlan *revplan)
UNDOCUMENTED.
int XLALREAL4AverageSpectrumWelch(REAL4FrequencySeries *spectrum, const REAL4TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL4Window *window, const REAL4FFTPlan *plan)
Use Welch's method to compute the average power spectrum of a time series.
int XLALCOMPLEX16TimeFreqFFT(COMPLEX16FrequencySeries *freq, const COMPLEX16TimeSeries *tser, const COMPLEX16FFTPlan *plan)
Definition: TimeFreqFFT.c:333
int XLALREAL4FreqTimeFFT(REAL4TimeSeries *tser, const COMPLEX8FrequencySeries *freq, const REAL4FFTPlan *plan)
Definition: TimeFreqFFT.c:74
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *tser, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
Definition: TimeFreqFFT.c:153
int XLALCOMPLEX8TimeFreqFFT(COMPLEX8FrequencySeries *freq, const COMPLEX8TimeSeries *tser, const COMPLEX8FFTPlan *plan)
Definition: TimeFreqFFT.c:206
int XLALREAL4AverageSpectrumMedianMean(REAL4FrequencySeries *spectrum, const REAL4TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL4Window *window, const REAL4FFTPlan *plan)
Median-Mean Method: divide overlapping segments into "even" and "odd" segments; compute the bin-by-bi...
int XLALREAL4TimeFreqFFT(COMPLEX8FrequencySeries *freq, const REAL4TimeSeries *tser, const REAL4FFTPlan *plan)
Definition: TimeFreqFFT.c:38
int XLALREAL8AverageSpectrumMedianMean(REAL8FrequencySeries *spectrum, const REAL8TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL8Window *window, const REAL8FFTPlan *plan)
Median-Mean Method: divide overlapping segments into "even" and "odd" segments; compute the bin-by-bi...
int XLALREAL4SpectrumInvertTruncate(REAL4FrequencySeries *spectrum, REAL4 lowfreq, UINT4 seglen, UINT4 trunclen, REAL4FFTPlan *fwdplan, REAL4FFTPlan *revplan)
UNDOCUMENTED.
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:909
Time series of COMPLEX16 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:600
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:899
Time series of COMPLEX8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:590
UNDOCUMENTED.
Definition: TimeFreqFFT.h:180
unsigned median_samples
Definition: TimeFreqFFT.h:182
REAL8Sequence ** history
Definition: TimeFreqFFT.h:184
unsigned n_samples
Definition: TimeFreqFFT.h:183
unsigned average_samples
Definition: TimeFreqFFT.h:181
REAL8FrequencySeries * mean_square
Definition: TimeFreqFFT.h:185
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:879
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:570
Structure for storing REAL4 window function data, providing storage for a sequence of samples as well...
Definition: Window.h:243
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:889
Time series of REAL8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:580
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
Structure for storing REAL8 window function data, providing storage for a sequence of samples as well...
Definition: Window.h:254