/** * Compute the largest magnitude of antenna velocity * \param [in] t0 Start time (GPS seconds) * \param [in] Tcoh Coherence length of the SFTs (in seconds) * \param [in] SFToverlap Overlap of the SFTs (in seconds) * \param [in] Tobs Observation time (in seconds) * \param [in] det A LALDetector struct * \param [in] edat Pointer to EphemerisData * \return Maximum magnitude of antenna velocity */ REAL4 CompDetectorVmax(REAL8 t0, REAL8 Tcoh, REAL8 SFToverlap, REAL8 Tobs, LALDetector det, EphemerisData *edat) { XLAL_CHECK( edat != NULL, XLAL_EINVAL ); INT4 ii; INT4 numffts = (INT4)floor(Tobs/(Tcoh-SFToverlap)-1); //Number of FFTs LALStatus XLAL_INIT_DECL(status); REAL8 detvel[3]; REAL4 Vmax = 0.0; for (ii=0; ii<numffts; ii++) { LIGOTimeGPS gpstime = LIGOTIMEGPSZERO; gpstime.gpsSeconds = (INT4)floor(t0 + ii*(Tcoh-SFToverlap) + 0.5*Tcoh); gpstime.gpsNanoSeconds = (INT4)floor((t0+ii*(Tcoh-SFToverlap)+0.5*Tcoh - floor(t0+ii*(Tcoh-SFToverlap)+0.5*Tcoh))*1e9); if (ii==0) { LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); Vmax = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); } else { LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 V = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); if (V > Vmax) Vmax = V; } /* if ii==0 else ... */ } /* for ii < numffts */ return Vmax; } /* CompDetectorVmax() */
/** * Compute the largest magnitude of antenna velocity * \param [in] t0 Start time (GPS seconds) * \param [in] Tsft Coherence length of the SFTs (in seconds) * \param [in] SFToverlap Overlap of the SFTs (in seconds) * \param [in] Tobs Observation time (in seconds) * \param [in] det A LALDetector struct * \param [in] edat Pointer to EphemerisData * \return Maximum magnitude of antenna velocity */ REAL4 CompDetectorVmax(const REAL8 t0, const REAL8 Tsft, const REAL8 SFToverlap, const REAL8 Tobs, const LALDetector det, EphemerisData *edat) { XLAL_CHECK( edat != NULL, XLAL_EINVAL ); INT4 numffts = (INT4)floor(Tobs/(Tsft-SFToverlap)-1); //Number of FFTs LALStatus XLAL_INIT_DECL(status); LIGOTimeGPS gpstime = LIGOTIMEGPSZERO; gpstime.gpsSeconds = (INT4)floor(t0 + 0.5*Tsft); gpstime.gpsNanoSeconds = (INT4)floor((t0+0.5*Tsft - floor(t0+0.5*Tsft))*1e9); REAL8 detvel[3]; LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 Vmax = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); for (INT4 ii=1; ii<numffts; ii++) { gpstime.gpsSeconds = (INT4)floor(t0 + ii*(Tsft-SFToverlap) + 0.5*Tsft); gpstime.gpsNanoSeconds = (INT4)floor((t0+ii*(Tsft-SFToverlap)+0.5*Tsft - floor(t0+ii*(Tsft-SFToverlap)+0.5*Tsft))*1e9); LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 V = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); if (V > Vmax) Vmax = V; } /* for ii < numffts */ return Vmax; } /* CompDetectorVmax() */
/** * Compute the maximum change in antenna velocity * \param [in] t0 Start time (GPS seconds) * \param [in] Tsft Coherence length of the SFTs (in seconds) * \param [in] SFToverlap Overlap of the SFTs (in seconds) * \param [in] Tobs Observation time (in seconds) * \param [in] det A LALDetector struct * \param [in] edat Pointer to EphemerisData * \return Maximum change in antenna velocity */ REAL4 CompDetectorDeltaVmax(const REAL8 t0, const REAL8 Tsft, const REAL8 SFToverlap, const REAL8 Tobs, const LALDetector det, EphemerisData *edat) { XLAL_CHECK( edat != NULL, XLAL_EINVAL ); INT4 numffts = (INT4)floor(Tobs/(Tsft-SFToverlap)-1); //Number of FFTs LALStatus XLAL_INIT_DECL(status); REAL8 detvel[3], detvel0[3], dv[3]; REAL4 deltaVmax = 0.0; for (INT4 ii=0; ii<numffts; ii++) { LIGOTimeGPS gpstime = LIGOTIMEGPSZERO; gpstime.gpsSeconds = (INT4)floor(t0 + ii*(Tsft-SFToverlap) + 0.5*Tsft); gpstime.gpsNanoSeconds = (INT4)floor((t0+ii*(Tsft-SFToverlap)+0.5*Tsft - floor(t0+ii*(Tsft-SFToverlap)+0.5*Tsft))*1e9); if (ii==0) { LALDetectorVel(&status, detvel0, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); } else { LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); dv[0] = detvel[0] - detvel0[0]; dv[1] = detvel[1] - detvel0[1]; dv[2] = detvel[2] - detvel0[2]; REAL4 deltaV = (REAL4)sqrt(dv[0]*dv[0] + dv[1]*dv[1] + dv[2]*dv[2]); if (deltaV > deltaVmax) deltaVmax = deltaV; } /* if ii==0 else ... */ } /* for ii < numffts */ return deltaVmax; } /* CompDetectorDeltaVmax() */
/*-------------------------------------------------- * extend the previous definition to an SFT-vector * this is simply the sum of individual SFT-products *--------------------------------------------------*/ REAL4 scalarProductSFTVector ( const SFTVector *sftvect1, const SFTVector *sftvect2 ) { XLAL_CHECK_REAL4 ( (sftvect1 != NULL) && (sftvect2 != NULL), XLAL_EINVAL ); XLAL_CHECK_REAL4 ( sftvect1->length == sftvect2->length, XLAL_EINVAL ); REAL8 prod = 0; for ( UINT4 i=0; i < sftvect1->length; i++ ) { REAL4 xy = scalarProductSFT ( &(sftvect1->data[i]), &(sftvect2->data[i]) ); prod += (REAL8) xy; } return (REAL4)prod; } /* scalarProductSFTVector() */
/** * Deprecated function to compute Line Veto statistics from multi- and single-detector \f$ \mathcal{F} \f$-stats, * using outdated \f$ \rho \f$ notation and prior normalization. * This is not the log-Bayes-factor! * \f$ \mathrm{LV} = \mathcal{F} - \log \left( \frac{\rho_{\mathrm{max,line}}^4}{70} + \sum_X l^X e^{\mathcal{F}^X} \right) \f$ * * \deprecated use XLALComputeBSGL() instead. * * Implemented by log sum exp formula: * \f$ \mathrm{LV} = \mathcal{F} - \max(\mathrm{denom. terms}) - \log \left( \sum e^{\mathrm{denom. terms}-\max} \right) \f$. * * From the analytical derivation, there should be an extra term \f$ + o_{SN} + 4 \log \left( \frac{\rho_{\mathrm{max,line}}}{\rho_{\mathrm{max,sig}}} \right) \f$, * but this is irrelevant for toplist sorting, only a normalization which can be replaced arbitrarily. * * NOTE: priors logRhoTerm, loglX have to be logarithmized already. */ REAL4 XLALComputeLineVetoArray ( const REAL4 TwoF, /**< multi-detector \f$ \mathcal{F} \f$-stat */ const UINT4 numDetectors, /**< number of detectors */ const REAL4 *TwoFX, /**< array of single-detector \f$ \mathcal{F} \f$-stats */ const REAL8 logRhoTerm, /**< extra term coming from prior normalization: \f$ \log \left( \frac{\rho_{\mathrm{max,line}}^4}{70} \right) \f$ */ const REAL8 *loglX, /**< array of logs of single-detector prior line odds ratios, default to \f$ \log(l^X)=\log(1)=0 \f$ for all \f$ X \f$ if NULL */ const BOOLEAN useAllTerms /**< only use leading term (FALSE) or all terms (TRUE) in log sum exp formula? */ ) { /* check input parameters and report errors */ XLAL_CHECK_REAL4 ( TwoF && TwoFX, XLAL_EFAULT, "Empty TwoF or TwoFX pointer as input parameter." ); /* set up temporary variables and structs */ REAL4 log0 = - LAL_REAL4_MAX; /* approximates -inf */ REAL4 maxInSum = log0; /* keep track of largest summand in denominator, for logsumexp formula below */ REAL4 FXprior[numDetectors]; /* FXprior equiv log(lX * e^(FX)) = FX + loglX */ for (UINT4 X = 0; X < numDetectors; X++) { FXprior[X] = 0.5 * TwoFX[X]; if (loglX) { /* if no priors given, just use lX=1 => loglX=0 for all X => do not add anything */ FXprior[X] += loglX[X]; } /* keep track of maximum value in denominator sum */ if ( FXprior[X] > maxInSum ) { maxInSum = FXprior[X]; } } /* for X < numDetectors */ /* special treatment for additional denominator term 'rho^4/70' */ if ( logRhoTerm > maxInSum ) { maxInSum = logRhoTerm; } REAL4 LV = 0.0; /* output variable for Line Veto statistics */ LV = 0.5 * TwoF - maxInSum; /* dominant term to LV-statistic */ if ( useAllTerms ) { /* optionally add logsumexp term (possibly negligible in many cases) */ REAL4 extraSum=0; /* will be: e^[-(maxInSum - logRhoTerm)] + sum_X e^[ -(maxInSum - FXprior) ] >= 1 */ /* need to treat (rho^4/70) term separately */ extraSum += exp ( logRhoTerm - maxInSum ); /* now add all FX-contributions */ for (UINT4 X = 0; X < numDetectors; X++) { extraSum += exp ( FXprior[X] - maxInSum ); } LV -= log ( extraSum ); } /* if useAllTerms */ return LV; } /* XLALComputeLineVetoArray() */
/** * Deprecated function to compute Line Veto statistics from multi- and single-detector \f$ \mathcal{F} \f$-stats, * using outdated \f$ \rho \f$ notation and prior normalization. * This is not the log-Bayes-factor! * \f$ \mathrm{LV} = \mathcal{F} - \log \left( \frac{\rho_{\mathrm{max,line}}^4}{70} + \sum_X l^X e^{\mathcal{F}^X} \right) \f$ * * \deprecated use XLALComputeBSGL() instead. * * Also this is just a wrapper for XLALComputeLineVetoArray, which is faster for many LV values at identical priors. * This function here just translates REAL4Vectors to fixed REAL4 arrays, * and linear priors rhomaxline and lX to logarithmic values. */ REAL4 XLALComputeLineVeto ( const REAL4 TwoF, /**< multi-detector \f$ \mathcal{F} \f$-stat */ const REAL4Vector *TwoFXvec, /**< vector of single-detector \f$ \mathcal{F} \f$-stats */ const REAL8 rhomaxline, /**< amplitude prior normalization for lines */ const REAL8Vector *lXvec, /**< vector of single-detector prior line odds ratio, default to \f$ l^X=1 \f$ for all \f$ X \f$ if NULL */ const BOOLEAN useAllTerms /**< only use leading term (FALSE) or all terms (TRUE) in log sum exp formula? */ ) { /* check input parameters and report errors */ XLAL_CHECK_REAL4 ( TwoF && TwoFXvec && TwoFXvec->data, XLAL_EFAULT, "Empty TwoF or TwoFX pointer as input parameter." ); UINT4 numDetectors = TwoFXvec->length; XLAL_CHECK_REAL4 ( !lXvec || ( lXvec->length == numDetectors ), XLAL_EBADLEN, "Input lX (%d) and TwoFX (%d) vectors have different lengths.", lXvec->length, numDetectors ); XLAL_CHECK_REAL4 ( rhomaxline >= 0, XLAL_EDOM, "Negative prior range 'rhomaxline' = %g. Must be >= 0!", rhomaxline ); REAL8 logRhoTerm = 0.0; if ( rhomaxline > 0.0 ) { logRhoTerm = 4.0 * log(rhomaxline) - log(70.0); } else { /* if rhomaxline == 0.0, logRhoTerm should become irrelevant in summation */ logRhoTerm = - LAL_REAL8_MAX; } REAL8 *loglX = NULL; REAL8 loglXtemp[numDetectors]; if ( lXvec ) { for (UINT4 X = 0; X < numDetectors; X++) { if ( lXvec->data[X] > 0 ) { loglXtemp[X] = log(lXvec->data[X]); } else if ( lXvec->data[X] == 0 ) { /* if zero prior ratio, approximate log(0)=-inf by -LAL_REAL4_MAX to avoid raising underflow exceptions */ loglXtemp[X] = - LAL_REAL8_MAX; } else { /* negative prior ratio is a mistake! */ XLAL_ERROR_REAL4 ( XLAL_EDOM, "Negative input prior-ratio for detector X=%d: lX[X]=%g\n", X, lXvec->data[X] ); } } /* for X < numDetectors */ loglX = loglXtemp; } /* if lXvec */ REAL4 LV = XLALComputeLineVetoArray ( TwoF, numDetectors, TwoFXvec->data, logRhoTerm, loglX, useAllTerms ); return LV; } /* XLALComputeLineVeto() */
/*-------------------------------------------------- * implements a straightforward L2 scalar product of * two time-series x_i and y_i : x*y = sum_i x_i y_i * in Fourier-space, which is 2/N * Re( sum_i X_i Y*_i) *--------------------------------------------------*/ REAL4 scalarProductSFT ( const SFTtype *sft1, const SFTtype *sft2 ) { XLAL_CHECK_REAL4 ( (sft1 != NULL) && (sft2 != NULL), XLAL_EINVAL ); XLAL_CHECK_REAL4 ( sft1->data->length == sft2->data->length, XLAL_EINVAL ); /* we do the calculation in REAL8 to avoid accumulating roundoff-errors */ REAL8 prod = 0; for ( UINT4 i=0; i < sft1->data->length; i++ ) { REAL8 xre = (REAL8)crealf(sft1->data->data[i]); REAL8 xim = (REAL8)cimagf(sft1->data->data[i]); REAL8 yre = (REAL8)crealf(sft2->data->data[i]); REAL8 yim = (REAL8)cimagf(sft2->data->data[i]); prod += xre * yre + xim * yim; } /* for i < SFT-length */ prod *= 2.0 / ((REAL8)sft1->data->length); return (REAL4) prod; } /* scalarProductSFT() */
/** * Compute the largest magnitude of antenna velocity * \param [in] t0 Start time (GPS seconds) * \param [in] Tsft Coherence length of the SFTs (in seconds) * \param [in] SFToverlap Overlap of the SFTs (in seconds) * \param [in] Tobs Observation time (in seconds) * \param [in] det A LALDetector struct * \param [in] edat Pointer to EphemerisData * \return Maximum magnitude of antenna velocity */ REAL4 CompDetectorVmax(const REAL8 t0, const REAL8 Tsft, const REAL8 SFToverlap, const REAL8 Tobs, const LALDetector det, EphemerisData *edat) { XLAL_CHECK( edat != NULL, XLAL_EINVAL ); INT4 numffts = (INT4)floor(Tobs/(Tsft-SFToverlap)-1); //Number of FFTs LALStatus XLAL_INIT_DECL(status); LIGOTimeGPS gpstime = LIGOTIMEGPSZERO; gpstime.gpsSeconds = (INT4)floor(t0 + 0.5*Tsft); gpstime.gpsNanoSeconds = (INT4)floor((t0+0.5*Tsft - floor(t0+0.5*Tsft))*1e9); REAL8 detvel[3]; LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 Vmax = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); for (INT4 ii=1; ii<numffts; ii++) { gpstime.gpsSeconds = (INT4)floor(t0 + ii*(Tsft-SFToverlap) + 0.5*Tsft); gpstime.gpsNanoSeconds = (INT4)floor((t0+ii*(Tsft-SFToverlap)+0.5*Tsft - floor(t0+ii*(Tsft-SFToverlap)+0.5*Tsft))*1e9); LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 V = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); if (V > Vmax) Vmax = V; } /* for ii < numffts */ return Vmax; } /* CompDetectorVmax() */ REAL4 CompDetectorVmax2(const LIGOTimeGPSVector *timestamps, const LALDetector det, EphemerisData *edat) { XLAL_CHECK( timestamps!=NULL && edat != NULL, XLAL_EINVAL ); LALStatus XLAL_INIT_DECL(status); LIGOTimeGPS gpstime = timestamps->data[0]; REAL8 detvel[3]; LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 Vmax = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); for (UINT4 ii=1; ii<timestamps->length; ii++) { gpstime = timestamps->data[ii]; LALDetectorVel(&status, detvel, &gpstime, det, edat); XLAL_CHECK_REAL4( status.statusCode == 0, XLAL_EFUNC ); REAL4 V = (REAL4)sqrt(detvel[0]*detvel[0] + detvel[1]*detvel[1] + detvel[2]*detvel[2]); if (V > Vmax) Vmax = V; } /* for ii < numffts */ return Vmax; }