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
upperlimits.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2011, 2014 Evan Goetz
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 <sys/stat.h>
21#include <gsl/gsl_roots.h>
22#include "upperlimits.h"
23#include "cdfdist.h"
24#include "IHS.h"
25
26
27/**
28 * Allocate a new UpperLimitVector
29 * \param [in] length Length of the vector
30 * \return Pointer to newly allocated UpperLimitVector
31 */
33{
34
36 XLAL_CHECK_NULL( ( vector = XLALMalloc( sizeof( *vector ) ) ) != NULL, XLAL_ENOMEM );
37
38 vector->length = length;
39 if ( length == 0 ) {
40 vector->data = NULL;
41 } else {
42 XLAL_CHECK_NULL( ( vector->data = XLALMalloc( length * sizeof( *vector->data ) ) ) != NULL, XLAL_ENOMEM );
43 for ( UINT4 ii = 0; ii < length; ii++ ) {
44 resetUpperLimitStruct( &( vector->data[ii] ) );
45 }
46 }
47
48 return vector;
49
50} // createUpperLimitVector()
51
52
53/**
54 * Resize an UpperLimitVector
55 * \param [in,out] vector Pointer to UpperLimitVector to resize
56 * \param [in] length New length of the vector
57 * \return Pointer to reallocated UpperLimitVector
58 */
60{
61
62 if ( vector == NULL ) {
63 return createUpperLimitVector( length );
64 }
65 if ( length == 0 ) {
67 return NULL;
68 }
69
70 UINT4 oldlength = vector->length;
71
72 XLAL_CHECK_NULL( ( vector->data = XLALRealloc( vector->data, length * sizeof( *vector->data ) ) ) != NULL, XLAL_ENOMEM );
73 vector->length = length;
74 for ( UINT4 ii = oldlength; ii < length; ii++ ) {
75 resetUpperLimitStruct( &( vector->data[ii] ) );
76 }
77
78 return vector;
79
80} // resizeUpperLimitVector()
81
82
83/**
84 * Free an UpperLimitVector
85 * \param [in] vector Pointer to an UpperLimitVector
86 */
88{
89 if ( vector == NULL ) {
90 return;
91 }
92 if ( ( !vector->length || !vector->data ) && ( vector->length || vector->data ) ) {
94 }
95 if ( vector->data ) {
96 for ( UINT4 ii = 0; ii < vector->length; ii++ ) {
97 destroyUpperLimitStruct( &( vector->data[ii] ) );
98 }
99 XLALFree( ( UpperLimit * )vector->data );
100 }
101 vector->data = NULL;
103 return;
104} // destroyUpperLimitVector()
105
106
107/**
108 * Reset an UpperLimitStruct
109 * \param [in] ul Pointer to an UpperLimit structure
110 */
112{
113 ul->fsig = NULL;
114 ul->period = NULL;
115 ul->moddepth = NULL;
116 ul->ULval = NULL;
117 ul->effSNRval = NULL;
118} // resetUpperLimitStruct()
119
120
121/**
122 * Free an UpperLimit structure
123 * \param [in] ul Pointer to an UpperLimit structure
124 */
126{
127 if ( ul->fsig ) {
128 XLALDestroyREAL8Vector( ul->fsig );
129 }
130 if ( ul->period ) {
131 XLALDestroyREAL8Vector( ul->period );
132 }
133 if ( ul->moddepth ) {
134 XLALDestroyREAL8Vector( ul->moddepth );
135 }
136 if ( ul->ULval ) {
137 XLALDestroyREAL8Vector( ul->ULval );
138 }
139 if ( ul->effSNRval ) {
140 XLALDestroyREAL8Vector( ul->effSNRval );
141 }
142} // destroyUpperLimitStruct()
143
144
145/**
146 * Determine the 95% confidence level upper limit at a particular sky location from the loudest IHS value
147 * \param [out] ul Pointer to an UpperLimit struct
148 * \param [in] params Pointer to UserInput_t
149 * \param [in] ffdata Pointer to ffdataStruct
150 * \param [in] ihsmaxima Pointer to an ihsMaximaStruct
151 * \param [in] ihsfar Pointer to an ihsfarStruct
152 * \param [in] fbinavgs Pointer to a REAL4VectorAligned of the 2nd FFT background powers
153 * \return Status value
154 */
155INT4 skypoint95UL( UpperLimit *ul, const UserInput_t *params, const ffdataStruct *ffdata, const ihsMaximaStruct *ihsmaxima, const ihsfarStruct *ihsfar, const REAL4VectorAligned *fbinavgs )
156{
157
158 XLAL_CHECK( ul != NULL && params != NULL && ffdata != NULL && ihsmaxima != NULL && ihsfar != NULL && fbinavgs != NULL, XLAL_EINVAL );
159
160 BOOLEAN ULdetermined = 0;
161
162 INT4 minrows = ( INT4 )round( 2.0 * params->dfmin * params->Tsft ) + 1;
163
164 //Allocate vectors
165 XLAL_CHECK( ( ul->fsig = XLALCreateREAL8Vector( ( ihsmaxima->rows - minrows ) + 1 ) ) != NULL, XLAL_EFUNC );
166 XLAL_CHECK( ( ul->period = XLALCreateREAL8Vector( ( ihsmaxima->rows - minrows ) + 1 ) ) != NULL, XLAL_EFUNC );
167 XLAL_CHECK( ( ul->moddepth = XLALCreateREAL8Vector( ( ihsmaxima->rows - minrows ) + 1 ) ) != NULL, XLAL_EFUNC );
168 XLAL_CHECK( ( ul->ULval = XLALCreateREAL8Vector( ( ihsmaxima->rows - minrows ) + 1 ) ) != NULL, XLAL_EFUNC );
169 XLAL_CHECK( ( ul->effSNRval = XLALCreateREAL8Vector( ( ihsmaxima->rows - minrows ) + 1 ) ) != NULL, XLAL_EFUNC );
170
171 //Initialize solver
172 const gsl_root_fsolver_type *T = gsl_root_fsolver_brent;
173 gsl_root_fsolver *s = NULL;
174 XLAL_CHECK( ( s = gsl_root_fsolver_alloc( T ) ) != NULL, XLAL_EFUNC );
175 gsl_function F;
176 switch ( params->ULsolver ) {
177 case 1:
178 F.function = &gsl_ncx2cdf_withouttinyprob_solver; //double precision, without the extremely tiny probability part
179 break;
180 case 2:
181 F.function = &gsl_ncx2cdf_float_solver; //single precision
182 break;
183 case 3:
184 F.function = &gsl_ncx2cdf_solver; //double precision
185 break;
186 case 4:
187 F.function = &ncx2cdf_float_withouttinyprob_withmatlabchi2cdf_solver; //single precision, w/ Matlab-based chi2cdf function
188 break;
189 case 5:
190 F.function = &ncx2cdf_withouttinyprob_withmatlabchi2cdf_solver; //double precision, w/ Matlab-based chi2cdf function
191 break;
192 default:
193 F.function = &gsl_ncx2cdf_float_withouttinyprob_solver; //single precision, without the extremely tiny probability part
194 break;
195 }
196 struct ncx2cdf_solver_params pars;
197
198 //loop over modulation depths
199 for ( INT4 ii = minrows; ii <= ihsmaxima->rows; ii++ ) {
200 REAL8 loudestoutlier = 0.0, loudestoutlierminusnoise = 0.0, loudestoutliernoise = 0.0;
201 INT4 jjbinofloudestoutlier = 0, locationofloudestoutlier = -1;
202 INT4 startpositioninmaximavector = ( ii - 2 ) * ffdata->numfbins - ( ( ii - 1 ) * ( ii - 1 ) - ( ii - 1 ) ) / 2;
203 REAL8 moddepth = 0.5 * ( ii - 1.0 ) / params->Tsft; //"Signal" modulation depth
204
205 //loop over frequency bins
206 for ( INT4 jj = 0; jj < ffdata->numfbins - ( ii - 1 ); jj++ ) {
207 INT4 locationinmaximavector = startpositioninmaximavector + jj; //Current location in IHS maxima vector
208 REAL8 noise = ihsfar->expectedIHSVector->data[ihsmaxima->locations->data[locationinmaximavector] - 5]; //Expected noise
209
210 //Sum across multiple frequency bins scaling noise each time with average noise floor
211 REAL8 totalnoise = 0.0;
212 for ( INT4 kk = 0; kk < ii; kk++ ) {
213 totalnoise += fbinavgs->data[jj + kk];
214 }
215 totalnoise = noise * totalnoise;
216
217 REAL8 ihsminusnoise = ihsmaxima->maxima->data[locationinmaximavector] - totalnoise; //IHS value minus noise
218
219 REAL8 fsig = params->fmin - params->dfmax + ( 0.5 * ( ii - 1.0 ) + jj - 6.0 ) / params->Tsft; //"Signal" frequency
220
221 if ( ihsminusnoise > loudestoutlierminusnoise &&
222 ( fsig >= params->ULfmin && fsig < params->ULfmin + params->ULfspan ) &&
223 ( moddepth >= params->ULminimumDeltaf && moddepth <= params->ULmaximumDeltaf ) ) {
224 loudestoutlier = ihsmaxima->maxima->data[locationinmaximavector];
225 loudestoutliernoise = totalnoise;
226 loudestoutlierminusnoise = ihsminusnoise;
227 locationofloudestoutlier = ihsmaxima->locations->data[locationinmaximavector];
228 jjbinofloudestoutlier = jj;
229 }
230 } /* for jj < ffdata->numfbins-(ii-1) */
231
232 if ( locationofloudestoutlier != -1 ) {
233 //We do a root finding algorithm to find the delta value required so that only 5% of a non-central chi-square
234 //distribution lies below the maximum value.
235 REAL8 initialguess = ncx2inv_float( 0.95, 2.0 * loudestoutliernoise, 2.0 * loudestoutlierminusnoise );
237
238 REAL8 lo = 0.001 * initialguess, hi = 10.0 * initialguess;
239 pars.val = 2.0 * loudestoutlier;
240 pars.dof = 2.0 * loudestoutliernoise;
241 pars.ULpercent = 0.95;
242 F.params = &pars;
243 XLAL_CHECK( gsl_root_fsolver_set( s, &F, lo, hi ) == GSL_SUCCESS, XLAL_EFUNC );
244
245 INT4 status = GSL_CONTINUE;
246 INT4 max_iter = 100;
247 REAL8 root = 0.0;
248 INT4 jj = 0;
249 while ( status == GSL_CONTINUE && jj < max_iter ) {
250 jj++;
251 status = gsl_root_fsolver_iterate( s );
252 XLAL_CHECK( status == GSL_CONTINUE || status == GSL_SUCCESS, XLAL_EFUNC, "gsl_root_fsolver_iterate() failed with code %d\n", status );
253 root = gsl_root_fsolver_root( s );
254 lo = gsl_root_fsolver_x_lower( s );
255 hi = gsl_root_fsolver_x_upper( s );
256 status = gsl_root_test_interval( lo, hi, 0.0, 0.001 );
257 XLAL_CHECK( status == GSL_CONTINUE || status == GSL_SUCCESS, XLAL_EFUNC, "gsl_root_test_interval() failed with code %d\n", status );
258 } /* while status==GSL_CONTINUE and jj<max_iter */
259 XLAL_CHECK( status == GSL_SUCCESS, XLAL_EFUNC, "Root finding iteration (%d/%d) failed with code %d\n", jj, max_iter, status );
260
261 //Convert the root value to an h0 value
262 REAL8 h0 = ihs2h0( root, params );
263
264 //Store values in the upper limit struct
265 ul->fsig->data[ii - minrows] = params->fmin - params->dfmax + ( 0.5 * ( ii - 1.0 ) + jjbinofloudestoutlier - 6.0 ) / params->Tsft;
266 ul->period->data[ii - minrows] = params->Tobs / locationofloudestoutlier;
267 ul->moddepth->data[ii - minrows] = 0.5 * ( ii - 1.0 ) / params->Tsft;
268 ul->ULval->data[ii - minrows] = h0;
269 ul->effSNRval->data[ii - minrows] = unitGaussianSNR( root, pars.dof );
270 ULdetermined++;
271 } // if locationofloudestoutlier != -1
272 } // for ii=minrows --> maximum rows
273
274 //Signal an error if we didn't find something above the noise level
275 XLAL_CHECK( ULdetermined != 0, XLAL_EFUNC, "Failed to reach a louder outlier minus noise greater than 0\n" );
276
277 gsl_root_fsolver_free( s );
278
279 return XLAL_SUCCESS;
280
281}
282
283
284//The non-central chi-square CDF solver used in the GSL root finding algorithm
285//Double precision
287{
288
290 REAL8 val = ncx2cdf( params->val, params->dof, x );
292 return val - ( 1.0 - params->ULpercent );
293
294}
295
296//The non-central chi-square CDF solver used in the GSL root finding algorithm
297//Float precision (although output is in double precision for GSL)
299{
300
302 REAL4 val = ncx2cdf_float( ( REAL4 )params->val, ( REAL4 )params->dof, ( REAL4 )x );
304 return ( REAL8 )val - ( 1.0 - params->ULpercent );
305
306}
307
308//The non-central chi-square CDF solver used in the GSL root finding algorithm
309//Double precision, without the tiny probability
311{
312
316 return val - ( 1.0 - params->ULpercent );
317
318}
319
320//The non-central chi-square CDF solver used in the GSL root finding algorithm
321//Float precision (although output is in double precision for GSL), without the tiny probability
323{
324
328 return ( REAL8 )val - ( 1.0 - params->ULpercent );
329
330}
331
332//The non-central chi-square CDF solver used in the GSL root finding algorithm, using a Matlab-based chi2cdf function
333//Double precision, without the tiny probability
335{
336
340 return val - ( 1.0 - params->ULpercent );
341
342}
343
344//The non-central chi-square CDF solver used in the GSL root finding algorithm, using a Matlab-based chi2cdf function
345//Float precision (although output is in double precision for GSL), without the tiny probability
347{
348
352 return ( REAL8 )val - ( 1.0 - params->ULpercent );
353
354}
355
356
357/**
358 * Output the highest upper limit to a file unless printAllULvalues==1 in which case, all UL values are printed to a file
359 * \param [in] outputfile String of the filename
360 * \param [in] ul UpperLimit structure to print to file
361 * \param [in] printAllULvalues Option flag to print all UL values from a sky location (1) or only the largest (0)
362 * \return Status value
363 */
364INT4 outputUpperLimitToFile( const CHAR *outputfile, const UpperLimit ul, const BOOLEAN printAllULvalues )
365{
366 XLAL_CHECK( outputfile != NULL, XLAL_EINVAL );
367
368 FILE *ULFILE = NULL;
369 struct stat XLAL_INIT_DECL( buf );
370 if ( stat( outputfile, &buf ) == -1 && errno == ENOENT ) {
371 XLAL_CHECK( ( ULFILE = fopen( outputfile, "w" ) ) != NULL, XLAL_EIO, "Couldn't fopen file %s to output upper limits\n", outputfile );
372 fprintf( ULFILE, "# TwoSpect upper limits output file\n" );
373 fprintf( ULFILE, "# RA DEC Upper limit SNR_eff Freq Period Mod. depth UL normalization\n" );
374 } else {
375 XLAL_CHECK( ( ULFILE = fopen( outputfile, "a" ) ) != NULL, XLAL_EIO, "Couldn't fopen file %s to output upper limits\n", outputfile );
376 }
377
378 REAL8 highesth0 = 0.0, snr = 0.0, fsig = 0.0, period = 0.0, moddepth = 0.0;
379 for ( UINT4 ii = 0; ii < ul.moddepth->length; ii++ ) {
380 if ( printAllULvalues == 1 ) {
381 fprintf( ULFILE, "%.6f %.6f %.6g %.6f %.6f %.6f %.6f %.6g\n", ul.alpha, ul.delta, ul.ULval->data[ii], ul.effSNRval->data[ii], ul.fsig->data[ii], ul.period->data[ii], ul.moddepth->data[ii], ul.normalization );
382 } else if ( printAllULvalues == 0 && ul.ULval->data[ii] > highesth0 ) {
383 highesth0 = ul.ULval->data[ii];
384 snr = ul.effSNRval->data[ii];
385 fsig = ul.fsig->data[ii];
386 period = ul.period->data[ii];
387 moddepth = ul.moddepth->data[ii];
388 }
389 }
390 if ( printAllULvalues == 0 ) {
391 fprintf( ULFILE, "%.6f %.6f %.6g %.6f %.6f %.6f %.6f %.6g\n", ul.alpha, ul.delta, highesth0, snr, fsig, period, moddepth, ul.normalization );
392 }
393
394 fclose( ULFILE );
395
396 return XLAL_SUCCESS;
397
398}
REAL8 ihs2h0(const REAL8 ihsval, const UserInput_t *params)
Convert the IHS statistic to an estimated h0, based on injections.
Definition: IHS.c:1083
#define fprintf
REAL8 unitGaussianSNR(REAL8 value, REAL8 dof)
Definition: cdfdist.c:826
REAL4 ncx2cdf_float(REAL4 x, REAL4 dof, REAL4 delta)
Definition: cdfdist.c:429
REAL4 ncx2inv_float(REAL8 p, REAL8 dof, REAL8 delta)
Definition: cdfdist.c:764
REAL8 ncx2cdf_withouttinyprob_withmatlabchi2cdf(REAL8 x, REAL8 dof, REAL8 delta)
Definition: cdfdist.c:559
REAL4 ncx2cdf_float_withouttinyprob_withmatlabchi2cdf(REAL4 x, REAL4 dof, REAL4 delta)
Definition: cdfdist.c:593
REAL8 ncx2cdf_withouttinyprob(REAL8 x, REAL8 dof, REAL8 delta)
Definition: cdfdist.c:491
REAL8 ncx2cdf(REAL8 x, REAL8 dof, REAL8 delta)
Matlab's version of the non-central chi-squared CDF with nu degrees of freedom and non-centrality del...
Definition: cdfdist.c:370
REAL4 ncx2cdf_float_withouttinyprob(REAL4 x, REAL4 dof, REAL4 delta)
Definition: cdfdist.c:524
unsigned char BOOLEAN
double REAL8
#define XLAL_INIT_DECL(var,...)
char CHAR
uint32_t UINT4
int32_t INT4
float REAL4
void * XLALMalloc(size_t n)
void * XLALRealloc(void *p, size_t n)
void XLALFree(void *p)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define XLAL_ERROR_VOID(...)
#define xlalErrno
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_REAL8(assertion,...)
#define XLAL_CHECK_NULL(assertion,...)
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EIO
XLAL_EINVAL
T
INT4 * data
REAL4VectorAligned * maxima
INT4Vector * locations
REAL4VectorAligned * expectedIHSVector
void destroyUpperLimitStruct(UpperLimit *ul)
Free an UpperLimit structure.
Definition: upperlimits.c:125
REAL8 gsl_ncx2cdf_withouttinyprob_solver(const REAL8 x, void *p)
Definition: upperlimits.c:310
REAL8 ncx2cdf_float_withouttinyprob_withmatlabchi2cdf_solver(REAL8 x, void *p)
Definition: upperlimits.c:346
REAL8 gsl_ncx2cdf_solver(const REAL8 x, void *p)
Definition: upperlimits.c:286
void destroyUpperLimitVector(UpperLimitVector *vector)
Free an UpperLimitVector.
Definition: upperlimits.c:87
INT4 skypoint95UL(UpperLimit *ul, const UserInput_t *params, const ffdataStruct *ffdata, const ihsMaximaStruct *ihsmaxima, const ihsfarStruct *ihsfar, const REAL4VectorAligned *fbinavgs)
Determine the 95% confidence level upper limit at a particular sky location from the loudest IHS valu...
Definition: upperlimits.c:155
UpperLimitVector * resizeUpperLimitVector(UpperLimitVector *vector, const UINT4 length)
Resize an UpperLimitVector.
Definition: upperlimits.c:59
REAL8 ncx2cdf_withouttinyprob_withmatlabchi2cdf_solver(const REAL8 x, void *p)
Definition: upperlimits.c:334
UpperLimitVector * createUpperLimitVector(const UINT4 length)
Allocate a new UpperLimitVector.
Definition: upperlimits.c:32
REAL8 gsl_ncx2cdf_float_solver(const REAL8 x, void *p)
Definition: upperlimits.c:298
REAL8 gsl_ncx2cdf_float_withouttinyprob_solver(const REAL8 x, void *p)
Definition: upperlimits.c:322
void resetUpperLimitStruct(UpperLimit *ul)
Reset an UpperLimitStruct.
Definition: upperlimits.c:111
INT4 outputUpperLimitToFile(const CHAR *outputfile, const UpperLimit ul, const BOOLEAN printAllULvalues)
Output the highest upper limit to a file unless printAllULvalues==1 in which case,...
Definition: upperlimits.c:364