LALApps 10.1.0.1-eeff03c
spectrm.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton, Lisa M. Goggin
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#include "config.h"
21#include <LALAppsVCSInfo.h>
22
23#include <math.h>
24
25#include <lal/LALStdlib.h>
26#include <lal/LALStdio.h>
27#include <lal/Units.h>
28#include <lal/AVFactories.h>
29#include <lal/TimeFreqFFT.h>
30#include <lal/RealFFT.h>
31#include <lal/Window.h>
32#include <lal/LIGOMetadataRingdownUtils.h>
33
34#include "spectrm.h"
35#include "errutil.h"
36
37#ifdef __GNUC__
38#define UNUSED __attribute__ ((unused))
39#else
40#define UNUSED
41#endif
42
43/* routine to compute an average spectrum from time series data */
46 int spectrumAlgthm,
47 REAL8 segmentDuration,
48 REAL8 strideDuration,
49 REAL4FFTPlan *fwdPlan,
50 int whiteSpectrum
51 )
52{
53 /*LALStatus XLAL_INIT_DECL(status);*/
54 REAL4Window *window = NULL;
55 REAL4FrequencySeries *spectrum;
56 UINT4 segmentLength;
57 UINT4 segmentStride;
58
59 segmentLength = floor( segmentDuration/series->deltaT + 0.5 );
60 segmentStride = floor( strideDuration/series->deltaT + 0.5 );
61
62 spectrum = LALCalloc( 1, sizeof( *spectrum ) );
63 spectrum->data = XLALCreateREAL4Vector( segmentLength/2 + 1 );
64
65 window = XLALCreateWelchREAL4Window( segmentLength );
66
67 if ( whiteSpectrum ) /* just return a constant spectrum */
68 {
69 UINT4 k;
70 REAL4 spec;
71 spec = 2.0 * series->deltaT;
72 verbose( "creating white spectrum with constant value %g\n", spec );
73 for ( k = 1; k < spectrum->data->length - 1; ++k )
74 spectrum->data->data[k] = spec;
75 /* DC and Nyquist */
76 spectrum->data->data[0] = 2.0 * spec;
77 spectrum->data->data[spectrum->data->length - 1] = 2.0 * spec;
78 spectrum->epoch = series->epoch;
79 spectrum->deltaF = 1.0/segmentDuration;
80 }
81 else /* compute average spectrum using either the median or the median-mean method */
82 {
83 switch ( spectrumAlgthm )
84 {
86 verbose( "estimating average spectrum using median method\n" );
87 XLALREAL4AverageSpectrumMedian(spectrum, series, segmentLength,
88 segmentStride, window, fwdPlan );
89 break;
91 verbose( "estimating average spectrum using median-mean method\n" );
92 XLALREAL4AverageSpectrumMedianMean( spectrum, series, segmentLength,
93 segmentStride, window, fwdPlan );
94 break;
95 default:
96 error( "unrecognized injection signal type\n" );
97 }
98 }
99
100 XLALDestroyREAL4Window( window );
101
102 return spectrum;
103}
104
106 REAL4FrequencySeries *origspectrum,
108 REAL8 segmentDuration
109 )
110{
111 REAL4FrequencySeries *rsmplspectrum;
112 UINT4 segmentLength;
113 REAL8 origDeltaF,rsmplDeltaF;
114 REAL8 currF,belowF,aboveF,belowWeight,aboveWeight,currPower;
115 UINT4 k;
116 INT4 belowK,aboveK;
117
118 segmentLength = floor( segmentDuration*sampleRate + 0.5 );
119 rsmplspectrum = LALCalloc( 1, sizeof( *rsmplspectrum ) );
120 rsmplspectrum->data = XLALCreateREAL4Vector( segmentLength/2 + 1 );
121
122 origDeltaF = origspectrum->deltaF;
123 rsmplDeltaF = 1.0/segmentDuration;
124 rsmplspectrum->epoch = origspectrum->epoch;
125 rsmplspectrum->f0 = origspectrum->f0;
126 rsmplspectrum->deltaF = rsmplDeltaF;
127 rsmplspectrum->sampleUnits = origspectrum->sampleUnits;
128 if((int)sizeof(rsmplspectrum->name) <= snprintf( rsmplspectrum->name, sizeof( rsmplspectrum->name ),
129 "%s_RSMPL", origspectrum->name))
130 XLAL_ERROR_NULL(XLAL_FAILURE,"String truncated");
131
132 for (k=0; k < segmentLength/2 + 1; k++)
133 {
134 currF = k * rsmplDeltaF;
135 belowK = floor( currF / origDeltaF);
136 aboveK = ceil( currF / origDeltaF);
137 belowF = belowK * origDeltaF;
138 aboveF = aboveK * origDeltaF;
139 if (belowK < 0)
140 belowK = 0;
141 if (aboveK < 0)
142 {
143 // Shouldn't this fail?
144 aboveK = 0;
145 }
146 if (belowK > (INT4)origspectrum->data->length)
147 belowK = origspectrum->data->length;
148 if (aboveK > (INT4)origspectrum->data->length)
149 aboveK = origspectrum->data->length;
150 sanity_check( aboveK >= belowK );
151 if (aboveK - belowK == 0)
152 {
153 belowWeight = 1;
154 aboveWeight = 0;
155 }
156 else
157 {
158 belowWeight = (currF - belowF) / (aboveF - belowF);
159 aboveWeight = (aboveF - currF) / (aboveF - belowF);
160 sanity_check( aboveWeight >= 0);
161 sanity_check( belowWeight >= 0);
162 }
163 currPower = origspectrum->data->data[belowK] * belowWeight;
164 currPower += origspectrum->data->data[aboveK] * aboveWeight;
165 rsmplspectrum->data->data[k] = currPower;
166 }
167
168 XLALDestroyREAL4Vector( origspectrum->data );
169 LALFree( origspectrum );
170
171 return rsmplspectrum;
172}
173
175 REAL4 deltaT,
176 REAL8 segmentDuration,
177 UINT4 spectrumNumber,
178 REAL8 simScale
179)
180{
181 REAL8FrequencySeries *spectrum;
182 UINT4 segmentLength;
183
184 segmentLength = floor( segmentDuration/deltaT + 0.5 );
185
186 spectrum = LALCalloc( 1, sizeof( *spectrum ) );
187 spectrum->data = XLALCreateREAL8Vector( segmentLength/2 + 1 );
188
189 spectrum->deltaF = 1.0/segmentDuration;
190
191 if (spectrumNumber == WHITE_PSD) /* just return a constant spectrum */
192 {
193 UINT4 k;
194 REAL4 spec;
195 spec = 2.0 * deltaT;
196 verbose( "creating white PSD with constant value %g\n", spec * simScale * simScale );
197 for ( k = 1; k < spectrum->data->length - 1; ++k )
198 spectrum->data->data[k] = spec * simScale * simScale;
199 /* DC and Nyquist are set to 0*/
200 spectrum->data->data[0] = 0.0;
201 spectrum->data->data[spectrum->data->length - 1] = 0.0;
202 snprintf( spectrum->name, sizeof( spectrum->name ),
203 "WHITE_NOISE_PSD" );
204 }
205 else if ( spectrumNumber == ILIGO_PSD )
206 {
207 verbose( "Creating initial LIGO PSD. PSD only generated from 30Hz \n" );
208 /* FIXME */
209 REAL4 flow = 30;
211 snprintf( spectrum->name, sizeof( spectrum->name ),
212 "iLIGO_PSD" );
213 }
214 else if ( spectrumNumber == ALIGO_PSD )
215 {
216 verbose( "Creating advanced LIGO high-power broad-band signal recycling "
217 "PSD. PSD only generated from 10Hz \n ");
218 REAL4 flow = 10;
220 snprintf( spectrum->name, sizeof( spectrum->name ),
221 "aLIGO_PSD" );
222 }
223 else
224 {
225 fprintf(stderr,"Spectrum number not valid. This message should not be seen."
226 " Have you broken the code?? \n");
227 }
228
229 return spectrum;
230}
231
232
233
234
235
236/* routine to invert and truncate (to have compact time support) a spectrum */
238 REAL4FrequencySeries *spectrum,
239 REAL8 dataSampleRate,
240 REAL8 UNUSED strideDuration,
241 REAL8 truncateDuration,
242 REAL8 lowCutoffFrequency,
243 REAL4FFTPlan *fwdPlan,
244 REAL4FFTPlan *revPlan
245 )
246{
247 REAL8 segmentDuration;
248 UINT4 segmentLength;
249 UINT4 UNUSED segmentStride;
250 UINT4 truncateLength;
251
252 segmentDuration = 1.0/spectrum->deltaF;
253 segmentLength = floor( segmentDuration * dataSampleRate + 0.5 );
254 segmentStride = floor( strideDuration * dataSampleRate + 0.5 );
255 if ( truncateDuration > 0.0 )
256 truncateLength = floor( truncateDuration * dataSampleRate + 0.5 );
257 else
258 truncateLength = 0;
259
260 verbose( "computing inverse spectrum with truncation length %d\n",
261 truncateLength );
262
263 XLALREAL4SpectrumInvertTruncate( spectrum, lowCutoffFrequency,
264 segmentLength, truncateLength, fwdPlan, revPlan );
265
266 return 0;
267}
268
269
270/* routine to scale a spectrum by the magnitude of the response function */
272 REAL4FrequencySeries *spectrum,
273 COMPLEX8FrequencySeries *response,
274 REAL8 lowCutoffFrequency,
275 int inverse
276 )
277{
278 UINT4 cut;
279 UINT4 k;
280 char name[LALNameLength];
281
282 if ( response )
283 {
284 /* compute low frequency cutoff */
285 if ( lowCutoffFrequency > 0.0 )
286 cut = lowCutoffFrequency / spectrum->deltaF;
287 else
288 cut = 0;
289
290 /* apply the response function */
291 if ( inverse ) /* divide by response */
292 {
293 for ( k = cut; k < spectrum->data->length; ++k )
294 {
295 REAL4 re = crealf(response->data->data[k]);
296 REAL4 im = cimagf(response->data->data[k]);
297 spectrum->data->data[k] /= (re*re + im*im );
298 }
299 XLALUnitMultiply( &spectrum->sampleUnits, &spectrum->sampleUnits,
300 &response->sampleUnits );
301 }
302 else /* multiply by response */
303 {
304 for ( k = cut; k < spectrum->data->length; ++k )
305 {
306 REAL4 re = crealf(response->data->data[k]);
307 REAL4 im = cimagf(response->data->data[k]);
308 spectrum->data->data[k] *= (re*re + im*im );
309 }
310 XLALUnitDivide( &spectrum->sampleUnits, &spectrum->sampleUnits,
311 &response->sampleUnits );
312 }
313 strncpy( name, spectrum->name, LALNameLength * sizeof(char) );
314 XLALStringPrint( spectrum->name, sizeof( spectrum->name ),
315 "%s_CAL", name );
316 }
317
318 return 0;
319}
int k
#define LALCalloc(m, n)
#define LALFree(p)
LALRINGDOWN_SPECTRUM_MEDIAN
LALRINGDOWN_SPECTRUM_MEDIAN_MEAN
#define fprintf
INT4 sampleRate
Definition: blindinj.c:124
int verbose
Definition: chirplen.c:77
#define sanity_check(condition)
Definition: coh_PTF.h:85
double flow
int error(const char *fmt,...)
Definition: errutil.c:37
double REAL8
uint32_t UINT4
int32_t INT4
float REAL4
LALNameLength
double XLALSimNoisePSDaLIGOZeroDetHighPower(double f)
int XLALSimNoisePSD(REAL8FrequencySeries *psd, double flow, double(*psdfunc)(double))
double XLALSimNoisePSDiLIGOSRD(double f)
int XLALStringPrint(char *s, size_t n, const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(3
int XLALREAL4AverageSpectrumMedian(REAL4FrequencySeries *spectrum, const REAL4TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL4Window *window, const REAL4FFTPlan *plan)
int XLALREAL4AverageSpectrumMedianMean(REAL4FrequencySeries *spectrum, const REAL4TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL4Window *window, const REAL4FFTPlan *plan)
int XLALREAL4SpectrumInvertTruncate(REAL4FrequencySeries *spectrum, REAL4 lowfreq, UINT4 seglen, UINT4 trunclen, REAL4FFTPlan *fwdplan, REAL4FFTPlan *revplan)
LALUnit * XLALUnitDivide(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL4Window(REAL4Window *window)
REAL4Window * XLALCreateWelchREAL4Window(UINT4 length)
#define XLAL_ERROR_NULL(...)
XLAL_FAILURE
char name[LIGOMETA_SOURCE_MAX]
Definition: inspinj.c:561
int calibrate_spectrum(REAL4FrequencySeries *spectrum, COMPLEX8FrequencySeries *response, REAL8 lowCutoffFrequency, int inverse)
Definition: spectrm.c:271
REAL4FrequencySeries * resample_psd(REAL4FrequencySeries *origspectrum, REAL8 sampleRate, REAL8 segmentDuration)
Definition: spectrm.c:105
REAL8FrequencySeries * generate_theoretical_psd(REAL4 deltaT, REAL8 segmentDuration, UINT4 spectrumNumber, REAL8 simScale)
Definition: spectrm.c:174
int invert_spectrum(REAL4FrequencySeries *spectrum, REAL8 dataSampleRate, REAL8 UNUSED strideDuration, REAL8 truncateDuration, REAL8 lowCutoffFrequency, REAL4FFTPlan *fwdPlan, REAL4FFTPlan *revPlan)
Definition: spectrm.c:237
REAL4FrequencySeries * compute_average_spectrum(REAL4TimeSeries *series, int spectrumAlgthm, REAL8 segmentDuration, REAL8 strideDuration, REAL4FFTPlan *fwdPlan, int whiteSpectrum)
Definition: spectrm.c:44
@ ALIGO_PSD
Definition: spectrm.h:94
@ ILIGO_PSD
Definition: spectrm.h:93
@ WHITE_PSD
Definition: spectrm.h:92
COMPLEX8Sequence * data
COMPLEX8 * data
REAL4Sequence * data
CHAR name[LALNameLength]
REAL4 * data
REAL8Sequence * data
CHAR name[LALNameLength]
REAL8 * data
Definition: series.h:36
double deltaT