/** Initialize amplitude-prior pdfs from the user-input */ int XLALInitAmplitudePrior ( AmplitudePrior_t *AmpPrior, const UserInput_t *uvar ) { const UINT4 AmpPriorBins = 100; // defines the binnning accuracy of our prior-pdfs /* consistency check */ if ( !AmpPrior || !uvar ) { XLALPrintError ( "%s: invalid NULL input 'AmpPrior' or 'uvar'\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } if ( AmpPrior->pdf_h0Nat || AmpPrior->pdf_cosi || AmpPrior->pdf_psi || AmpPrior->pdf_phi0 ) { XLALPrintError ("%s: AmplitudePriors must be set to NULL before calling this function!\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } /* first check that user only provided *one* method of determining the amplitude-prior range */ UINT4 numSets = 0; if ( uvar->fixedh0Nat >= 0 ) numSets ++; if ( uvar->fixedSNR >= 0 ) numSets ++; if ( uvar->fixedh0NatMax >= 0 ) numSets ++ ; if ( uvar->fixedRhohMax >= 0 ) numSets ++; if ( numSets != 1 ) { XLALPrintError ("%s: Specify (>=0) exactly *ONE* amplitude-prior range of {fixedh0Nat, fixedSNR, fixedh0NatMax, fixedRhohMax}\n", __func__); XLAL_ERROR ( XLAL_EINVAL ); } /* ===== first pass: deal with all user-supplied fixed values ==> singular priors! ===== */ /* ----- h0 ----- */ if ( uvar->fixedh0Nat >= 0 ) /* fix h0Nat */ if ( (AmpPrior->pdf_h0Nat = XLALCreateSingularPDF1D ( uvar->fixedh0Nat )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); if ( uvar->fixedSNR >= 0 ) /* dummy-pdf, as signal will be computed with h0Nat=1 then rescaled to fixedSNR */ if ( (AmpPrior->pdf_h0Nat = XLALCreateSingularPDF1D ( 1.0 )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); AmpPrior->fixedSNR = uvar->fixedSNR; AmpPrior->fixRhohMax = (uvar->fixedRhohMax >= 0); /* ----- cosi ----- */ if ( XLALUserVarWasSet ( &uvar->cosi ) ) if ( (AmpPrior->pdf_cosi = XLALCreateSingularPDF1D ( uvar->cosi )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- psi ----- */ if ( XLALUserVarWasSet ( &uvar->psi ) ) if ( (AmpPrior->pdf_psi = XLALCreateSingularPDF1D ( uvar->psi )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- phi0 ----- */ if ( XLALUserVarWasSet ( &uvar->phi0 ) ) if ( (AmpPrior->pdf_phi0 = XLALCreateSingularPDF1D ( uvar->phi0 )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ===== second pass: deal with non-singular prior ranges, taking into account the type of priors to use */ REAL8 h0NatMax = 0; if ( uvar->fixedh0NatMax >= 0 ) /* draw h0Nat from [0, h0NatMax] */ h0NatMax = uvar->fixedh0NatMax; if ( uvar->fixedRhohMax >= 0 ) /* draw h0 from [0, rhohMax/(detM)^(1/8)] */ h0NatMax = uvar->fixedRhohMax; /* at first, will be rescaled by (detM)^(1/8) after the fact */ switch ( uvar->AmpPriorType ) { case AMP_PRIOR_TYPE_PHYSICAL: /* ----- h0 ----- */ // uniform in [0, h0NatMax] : not that 'physical', but simple if ( AmpPrior->pdf_h0Nat == NULL ) if ( (AmpPrior->pdf_h0Nat = XLALCreateUniformPDF1D ( 0, h0NatMax )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- cosi ----- */ if ( AmpPrior->pdf_cosi == NULL ) if ( (AmpPrior->pdf_cosi = XLALCreateUniformPDF1D ( -1.0, 1.0 )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- psi ----- */ if ( AmpPrior->pdf_psi == NULL ) if ( (AmpPrior->pdf_psi = XLALCreateUniformPDF1D ( -LAL_PI_4, LAL_PI_4 )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- phi0 ----- */ if ( AmpPrior->pdf_phi0 == NULL ) if ( (AmpPrior->pdf_phi0 = XLALCreateUniformPDF1D ( 0, LAL_TWOPI )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); break; case AMP_PRIOR_TYPE_CANONICAL: /* ----- pdf(h0) ~ h0^3 ----- */ if ( AmpPrior->pdf_h0Nat == NULL ) { UINT4 i; pdf1D_t *pdf; if ( ( pdf = XLALCreateDiscretePDF1D ( 0, h0NatMax, AmpPriorBins )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); for ( i=0; i < pdf->probDens->length; i ++ ) { REAL8 xMid = 0.5 * ( pdf->xTics->data[i] + pdf->xTics->data[i+1] ); pdf->probDens->data[i] = CUBE( xMid ); // pdf(h0) ~ h0^3 } AmpPrior->pdf_h0Nat = pdf; } /* ----- pdf(cosi) ~ ( 1 - cosi^2)^3 ----- */ if ( AmpPrior->pdf_cosi == NULL ) { UINT4 i; pdf1D_t *pdf; if ( ( pdf = XLALCreateDiscretePDF1D ( -1.0, 1.0, AmpPriorBins )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); for ( i=0; i < pdf->probDens->length; i ++ ) { REAL8 xMid = 0.5 * ( pdf->xTics->data[i] + pdf->xTics->data[i+1] ); REAL8 y = 1.0 - SQ(xMid); pdf->probDens->data[i] = CUBE( y ); } AmpPrior->pdf_cosi = pdf; } /* ----- psi ----- */ if ( AmpPrior->pdf_psi == NULL ) if ( (AmpPrior->pdf_psi = XLALCreateUniformPDF1D ( -LAL_PI_4, LAL_PI_4 )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- phi0 ----- */ if ( AmpPrior->pdf_phi0 == NULL ) if ( (AmpPrior->pdf_phi0 = XLALCreateUniformPDF1D ( 0, LAL_TWOPI )) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); break; default: XLALPrintError ("%s: something went wrong ... unknown priorType = %d\n", __func__, uvar->AmpPriorType ); XLAL_ERROR ( XLAL_EINVAL ); break; } // switch( uvar->AmpPriorType ) return XLAL_SUCCESS; } /* XLALInitAmplitudePrior() */
/** * Compute transient-CW posterior (normalized) on timescale tau, using given type and parameters * of transient window range. * * NOTE: the returned pdf has a number of sample-points N_tauRange given by the size * of the input matrix FstatMap (namely N_tauRange = tauBand / dtau) * */ pdf1D_t * XLALComputeTransientPosterior_tau ( transientWindowRange_t windowRange, /**< [in] type and parameters specifying transient window range */ const transientFstatMap_t *FstatMap /**< [in] pre-computed transient-Fstat map F_mn over {t0, tau} ranges */ ) { /* ----- check input consistency */ if ( !FstatMap || !FstatMap->F_mn ) { XLALPrintError ("%s: invalid NULL input 'FstatMap' or 'FstatMap->F_mn'\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( windowRange.type >= TRANSIENT_LAST ) { XLALPrintError ("%s: unknown window-type (%d) passes as input. Allowed are [0,%d].\n", __func__, windowRange.type, TRANSIENT_LAST-1); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* ----- step through F_mn array subtract maxF and sum e^{F_mn - maxF}*/ /* * It is numerically more robust to marginalize over e^(F_mn - Fmax), which at worst can underflow, while * e^F_mn can overflow (for F>~700). The constant offset e^Fmax is irrelevant for posteriors (normalization constant). */ UINT4 N_t0Range = FstatMap->F_mn->size1; UINT4 N_tauRange = FstatMap->F_mn->size2; REAL8 tau0 = windowRange.tau; REAL8 tau1 = tau0 + windowRange.tauBand; pdf1D_t *ret; /* ----- handle special cases: 1) point-like support, 2) uniform pdf-value over 1 bin ----- */ if ( N_tauRange == 1 && (windowRange.tauBand == 0) ) { if ( (ret = XLALCreateSingularPDF1D ( tau0 )) == NULL ) { XLALPrintError ("%s: failed to create singular pdf for tau0 = %g\n", __func__, tau0 ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } return ret; } /* if singular pdf in tau */ if ( (N_tauRange == 1) && (windowRange.tauBand > 0) ) { if ( (ret = XLALCreateUniformPDF1D ( tau0, tau1 )) == NULL ) { XLALPrintError ( "%s: failed to created unform pdf over [%g, %g]\n", __func__, tau0, tau1 ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } return ret; } /* if uniform pdf over small band tauBand */ /* ----- general N>1 point pdf case ----- */ if ( ( ret = XLALCreateDiscretePDF1D ( tau0, tau1, N_tauRange )) == NULL ) { XLALPrintError ("%s: XLALCreateDiscretePDF1D() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } UINT4 m, n; for ( n=0; n < N_tauRange; n ++ ) /* loop over timescales tau */ { REAL8 sum_eF = 0; for ( m=0; m < N_t0Range; m ++ ) /* loop over start-times t0 */ { REAL8 DeltaF = FstatMap->maxF - gsl_matrix_get ( FstatMap->F_mn, m, n ); // always >= 0, exactly ==0 at {m,n}_max //sum_eB += exp ( - DeltaF ); sum_eF += XLALFastNegExp ( DeltaF ); } /* for m < N_t0Range */ ret->probDens->data[n] = sum_eF; } /* for n < N_tauRange */ /* free mem */ XLALDestroyExpLUT(); /* normalize this PDF */ if ( XLALNormalizePDF1D ( ret ) != XLAL_SUCCESS ) { XLALPrintError ("%s: failed to normalize posterior pdf ..\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* ----- return ----- */ return ret; } /* XLALComputeTransientPosterior_tau() */