LAL  7.5.0.1-b72065a
TimeFreqFFT.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Duncan Brown, Jolien Creighton, Patrick Brady, Reinhard Prix, Tania Regimbau, John Whelan
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 
21 #include <complex.h>
22 #include <math.h>
23 #include <lal/Units.h>
24 #include <lal/AVFactories.h>
25 #include <lal/TimeFreqFFT.h>
26 #include <lal/LALConstants.h>
27 #include <lal/RngMedBias.h>
28 
29 /* ---------- see TimeFreqFFT.h for doxygen documentation */
30 
31 /*
32  *
33  * XLAL REAL4 Time->Freq and Freq->Time FFT routines
34  *
35  */
36 
37 
40  const REAL4TimeSeries *time,
41  const REAL4FFTPlan *plan
42  )
43 {
44  UINT4 k;
45 
46  if ( ! freq || ! time || ! plan )
48  if ( time->deltaT <= 0.0 )
50 
51  /* perform the transform */
52  if ( XLALREAL4ForwardFFT( freq->data, time->data, plan ) == XLAL_FAILURE )
54 
55  /* adjust the units */
56  if ( ! XLALUnitMultiply( &freq->sampleUnits, &time->sampleUnits, &lalSecondUnit ) )
58 
59  /* remaining fields */
60  if ( time->f0 ) /* TODO: need to figure out what to do here */
61  XLALPrintWarning( "XLAL Warning - frequency series may have incorrect f0" );
62  freq->f0 = 0.0; /* FIXME: what if heterodyned data? */
63  freq->epoch = time->epoch;
64  freq->deltaF = 1.0 / ( time->deltaT * time->data->length );
65 
66  /* provide the correct scaling of the result */
67  for ( k = 0; k < freq->data->length; ++k )
68  freq->data->data[k] *= time->deltaT;
69 
70  return 0;
71 }
72 
73 
75  REAL4TimeSeries *time,
76  const COMPLEX8FrequencySeries *freq,
77  const REAL4FFTPlan *plan
78  )
79 {
80  UINT4 j;
81 
82  if ( ! freq || ! time || ! plan )
84  if ( freq->deltaF <= 0.0 )
86 
87  /* perform the transform */
88  if ( XLALREAL4ReverseFFT( time->data, freq->data, plan ) == XLAL_FAILURE )
90 
91  /* adjust the units */
92  if ( ! XLALUnitMultiply( &time->sampleUnits, &freq->sampleUnits, &lalHertzUnit ) )
94 
95  /* remaining fields */
96  if ( freq->f0 ) /* TODO: need to figure out what to do here */
97  XLALPrintWarning( "XLAL Warning - time series may have incorrect f0" );
98  time->f0 = 0.0; /* FIXME: what if heterodyned data? */
99  time->epoch = freq->epoch;
100  time->deltaT = 1.0 / ( freq->deltaF * time->data->length );
101 
102  /* provide the correct scaling of the result */
103  for ( j = 0; j < time->data->length; ++j )
104  time->data->data[j] *= freq->deltaF;
105 
106  return 0;
107 }
108 
109 
110 /*
111  *
112  * XLAL REAL8 Time->Freq and Freq->Time FFT routines
113  *
114  */
115 
116 
119  const REAL8TimeSeries *time,
120  const REAL8FFTPlan *plan
121  )
122 {
123  UINT4 k;
124 
125  if ( ! freq || ! time || ! plan )
127  if ( time->deltaT <= 0.0 )
129 
130  /* perform the transform */
131  if ( XLALREAL8ForwardFFT( freq->data, time->data, plan ) == XLAL_FAILURE )
133 
134  /* adjust the units */
135  if ( ! XLALUnitMultiply( &freq->sampleUnits, &time->sampleUnits, &lalSecondUnit ) )
137 
138  /* remaining fields */
139  if ( time->f0 ) /* TODO: need to figure out what to do here */
140  XLALPrintWarning( "XLAL Warning - frequency series may have incorrect f0" );
141  freq->f0 = 0.0; /* FIXME: what if heterodyned data? */
142  freq->epoch = time->epoch;
143  freq->deltaF = 1.0 / ( time->deltaT * time->data->length );
144 
145  /* provide the correct scaling of the result */
146  for ( k = 0; k < freq->data->length; ++k )
147  freq->data->data[k] *= time->deltaT;
148 
149  return 0;
150 }
151 
152 
154  REAL8TimeSeries *time,
155  const COMPLEX16FrequencySeries *freq,
156  const REAL8FFTPlan *plan
157  )
158 {
159  UINT4 j;
160 
161  if ( ! freq || ! time || ! plan )
163  if ( freq->deltaF <= 0.0 )
165 
166  /* perform the transform */
167  if ( XLALREAL8ReverseFFT( time->data, freq->data, plan ) == XLAL_FAILURE )
169 
170  /* adjust the units */
171  if ( ! XLALUnitMultiply( &time->sampleUnits, &freq->sampleUnits, &lalHertzUnit ) )
173 
174  /* remaining fields */
175  if ( freq->f0 ) /* TODO: need to figure out what to do here */
176  XLALPrintWarning( "XLAL Warning - time series may have incorrect f0" );
177  time->f0 = 0.0; /* FIXME: what if heterodyned data? */
178  time->epoch = freq->epoch;
179  time->deltaT = 1.0 / ( freq->deltaF * time->data->length );
180 
181  /* provide the correct scaling of the result */
182  for ( j = 0; j < time->data->length; ++j )
183  time->data->data[j] *= freq->deltaF;
184 
185  return 0;
186 }
187 
188 
189 /*
190  *
191  * XLAL COMPLEX8 Time->Freq and Freq->Time FFT routines
192  *
193  */
194 
195 /* We need to define the COMPLEX8FFTPlan structure so that we can check the FFT
196  * sign. The plan is not really a void*, but it is a pointer so a void* is
197  * good enough (we don't need it). */
198 struct tagCOMPLEX8FFTPlan
199 {
200  INT4 sign;
201  UINT4 size;
202  void *junk;
203 };
204 
205 
208  const COMPLEX8TimeSeries *time,
209  const COMPLEX8FFTPlan *plan
210  )
211 {
212  COMPLEX8Vector *tmp;
213  UINT4 k;
214 
215  if ( ! freq || ! time || ! plan )
217  if ( time->deltaT <= 0.0 )
219  if ( plan->sign != -1 )
221 
222  /* create temporary workspace */
223  tmp = XLALCreateCOMPLEX8Vector( time->data->length );
224  if ( ! tmp )
226 
227  /* perform transform */
228  if ( XLALCOMPLEX8VectorFFT( tmp, time->data, plan ) == XLAL_FAILURE )
229  {
230  int saveErrno = xlalErrno;
231  xlalErrno = 0;
233  xlalErrno = saveErrno;
235  }
236 
237  /* unpack the frequency series and multiply by deltaT */
238  for ( k = 0; k < time->data->length / 2; ++k )
239  freq->data->data[k] = time->deltaT * tmp->data[k+(time->data->length+1)/2];
240  for ( k = time->data->length / 2; k < time->data->length; ++k )
241  freq->data->data[k] = time->deltaT * tmp->data[k-time->data->length/2];
242 
243  /* destroy temporary workspace */
245  if ( xlalErrno )
247 
248  /* adjust the units */
249  if ( ! XLALUnitMultiply( &freq->sampleUnits, &time->sampleUnits, &lalSecondUnit ) )
251 
252  /* remaining fields */
253  freq->epoch = time->epoch;
254  freq->deltaF = 1.0 / ( time->deltaT * time->data->length );
255  freq->f0 = time->f0 - freq->deltaF * floor( time->data->length / 2 );
256 
257  return 0;
258 }
259 
260 
262  COMPLEX8TimeSeries *time,
263  const COMPLEX8FrequencySeries *freq,
264  const COMPLEX8FFTPlan *plan
265  )
266 {
267  COMPLEX8Vector *tmp;
268  UINT4 k;
269 
270  if ( ! freq || ! time || ! plan )
272  if ( freq->deltaF <= 0.0 )
274  if ( plan->sign != 1 )
276 
277  /* create temporary workspace */
278  tmp = XLALCreateCOMPLEX8Vector( freq->data->length );
279  if ( ! tmp )
281 
282  /* pack the frequency series and multiply by deltaF */
283  for ( k = 0; k < freq->data->length / 2; ++k )
284  tmp->data[k+(freq->data->length+1)/2] = freq->deltaF * freq->data->data[k];
285  for ( k = freq->data->length / 2; k < freq->data->length; ++k )
286  tmp->data[k-freq->data->length/2] = freq->deltaF * freq->data->data[k];
287 
288  /* perform transform */
289  if ( XLALCOMPLEX8VectorFFT( time->data, tmp, plan ) == XLAL_FAILURE )
290  {
291  int saveErrno = xlalErrno;
292  xlalErrno = 0;
294  xlalErrno = saveErrno;
296  }
297 
298  /* destroy temporary workspace */
300  if ( xlalErrno )
302 
303  /* adjust the units */
304  if ( ! XLALUnitMultiply( &time->sampleUnits, &freq->sampleUnits, &lalHertzUnit ) )
306 
307  /* remaining fields */
308  time->f0 = freq->f0 + freq->deltaF * floor( freq->data->length / 2 );
309  time->epoch = freq->epoch;
310  time->deltaT = 1.0 / ( freq->deltaF * freq->data->length );
311 
312  return 0;
313 }
314 
315 
316 /*
317  *
318  * XLAL COMPLEX16 Time->Freq and Freq->Time FFT routines
319  *
320  */
321 
322 /* We need to define the COMPLEX16FFTPlan structure so that we can check the FFT
323  * sign. The plan is not really a void*, but it is a pointer so a void* is
324  * good enough (we don't need it). */
325 struct tagCOMPLEX16FFTPlan
326 {
327  INT4 sign;
328  UINT4 size;
329  void *junk;
330 };
331 
332 
335  const COMPLEX16TimeSeries *time,
336  const COMPLEX16FFTPlan *plan
337  )
338 {
339  COMPLEX16Vector *tmp;
340  UINT4 k;
341 
342  if ( ! freq || ! time || ! plan )
344  if ( time->deltaT <= 0.0 )
346  if ( plan->sign != -1 )
348 
349  /* create temporary workspace */
350  tmp = XLALCreateCOMPLEX16Vector( time->data->length );
351  if ( ! tmp )
353 
354  /* perform transform */
355  if ( XLALCOMPLEX16VectorFFT( tmp, time->data, plan ) == XLAL_FAILURE )
356  {
357  int saveErrno = xlalErrno;
358  xlalErrno = 0;
360  xlalErrno = saveErrno;
362  }
363 
364  /* unpack the frequency series and multiply by deltaT */
365  for ( k = 0; k < time->data->length / 2; ++k )
366  freq->data->data[k] = time->deltaT * tmp->data[k+(time->data->length+1)/2];
367  for ( k = time->data->length / 2; k < time->data->length; ++k )
368  freq->data->data[k] = time->deltaT * tmp->data[k-time->data->length/2];
369 
370  /* destroy temporary workspace */
372  if ( xlalErrno )
374 
375  /* adjust the units */
376  if ( ! XLALUnitMultiply( &freq->sampleUnits, &time->sampleUnits, &lalSecondUnit ) )
378 
379  /* remaining fields */
380  freq->epoch = time->epoch;
381  freq->deltaF = 1.0 / ( time->deltaT * time->data->length );
382  freq->f0 = time->f0 - freq->deltaF * floor( time->data->length / 2 );
383 
384  return 0;
385 }
386 
387 
389  COMPLEX16TimeSeries *time,
390  const COMPLEX16FrequencySeries *freq,
391  const COMPLEX16FFTPlan *plan
392  )
393 {
394  COMPLEX16Vector *tmp;
395  UINT4 k;
396 
397  if ( ! freq || ! time || ! plan )
399  if ( freq->deltaF <= 0.0 )
401  if ( plan->sign != 1 )
403 
404  /* create temporary workspace */
405  tmp = XLALCreateCOMPLEX16Vector( freq->data->length );
406  if ( ! tmp )
408 
409  /* pack the frequency series and multiply by deltaF */
410  for ( k = 0; k < freq->data->length / 2; ++k )
411  tmp->data[k+(freq->data->length+1)/2] = freq->deltaF * freq->data->data[k];
412  for ( k = freq->data->length / 2; k < freq->data->length; ++k )
413  tmp->data[k-freq->data->length/2] = freq->deltaF * freq->data->data[k];
414 
415  /* perform transform */
416  if ( XLALCOMPLEX16VectorFFT( time->data, tmp, plan ) == XLAL_FAILURE )
417  {
418  int saveErrno = xlalErrno;
419  xlalErrno = 0;
421  xlalErrno = saveErrno;
423  }
424 
425  /* destroy temporary workspace */
427  if ( xlalErrno )
429 
430  /* adjust the units */
431  if ( ! XLALUnitMultiply( &time->sampleUnits, &freq->sampleUnits, &lalHertzUnit ) )
433 
434  /* remaining fields */
435  time->f0 = freq->f0 + freq->deltaF * floor( freq->data->length / 2 );
436  time->epoch = freq->epoch;
437  time->deltaT = 1.0 / ( freq->deltaF * freq->data->length );
438 
439  return 0;
440 }
int XLALPrintWarning(const char *fmt,...)
Definition: XLALError.c:79
int XLALCOMPLEX8VectorFFT(COMPLEX8Vector *_LAL_RESTRICT_ output, const COMPLEX8Vector *_LAL_RESTRICT_ input, const COMPLEX8FFTPlan *plan)
Perform a COMPLEX8Vector to COMPLEX8Vector FFT.
int XLALCOMPLEX16VectorFFT(COMPLEX16Vector *_LAL_RESTRICT_ output, const COMPLEX16Vector *_LAL_RESTRICT_ input, const COMPLEX16FFTPlan *plan)
Perform a COMPLEX16Vector to COMPLEX16Vector FFT.
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
int XLALREAL8ForwardFFT(COMPLEX16Vector *output, const REAL8Vector *input, const REAL8FFTPlan *plan)
Performs a forward FFT of REAL8 data.
Definition: CudaRealFFT.c:471
int XLALREAL8ReverseFFT(REAL8Vector *output, const COMPLEX16Vector *input, const REAL8FFTPlan *plan)
Performs a reverse FFT of REAL8 data.
Definition: CudaRealFFT.c:518
int XLALREAL4ReverseFFT(REAL4Vector *output, const COMPLEX8Vector *input, const REAL4FFTPlan *plan)
Performs a reverse FFT of REAL4 data.
Definition: CudaRealFFT.c:198
int XLALREAL4ForwardFFT(COMPLEX8Vector *output, const REAL4Vector *input, const REAL4FFTPlan *plan)
Performs a forward FFT of REAL4 data.
Definition: CudaRealFFT.c:161
int XLALCOMPLEX16FreqTimeFFT(COMPLEX16TimeSeries *time, const COMPLEX16FrequencySeries *freq, const COMPLEX16FFTPlan *plan)
Definition: TimeFreqFFT.c:388
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *time, const REAL8FFTPlan *plan)
Definition: TimeFreqFFT.c:117
int XLALCOMPLEX8FreqTimeFFT(COMPLEX8TimeSeries *time, const COMPLEX8FrequencySeries *freq, const COMPLEX8FFTPlan *plan)
Definition: TimeFreqFFT.c:261
int XLALCOMPLEX16TimeFreqFFT(COMPLEX16FrequencySeries *freq, const COMPLEX16TimeSeries *time, const COMPLEX16FFTPlan *plan)
Definition: TimeFreqFFT.c:333
int XLALREAL4FreqTimeFFT(REAL4TimeSeries *time, const COMPLEX8FrequencySeries *freq, const REAL4FFTPlan *plan)
Definition: TimeFreqFFT.c:74
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *time, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
Definition: TimeFreqFFT.c:153
int XLALCOMPLEX8TimeFreqFFT(COMPLEX8FrequencySeries *freq, const COMPLEX8TimeSeries *time, const COMPLEX8FFTPlan *plan)
Definition: TimeFreqFFT.c:206
int XLALREAL4TimeFreqFFT(COMPLEX8FrequencySeries *freq, const REAL4TimeSeries *time, const REAL4FFTPlan *plan)
Definition: TimeFreqFFT.c:38
const LALUnit lalSecondUnit
second [s]
Definition: UnitDefs.c:162
const LALUnit lalHertzUnit
Hertz [Hz].
Definition: UnitDefs.c:171
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
This function multiplies together the LALUnit structures *(input->unitOne) and *(input->unitTwo),...
Definition: UnitMultiply.c:64
COMPLEX16Vector * XLALCreateCOMPLEX16Vector(UINT4 length)
void XLALDestroyCOMPLEX16Vector(COMPLEX16Vector *vector)
COMPLEX8Vector * XLALCreateCOMPLEX8Vector(UINT4 length)
void XLALDestroyCOMPLEX8Vector(COMPLEX8Vector *vector)
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
Definition: XLALError.h:571
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:700
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
@ XLAL_FAILURE
Failure return value (not an error number)
Definition: XLALError.h:402
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:909
COMPLEX16Sequence * data
Definition: LALDatatypes.h:915
Time series of COMPLEX16 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:600
REAL8 f0
The heterodyning frequency, in Hertz (zero if not heterodyned).
Definition: LALDatatypes.h:604
COMPLEX16Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:606
LALUnit sampleUnits
The physical units of the quantity being sampled.
Definition: LALDatatypes.h:605
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:602
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:603
Vector of type COMPLEX16, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:172
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:176
COMPLEX16 * data
Pointer to the data array.
Definition: LALDatatypes.h:177
See DATATYPE-FrequencySeries types for documentation.
Definition: LALDatatypes.h:899
COMPLEX8Sequence * data
Definition: LALDatatypes.h:905
Time series of COMPLEX8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:590
LALUnit sampleUnits
The physical units of the quantity being sampled.
Definition: LALDatatypes.h:595
REAL8 f0
The heterodyning frequency, in Hertz (zero if not heterodyned).
Definition: LALDatatypes.h:594
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:593
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:592
COMPLEX8Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:596
Vector of type COMPLEX8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:163
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:167
COMPLEX8 * data
Pointer to the data array.
Definition: LALDatatypes.h:168
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:570
REAL4Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:576
LALUnit sampleUnits
The physical units of the quantity being sampled.
Definition: LALDatatypes.h:575
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:573
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:572
REAL8 f0
The heterodyning frequency, in Hertz (zero if not heterodyned).
Definition: LALDatatypes.h:574
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Time series of REAL8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:580
REAL8Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:586
LALUnit sampleUnits
The physical units of the quantity being sampled.
Definition: LALDatatypes.h:585
REAL8 f0
The heterodyning frequency, in Hertz (zero if not heterodyned).
Definition: LALDatatypes.h:584
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:583
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:582
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158
Plan to perform an FFT of COMPLEX16 data.
Definition: ComplexFFT.c:137
INT4 sign
sign in transform exponential, -1 for forward, +1 for reverse
Definition: ComplexFFT.c:138
UINT4 size
length of the complex data vector for this plan
Definition: ComplexFFT.c:139
Plan to perform an FFT of COMPLEX8 data.
Definition: ComplexFFT.c:126
UINT4 size
length of the complex data vector for this plan
Definition: ComplexFFT.c:128
INT4 sign
sign in transform exponential, -1 for forward, +1 for reverse
Definition: ComplexFFT.c:127