Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ppe_inject.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2014 Matthew Pitkin
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/* SOFTWARE INJECTION FUNCTIONS */
22/******************************************************************************/
23
24#include "config.h"
25#include "ppe_inject.h"
26
27/**
28 * \brief Inject a simulated signal into the data
29 *
30 * This function will create an simulated signal (of the required model) to inject into the data from multiple
31 * detectors. The parameters of the signal to be injected must be specified in a TEMPO-stype .par file given with the
32 * \c inject-file command line argument. The parameters do not have to be the same as those in the .par file controlling
33 * the analysis (although should ideally contain a signal within the bandwidth of the data).
34 *
35 * If a signal of a specific signal-to-noise ratio is required then the \c scale-snr command line argument can be used
36 * to give the multi-detector SNR to which the signal needs to be scaled.
37 *
38 * The injected signal can be output if \c inject-output is set. Two files will be output: one containing the signal
39 * only, and one containing the signal plus noise. These will both be in the format of a standard data input file. The
40 * files will have names given by the \c inject-output value, with a prefix of the detector name, and a suffix of of \c
41 * _signal_only, respectively.
42 *
43 * \param runState [in] the program information structure
44 *
45 * \sa calculate_time_domain_snr
46 */
48{
49 LALInferenceIFOData *data = runState->data;
50 LALInferenceIFOModel *ifo_model = runState->threads[0].model->ifo;
51
52 CHAR *injectfile = NULL, *snrfile = NULL;
53 ProcessParamsTable *ppt;
54 ProcessParamsTable *commandLine = runState->commandLine;
55
56 PulsarParameters *injpars = XLALCalloc( sizeof( *injpars ), 1 );
57
58 FILE *fpsnr = NULL; /* output file for SNRs */
59 INT4 ndats = 0;
60
61 REAL8Vector *freqFactors = NULL;
62 REAL8 snrmulti = 0.;
63 REAL8 snrscale = 0;
64
65 ppt = LALInferenceGetProcParamVal( commandLine, "--outfile" );
66 if ( !ppt ) {
67 XLAL_ERROR_VOID( XLAL_EINVAL, "Error... no output file specified!" );
68 }
69
70 snrfile = XLALStringDuplicate( ppt->value );
71 /* strip the file extension */
72 CHAR *dotloc = strrchr( snrfile, '.' );
73 CHAR *slashloc = strrchr( snrfile, '/' );
74 if ( dotloc != NULL ) {
75 if ( slashloc != NULL ) { /* check dot is after any filename seperator */
76 if ( slashloc < dotloc ) {
77 *dotloc = '\0';
78 }
79 } else {
80 *dotloc = '\0';
81 }
82 }
83 snrfile = XLALStringAppend( snrfile, "_SNR" );
84
85 if ( ( fpsnr = fopen( snrfile, "w" ) ) == NULL ) {
86 XLAL_ERROR_VOID( XLAL_EIO, "Error... cannot open output SNR file!" );
87 }
88 XLALFree( snrfile );
89
90 ppt = LALInferenceGetProcParamVal( commandLine, "--inject-file" );
91 if ( ppt ) {
92 injectfile = XLALStringDuplicate( ppt->value );
93
94 /* check that the file exists */
95 if ( fopen( injectfile, "r" ) == NULL ) {
96 XLAL_ERROR_VOID( XLAL_EINVAL, "Error... Injection specified, but the injection parameter file %s is wrong.", injectfile );
97 }
98
99 /* read in injection parameter file */
100 injpars = XLALReadTEMPOParFile( injectfile );
101 XLALFree( injectfile );
102
103 /* check RA and DEC are set (if only RAJ and DECJ are given in the par file) */
104 if ( !PulsarCheckParam( injpars, "RA" ) ) {
105 if ( PulsarCheckParam( injpars, "RAJ" ) ) {
106 REAL8 ra = PulsarGetREAL8Param( injpars, "RAJ" );
107 PulsarAddParam( injpars, "RA", &ra, PULSARTYPE_REAL8_t );
108 } else {
109 XLAL_ERROR_VOID( XLAL_EINVAL, "No source right ascension specified!" );
110 }
111 }
112 if ( !PulsarCheckParam( injpars, "DEC" ) ) {
113 if ( PulsarCheckParam( injpars, "DECJ" ) ) {
114 REAL8 dec = PulsarGetREAL8Param( injpars, "DECJ" );
115 PulsarAddParam( injpars, "DEC", &dec, PULSARTYPE_REAL8_t );
116 } else {
117 XLAL_ERROR_VOID( XLAL_EINVAL, "No source declination specified!" );
118 }
119 }
120
121 /* check if Q22, DIST and F0 are set, but not H0 */
122 if ( !PulsarCheckParam( injpars, "H0" ) && PulsarCheckParam( injpars, "Q22" ) && PulsarCheckParam( injpars, "DIST" ) && PulsarCheckParam( injpars, "F" ) ) {
123 REAL8 f0val = PulsarGetREAL8VectorParamIndividual( injpars, "F0" );
124 REAL8 distval = PulsarGetREAL8Param( injpars, "DIST" );
125 REAL8 q22val = PulsarGetREAL8Param( injpars, "Q22" );
126 REAL8 h0val = q22val * sqrt( 8.*LAL_PI / 15. ) * 16.*LAL_PI * LAL_PI * LAL_G_SI * f0val * f0val / ( LAL_C_SI * LAL_C_SI * LAL_C_SI * LAL_C_SI * distval );
127 PulsarAddParam( injpars, "H0", &h0val, PULSARTYPE_REAL8_t );
128 }
129
130 /* make sure that we have parameters in terms of amplitude and phase parameters */
131 invert_source_params( injpars );
132 } else {
133 PulsarFreeParams( injpars );
134 fclose( fpsnr );
135 return;
136 }
137
138 /* check the number of frequency and frequency derivative parameters (add DELTAF parameter) */
139 if ( LALInferenceCheckVariable( runState->threads[0].currentParams, "FREQNUM" ) ) {
140 UINT4 freqnum = LALInferenceGetUINT4Variable( runState->threads[0].currentParams, "FREQNUM" );
141 REAL8Vector *deltafreqs = XLALCreateREAL8Vector( freqnum );
142 const REAL8Vector *freqs = NULL;
143 REAL8Vector *freqsnew = NULL;
144
145 if ( PulsarCheckParam( injpars, "F" ) ) {
146 freqs = PulsarGetREAL8VectorParam( injpars, "F" );
147
148 if ( freqs->length > freqnum ) {
149 freqnum = freqs->length;
150 } else if ( freqs->length < freqnum ) { /* add on additional freqs */
151 freqsnew = XLALCreateREAL8Vector( freqnum );
152 for ( UINT4 i = 0; i < freqs->length; i++ ) {
153 freqsnew->data[i] = freqs->data[i];
154 }
155 for ( UINT4 i = freqs->length; i < freqnum; i++ ) {
156 freqsnew->data[i] = 0.;
157 }
158 PulsarRemoveParam( injpars, "F" );
159 PulsarAddREAL8VectorParam( injpars, "F", ( const REAL8Vector * )freqsnew );
160 XLALDestroyREAL8Vector( freqsnew );
161 }
162 } else {
163 freqsnew = XLALCreateREAL8Vector( freqnum );
164 for ( UINT4 i = 0; i < freqnum; i++ ) {
165 freqsnew->data[i] = 0.;
166 }
167 PulsarAddREAL8VectorParam( injpars, "F", ( const REAL8Vector * )freqsnew );
168 XLALDestroyREAL8Vector( freqsnew );
169 freqs = PulsarGetREAL8VectorParam( injpars, "F" );
170 }
171
172 for ( UINT4 i = 0; i < freqnum; i++ ) {
173 CHAR varname[256];
174 snprintf( varname, sizeof( varname ), "F%u_FIXED", i );
175 REAL8 f0fixed = LALInferenceGetREAL8Variable( runState->threads[0].currentParams, varname );
176 deltafreqs->data[i] = freqs->data[i] - f0fixed; /* frequency (derivative) difference */
177 }
178 PulsarAddREAL8VectorParam( injpars, "DELTAF", ( const REAL8Vector * )deltafreqs );
179 XLALDestroyREAL8Vector( deltafreqs );
180 }
181
182 freqFactors = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "freqfactors" );
183
184 /* get the SNR scale factor if required */
185 ppt = LALInferenceGetProcParamVal( commandLine, "--scale-snr" );
186 if ( ppt ) {
187 snrscale = atof( ppt->value );
188 }
189
190 /* create signal to inject */
191 /* for injection always attempt to include the signal phase model even if the search is not going to be over phase */
192 INT4 varyphase = 1, varyskypos = 1, varybinary = 1;
193 while ( ifo_model ) {
194 if ( !LALInferenceCheckVariable( ifo_model->params, "varyphase" ) ) {
195 LALInferenceAddVariable( ifo_model->params, "varyphase", &varyphase, LALINFERENCE_INT4_t, LALINFERENCE_PARAM_FIXED );
196 varyphase = 0; /* set to zero so varyphase is removed after the model is created */
197
198 if ( !LALInferenceCheckVariable( ifo_model->params, "varyskypos" ) ) {
199 LALInferenceAddVariable( ifo_model->params, "varyskypos", &varyskypos, LALINFERENCE_INT4_t, LALINFERENCE_PARAM_FIXED );
200 varyskypos = 0;
201 }
202
203 if ( PulsarCheckParam( injpars, "BINARY" ) ) {
204 if ( !LALInferenceCheckVariable( ifo_model->params, "varybinary" ) ) {
205 LALInferenceAddVariable( ifo_model->params, "varybinary", &varybinary, LALINFERENCE_INT4_t, LALINFERENCE_PARAM_FIXED );
206 varybinary = 0;
207 }
208 }
209 }
210 ifo_model = ifo_model->next;
211 }
212 ifo_model = runState->threads[0].model->ifo;
213
214 /* check whether to inject a non-GR signal (the default will ALWAYS be GR) */
215 UINT4 nonGR_search = LALInferenceCheckVariable( ifo_model->params, "nonGR" );
216
217 char *injection_model = NULL;
218 ProcessParamsTable *nonGR_injection;
219 nonGR_injection = LALInferenceGetProcParamVal( commandLine, "--inject-nonGR" );
220
221 if ( nonGR_injection ) {
222 /* set injection model */
223 injection_model = XLALStringDuplicate( nonGR_injection->value );
224 if ( !nonGR_search ) {
225 /* add "nonGR" flag so that pulsar_model() runs in nonGR mode */
226 UINT4 nonGRval = 1;
227 while ( ifo_model ) {
229 ifo_model = ifo_model->next;
230 }
231 ifo_model = runState->threads[0].model->ifo;
232 /* setup nonGR lookup tables */
233 LALSource psr;
237 setup_lookup_tables( runState, &psr );
238 }
239 if ( *injection_model != '\0' ) {
240 /* set parameters corresponding to specific model */
241 set_nonGR_model_parameters( injpars, injection_model );
242 }
243 } else {
244 /* remove "nonGR" flag so that pulsar_model() runs in GR mode */
245 while ( ifo_model ) {
246 LALInferenceRemoveVariable( ifo_model->params, "nonGR" );
247 ifo_model = ifo_model->next;
248 }
249 ifo_model = runState->threads[0].model->ifo;
250 }
251
252 pulsar_model( injpars, ifo_model );
253
254 /* get summed data for use in SNR calculation */
255 sum_data( runState );
256
257 fprintf( fpsnr, "# Injected SNR\n" );
258
259 /* reset model to head */
260 ifo_model = runState->threads[0].model->ifo;
261
262 /* calculate SNRs */
263 while ( data ) {
264 REAL8 snrval = 0.;
265
266 snrval = calculate_time_domain_snr( data, ifo_model );
267 snrmulti += SQUARE( snrval );
268
269 /* if not scaling print out individual detector/datastream SNRs */
270 if ( snrscale == 0. ) {
271 fprintf( fpsnr, "%s\t%.3lf\t%le\n", data->name, freqFactors->data[ndats % ( INT4 )freqFactors->length], snrval );
272 }
273
274 data = data->next;
275 ifo_model = ifo_model->next;
276
277 ndats++;
278 }
279
280 /* get overall multi-detector SNR */
281 snrmulti = sqrt( snrmulti );
282
283 /* only need to print out multi-detector snr if the were multiple detectors or data streams */
284 if ( snrscale == 0. ) {
285 if ( ndats > 1 ) {
286 fprintf( fpsnr, "Coherent\t%le\n", snrmulti );
287 }
288 } else {
289 /* rescale the signal and calculate the SNRs */
290 snrscale /= snrmulti;
291
292 REAL8 C22 = PulsarGetREAL8ParamOrZero( injpars, "C22" ) * snrscale;
293 REAL8 C21 = PulsarGetREAL8ParamOrZero( injpars, "C21" ) * snrscale;
294 PulsarAddParam( injpars, "C22", &C22, PULSARTYPE_REAL8_t );
295 PulsarAddParam( injpars, "C21", &C21, PULSARTYPE_REAL8_t );
296
297 /* reset to head */
298 ifo_model = runState->threads[0].model->ifo;
299 data = runState->data;
300
301 pulsar_model( injpars, ifo_model );
302
303 /* get new summed data for use in SNR calculation */
304 sum_data( runState );
305
306 /* get new snrs */
307 snrmulti = 0;
308 ndats = 0;
309
310 ifo_model = runState->threads[0].model->ifo;
311
312 while ( data ) {
313 REAL8 snrval = 0.;
314
315 /* recalculate the SNR */
316 snrval = calculate_time_domain_snr( data, ifo_model );
317 snrmulti += SQUARE( snrval );
318
319 fprintf( fpsnr, "%s\t%.3lf\t%le\t%le\n", data->name, freqFactors->data[ndats % ( INT4 )freqFactors->length], snrscale, snrval );
320
321 data = data->next;
322 ifo_model = ifo_model->next;
323
324 ndats++;
325 }
326
327 snrmulti = sqrt( snrmulti );
328 //fprintf(stderr, "scaled multi data snr: %le\n", snrmulti);
329
330 if ( ndats > 1 ) {
331 fprintf( fpsnr, "Coherent\t%le\n", snrmulti );
332 }
333 }
334
335 fclose( fpsnr );
336
337 data = runState->data;
338 ifo_model = runState->threads[0].model->ifo;
339 ndats = 0;
340
341 /* add signal to data */
342 while ( data ) {
343 FILE *fp = NULL, *fpso = NULL;
344 ProcessParamsTable *ppt2 = LALInferenceGetProcParamVal( commandLine, "--inject-output" );
345 INT4 i = 0, length = IFO_XTRA_DATA( ifo_model )->times->length;
346
347 /* check whether to output the data */
348 if ( ppt2 ) {
349 /* add the site prefix to the start of the output name */
350 CHAR *outfile = NULL;
351 CHAR *signalonly = NULL; /* file containing only signal and no noise */
352 CHAR suffix[5];
353 INT4 sf;
354
355 outfile = XLALStringDuplicate( ppt2->value );
356
357 /* append detector name to file */
359 outfile = XLALStringAppend( outfile, data->detector->frDetector.prefix );
360
361 /* append the harmonic frequency of the signal in the file */
362 sf = sprintf( suffix, "_%.1lf", freqFactors->data[ndats % ( INT4 )freqFactors->length] );
363 outfile = XLALStringAppend( outfile, suffix );
364
365 if ( ( fp = fopen( outfile, "w" ) ) == NULL || !sf ) {
366 fprintf( stderr, "Non-fatal error... unable to open file %s to output injection\n", outfile );
367 }
368
369 signalonly = XLALStringDuplicate( outfile );
370 signalonly = XLALStringAppend( signalonly, "_signal_only" );
371
372 if ( ( fpso = fopen( signalonly, "w" ) ) == NULL ) {
373 fprintf( stderr, "Non-fatal error... unable to open file %s to output injection\n", signalonly );
374 }
375 XLALFree( outfile );
376 }
377
378 /* add the signal to the data */
379 for ( i = 0; i < length; i++ ) {
380 data->compTimeData->data->data[i] += ifo_model->compTimeSignal->data->data[i];
381
382 /* write out injection to file */
383 if ( fp != NULL && fpso != NULL ) {
384 /* print out data - time stamp, real and imaginary parts of data (injected signal + noise) */
385 fprintf( fp, "%.5lf\t%.12le\t%.12le\n", XLALGPSGetREAL8( &IFO_XTRA_DATA( ifo_model )->times->data[i] ),
386 creal( data->compTimeData->data->data[i] ), cimag( data->compTimeData->data->data[i] ) );
387
388 /* print signal only data - time stamp, real and imaginary parts of signal */
389 fprintf( fpso, "%.5lf\t%.12le\t%.12le\n", XLALGPSGetREAL8( &IFO_XTRA_DATA( ifo_model )->times->data[i] ),
390 creal( ifo_model->compTimeSignal->data->data[i] ), cimag( ifo_model->compTimeSignal->data->data[i] ) );
391 }
392 }
393
394 if ( fp != NULL ) {
395 fclose( fp );
396 }
397 if ( fpso != NULL ) {
398 fclose( fpso );
399 }
400
401 /* recalculate the data noise variance with the signal added (this mimics the variance that
402 * would be calculated for a real signal.
403 */
404 compute_variance( data, ifo_model );
405
406 data = data->next;
407 ifo_model = ifo_model->next;
408 ndats++;
409 }
410
411 /* reset nonGR status */
412 ifo_model = runState->threads[0].model->ifo;
413 if ( nonGR_search ) {
414 if ( !nonGR_injection ) {
415 UINT4 nonGRval = 1;
416 while ( ifo_model ) {
418 ifo_model = ifo_model->next;
419 }
420 ifo_model = runState->threads[0].model->ifo;
421 }
422 } else {
423 while ( ifo_model ) {
424 LALInferenceRemoveVariable( ifo_model->params, "nonGR" );
425 ifo_model = ifo_model->next;
426 }
427 ifo_model = runState->threads[0].model->ifo;
428 }
429
430 UINT4 outputchunks = 0, chunkMin = 0, chunkMax = 0;
431 INT4 inputsigma = 0;
432 if ( LALInferenceGetProcParamVal( commandLine, "--output-chunks" ) ) {
433 outputchunks = 1;
434 }
435
436 ifo_model = runState->threads[0].model->ifo;
437 data = runState->data;
438 while ( ifo_model ) {
439 UINT4Vector *chunkLength = NULL;
440
441 if ( !varyphase ) {
442 LALInferenceRemoveVariable( ifo_model->params, "varyphase" );
443 }
444 if ( !varyskypos ) {
445 LALInferenceRemoveVariable( ifo_model->params, "varyskypos" );
446 }
447 if ( !varybinary ) {
448 LALInferenceRemoveVariable( ifo_model->params, "varybinary" );
449 }
450
451 /* re-do segmentation of the data including the signal */
452 inputsigma = LALInferenceGetINT4Variable( ifo_model->params, "inputSigma" );
453 if ( !inputsigma && ! LALInferenceGetProcParamVal( commandLine, "--oldChunks" ) ) {
454 chunkMin = LALInferenceGetUINT4Variable( ifo_model->params, "chunkMin" );
455 chunkMax = LALInferenceGetUINT4Variable( ifo_model->params, "chunkMax" );
456
457 chunkLength = chop_n_merge( data, chunkMin, chunkMax, outputchunks );
458 LALInferenceRemoveVariable( ifo_model->params, "chunkLength" );
459 LALInferenceAddVariable( ifo_model->params, "chunkLength", &chunkLength, LALINFERENCE_UINT4Vector_t, LALINFERENCE_PARAM_FIXED );
460 }
461
462 /* recompute variances */
463 if ( !inputsigma ) {
464 compute_variance( data, ifo_model );
465 }
466
467 ifo_model = ifo_model->next;
468 data = data->next;
469 }
470
471 PulsarFreeParams( injpars ); /* free memory */
472
473 /* check if we only want to create and output an injection file and not analyse it yet */
474 if ( LALInferenceGetProcParamVal( commandLine, "--inject-file" ) && LALInferenceGetProcParamVal( commandLine, "--inject-only" ) ) {
475 exit( 0 ); /* exit the code */
476 }
477}
478
479/*-------------------- END OF SOFTWARE INJECTION FUNCTIONS -------------------*/
480
481
482
483/**
484 * \brief Calculates the optimal matched filter signal-to-noise ratio for a given signal
485 *
486 * This function calculates the optimal matched filter signal-to-noise ratio (SNR) of a given signal model for a set of
487 * detector data via:
488 * \f[
489 * \rho = \sqrt{\sum_{i=1}^N \frac{d_i^2}{\sigma^2}},
490 * \f]
491 * where \f$ \{d\} \f$ is a time series of data, and \f$ \sigma^2 \f$ is its variance. As the data and model used here are
492 * complex the real and imaginary SNRs are added in quadrature to give the total SNR.
493 *
494 * The data variance \f$ \sigma^2 \f$ is calculated on data that has had the running median subtracted in order to remove
495 * any underlying trends (e.g. caused by a string signal). The variance is assumed constant over segments given in the
496 * \c chunkLength vector and the SNR from each segment is added in quadrature.
497 *
498 * \param data [in] A data pointer containing detector data and the signal model
499 * \param ifo_model [in] A model structure containing detector parameters and buffers
500 *
501 * \return The optimal matched filter signal-to-noise ratio
502 */
504{
505 REAL8 snrval = 0., chunkLength = 0;
506
507 INT4 i = 0, j = 0, length = 0, cl = 0;
508
509 INT4 chunkMin = 0, count = 0, varyphase = 0, nonGR = 0, roq = 0;
510
511 UINT4Vector *chunkLengths = NULL;
512 chunkLengths = *( UINT4Vector ** )LALInferenceGetVariable( ifo_model->params, "chunkLength" );
513 chunkMin = *( INT4 * )LALInferenceGetVariable( ifo_model->params, "chunkMin" );
514
515 REAL8Vector *sumP = NULL, *sumC = NULL, *sumX = NULL, *sumY = NULL, *sumB = NULL, *sumL = NULL;
516 REAL8Vector *sumPC = NULL, *sumPX = NULL, *sumPY = NULL, *sumPB = NULL, *sumPL = NULL;
517 REAL8Vector *sumCX = NULL, *sumCY = NULL, *sumCB = NULL, *sumCL = NULL;
518 REAL8Vector *sumXY = NULL, *sumXB = NULL, *sumXL = NULL;
519 REAL8Vector *sumYB = NULL, *sumYL = NULL;
520 REAL8Vector *sumBL = NULL;
521
522 if ( LALInferenceCheckVariable( ifo_model->params, "varyphase" ) ) {
523 varyphase = 1;
524 }
525 if ( LALInferenceCheckVariable( ifo_model->params, "nonGR" ) ) {
526 nonGR = 1;
527 }
528 if ( LALInferenceCheckVariable( ifo_model->params, "roq" ) ) {
529 roq = 1;
530 }
531
532 if ( !varyphase && !roq ) {
533 /* get explicitly whitened versions of these sums */
534 sumP = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumPWhite" );
535 sumC = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumCWhite" );
536 sumPC = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumPCWhite" );
537
538 if ( nonGR ) {
539 sumX = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumXWhite" );
540 sumY = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumYWhite" );
541 sumB = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumBWhite" );
542 sumL = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumLWhite" );
543
544 sumPX = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumPXWhite" );
545 sumPY = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumPYWhite" );
546 sumPB = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumPBWhite" );
547 sumPL = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumPLWhite" );
548 sumCX = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumCXWhite" );
549 sumCY = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumCYWhite" );
550 sumCB = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumCBWhite" );
551 sumCL = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumCLWhite" );
552 sumXY = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumXYWhite" );
553 sumXB = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumXBWhite" );
554 sumXL = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumXLWhite" );
555 sumYB = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumYBWhite" );
556 sumYL = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumYLWhite" );
557 sumBL = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "sumBLWhite" );
558 }
559 }
560
561 length = data->compTimeData->data->length;
562
563 for ( i = 0; i < length; i += ( INT4 )chunkLength ) {
564 REAL8 snrcRe = 0., snrcIm = 0.;
565
566 chunkLength = ( REAL8 )chunkLengths->data[count];
567
568 /* skip section of data if its length is less than the minimum allowed chunk length */
569 if ( chunkLength < chunkMin ) {
570 count++;
571 continue;
572 }
573
574 cl = i + ( INT4 )chunkLength;
575
576 /* check whether the full time domain model exists, or the pre-summed model */
577 if ( varyphase || roq ) {
578 for ( j = i ; j < cl ; j++ ) {
579 /* calculate optimal signal power */
580 snrcRe += SQUARE( creal( ifo_model->compTimeSignal->data->data[j] ) ) / data->varTimeData->data->data[j];
581 snrcIm += SQUARE( cimag( ifo_model->compTimeSignal->data->data[j] ) ) / data->varTimeData->data->data[j];
582 }
583 } else {
584 COMPLEX16 Mp, Mc;
585 Mp = ifo_model->compTimeSignal->data->data[0];
586 Mc = ifo_model->compTimeSignal->data->data[1];
587
588 snrcRe += sumP->data[count] * ( creal( Mp ) * creal( Mp ) + cimag( Mp ) * cimag( Mp ) ) +
589 sumC->data[count] * ( creal( Mc ) * creal( Mc ) + cimag( Mc ) * cimag( Mc ) ) +
590 2.*sumPC->data[count] * ( creal( Mp ) * creal( Mc ) + cimag( Mp ) * cimag( Mc ) );
591 snrcIm = 0.;
592
593 if ( nonGR ) {
594 COMPLEX16 Mx, My, Mb, Ml;
595
596 Mx = ifo_model->compTimeSignal->data->data[2];
597 My = ifo_model->compTimeSignal->data->data[3];
598 Mb = ifo_model->compTimeSignal->data->data[4];
599 Ml = ifo_model->compTimeSignal->data->data[5];
600
601 snrcRe += sumX->data[count] * ( creal( Mx ) * creal( Mx ) + cimag( Mx ) * cimag( Mx ) ) +
602 sumY->data[count] * ( creal( My ) * creal( My ) + cimag( My ) * cimag( My ) ) +
603 sumB->data[count] * ( creal( Mb ) * creal( Mb ) + cimag( Mb ) * cimag( Mb ) ) +
604 sumL->data[count] * ( creal( Ml ) * creal( Ml ) + cimag( Ml ) * cimag( Ml ) ) +
605 2.*( sumPX->data[count] * ( creal( Mp ) * creal( Mx ) + cimag( Mp ) * cimag( Mx ) ) +
606 sumPY->data[count] * ( creal( Mp ) * creal( My ) + cimag( Mp ) * cimag( My ) ) +
607 sumPB->data[count] * ( creal( Mp ) * creal( Mb ) + cimag( Mp ) * cimag( Mb ) ) +
608 sumPL->data[count] * ( creal( Mp ) * creal( Ml ) + cimag( Mp ) * cimag( Ml ) ) +
609 sumCX->data[count] * ( creal( Mc ) * creal( Mx ) + cimag( Mc ) * cimag( Mx ) ) +
610 sumCY->data[count] * ( creal( Mc ) * creal( My ) + cimag( Mc ) * cimag( My ) ) +
611 sumCB->data[count] * ( creal( Mc ) * creal( Mb ) + cimag( Mc ) * cimag( Mb ) ) +
612 sumCL->data[count] * ( creal( Mc ) * creal( Ml ) + cimag( Mc ) * cimag( Ml ) ) +
613 sumXY->data[count] * ( creal( Mx ) * creal( My ) + cimag( Mx ) * cimag( My ) ) +
614 sumXB->data[count] * ( creal( Mx ) * creal( Mb ) + cimag( Mx ) * cimag( Mb ) ) +
615 sumXL->data[count] * ( creal( Mx ) * creal( Ml ) + cimag( Mx ) * cimag( Ml ) ) +
616 sumYB->data[count] * ( creal( My ) * creal( Mb ) + cimag( My ) * cimag( Mb ) ) +
617 sumYL->data[count] * ( creal( My ) * creal( Ml ) + cimag( My ) * cimag( Ml ) ) +
618 sumBL->data[count] * ( creal( Mb ) * creal( Ml ) + cimag( Mb ) * cimag( Ml ) ) );
619 }
620 }
621
622 /* add SNRs for each chunk in quadrature */
623 snrval += ( snrcRe + snrcIm );
624
625 count++;
626 }
627
628 snrval = sqrt( snrval );
629
630 return snrval;
631}
632
633
634/**
635 * \brief Get the signal-to-noise ratio of the maximum likelihood signal
636 *
637 * The function uses the signal with the highest likelihood (which will be the final point in the live points array) and
638 * calculates the optimal signal-to-noise ratio (SNR) for it. This is output to a file based on the \c outfile value,
639 * but with \c _SNR appended to it. For multiple detector, and/or models with multiple data sets, the individual
640 * detector/data set SNR values will be output, with the final value being the multi-detector SNR. If a fake signal has
641 * been injected into the data this file will already contain the optimal SNR of the true signal.
642 *
643 * \param runState [in] The analysis information structure
644 *
645 * \sa calculate_time_domain_snr
646 */
648{
649 INT4 ndats = 0;
650 UINT4 roq = 0; // i = 0;
651 INT4 Nlive = *( INT4 * )LALInferenceGetVariable( runState->algorithmParams, "Nlive" );
652 REAL8 snrmulti = 0.;
653 REAL8Vector *freqFactors = NULL;
654
655 CHAR *snrfile = NULL;
656 FILE *fpsnr = NULL;
657
658 ProcessParamsTable *ppt;
659 ProcessParamsTable *commandLine = runState->commandLine;
660
661 LALInferenceVariables *loudestParams = NULL;
662 LALInferenceIFOData *data = runState->data;
663 LALInferenceIFOModel *ifo_model = runState->threads[0].model->ifo;
664
665 loudestParams = XLALCalloc( 1, sizeof( LALInferenceVariables ) );
666
667 /* max likelihood point should have been sorted to be the final value */
668 LALInferenceCopyVariables( runState->livePoints[Nlive - 1], loudestParams );
669
670 /* if using ROQ we need to reinstate the full time stamp vector to compute the model for the SNR calculation */
671 if ( LALInferenceGetProcParamVal( runState->commandLine, "--roq" ) ) {
672 roq = 1;
673
674 while ( ifo_model ) {
675 REAL8Vector *sidtime = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "siderealDayFull" );
676 LALInferenceRemoveVariable( ifo_model->params, "siderealDay" );
678
679 LIGOTimeGPSVector *timestamps = *( LIGOTimeGPSVector ** )LALInferenceGetVariable( ifo_model->params, "timeStampVectorFull" );
680 XLALDestroyTimestampVector( IFO_XTRA_DATA( ifo_model )->times );
681 IFO_XTRA_DATA( ifo_model )->times = timestamps;
682 //fprintf(stderr, "timestamps->length = %d, IFO_XTRA_DATA( ifo_model )->times->data[0] = %d, IFO_XTRA_DATA( ifo_model )->times->data[-1] = %d\n", timestamps->length, IFO_XTRA_DATA( ifo_model )->times->data[0].gpsSeconds, IFO_XTRA_DATA( ifo_model )->times->data[timestamps->length-1].gpsSeconds);
683
684 ifo_model->compTimeSignal = XLALResizeCOMPLEX16TimeSeries( ifo_model->compTimeSignal, 0, IFO_XTRA_DATA( ifo_model )->times->length );
685
686 /* remove the ROQ variable for calculating the likelihood */
687 LALInferenceRemoveVariable( ifo_model->params, "roq" );
688
689 if ( LALInferenceCheckVariable( ifo_model->params, "ssb_delays" ) ) {
690 REAL8Vector *ssbdelays = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "ssb_delays_full" );
691 LALInferenceRemoveVariable( ifo_model->params, "ssb_delays" );
693 }
694
695 if ( LALInferenceCheckVariable( ifo_model->params, "bsb_delays" ) ) {
696 REAL8Vector *bsbdelays = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "bsb_delays_full" );
697 LALInferenceRemoveVariable( ifo_model->params, "bsb_delays" );
699 }
700
701 if ( LALInferenceCheckVariable( ifo_model->params, "glitch_phase" ) ) {
702 REAL8Vector *glitchphase = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "glitch_phase_full" );
703 LALInferenceRemoveVariable( ifo_model->params, "glitch_phase" );
704 LALInferenceAddVariable( ifo_model->params, "glitch_phase", &glitchphase, LALINFERENCE_REAL8Vector_t, LALINFERENCE_PARAM_FIXED );
705 }
706
707 /* make sure varyphase is set (this is required if having used ROQ for a non-varyphase model) */
708 if ( !LALInferenceCheckVariable( ifo_model->params, "varyphase" ) ) {
709 UINT4 varyphasetmp = 1;
710 LALInferenceAddVariable( ifo_model->params, "varyphase", &varyphasetmp, LALINFERENCE_UINT4_t, LALINFERENCE_PARAM_FIXED );
711 }
712
713 ifo_model = ifo_model->next;
714 }
715 }
716
717 /* make sure that the signal model in runState->data is that of the loudest signal */
718 REAL8 logLnew = runState->likelihood( loudestParams, runState->data, runState->threads[0].model );
719
720 if ( !roq ) {
721 /* we don't expect exactly identical likelihoods if using ROQ */
722 if ( logLnew != *( REAL8 * )LALInferenceGetVariable(
723 runState->livePoints[Nlive - 1], "logL" ) ) {
724 fprintf( stderr, "Error... maximum log likelihood problem!\n" );
725 exit( 0 );
726 }
727 } else {
728 /* check likelihoods agree to within 0.1% */
729 fprintf( stderr, "Max. ROQ likeihood = %.12le, Max. full likelihood = %.12le\n", *( REAL8 * )LALInferenceGetVariable( runState->livePoints[Nlive - 1], "logL" ), logLnew );
730 if ( 100.*( 1. - fabs( *( REAL8 * )LALInferenceGetVariable( runState->livePoints[Nlive - 1], "logL" ) / logLnew ) ) > 0.1 ) {
731 fprintf( stderr, "WARNING... maximum likelihood using ROQ is greater than 0.1%% different that the full likelihood calculation.\n" );
732 }
733 }
734
735 LALInferenceClearVariables( loudestParams );
736
737 /* setup output file */
738 ppt = LALInferenceGetProcParamVal( commandLine, "--outfile" );
739 if ( !ppt ) {
740 XLAL_ERROR_VOID( XLAL_EIO, "Error... no output file specified!\n" );
741 }
742
743 snrfile = XLALStringDuplicate( ppt->value );
744 /* strip the file extension */
745 CHAR *dotloc = strrchr( snrfile, '.' );
746 CHAR *slashloc = strrchr( snrfile, '/' );
747 if ( dotloc != NULL ) {
748 if ( slashloc != NULL ) { /* check dot is after any filename seperator */
749 if ( slashloc < dotloc ) {
750 *dotloc = '\0';
751 }
752 } else {
753 *dotloc = '\0';
754 }
755 }
756 snrfile = XLALStringAppend( snrfile, "_SNR" );
757
758 /* append to previous injection SNR file if it exists */
759 if ( ( fpsnr = fopen( snrfile, "a" ) ) == NULL ) {
760 fprintf( stderr, "Error... cannot open output SNR file!\n" );
761 exit( 0 );
762 }
763 XLALFree( snrfile );
764
765 /* get SNR of loudest point and print out to file */
766 data = runState->data;
767 ifo_model = runState->threads[0].model->ifo;
768
769 //FILE *fp = NULL;
770 //fp = fopen("max_like_signal.txt", "w");
771
772 fprintf( fpsnr, "# Recovered SNR\n" );
773
774 freqFactors = *( REAL8Vector ** )LALInferenceGetVariable( ifo_model->params, "freqfactors" );
775
776 while ( data ) {
777 if ( roq ) {
779 }
780
781 REAL8 snrval = calculate_time_domain_snr( data, ifo_model );
782
783 //UINT4 length = ifo_model->compTimeSignal->data->length;
784
785 /* print out maxlikelihood template */
786 //for ( UINT4 j=0; j < length; j++ ){
787 // fprintf(fp, "%lf\t%le\t%le\n",
788 // XLALGPSGetREAL8( &IFO_XTRA_DATA( ifo_model )->times->data[j] ),
789 // creal(ifo_model->compTimeSignal->data->data[j]),
790 // cimag(ifo_model->compTimeSignal->data->data[j]));
791 //}
792
793 snrmulti += SQUARE( snrval );
794
795 /* print out SNR value */
796 fprintf( fpsnr, "%s\t%.3lf\t%le\n", data->name, freqFactors->data[ndats % ( INT4 )freqFactors->length], snrval );
797
798 ndats++;
799
800 data = data->next;
801 ifo_model = ifo_model->next;
802 }
803
804 //fclose(fp);
805
806 /* print out multi-detector/multi-datastream SNR value */
807 if ( ndats > 1 ) {
808 fprintf( fpsnr, "Coherent\t%le\n", sqrt( snrmulti ) );
809 }
810
811 fclose( fpsnr );
812}
ProcessParamsTable * ppt
int j
const REAL8Vector * PulsarGetREAL8VectorParam(const PulsarParameters *pars, const CHAR *name)
Return a REAL8Vector parameter.
REAL8 PulsarGetREAL8ParamOrZero(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter if it exists, otherwise return zero.
int PulsarCheckParam(const PulsarParameters *pars, const CHAR *name)
Check for the existence of the parameter name in the PulsarParameters structure.
PulsarParameters * XLALReadTEMPOParFile(const CHAR *pulsarAndPath)
Read in the parameters from a TEMPO(2) parameter file into a PulsarParameters structure.
void PulsarAddParam(PulsarParameters *pars, const CHAR *name, void *value, PulsarParamType type)
Add a parameter and value to the PulsarParameters structure.
REAL8 PulsarGetREAL8Param(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter.
void PulsarRemoveParam(PulsarParameters *pars, const CHAR *name)
Remove a given parameter from a PulsarParameters structure.
void PulsarFreeParams(PulsarParameters *pars)
Function to free memory from pulsar parameters.
void PulsarAddREAL8VectorParam(PulsarParameters *pars, const CHAR *name, const REAL8Vector *value)
Add a REAL8Vector parameter to the PulsarParameters structure.
REAL8 PulsarGetREAL8VectorParamIndividual(const PulsarParameters *pars, const CHAR *name)
Return an individual REAL8 value from a REAL8Vector parameter.
@ PULSARTYPE_REAL8_t
LIGOTimeGPSVector * timestamps
#define fprintf
#define LAL_PI
#define LAL_G_SI
double complex COMPLEX16
double REAL8
char CHAR
uint32_t UINT4
int32_t INT4
UINT4 LALInferenceGetUINT4Variable(LALInferenceVariables *vars, const char *name)
void LALInferenceAddVariable(LALInferenceVariables *vars, const char *name, const void *value, LALInferenceVariableType type, LALInferenceParamVaryType vary)
REAL8 LALInferenceGetREAL8Variable(LALInferenceVariables *vars, const char *name)
void LALInferenceRemoveVariable(LALInferenceVariables *vars, const char *name)
void LALInferenceCopyVariables(LALInferenceVariables *origin, LALInferenceVariables *target)
void * LALInferenceGetVariable(const LALInferenceVariables *vars, const char *name)
INT4 LALInferenceGetINT4Variable(LALInferenceVariables *vars, const char *name)
ProcessParamsTable * LALInferenceGetProcParamVal(ProcessParamsTable *procparams, const char *name)
void LALInferenceClearVariables(LALInferenceVariables *vars)
int LALInferenceCheckVariable(LALInferenceVariables *vars, const char *name)
LALINFERENCE_PARAM_FIXED
LALINFERENCE_INT4_t
LALINFERENCE_REAL8Vector_t
LALINFERENCE_UINT4_t
LALINFERENCE_UINT4Vector_t
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
char char * XLALStringDuplicate(const char *s)
int char * XLALStringAppend(char *s, const char *append)
void XLALDestroyTimestampVector(LIGOTimeGPSVector *vect)
De-allocate a LIGOTimeGPSVector.
Definition: SFTtimestamps.c:69
COORDINATESYSTEM_EQUATORIAL
COMPLEX16TimeSeries * XLALResizeCOMPLEX16TimeSeries(COMPLEX16TimeSeries *series, int first, size_t length)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define XLAL_ERROR_VOID(...)
XLAL_EIO
XLAL_EINVAL
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
long long count
Definition: hwinject.c:371
float data[BLOCKSIZE]
Definition: hwinject.c:360
void sum_data(LALInferenceRunState *runState)
Calculates the sum of the square of the data and model terms.
Definition: ppe_init.c:1110
void setup_lookup_tables(LALInferenceRunState *runState, LALSource *source)
Sets the time angle antenna response lookup table.
Definition: ppe_init.c:296
REAL8 calculate_time_domain_snr(LALInferenceIFOData *data, LALInferenceIFOModel *ifo_model)
Calculates the optimal matched filter signal-to-noise ratio for a given signal.
Definition: ppe_inject.c:503
void inject_signal(LALInferenceRunState *runState)
Inject a simulated signal into the data.
Definition: ppe_inject.c:47
void get_loudest_snr(LALInferenceRunState *runState)
Get the signal-to-noise ratio of the maximum likelihood signal.
Definition: ppe_inject.c:647
Header file for the signal injection functions for the parameter estimation code for known pulsar sea...
void pulsar_model(PulsarParameters *params, LALInferenceIFOModel *ifo)
Generate the model of the neutron star signal.
Definition: ppe_models.c:408
void invert_source_params(PulsarParameters *params)
Convert sources parameters into amplitude and phase notation parameters.
Definition: ppe_models.c:1367
void set_nonGR_model_parameters(PulsarParameters *pars, char *nonGRmodel)
Set amplitude parameters for specific non-GR models.
Definition: ppe_models.c:301
#define IFO_XTRA_DATA(ifo)
Definition: ppe_models.h:35
void compute_variance(LALInferenceIFOData *data, LALInferenceIFOModel *model)
Compute the noise variance for each data segment.
Definition: ppe_utils.c:38
UINT4Vector * chop_n_merge(LALInferenceIFOData *data, UINT4 chunkMin, UINT4 chunkMax, UINT4 outputchunks)
Chops and remerges data into stationary segments.
Definition: ppe_utils.c:177
#define SQUARE(x)
COMPLEX16Sequence * data
COMPLEX16 * data
struct tagLALInferenceIFOModel * next
LALInferenceVariables * params
COMPLEX16TimeSeries * compTimeSignal
LALInferenceIFOModel * ifo
ProcessParamsTable * commandLine
LALInferenceVariables * algorithmParams
struct tagLALInferenceIFOData * data
LALInferenceThreadState * threads
LALInferenceVariables ** livePoints
LALInferenceLikelihoodFunction likelihood
LALInferenceVariables * currentParams
LALInferenceModel * model
SkyPosition equatorialCoords
A vector of 'timestamps' of type LIGOTimeGPS.
Definition: SFTfileIO.h:188
The PulsarParameters structure to contain a set of pulsar parameters.
REAL8 * data
REAL8 longitude
REAL8 latitude
CoordinateSystem system
UINT4 * data