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
FstatisticTools.c
Go to the documentation of this file.
1//
2// Copyright (C) 2017 Maximillian Bensch, Reinhard Prix
3// Copyright (C) 2014 Reinhard Prix
4// Copyright (C) 2012, 2013, 2014 Karl Wette
5// Copyright (C) 2007 Chris Messenger
6// Copyright (C) 2006 John T. Whelan, Badri Krishnan
7// Copyright (C) 2005, 2006, 2007, 2010 Reinhard Prix
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; either version 2 of the License, or
12// (at your option) any later version.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with with program; see the file COPYING. If not, write to the
21// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22// MA 02110-1301 USA
23//
24
25// ---------- includes ----------
26#include <gsl/gsl_vector.h>
27#include <gsl/gsl_matrix.h>
28#include <gsl/gsl_blas.h>
29#include <gsl/gsl_permutation.h>
30#include <gsl/gsl_linalg.h>
31
32#include <lal/ExtrapolatePulsarSpins.h>
33
34#include <lal/FstatisticTools.h>
35
36// ---------- local macro definitions ----------
37#define SQ(x) ( (x) * (x) )
38#define MYSIGN(x) ( ((x) < 0) ? (-1.0):(+1.0) )
39
40
41// ==================== function definitions ====================
42
43/// \addtogroup FstatisticTools_h
44/// @{
45
46///
47/// Estimate the amplitude parameters of a pulsar CW signal, given its phase parameters,
48/// constituent parts of the \f$ \mathcal{F} \f$ -statistic, and antenna pattern matrix.
49///
50/// \note Parameter-estimation based on large parts on Yousuke's notes and implemention (in CFSv1),
51/// extended for error-estimation.
52///
53int
54XLALEstimatePulsarAmplitudeParams( PulsarCandidate *pulsarParams, ///< [in,out] Pulsar candidate parameters.
55 const LIGOTimeGPS *FaFb_refTime, ///< [in] Reference time of \f$ F_a \f$ and \f$ F_b \f$ , may differ from pulsar candidate reference time.
56 const COMPLEX8 Fa, ///< [in] Complex \f$ \mathcal{F} \f$ -statistic amplitude \f$ F_a \f$ .
57 const COMPLEX8 Fb, ///< [in] Complex \f$ \mathcal{F} \f$ -statistic amplitude \f$ F_b \f$ .
58 const AntennaPatternMatrix *Mmunu ///< [in] Antenna pattern matrix \f$ M_{\mu\nu} \f$ .
59 )
60{
61
62 REAL8 A1h, A2h, A3h, A4h;
63 REAL8 Ad, Bd, Cd, Dd, Ed;
64 REAL8 normAmu;
65 REAL8 A1check, A2check, A3check, A4check;
66
67 REAL8 Asq, Da, disc;
68 REAL8 aPlus, aCross;
69 REAL8 Ap2, Ac2;
70 REAL8 beta;
71 REAL8 phi0, psi;
72 REAL8 b1, b2, b3;
73
74 REAL8 cosphi0, sinphi0, cos2psi, sin2psi;
75
76 REAL8 tolerance = LAL_REAL4_EPS;
77
78 gsl_vector *x_mu, *A_Mu;
79 gsl_matrix *M_Mu_Nu;
80 gsl_matrix *Jh_Mu_nu;
81 gsl_permutation *permh;
82 gsl_matrix *tmp, *tmp2;
83 int signum;
84
85 XLAL_CHECK( pulsarParams != NULL, XLAL_EINVAL );
86 XLAL_CHECK( FaFb_refTime != NULL, XLAL_EINVAL );
87 XLAL_CHECK( isfinite( creal( Fa ) ) && isfinite( cimag( Fb ) ), XLAL_EDOM,
88 "Fa = (%g, %g) is not finite", creal( Fa ), cimag( Fa ) );
89 XLAL_CHECK( isfinite( creal( Fb ) ) && isfinite( cimag( Fb ) ), XLAL_EDOM,
90 "Fb = (%g, %g) is not finite", creal( Fb ), cimag( Fb ) );
91 XLAL_CHECK( Mmunu != NULL, XLAL_EINVAL );
92
93 Ad = Mmunu->Ad;
94 Bd = Mmunu->Bd;
95 Cd = Mmunu->Cd;
96 Ed = Mmunu->Ed;
97 Dd = Ad * Bd - Cd * Cd - Ed * Ed;
98
99 normAmu = 2.0 / sqrt( 2.0 * Mmunu->Sinv_Tsft ); // generally *very* small!!
100
101 // ----- GSL memory allocation -----
102 XLAL_CHECK( ( x_mu = gsl_vector_calloc( 4 ) ) != NULL, XLAL_ENOMEM );
103 XLAL_CHECK( ( A_Mu = gsl_vector_calloc( 4 ) ) != NULL, XLAL_ENOMEM );
104 XLAL_CHECK( ( M_Mu_Nu = gsl_matrix_calloc( 4, 4 ) ) != NULL, XLAL_ENOMEM );
105 XLAL_CHECK( ( Jh_Mu_nu = gsl_matrix_calloc( 4, 4 ) ) != NULL, XLAL_ENOMEM );
106
107 XLAL_CHECK( ( permh = gsl_permutation_calloc( 4 ) ) != NULL, XLAL_ENOMEM );
108 XLAL_CHECK( ( tmp = gsl_matrix_calloc( 4, 4 ) ) != NULL, XLAL_ENOMEM );
109 XLAL_CHECK( ( tmp2 = gsl_matrix_calloc( 4, 4 ) ) != NULL, XLAL_ENOMEM );
110
111 // ----- fill vector x_mu
112 gsl_vector_set( x_mu, 0, creal( Fa ) ); // x_1
113 gsl_vector_set( x_mu, 1, creal( Fb ) ); // x_2
114 gsl_vector_set( x_mu, 2, - cimag( Fa ) ); // x_3
115 gsl_vector_set( x_mu, 3, - cimag( Fb ) ); // x_4
116
117 // ----- fill matrix M^{mu,nu} [symmetric: use UPPER HALF ONLY!!]
118 gsl_matrix_set( M_Mu_Nu, 0, 0, Bd / Dd );
119 gsl_matrix_set( M_Mu_Nu, 1, 1, Ad / Dd );
120 gsl_matrix_set( M_Mu_Nu, 0, 1, - Cd / Dd );
121
122 gsl_matrix_set( M_Mu_Nu, 0, 3, - Ed / Dd );
123 gsl_matrix_set( M_Mu_Nu, 1, 2, Ed / Dd );
124
125 gsl_matrix_set( M_Mu_Nu, 2, 2, Bd / Dd );
126 gsl_matrix_set( M_Mu_Nu, 3, 3, Ad / Dd );
127 gsl_matrix_set( M_Mu_Nu, 2, 3, - Cd / Dd );
128
129 // get (un-normalized) MLE's for amplitudes A^mu = M^{mu,nu} x_nu
130
131 /* GSL-doc: int gsl_blas_dsymv (CBLAS_UPLO_t Uplo, double alpha, const gsl_matrix * A,
132 * const gsl_vector * x, double beta, gsl_vector * y )
133 *
134 * compute the matrix-vector product and sum: y = alpha A x + beta y
135 * for the symmetric matrix A. Since the matrix A is symmetric only its
136 * upper half or lower half need to be stored. When Uplo is CblasUpper
137 * then the upper triangle and diagonal of A are used, and when Uplo
138 * is CblasLower then the lower triangle and diagonal of A are used.
139 */
140 XLAL_CHECK( gsl_blas_dsymv( CblasUpper, 1.0, M_Mu_Nu, x_mu, 0.0, A_Mu ) == 0, XLAL_EERR );
141
142 A1h = gsl_vector_get( A_Mu, 0 );
143 A2h = gsl_vector_get( A_Mu, 1 );
144 A3h = gsl_vector_get( A_Mu, 2 );
145 A4h = gsl_vector_get( A_Mu, 3 );
146
147 Asq = SQ( A1h ) + SQ( A2h ) + SQ( A3h ) + SQ( A4h );
148 Da = A1h * A4h - A2h * A3h;
149 disc = sqrt( SQ( Asq ) - 4.0 * SQ( Da ) );
150
151 Ap2 = 0.5 * ( Asq + disc );
152 aPlus = sqrt( Ap2 ); // not yet normalized
153
154 Ac2 = 0.5 * ( Asq - disc );
155 aCross = sqrt( Ac2 );
156 aCross *= MYSIGN( Da ); // not yet normalized
157
158 beta = aCross / aPlus;
159
160 b1 = A4h - beta * A1h;
161 b2 = A3h + beta * A2h;
162 b3 = - A1h + beta * A4h ;
163
164 psi = 0.5 * atan( b1 / b2 ); // in [-pi/4,pi/4] (gauge used also by TDS)
165 phi0 = atan( b2 / b3 ); // in [-pi/2,pi/2]
166
167 // Fix remaining sign-ambiguity by checking sign of reconstructed A1
168 A1check = aPlus * cos( phi0 ) * cos( 2.0 * psi ) - aCross * sin( phi0 ) * sin( 2 * psi );
169 if ( A1check * A1h < 0 ) {
170 phi0 += LAL_PI;
171 }
172
173 cosphi0 = cos( phi0 );
174 sinphi0 = sin( phi0 );
175 cos2psi = cos( 2 * psi );
176 sin2psi = sin( 2 * psi );
177
178 // check numerical consistency of estimated Amu and reconstructed
179 A1check = aPlus * cosphi0 * cos2psi - aCross * sinphi0 * sin2psi;
180 A2check = aPlus * cosphi0 * sin2psi + aCross * sinphi0 * cos2psi;
181 A3check = - aPlus * sinphi0 * cos2psi - aCross * cosphi0 * sin2psi;
182 A4check = - aPlus * sinphi0 * sin2psi + aCross * cosphi0 * cos2psi;
183
184 if ( ( fabs( ( A1check - A1h ) / A1h ) > tolerance ) ||
185 ( fabs( ( A2check - A2h ) / A2h ) > tolerance ) ||
186 ( fabs( ( A3check - A3h ) / A3h ) > tolerance ) ||
187 ( fabs( ( A4check - A4h ) / A4h ) > tolerance ) ) {
188 if ( lalDebugLevel )
189 XLALPrintError( "WARNING %s(): Difference between estimated and reconstructed Amu exceeds tolerance of %g\n",
190 __func__, tolerance );
191 }
192
193 // ========== Estimate the errors ==========
194
195 // ----- compute derivatives \partial A^\mu / \partial A^\nu, where
196 // we consider the output-variables A^\nu = (aPlus, aCross, phi0, psi)
197 // where aPlus = 0.5 * h0 * (1 + cosi^2) and aCross = h0 * cosi
198 {
199 // Eqn (114) in T0900149 v5
200 // ----- A1 = aPlus * cosphi0 * cos2psi - aCross * sinphi0 * sin2psi; -----
201 gsl_matrix_set( Jh_Mu_nu, 0, 0, cosphi0 * cos2psi ); /* dA1/daPlus */
202 gsl_matrix_set( Jh_Mu_nu, 0, 1, - sinphi0 * sin2psi ); /* dA1/daCross */
203 gsl_matrix_set( Jh_Mu_nu, 0, 2, A3h ); /* dA1/dphi0 */
204 gsl_matrix_set( Jh_Mu_nu, 0, 3, - 2.0 * A2h ); /* dA1/dpsi */
205
206 // ----- A2 = aPlus * cosphi0 * sin2psi + aCross * sinphi0 * cos2psi; -----
207 gsl_matrix_set( Jh_Mu_nu, 1, 0, cosphi0 * sin2psi ); /* dA2/daPlus */
208 gsl_matrix_set( Jh_Mu_nu, 1, 1, sinphi0 * cos2psi ); /* dA2/daCross */
209 gsl_matrix_set( Jh_Mu_nu, 1, 2, A4h ); /* dA2/dphi0 */
210 gsl_matrix_set( Jh_Mu_nu, 1, 3, 2.0 * A1h ); /* dA2/dpsi */
211
212 // ----- A3 = - aPlus * sinphi0 * cos2psi - aCross * cosphi0 * sin2psi; -----
213 gsl_matrix_set( Jh_Mu_nu, 2, 0, - sinphi0 * cos2psi ); /* dA3/daPlus */
214 gsl_matrix_set( Jh_Mu_nu, 2, 1, - cosphi0 * sin2psi ); /* dA3/daCross */
215 gsl_matrix_set( Jh_Mu_nu, 2, 2, - A1h ); /* dA3/dphi0 */
216 gsl_matrix_set( Jh_Mu_nu, 2, 3, - 2.0 * A4h ); /* dA3/dpsi */
217
218 // ----- A4 = - aPlus * sinphi0 * sin2psi + aCross * cosphi0 * cos2psi; -----
219 gsl_matrix_set( Jh_Mu_nu, 3, 0, - sinphi0 * sin2psi ); /* dA4/daPlus */
220 gsl_matrix_set( Jh_Mu_nu, 3, 1, cosphi0 * cos2psi ); /* dA4/daCross */
221 gsl_matrix_set( Jh_Mu_nu, 3, 2, - A2h ); /* dA4/dphi0 */
222 gsl_matrix_set( Jh_Mu_nu, 3, 3, 2.0 * A3h ); /* dA4/dpsi */
223 }
224
225 // ----- compute inverse matrices Jh^{-1} by LU-decomposition -----
226 XLAL_CHECK( gsl_linalg_LU_decomp( Jh_Mu_nu, permh, &signum ) == 0, XLAL_EERR );
227
228 // inverse matrix
229 XLAL_CHECK( gsl_linalg_LU_invert( Jh_Mu_nu, permh, tmp ) == 0, XLAL_EERR );
230 gsl_matrix_memcpy( Jh_Mu_nu, tmp );
231
232 // ----- compute Jh^-1 . Minv . (Jh^-1)^T -----
233
234 /* GSL-doc: gsl_blas_dgemm (CBLAS_TRANSPOSE_t TransA, CBLAS_TRANSPOSE_t TransB, double alpha,
235 * const gsl_matrix *A, const gsl_matrix *B, double beta, gsl_matrix *C)
236 * These functions compute the matrix-matrix product and sum
237 * C = \alpha op(A) op(B) + \beta C
238 * where op(A) = A, A^T, A^H for TransA = CblasNoTrans, CblasTrans, CblasConjTrans
239 * and similarly for the parameter TransB.
240 */
241
242 // first tmp = Minv . (Jh^-1)^T
243 XLAL_CHECK( gsl_blas_dgemm( CblasNoTrans, CblasTrans, 1.0, M_Mu_Nu, Jh_Mu_nu, 0.0, tmp ) == 0, XLAL_EERR );
244 // then J^-1 . tmp , store result in tmp2
245 XLAL_CHECK( gsl_blas_dgemm( CblasNoTrans, CblasNoTrans, 1.0, Jh_Mu_nu, tmp, 0.0, tmp2 ) == 0, XLAL_EERR );
246 gsl_matrix_memcpy( Jh_Mu_nu, tmp2 );
247
248 // ===== debug-output resulting matrices =====
249 // propagate initial-phase from Fstat-reference-time to refTime of Doppler-params
250 // XLALExtrapolatePulsarPhase() guarantees propagated phi0 is in [0, 2*pi]
251 const REAL8 dtau = XLALGPSDiff( &pulsarParams->Doppler.refTime, FaFb_refTime );
253
254 // fill candidate-struct with the obtained signal-parameters and error-estimations
255 pulsarParams->Amp.aPlus = normAmu * aPlus;
256 pulsarParams->Amp.aCross = normAmu * aCross;
257 pulsarParams->Amp.phi0 = phi0;
258 pulsarParams->Amp.psi = psi;
259
260 // read out principal estimation-errors from diagonal elements of inverse Fisher-matrix
261 pulsarParams->dAmp.aPlus = normAmu * sqrt( gsl_matrix_get( Jh_Mu_nu, 0, 0 ) );
262 pulsarParams->dAmp.aCross = normAmu * sqrt( gsl_matrix_get( Jh_Mu_nu, 1, 1 ) );
263 pulsarParams->dAmp.phi0 = sqrt( gsl_matrix_get( Jh_Mu_nu, 2, 2 ) );
264 pulsarParams->dAmp.psi = sqrt( gsl_matrix_get( Jh_Mu_nu, 3, 3 ) );
265 // return also the full Amplitude-Fisher matrix: invert Jh_Mu_nu
266 XLAL_CHECK( gsl_linalg_LU_decomp( Jh_Mu_nu, permh, &signum ) == 0, XLAL_EERR );
267 XLAL_CHECK( gsl_linalg_LU_invert( Jh_Mu_nu, permh, tmp ) == 0, XLAL_EERR );
268 pulsarParams->AmpFisherMatrix = tmp;
269
270 // ----- free GSL memory -----
271 gsl_vector_free( x_mu );
272 gsl_vector_free( A_Mu );
273 gsl_matrix_free( M_Mu_Nu );
274 gsl_matrix_free( Jh_Mu_nu );
275 gsl_permutation_free( permh );
276 gsl_matrix_free( tmp2 );
277
278 return XLAL_SUCCESS;
279
280} // XLALEstimatePulsarAmplitudeParams()
281
282///
283/// Convert amplitude params from 'physical' coordinates \f$ (h_0, \cos\iota, \psi, \phi_0) \f$ into
284/// 'canonical' coordinates \f$ A^\mu = (A_1, A_2, A_3, A_4) \f$ . The equations can be found in
285/// \cite JKS98 or \cite Prix07 Eq.(2).
286///
287int
288XLALAmplitudeParams2Vect( PulsarAmplitudeVect A_Mu, ///< [out] Canonical amplitude coordinates \f$ A^\mu = (A_1, A_2, A_3, A_4) \f$ .
289 const PulsarAmplitudeParams Amp ///< [in] Physical amplitude params \f$ (h_0, \cos\iota, \psi, \phi_0) \f$ .
290 )
291{
292
293 REAL8 aPlus = Amp.aPlus;
294 REAL8 aCross = Amp.aCross;
295 REAL8 cos2psi = cos( 2.0 * Amp.psi );
296 REAL8 sin2psi = sin( 2.0 * Amp.psi );
297 REAL8 cosphi0 = cos( Amp.phi0 );
298 REAL8 sinphi0 = sin( Amp.phi0 );
299
300 XLAL_CHECK( A_Mu != NULL, XLAL_EINVAL );
301
302 A_Mu[0] = aPlus * cos2psi * cosphi0 - aCross * sin2psi * sinphi0;
303 A_Mu[1] = aPlus * sin2psi * cosphi0 + aCross * cos2psi * sinphi0;
304 A_Mu[2] = -aPlus * cos2psi * sinphi0 - aCross * sin2psi * cosphi0;
305 A_Mu[3] = -aPlus * sin2psi * sinphi0 + aCross * cos2psi * cosphi0;
306
307 return XLAL_SUCCESS;
308
309} // XLALAmplitudeParams2Vect()
310
311///
312/// Compute amplitude params \f$ (h_0, \cos\iota, \psi, \phi_0) \f$ from amplitude-vector \f$ A^\mu = (A_1, A_2, A_3, A_4) \f$ .
313/// Adapted from algorithm in XLALEstimatePulsarAmplitudeParams().
314///
315int
316XLALAmplitudeVect2Params( PulsarAmplitudeParams *Amp, ///< [out] Physical amplitude params \f$ (h_0, \cos\iota, \psi, \phi_0) \f$ .
317 const PulsarAmplitudeVect A_Mu ///< [in] Canonical amplitude coordinates \f$ A^\mu = (A_1, A_2, A_3, A_4) \f$ .
318 )
319{
320
321 REAL8 psiRet, phi0Ret;
322
323 REAL8 A1, A2, A3, A4, Asq, Da, disc;
324 REAL8 Ap2, Ac2, aPlus, aCross;
325 REAL8 beta, b1, b2, b3;
326
327 XLAL_CHECK( A_Mu != NULL, XLAL_EINVAL );
328 XLAL_CHECK( Amp != NULL, XLAL_EINVAL );
329
330 A1 = A_Mu[0];
331 A2 = A_Mu[1];
332 A3 = A_Mu[2];
333 A4 = A_Mu[3];
334
335 Asq = SQ( A1 ) + SQ( A2 ) + SQ( A3 ) + SQ( A4 );
336 Da = A1 * A4 - A2 * A3;
337
338 disc = sqrt( SQ( Asq ) - 4.0 * SQ( Da ) );
339
340 Ap2 = 0.5 * ( Asq + disc );
341 aPlus = sqrt( Ap2 );
342
343 Ac2 = 0.5 * ( Asq - disc );
344 aCross = MYSIGN( Da ) * sqrt( Ac2 );
345
346 beta = aCross / aPlus;
347
348 b1 = A4 - beta * A1;
349 b2 = A3 + beta * A2;
350 b3 = - A1 + beta * A4 ;
351
352 // amplitude params in LIGO conventions
353 psiRet = 0.5 * atan2( b1, b2 ); /* [-pi/2,pi/2] */
354 phi0Ret = atan2( b2, b3 ); /* [-pi, pi] */
355
356 // Fix remaining sign-ambiguity by checking sign of reconstructed A1
357 REAL8 A1check = aPlus * cos( phi0Ret ) * cos( 2.0 * psiRet ) - aCross * sin( phi0Ret ) * sin( 2 * psiRet );
358 if ( A1check * A1 < 0 ) {
359 phi0Ret += LAL_PI;
360 }
361
362 // make unique by fixing the gauge to be psi in [-pi/4, pi/4], phi0 in [0, 2*pi]
363 while ( psiRet > LAL_PI_4 ) {
364 psiRet -= LAL_PI_2;
365 phi0Ret -= LAL_PI;
366 }
367 while ( psiRet < - LAL_PI_4 ) {
368 psiRet += LAL_PI_2;
369 phi0Ret += LAL_PI;
370 }
371 while ( phi0Ret < 0 ) {
372 phi0Ret += LAL_TWOPI;
373 }
374
375 while ( phi0Ret > LAL_TWOPI ) {
376 phi0Ret -= LAL_TWOPI;
377 }
378
379 // Return final answer
380 Amp->aPlus = aPlus;
381 Amp->aCross = aCross;
382 Amp->psi = psiRet;
383 Amp->phi0 = phi0Ret;
384
385 return XLAL_SUCCESS;
386
387} // XLALAmplitudeVect2Params()
388
389
390
391/**
392 * Calculates the 'optimal' / perfect-match squared signal-to-noise ratio (SNR^2) for a CW signal for
393 * given PulsarAmplitudeParameters 'pap' and Antenna Pattern Matrix 'Mmunu'.
394 * The computed 'SNR' is related to the expectation value of the coherent F-statistic 'F' via
395 * E[2F] = 4 + SNR^2 for a template perfectly matching the signal, ie SNR^2 = (signal|signal).
396 */
397REAL8
398XLALComputeOptimalSNR2FromMmunu( const PulsarAmplitudeParams pap, /**< [in] PulsarAmplitudeParameter {aPlus, aCross, psi, phi0} */
399 const AntennaPatternMatrix Mmunu /**< [in] Antenna-pattern Matrix */
400 )
401{
402 // Calculate the SNR using the expressions from the 'CFSv2 notes' T0900149-v5
403 // https://dcc.ligo.org/LIGO-T0900149-v5/public, namely Eqs.(77)-(80), keeping in mind
404 // that Mmunu.{Ad,Bd,Cd} = Nsft * {A,B,C}, and Tdata = Nsft * Tsft
405
406 REAL8 cos2psi = cos( 2.0 * pap.psi );
407 REAL8 sin2psi = sin( 2.0 * pap.psi );
408 REAL8 cos2psiSq = SQ( cos2psi );
409 REAL8 sin2psiSq = SQ( sin2psi );
410
411 REAL8 h0sq_al1 = SQ( pap.aPlus ) * cos2psiSq + SQ( pap.aCross ) * sin2psiSq; // Eq.(78) generalised to (aPlus,aCross)
412 REAL8 h0sq_al2 = SQ( pap.aPlus ) * sin2psiSq + SQ( pap.aCross ) * cos2psiSq; // Eq.(79) generalised to (aPlus,aCross)
413 REAL8 h0sq_al3 = ( SQ( pap.aPlus ) - SQ( pap.aCross ) ) * sin2psi * cos2psi; // Eq.(80) generalised to (aPlus,aCross)
414
415 // SNR^2: Eq.(77)
416 REAL8 rho2 = ( h0sq_al1 * Mmunu.Ad + h0sq_al2 * Mmunu.Bd + 2.0 * h0sq_al3 * Mmunu.Cd ) * Mmunu.Sinv_Tsft;
417
418 return rho2;
419
420} // XLALComputeOptimalSNR2FromMmunu()
421
422/// @}
#define __func__
log an I/O error, i.e.
#define MYSIGN(x)
#define SQ(x)
const double b1
const double b2
const double rho2
int XLALExtrapolatePulsarPhase(REAL8 *phi1, const PulsarSpins fkdot1, const REAL8 phi0, const REAL8 dtau)
Extrapolate phase from to , given the spins fkdot1 at .
int XLALEstimatePulsarAmplitudeParams(PulsarCandidate *pulsarParams, const LIGOTimeGPS *FaFb_refTime, const COMPLEX8 Fa, const COMPLEX8 Fb, const AntennaPatternMatrix *Mmunu)
Estimate the amplitude parameters of a pulsar CW signal, given its phase parameters,...
int XLALAmplitudeParams2Vect(PulsarAmplitudeVect A_Mu, const PulsarAmplitudeParams Amp)
Convert amplitude params from 'physical' coordinates into 'canonical' coordinates .
REAL8 XLALComputeOptimalSNR2FromMmunu(const PulsarAmplitudeParams pap, const AntennaPatternMatrix Mmunu)
Calculates the 'optimal' / perfect-match squared signal-to-noise ratio (SNR^2) for a CW signal for gi...
int XLALAmplitudeVect2Params(PulsarAmplitudeParams *Amp, const PulsarAmplitudeVect A_Mu)
Compute amplitude params from amplitude-vector .
#define LAL_PI_2
#define LAL_PI
#define LAL_TWOPI
#define LAL_PI_4
#define LAL_REAL4_EPS
double REAL8
float complex COMPLEX8
#define lalDebugLevel
REAL8 PulsarAmplitudeVect[4]
Struct for 'canonical' coordinates in amplitude-params space A^mu = {A1, A2, A3, A4}.
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EERR
XLAL_EDOM
XLAL_EINVAL
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
Struct holding the "antenna-pattern" matrix , in terms of the multi-detector scalar product.
Definition: LALComputeAM.h:127
REAL8 Sinv_Tsft
normalization-factor (using single-sided PSD!)
Definition: LALComputeAM.h:133
Type containing the JKS 'amplitude parameters' {h0, cosi, phi0, psi}.
REAL8 aCross
Signal amplitude (cross)
REAL8 psi
polarization angle psi
REAL8 aPlus
Signal amplitude (plus)
REAL8 phi0
initial signal-phase (at some reference time)
Type containing a "candidate": parameter-space point with estimated errors and Fstat-value/significan...
PulsarAmplitudeParams dAmp
amplitude-parameters and error-estimates
PulsarAmplitudeParams Amp
gsl_matrix * AmpFisherMatrix
Fisher-matrix of amplitude-subspace: has more info than dAmp!
PulsarDopplerParams Doppler
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ... ] where fkdot = d^kFreq/dt^k.
LIGOTimeGPS refTime
Reference time of pulsar parameters (in SSB!)