Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LineRobustStats.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2011-2014 David Keitel
3 * Copyright (C) 2014 Reinhard Prix
4 * Copyright (C) 2017 Reinhard Prix
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with with program; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
21
22//---------- INCLUDES ----------
23#include <lal/UserInputParse.h>
24
25#include <lal/LineRobustStats.h>
26
27
28//---------- local DEFINES ----------
29
30//----- Macros -----
31
32// ---------- internal types ----------
33// ----- module-internal global variables ----------
34
35// opaque internal setup structure for XLALComputeBSGL()
38 REAL4 Fstar0sc; // semi-coherent Fstar0sc = Nseg * Fstar0coh
40 REAL4 C; // constant term C = Fstar0sc + ln(1-pL)
41 REAL4 ln_pLtL_X[PULSAR_MAX_DETECTORS]; // per-detector term ln(pX) = ln(oLGX) - ln(1+oLG)
42 REAL4 perSegTerm; // extra term for per-segment transient contributions, (Nseg - 1)*Fstar0sc/Nseg - ln(Nseg)
44};
45
46// ---------- module-internal prototypes ----------
47int
49 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS],
50 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS],
51 const UINT4 len,
52 const BSGLSetup *setup
53 );
54
55/*==================== FUNCTION DEFINITIONS ====================*/
56
57/// \addtogroup LineRobustStats_h
58/// @{
59
60/**
61 * \f[
62 * \newcommand{\coh}[1]{\widetilde{#1}}
63 * \newcommand{\Ndet}{N_{\mathrm{det}}}
64 * \newcommand{\F}{\mathcal{F}}
65 * \newcommand{\scF}{\hat{\F}}
66 * \newcommand{\cohFtho}{\coh{\F}_*^{(0)}}
67 * \newcommand{\scFtho}{\scF_*^{(0)}}
68 * \newcommand{\oLGX}{o_{\mathrm{LG}}^X}
69 * \newcommand{\Nseg}{N_{\mathrm{seg}}}
70 * \f]
71 * Pre-compute the 'setup' for XLALComputeBSGL() for given prior parameters \f$ \scFtho \f$ and \f$ \{\oLGX\} \f$ .
72 */
73BSGLSetup *
74XLALCreateBSGLSetup( const UINT4 numDetectors, //!< [in] number of detectors \f$ \Ndet \f$
75 const REAL4 Fstar0sc, //!< [in] (semi-coherent) prior transition-scale parameter \f$ \scFtho=\Nseg\cohFtho \f$
76 const REAL4 oLGX[PULSAR_MAX_DETECTORS], //!< [in] prior per-detector line odds \f$ \{\oLGX\} \f$ , if NULL: interpreted as \f$ \oLGX=\frac{1}{\Ndet} \forall X \f$
77 const BOOLEAN useLogCorrection, //!< [in] include log-term correction [slower] or not [faster, less accurate]
78 const UINT4 numSegments //!< [in] number of segments \f$ \Nseg \f$ in a semi-coherent search (=1 for coherent search)
79 )
80{
81 // check input
82 XLAL_CHECK_NULL( ( numDetectors >= 2 ) && ( numDetectors <= PULSAR_MAX_DETECTORS ), XLAL_EDOM, "numDetectors = %d not within [2,%d]\n", numDetectors, PULSAR_MAX_DETECTORS );
83 for ( UINT4 X = 0; X < numDetectors; X ++ ) {
84 XLAL_CHECK_NULL( ( oLGX == NULL ) || ( oLGX[X] >= 0 ), XLAL_EDOM );
85 }
86
87 // create setup struct
88 BSGLSetup *setup;
89 XLAL_CHECK_NULL( ( setup = XLALCalloc( 1, sizeof( *setup ) ) ) != NULL, XLAL_ENOMEM );
90 setup->numDetectors = numDetectors;
91 setup->Fstar0sc = Fstar0sc;
92
93 // Compute oLG from Eq.(22)
94 REAL4 oLG = 0.0;
95 REAL4 oLGX_default = 1.0 / numDetectors; // 'even odds': use oLGX=1/numDetectors for all X ==> oLG=1, pL=0.5
96 for ( UINT4 X = 0; X < numDetectors; X ++ ) {
97 setup->oLGX[X] = ( oLGX != NULL ) ? oLGX[X] : oLGX_default;
98 oLG += setup->oLGX[X];
99 }
100
101 // constant transition scale term
102 REAL4 ln_1_plus_oLG = logf( 1.0 + oLG ); // ln(1+oLG)
103 setup->C = Fstar0sc - ln_1_plus_oLG; // Fstar0sc + ln(1-pL) = Fstar0sc - ln(1+oLG)
104
105 for ( UINT4 X = 0; X < numDetectors; X++ ) {
106 setup->ln_pLtL_X[X] = -LAL_REAL4_MAX; // fallback if oLGX==0 to avoid raising underflow
107 if ( setup->oLGX[X] > 0 ) {
108 setup->ln_pLtL_X[X] = logf( setup->oLGX[X] ) - ln_1_plus_oLG; // ln(oLGX) - ln(1+oLG)
109 }
110 }
111
112 setup->perSegTerm = Fstar0sc * ( numSegments - 1 ) / numSegments - logf( numSegments );
113
114 setup->useLogCorrection = useLogCorrection;
115
116 return setup;
117
118} // XLALCreateBSGLSetup()
119
120void
121XLALDestroyBSGLSetup( BSGLSetup *setup )
122{
123 XLALFree( setup );
124 return;
125} // XLALDestroyBSGLSetup()
126
127/**
128 * \f[
129 * \newcommand{\F}{\mathcal{F}}
130 * \newcommand{\FpMax}{\F^{\#}_{\mathrm{max}}}
131 * \newcommand{\Ndet}{N_{\mathrm{det}}}
132 * \newcommand{\Signal}{\mathrm{S}}
133 * \newcommand{\Gauss}{\mathrm{G}}
134 * \newcommand{\Line}{\mathrm{L}}
135 * \newcommand{\SGL}{{\Signal/\Gauss\Line}}
136 * \newcommand{\oLG}{o_{\Line/\Gauss}}
137 * \newcommand{\oLGX}{\oLG^X}
138 * \newcommand{\OSGL}{O_\SGL}
139 * \newcommand{\oSGL}{o_\SGL}
140 * \newcommand{\data}{\mathrm{data}}
141 * \newcommand{\pL}{p_\Line}
142 * \newcommand{\logten}{\log_{10}}
143 * \newcommand{\BSGL}{B_{\SGL}}
144 * \f]
145 * Compute the 'line-robust statistic' \f$ \logten \BSGL \f$ from multi-detector \f$ 2\F \f$ and single-detector \f$ \{2\F^X\} \f$ 'F-stat values'
146 * (coherent or semi-coherent sum) and a pre-computed 'setup' from XLALCreateBSGLSetup().
147 *
148 * \f$ \BSGL \f$ is the BayesFactor[Signal-vs-Gauss_OR_Line], i.e.
149 * \f$ \BSGL \equiv \frac{P(\data | \text{Signal})}{P(\data | \text{Gauss or Line})} \f$ , which is related to the odds ratio
150 * via \f$ \OSGL = \oSGL\,\BSGL \f$ in terms of the prior odds \f$ \oSGL \f$ .
151 *
152 * Here we use the odds ratio derived in Eq.(36) (and Eq.(55)) of \cite KPPLS2014 , from which we can obtain
153 * \f{equation}{
154 * \ln \BSGL = \F - \FpMax - \ln\left( e^{C - \FpMax} + \sum_X \pL^X \, e^{\F^X - \FpMax} \right) \,,
155 * \f}
156 * where \c setup->useLogCorrection controls whether or not to include the (usually small) log-correction of the last term,
157 * and we defined
158 * \f{equation}{ \FpMax \equiv \max\left[ C, \{ \F^X + \ln\pL^X \} \right] \f}
159 * and \f$ C,\{\ln\pL^X\} \f$ are the prior quantities pre-computed in XLALCreateBSGLSetup(), namely
160 * \f{align}{
161 * C &\equiv \scFtho + \ln(1-\pL) = \scFtho - \ln(1+\oLG)\,,\\
162 * \ln\pL^X &\equiv \ln \oLGX - \ln(1+\oLG)\,,
163 * \f}
164 * and we used the following relations from \cite KPPLS2014 :
165 * \f$ \oLG = \sum_X \oLGX \; \f$ [Eq.(22)],
166 * and \f$ \pL = \frac{\oLG}{1 + \oLG} \; \f$ [Eq.(37)].
167 *
168 * Here, \f$ \FpMax \f$ differs from \f$ \F''_{\mathrm{max}} \f$ from [Eq.(41)] by \f$ \ln\Ndet \f$ , due to summation instead of an average over detectors.
169 *
170 * \return NOTE: return is \f$ \logten B_\SGL = \ln B_\SGL \, \logten e \f$
171 *
172 */
173int
174XLALVectorComputeBSGL( REAL4 *outBSGL, //!< [out] pre-allocated output vector for returning BSGL
175 const REAL4 *twoF, //!< [in] input vector of multi-IFO 2F values
176 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], //!< [in] input vector of per-IFO 2F[X] values
177 const UINT4 len, //!< [in] length of input/output vectors
178 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
179 )
180{
181 XLAL_CHECK( ( outBSGL != NULL ) && ( twoF != NULL ) && ( twoFPerDet != NULL ) && ( setup != NULL ) && ( len >= 1 ), XLAL_EINVAL );
182
183 for ( UINT4 i = 0; i < len; i ++ ) {
184 // --------------------------------------------------
185 REAL4 FpMax = setup->C; // used to keep track of log of maximal denominator sum-term
186
187 // per-detector contributions, including line weights
189 for ( UINT4 X = 0; X < setup->numDetectors; X ++ ) {
190 Xterm[X] = 0.5f * twoFPerDet[X][i] + setup->ln_pLtL_X[X]; // FX + ln(pLtL_X) = FX + ln(pL_X) as ptL=0
191 FpMax = fmaxf( FpMax, Xterm[X] );
192 }
193
194 outBSGL[i] = 0.5f * twoF[i] - FpMax; // approximate result without log-correction term
195
196 if ( setup->useLogCorrection ) { // FIXME: indicate to gcc that this is the unlikely branch
197 // if useLogCorrection: extraSum = e^(Fstar0sc +ln(1-pL) - FpMax) + sum_X e^( Xterm[X] - FpMax )
198 REAL4 extraSum = expf( setup->C - FpMax );
199
200 // ... and add all FX-contributions
201 for ( UINT4 X = 0; X < setup->numDetectors; X++ ) {
202 extraSum += expf( Xterm[X] - FpMax );
203 }
204 outBSGL[i] -= logf( extraSum ); // F - FpMax - ln( ... )
205 } // if useLogCorrection
206
207 outBSGL[i] *= LAL_LOG10E; // return log10(B_SGL)
208
209 } // for i < len
210
211 return XLAL_SUCCESS;
212
213} // XLALVectorComputeBSGL()
214
215
216/// Single-bin wrapper of XLALVectorComputeBSGL(), provided for backwards compatibility.
217REAL4
218XLALComputeBSGL( const REAL4 twoF, //!< [in] multi-detector F-stat \f$ 2\F \f$ (coherent or semi-coherent sum(!))
219 const REAL4 twoFX[PULSAR_MAX_DETECTORS], //!< [in] per-detector F-stats \f$ \{2\F^X\} \f$ (coherent or semi-coherent sum(!))
220 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
221 )
222{
223 REAL4 outBSGL;
224 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS];
225 for ( UINT4 X = 0; X < setup->numDetectors; X ++ ) {
226 twoFPerDet[X] = &( twoFX[X] );
227 }
228 XLAL_CHECK_REAL4( XLALVectorComputeBSGL( &outBSGL, &twoF, twoFPerDet, 1, setup ) == XLAL_SUCCESS, XLAL_EFUNC );
229
230 return outBSGL;
231
232} // XLALComputeBSGL()
233
234/**
235 * \f[
236 * \newcommand{\cohF}{\coh{\F}}
237 * \f]
238 * Helper function to compute the denominator for XLALVectorComputeBSGLtL() and XLALVectorComputeBtSGLtL() - see their documentation for details.
239 */
240int
241XLALVectorComputeGLtLDenominator( REAL4 *outDenom, //!< [out] pre-allocated output array of denominator values
242 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], //!< [in] input vector of semi-coherent sums \f$ \{2\scF^X\} \f$ of per-detector F-stats
243 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS],//!< [in] input vector of maxima over segments of \f$ \{\max\limits_{\ell}2\{\cohF^{X\ell}\}\} \f$ of per-detector F-stats
244 const UINT4 len, //!< [in] length of input/output vectors
245 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
246 )
247{
248 XLAL_CHECK( ( outDenom != NULL ) && ( twoFPerDet != NULL ) && ( maxTwoFSegPerDet != NULL ) && ( setup != NULL ), XLAL_EINVAL );
249 XLAL_CHECK_REAL4( !setup->useLogCorrection, XLAL_EDOM, "log correction not implemented for GLtL denominator." );
250
251 for ( UINT4 i = 0; i < len; i ++ ) {
252 REAL4 FpMax = setup->C; // used to keep track of log of maximal denominator sum-term
253
254 // per-detector contributions, including line weights
257 for ( UINT4 X = 0; X < setup->numDetectors; X ++ ) {
258 REAL4 ln_pLX = setup->ln_pLtL_X[X] - ( REAL4 )LAL_LN2; // ln(pLX) = ln(pLtLX/2), as we assume pLX=ptLX, so pLtLX = 2*pLX
259 Xterm[X] = 0.5f * twoFPerDet[X][i] + ln_pLX; // FX + ln(pLX)
260 FpMax = fmaxf( FpMax, Xterm[X] );
261 Xlterm[X] = 0.5f * maxTwoFSegPerDet[X][i] + setup->perSegTerm + ln_pLX; // assuming equal odds between segments: ptL_X = pL_X/Nseg
262 FpMax = fmaxf( FpMax, Xlterm[X] );
263 } // for X < numDetectors
264
265 outDenom[i] = FpMax;
266 } // for i < len
267
268 return XLAL_SUCCESS;
269
270} // XLALVectorComputeGLtLDenominator()
271
272/**
273 * \f[
274 * \newcommand{\sc}[1]{\widehat{#1}}
275 * \newcommand{\cohF}{\coh{\F}}
276 * \newcommand{\scF}{\sc{\F}}
277 * \newcommand{\denomterm}{\sc{D}}
278 * \newcommand{\denommax}{\denomterm_{\mathrm{max}}}
279 * \newcommand{\Transline}{{\mathrm{t\Line}}}
280 * \newcommand{\cppLX}{\sc{p}_{\Line}^X}
281 * \newcommand{\cppTLXk}{\coh{p}_{\Transline}^{X\ell}}
282 * \newcommand{\cppLTLsc}{\sc{p}_{\Line\Transline}}
283 * \newcommand{\denomtermset}{\mathcal{\denomterm}}
284 * \newcommand{\SGLtL}{{\Signal/\Gauss\Line\Transline}}
285 * \newcommand{\OSGLtL}{O_\SGLtL}
286 * \newcommand{\oSGLtL}{o_\SGLtL}
287 * \newcommand{\BSGLtL}{B_{\SGLtL}}
288 * \f]
289 * Compute the semi-coherent transient-line-robust CW detection statistic \f$ \logten \BSGLtL \f$
290 * from \cite Keitel2015 .
291 *
292 * As defined in Eq.(22), \f$ \BSGLtL \f$ is the BayesFactor for CW signals vs.
293 * either Gaussian noise, a persistent line or a transient line, i.e.
294 * \f$ \BSGLtL \equiv \frac{P(\data | \text{Signal})}{P(\data | \text{Gauss or Line or transient Line})} \f$ .
295 *
296 * This function returns an approximation of \f$ \logten \BSGLtL = \ln \BSGLtL \, \logten e \f$ ,
297 * with the general expression for \f$ \ln \BSGLtL \f$ given in Eq.(23) of \cite Keitel2015,
298 * while here we compute only the leading term
299 * \f{equation}{
300 * \ln \BSGLtL \approx \F - \denommax\,.
301 * \f}
302 *
303 *
304 * NOTE: In the current implementation, only
305 * \c setup->useLogCorrection == FALSE
306 * is accepted!
307 * In this case, the output is simply the maximum of the set of denominator exponents,
308 * \f{equation}{
309 * \denommax \equiv \max \left\{ \Nseg\cohFtho + \ln\left( 1-\cppLTLsc \right) ,\,
310 * \scF^X + \ln\cppLX ,\,
311 * \cohF^{X\ell} + (\Nseg-1)\cohFtho + \ln\cppTLXk
312 * \right\} \,,
313 * \f}
314 * with the simplifying assumption of equal prior odds for persistent and transient lines (with equal odds for all segments), ie.
315 * \f$ \cppTLXk = \cppLX / \Nseg \f$ , therefore \f$ \ln\cppTLXk = \ln\cppLX - \ln\Nseg \f$ .
316 *
317 */
318int
319XLALVectorComputeBSGLtL( REAL4 *outBSGLtL, //!< [out] pre-allocated vector for returning BSLGtL values
320 const REAL4 *twoF, //!< [in] vector of semi-coherent sum \f$ 2\scF \f$ of multi-detector F-stats
321 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS],//!< [in] vector of semi-coherent sums \f$ \{2\scF^X\} \f$ of per-detector F-stats
322 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS], //!< [in] vector of maxima over segments of \f$ \{\max\limits_{\ell}2\{\cohF^{X\ell}\}\} \f$ of per-detector F-stats
323 const UINT4 len, //!< [in] length of input/output vectors
324 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
325 )
326{
327 XLAL_CHECK( ( outBSGLtL != NULL ) && ( twoF != NULL ) && ( twoFPerDet != NULL ) && ( maxTwoFSegPerDet != NULL ) && ( setup != NULL ), XLAL_EFUNC );
328
329 XLAL_CHECK( XLALVectorComputeGLtLDenominator( outBSGLtL, twoFPerDet, maxTwoFSegPerDet, len, setup ) == XLAL_SUCCESS, XLAL_EFUNC );
330 // outBSGLtL now holds 'GLtLDenominator'
331
332 for ( UINT4 i = 0; i < len; i ++ ) {
333 outBSGLtL[i] -= 0.5f * twoF[i]; // GLtLDenominator - F;
334 outBSGLtL[i] *= -LAL_LOG10E; //convert to log10(B_SGLtL), flip sign
335 }
336
337 return XLAL_SUCCESS;
338
339} // XLALVectorComputeBSGLtL()
340
341/// Single-bin wrapper of XLALVectorComputeBSGLtL(), provided for backwards compatibility.
342REAL4
343XLALComputeBSGLtL( const REAL4 twoF, //!< [in] semi-coherent sum \f$ 2\scF \f$ of multi-detector F-stats
344 const REAL4 twoFX[PULSAR_MAX_DETECTORS], //!< [in] semi-coherent sums \f$ \{2\scF^X\} \f$ of per-detector F-stats
345 const REAL4 maxtwoFlX[PULSAR_MAX_DETECTORS], //!< [in] maxima \f$ \{\max\limits_{\ell}2\{\cohF^{X\ell}\}\} \f$ of per-detector F-stats over segments
346 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
347 )
348{
349 REAL4 outBSGLtL;
350 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS];
351 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS];
352 for ( UINT4 X = 0; X < setup->numDetectors; X ++ ) {
353 twoFPerDet[X] = &( twoFX[X] );
354 maxTwoFSegPerDet[X] = &( maxtwoFlX[X] );
355 }
356 XLAL_CHECK_REAL4( XLALVectorComputeBSGLtL( &outBSGLtL, &twoF, twoFPerDet, maxTwoFSegPerDet, 1, setup ) == XLAL_SUCCESS, XLAL_EFUNC );
357
358 return outBSGLtL;
359
360} // XLALComputeBSGLtL()
361
362/**
363 * \f[
364 * \newcommand{\Transsig}{{\mathrm{t\Signal}}}
365 * \newcommand{\tSGLtL}{{\Transsig/\Gauss\Line\Transline}}
366 * \newcommand{\BtSGLtL}{B_{\tSGLtL}}
367 * \newcommand{\OtSGLtL}{O_\tSGLtL}
368 * \newcommand{\otSGLtL}{o_\tSGLtL}
369 * \newcommand{\oTSGk}{\coh{o}_{\Transsig/\Gauss}^{\ell}}
370 * \f]
371 * Compute a semi-coherent transient-line-robust tCW detection statistic \f$ \logten \BtSGLtL \f$
372 * from \cite Keitel2015 .
373 *
374 * As defined in Eq.(40), \f$ \BtSGLtL \f$ is the BayesFactor for tCW signals vs.
375 * either Gaussian noise, a persistent line or a transient line, i.e.
376 * \f$ \BtSGLtL \equiv \frac{P(\data | \text{transient Signal})}{P(\data | \text{Gauss or Line or transient Line})} \f$ .
377 *
378 * This function returns an approximation of \f$ \logten \BtSGLtL = \ln \BtSGLtL \, \logten e \f$ ,
379 * computing only the leading term
380 * \f{equation}{
381 * \ln \BtSGLtL \approx \max_{\ell}\cohF^{\ell} + (\Nseg - 1)\cohFtho - \ln \Nseg - \denommax\,,
382 * \f}
383 * using the maximum multi-detector, single-segment F-stat value \f$ \max\cohF^{\ell} \f$ in the numerator,
384 * and the maximum \f$ \denommax \f$ of the set of denominator exponents, see the documentation of XLALVectorComputeBSGLtL() for its definition.
385 *
386 * NOTE: This implementation also assumes equal prior transient-signal odds for all segments.
387 *
388 */
389int
390XLALVectorComputeBtSGLtL( REAL4 *outBtSGLtL, //!< [out] pre-allocated vector for returning BtSGLtL values
391 const REAL4 *maxTwoFSeg, //!< [in] vector of maximum \f$ \max\limits_{\ell}2\cohF^\ell \f$ of multi-detector F-stats over segments
392 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], //!< [in] vector of semi-coherent sums \f$ \{2\scF^X\} \f$ of per-detector F-stats
393 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS], //!< [in] vector of maxima \f$ \{\max\limits_{\ell}2\{\cohF^{X\ell}\}\} \f$ of per-detector F-stats over segments
394 const UINT4 len, //!< [in] length of input/output vectors
395 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
396 )
397{
398 XLAL_CHECK( ( outBtSGLtL != NULL ) && ( maxTwoFSeg != NULL ) && ( twoFPerDet != NULL ) && ( maxTwoFSegPerDet != NULL ) && ( setup != NULL ), XLAL_EFUNC );
399
400 XLAL_CHECK( XLALVectorComputeGLtLDenominator( outBtSGLtL, twoFPerDet, maxTwoFSegPerDet, len, setup ) == XLAL_SUCCESS, XLAL_EFUNC ); // outBtSGLtL = GLtLDenominator
401
402 for ( UINT4 i = 0; i < len; i ++ ) {
403 outBtSGLtL[i] -= 0.5f * maxTwoFSeg[i] + setup->perSegTerm; // outBtSGLtL = GLtLDenominator - (max_l F_l + perSegTerm)
404 outBtSGLtL[i] *= -LAL_LOG10E; // convert to log10 and flip sign
405 }
406
407 return XLAL_SUCCESS;
408
409} // XLALVectorComputeBtSGLtL()
410
411/// Single-bin wrapper of XLALVectorComputeBtSGLtL(), provided for backwards compatibility.
412REAL4
413XLALComputeBtSGLtL( const REAL4 maxtwoFl, //!< [in] maximum \f$ \max\limits_{\ell}2\cohF^\ell \f$ of multi-detector F-stats over segments
414 const REAL4 twoFX[PULSAR_MAX_DETECTORS], //!< [in] semi-coherent sums \f$ \{2\scF^X\} \f$ of per-detector F-stats
415 const REAL4 maxtwoFXl[PULSAR_MAX_DETECTORS], //!< [in] maxima \f$ \{\max\limits_{\ell}2\{\cohF^{X\ell}\}\} \f$ of per-detector F-stats over segments
416 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
417 )
418{
419 REAL4 outBtSGLtL;
420 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS];
421 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS];
422 for ( UINT4 X = 0; X < setup->numDetectors; X ++ ) {
423 twoFPerDet[X] = &( twoFX[X] );
424 maxTwoFSegPerDet[X] = &( maxtwoFXl[X] );
425 }
426 XLAL_CHECK_REAL4( XLALVectorComputeBtSGLtL( &outBtSGLtL, &maxtwoFl, twoFPerDet, maxTwoFSegPerDet, 1, setup ) == XLAL_SUCCESS, XLAL_EFUNC );
427
428 return outBtSGLtL;
429} // XLALComputeBtSGLtL()
430
431/**
432 * \f[
433 * \newcommand{\StSGLtL}{{\Signal\Transsig\Gauss\Line\Transline}}
434 * \newcommand{\OStSGLtL}{O_\StSGLtL}
435 * \newcommand{\oStSGLtL}{o_\StSGLtL}
436 * \newcommand{\BStSGLtL}{B_{\StSGLtL}}
437 * \newcommand{\numerterm}{\sc{E}}
438 * \newcommand{\numertermset}{\mathcal{\numerterm}}
439 * \newcommand{\numermin}{\numerterm_{\mathrm{min}}}
440 * \newcommand{\numermax}{\numerterm_{\mathrm{max}}}
441 * \newcommand{\cppS}{\sc{p}_{\Signal}}
442 * \newcommand{\cppTS}{\coh{p}_{\Transsig}}
443 * \newcommand{\cppTSk}{\coh{p}_{\Transsig}^{\ell}}
444 * \f]
445 * Compute the semi-coherent transient-line-robust CW+tCW detection statistic \f$ \logten \BStSGLtL \f$
446 * from \cite Keitel2015 .
447 *
448 * As defined in Eq.(35), \f$ \BStSGLtL \f$ is the BayesFactor for either persistent CW or transient tCW signals vs.
449 * either Gaussian noise, a persistent line or a transient line, i.e.
450 * \f$ \BStSGLtL \equiv \frac{P(\data | \text{Signal or transient Signal})}{P(\data | \text{Gauss or Line or transient Line})} \f$ .
451 *
452 * This function returns an approximation of \f$ \logten \BStSGLtL = \ln \BStSGLtL \, \logten e \f$ ,
453 * with the general expression for \f$ \ln \BStSGLtL \f$ given in Eq.(36) of \cite Keitel2015 .
454 * Here we compute only the leading term
455 * \f{equation}{
456 * \ln \BStSGLtL \approx \numermax + \ln \left( 1 + e^{\numermin-\numermax} \right) - \denommax \,,
457 * \f}
458 *
459 * with the \f$ \denommax \f$ terms defined in the documentation of XLALVectorComputeBSGLtL(), and
460 *
461 * \f$ \numermax = \max \left\{ \scF, \max\limits_{\ell}\cohF^\ell + \cohFtho (\Nseg-1) - \ln \Nseg\right\} \f$ ,
462 * where we have assumed prior equal odds between persistent and transient signals and equal odds for all segments.
463 *
464 */
465REAL4
466XLALComputeBStSGLtL( const REAL4 twoF, //!< [in] semi-coherent sum \f$ 2\scF \f$ of multi-detector F-stats
467 const REAL4 maxtwoFl, //!< [in] maximum \f$ \max\limits_{\ell}2\cohF^\ell \f$ of multi-detector F-stats over segments
468 const REAL4 twoFX[PULSAR_MAX_DETECTORS], //!< [in] semi-coherent sums \f$ \{2\scF^X\} \f$ of per-detector F-stats
469 const REAL4 maxtwoFXl[PULSAR_MAX_DETECTORS], //!< [in] maxima \f$ \{\max\limits_{\ell}2\{\cohF^{X\ell}\}\} \f$ of per-detector F-stats over segments
470 const BSGLSetup *setup //!< [in] pre-computed setup from XLALCreateBSGLSetup()
471 )
472{
473 XLAL_CHECK_REAL4( setup != NULL, XLAL_EINVAL );
474
475 REAL4 GLtLDenominator;
476 const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS];
477 const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS];
478 for ( UINT4 X = 0; X < setup->numDetectors; X ++ ) {
479 twoFPerDet[X] = &( twoFX[X] );
480 maxTwoFSegPerDet[X] = &( maxtwoFXl[X] );
481 }
482 XLAL_CHECK_REAL4( XLALVectorComputeGLtLDenominator( &GLtLDenominator, twoFPerDet, maxTwoFSegPerDet, 1, setup ) == XLAL_SUCCESS, XLAL_EFUNC );
483
484 const REAL4 ln_pS = -( REAL4 )LAL_LN2; // =ln(2) assuming equal odds between S and tS hypotheses: pS = ptS = 1/2, conditional on (S or tS)
485 REAL4 multiF = 0.5f * twoF + ln_pS;
486 REAL4 tsTerm = 0.5f * maxtwoFl + setup->perSegTerm + ln_pS; // ptS_l = ptS/Nseg = pS/Nseg
487 REAL4 maxNumerator = fmaxf( multiF, tsTerm );
488 REAL4 minNumerator = fminf( multiF, tsTerm );
489
490 REAL4 ln_BStSGLtL = maxNumerator + logf( 1 + expf( minNumerator - maxNumerator ) ) - GLtLDenominator;
491
492 return ln_BStSGLtL * LAL_LOG10E; // return log10(B_SGL)
493
494} // XLALComputeBStSGLtL()
495
496/**
497 * Parse string-vectors (typically input by user) of N per-detector line-to-Gaussian prior ratios
498 * \f$ o_{LG}^X = \frac{P(H_L^X)}{P(H_G^X)} \f$ to a flat array of REAL4s.
499 */
500int
501XLALParseLinePriors( REAL4 oLGX[PULSAR_MAX_DETECTORS], //!< [out] array of parsed \f$ o_{LG}^X \f$ values
502 const LALStringVector *oLGX_string //!< [in] string-list of \f$ o_{LG}^X \f$ values
503 )
504{
505 XLAL_CHECK( oLGX != NULL, XLAL_EINVAL );
506 XLAL_CHECK( oLGX_string != NULL, XLAL_EINVAL );
507 UINT4 numDetectors = oLGX_string->length;
509
510 // parse input string
511 for ( UINT4 X = 0; X < numDetectors; X ++ ) {
512 XLAL_CHECK( XLALParseStringValueAsREAL4( &oLGX[X], oLGX_string->data[X] ) == XLAL_SUCCESS, XLAL_EFUNC );
513 } // for X < numDetectors
514
515 return XLAL_SUCCESS;
516
517} // XLALParseLinePriors()
518
519/// @}
#define LAL_LN2
#define LAL_REAL4_MAX
#define LAL_LOG10E
unsigned char BOOLEAN
uint32_t UINT4
float REAL4
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
int XLALVectorComputeBSGLtL(REAL4 *outBSGLtL, const REAL4 *twoF, const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS], const UINT4 len, const BSGLSetup *setup)
REAL4 XLALComputeBSGLtL(const REAL4 twoF, const REAL4 twoFX[PULSAR_MAX_DETECTORS], const REAL4 maxtwoFlX[PULSAR_MAX_DETECTORS], const BSGLSetup *setup)
Single-bin wrapper of XLALVectorComputeBSGLtL(), provided for backwards compatibility.
REAL4 XLALComputeBtSGLtL(const REAL4 maxtwoFl, const REAL4 twoFX[PULSAR_MAX_DETECTORS], const REAL4 maxtwoFXl[PULSAR_MAX_DETECTORS], const BSGLSetup *setup)
Single-bin wrapper of XLALVectorComputeBtSGLtL(), provided for backwards compatibility.
void XLALDestroyBSGLSetup(BSGLSetup *setup)
int XLALVectorComputeBSGL(REAL4 *outBSGL, const REAL4 *twoF, const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], const UINT4 len, const BSGLSetup *setup)
REAL4 XLALComputeBStSGLtL(const REAL4 twoF, const REAL4 maxtwoFl, const REAL4 twoFX[PULSAR_MAX_DETECTORS], const REAL4 maxtwoFXl[PULSAR_MAX_DETECTORS], const BSGLSetup *setup)
BSGLSetup * XLALCreateBSGLSetup(const UINT4 numDetectors, const REAL4 Fstar0sc, const REAL4 oLGX[PULSAR_MAX_DETECTORS], const BOOLEAN useLogCorrection, const UINT4 numSegments)
REAL4 XLALComputeBSGL(const REAL4 twoF, const REAL4 twoFX[PULSAR_MAX_DETECTORS], const BSGLSetup *setup)
Single-bin wrapper of XLALVectorComputeBSGL(), provided for backwards compatibility.
int XLALVectorComputeGLtLDenominator(REAL4 *outDenom, const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS], const UINT4 len, const BSGLSetup *setup)
int XLALParseLinePriors(REAL4 oLGX[PULSAR_MAX_DETECTORS], const LALStringVector *oLGX_string)
Parse string-vectors (typically input by user) of N per-detector line-to-Gaussian prior ratios to a ...
int XLALVectorComputeBtSGLtL(REAL4 *outBtSGLtL, const REAL4 *maxTwoFSeg, const REAL4 *twoFPerDet[PULSAR_MAX_DETECTORS], const REAL4 *maxTwoFSegPerDet[PULSAR_MAX_DETECTORS], const UINT4 len, const BSGLSetup *setup)
#define PULSAR_MAX_DETECTORS
maximal number of detectors we can handle (for static arrays of detector quantities)
int XLALParseStringValueAsREAL4(REAL4 *valREAL4, const char *valString)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_REAL4(assertion,...)
#define XLAL_CHECK_NULL(assertion,...)
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EDOM
XLAL_EINVAL
size_t numDetectors
internal storage for setup and pre-computed BSGL quantities
REAL4 oLGX[PULSAR_MAX_DETECTORS]
REAL4 ln_pLtL_X[PULSAR_MAX_DETECTORS]
BOOLEAN useLogCorrection