/** * Free an UpperLimit structure * \param [in] ul Pointer to an UpperLimit structure */ void free_UpperLimitStruct(UpperLimit *ul) { if (ul->fsig) XLALDestroyREAL8Vector(ul->fsig); if (ul->period) XLALDestroyREAL8Vector(ul->period); if (ul->moddepth) XLALDestroyREAL8Vector(ul->moddepth); if (ul->ULval) XLALDestroyREAL8Vector(ul->ULval); if (ul->effSNRval) XLALDestroyREAL8Vector(ul->effSNRval); } /* free_UpperLimitStruct() */
// test string-vector parsing function XLALParseStringValueAsStringVector() int test_ParseREAL8Vector(void) { const char *csvIn = "0.1,5,-5.1e+99,1.23456789e-99,inf,nan"; REAL8 vals[] = {0.1, 5, -5.1e+99, 1.23456789e-99 }; // only finite values for comparison // parse csv string as REAL8Vector: REAL8Vector *vect1 = NULL; XLAL_CHECK ( XLALParseStringValueAsREAL8Vector ( &vect1, csvIn ) == XLAL_SUCCESS, XLAL_EFUNC ); // test1: re-print as string, compare strings char *csvOut; XLAL_CHECK ( (csvOut = XLALPrintStringValueOfREAL8Vector ( &vect1 )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( strcmp ( csvIn, csvOut ) == 0, XLAL_EFAILED, "csvIn != csvOut:\ncsvIn = %s\ncsvOut = %s\n", csvIn, csvOut ); // test2: compare finite parsed values: for ( UINT4 i = 0; i < 4; i ++ ) { XLAL_CHECK ( vect1->data[i] == vals[i], XLAL_EFAILED, "Parsed %d-th value differs from input: %.16g != %.16g\n", i, vect1->data[i], vals[i] ); } // check non-finite values XLAL_CHECK ( fpclassify ( vect1->data[4] ) == FP_INFINITE, XLAL_EFAILED, "Failed to parse 'inf'\n"); XLAL_CHECK ( fpclassify ( vect1->data[5] ) == FP_NAN, XLAL_EFAILED, "Failed to parse 'nan'\n"); // clean up memory XLALFree ( csvOut ); XLALDestroyREAL8Vector ( vect1 ); return XLAL_SUCCESS; } // test_ParseREAL8Vector()
/** (Complex)Sinc-interpolate an input SFT to an output SFT. * This is a simple convenience wrapper to XLALSincInterpolateCOMPLEX8FrequencySeries() * for the special case of interpolating onto new SFT frequency bins */ SFTtype * XLALSincInterpolateSFT ( const SFTtype *sft_in, ///< [in] input SFT REAL8 f0Out, ///< [in] new start frequency REAL8 dfOut, ///< [in] new frequency step-size UINT4 numBinsOut, ///< [in] new number of bins UINT4 Dterms ///< [in] truncate interpolation kernel sum to +-Dterms around max ) { XLAL_CHECK_NULL ( sft_in != NULL, XLAL_EINVAL ); XLAL_CHECK_NULL ( dfOut > 0, XLAL_EINVAL ); XLAL_CHECK_NULL ( numBinsOut > 0, XLAL_EINVAL ); // setup frequency vector REAL8Vector *f_out; XLAL_CHECK_NULL ( (f_out = XLALCreateREAL8Vector ( numBinsOut )) != NULL, XLAL_EFUNC ); for ( UINT4 k = 0; k < numBinsOut; k ++ ) { f_out->data[k] = f0Out + k * dfOut; } // for k < numBinsOut SFTtype *out; XLAL_CHECK_NULL ( (out = XLALCalloc ( 1, sizeof(*out))) != NULL, XLAL_EFUNC ); (*out) = (*sft_in); // copy header out->f0 = f0Out; out->deltaF = dfOut; XLAL_CHECK_NULL ( (out->data = XLALCreateCOMPLEX8Vector ( numBinsOut )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( XLALSincInterpolateCOMPLEX8FrequencySeries ( out->data, f_out, sft_in, Dterms ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyREAL8Vector ( f_out ); return out; } // XLALSincInterpolateSFT()
void XLALSQTPNDestroyCoherentGW(CoherentGW *wave) { //static const char *func = "LALSQTPNDestroyCoherentGW"; if (wave->a) { if (wave->a->data) { XLALDestroyREAL4VectorSequence(wave->a->data); } XLALFree(wave->a); } if (wave->f) { if (wave->f->data) { XLALDestroyREAL4Vector(wave->f->data); } XLALFree(wave->f); } if (wave->phi) { if (wave->phi->data) { XLALDestroyREAL8Vector(wave->phi->data); } XLALFree(wave->phi); } if (wave->shift) { if (wave->shift->data) { XLALDestroyREAL4Vector(wave->shift->data); } XLALFree(wave->shift); } }
static void destroyCoherentGW( CoherentGW *waveform ) { if ( waveform->h ) { XLALDestroyREAL4VectorSequence( waveform->h->data ); LALFree( waveform->a ); } if ( waveform->a ) { XLALDestroyREAL4VectorSequence( waveform->a->data ); LALFree( waveform->a ); } if ( waveform->phi ) { XLALDestroyREAL8Vector( waveform->phi->data ); LALFree( waveform->phi ); } if ( waveform->f ) { XLALDestroyREAL4Vector( waveform->f->data ); LALFree( waveform->f ); } if ( waveform->shift ) { XLALDestroyREAL4Vector( waveform->shift->data ); LALFree( waveform->shift ); } return; }
int main( int argc, char *argv[]) { /* sanity check for input arguments */ if ( argc != 1 ) XLAL_ERROR ( XLAL_EINVAL, "The executable '%s' doesn't support any input arguments right now.\n", argv[0] ); printf ("Starting test...\n"); /* set up single- and multi-IFO F-stat input */ REAL4 TwoF = 7.0; UINT4 numDetectors = 2; REAL4Vector *TwoFX = NULL; if ( (TwoFX = XLALCreateREAL4Vector ( numDetectors )) == NULL ) { XLAL_ERROR ( XLAL_EFUNC, "failed to XLALCreateREAL4Vector( %d )\n", numDetectors ); return XLAL_EFAILED; } TwoFX->data[0] = 4.0; TwoFX->data[1] = 12.0; REAL8 rhomaxline = 0.0; /* prior from LV-stat derivation, 0 means pure line veto, +inf means pure multi-Fstat */ REAL8Vector *lX = NULL; /* per-IFO prior odds ratio for line vs. Gaussian noise, NULL is interpreted as l[X]=1 for all X */ /* maximum allowed difference between recalculated and XLAL result */ REAL4 tolerance_allterms = 2e-04; REAL4 tolerance_leadterm = 2e-02; /* compute and compare the results for one set of rhomaxline, lX values */ printf ("Computing LV-stat for TwoF_multi=%f, TwoFX[0]=%f, TwoFX[1]=%f, rhomaxline=%f, priors lX=NULL...\n", TwoF, TwoFX->data[0], TwoFX->data[1], rhomaxline ); if ( XLALCompareLVComputations( TwoF, TwoFX, rhomaxline, lX, tolerance_allterms, tolerance_leadterm ) != XLAL_SUCCESS ) { XLAL_ERROR ( XLAL_EFUNC, "Test failed.\n" ); return XLAL_EFAILED; } /* change the priors to catch more possible problems */ rhomaxline = 5.0; if ( (lX = XLALCreateREAL8Vector ( numDetectors )) == NULL ) { XLAL_ERROR ( XLAL_EFUNC, "failed to XLALCreateREAL8Vector( %d )\n", numDetectors ); return XLAL_EFAILED; } lX->data[0] = 0.5; lX->data[1] = 0.8; /* compute and compare the results for second set of rhomaxline, lX values */ printf ("Computing LV-stat for TwoF_multi=%f, TwoFX[0]=%f, TwoFX[1]=%f, rhomaxline=%f, priors lX=(%f,%f)...\n", TwoF, TwoFX->data[0], TwoFX->data[1], rhomaxline, lX->data[0], lX->data[1] ); if ( XLALCompareLVComputations( TwoF, TwoFX, rhomaxline, lX, tolerance_allterms, tolerance_leadterm ) != XLAL_SUCCESS ) { XLAL_ERROR ( XLAL_EFUNC, "Test failed.\n" ); return XLAL_EFAILED; } /* free memory */ XLALDestroyREAL4Vector(TwoFX); XLALDestroyREAL8Vector(lX); LALCheckMemoryLeaks(); return XLAL_SUCCESS; } /* main */
/** Destructor for internal configuration struct */ int XLALDestroyConfig ( ConfigVariables *cfg ) { XLAL_CHECK ( cfg != NULL, XLAL_EINVAL ); XLALDestroyUserVars (); XLALDestroyREAL8Vector ( cfg->Alpha ); XLALDestroyREAL8Vector ( cfg->Delta ); XLALDestroyMultiTimestamps ( cfg->multiTimestamps ); XLALDestroyUINT4Vector ( cfg->numTimeStampsX ); XLALDestroyEphemerisData ( cfg->edat ); XLALDestroyMultiDetectorStateSeries ( cfg->multiDetStates ); XLALDestroyMultiNoiseWeights ( cfg->multiNoiseWeights ); return XLAL_SUCCESS; } /* XLALDestroyConfig() */
/** * Test function to compute BSGL values from: * XLALComputeBSGL, from scratch * and from deprecated XLALComputeLineVeto and XLALComputeLineVetoArray * compare the results and exit if tolerance is violated. */ int XLALCompareBSGLComputations ( const REAL4 TwoF, /**< multi-detector Fstat */ const UINT4 numDetectors, /**< number of detectors */ const REAL4Vector *TwoFX, /**< vector of single-detector Fstats */ const REAL4 Fstar0, /**< amplitude prior normalization for lines */ const REAL4 *oLGX, /**< array of single-detector prior line odds ratio, can be NULL */ const REAL4 tolerance /**< tolerance for comparisons */ ) { /* conversions between old (rho) and new (F*) notation, REAL4 and REAL8 */ REAL8 LVrho = exp( 0.25 * ( Fstar0 + log(70.0) ) ); REAL4 oLG = 0.0; REAL8Vector *oLGXREAL8 = NULL; XLAL_CHECK ( (oLGXREAL8 = XLALCreateREAL8Vector ( numDetectors )) != NULL, XLAL_EFUNC ); if ( oLGX ) { for ( UINT4 X = 0; X < numDetectors; X++ ) { oLGXREAL8->data[X] = (REAL8)oLGX[X]; oLG += oLGX[X]; } } else { /* if oLGX == NULL, assume oLGX=1/numDetectors for all X ==> oLG = sumX oLGX = 1*/ oLG = 1.0; for (UINT4 X = 0; X < numDetectors; X++) { oLGXREAL8->data[X] = 1.0/numDetectors; /* need to set this manually, as old functions still assume oLGX=1 instead */ } } // if ( oLGX == NULL ) /* further parameter pre-conversions for XLALComputeLineVetoArray() */ REAL8 logRhoTerm = Fstar0; REAL8 logoLGX[numDetectors]; for (UINT4 X = 0; X < numDetectors; X++) { logoLGX[X] = log(oLGXREAL8->data[X]); } /* compute BSGL "the pedestrian way", from Eq. (40) of Keitel, Prix, Papa, Leaci, Siddiqi, PR D 89, 064023 (2014), * explicit formula for numDet=2: * log10 BSGL = F - log ( e^F* + e^{F1}*oLG1/oLG + e^{F2}*oLG2/oLG ) */ REAL8 BSGL_extcomp_terms[3]; BSGL_extcomp_terms[0] = exp(Fstar0)/oLG; REAL8 BSGL_extcomp_maxterm = BSGL_extcomp_terms[0]; for (UINT4 X = 0; X < numDetectors; X++) { BSGL_extcomp_terms[1+X] = exp(0.5*TwoFX->data[X]); if ( oLGX ) { BSGL_extcomp_terms[1+X] *= oLGX[X]/oLG; } else { /* oLGX=NULL is interpreted as oLGX[X]=1/numDetectors=0.5 for all X ==> oLG=1 */ BSGL_extcomp_terms[1+X] *= 0.5/oLG; } if ( BSGL_extcomp_terms[1+X] > BSGL_extcomp_maxterm ) { BSGL_extcomp_maxterm = BSGL_extcomp_terms[1+X]; } } REAL4 log10BSGL_extcomp_notallterms = 0.5*TwoF - log(BSGL_extcomp_maxterm); REAL8 BSGL_extcomp_denom = 0.0; for (UINT4 X = 0; X < 1+numDetectors; X++) { BSGL_extcomp_denom += BSGL_extcomp_terms[X]; } REAL4 log10BSGL_extcomp_allterms = 0.5*TwoF - log( BSGL_extcomp_denom ); /* these are not the log-Bayes-factor, as computed by XLALComputeBSGL(), so need to correct by log(1+1/oLG) */ log10BSGL_extcomp_allterms += log(1+1/oLG); log10BSGL_extcomp_notallterms += log(1+1/oLG); /* and actually switch to log10 */ log10BSGL_extcomp_allterms *= LAL_LOG10E; log10BSGL_extcomp_notallterms *= LAL_LOG10E; /* faster version: use only the leading term of the BSGL denominator sum */ BSGLSetup *setup_noLogCorrection; XLAL_CHECK ( (setup_noLogCorrection = XLALCreateBSGLSetup ( numDetectors, Fstar0, oLGX, FALSE )) != NULL, XLAL_EFUNC ); REAL4 log10BSGL_XLAL_notallterms = XLALComputeBSGL ( TwoF, TwoFX->data, setup_noLogCorrection ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeBSGL() failed with xlalErrno = %d\n", xlalErrno ); XLALFree ( setup_noLogCorrection ); setup_noLogCorrection = NULL; /* more precise version: use all terms of the BSGL denominator sum */ BSGLSetup *setup_withLogCorrection; XLAL_CHECK ( (setup_withLogCorrection = XLALCreateBSGLSetup ( numDetectors, Fstar0, oLGX, TRUE )) != NULL, XLAL_EFUNC ); REAL4 log10BSGL_XLAL_allterms = XLALComputeBSGL ( TwoF, TwoFX->data, setup_withLogCorrection ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeBSGL() failed with xlalErrno = %d\n", xlalErrno ); XLALFree ( setup_withLogCorrection ); setup_withLogCorrection = NULL; /* compute relative deviations */ REAL4 diff_allterms = fabs( log10BSGL_XLAL_allterms - log10BSGL_extcomp_allterms ) / ( 0.5 * ( log10BSGL_XLAL_allterms + log10BSGL_extcomp_allterms )); REAL4 diff_notallterms = fabs( log10BSGL_XLAL_notallterms - log10BSGL_extcomp_notallterms ) / ( 0.5 * ( log10BSGL_XLAL_notallterms + log10BSGL_extcomp_notallterms )); /* output results and deviations and return with error when tolerances are violated */ printf ( "Externally recomputed with allterms: log10BSGL=%f\n", log10BSGL_extcomp_allterms ); printf ( "Externally recomputed with !allterms: log10BSGL=%f\n", log10BSGL_extcomp_notallterms ); printf ( "XLALComputeBSGL() with allterms: log10BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_allterms, diff_allterms ); XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_allterms, tolerance, "XLALComputeBSGL() with useAllTerms=TRUE" ) == XLAL_SUCCESS, XLAL_EFUNC ); printf ( "XLALComputeBSGL() with !allterms: log10BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_notallterms, diff_notallterms ); XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_notallterms, tolerance, "XLALComputeBSGL() with useAllTerms=TRUE" ) == XLAL_SUCCESS, XLAL_EFUNC ); /* also test against deprecated rho-notation functions for consistency * need to correct for different prior parametrization, * log(BSGL_new)=LV_old+log(1+oLG) */ REAL4 old_LV_corr = log(1+oLG); xlalErrno = 0; REAL4 log10BSGL_XLAL_rho_notallterms = XLALComputeLineVeto ( TwoF, TwoFX, LVrho, oLGXREAL8, FALSE ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVeto() failed with xlalErrno = %d\n", xlalErrno ); log10BSGL_XLAL_rho_notallterms += old_LV_corr; log10BSGL_XLAL_rho_notallterms *= LAL_LOG10E; xlalErrno = 0; REAL4 log10BSGL_XLAL_rhoarray_notallterms = XLALComputeLineVetoArray ( TwoF, numDetectors, TwoFX->data, logRhoTerm, logoLGX, FALSE ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVetoArray() failed with xlalErrno = %d\n", xlalErrno ); log10BSGL_XLAL_rhoarray_notallterms += old_LV_corr; log10BSGL_XLAL_rhoarray_notallterms *= LAL_LOG10E; xlalErrno = 0; REAL4 log10BSGL_XLAL_rho_allterms = XLALComputeLineVeto ( TwoF, TwoFX, LVrho, oLGXREAL8, TRUE ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVeto() failed with xlalErrno = %d\n", xlalErrno ); log10BSGL_XLAL_rho_allterms += old_LV_corr; log10BSGL_XLAL_rho_allterms *= LAL_LOG10E; xlalErrno = 0; REAL4 log10BSGL_XLAL_rhoarray_allterms = XLALComputeLineVetoArray ( TwoF, numDetectors, TwoFX->data, logRhoTerm, logoLGX, TRUE ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVetoArray() failed with xlalErrno = %d\n", xlalErrno ); log10BSGL_XLAL_rhoarray_allterms += old_LV_corr; log10BSGL_XLAL_rhoarray_allterms *= LAL_LOG10E; REAL4 diff_rho_allterms = fabs( log10BSGL_XLAL_rho_allterms - log10BSGL_extcomp_allterms ) / ( 0.5 * ( log10BSGL_XLAL_rho_allterms + log10BSGL_extcomp_allterms )); REAL4 diff_rhoarray_allterms = fabs( log10BSGL_XLAL_rhoarray_allterms - log10BSGL_extcomp_allterms ) / ( 0.5 * ( log10BSGL_XLAL_rhoarray_allterms + log10BSGL_extcomp_allterms )); REAL4 diff_rho_notallterms = fabs( log10BSGL_XLAL_rho_notallterms - log10BSGL_extcomp_notallterms ) / ( 0.5 * ( log10BSGL_XLAL_rho_notallterms + log10BSGL_extcomp_notallterms )); REAL4 diff_rhoarray_notallterms = fabs( log10BSGL_XLAL_rhoarray_notallterms - log10BSGL_extcomp_notallterms ) / ( 0.5 * ( log10BSGL_XLAL_rhoarray_notallterms + log10BSGL_extcomp_notallterms )); printf( "Legacy functions with rho-notation, corrected as BSGL_new=LV_old+log(1+oLG)=LV_old+%f:\n", old_LV_corr ); printf ( "XLALComputeLineVeto() with allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rho_allterms, diff_rho_allterms ); XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rho_allterms, tolerance, "XLALComputeLineVeto() with useAllTerms=TRUE" ) == XLAL_SUCCESS, XLAL_EFUNC ); printf ( "XLALComputeLineVetoArray() with allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rhoarray_allterms, diff_rhoarray_allterms ); XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rhoarray_allterms, tolerance, "XLALComputeLineVetoArray() with useAllTerms=TRUE" ) == XLAL_SUCCESS, XLAL_EFUNC ); printf ( "XLALComputeLineVeto() with !allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rho_notallterms, diff_rho_notallterms ); XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rho_notallterms, tolerance, "XLALComputeLineVeto() with useAllTerms=FALSE" ) == XLAL_SUCCESS, XLAL_EFUNC ); printf ( "XLALComputeLineVetoArray() with !allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rhoarray_notallterms, diff_rhoarray_notallterms ); XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rhoarray_notallterms, tolerance, "XLALComputeLineVetoArray() with useAllTerms=FALSE" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyREAL8Vector(oLGXREAL8); return XLAL_SUCCESS; } /* XLALCompareBSGLComputations() */
/** The main function of Intermittent.c * */ int main( int argc, char *argv[] ) { UserInput_t uvar = empty_UserInput; /* user input variables */ INT4 i, k, m; /* counter */ CHAR newtemp[LONGSTRINGLENGTH]; FILE *ifp = NULL; CHAR *clargs = NULL; /* store the command line args */ /**********************************************************************************/ /* register and read all user-variables */ if ( XLALReadUserVars( argc, argv, &uvar ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALReadUserVars() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : read in uservars\n", __func__ ); } /**********************************************************************************/ /* make temporary directory */ if ( uvar.tempdir ) { /* initialise the random number generator - use the clock */ gsl_rng *q; if ( XLALInitgslrand( &q, 0 ) ) { LogPrintf( LOG_CRITICAL, "%s: XLALinitgslrand() failed with error = %d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFAULT ); } INT4 id = ( INT4 )( 1e9 * gsl_rng_uniform( q ) ); sprintf( newtemp, "%s/%09d", uvar.tempdir, id ); fprintf( stdout, "temp dir = %s\n", newtemp ); if ( mkdir( newtemp, 0755 ) ) { if ( uvar.verbose ) { fprintf( stdout, "%s : Unable to make temporary directory %s. Might be a problem.\n", __func__, newtemp ); } return 1; } } /**********************************************************************************/ /* read in the cache file and find the correct entry for the binary file */ FILE *cachefp = NULL; if ( ( cachefp = fopen( uvar.cachefile, "r" ) ) == NULL ) { LogPrintf( LOG_CRITICAL, "%s : failed to open binary input file %s\n", __func__, uvar.cachefile ); return 1; } i = 0; INT4 idx = -1; CHAR filename[LONGSTRINGLENGTH]; CHAR dummy[LONGSTRINGLENGTH]; LIGOTimeGPS fileStart; INT4 dummysec = 0; INT4 dummynan = 0; while ( fscanf( cachefp, "%s %d %d", dummy, &dummysec, &dummynan ) != EOF ) { if ( strstr( dummy, uvar.binfile ) ) { idx = i; strcpy( filename, dummy ); fileStart.gpsSeconds = dummysec; fileStart.gpsNanoSeconds = ( INT4 )1e9 * ( floor( 1e-9 * dummynan / uvar.tsamp + 0.5 ) * uvar.tsamp ); /* round to make sure we get samples at GPS seconds */ } i++; } if ( idx < 0 ) { LogPrintf( LOG_CRITICAL, "%s : failed to find binary input file %s in cache file %s\n", __func__, filename, uvar.cachefile ); return 1; } fclose( cachefp ); if ( uvar.verbose ) { fprintf( stdout, "%s : found the requested binary file entry in the cache file.\n", __func__ ); } /***********************************************************************************/ /* setup the fixed binaryToSFT parameters */ BinaryToSFTparams par; par.tsamp = uvar.tsamp; par.highpassf = uvar.highpassf; par.amp_inj = 0.0; par.f_inj = 0.0; par.asini_inj = 0.0; XLALGPSSetREAL8( &( par.tasc_inj ), 0 ); par.tref = fileStart; par.P_inj = 0; par.phi_inj = 0; par.r = NULL; /* setup the gridding over coherent times - which we make sure are integers */ INT4 dummyT = uvar.Tmin; INT4 NT = 0; while ( dummyT < uvar.Tmax ) { dummyT = ( INT4 )( ( REAL8 )dummyT * ( 1.0 + uvar.mismatch ) ); NT++; } if ( uvar.verbose ) { fprintf( stdout, "%s : Going to do %d different coherent lengths.\n", __func__, NT ); } /**********************************************************************************/ /* OPEN INTERMEDIATE RESULTS FILE */ /**********************************************************************************/ CHAR intname[LONGSTRINGLENGTH]; if ( XLALOpenIntermittentResultsFile( &ifp, intname, newtemp, clargs, &uvar, &fileStart ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALOpenCoherentResultsFile() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : opened coherent results file %s.\n", __func__, intname ); } /**********************************************************************************/ /* loop over the different coherent lengths */ INT4 currentT = uvar.Tmin; for ( i = 0; i < NT; i++ ) { if ( uvar.verbose ) { fprintf( stdout, "%s : working on segment length %d/%d using a segment time of %d sec\n", __func__, i, NT, currentT ); } /* define SFT frequency bounds */ REAL8 wings = LAL_TWOPI * uvar.maxasini / uvar.minorbperiod; REAL8 fmin_read = MINBAND * floor( ( uvar.freq - WINGS_FACTOR * uvar.freq * wings - ( REAL8 )uvar.blocksize / ( REAL8 )uvar.Tmin ) / MINBAND ); REAL8 fmax_read = MINBAND * ceil( ( uvar.freq + ( REAL8 )uvar.blocksize / ( REAL8 )uvar.Tmin + uvar.freqband + WINGS_FACTOR * ( uvar.freq + uvar.freqband ) * wings ) / MINBAND ); REAL8 fband_read = fmax_read - fmin_read; if ( uvar.verbose ) { fprintf( stdout, "%s : reading in SFT frequency band [%f -> %f]\n", __func__, fmin_read, fmax_read ); } /* define the number of different start times */ INT4 Ns = ceil( 1.0 / uvar.mismatch ); INT4 Tstep = ( INT4 )floor( currentT / ( REAL8 )Ns ); if ( Tstep == 0 ) { Ns = 1; } else { Ns = ( INT4 )ceil( ( REAL8 )currentT / ( REAL8 )Tstep ); } if ( uvar.verbose ) { fprintf( stdout, "%s : number of start times is %d and time step is %d sec\n", __func__, Ns, Tstep ); } par.tsft = currentT; par.freq = fmin_read; par.freqband = fband_read; /* loop over different start times - make sure they are integer GPS time for simplicity */ LIGOTimeGPS currentStart; currentStart.gpsSeconds = ( INT4 )ceil( ( REAL8 )fileStart.gpsSeconds + 1e-9 * ( REAL8 )fileStart.gpsNanoSeconds ); currentStart.gpsNanoSeconds = 0; for ( k = 0; k < Ns; k++ ) { if ( uvar.verbose ) { fprintf( stdout, "%s : working on offset start %d/%d using a start time of %d %d sec\n", __func__, k, Ns, currentStart.gpsSeconds, currentStart.gpsNanoSeconds ); } memcpy( &( par.tstart ), ¤tStart, sizeof( LIGOTimeGPS ) ); ParameterSpace pspace = empty_ParameterSpace; /* the search parameter space */ COMPLEX8TimeSeriesArray *dstimevec = NULL; /* contains the downsampled inverse FFT'd SFTs */ REAL4DemodulatedPowerVector *dmpower = NULL; /* contains the demodulated power for all SFTs */ GridParametersVector *freqgridparams = NULL; /* the coherent grid on the frequency derivitive parameter space */ SFTVector *sftvec = NULL; INT8Vector *np = NULL; REAL8Vector *R = NULL; /**********************************************************************************/ /* GENERATE SFTS FROM BINARY INPUT FILE */ /**********************************************************************************/ /* converts a binary input file into sfts */ if ( XLALBinaryToSFTVector( &sftvec, filename, &fileStart, &par, &np, &R ) ) { LogPrintf( LOG_CRITICAL, "%s : failed to convert binary input file %s to sfts\n", __func__, uvar.binfile ); return 1; } XLALDestroyINT8Vector( np ); XLALDestroyREAL8Vector( R ); if ( uvar.verbose ) { fprintf( stdout, "%s : generated SFTs for file %s\n", __func__, filename ); } /* if we have any SFTs */ if ( sftvec->length > 0 ) { /* define SFT length and the start and span of the observations plus the definitive segment time */ pspace.tseg = 1.0 / sftvec->data[0].deltaF; memcpy( &( pspace.epoch ), &( sftvec->data[0].epoch ), sizeof( LIGOTimeGPS ) ); pspace.span = XLALGPSDiff( &( sftvec->data[sftvec->length - 1].epoch ), &( sftvec->data[0].epoch ) ) + pspace.tseg; if ( uvar.verbose ) { fprintf( stdout, "%s : SFT length = %f seconds\n", __func__, pspace.tseg ); fprintf( stdout, "%s : entire dataset starts at GPS time %d contains %d SFTS and spans %.0f seconds\n", __func__, pspace.epoch.gpsSeconds, sftvec->length, pspace.span ); } /**********************************************************************************/ /* NORMALISE THE SFTS */ /**********************************************************************************/ /* compute the background noise using the sfts - this routine uses the running median at the edges to normalise the wings */ if ( XLALNormalizeSFTVect( sftvec, uvar.blocksize, 0 ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALNormaliseSFTVect() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : normalised the SFTs\n", __func__ ); } /**********************************************************************************/ /* DEFINE THE BINARY PARAMETER SPACE */ /**********************************************************************************/ /* define the binary parameter space */ if ( XLALDefineBinaryParameterSpace( &( pspace.space ), pspace.epoch, pspace.span, &uvar ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALDefineBinaryParameterSpace() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : defined binary parameter prior space\n", __func__ ); } /**********************************************************************************/ /* COMPUTE THE COARSE GRID ON FREQUENCY DERIVITIVES */ /**********************************************************************************/ /* compute the grid parameters for all SFTs */ INT4 ndim = -1; if ( XLALComputeFreqGridParamsVector( &freqgridparams, pspace.space, sftvec, uvar.mismatch, &ndim, BINS_FACTOR ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALComputeFreqGridParams() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : computed the grid parameters for the sfts\n", __func__ ); } /**********************************************************************************/ /* CONVERT ALL SFTS TO DOWNSAMPLED TIMESERIES */ /**********************************************************************************/ if ( XLALSFTVectorToCOMPLEX8TimeSeriesArray( &dstimevec, sftvec ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALSFTVectorToCOMPLEX8TimeSeriesArray() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : converted SFTs to downsampled timeseries\n", __func__ ); } /**********************************************************************************/ /* COMPUTE THE STATISTICS ON THE COARSE GRID */ /**********************************************************************************/ /* compute the demodulated power on the frequency derivitive grid */ if ( XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector( &dmpower, dstimevec, freqgridparams, ifp ) ) { LogPrintf( LOG_CRITICAL, "%s : XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector() failed with error = %d\n", __func__, xlalErrno ); return 1; } if ( uvar.verbose ) { fprintf( stdout, "%s : computed the demodulated power\n", __func__ ); } /**********************************************************************************/ /* FREE MEMORY */ /**********************************************************************************/ /* free memory inside the loop */ XLALFreeParameterSpace( &pspace ); XLALFreeREAL4DemodulatedPowerVector( dmpower ); for ( m = 0; m < ( INT4 )dstimevec->length; m++ ) { XLALDestroyCOMPLEX8TimeSeries( dstimevec->data[m] ); } XLALFree( dstimevec->data ); XLALFree( dstimevec ); for ( m = 0; m < ( INT4 )freqgridparams->length; m++ ) { XLALFree( freqgridparams->segment[m]->grid ); XLALFree( freqgridparams->segment[m]->prod ); XLALFree( freqgridparams->segment[m] ); } XLALFree( freqgridparams->segment ); XLALFree( freqgridparams ); if ( uvar.verbose ) { fprintf( stdout, "%s : freed memory\n", __func__ ); } XLALDestroySFTVector( sftvec ); } /* end if statement on whether we have SFTs */ /* update the start time of the segment */ XLALGPSAdd( ¤tStart, ( REAL8 )Tstep ); } /* end loop over start times */ /* update segment length */ currentT = ( INT4 )( ( REAL8 )currentT * ( 1.0 + uvar.mismatch ) ); } /* end loop over segment lengths */ /* move the temporary directory to the final location */ if ( uvar.tempdir ) { CHAR newoutputfile[LONGSTRINGLENGTH]; snprintf( newoutputfile, LONGSTRINGLENGTH, "%s/IntermittentResults-%s-%d.txt", uvar.outputdir, uvar.outLabel, fileStart.gpsSeconds ); if ( rename( intname, newoutputfile ) ) { LogPrintf( LOG_CRITICAL, "%s : unable to move final results file %s -> %s. Exiting.\n", __func__, intname, newoutputfile ); return 1; } } /**********************************************************************************/ /* FREE MEMORY */ /**********************************************************************************/ fclose( ifp ); LALCheckMemoryLeaks(); return 0; }
/* Everything needs to be declared as unused in case HDF is not enabled. */ int XLALSimInspiralNRWaveformGetHplusHcross( UNUSED REAL8TimeSeries **hplus, /**< Output h_+ vector */ UNUSED REAL8TimeSeries **hcross, /**< Output h_x vector */ UNUSED REAL8 phiRef, /**< orbital phase at reference pt. */ UNUSED REAL8 inclination, /**< inclination angle */ UNUSED REAL8 deltaT, /**< sampling interval (s) */ UNUSED REAL8 m1, /**< mass of companion 1 (kg) */ UNUSED REAL8 m2, /**< mass of companion 2 (kg) */ UNUSED REAL8 r, /**< distance of source (m) */ UNUSED REAL8 fStart, /**< start GW frequency (Hz) */ UNUSED REAL8 fRef, /**< reference GW frequency (Hz) */ UNUSED REAL8 s1x, /**< initial value of S1x */ UNUSED REAL8 s1y, /**< initial value of S1y */ UNUSED REAL8 s1z, /**< initial value of S1z */ UNUSED REAL8 s2x, /**< initial value of S2x */ UNUSED REAL8 s2y, /**< initial value of S2y */ UNUSED REAL8 s2z, /**< initial value of S2z */ UNUSED const char *NRDataFile, /**< Location of NR HDF file */ UNUSED LALValue* ModeArray /**< Container for the ell and m modes to generate. To generate all available modes pass NULL */ ) { #ifndef LAL_HDF5_ENABLED XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled"); #else /* Declarations */ UINT4 curr_idx, nr_file_format; INT4 model, modem; size_t array_length; REAL8 nrEta; REAL8 S1x, S1y, S1z, S2x, S2y, S2z; REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s; REAL8 est_start_time, curr_h_real, curr_h_imag; REAL8 theta, psi, calpha, salpha; REAL8 distance_scale_fac; COMPLEX16 curr_ylm; REAL8TimeSeries *hplus_corr; REAL8TimeSeries *hcross_corr; /* These keys follow a strict formulation and cannot be longer than 11 * characters */ char amp_key[20]; char phase_key[20]; gsl_vector *tmpVector=NULL; LALH5File *file, *group; LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO; REAL8Vector *curr_amp, *curr_phase; /* Use solar masses for units. NR files will use * solar masses as well, so easier for that conversion */ m1 = m1 / LAL_MSUN_SI; m2 = m2 / LAL_MSUN_SI; file = XLALH5FileOpen(NRDataFile, "r"); if (file == NULL) { XLAL_ERROR(XLAL_EIO, "NR SIMULATION DATA FILE %s NOT FOUND.\n", NRDataFile); } /* Sanity checks on physical parameters passed to waveform * generator to guarantee consistency with NR data file. */ XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta"); if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "MASSES (%e and %e) ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION (eta=%e).\n", m1, m2, nrEta); } /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure * the ChooseTDWaveform() input values are consistent with the data * recorded in the metadata of the HDF5 file. * PS: This assumes that the input spins are in the LAL frame! */ XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format"); if (nr_file_format < 2) { XLALPrintInfo("This NR file is format %d. Only formats 2 and above support the use of reference frequency. For formats < 2 the reference frequency always corresponds to the start of the waveform.", nr_file_format); fRef = -1; } XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z, &S2x, &S2y, &S2z, fRef, m1+m2, file); if (fabs(S1x - s1x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1y - s1y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1z - s1z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2x - s2x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2y - s2y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2z - s2z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } /* First estimate the length of time series that is needed. * Demand that 22 mode that is present and use that to figure this out */ XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN"); /* Figure out start time of data */ group = XLALH5GroupOpen(file, "amp_l2_m2"); ReadHDF5RealVectorDataset(group, "X", &tmpVector); time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0)); time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1)); gsl_vector_free(tmpVector); time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI; time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI; /* We don't want to return the *entire* waveform if it will be much longer * than the specified f_lower. Therefore guess waveform length using * the SEOBNR_ROM function and add 10% for safety. * FIXME: Is this correct for precessing waveforms? */ if (fStart < Mflower / (m1 + m2) ) { XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e", fStart, Mflower, Mflower / (m1 + m2)); } XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format"); if (nr_file_format > 1) { if (XLALSimInspiralNRWaveformCheckFRef(file, fStart * (m1+m2)) > 0) { /* Can use Omega array to get start time */ est_start_time = XLALSimInspiralNRWaveformGetRefTimeFromRefFreq(file, fStart * (m1+m2)) * (m1 + m2) * LAL_MTSUN_SI; } else { /* This is the potential weird case where Omega-vs-time does not start * at precisely the same time as flower_at_1MSUN. This gap should be * small, so just use the full waveform here. */ est_start_time = time_start_s; } } else { /* Fall back on SEOBNR chirp time estimate */ XLALSimIMRSEOBNRv4ROMTimeOfFrequency(&est_start_time, fStart, m1 * LAL_MSUN_SI, m2 * LAL_MSUN_SI, s1z, s2z); est_start_time = (-est_start_time) * 1.1; } if (est_start_time > time_start_s) { /* Restrict start time of waveform */ time_start_s = est_start_time; time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI); } array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT)); /* Compute correct angles for hplus and hcross following LAL convention. */ theta = psi = calpha = salpha = 0.; XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha, &salpha, file, inclination, phiRef, fRef*(m1+m2)); /* Create the return time series, use arbitrary epoch here. We set this * properly later. */ XLALGPSAdd(&tmpEpoch, time_start_s); *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { hplus_corr->data->data[curr_idx] = 0.0; hcross_corr->data->data[curr_idx] = 0.0; } /* Create the distance scale factor */ distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r; /* Generate the waveform */ /* NOTE: We assume that for a given ell mode, all m modes are present */ INT4 NRLmax; XLALH5FileQueryScalarAttributeValue(&NRLmax, file, "Lmax"); if ( ModeArray == NULL ) {/* Default behaviour: Generate all modes upto NRLmax */ ModeArray = XLALSimInspiralCreateModeArray(); for (int ell=2; ell<=NRLmax; ell++) { XLALSimInspiralModeArrayActivateAllModesAtL(ModeArray, ell); } } /* else Use the ModeArray given */ for (model=2; model < (NRLmax + 1) ; model++) { for (modem=-model; modem < (model+1); modem++) { /* first check if (l,m) mode is 'activated' in the ModeArray */ /* if activated then generate the mode, else skip this mode. */ if (XLALSimInspiralModeArrayIsModeActive(ModeArray, model, modem) != 1) { XLAL_PRINT_INFO("SKIPPING model = %i modem = %i\n", model, modem); continue; } XLAL_PRINT_INFO("generateing model = %i modem = %i\n", model, modem); snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem); snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem); /* Check that both groups exist */ if (XLALH5FileCheckGroupExists(file, amp_key) == 0) { continue; } if (XLALH5FileCheckGroupExists(file, phase_key) == 0) { continue; } /* Get amplitude and phase from file */ XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2), time_start_s, array_length, deltaT, amp_key); XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2), time_start_s, array_length, deltaT, phase_key); curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2, model, modem); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { curr_h_real = curr_amp->data[curr_idx] * cos(curr_phase->data[curr_idx]) * distance_scale_fac; curr_h_imag = curr_amp->data[curr_idx] * sin(curr_phase->data[curr_idx]) * distance_scale_fac; hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx] + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm); hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx] - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm); } XLALDestroyREAL8Vector(curr_amp); XLALDestroyREAL8Vector(curr_phase); } } /* Correct for the "alpha" angle as given in T1600045 to translate * from the NR wave frame to LAL wave-frame * Helper time series needed. */ for (curr_idx = 0; curr_idx < array_length; curr_idx++) { (*hplus)->data->data[curr_idx] = (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx] - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx]; (*hcross)->data->data[curr_idx] = + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx] + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx]; } XLALDestroyREAL8TimeSeries(hplus_corr); XLALDestroyREAL8TimeSeries(hcross_corr); XLALH5FileClose(file); XLALDestroyValue(ModeArray); return XLAL_SUCCESS; #endif }
/** * load a full multi-dim template grid from the file init->gridFile, * the file-format is: lines of 6 columns, which are: * * Freq Alpha Delta f1dot f2dot f3dot * * \note * *) this function returns the effective spinRange covered by the read-in template bank * by storing it in scan->spinRange, potentially overwriting any previous user-input values in there. * * *) a possible future extension should probably *clip* the template-bank to the user-specified ranges, * then return the effective ranges spanned by the resultant template bank. * * *) in order to avoid surprises until such a feature is implemented, we currently return an error if * any of the input spinRanges are non-zero * */ int XLALLoadFullGridFile ( DopplerFullScanState *scan, const DopplerFullScanInit *init ) { XLAL_CHECK ( (scan != NULL) && (init != NULL), XLAL_EINVAL ); XLAL_CHECK ( init->gridFile != NULL, XLAL_EINVAL ); XLAL_CHECK ( scan->state == STATE_IDLE, XLAL_EINVAL ); REAL8VectorList XLAL_INIT_DECL(head); REAL8VectorList *tail = NULL; REAL8Vector *entry = NULL; UINT4 numTemplates; FILE *fp; /* Check that all user-input spin- and sky-ranges are zero, otherwise fail! * * NOTE: In the future we should allow combining the user-input ranges with * those found in the grid-file by forming the intersection, ie *clipping* * of the read-in grids to the user-input ranges. * Right now we require empty ranges input, and report back the ranges from the grid-file * */ if ( init->searchRegion.skyRegionString != NULL ) { XLAL_ERROR ( XLAL_EINVAL, "\nnon-NULL skyRegion input currently not supported! skyRegion = '%s'\n\n", init->searchRegion.skyRegionString ); } for ( UINT4 s = 0; s < PULSAR_MAX_SPINS; s ++ ) { if ( (init->searchRegion.fkdot[s] != 0) || (init->searchRegion.fkdotBand[s] != 0 )) { XLAL_ERROR ( XLAL_EINVAL, "\nnon-zero input spinRanges currently not supported! fkdot[%d] = %g, fkdotBand[%d] = %g\n\n", s, init->searchRegion.fkdot[s], s, init->searchRegion.fkdotBand[s] ); } } /* for s < max_spins */ /* open input data file */ XLAL_CHECK ( (fp = LALFopen (init->gridFile, "r")) != NULL, XLAL_ESYS, "Could not open data-file: `%s`\n\n", init->gridFile ); /* prepare grid-entry buffer */ XLAL_CHECK ( (entry = XLALCreateREAL8Vector ( 6 ) ) != NULL, XLAL_EFUNC ); /* keep track of the sky- and spinRanges spanned by the template bank */ REAL8 FreqMax = - LAL_REAL4_MAX, FreqMin = LAL_REAL4_MAX; // only using REAL4 ranges to avoid over/under flows, and should be enough REAL8 f1dotMax = - LAL_REAL4_MAX, f1dotMin = LAL_REAL4_MAX; REAL8 f2dotMax = - LAL_REAL4_MAX, f2dotMin = LAL_REAL4_MAX; REAL8 f3dotMax = - LAL_REAL4_MAX, f3dotMin = LAL_REAL4_MAX; REAL8 alphaMax = - LAL_REAL4_MAX, alphaMin = LAL_REAL4_MAX; REAL8 deltaMax = - LAL_REAL4_MAX, deltaMin = LAL_REAL4_MAX; /* parse this list of lines into a full grid */ numTemplates = 0; tail = &head; /* head will remain empty! */ CHAR line[2048]; while ( ! feof ( fp ) && ! ferror ( fp ) && fgets( line, sizeof(line), fp ) != NULL ) { // Skip over any comment lines if ( line[0] == '#' || line[0] == '%' ) { continue; } // File format expects lines containing 6 columns: Freq Alpha Delta f1dot f2dot f3dot REAL8 Freq, Alpha, Delta, f1dot, f2dot, f3dot; if ( 6 != sscanf( line, "%" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT "\n", &Freq, &Alpha, &Delta, &f1dot, &f2dot, &f3dot ) ) { XLALPrintError ("ERROR: Failed to parse 6 REAL8's from line %d in grid-file '%s'\n\n", numTemplates + 1, init->gridFile); if ( head.next ) { XLALREAL8VectorListDestroy (head.next); } XLAL_ERROR ( XLAL_EINVAL ); } /* keep track of maximal spans */ alphaMin = fmin ( Alpha, alphaMin ); deltaMin = fmin ( Delta, deltaMin ); FreqMin = fmin ( Freq, FreqMin ); f1dotMin = fmin ( f1dot, f1dotMin ); f2dotMin = fmin ( f2dot, f2dotMin ); f3dotMin = fmin ( f3dot, f3dotMin ); alphaMax = fmax ( Alpha, alphaMax ); deltaMax = fmax ( Delta, deltaMax ); FreqMax = fmax ( Freq, FreqMax ); f1dotMax = fmax ( f1dot, f1dotMax ); f2dotMax = fmax ( f2dot, f2dotMax ); f3dotMax = fmax ( f3dot, f3dotMax ); /* add this entry to template-bank list */ entry->data[0] = Freq; entry->data[1] = Alpha; entry->data[2] = Delta; entry->data[3] = f1dot; entry->data[4] = f2dot; entry->data[5] = f3dot; if ( (tail = XLALREAL8VectorListAddEntry (tail, entry)) == NULL ) { if ( head.next ) { XLALREAL8VectorListDestroy (head.next); } XLAL_ERROR ( XLAL_EINVAL ); } numTemplates ++ ; } /* while !feof(fp) && ... */ if ( ferror ( fp ) ) { XLAL_ERROR ( XLAL_EIO ); } XLALDestroyREAL8Vector ( entry ); /* ---------- update scan-state ---------- */ // ----- report back ranges actually spanned by grid-file CHAR *skyRegionString = NULL; REAL8 eps = LAL_REAL8_EPS; XLAL_CHECK ( (skyRegionString = XLALSkySquare2String ( alphaMin, deltaMin, (alphaMax - alphaMin) + eps, (deltaMax - deltaMin) + eps )) != NULL, XLAL_EFUNC ); // note: we slight expanded the enclosing sky-square by eps to avoid complaints when a grid-file contains // only points in a line, which is perfectly valid here. XLAL_CHECK ( XLALParseSkyRegionString ( &scan->skyRegion, skyRegionString ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALFree ( skyRegionString ); scan->spinRange.fkdot[0] = FreqMin; scan->spinRange.fkdotBand[0] = FreqMax - FreqMin; scan->spinRange.fkdot[1] = f1dotMin; scan->spinRange.fkdotBand[1] = f1dotMax - f1dotMin; scan->spinRange.fkdot[2] = f2dotMin; scan->spinRange.fkdotBand[2] = f2dotMax - f2dotMin; scan->spinRange.fkdot[3] = f3dotMin; scan->spinRange.fkdotBand[3] = f3dotMax - f3dotMin; scan->numTemplates = numTemplates; scan->covering = head.next; /* pass result (without head!) */ scan->thisGridPoint = scan->covering; /* init to start */ XLALPrintInfo ( "Template grid: nTot = %.0f\n", 1.0 * numTemplates ); XLALPrintInfo ( "Spanned ranges: Freq in [%g, %g], f1dot in [%g, %g], f2dot in [%g, %g], f3dot in [%g, %g]\n", FreqMin, FreqMax, f1dotMin, f1dotMax, f2dotMin, f2dotMax, f3dotMin, f3dotMax ); return XLAL_SUCCESS; } /* XLALLoadFullGridFile() */
/// /// Make SFTs from given REAL8TimeSeries at given timestamps, potentially applying a time-domain window on each timestretch first /// SFTVector * XLALMakeSFTsFromREAL8TimeSeries ( const REAL8TimeSeries *timeseries, //!< input time-series const LIGOTimeGPSVector *timestamps, //!< timestamps to produce SFTs for (can be NULL), if given must all lies within timeseries' time-span const char *windowType, //!< optional time-domain window function to apply before FFTing REAL8 windowBeta //!< window parameter, if any ) { XLAL_CHECK_NULL ( timeseries != NULL, XLAL_EINVAL, "Invalid NULL input 'timeseries'\n"); XLAL_CHECK_NULL ( timestamps != NULL, XLAL_EINVAL, "Invalid NULL input 'timestamps'\n"); REAL8 dt = timeseries->deltaT; // timeseries timestep */ REAL8 Tsft = timestamps->deltaT; REAL8 df = 1.0 / Tsft; // SFT frequency spacing // make sure that number of timesamples/SFT is an integer (up to possible rounding error 'eps') REAL8 timestepsSFT0 = Tsft / dt; UINT4 timestepsSFT = lround ( timestepsSFT0 ); XLAL_CHECK_NULL ( fabs ( timestepsSFT0 - timestepsSFT ) / timestepsSFT0 < eps, XLAL_ETOL, "Inconsistent sampling-step (dt=%g) and Tsft=%g: must be integer multiple Tsft/dt = %g >= %g\n", dt, Tsft, timestepsSFT0, eps ); // prepare window function if requested REAL8Window *window = NULL; if ( windowType != NULL ) { XLAL_CHECK_NULL ( (window = XLALCreateNamedREAL8Window ( windowType, windowBeta, timestepsSFT )) != NULL, XLAL_EFUNC ); } // ---------- Prepare FFT ---------- REAL8Vector *timeStretchCopy; // input array of length N XLAL_CHECK_NULL ( (timeStretchCopy = XLALCreateREAL8Vector ( timestepsSFT )) != NULL, XLAL_EFUNC, "XLALCreateREAL4Vector(%d) failed.\n", timestepsSFT ); UINT4 numSFTBins = timestepsSFT / 2 + 1; // number of positive frequency-bins + 'DC' to be stored in SFT fftw_complex *fftOut; // output array of length N/2 + 1 XLAL_CHECK_NULL ( (fftOut = fftw_malloc ( numSFTBins * sizeof(fftOut[0]) )) != NULL, XLAL_ENOMEM, "fftw_malloc(%d*sizeof(complex)) failed\n", numSFTBins ); fftw_plan fftplan; // FFTW plan LAL_FFTW_WISDOM_LOCK; XLAL_CHECK_NULL ( (fftplan = fftw_plan_dft_r2c_1d ( timestepsSFT, timeStretchCopy->data, fftOut, FFTW_ESTIMATE)) != NULL, XLAL_EFUNC ); // FIXME: or try FFTW_MEASURE LAL_FFTW_WISDOM_UNLOCK; LIGOTimeGPS tStart = timeseries->epoch; // get last possible start-time for an SFT REAL8 duration = round ( timeseries->data->length * dt ); // rounded to seconds LIGOTimeGPS tLast = tStart; XLALGPSAdd( &tLast, duration - Tsft ); // check that all timestamps lie within [tStart, tLast] for ( UINT4 i = 0; i < timestamps->length; i ++ ) { char buf1[256], buf2[256]; XLAL_CHECK_NULL ( XLALGPSDiff ( &tStart, &(timestamps->data[i]) ) <= 0, XLAL_EDOM, "Timestamp i=%d: %s before start-time %s\n", i, XLALGPSToStr ( buf1, &(timestamps->data[i]) ), XLALGPSToStr ( buf2, &tStart ) ); XLAL_CHECK_NULL ( XLALGPSDiff ( &tLast, &(timestamps->data[i]) ) >=0, XLAL_EDOM, "Timestamp i=%d: %s after last start-time %s\n", i, XLALGPSToStr ( buf1, &(timestamps->data[i]) ), XLALGPSToStr ( buf2, &tLast ) ); } UINT4 numSFTs = timestamps->length; // prepare output SFT-vector SFTVector *sftvect; XLAL_CHECK_NULL ( (sftvect = XLALCreateSFTVector ( numSFTs, numSFTBins )) != NULL, XLAL_EFUNC, "XLALCreateSFTVector(numSFTs=%d, numBins=%d) failed.\n", numSFTs, numSFTBins ); // main loop: apply FFT to the requested time-stretches and store in output SFTs for ( UINT4 iSFT = 0; iSFT < numSFTs; iSFT++ ) { SFTtype *thisSFT = &(sftvect->data[iSFT]); // point to current SFT-slot to store output in // find the start-bin for this SFT in the time-series REAL8 offset = XLALGPSDiff ( &(timestamps->data[iSFT]), &tStart ); INT4 offsetBins = lround ( offset / dt ); // copy timeseries-data for that SFT into local buffer memcpy ( timeStretchCopy->data, timeseries->data->data + offsetBins, timeStretchCopy->length * sizeof(timeStretchCopy->data[0]) ); // window the current time series stretch if required REAL8 sigma_window = 1; if ( window != NULL ) { sigma_window = sqrt ( window->sumofsquares / window->data->length ); for( UINT4 iBin = 0; iBin < timeStretchCopy->length; iBin++ ) { timeStretchCopy->data[iBin] *= window->data->data[iBin]; } } // if window // FFT this time-stretch fftw_execute ( fftplan ); // fill the header of the i'th output SFT */ strcpy ( thisSFT->name, timeseries->name ); thisSFT->epoch = timestamps->data[iSFT]; thisSFT->f0 = timeseries->f0; // SFT starts at heterodyning frequency thisSFT->deltaF = df; // normalize DFT-data to conform to v2 specification ==> multiply DFT by (dt/sigma{window}) // the SFT normalization in case of windowing follows the conventions detailed in the SFTv2 specification, // namely LIGO-T040164, and in particular Eqs.(3),(4) and (6) in T010095-00.pdf // https://dcc.ligo.org/cgi-bin/private/DocDB/ShowDocument?.submit=Number&docid=T010095 // https://dcc.ligo.org/DocDB/0026/T010095/000/T010095-00.pdf REAL8 norm = dt / sigma_window; for ( UINT4 k = 0; k < numSFTBins ; k ++ ) { thisSFT->data->data[k] = (COMPLEX8) ( norm * fftOut[k] ); } // correct heterodyning-phase, IF NECESSARY: ie if (fHet * tStart) is not an integer, such that phase-corr = multiple of 2pi if ( ( (INT4)timeseries->f0 != timeseries->f0 ) || (timeseries->epoch.gpsNanoSeconds != 0) || (thisSFT->epoch.gpsNanoSeconds != 0) ) { XLAL_CHECK_NULL ( XLALcorrect_phase ( thisSFT, timeseries->epoch) == XLAL_SUCCESS, XLAL_EFUNC ); } } // for iSFT < numSFTs // free memory fftw_free ( fftOut ); LAL_FFTW_WISDOM_LOCK; fftw_destroy_plan ( fftplan ); LAL_FFTW_WISDOM_UNLOCK; XLALDestroyREAL8Vector ( timeStretchCopy ); XLALDestroyREAL8Window ( window ); return sftvect; } // XLALMakeSFTsFromREAL8TimeSeries()
/*--------------main function---------------*/ int main(int argc, char **argv){ const CHAR *fn = __func__; InputParams XLAL_INIT_DECL(inputs); REAL8 srate = 16384.0; /*sample rate defaulted to 16384 */ /* read in command line input args */ ReadInput( &inputs, argc, argv ); LALStatus XLAL_INIT_DECL(status); EphemerisData *edat; if ( (edat = InitEphemeris ( inputs.ephemType, inputs.ephemDir)) == NULL ){ XLALPrintError ( "%s: Failed to init ephemeris data\n", fn ); XLAL_ERROR ( XLAL_EFUNC ); } /*init detector info */ LALDetector *site; if ( ( site = XLALGetSiteInfo ( inputs.det )) == NULL ){ XLALPrintError("%s: Failed to get site-info for detector '%s'\n", fn, inputs.det ); XLAL_ERROR ( XLAL_EFUNC ); } if( inputs.geocentre ){ /* set site to the geocentre */ site->location[0] = 0.0; site->location[1] = 0.0; site->location[2] = 0.0; } struct dirent **pulsars; INT4 n=scandir(inputs.pulsarDir, &pulsars, 0, alphasort); if ( n < 0){ XLALPrintError("scandir failed\n"); XLAL_ERROR(XLAL_EIO); } UINT4 numpulsars = (UINT4)n; UINT4 h=0; CHAR parname[256]; PulsarParameters *pulparams[numpulsars]; for(h=2; h<numpulsars; h++){ if(strstr(pulsars[h]->d_name,".par") == NULL){ free(pulsars[h]); continue; } else{ sprintf(parname,"%s/%s", inputs.pulsarDir, pulsars[h]->d_name); fprintf(stderr, "%s\n", parname); FILE *inject; if (( inject = fopen ( parname, "r" )) == NULL ){ fprintf(stderr,"Error opening file: %s\n", parname); XLAL_ERROR ( XLAL_EIO ); } pulparams[h] = XLALReadTEMPOParFile( parname ); fclose( inject ); } } LIGOTimeGPS epoch; UINT4 ndata; epoch.gpsSeconds = inputs.epoch; epoch.gpsNanoSeconds = 0; ndata = inputs.frDur; REAL8TimeSeries *series=NULL; CHAR out_file[256]; sprintf(out_file, "%s-%s-%d-%d.gwf", inputs.det, inputs.outStr, epoch.gpsSeconds, ndata ); LALFrameH *outFrame = NULL; if ((outFrame = XLALFrameNew( &epoch, (REAL8)ndata, inputs.channel, 1, 0, 0 )) == NULL) { LogPrintf(LOG_CRITICAL, "%s : XLALFrameNew() filed with error = %d.\n", fn, xlalErrno); XLAL_ERROR( XLAL_EFAILED); } if ((series = XLALCreateREAL8TimeSeries( inputs.channel, &epoch, 0., 1./srate,&lalSecondUnit, (int)(ndata*srate) )) == NULL) { XLAL_ERROR( XLAL_EFUNC ); } UINT4 counter=0; for (counter = 0; counter < series->data->length; counter++) series->data->data[counter] = 0; /*** Read Pulsar Data ***/ for (h=0; h < numpulsars; h++){ if(strstr(pulsars[h]->d_name,".par")==NULL){ free(pulsars[h]); continue; } else{ PulsarSignalParams XLAL_INIT_DECL(params); /* set signal generation barycenter delay look-up table step size */ params.dtDelayBy2 = 10.; /* generate table every 10 seconds */ if (( params.pulsar.spindown = XLALCreateREAL8Vector(1)) == NULL ){ XLALPrintError("Out of memory"); XLAL_ERROR ( XLAL_EFUNC ); } INT4 dtpos = 0; if ( PulsarCheckParam(pulparams[h], "POSEPOCH") ) dtpos = epoch.gpsSeconds - (INT4)PulsarGetREAL8Param(pulparams[h], "POSEPOCH"); else dtpos = epoch.gpsSeconds - (INT4)PulsarGetREAL8Param(pulparams[h], "PEPOCH"); REAL8 ra = 0., dec = 0.; if ( PulsarCheckParam( pulparams[h], "RAJ" ) ) { ra = PulsarGetREAL8Param( pulparams[h], "RAJ" ); } else if ( PulsarCheckParam( pulparams[h], "RA" ) ){ ra = PulsarGetREAL8Param( pulparams[h], "RA" ); } else{ XLALPrintError("No right ascension found"); XLAL_ERROR ( XLAL_EFUNC ); } if ( PulsarCheckParam( pulparams[h], "DECJ" ) ) { dec = PulsarGetREAL8Param( pulparams[h], "DECJ" ); } else if ( PulsarCheckParam( pulparams[h], "DEC" ) ){ dec = PulsarGetREAL8Param( pulparams[h], "DEC" ); } else{ XLALPrintError("No declination found"); XLAL_ERROR ( XLAL_EFUNC ); } params.pulsar.position.latitude = dec + (REAL8)dtpos * PulsarGetREAL8ParamOrZero(pulparams[h], "PMDEC"); params.pulsar.position.longitude = ra + (REAL8)dtpos * PulsarGetREAL8ParamOrZero(pulparams[h], "PMRA") / cos(params.pulsar.position.latitude); params.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; REAL8Vector *fs = PulsarGetREAL8VectorParam(pulparams[h], "F"); if ( fs->length == 0 ){ XLALPrintError("No frequencies found"); XLAL_ERROR ( XLAL_EFUNC ); } params.pulsar.f0 = 2.*fs->data[0]; if ( fs->length > 1 ){ params.pulsar.spindown->data[0] = 2.*fs->data[1]; } if (( XLALGPSSetREAL8(&(params.pulsar.refTime), PulsarGetREAL8Param(pulparams[h], "PEPOCH")) ) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); params.pulsar.psi = PulsarGetREAL8ParamOrZero(pulparams[h], "PSI"); params.pulsar.phi0 = PulsarGetREAL8ParamOrZero(pulparams[h], "PHI0"); REAL8 cosiota = PulsarGetREAL8ParamOrZero(pulparams[h], "COSIOTA"); REAL8 h0 = PulsarGetREAL8ParamOrZero(pulparams[h], "H0"); params.pulsar.aPlus = 0.5 * h0 * (1. + cosiota * cosiota ); params.pulsar.aCross = h0 * cosiota; /*Add binary later if needed!*/ params.site = site; params.ephemerides = edat; params.startTimeGPS = epoch; params.duration = ndata; params.samplingRate = srate; params.fHeterodyne = 0.; REAL4TimeSeries *TSeries = NULL; LALGeneratePulsarSignal( &status, &TSeries, ¶ms ); if (status.statusCode){ fprintf(stderr, "LAL Routine failed!\n"); XLAL_ERROR (XLAL_EFAILED); } UINT4 i; for (i=0; i < TSeries->data->length; i++) series->data->data[i] += TSeries->data->data[i]; XLALDestroyREAL4TimeSeries(TSeries); XLALDestroyREAL8Vector(params.pulsar.spindown); } } if (XLALFrameAddREAL8TimeSeriesProcData(outFrame,series)){ LogPrintf(LOG_CRITICAL, "%s : XLALFrameAddREAL8TimeSeries() failed with error = %d.\n",fn,xlalErrno); XLAL_ERROR(XLAL_EFAILED); } CHAR OUTFILE[256]; sprintf(OUTFILE, "%s/%s", inputs.outDir, out_file); if ( XLALFrameWrite(outFrame, OUTFILE)){ LogPrintf(LOG_CRITICAL, "%s : XLALFrameWrite() failed with error = %d.\n", fn, xlalErrno); XLAL_ERROR( XLAL_EFAILED ); } XLALFrameFree(outFrame); XLALDestroyREAL8TimeSeries( series ); return 0; }
/** * Calculate the derivative of the Hamiltonian w.r.t. a specific parameter * Used by generic spin EOB model, including initial conditions solver. */ static REAL8 XLALSpinHcapExactDerivWRTParam( const INT4 paramIdx, /**<< Index of the parameters */ const REAL8 values[], /**<< Dynamical variables */ SpinEOBParams *funcParams /**<< SEOB Parameters */ ) { REAL8 result; REAL8Vector *sigmaKerr = funcParams->sigmaKerr; REAL8Vector *sigmaStar = funcParams->sigmaStar; SpinEOBHCoeffs *coeffs = funcParams->seobCoeffs; REAL8Vector *s1Vec = funcParams->s1Vec; REAL8Vector *s2Vec = funcParams->s2Vec; REAL8Vector *x=NULL; REAL8Vector *p=NULL; /* Note that this function is called a limited number of times in the initial condition setup, * so no worries about the below memory allocations slowing the code... at this point. */ x=XLALCreateREAL8Vector(3); p=XLALCreateREAL8Vector(3); memcpy(x->data,&values[0],3*sizeof(REAL8)); memcpy(p->data,&values[3],3*sizeof(REAL8)); REAL8 eta = funcParams->eobParams->eta; REAL8 e3z = (0.0 <= sigmaKerr->data[2]) - (sigmaKerr->data[2] < 0.0); // This is a modified sign function: e3z = 1 if sigmaKerr->data[2]>=0, -1 otherwise /* Now calculate derivatives w.r.t. the required parameter */ if (funcParams->tortoise==1){ if (paramIdx==4){ #include "mathematica_codes/SEOBNRv2_opt_dp1tortoise.h" result = dHdp1/eta; } else if (paramIdx==3){ #include "mathematica_codes/SEOBNRv2_opt_dp0tortoise.h" result = dHdp0/eta; } else if (paramIdx==5){ #include "mathematica_codes/SEOBNRv2_opt_dp2tortoise.h" result = dHdp2/eta; } else if (paramIdx==0){ #include "mathematica_codes/SEOBNRv2_opt_dx0tortoise.h" result = dHdx0/eta; } else { XLAL_ERROR( XLAL_EFUNC ); } }else if(funcParams->tortoise==0) { if (paramIdx==4){ #include "mathematica_codes/SEOBNRv2_opt_dp1.h" result = dHdp1/eta; } else if (paramIdx==3){ #include "mathematica_codes/SEOBNRv2_opt_dp0.h" result = dHdp0/eta; } else if (paramIdx==5){ #include "mathematica_codes/SEOBNRv2_opt_dp2.h" result = dHdp2/eta; } else if (paramIdx==0){ #include "mathematica_codes/SEOBNRv2_opt_dx0.h" result = dHdx0/eta; } else { XLAL_ERROR( XLAL_EFUNC ); } } else { XLAL_ERROR( XLAL_EFUNC ); } XLALDestroyREAL8Vector(x); XLALDestroyREAL8Vector(p); return result; }
/* Everything needs to be declared as unused in case HDF is not enabled. */ int XLALSimInspiralNRWaveformGetHplusHcross( UNUSED REAL8TimeSeries **hplus, /**< Output h_+ vector */ UNUSED REAL8TimeSeries **hcross, /**< Output h_x vector */ UNUSED REAL8 phiRef, /**< orbital phase at reference pt. */ UNUSED REAL8 inclination, /**< inclination angle */ UNUSED REAL8 deltaT, /**< sampling interval (s) */ UNUSED REAL8 m1, /**< mass of companion 1 (kg) */ UNUSED REAL8 m2, /**< mass of companion 2 (kg) */ UNUSED REAL8 r, /**< distance of source (m) */ UNUSED REAL8 fStart, /**< start GW frequency (Hz) */ UNUSED REAL8 fRef, /**< reference GW frequency (Hz) */ UNUSED REAL8 s1x, /**< initial value of S1x */ UNUSED REAL8 s1y, /**< initial value of S1y */ UNUSED REAL8 s1z, /**< initial value of S1z */ UNUSED REAL8 s2x, /**< initial value of S2x */ UNUSED REAL8 s2y, /**< initial value of S2y */ UNUSED REAL8 s2z, /**< initial value of S2z */ UNUSED const char *NRDataFile /**< Location of NR HDF file */ ) { #ifndef LAL_HDF5_ENABLED XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled"); #else /* Declarations */ UINT4 curr_idx; INT4 model, modem; size_t array_length; REAL8 nrEta; REAL8 S1x, S1y, S1z, S2x, S2y, S2z; REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s; REAL8 chi, est_start_time, curr_h_real, curr_h_imag; REAL8 theta, psi, calpha, salpha; REAL8 distance_scale_fac; COMPLEX16 curr_ylm; REAL8TimeSeries *hplus_corr; REAL8TimeSeries *hcross_corr; /* These keys follow a strict formulation and cannot be longer than 11 * characters */ char amp_key[20]; char phase_key[20]; gsl_vector *tmpVector=NULL; LALH5File *file, *group; LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO; REAL8Vector *curr_amp, *curr_phase; /* Use solar masses for units. NR files will use * solar masses as well, so easier for that conversion */ m1 = m1 / LAL_MSUN_SI; m2 = m2 / LAL_MSUN_SI; file = XLALH5FileOpen(NRDataFile, "r"); /* Sanity checks on physical parameters passed to waveform * generator to guarantee consistency with NR data file. */ XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta"); if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "MASSES ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION.\n"); } /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure * the ChooseTDWaveform() input values are consistent with the data * recorded in the metadata of the HDF5 file. * PS: This assumes that the input spins are in the LAL frame! */ XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z, &S2x, &S2y, &S2z, file); if (fabs(S1x - s1x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1y - s1y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1z - s1z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2x - s2x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2y - s2y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2z - s2z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } /* First estimate the length of time series that is needed. * Demand that 22 mode that is present and use that to figure this out */ XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN"); /* Figure out start time of data */ group = XLALH5GroupOpen(file, "amp_l2_m2"); ReadHDF5RealVectorDataset(group, "knots", &tmpVector); time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0)); time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1)); gsl_vector_free(tmpVector); time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI; time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI; /* We don't want to return the *entire* waveform if it will be much longer * than the specified f_lower. Therefore guess waveform length using * the SEOBNR_ROM function and add 10% for safety. * FIXME: Is this correct for precessing waveforms? */ chi = XLALSimIMRPhenomBComputeChi(m1, m2, s1z, s2z); est_start_time = XLALSimIMRSEOBNRv2ChirpTimeSingleSpin(m1 * LAL_MSUN_SI, m2 * LAL_MSUN_SI, chi, fStart); est_start_time = (-est_start_time) * 1.1; if (est_start_time > time_start_s) { /* Restrict start time of waveform */ time_start_s = est_start_time; time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI); } else if (fStart < Mflower / (m1 + m2) ) { XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e", fStart, Mflower, Mflower / (m1 + m2)); } array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT)); /* Compute correct angles for hplus and hcross following LAL convention. */ theta = psi = calpha = salpha = 0.; XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha, &salpha, file, inclination, phiRef); /* Create the return time series, use arbitrary epoch here. We set this * properly later. */ XLALGPSAdd(&tmpEpoch, time_start_s); *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { hplus_corr->data->data[curr_idx] = 0.0; hcross_corr->data->data[curr_idx] = 0.0; } /* Create the distance scale factor */ distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r; /* Generate the waveform */ for (model=2; model < 9 ; model++) { for (modem=-model; modem < (model+1); modem++) { snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem); snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem); /* Check that both groups exist */ if (XLALH5CheckGroupExists(file, amp_key) == 0) { continue; } if (XLALH5CheckGroupExists(file, phase_key) == 0) { continue; } /* Get amplitude and phase from file */ XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2), time_start_s, array_length, deltaT, amp_key); XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2), time_start_s, array_length, deltaT, phase_key); curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2, model, modem); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { curr_h_real = curr_amp->data[curr_idx] * cos(curr_phase->data[curr_idx]) * distance_scale_fac; curr_h_imag = curr_amp->data[curr_idx] * sin(curr_phase->data[curr_idx]) * distance_scale_fac; hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx] + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm); hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx] - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm); } XLALDestroyREAL8Vector(curr_amp); XLALDestroyREAL8Vector(curr_phase); } } /* Correct for the "alpha" angle as given in T1600045 to translate * from the NR wave frame to LAL wave-frame * Helper time series needed. */ for (curr_idx = 0; curr_idx < array_length; curr_idx++) { (*hplus)->data->data[curr_idx] = (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx] - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx]; (*hcross)->data->data[curr_idx] = + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx] + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx]; } XLALDestroyREAL8TimeSeries(hplus_corr); XLALDestroyREAL8TimeSeries(hcross_corr); XLALH5FileClose(file); return XLAL_SUCCESS; #endif }
void LALTaylorT4WaveformForInjection( LALStatus *status, CoherentGW *waveform, InspiralTemplate *params, PPNParamStruc *ppnParams ) { UINT4 count, i; REAL8 phiC; REAL4Vector *a = NULL; /* pointers to generated amplitude data */ REAL4Vector *ff = NULL; /* pointers to generated frequency data */ REAL8Vector *phi = NULL; /* pointer to generated phase data */ InspiralInit paramsInit; INITSTATUS(status); ATTATCHSTATUSPTR(status); /* Make sure parameter and waveform structures exist. */ ASSERT( params, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT(waveform, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL); ASSERT( !( waveform->a ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT( !( waveform->h ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT( !( waveform->f ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT( !( waveform->phi ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); params->ampOrder = (LALPNOrder) 0; XLALPrintInfo( "WARNING: Amp Order has been reset to %d", params->ampOrder); /* Compute some parameters*/ LALInspiralInit(status->statusPtr, params, ¶msInit); CHECKSTATUSPTR(status); if (paramsInit.nbins == 0) { XLALPrintError( "Error: Estimated length of injection is zero.\n" ); ABORT( status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE ); } /* Now we can allocate memory and vector for coherentGW structure*/ ff = XLALCreateREAL4Vector( paramsInit.nbins ); a = XLALCreateREAL4Vector( 2*paramsInit.nbins ); phi = XLALCreateREAL8Vector( paramsInit.nbins ); if ( !ff || !a || !phi ) { if ( ff ) XLALDestroyREAL4Vector( ff ); if ( a ) XLALDestroyREAL4Vector( a ); if ( phi ) XLALDestroyREAL8Vector( phi ); ABORTXLAL( status ); } /* Call the engine function */ LALTaylorT4WaveformEngine(status->statusPtr, NULL, NULL, a, ff, phi, &count, params, ¶msInit); BEGINFAIL( status ) { XLALDestroyREAL4Vector( ff ); XLALDestroyREAL4Vector( a ); XLALDestroyREAL8Vector( phi ); } ENDFAIL( status ); /*wrap the phase vector*/ phiC = phi->data[count-1] ; for (i = 0; i < count; i++) { phi->data[i] = phi->data[i] - phiC + ppnParams->phi; } /* Allocate the waveform structures. */ if ( ( waveform->a = (REAL4TimeVectorSeries *) LALCalloc(1, sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { XLALDestroyREAL4Vector( ff ); XLALDestroyREAL4Vector( a ); XLALDestroyREAL8Vector( phi ); ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } if ( ( waveform->f = (REAL4TimeSeries *) LALCalloc(1, sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( waveform->a ); waveform->a = NULL; XLALDestroyREAL4Vector( ff ); XLALDestroyREAL4Vector( a ); XLALDestroyREAL8Vector( phi ); ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } if ( ( waveform->phi = (REAL8TimeSeries *) LALCalloc(1, sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( waveform->a ); waveform->a = NULL; LALFree( waveform->f ); waveform->f = NULL; XLALDestroyREAL4Vector( ff ); XLALDestroyREAL4Vector( a ); XLALDestroyREAL8Vector( phi ); ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } waveform->a->data = XLALCreateREAL4VectorSequence( (UINT4)count, 2 ); waveform->f->data = XLALCreateREAL4Vector( count ); waveform->phi->data = XLALCreateREAL8Vector( count ); if ( !waveform->a->data || !waveform->f->data || !waveform->phi->data ) { if ( waveform->a->data ) XLALDestroyREAL4VectorSequence( waveform->a->data ); if ( waveform->f->data ) XLALDestroyREAL4Vector( waveform->f->data ); if ( waveform->phi->data ) XLALDestroyREAL8Vector( waveform->phi->data ); LALFree( waveform->a ); waveform->a = NULL; LALFree( waveform->f ); waveform->f = NULL; XLALDestroyREAL4Vector( ff ); XLALDestroyREAL4Vector( a ); XLALDestroyREAL8Vector( phi ); ABORTXLAL( status ); } memcpy(waveform->f->data->data , ff->data, count*(sizeof(REAL4))); memcpy(waveform->a->data->data , a->data, 2*count*(sizeof(REAL4))); memcpy(waveform->phi->data->data ,phi->data, count*(sizeof(REAL8))); waveform->a->deltaT = waveform->f->deltaT = waveform->phi->deltaT = ppnParams->deltaT; waveform->a->sampleUnits = lalStrainUnit; waveform->f->sampleUnits = lalHertzUnit; waveform->phi->sampleUnits = lalDimensionlessUnit; waveform->position = ppnParams->position; waveform->psi = ppnParams->psi; snprintf( waveform->a->name, LALNameLength, "T4 inspiral amplitude" ); snprintf( waveform->f->name, LALNameLength, "T4 inspiral frequency" ); snprintf( waveform->phi->name, LALNameLength, "T4 inspiral phase" ); /* --- fill some output ---*/ ppnParams->tc = (double)(count-1) / params->tSampling ; ppnParams->length = count; ppnParams->dfdt = ((REAL4)(waveform->f->data->data[count-1] - waveform->f->data->data[count-2])) * ppnParams->deltaT; ppnParams->fStop = params->fFinal; ppnParams->termCode = GENERATEPPNINSPIRALH_EFSTOP; ppnParams->termDescription = GENERATEPPNINSPIRALH_MSGEFSTOP; ppnParams->fStart = ppnParams->fStartIn; /* --- free memory --- */ XLALDestroyREAL4Vector( ff ); XLALDestroyREAL4Vector( a ); XLALDestroyREAL8Vector( phi ); DETATCHSTATUSPTR(status); RETURN (status); }
/** * basic initializations: deal with user input and return standardized 'ConfigVariables' */ int XLALInitCode ( ConfigVariables *cfg, const UserVariables_t *uvar, const char *app_name) { XLAL_CHECK ( cfg && uvar && app_name, XLAL_EINVAL, "Illegal NULL pointer input." ); /* init ephemeris data */ XLAL_CHECK ( ( cfg->edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun ) ) != NULL, XLAL_EFUNC, "XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s.", uvar->ephemEarth, uvar->ephemSun); cfg->numDetectors = uvar->IFOs->length; cfg->numTimeStamps = 0; XLAL_CHECK ( (cfg->numTimeStampsX = XLALCreateUINT4Vector ( cfg->numDetectors )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(%d) failed.", cfg->numDetectors ); BOOLEAN haveTimeGPS = XLALUserVarWasSet( &uvar->timeGPS ); BOOLEAN haveTimeStampsFile = XLALUserVarWasSet( &uvar->timeStampsFile ); BOOLEAN haveTimeStampsFiles = XLALUserVarWasSet( &uvar->timeStampsFiles ); XLAL_CHECK ( !(haveTimeStampsFiles && haveTimeStampsFile), XLAL_EINVAL, "Can't handle both timeStampsFiles and (deprecated) haveTimeStampsFiles input options." ); XLAL_CHECK ( !(haveTimeGPS && haveTimeStampsFile), XLAL_EINVAL, "Can't handle both (deprecated) timeStampsFile and timeGPS input options." ); XLAL_CHECK ( !(haveTimeGPS && haveTimeStampsFiles), XLAL_EINVAL, "Can't handle both timeStampsFiles and timeGPS input options." ); XLAL_CHECK ( haveTimeGPS || haveTimeStampsFiles || haveTimeStampsFile, XLAL_EINVAL, "Need either timeStampsFiles or timeGPS input option." ); if ( haveTimeStampsFiles ) { XLAL_CHECK ( (uvar->timeStampsFiles->length == 1 ) || ( uvar->timeStampsFiles->length == cfg->numDetectors ), XLAL_EINVAL, "Length of timeStampsFiles list is neither 1 (one file for all detectors) nor does it match the number of detectors. (%d != %d)", uvar->timeStampsFiles->length, cfg->numDetectors ); XLAL_CHECK ( (uvar->timeStampsFiles->length == 1 ) || !uvar->outab, XLAL_EINVAL, "At the moment, can't produce a(t), b(t) output (--outab) when given per-IFO --timeStampsFiles."); } if ( haveTimeStampsFiles && ( uvar->timeStampsFiles->length == cfg->numDetectors ) ) { XLAL_CHECK ( ( cfg->multiTimestamps = XLALReadMultiTimestampsFiles ( uvar->timeStampsFiles ) ) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (cfg->multiTimestamps->length > 0) && (cfg->multiTimestamps->data != NULL), XLAL_EINVAL, "Got empty timestamps-list from '%s'.", uvar->timeStampsFiles ); } else { /* prepare multiTimestamps structure */ UINT4 nTS = 0; XLAL_CHECK ( ( cfg->multiTimestamps = XLALCalloc ( 1, sizeof(*cfg->multiTimestamps))) != NULL, XLAL_ENOMEM, "Allocating multiTimestamps failed." ); XLAL_CHECK ( ( cfg->multiTimestamps->data = XLALCalloc ( cfg->numDetectors, sizeof(cfg->multiTimestamps->data) )) != NULL, XLAL_ENOMEM, "Allocating multiTimestamps->data failed." ); cfg->multiTimestamps->length = cfg->numDetectors; if ( haveTimeGPS ) { /* set up timestamps vector from timeGPS, use same for all IFOs */ nTS = uvar->timeGPS->length; XLAL_CHECK ( (cfg->multiTimestamps->data[0] = XLALCreateTimestampVector ( nTS ) ) != NULL, XLAL_EFUNC, "XLALCreateTimestampVector( %d ) failed.", nTS ); /* convert input REAL8 times into LIGOTimeGPS for first detector */ for (UINT4 t = 0; t < nTS; t++) { REAL8 temp_real8_timestamp = 0; XLAL_CHECK ( 1 == sscanf ( uvar->timeGPS->data[t], "%" LAL_REAL8_FORMAT, &temp_real8_timestamp ), XLAL_EINVAL, "Illegal REAL8 commandline argument to --timeGPS[%d]: '%s'", t, uvar->timeGPS->data[t] ); XLAL_CHECK ( XLALGPSSetREAL8( &cfg->multiTimestamps->data[0]->data[t], temp_real8_timestamp ) != NULL, XLAL_EFUNC, "Failed to convert input GPS %g into LIGOTimeGPS", temp_real8_timestamp ); } // for (UINT4 t = 0; t < nTS; t++) } // if ( haveTimeGPS ) else { // haveTimeStampsFiles || haveTimeStampsFile CHAR *singleTimeStampsFile = NULL; if ( haveTimeStampsFiles ) { singleTimeStampsFile = uvar->timeStampsFiles->data[0]; } else if ( haveTimeStampsFile ) { singleTimeStampsFile = uvar->timeStampsFile; } XLAL_CHECK ( ( cfg->multiTimestamps->data[0] = XLALReadTimestampsFile ( singleTimeStampsFile ) ) != NULL, XLAL_EFUNC ); nTS = cfg->multiTimestamps->data[0]->length; } // else: haveTimeStampsFiles || haveTimeStampsFile /* copy timestamps from first detector to all others */ if ( cfg->numDetectors > 1 ) { for ( UINT4 X=1; X < cfg->numDetectors; X++ ) { XLAL_CHECK ( (cfg->multiTimestamps->data[X] = XLALCreateTimestampVector ( nTS ) ) != NULL, XLAL_EFUNC, "XLALCreateTimestampVector( %d ) failed.", nTS ); for (UINT4 t = 0; t < nTS; t++) { cfg->multiTimestamps->data[X]->data[t].gpsSeconds = cfg->multiTimestamps->data[0]->data[t].gpsSeconds; cfg->multiTimestamps->data[X]->data[t].gpsNanoSeconds = cfg->multiTimestamps->data[0]->data[t].gpsNanoSeconds; } // for (UINT4 t = 0; t < nTS; t++) } // for ( UINT4 X=1; X < cfg->numDetectors X++ ) } // if ( cfg->numDetectors > 1 ) } // if !( haveTimeStampsFiles && ( uvar->timeStampsFiles->length == cfg->numDetectors ) ) for ( UINT4 X=0; X < cfg->numDetectors; X++ ) { cfg->numTimeStampsX->data[X] = cfg->multiTimestamps->data[X]->length; cfg->numTimeStamps += cfg->numTimeStampsX->data[X]; } /* convert detector names into site-info */ MultiLALDetector multiDet; XLAL_CHECK ( XLALParseMultiLALDetector ( &multiDet, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); /* get detector states */ XLAL_CHECK ( (cfg->multiDetStates = XLALGetMultiDetectorStates ( cfg->multiTimestamps, &multiDet, cfg->edat, 0.5 * uvar->Tsft )) != NULL, XLAL_EFUNC, "XLALGetDetectorStates() failed." ); BOOLEAN haveAlphaDelta = ( XLALUserVarWasSet(&uvar->Alpha) && XLALUserVarWasSet(&uvar->Delta) ); BOOLEAN haveSkyGrid = XLALUserVarWasSet( &uvar->skyGridFile ); XLAL_CHECK ( !(haveAlphaDelta && haveSkyGrid), XLAL_EINVAL, "Can't handle both Alpha/Delta and skyGridFile input options." ); XLAL_CHECK ( haveAlphaDelta || haveSkyGrid, XLAL_EINVAL, "Need either Alpha/Delta or skyGridFile input option." ); if (haveAlphaDelta) { /* parse this into one-element Alpha, Delta vectors */ XLAL_CHECK ( (cfg->Alpha = XLALCreateREAL8Vector ( 1 )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(1) failed." ); cfg->Alpha->data[0] = uvar->Alpha; XLAL_CHECK ( (cfg->Delta = XLALCreateREAL8Vector ( 1 )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(1) failed." ); cfg->Delta->data[0] = uvar->Delta; cfg->numSkyPoints = 1; } // if (haveAlphaDelta) else if ( haveSkyGrid ) { LALParsedDataFile *data = NULL; XLAL_CHECK ( XLALParseDataFile (&data, uvar->skyGridFile) == XLAL_SUCCESS, XLAL_EFUNC, "Failed to parse data file '%s'.", uvar->skyGridFile ); cfg->numSkyPoints = data->lines->nTokens; XLAL_CHECK ( (cfg->Alpha = XLALCreateREAL8Vector ( cfg->numSkyPoints )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector( %d ) failed.", cfg->numSkyPoints ); XLAL_CHECK ( (cfg->Delta = XLALCreateREAL8Vector ( cfg->numSkyPoints )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector( %d ) failed.", cfg->numSkyPoints ); for (UINT4 n=0; n < cfg->numSkyPoints; n++) { XLAL_CHECK ( 2 == sscanf( data->lines->tokens[n], "%" LAL_REAL8_FORMAT "%" LAL_REAL8_FORMAT, &cfg->Alpha->data[n], &cfg->Delta->data[n] ), XLAL_EDATA, "Could not parse 2 numbers from line %d in candidate-file '%s':\n'%s'", n, uvar->skyGridFile, data->lines->tokens[n] ); } // for (UINT4 n=0; n < cfg->numSkyPoints; n++) XLALDestroyParsedDataFile ( data ); } // else if ( haveSkyGrid ) if ( uvar->noiseSqrtShX ) { /* translate user-input PSD sqrt(SX) to noise-weights (this actually does not care whether they were normalized or not) */ if ( uvar->noiseSqrtShX->length != cfg->numDetectors ) { fprintf(stderr, "Length of noiseSqrtShX vector does not match number of detectors! (%d != %d)\n", uvar->noiseSqrtShX->length, cfg->numDetectors); XLAL_ERROR ( XLAL_EINVAL ); } REAL8Vector *noiseSqrtShX = NULL; if ( (noiseSqrtShX = XLALCreateREAL8Vector ( cfg->numDetectors )) == NULL ) { fprintf(stderr, "Failed call to XLALCreateREAL8Vector( %d )\n", cfg->numDetectors ); XLAL_ERROR ( XLAL_EFUNC ); } REAL8 psd_normalization = 0; for (UINT4 X = 0; X < cfg->numDetectors; X++) { if ( 1 != sscanf ( uvar->noiseSqrtShX->data[X], "%" LAL_REAL8_FORMAT, &noiseSqrtShX->data[X] ) ) { fprintf(stderr, "Illegal REAL8 commandline argument to --noiseSqrtShX[%d]: '%s'\n", X, uvar->noiseSqrtShX->data[X]); XLAL_ERROR ( XLAL_EINVAL ); } if ( noiseSqrtShX->data[X] <= 0.0 ) { fprintf(stderr, "Non-positive input PSD ratio for detector X=%d: noiseSqrtShX[X]=%f\n", X, noiseSqrtShX->data[X] ); XLAL_ERROR ( XLAL_EINVAL ); } psd_normalization += 1.0/SQ(noiseSqrtShX->data[X]); } /* for X < cfg->numDetectors */ psd_normalization = (REAL8)cfg->numDetectors/psd_normalization; /* S = NSFT / sum S_Xalpha^-1, no per-SFT variation here -> S = Ndet / sum S_X^-1 */ /* create multi noise weights */ if ( (cfg->multiNoiseWeights = XLALCalloc(1, sizeof(*cfg->multiNoiseWeights))) == NULL ) { XLALPrintError ("%s: failed to XLALCalloc ( 1, %d )\n", __func__, sizeof(*cfg->multiNoiseWeights) ); XLAL_ERROR ( XLAL_ENOMEM ); } if ( (cfg->multiNoiseWeights->data = XLALCalloc(cfg->numDetectors, sizeof(*cfg->multiNoiseWeights->data))) == NULL ) { XLALPrintError ("%s: failed to XLALCalloc ( %d, %d )\n", __func__, cfg->numDetectors, sizeof(*cfg->multiNoiseWeights->data) ); XLAL_ERROR ( XLAL_ENOMEM ); } cfg->multiNoiseWeights->length = cfg->numDetectors; for (UINT4 X = 0; X < cfg->numDetectors; X++) { REAL8 noise_weight_X = psd_normalization/SQ(noiseSqrtShX->data[X]); /* w_Xalpha = S_Xalpha^-1/S^-1 = S / S_Xalpha */ /* create k^th weights vector */ if( ( cfg->multiNoiseWeights->data[X] = XLALCreateREAL8Vector ( cfg->numTimeStampsX->data[X] ) ) == NULL ) { /* free weights vectors created previously in loop */ XLALDestroyMultiNoiseWeights ( cfg->multiNoiseWeights ); XLAL_ERROR ( XLAL_EFUNC, "Failed to allocate noiseweights for IFO X = %d\n", X ); } /* if XLALCreateREAL8Vector() failed */ /* loop over rngmeds and calculate weights -- one for each sft */ for ( UINT4 alpha = 0; alpha < cfg->numTimeStampsX->data[X]; alpha++) { cfg->multiNoiseWeights->data[X]->data[alpha] = noise_weight_X; } } /* for X < cfg->numDetectors */ XLALDestroyREAL8Vector ( noiseSqrtShX ); } /* if ( uvar->noiseSqrtShX ) */ else { cfg->multiNoiseWeights = NULL; } return XLAL_SUCCESS; } /* XLALInitCode() */
/** * Generates the ringdown wave associated with the given real * and imaginary parts of the inspiral waveform. The parameters of * the ringdown, such as amplitude and phase offsets, are determined * by solving the linear equations defined in the DCC document T1100433. * In the linear equations Ax=y, * A is a 16-by-16 matrix depending on QNM (complex) frequencies, * x is a 16-d vector of the 8 unknown complex QNM amplitudes, * y is a 16-d vector depending on inspiral-plunge waveforms and their derivatives near merger. */ static INT4 XLALSimIMREOBHybridRingdownWave( REAL8Vector *rdwave1, /**<< OUTPUT, Real part of ringdown waveform */ REAL8Vector *rdwave2, /**<< OUTPUT, Imag part of ringdown waveform */ const REAL8 dt, /**<< Sampling interval */ const REAL8 mass1, /**<< First component mass (in Solar masses) */ const REAL8 mass2, /**<< Second component mass (in Solar masses) */ REAL8VectorSequence *inspwave1, /**<< Values and derivs of real part inspiral waveform */ REAL8VectorSequence *inspwave2, /**<< Values and derivs of imag part inspiral waveform */ COMPLEX16Vector *modefreqs, /**<< Complex freqs of ringdown (scaled by total mass) */ REAL8Vector *matchrange /**<< Times which determine the comb of ringdown attachment */ ) { /* XLAL error handling */ INT4 errcode = XLAL_SUCCESS; /* For checking GSL return codes */ INT4 gslStatus; UINT4 i, j, k, nmodes = 8; /* Sampling rate from input */ REAL8 t1, t2, t3, t4, t5, rt; gsl_matrix *coef; gsl_vector *hderivs; gsl_vector *x; gsl_permutation *p; REAL8Vector *modeamps; int s; REAL8 tj; REAL8 m; /* mass in geometric units */ m = (mass1 + mass2) * LAL_MTSUN_SI; t5 = (matchrange->data[0] - matchrange->data[1]) * m; rt = -t5 / 5.; t4 = t5 + rt; t3 = t4 + rt; t2 = t3 + rt; t1 = t2 + rt; if ( inspwave1->length != 3 || inspwave2->length != 3 || modefreqs->length != nmodes ) { XLAL_ERROR( XLAL_EBADLEN ); } /* Solving the linear system for QNMs amplitude coefficients using gsl routine */ /* Initiate matrices and supporting variables */ XLAL_CALLGSL( coef = (gsl_matrix *) gsl_matrix_alloc(2 * nmodes, 2 * nmodes) ); XLAL_CALLGSL( hderivs = (gsl_vector *) gsl_vector_alloc(2 * nmodes) ); XLAL_CALLGSL( x = (gsl_vector *) gsl_vector_alloc(2 * nmodes) ); XLAL_CALLGSL( p = (gsl_permutation *) gsl_permutation_alloc(2 * nmodes) ); /* Check all matrices and variables were allocated */ if ( !coef || !hderivs || !x || !p ) { if (coef) gsl_matrix_free(coef); if (hderivs) gsl_vector_free(hderivs); if (x) gsl_vector_free(x); if (p) gsl_permutation_free(p); XLAL_ERROR( XLAL_ENOMEM ); } /* Define the linear system Ax=y */ /* Matrix A (2*n by 2*n) has block symmetry. Define half of A here as "coef" */ /* The half of A defined here corresponds to matrices M1 and -M2 in the DCC document T1100433 */ /* Define y here as "hderivs" */ for (i = 0; i < nmodes; ++i) { gsl_matrix_set(coef, 0, i, 1); gsl_matrix_set(coef, 1, i, - cimag(modefreqs->data[i])); gsl_matrix_set(coef, 2, i, exp(-cimag(modefreqs->data[i])*t1) * cos(creal(modefreqs->data[i])*t1)); gsl_matrix_set(coef, 3, i, exp(-cimag(modefreqs->data[i])*t2) * cos(creal(modefreqs->data[i])*t2)); gsl_matrix_set(coef, 4, i, exp(-cimag(modefreqs->data[i])*t3) * cos(creal(modefreqs->data[i])*t3)); gsl_matrix_set(coef, 5, i, exp(-cimag(modefreqs->data[i])*t4) * cos(creal(modefreqs->data[i])*t4)); gsl_matrix_set(coef, 6, i, exp(-cimag(modefreqs->data[i])*t5) * cos(creal(modefreqs->data[i])*t5)); gsl_matrix_set(coef, 7, i, exp(-cimag(modefreqs->data[i])*t5) * (-cimag(modefreqs->data[i]) * cos(creal(modefreqs->data[i])*t5) -creal(modefreqs->data[i]) * sin(creal(modefreqs->data[i])*t5))); gsl_matrix_set(coef, 8, i, 0); gsl_matrix_set(coef, 9, i, - creal(modefreqs->data[i])); gsl_matrix_set(coef, 10, i, -exp(-cimag(modefreqs->data[i])*t1) * sin(creal(modefreqs->data[i])*t1)); gsl_matrix_set(coef, 11, i, -exp(-cimag(modefreqs->data[i])*t2) * sin(creal(modefreqs->data[i])*t2)); gsl_matrix_set(coef, 12, i, -exp(-cimag(modefreqs->data[i])*t3) * sin(creal(modefreqs->data[i])*t3)); gsl_matrix_set(coef, 13, i, -exp(-cimag(modefreqs->data[i])*t4) * sin(creal(modefreqs->data[i])*t4)); gsl_matrix_set(coef, 14, i, -exp(-cimag(modefreqs->data[i])*t5) * sin(creal(modefreqs->data[i])*t5)); gsl_matrix_set(coef, 15, i, exp(-cimag(modefreqs->data[i])*t5) * ( cimag(modefreqs->data[i]) * sin(creal(modefreqs->data[i])*t5) -creal(modefreqs->data[i]) * cos(creal(modefreqs->data[i])*t5))); } for (i = 0; i < 2; ++i) { gsl_vector_set(hderivs, i, inspwave1->data[(i + 1) * inspwave1->vectorLength - 1]); gsl_vector_set(hderivs, i + nmodes, inspwave2->data[(i + 1) * inspwave2->vectorLength - 1]); gsl_vector_set(hderivs, i + 6, inspwave1->data[i * inspwave1->vectorLength]); gsl_vector_set(hderivs, i + 6 + nmodes, inspwave2->data[i * inspwave2->vectorLength]); } gsl_vector_set(hderivs, 2, inspwave1->data[4]); gsl_vector_set(hderivs, 2 + nmodes, inspwave2->data[4]); gsl_vector_set(hderivs, 3, inspwave1->data[3]); gsl_vector_set(hderivs, 3 + nmodes, inspwave2->data[3]); gsl_vector_set(hderivs, 4, inspwave1->data[2]); gsl_vector_set(hderivs, 4 + nmodes, inspwave2->data[2]); gsl_vector_set(hderivs, 5, inspwave1->data[1]); gsl_vector_set(hderivs, 5 + nmodes, inspwave2->data[1]); /* Complete the definition for the rest half of A */ for (i = 0; i < nmodes; ++i) { for (k = 0; k < nmodes; ++k) { gsl_matrix_set(coef, i, k + nmodes, - gsl_matrix_get(coef, i + nmodes, k)); gsl_matrix_set(coef, i + nmodes, k + nmodes, gsl_matrix_get(coef, i, k)); } } #if 0 /* print ringdown-matching linear system: coefficient matrix and RHS vector */ printf("\nRingdown matching matrix:\n"); for (i = 0; i < 16; ++i) { for (j = 0; j < 16; ++j) { printf("%.12e ",gsl_matrix_get(coef,i,j)); } printf("\n"); } printf("RHS: "); for (i = 0; i < 16; ++i) { printf("%.12e ",gsl_vector_get(hderivs,i)); } printf("\n"); #endif /* Call gsl LU decomposition to solve the linear system */ XLAL_CALLGSL( gslStatus = gsl_linalg_LU_decomp(coef, p, &s) ); if ( gslStatus == GSL_SUCCESS ) { XLAL_CALLGSL( gslStatus = gsl_linalg_LU_solve(coef, p, hderivs, x) ); } if ( gslStatus != GSL_SUCCESS ) { gsl_matrix_free(coef); gsl_vector_free(hderivs); gsl_vector_free(x); gsl_permutation_free(p); XLAL_ERROR( XLAL_EFUNC ); } /* Putting solution to an XLAL vector */ modeamps = XLALCreateREAL8Vector(2 * nmodes); if ( !modeamps ) { gsl_matrix_free(coef); gsl_vector_free(hderivs); gsl_vector_free(x); gsl_permutation_free(p); XLAL_ERROR( XLAL_ENOMEM ); } for (i = 0; i < nmodes; ++i) { modeamps->data[i] = gsl_vector_get(x, i); modeamps->data[i + nmodes] = gsl_vector_get(x, i + nmodes); } /* Free all gsl linear algebra objects */ gsl_matrix_free(coef); gsl_vector_free(hderivs); gsl_vector_free(x); gsl_permutation_free(p); /* Build ring-down waveforms */ REAL8 timeOffset = fmod( matchrange->data[1], dt/m) * dt; for (j = 0; j < rdwave1->length; ++j) { tj = j * dt - timeOffset; rdwave1->data[j] = 0; rdwave2->data[j] = 0; for (i = 0; i < nmodes; ++i) { rdwave1->data[j] += exp(- tj * cimag(modefreqs->data[i])) * ( modeamps->data[i] * cos(tj * creal(modefreqs->data[i])) + modeamps->data[i + nmodes] * sin(tj * creal(modefreqs->data[i])) ); rdwave2->data[j] += exp(- tj * cimag(modefreqs->data[i])) * (- modeamps->data[i] * sin(tj * creal(modefreqs->data[i])) + modeamps->data[i + nmodes] * cos(tj * creal(modefreqs->data[i])) ); } } XLALDestroyREAL8Vector(modeamps); return errcode; }
/** * Given the trajectory in an inertial frame, this computes Euler angles * of the roation from the inertial frame to the minimal-rotation frame * that co-precesses with LN(t) = rvec(t) x rdotvec(t) */ static int EulerAnglesI2P(REAL8Vector *Alpha, /**<< output: alpha Euler angle */ REAL8Vector *Beta, /**<< output: beta Euler angle */ REAL8Vector *Gamma, /**<< output: gamma Euler angle */ INT4 *phaseCounterA, /**<< output: counter for unwrapping of alpha */ INT4 *phaseCounterB, /**<< output: counter for unwrapping of beta */ const REAL8Vector tVec, /**<< time series */ const REAL8Vector posVecx, /**<< x time series */ const REAL8Vector posVecy, /**<< y time series */ const REAL8Vector posVecz, /**<< z time series */ const UINT4 retLenLow, /**<< Array length of the trajectory */ const REAL8 InitialAlpha, /**<< Initial alpha (used only if flag_highSR=1) */ const REAL8 InitialGamma, /**<< Initial gamma */ UINT4 flag_highSR /**<< Flag to indicate whether one is analyzing the high SR trajectory */) { UINT4 i = 0; REAL8Vector *LN_x = NULL, *LN_y = NULL, *LN_z = NULL; REAL8 tmpR[3], tmpRdot[3], magLN; REAL8 precEulerresult = 0, precEulererror = 0; gsl_integration_workspace * precEulerw = gsl_integration_workspace_alloc (1000); gsl_function precEulerF; PrecEulerAnglesIntegration precEulerparams; REAL8 inGamma = InitialGamma; LN_x = XLALCreateREAL8Vector( retLenLow ); LN_y = XLALCreateREAL8Vector( retLenLow ); LN_z = XLALCreateREAL8Vector( retLenLow ); gsl_spline *x_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow ); gsl_spline *y_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow ); gsl_spline *z_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow ); gsl_interp_accel *x_acc = gsl_interp_accel_alloc(); gsl_interp_accel *y_acc = gsl_interp_accel_alloc(); gsl_interp_accel *z_acc = gsl_interp_accel_alloc(); gsl_spline_init( x_spline, tVec.data, posVecx.data, retLenLow ); gsl_spline_init( y_spline, tVec.data, posVecy.data, retLenLow ); gsl_spline_init( z_spline, tVec.data, posVecz.data, retLenLow ); for( i=0; i < retLenLow; i++ ) { tmpR[0] = posVecx.data[i]; tmpR[1] = posVecy.data[i]; tmpR[2] = posVecz.data[i]; tmpRdot[0] = gsl_spline_eval_deriv( x_spline, tVec.data[i], x_acc ); tmpRdot[1] = gsl_spline_eval_deriv( y_spline, tVec.data[i], y_acc ); tmpRdot[2] = gsl_spline_eval_deriv( z_spline, tVec.data[i], z_acc ); LN_x->data[i] = tmpR[1] * tmpRdot[2] - tmpR[2] * tmpRdot[1]; LN_y->data[i] = tmpR[2] * tmpRdot[0] - tmpR[0] * tmpRdot[2]; LN_z->data[i] = tmpR[0] * tmpRdot[1] - tmpR[1] * tmpRdot[0]; magLN = sqrt(LN_x->data[i] * LN_x->data[i] + LN_y->data[i] * LN_y->data[i] + LN_z->data[i] * LN_z->data[i]); LN_x->data[i] /= magLN; LN_y->data[i] /= magLN; LN_z->data[i] /= magLN; /* Eq. 19 of PRD 89, 084006 (2014) */ /* Also unwrap the two angles */ if (fabs(LN_x->data[i]) <= 1.e-10 && fabs(LN_y->data[i]) <=1.e-10){ Alpha->data[i] = 0.0; inGamma = 0.0; } else { Alpha->data[i] = atan2( LN_y->data[i], LN_x->data[i] ) + *phaseCounterA * LAL_TWOPI; if (i==0 && flag_highSR != 1){ inGamma = -Alpha->data[i]; } } if( i>0 && Alpha->data[i] - Alpha->data[i-1] > 5. ) { *phaseCounterA = *phaseCounterA - 1; Alpha->data[i] -= LAL_TWOPI; } else if ( i && Alpha->data[i] - Alpha->data[i-1] < -5. ) { *phaseCounterA = *phaseCounterA + 1; Alpha->data[i] += LAL_TWOPI; } if (LN_z->data[i] >1.) { LN_z->data[i] = 1.; } if (LN_z->data[i] <-1.) { LN_z->data[i] = -1.; } if ( flag_highSR == 1) { Alpha->data[i] -= (Alpha->data[0] - InitialAlpha); } if (fabs(1.0 - LN_z->data[i]) < 1.e-12){ REAL8 LN_xy; LN_xy = sqrt(LN_x->data[i]*LN_x->data[i] + LN_y->data[i]*LN_y->data[i]); //LN_z->data[i] = sqrt(1.0 - LN_xy*LN_xy); Beta->data[i] = atan2(LN_xy, LN_z->data[i]); //printf("here "); }else{ Beta->data[i] = acos( LN_z->data[i] ); } if( i>0 && Beta->data[i] > Beta->data[i-1] ) { *phaseCounterB = *phaseCounterB - 1; } } /* Integrate \dot{\alpha} \cos{\beta} to get the final Euler angle Eq. 20 of PRD 89, 084006 (2014) */ gsl_spline_init( x_spline, tVec.data, Alpha->data, retLenLow ); gsl_spline_init( y_spline, tVec.data, Beta->data, retLenLow ); precEulerparams.alpha_spline = x_spline; precEulerparams.alpha_acc = x_acc; precEulerparams.beta_spline = y_spline; precEulerparams.beta_acc = y_acc; precEulerF.function = &f_alphadotcosi; precEulerF.params = &precEulerparams; for( i = 0; i < retLenLow; i++ ) { //if( i==0 ) { Gamma->data[i] = InitialGamma; } if( i==0 ) { Gamma->data[i] = inGamma; } else { gsl_integration_qags (&precEulerF, tVec.data[i-1], tVec.data[i], 1e-9, 1e-9, 1000, precEulerw, &precEulerresult, &precEulererror); Gamma->data[i] = Gamma->data[i-1] + precEulerresult; } } gsl_integration_workspace_free( precEulerw ); gsl_spline_free( x_spline ); gsl_spline_free( y_spline ); gsl_spline_free( z_spline ); gsl_interp_accel_free( x_acc ); gsl_interp_accel_free( y_acc ); gsl_interp_accel_free( z_acc ); XLALDestroyREAL8Vector( LN_x ); XLALDestroyREAL8Vector( LN_y ); XLALDestroyREAL8Vector( LN_z ); return XLAL_SUCCESS; }
/** * Unit test for metric functions XLALComputeDopplerPhaseMetric() * and XLALComputeDopplerFstatMetric() * * Initially modelled afer testMetricCodes.py script: * Check metric codes 'getMetric' 'FstatMetric' and 'FstatMetric_v2' by * comparing them against each other. * Given that they represent 3 very different implementations of * metric calculations, this provides a very powerful consistency test * */ static int test_XLALComputeDopplerMetrics ( void ) { int ret; const REAL8 tolPh = 0.01; // 1% tolerance on phase metrics [taken from testMetricCodes.py] // ----- load ephemeris const char earthEphem[] = TEST_DATA_DIR "earth00-19-DE200.dat.gz"; const char sunEphem[] = TEST_DATA_DIR "sun00-19-DE200.dat.gz"; EphemerisData *edat = XLALInitBarycenter ( earthEphem, sunEphem ); XLAL_CHECK ( edat != NULL, XLAL_EFUNC, "XLALInitBarycenter('%s','%s') failed with xlalErrno = %d\n", earthEphem, sunEphem, xlalErrno ); // ----- set test-parameters ---------- const LIGOTimeGPS startTimeGPS = { 792576013, 0 }; const REAL8 Tseg = 60000; const REAL8 Alpha = 1.0; const REAL8 Delta = 0.5; const REAL8 Freq = 100; const REAL8 f1dot = 0;// -1e-8; LALStringVector *detNames = XLALCreateStringVector ( "H1", "L1", "V1", NULL ); LALStringVector *sqrtSX = XLALCreateStringVector ( "1.0", "0.5", "1.5", NULL ); MultiLALDetector multiIFO; XLAL_CHECK ( XLALParseMultiLALDetector ( &multiIFO, detNames ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyStringVector ( detNames ); MultiNoiseFloor multiNoiseFloor; XLAL_CHECK ( XLALParseMultiNoiseFloor ( &multiNoiseFloor, sqrtSX, multiIFO.length ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyStringVector ( sqrtSX ); // prepare metric parameters for modern XLALComputeDopplerFstatMetric() and mid-old XLALOldDopplerFstatMetric() const DopplerCoordinateSystem coordSys = { 4, { DOPPLERCOORD_FREQ, DOPPLERCOORD_ALPHA, DOPPLERCOORD_DELTA, DOPPLERCOORD_F1DOT } }; const PulsarAmplitudeParams Amp = { 0.03, -0.3, 0.5, 0.0 }; // h0, cosi, psi, phi0 const PulsarDopplerParams dop = { .refTime = startTimeGPS, .Alpha = Alpha, .Delta = Delta, .fkdot = { Freq, f1dot }, }; LALSegList XLAL_INIT_DECL(segList); ret = XLALSegListInitSimpleSegments ( &segList, startTimeGPS, 1, Tseg ); XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno ); const DopplerMetricParams master_pars2 = { .coordSys = coordSys, .detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT, .segmentList = segList, .multiIFO = multiIFO, .multiNoiseFloor = multiNoiseFloor, .signalParams = { .Amp = Amp, .Doppler = dop }, .projectCoord = - 1, // -1==no projection .approxPhase = 0, }; // ----- prepare call-parameters of ancient LALPulsarMetric() LALStatus XLAL_INIT_DECL(status); REAL4 master_pars0_spindown_data[1] = { f1dot / Freq }; /* 'old-style' "f1" = f1dot / Freq !!*/ REAL4Vector master_pars0_spindown = { .length = 1, .data = master_pars0_spindown_data }; const PtoleMetricIn master_pars0 = { .spindown = &master_pars0_spindown, .position = { .longitude = Alpha, .latitude = Delta, .system = COORDINATESYSTEM_EQUATORIAL }, .epoch = startTimeGPS, .duration = Tseg, .maxFreq = Freq, .site = &(multiIFO.sites[0]), // use first detector for phase-metric .ephemeris = edat, .metricType = LAL_PMETRIC_COH_EPHEM, }; // ========== BEGINNING OF TEST CALLS ========== XLALPrintWarning("\n---------- ROUND 1: ephemeris-based, single-IFO phase metrics ----------\n"); { REAL8Vector *metric0 = 0; gsl_matrix *g0_ij; OldDopplerMetric *metric1; DopplerPhaseMetric *metric2P; REAL8 diff_2_0, diff_2_1, diff_1_0; PtoleMetricIn pars0 = master_pars0; DopplerMetricParams pars2 = master_pars2; pars2.multiIFO.length = 1; // truncate to first detector pars2.multiNoiseFloor.length = 1; // truncate to first detector // 0) compute metric using ancient LALPulsarMetric() function (used in lalapps_getMetric) LALPulsarMetric ( &status, &metric0, &pars0 ); XLAL_CHECK ( status.statusCode == 0, XLAL_EFAILED, "LALPulsarMetric() failed with status=%d: '%s'\n", status.statusCode, status.statusDescription ); XLAL_CHECK ( (g0_ij = convert_old_metric_2_new ( metric0, Freq )) != NULL, XLAL_EFUNC ); XLALDestroyREAL8Vector ( metric0 ); metric0 = NULL; // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric() XLAL_CHECK ( (metric1 = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_PHASE, &pars2, edat )) != NULL, XLAL_EFUNC ); // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2) XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC ); // compare all 3 metrics against each other: XLAL_CHECK ( (diff_2_0 = XLALCompareMetrics ( metric2P->g_ij, g0_ij )) < tolPh, XLAL_ETOL, "Error(g2,g0)= %g exceeds tolerance of %g\n", diff_2_0, tolPh ); XLALPrintWarning ("diff_2_0 = %e\n", diff_2_0 ); XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2P->g_ij, metric1->g_ij )) < tolPh, XLAL_ETOL, "Error(g2,g1)= %g exceeds tolerance of %g\n", diff_2_1, tolPh ); XLALPrintWarning ("diff_2_1 = %e\n", diff_2_1 ); XLAL_CHECK ( (diff_1_0 = XLALCompareMetrics ( metric1->g_ij, g0_ij )) < tolPh, XLAL_ETOL, "Error(g1,g0)= %g exceeds tolerance of %g\n", diff_1_0, tolPh ); XLALPrintWarning ("diff_1_0 = %e\n", diff_1_0 ); gsl_matrix_free ( g0_ij ); XLALDestroyOldDopplerMetric ( metric1 ); XLALDestroyDopplerPhaseMetric ( metric2P ); } XLALPrintWarning("\n---------- ROUND 2: Ptolemaic-based, single-IFO phase metrics ----------\n"); { REAL8Vector *metric0 = 0; gsl_matrix *g0_ij; OldDopplerMetric *metric1; DopplerPhaseMetric *metric2P; REAL8 diff_2_0, diff_2_1, diff_1_0; PtoleMetricIn pars0 = master_pars0; DopplerMetricParams pars2 = master_pars2; pars2.multiIFO.length = 1; // truncate to first detector pars2.multiNoiseFloor.length = 1; // truncate to first detector pars0.metricType = LAL_PMETRIC_COH_PTOLE_ANALYTIC; pars2.detMotionType = DETMOTION_SPIN | DETMOTION_PTOLEORBIT; // 0) compute metric using ancient LALPulsarMetric() function (used in lalapps_getMetric) LALPulsarMetric ( &status, &metric0, &pars0 ); XLAL_CHECK ( status.statusCode == 0, XLAL_EFAILED, "LALPulsarMetric() failed with status=%d: '%s'\n", status.statusCode, status.statusDescription ); XLAL_CHECK ( (g0_ij = convert_old_metric_2_new ( metric0, Freq )) != NULL, XLAL_EFUNC ); XLALDestroyREAL8Vector ( metric0 ); metric0 = NULL; // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric() XLAL_CHECK ( (metric1 = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_PHASE, &pars2, edat )) != NULL, XLAL_EFUNC ); // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2) XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC ); // compare all 3 metrics against each other: XLAL_CHECK ( (diff_2_0 = XLALCompareMetrics ( metric2P->g_ij, g0_ij )) < tolPh, XLAL_ETOL, "Error(g2,g0)= %g exceeds tolerance of %g\n", diff_2_0, tolPh ); XLALPrintWarning ("diff_2_0 = %e\n", diff_2_0 ); XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2P->g_ij, metric1->g_ij )) < tolPh, XLAL_ETOL, "Error(g2,g1)= %g exceeds tolerance of %g\n", diff_2_1, tolPh ); XLALPrintWarning ("diff_2_1 = %e\n", diff_2_1 ); XLAL_CHECK ( (diff_1_0 = XLALCompareMetrics ( metric1->g_ij, g0_ij )) < tolPh, XLAL_ETOL, "Error(g1,g0)= %g exceeds tolerance of %g\n", diff_1_0, tolPh ); XLALPrintWarning ("diff_1_0 = %e\n", diff_1_0 ); gsl_matrix_free ( g0_ij ); XLALDestroyOldDopplerMetric ( metric1 ); XLALDestroyDopplerPhaseMetric ( metric2P ); } XLALPrintWarning("\n---------- ROUND 3: ephemeris-based, multi-IFO F-stat metrics ----------\n"); { OldDopplerMetric *metric1; DopplerFstatMetric *metric2F; REAL8 diff_2_1; DopplerMetricParams pars2 = master_pars2; pars2.detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT; pars2.multiIFO = multiIFO; // 3 IFOs pars2.multiNoiseFloor = multiNoiseFloor;// 3 IFOs // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric() XLAL_CHECK ( (metric1 = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_FSTAT, &pars2, edat )) != NULL, XLAL_EFUNC ); // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2) XLAL_CHECK ( (metric2F = XLALComputeDopplerFstatMetric ( &pars2, edat )) != NULL, XLAL_EFUNC ); // compare both metrics against each other: XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2F->gF_ij, metric1->gF_ij )) < tolPh, XLAL_ETOL, "Error(gF2,gF1)= %e exceeds tolerance of %e\n", diff_2_1, tolPh ); XLALPrintWarning ("gF: diff_2_1 = %e\n", diff_2_1 ); XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2F->gFav_ij, metric1->gFav_ij )) < tolPh, XLAL_ETOL, "Error(gFav2,gFav1)= %e exceeds tolerance of %e\n", diff_2_1, tolPh ); XLALPrintWarning ("gFav: diff_2_1 = %e\n", diff_2_1 ); XLALDestroyOldDopplerMetric ( metric1 ); XLALDestroyDopplerFstatMetric ( metric2F ); } XLALPrintWarning("\n---------- ROUND 4: compare analytic {f,f1dot,f2dot,f3dot} phase metric vs XLALComputeDopplerPhaseMetric() ----------\n"); { DopplerPhaseMetric *metric2P; REAL8 diff_2_1; DopplerMetricParams pars2 = master_pars2; pars2.multiIFO.length = 1; // truncate to 1st detector pars2.multiNoiseFloor.length = 1; // truncate to 1st detector pars2.detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT; pars2.approxPhase = 1; // use same phase-approximation as in analytic solution to improve comparison DopplerCoordinateSystem coordSys2 = { 4, { DOPPLERCOORD_FREQ, DOPPLERCOORD_F1DOT, DOPPLERCOORD_F2DOT, DOPPLERCOORD_F3DOT } }; pars2.coordSys = coordSys2; gsl_matrix* gN_ij; // a) compute metric at refTime = startTime pars2.signalParams.Doppler.refTime = startTimeGPS; XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC ); gN_ij = NULL; XLAL_CHECK ( XLALNaturalizeMetric ( &gN_ij, NULL, metric2P->g_ij, &pars2 ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 gStart_ij[] = { 1.0/3, 2.0/3, 6.0/5, 32.0/15, \ 2.0/3, 64.0/45, 8.0/3, 512.0/105, \ 6.0/5, 8.0/3, 36.0/7, 48.0/5, \ 32.0/15, 512.0/105, 48.0/5, 4096.0/225 }; const gsl_matrix_view gStart = gsl_matrix_view_array ( gStart_ij, 4, 4 ); // compare natural-units metric against analytic solution XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( gN_ij, &(gStart.matrix) )) < tolPh, XLAL_ETOL, "RefTime=StartTime: Error(g_ij,g_analytic)= %e exceeds tolerance of %e\n", diff_2_1, tolPh ); XLALPrintWarning ("Analytic (refTime=startTime): diff_2_1 = %e\n", diff_2_1 ); XLALDestroyDopplerPhaseMetric ( metric2P ); gsl_matrix_free ( gN_ij ); // b) compute metric at refTime = midTime pars2.signalParams.Doppler.refTime = startTimeGPS; pars2.signalParams.Doppler.refTime.gpsSeconds += Tseg / 2; XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC ); gN_ij = NULL; XLAL_CHECK ( XLALNaturalizeMetric ( &gN_ij, NULL, metric2P->g_ij, &pars2 ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 gMid_ij[] = { 1.0/3, 0, 1.0/5, 0, \ 0, 4.0/45, 0, 8.0/105, \ 1.0/5, 0, 1.0/7, 0, \ 0, 8.0/105, 0, 16.0/225 }; const gsl_matrix_view gMid = gsl_matrix_view_array ( gMid_ij, 4, 4 ); // compare natural-units metric against analytic solution XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( gN_ij, &(gMid.matrix) )) < tolPh, XLAL_ETOL, "RefTime=MidTime: Error(g_ij,g_analytic)= %e exceeds tolerance of %e\n", diff_2_1, tolPh ); XLALPrintWarning ("Analytic (refTime=midTime): diff_2_1 = %e\n\n", diff_2_1 ); XLALDestroyDopplerPhaseMetric ( metric2P ); gsl_matrix_free ( gN_ij ); } XLALPrintWarning("\n---------- ROUND 5: ephemeris-based, single-IFO, segment-averaged phase metrics ----------\n"); { OldDopplerMetric *metric1; DopplerPhaseMetric *metric2P; REAL8 diff_2_1; DopplerMetricParams pars2 = master_pars2; pars2.detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT; pars2.multiIFO.length = 1; // truncate to first detector pars2.multiNoiseFloor.length = 1; // truncate to first detector pars2.approxPhase = 1; const UINT4 Nseg = 10; LALSegList XLAL_INIT_DECL(NsegList); ret = XLALSegListInitSimpleSegments ( &NsegList, startTimeGPS, Nseg, Tseg ); XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno ); pars2.segmentList = NsegList; LALSegList XLAL_INIT_DECL(segList_k); LALSeg segment_k; XLALSegListInit( &segList_k ); // prepare single-segment list containing segment k segList_k.arraySize = 1; segList_k.length = 1; segList_k.segs = &segment_k; // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric() metric1 = NULL; for (UINT4 k = 0; k < Nseg; ++k) { // setup 1-segment segment-list pointing k-th segment DopplerMetricParams pars2_k = pars2; pars2_k.segmentList = segList_k; pars2_k.segmentList.segs[0] = pars2.segmentList.segs[k]; // XLALOldDopplerFstatMetric() does not agree numerically with UniversalDopplerMetric when using refTime != startTime pars2_k.signalParams.Doppler.refTime = pars2_k.segmentList.segs[0].start; OldDopplerMetric *metric1_k; // per-segment coherent metric XLAL_CHECK ( (metric1_k = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_PHASE, &pars2_k, edat )) != NULL, XLAL_EFUNC ); // manually correct reference time of metric1_k->g_ij; see Prix, "Frequency metric for CW searches" (2014-08-17), p. 4 const double dt = XLALGPSDiff( &(pars2_k.signalParams.Doppler.refTime), &(pars2.signalParams.Doppler.refTime) ); const double gFF = gsl_matrix_get( metric1_k->g_ij, 0, 0 ); const double gFA = gsl_matrix_get( metric1_k->g_ij, 0, 1 ); const double gFD = gsl_matrix_get( metric1_k->g_ij, 0, 2 ); const double gFf = gsl_matrix_get( metric1_k->g_ij, 0, 3 ); const double gAf = gsl_matrix_get( metric1_k->g_ij, 1, 3 ); const double gDf = gsl_matrix_get( metric1_k->g_ij, 2, 3 ); const double gff = gsl_matrix_get( metric1_k->g_ij, 3, 3 ); gsl_matrix_set( metric1_k->g_ij, 0, 3, gFf + gFF*dt ); gsl_matrix_set( metric1_k->g_ij, 3, 0, gsl_matrix_get( metric1_k->g_ij, 0, 3 ) ); gsl_matrix_set( metric1_k->g_ij, 1, 3, gAf + gFA*dt ); gsl_matrix_set( metric1_k->g_ij, 3, 1, gsl_matrix_get( metric1_k->g_ij, 1, 3 ) ); gsl_matrix_set( metric1_k->g_ij, 2, 3, gDf + gFD*dt ); gsl_matrix_set( metric1_k->g_ij, 3, 2, gsl_matrix_get( metric1_k->g_ij, 2, 3 ) ); gsl_matrix_set( metric1_k->g_ij, 3, 3, gff + 2*gFf*dt + gFF*dt*dt ); XLAL_CHECK ( XLALAddOldDopplerMetric ( &metric1, metric1_k ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyOldDopplerMetric ( metric1_k ); } XLAL_CHECK ( XLALScaleOldDopplerMetric ( metric1, 1.0 / Nseg ) == XLAL_SUCCESS, XLAL_EFUNC ); // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2) XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC ); GPMAT( metric1->g_ij, "%0.4e" ); GPMAT( metric2P->g_ij, "%0.4e" ); // compare both metrics against each other: XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2P->g_ij, metric1->g_ij )) < tolPh, XLAL_ETOL, "Error(g2,g1)= %g exceeds tolerance of %g\n", diff_2_1, tolPh ); XLALPrintWarning ("diff_2_1 = %e\n", diff_2_1 ); XLALDestroyOldDopplerMetric ( metric1 ); XLALDestroyDopplerPhaseMetric ( metric2P ); XLALSegListClear ( &NsegList ); } XLALPrintWarning("\n---------- ROUND 6: directed binary orbital metric ----------\n"); { REAL8 Period = 68023.70496; REAL8 Omega = LAL_TWOPI / Period; REAL8 asini = 1.44; REAL8 tAsc = 897753994; REAL8 argp = 0; LIGOTimeGPS tP; XLALGPSSetREAL8 ( &tP, tAsc + argp / Omega ); const PulsarDopplerParams dopScoX1 = { .refTime = startTimeGPS, .Alpha = Alpha, .Delta = Delta, .fkdot = { Freq }, .asini = asini, .period = Period, .tp = tP }; REAL8 TspanScoX1 = 20 * 19 * 3600; // 20xPorb for long-segment regime LALSegList XLAL_INIT_DECL(segListScoX1); XLAL_CHECK ( XLALSegListInitSimpleSegments ( &segListScoX1, startTimeGPS, 1, TspanScoX1 ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 tMid = XLALGPSGetREAL8(&startTimeGPS) + 0.5 * TspanScoX1; REAL8 DeltaMidAsc = tMid - tAsc; const DopplerCoordinateSystem coordSysScoX1 = { 6, { DOPPLERCOORD_FREQ, DOPPLERCOORD_ASINI, DOPPLERCOORD_TASC, DOPPLERCOORD_PORB, DOPPLERCOORD_KAPPA, DOPPLERCOORD_ETA } }; DopplerMetricParams pars_ScoX1 = { .coordSys = coordSysScoX1, .detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT, .segmentList = segListScoX1, .multiIFO = multiIFO, .multiNoiseFloor = multiNoiseFloor, .signalParams = { .Amp = Amp, .Doppler = dopScoX1 }, .projectCoord = - 1, // -1==no projection .approxPhase = 1, }; pars_ScoX1.multiIFO.length = 1; // truncate to first detector pars_ScoX1.multiNoiseFloor.length = 1; // truncate to first detector // compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2) DopplerPhaseMetric *metric_ScoX1; XLAL_CHECK ( (metric_ScoX1 = XLALComputeDopplerPhaseMetric ( &pars_ScoX1, edat )) != NULL, XLAL_EFUNC ); // compute analytic metric computed from Eq.(47) in Leaci,Prix PRD91, 102003 (2015): gsl_matrix *g0_ij; XLAL_CHECK ( (g0_ij = gsl_matrix_calloc ( 6, 6 )) != NULL, XLAL_ENOMEM, "Failed to gsl_calloc a 6x6 matrix\n"); gsl_matrix_set ( g0_ij, 0, 0, pow ( LAL_PI * TspanScoX1, 2 ) / 3.0 ); gsl_matrix_set ( g0_ij, 1, 1, 2.0 * pow ( LAL_PI * Freq, 2 ) ); gsl_matrix_set ( g0_ij, 2, 2, 2.0 * pow ( LAL_PI * Freq * asini * Omega, 2 ) ); gsl_matrix_set ( g0_ij, 3, 3, 0.5 * pow ( Omega, 4 ) * pow ( Freq * asini, 2 ) * ( pow ( TspanScoX1, 2 ) / 12.0 + pow ( DeltaMidAsc, 2 ) ) ); REAL8 gPAsc = LAL_PI * pow ( Freq * asini, 2 ) * pow ( Omega, 3 ) * DeltaMidAsc; gsl_matrix_set ( g0_ij, 2, 3, gPAsc ); gsl_matrix_set ( g0_ij, 3, 2, gPAsc ); gsl_matrix_set ( g0_ij, 4, 4, 0.5 * pow ( LAL_PI * Freq * asini, 2 ) ); gsl_matrix_set ( g0_ij, 5, 5, 0.5 * pow ( LAL_PI * Freq * asini, 2 ) ); GPMAT ( metric_ScoX1->g_ij, "%0.4e" ); GPMAT ( g0_ij, "%0.4e" ); // compare metrics against each other REAL8 diff, tolScoX1 = 0.05; XLAL_CHECK ( (diff = XLALCompareMetrics ( metric_ScoX1->g_ij, g0_ij )) < tolScoX1, XLAL_ETOL, "Error(gNum,gAn)= %g exceeds tolerance of %g\n", diff, tolScoX1 ); XLALPrintWarning ("diff_Num_An = %e\n", diff ); gsl_matrix_free ( g0_ij ); XLALDestroyDopplerPhaseMetric ( metric_ScoX1 ); XLALSegListClear ( &segListScoX1 ); } // ----- clean up memory XLALSegListClear ( &segList ); XLALDestroyEphemerisData ( edat ); return XLAL_SUCCESS; } /* test_XLALComputeDopplerMetrics() */
/*============================================================ * FUNCTION definitions *============================================================*/ int main(int argc, char *argv[]) { static LALStatus status; /* LALStatus pointer */ UserVariables_t XLAL_INIT_DECL(uvar); ConfigVariables_t XLAL_INIT_DECL(cfg); UINT4 k, numBins, numIFOs, maxNumSFTs, X, alpha; REAL8 Freq0, dFreq, normPSD; UINT4 finalBinSize, finalBinStep, finalNumBins; REAL8Vector *overSFTs = NULL; /* one frequency bin over SFTs */ REAL8Vector *overIFOs = NULL; /* one frequency bin over IFOs */ REAL8Vector *finalPSD = NULL; /* math. operation PSD over SFTs and IFOs */ REAL8Vector *finalNormSFT = NULL; /* normalised SFT power */ vrbflg = 1; /* verbose error-messages */ /* set LAL error-handler */ lal_errhandler = LAL_ERR_EXIT; /* register and read user variables */ if (initUserVars(argc, argv, &uvar) != XLAL_SUCCESS) return EXIT_FAILURE; MultiSFTVector *inputSFTs = NULL; if ( ( inputSFTs = XLALReadSFTs ( &cfg, &uvar ) ) == NULL ) { XLALPrintError ("Call to XLALReadSFTs() failed with xlalErrno = %d\n", xlalErrno ); return EXIT_FAILURE; } /* clean sfts if required */ if ( XLALUserVarWasSet( &uvar.linefiles ) ) { RandomParams *randPar=NULL; FILE *fpRand=NULL; INT4 seed, ranCount; if ( (fpRand = fopen("/dev/urandom", "r")) == NULL ) { fprintf(stderr,"Error in opening /dev/urandom" ); return EXIT_FAILURE; } if ( (ranCount = fread(&seed, sizeof(seed), 1, fpRand)) != 1 ) { fprintf(stderr,"Error in getting random seed" ); return EXIT_FAILURE; } LAL_CALL ( LALCreateRandomParams (&status, &randPar, seed), &status ); LAL_CALL( LALRemoveKnownLinesInMultiSFTVector ( &status, inputSFTs, uvar.maxBinsClean, uvar.blocksRngMed, uvar.linefiles, randPar), &status); LAL_CALL ( LALDestroyRandomParams (&status, &randPar), &status); fclose(fpRand); } /* end cleaning */ LogPrintf (LOG_DEBUG, "Computing spectrogram and PSD ... "); /* get power running-median rngmed[ |data|^2 ] from SFTs */ MultiPSDVector *multiPSD = NULL; XLAL_CHECK_MAIN( ( multiPSD = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.blocksRngMed, NULL ) ) != NULL, XLAL_EFUNC); /* restrict this PSD to just the "physical" band if requested using {--Freq, --FreqBand} */ if ( ( XLALCropMultiPSDandSFTVectors ( multiPSD, inputSFTs, cfg.firstBin, cfg.lastBin )) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALCropMultiPSDandSFTVectors (inputPSD, inputSFTs, %d, %d) failed with xlalErrno = %d\n", __func__, cfg.firstBin, cfg.lastBin, xlalErrno ); return EXIT_FAILURE; } /* start frequency and frequency spacing */ Freq0 = multiPSD->data[0]->data[0].f0; dFreq = multiPSD->data[0]->data[0].deltaF; /* number of raw bins in final PSD */ numBins = multiPSD->data[0]->data[0].data->length; if ( (finalPSD = XLALCreateREAL8Vector ( numBins )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* number of IFOs */ numIFOs = multiPSD->length; if ( (overIFOs = XLALCreateREAL8Vector ( numIFOs )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* maximum number of SFTs */ maxNumSFTs = 0; for (X = 0; X < numIFOs; ++X) { maxNumSFTs = GSL_MAX(maxNumSFTs, multiPSD->data[X]->length); } if ( (overSFTs = XLALCreateREAL8Vector ( maxNumSFTs )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* normalize rngmd(power) to get proper *single-sided* PSD: Sn = (2/Tsft) rngmed[|data|^2]] */ normPSD = 2.0 * dFreq; /* loop over frequency bins in final PSD */ for (k = 0; k < numBins; ++k) { /* loop over IFOs */ for (X = 0; X < numIFOs; ++X) { /* number of SFTs for this IFO */ UINT4 numSFTs = multiPSD->data[X]->length; /* copy PSD frequency bins and normalise multiPSD for later use */ for (alpha = 0; alpha < numSFTs; ++alpha) { multiPSD->data[X]->data[alpha].data->data[k] *= normPSD; overSFTs->data[alpha] = multiPSD->data[X]->data[alpha].data->data[k]; } /* compute math. operation over SFTs for this IFO */ overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.PSDmthopSFTs); if ( isnan( overIFOs->data[X] ) ) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X ); } /* for IFOs X */ /* compute math. operation over IFOs for this frequency */ finalPSD->data[k] = math_op(overIFOs->data, numIFOs, uvar.PSDmthopIFOs); if ( isnan ( finalPSD->data[k] ) ) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in finalPSD->data[k=%d] = NAN ... exiting\n", k ); } /* for freq bins k */ LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); /* compute normalised SFT power */ if (uvar.outputNormSFT) { LogPrintf (LOG_DEBUG, "Computing normalised SFT power ... "); if ( (finalNormSFT = XLALCreateREAL8Vector ( numBins )) == NULL ) { LogPrintf (LOG_CRITICAL, "Out of memory!\n"); return EXIT_FAILURE; } /* loop over frequency bins in SFTs */ for (k = 0; k < numBins; ++k) { /* loop over IFOs */ for (X = 0; X < numIFOs; ++X) { /* number of SFTs for this IFO */ UINT4 numSFTs = inputSFTs->data[X]->length; /* compute SFT power */ for (alpha = 0; alpha < numSFTs; ++alpha) { COMPLEX8 bin = inputSFTs->data[X]->data[alpha].data->data[k]; overSFTs->data[alpha] = crealf(bin)*crealf(bin) + cimagf(bin)*cimagf(bin); } /* compute math. operation over SFTs for this IFO */ overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.nSFTmthopSFTs); if ( isnan ( overIFOs->data[X] )) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X ); } /* over IFOs */ /* compute math. operation over IFOs for this frequency */ finalNormSFT->data[k] = math_op(overIFOs->data, numIFOs, uvar.nSFTmthopIFOs); if ( isnan( finalNormSFT->data[k] ) ) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in bin finalNormSFT->data[k=%d] = NAN ... exiting\n", k ); } /* over freq bins */ LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); } /* output spectrograms */ if ( uvar.outputSpectBname ) { LAL_CALL ( LALfwriteSpectrograms ( &status, uvar.outputSpectBname, multiPSD ), &status ); } /* ---------- if user requested it, output complete MultiPSDVector over IFOs X, timestamps and freq-bins into ASCI file(s) */ if ( uvar.dumpMultiPSDVector ) { if ( XLALDumpMultiPSDVector ( uvar.outputPSD, multiPSD ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALDumpMultiPSDVector() failed, xlalErrnor = %d\n", __func__, xlalErrno ); return EXIT_FAILURE; } } /* if uvar.dumpMultiPSDVector */ /* ----- if requested, compute data-quality factor 'Q' -------------------- */ if ( uvar.outputQ ) { REAL8FrequencySeries *Q; if ( (Q = XLALComputeSegmentDataQ ( multiPSD, cfg.dataSegment )) == NULL ) { XLALPrintError ("%s: XLALComputeSegmentDataQ() failed with xlalErrno = %d\n", __func__, xlalErrno ); return EXIT_FAILURE; } if ( XLAL_SUCCESS != XLALWriteREAL8FrequencySeries_to_file ( Q, uvar.outputQ ) ) { return EXIT_FAILURE; } XLALDestroyREAL8FrequencySeries ( Q ); } /* if outputQ */ /* ---------- BINNING if requested ---------- */ /* work out bin size */ if (XLALUserVarWasSet(&uvar.binSize)) { finalBinSize = uvar.binSize; } else if (XLALUserVarWasSet(&uvar.binSizeHz)) { finalBinSize = (UINT4)floor(uvar.binSizeHz / dFreq + 0.5); /* round to nearest bin */ } else { finalBinSize = 1; } /* work out bin step */ if (XLALUserVarWasSet(&uvar.binStep)) { finalBinStep = uvar.binStep; } else if (XLALUserVarWasSet(&uvar.binStepHz)) { finalBinStep = (UINT4)floor(uvar.binStepHz / dFreq + 0.5); /* round to nearest bin */ } else { finalBinStep = finalBinSize; } /* work out total number of bins */ finalNumBins = (UINT4)floor((numBins - finalBinSize) / finalBinStep) + 1; /* write final PSD to file */ if (XLALUserVarWasSet(&uvar.outputPSD)) { FILE *fpOut = NULL; if ((fpOut = fopen(uvar.outputPSD, "wb")) == NULL) { LogPrintf ( LOG_CRITICAL, "Unable to open output file %s for writing...exiting \n", uvar.outputPSD ); return EXIT_FAILURE; } /* write header info in comments */ if ( XLAL_SUCCESS != XLALOutputVersionString ( fpOut, 0 ) ) XLAL_ERROR ( XLAL_EFUNC ); /* write the command-line */ for (int a = 0; a < argc; a++) fprintf(fpOut,"%%%% argv[%d]: '%s'\n", a, argv[a]); /* write column headings */ fprintf(fpOut,"%%%% columns:\n%%%% FreqBinStart"); if (uvar.outFreqBinEnd) fprintf(fpOut," FreqBinEnd"); fprintf(fpOut," PSD"); if (uvar.outputNormSFT) fprintf(fpOut," normSFTpower"); fprintf(fpOut,"\n"); LogPrintf(LOG_DEBUG, "Printing PSD to file ... "); for (k = 0; k < finalNumBins; ++k) { UINT4 b = k * finalBinStep; REAL8 f0 = Freq0 + b * dFreq; REAL8 f1 = f0 + finalBinStep * dFreq; fprintf(fpOut, "%f", f0); if (uvar.outFreqBinEnd) fprintf(fpOut, " %f", f1); REAL8 psd = math_op(&(finalPSD->data[b]), finalBinSize, uvar.PSDmthopBins); if ( isnan ( psd )) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in psd[k=%d] = NAN ... exiting\n", k ); fprintf(fpOut, " %e", psd); if (uvar.outputNormSFT) { REAL8 nsft = math_op(&(finalNormSFT->data[b]), finalBinSize, uvar.nSFTmthopBins); if ( isnan ( nsft )) XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in nsft[k=%d] = NAN ... exiting\n", k ); fprintf(fpOut, " %f", nsft); } fprintf(fpOut, "\n"); } // k < finalNumBins LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); fclose(fpOut); } /* we are now done with the psd */ XLALDestroyMultiPSDVector ( multiPSD); XLALDestroyMultiSFTVector ( inputSFTs); XLALDestroyUserVars(); XLALDestroyREAL8Vector ( overSFTs ); XLALDestroyREAL8Vector ( overIFOs ); XLALDestroyREAL8Vector ( finalPSD ); XLALDestroyREAL8Vector ( finalNormSFT ); LALCheckMemoryLeaks(); return EXIT_SUCCESS; } /* main() */
void LALReadNRWave_raw_real8(LALStatus *status, /**< pointer to LALStatus structure */ REAL8TimeVectorSeries **out, /**< [out] output time series for h+ and hx */ const CHAR *filename /**< [in] File containing numrel waveform */) { UINT4 length, k, r; REAL8TimeVectorSeries *ret=NULL; REAL8VectorSequence *data=NULL; REAL8Vector *timeVec=NULL; LALParsedDataFile *cfgdata=NULL; REAL8 tmp1, tmp2, tmp3; INITSTATUS(status); ATTATCHSTATUSPTR (status); /* some consistency checks */ ASSERT (filename != NULL, status, NRWAVEIO_ENULL, NRWAVEIO_MSGENULL ); ASSERT ( out != NULL, status, NRWAVEIO_ENULL, NRWAVEIO_MSGENULL ); ASSERT ( *out == NULL, status, NRWAVEIO_ENONULL, NRWAVEIO_MSGENONULL ); if ( XLALParseDataFile ( &cfgdata, filename ) != XLAL_SUCCESS ) { ABORT( status, NRWAVEIO_EFILE, NRWAVEIO_MSGEFILE ); } length = cfgdata->lines->nTokens; /*number of data points */ /* allocate memory */ ret = LALCalloc(1, sizeof(*ret)); if (!ret) { ABORT( status, NRWAVEIO_ENOMEM, NRWAVEIO_MSGENOMEM ); } strcpy(ret->name,filename); ret->f0 = 0; data = XLALCreateREAL8VectorSequence (2, length); if (!data) { ABORT( status, NRWAVEIO_ENOMEM, NRWAVEIO_MSGENOMEM ); } timeVec = XLALCreateREAL8Vector (length); if (!timeVec) { ABORT( status, NRWAVEIO_ENOMEM, NRWAVEIO_MSGENOMEM ); } /* now get the data */ for (k = 0; k < length; k++) { r = sscanf(cfgdata->lines->tokens[k], "%lf%lf%lf", &tmp1, &tmp2, &tmp3); /* Check the data file format */ if ( r != 3) { /* there must be exactly 3 data entries -- time, h+, hx */ ABORT( status, NRWAVEIO_EFORMAT, NRWAVEIO_MSGEFORMAT ); } timeVec->data[k] = tmp1; data->data[k] = tmp2; data->data[data->vectorLength + k] = tmp3; } /* scale time */ ret->deltaT = timeVec->data[1] - timeVec->data[0]; /* might also want to go through timeVec to make sure it is evenly spaced */ ret->data = data; (*out) = ret; XLALDestroyREAL8Vector (timeVec); XLALDestroyParsedDataFile (cfgdata); DETATCHSTATUSPTR(status); RETURN(status); } /* LALReadNRWave() */
int main ( void ) { const char *fn = __func__; //LALStatus status = empty_status; SFTtype *mySFT; LIGOTimeGPS epoch = { 731210229, 0 }; REAL8 dFreq = 1.0 / 1800.0; REAL8 f0 = 150.0 - 2.0 * dFreq; /* init data array */ COMPLEX8 vals[] = { crectf( -1.249241e-21, 1.194085e-21 ), crectf( 2.207420e-21, 2.472366e-22 ), crectf( 1.497939e-21, 6.593609e-22 ), crectf( 3.544089e-20, -9.365807e-21 ), crectf( 1.292773e-21, -1.402466e-21 ) }; UINT4 numBins = sizeof ( vals ) / sizeof(vals[0] ); if ( (mySFT = XLALCreateSFT ( numBins )) == NULL ) { XLALPrintError ("%s: Failed to create test-SFT using XLALCreateSFT(), xlalErrno = %d\n", fn, xlalErrno ); return XLAL_EFAILED; } /* init header */ strcpy ( mySFT->name, "H1;testSFTRngmed" ); mySFT->epoch = epoch; mySFT->f0 = f0; mySFT->deltaF = dFreq; /* we simply copy over these data-values into the SFT */ UINT4 iBin; for ( iBin = 0; iBin < numBins; iBin ++ ) mySFT->data->data[iBin] = vals[iBin]; /* get memory for running-median vector */ REAL8FrequencySeries rngmed; INIT_MEM ( rngmed ); XLAL_CHECK ( (rngmed.data = XLALCreateREAL8Vector ( numBins )) != NULL, XLAL_EFUNC, "Failed XLALCreateREAL8Vector ( %d )", numBins ); // ---------- Test running-median PSD estimation in simple blocksize cases // ------------------------------------------------------------ // TEST 1: odd blocksize = 3 // ------------------------------------------------------------ UINT4 blockSize3 = 3; /* reference result for 3-bin block running-median computed in octave: octave> sft = [ \ -1.249241e-21 + 1.194085e-21i, \ 2.207420e-21 + 2.472366e-22i, \ 1.497939e-21 + 6.593609e-22i, \ 3.544089e-20 - 9.365807e-21i, \ 1.292773e-21 - 1.402466e-21i \ ]; octave> periodo = abs(sft).^2; octave> m1 = median ( periodo(1:3) ); m2 = median ( periodo(2:4) ); m3 = median ( periodo (3:5 ) ); octave> rngmed = [ m1, m1, m2, m3, m3 ]; octave> printf ("rngmedREF3 = { %.16g, %.16g, %.16g, %.16g, %.16g };\n", rngmed ); rngmedREF3[] = { 2.986442063306e-42, 2.986442063306e-42, 4.933828992779561e-42, 3.638172910684999e-42, 3.638172910684999e-42 }; */ REAL8 rngmedREF3[] = { 2.986442063306e-42, 2.986442063306e-42, 4.933828992779561e-42, 3.638172910684999e-42, 3.638172910684999e-42 }; /* compute running median */ XLAL_CHECK ( XLALSFTtoRngmed ( &rngmed, mySFT, blockSize3 ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALSFTtoRngmed() failed."); /* get median->mean bias correction, needed for octave-reference results, to make * them comparable to the bias-corrected results from LALSFTtoRngmed() */ REAL8 medianBias3 = XLALRngMedBias ( blockSize3 ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALRngMedBias() failed."); BOOLEAN pass = 1; const CHAR *passStr; printf ("%4s %22s %22s %8s <%g\n", "Bin", "rngmed(LAL)", "rngmed(Octave)", "relError", tol); for (iBin=0; iBin < numBins; iBin ++ ) { REAL8 rngmedVAL = rngmed.data->data[iBin]; REAL8 rngmedREF = rngmedREF3[iBin] / medianBias3; // apply median-bias correction REAL8 relErr = REL_ERR ( rngmedREF, rngmedVAL ); if ( relErr > tol ) { pass = 0; passStr = "fail"; } else { passStr = "OK."; } printf ("%4d %22.16g %22.16g %8.1g %s\n", iBin, rngmedVAL, rngmedREF, relErr, passStr ); } /* for iBin < numBins */ // ------------------------------------------------------------ // TEST 2: even blocksize = 4 // ------------------------------------------------------------ UINT4 blockSize4 = 4; /* reference result for 4-bin block running-median computed in octave: octave> m1 = median ( periodo(1:4) ); m2 = median ( periodo(2:5) ); octave> rngmed = [ m1, m1, m1, m2, m2 ]; octave> printf ("rngmedREF4[] = { %.16g, %.16g, %.16g, %.16g, %.16g };\n", rngmed ); rngmedREF4[] = { 3.96013552804278e-42, 3.96013552804278e-42, 3.96013552804278e-42, 4.28600095173228e-42, 4.28600095173228e-42 }; */ REAL8 rngmedREF4[] = { 3.96013552804278e-42, 3.96013552804278e-42, 3.96013552804278e-42, 4.28600095173228e-42, 4.28600095173228e-42 }; /* compute running median */ XLAL_CHECK ( XLALSFTtoRngmed ( &rngmed, mySFT, blockSize4 ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALSFTtoRngmed() failed."); /* get median->mean bias correction, needed for octave-reference results, to make * them comparable to the bias-corrected results from LALSFTtoRngmed() */ REAL8 medianBias4 = XLALRngMedBias ( blockSize4 ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALRngMedBias() failed."); printf ("%4s %22s %22s %8s <%g\n", "Bin", "rngmed(LAL)", "rngmed(Octave)", "relError", tol); for (iBin=0; iBin < numBins; iBin ++ ) { REAL8 rngmedVAL = rngmed.data->data[iBin]; REAL8 rngmedREF = rngmedREF4[iBin] / medianBias4; // apply median-bias correction REAL8 relErr = REL_ERR ( rngmedREF, rngmedVAL ); if ( relErr > tol ) { pass = 0; passStr = "fail"; } else { passStr = "OK."; } printf ("%4d %22.16g %22.16g %8.1g %s\n", iBin, rngmedVAL, rngmedREF, relErr, passStr ); } /* for iBin < numBins */ /* free memory */ XLALDestroyREAL8Vector ( rngmed.data ); XLALDestroySFT ( mySFT ); LALCheckMemoryLeaks(); if ( !pass ) { printf ("Test failed! Difference exceeded tolerance.\n"); return XLAL_EFAILED; } else { printf ("Test passed.\n"); return XLAL_SUCCESS; } } /* main() */
/** * The main workhorse function for performing the ringdown attachment for EOB * models EOBNRv2 and SEOBNRv1. This is the function which gets called by the * code generating the full IMR waveform once generation of the inspiral part * has been completed. * The ringdown is attached using the hybrid comb matching detailed in * The method is describe in Sec. II C of Pan et al. PRD 84, 124052 (2011), * specifically Eqs. 30 - 32.. Further details of the * implementation of the found in the DCC document T1100433. * In SEOBNRv1, the last physical overtone is replace by a pseudoQNM. See * Taracchini et al. PRD 86, 024011 (2012) for details. * STEP 1) Get mass and spin of the final black hole and the complex ringdown frequencies * STEP 2) Based on least-damped-mode decay time, allocate memory for rigndown waveform * STEP 3) Get values and derivatives of inspiral waveforms at matching comb points * STEP 4) Solve QNM coefficients and generate ringdown waveforms * STEP 5) Stitch inspiral and ringdown waveoforms */ static INT4 XLALSimIMREOBHybridAttachRingdown( REAL8Vector *signal1, /**<< OUTPUT, Real of inspiral waveform to which we attach ringdown */ REAL8Vector *signal2, /**<< OUTPUT, Imag of inspiral waveform to which we attach ringdown */ const INT4 l, /**<< Current mode l */ const INT4 m, /**<< Current mode m */ const REAL8 dt, /**<< Sample time step (in seconds) */ const REAL8 mass1, /**<< First component mass (in Solar masses) */ const REAL8 mass2, /**<< Second component mass (in Solar masses) */ const REAL8 spin1x, /**<<The spin of the first object; only needed for spin waveforms */ const REAL8 spin1y, /**<<The spin of the first object; only needed for spin waveforms */ const REAL8 spin1z, /**<<The spin of the first object; only needed for spin waveforms */ const REAL8 spin2x, /**<<The spin of the second object; only needed for spin waveforms */ const REAL8 spin2y, /**<<The spin of the second object; only needed for spin waveforms */ const REAL8 spin2z, /**<<The spin of the second object; only needed for spin waveforms */ REAL8Vector *timeVec, /**<< Vector containing the time values */ REAL8Vector *matchrange, /**<< Time values chosen as points for performing comb matching */ Approximant approximant /**<<The waveform approximant being used */ ) { COMPLEX16Vector *modefreqs; UINT4 Nrdwave; UINT4 j; UINT4 nmodes; REAL8Vector *rdwave1; REAL8Vector *rdwave2; REAL8Vector *rinspwave; REAL8Vector *dinspwave; REAL8Vector *ddinspwave; REAL8VectorSequence *inspwaves1; REAL8VectorSequence *inspwaves2; REAL8 eta, a, NRPeakOmega22; /* To generate pQNM frequency */ REAL8 mTot; /* In geometric units */ REAL8 spin1[3] = { spin1x, spin1y, spin1z }; REAL8 spin2[3] = { spin2x, spin2y, spin2z }; REAL8 finalMass, finalSpin; mTot = (mass1 + mass2) * LAL_MTSUN_SI; eta = mass1 * mass2 / ( (mass1 + mass2) * (mass1 + mass2) ); /* * STEP 1) Get mass and spin of the final black hole and the complex ringdown frequencies */ /* Create memory for the QNM frequencies */ nmodes = 8; modefreqs = XLALCreateCOMPLEX16Vector( nmodes ); if ( !modefreqs ) { XLAL_ERROR( XLAL_ENOMEM ); } if ( XLALSimIMREOBGenerateQNMFreqV2( modefreqs, mass1, mass2, spin1, spin2, l, m, nmodes, approximant ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLAL_ERROR( XLAL_EFUNC ); } /* Call XLALSimIMREOBFinalMassSpin() to get mass and spin of the final black hole */ if ( XLALSimIMREOBFinalMassSpin(&finalMass, &finalSpin, mass1, mass2, spin1, spin2, approximant) == XLAL_FAILURE ) { XLAL_ERROR( XLAL_EFUNC ); } if ( approximant == SEOBNRv1 ) { /* Replace the last QNM with pQNM */ /* We assume aligned/antialigned spins here */ a = (spin1[2] + spin2[2]) / 2. * (1.0 - 2.0 * eta) + (spin1[2] - spin2[2]) / 2. * (mass1 - mass2) / (mass1 + mass2); NRPeakOmega22 = GetNRSpinPeakOmega( l, m, eta, a ) / mTot; /*printf("a and NRomega in QNM freq: %.16e %.16e %.16e %.16e %.16e\n",spin1[2],spin2[2], mTot/LAL_MTSUN_SI,a,NRPeakOmega22*mTot);*/ modefreqs->data[7] = (NRPeakOmega22/finalMass + creal(modefreqs->data[0])) / 2.; modefreqs->data[7] += I * 10./3. * cimag(modefreqs->data[0]); } /*for (j = 0; j < nmodes; j++) { printf("QNM frequencies: %d %d %d %e %e\n",l,m,j,modefreqs->data[j].re*mTot,1./modefreqs->data[j].im/mTot); }*/ /* Ringdown signal length: 10 times the decay time of the n=0 mode */ Nrdwave = (INT4) (EOB_RD_EFOLDS / cimag(modefreqs->data[0]) / dt); /* Check the value of attpos, to prevent memory access problems later */ if ( matchrange->data[0] * mTot / dt < 5 || matchrange->data[1]*mTot/dt > matchrange->data[2] *mTot/dt - 2 ) { XLALPrintError( "More inspiral points needed for ringdown matching.\n" ); //printf("%.16e,%.16e,%.16e\n",matchrange->data[0] * mTot / dt, matchrange->data[1]*mTot/dt, matchrange->data[2] *mTot/dt - 2); XLALDestroyCOMPLEX16Vector( modefreqs ); XLAL_ERROR( XLAL_EFAILED ); } /* * STEP 2) Based on least-damped-mode decay time, allocate memory for rigndown waveform */ /* Create memory for the ring-down and full waveforms, and derivatives of inspirals */ rdwave1 = XLALCreateREAL8Vector( Nrdwave ); rdwave2 = XLALCreateREAL8Vector( Nrdwave ); rinspwave = XLALCreateREAL8Vector( 6 ); dinspwave = XLALCreateREAL8Vector( 6 ); ddinspwave = XLALCreateREAL8Vector( 6 ); inspwaves1 = XLALCreateREAL8VectorSequence( 3, 6 ); inspwaves2 = XLALCreateREAL8VectorSequence( 3, 6 ); /* Check memory was allocated */ if ( !rdwave1 || !rdwave2 || !rinspwave || !dinspwave || !ddinspwave || !inspwaves1 || !inspwaves2 ) { XLALDestroyCOMPLEX16Vector( modefreqs ); if (rdwave1) XLALDestroyREAL8Vector( rdwave1 ); if (rdwave2) XLALDestroyREAL8Vector( rdwave2 ); if (rinspwave) XLALDestroyREAL8Vector( rinspwave ); if (dinspwave) XLALDestroyREAL8Vector( dinspwave ); if (ddinspwave) XLALDestroyREAL8Vector( ddinspwave ); if (inspwaves1) XLALDestroyREAL8VectorSequence( inspwaves1 ); if (inspwaves2) XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_ENOMEM ); } memset( rdwave1->data, 0, rdwave1->length * sizeof( REAL8 ) ); memset( rdwave2->data, 0, rdwave2->length * sizeof( REAL8 ) ); /* * STEP 3) Get values and derivatives of inspiral waveforms at matching comb points */ /* Generate derivatives of the last part of inspiral waves */ /* Get derivatives of signal1 */ if ( XLALGenerateHybridWaveDerivatives( rinspwave, dinspwave, ddinspwave, timeVec, signal1, matchrange, dt, mass1, mass2 ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_EFUNC ); } for (j = 0; j < 6; j++) { inspwaves1->data[j] = rinspwave->data[j]; inspwaves1->data[j + 6] = dinspwave->data[j]; inspwaves1->data[j + 12] = ddinspwave->data[j]; } /* Get derivatives of signal2 */ if ( XLALGenerateHybridWaveDerivatives( rinspwave, dinspwave, ddinspwave, timeVec, signal2, matchrange, dt, mass1, mass2 ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_EFUNC ); } for (j = 0; j < 6; j++) { inspwaves2->data[j] = rinspwave->data[j]; inspwaves2->data[j + 6] = dinspwave->data[j]; inspwaves2->data[j + 12] = ddinspwave->data[j]; } /* * STEP 4) Solve QNM coefficients and generate ringdown waveforms */ /* Generate ring-down waveforms */ if ( XLALSimIMREOBHybridRingdownWave( rdwave1, rdwave2, dt, mass1, mass2, inspwaves1, inspwaves2, modefreqs, matchrange ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_EFUNC ); } /* * STEP 5) Stitch inspiral and ringdown waveoforms */ /* Generate full waveforms, by stitching inspiral and ring-down waveforms */ UINT4 attachIdx = matchrange->data[1] * mTot / dt; for (j = 1; j < Nrdwave; ++j) { signal1->data[j + attachIdx] = rdwave1->data[j]; signal2->data[j + attachIdx] = rdwave2->data[j]; } memset( signal1->data+Nrdwave+attachIdx, 0, (signal1->length - Nrdwave - attachIdx)*sizeof(REAL8) ); memset( signal2->data+Nrdwave+attachIdx, 0, (signal2->length - Nrdwave - attachIdx)*sizeof(REAL8) ); /* Free memory */ XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); return XLAL_SUCCESS; }
/** The main function of binary2sft.c * */ int main( int argc, char *argv[] ) { UserInput_t uvar = empty_UserInput; /* user input variables */ INT4 i,j; /* counter */ SFTVector *SFTvect = NULL; char *noisestr = XLALCalloc(1,sizeof(char)); /**********************************************************************************/ /* register and read all user-variables */ if (XLALReadUserVars(argc,argv,&uvar)) { LogPrintf(LOG_CRITICAL,"%s : XLALReadUserVars() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_DEBUG,"%s : read in uservars\n",__func__); /**********************************************************************************/ /* read in the cache file */ FILE *cachefp = NULL; if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) { LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile); return 1; } i = 0; while (fscanf(cachefp,"%*s %*d %*d")!=EOF) i++; INT4 Nfiles = i; fclose(cachefp); LogPrintf(LOG_DEBUG,"%s : counted %d files listed in the cache file.\n",__func__,Nfiles); /* allocate memory */ char **filenames = LALCalloc(Nfiles,sizeof(char*)); LIGOTimeGPSVector fileStart; fileStart.data = LALCalloc(Nfiles,sizeof(LIGOTimeGPS)); for (i=0;i<Nfiles;i++) filenames[i] = LALCalloc(512,sizeof(char)); if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) { LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile); return 1; } for (i=0;i<Nfiles;i++) { fscanf(cachefp,"%s %d %d %*d",filenames[i],&(fileStart.data[i].gpsSeconds),&(fileStart.data[i].gpsNanoSeconds)); } fclose(cachefp); /* initialise the random number generator */ gsl_rng * r; if (XLALInitgslrand(&r,uvar.seed)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } /* setup the binaryToSFT parameters */ BinaryToSFTparams par; par.tsft = uvar.tsft; par.freq = uvar.freq; par.freqband = uvar.freqband; par.tsamp = uvar.tsamp; par.highpassf = uvar.highpassf; par.amp_inj = uvar.amp_inj; par.f_inj = uvar.f_inj; par.asini_inj = uvar.asini_inj; XLALGPSSetREAL8(&(par.tasc_inj),uvar.tasc_inj); par.tref = fileStart.data[0]; par.P_inj = uvar.P_inj; par.phi_inj = uvar.phi_inj; par.r = r; /**********************************************************************************/ /* loop over the input files */ long int ntot = 0; for (j=0;j<Nfiles;j++) { UINT4 k = 0; INT8Vector *np = NULL; REAL8Vector *R = NULL; par.tstart = fileStart.data[j]; REAL8 norm1 = par.tsamp/par.tsft; REAL8 norm2 = 1.0/(par.tsamp*par.tsft); UINT4 oldlen; if (SFTvect==NULL) oldlen = 0; else oldlen = SFTvect->length; LogPrintf(LOG_DEBUG,"%s : working on file %s\n",__func__,filenames[j]); if (XLALBinaryToSFTVector(&SFTvect,filenames[j],&(fileStart.data[j]),&par,&np,&R)) { LogPrintf(LOG_CRITICAL,"%s : failed to convert binary input file %s to sfts\n",__func__,filenames[j]); return 1; } if ((np!=NULL) && (R!=NULL)) { for (k=0;k<np->length;k++) { ntot += np->data[k]; char temp[64]; sprintf(temp,"%d %e %e\n",SFTvect->data[oldlen+k].epoch.gpsSeconds,(REAL8)np->data[k]*norm1,R->data[k]*norm2); noisestr = (char *)XLALRealloc(noisestr,sizeof(char)*(1+strlen(noisestr)+strlen(temp))); strcat(noisestr,temp); } XLALDestroyINT8Vector(np); XLALDestroyREAL8Vector(R); } } /* end loop over input files */ /**********************************************************************************/ /* create a noise string */ /**********************************************************************************/ /* generate comment string */ char *VCSInfoString = XLALGetVersionString(0); XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); CHAR *logstr; size_t len; XLAL_CHECK ( (logstr = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) != NULL, XLAL_EFUNC ); char *comment = XLALCalloc ( 1, len = strlen ( logstr ) + strlen(VCSInfoString) + strlen(noisestr) + 512 ); XLAL_CHECK ( comment != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zd) failed.\n", len ); sprintf ( comment, "Generated by:\n%s\n%s\nTotal number of photons = %ld\n%s\n", logstr, VCSInfoString, ntot, noisestr ); /**********************************************************************************/ /* either write whole SFT-vector to single concatenated file */ if ( uvar.outSingleSFT ) { XLAL_CHECK ( XLALWriteSFTVector2File( SFTvect, uvar.outputdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { /* or as individual SFT-files */ XLAL_CHECK ( XLALWriteSFTVector2Dir( SFTvect, uvar.outputdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); } /**********************************************************************************/ /* free memory */ XLALDestroySFTVector(SFTvect); XLALFree(logstr); XLALFree(comment); XLALFree(noisestr); LALCheckMemoryLeaks(); return 0; }
/** The main function of semicoherentbinary.c * */ int main( int argc, char *argv[] ) { UserInput_t uvar = empty_UserInput; /* user input variables */ CHAR *clargs = NULL; /* store the command line args */ SFTVector *sftvec = NULL; /* stores the input SFTs */ /* REAL4VectorArray *background = NULL; /\* running median estimates of the background for each SFT *\/ */ ParameterSpace pspace = empty_ParameterSpace; /* the search parameter space */ COMPLEX8TimeSeriesArray *dstimevec = NULL; /* contains the downsampled inverse FFT'd SFTs */ REAL4DemodulatedPowerVector *dmpower = NULL; /* contains the demodulated power for all SFTs */ GridParametersVector *freqgridparams = NULL; /* the coherent grid on the frequency derivitive parameter space */ GridParameters *bingridparams = NULL; CHAR newnewtemp[LONGSTRINGLENGTH]; /* REAL8Vector *SemiCo = NULL; /\* the semi-coherent statistic results *\/ */ REAL8 fmin_read,fmax_read,fband_read; /* the range of frequencies to be read from SFTs */ UINT4 i; /* counters */ FILE *sfp = NULL; /* FILE *cfp = NULL; */ vrbflg = 0; /* verbose error-messages */ /* turn off default GSL error handler */ gsl_set_error_handler_off(); /* register and read all user-variables */ if (XLALReadUserVars(argc,argv,&uvar,&clargs)) { LogPrintf(LOG_CRITICAL,"%s : XLALReadUserVars() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : read in uservars\n",__func__); /* initialise sin-cosine lookup table */ XLALSinCosLUTInit(); /* initialise the random number generator */ if (XLALInitgslrand(&r,uvar.seed)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } /* make output directory */ { struct stat st; if (stat(uvar.outputdir, &st)) { if (mkdir(uvar.outputdir,0755) != 0 && errno != EEXIST) { LogPrintf(LOG_DEBUG,"%s : Unable to make output directory %s. Might be a problem.\n",__func__,uvar.outputdir); } } } /* make temporary directory */ if (uvar.tempdir) { struct stat st; if (stat(uvar.tempdir, &st)) { if (mkdir(uvar.tempdir,0755) != 0 && errno != EEXIST) { LogPrintf(LOG_DEBUG,"%s : Unable to make temporary directory %s. Might be a problem.\n",__func__,uvar.tempdir); } } /* initialise the random number generator - use the clock */ gsl_rng * q; if (XLALInitgslrand(&q,0)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } CHAR newtemp[LONGSTRINGLENGTH]; INT4 id = (INT4)(1e9*gsl_rng_uniform(q)); sprintf(newtemp,"%s/%09d",uvar.tempdir,id); if (mkdir(newtemp,0755) != 0 && errno != EEXIST) { LogPrintf(LOG_DEBUG,"%s : Unable to make temporary directory %s. Might be a problem.\n",__func__,newtemp); } sprintf(newnewtemp,"%s/%.3f-%.3f",newtemp,uvar.freq,uvar.freq+uvar.freqband); } else { sprintf(newnewtemp,"%s/%.3f-%.3f",uvar.outputdir,uvar.freq,uvar.freq+uvar.freqband); } /* make frequency+band directory inside output/temporary directory */ if (mkdir(newnewtemp,0755) != 0 && errno != EEXIST) { LogPrintf(LOG_CRITICAL,"%s : Unable to make frequency+band directory %s\n",__func__,newnewtemp); return 1; } /* initialise the random number generator */ if (XLALInitgslrand(&r,uvar.seed)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } /* make crude but safe estimate of the bandwidth required for the source - now includes running median wings */ { REAL8 wings = LAL_TWOPI*uvar.maxasini/uvar.minorbperiod; fmin_read = MINBAND*floor((uvar.freq - WINGS_FACTOR*uvar.freq*wings - (REAL8)uvar.blocksize/(REAL8)uvar.tsft)/MINBAND); fmax_read = MINBAND*ceil((uvar.freq + (REAL8)uvar.blocksize/(REAL8)uvar.tsft + uvar.freqband + WINGS_FACTOR*(uvar.freq + uvar.freqband)*wings)/MINBAND); fband_read = fmax_read - fmin_read; LogPrintf(LOG_NORMAL,"%s : reading in SFT frequency band [%f -> %f]\n",__func__,fmin_read,fmax_read); } /* initialise the random number generator */ if (XLALInitgslrand(&r,uvar.seed)) { LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno); XLAL_ERROR(XLAL_EFAULT); } /**********************************************************************************/ /* READ THE SFT DATA */ /**********************************************************************************/ /* load in the SFTs - also fill in the segment parameters structure */ if (XLALReadSFTs(&sftvec,uvar.sftbasename,fmin_read,fband_read,uvar.gpsstart,uvar.gpsend,uvar.tsft,uvar.bins_factor)) { LogPrintf(LOG_CRITICAL,"%s : XLALReadSFTs() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : read in SFTs\n",__func__); /* define SFT length and the start and span of the observations plus the definitive segment time */ pspace.tseg = 1.0/sftvec->data[0].deltaF; memcpy(&(pspace.epoch),&(sftvec->data[0].epoch),sizeof(LIGOTimeGPS)); pspace.span = XLALGPSDiff(&(sftvec->data[sftvec->length-1].epoch),&(sftvec->data[0].epoch)) + pspace.tseg; LogPrintf(LOG_NORMAL,"%s : SFT length = %f seconds\n",__func__,pspace.tseg); LogPrintf(LOG_NORMAL,"%s : entire dataset starts at GPS time %d contains %d SFTS and spans %.0f seconds\n",__func__,pspace.epoch.gpsSeconds,sftvec->length,pspace.span); /**********************************************************************************/ /* NORMALISE THE SFTS */ /**********************************************************************************/ if (uvar.blocksize>0) { /* compute the background noise using the sfts - this routine uses the running median at the edges to normalise the wings */ if (XLALNormalizeSFTVect(sftvec,uvar.blocksize,0)) { LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVect() failed with error = %d\n",__func__,xlalErrno); return 1; } } else { REAL8Vector *means = XLALCreateREAL8Vector(sftvec->length); if (uvar.blocksize==0) { /* compute the background noise using the sfts - this routine simply divides by the median */ if (XLALNormalizeSFTVectMedian(sftvec,means,1)) { LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVectMedian() failed with error = %d\n",__func__,xlalErrno); return 1; } } else { /* compute the background noise using the sfts - this routine simply divides by the mean */ if (XLALNormalizeSFTVectMean(sftvec,means,1)) { LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVectMean() failed with error = %d\n",__func__,xlalErrno); return 1; } } XLALDestroyREAL8Vector(means); } LogPrintf(LOG_NORMAL,"%s : normalised the SFTs\n",__func__); /* for (i=0;i<sftvec->length;i++) { for (j=0;j<sftvec->data[i].data->length;j++) { if (isnan(crealf(sftvec->data[i].data->data[j]))||isinf(crealf(sftvec->data[i].data->data[j]))||isnan(cimagf(sftvec->data[i].data->data[j]))||isinf(cimagf(sftvec->data[i].data->data[j]))) { LogPrintf(LOG_DEBUG,"SFT %d : %f %e %e\n",i,sftvec->data[i].f0 + j*sftvec->data[i].deltaF,crealf(sftvec->data[i].data->data[j]),cimagf(sftvec->data[i].data->data[j])); } } } */ /**********************************************************************************/ /* DEFINE THE BINARY PARAMETER SPACE */ /**********************************************************************************/ /* define the binary parameter space */ if (XLALDefineBinaryParameterSpace(&(pspace.space),pspace.epoch,pspace.span,&uvar)) { LogPrintf(LOG_CRITICAL,"%s : XLALDefineBinaryParameterSpace() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : defined binary parameter prior space\n",__func__); /**********************************************************************************/ /* COMPUTE THE COARSE GRID ON FREQUENCY DERIVITIVES */ /**********************************************************************************/ /* compute the grid parameters for all SFTs */ if (XLALComputeFreqGridParamsVector(&freqgridparams,pspace.space,sftvec,uvar.mismatch,&uvar.ndim,uvar.bins_factor)) { LogPrintf(LOG_CRITICAL,"%s : XLALComputeFreqGridParams() failed with error = %d\n",__func__,xlalErrno); return 1; } /**********************************************************************************/ /* COMPUTE THE FINE GRID PARAMETERS */ /**********************************************************************************/ /* compute the fine grid on the binary parameters */ if (XLALComputeBinaryGridParams(&bingridparams,pspace.space,pspace.span,pspace.tseg,uvar.mismatch,uvar.coverage)) { LogPrintf(LOG_CRITICAL,"%s : XLALComputeBinaryGridParams() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : computed the binary parameter space grid\n",__func__); /**********************************************************************************/ /* CONVERT ALL SFTS TO DOWNSAMPLED TIMESERIES */ /**********************************************************************************/ /* convert sfts to downsample dtimeseries */ if (XLALSFTVectorToCOMPLEX8TimeSeriesArray(&dstimevec,sftvec)) { LogPrintf(LOG_CRITICAL,"%s : XLALSFTVectorToCOMPLEX8TimeSeriesArray() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : converted SFTs to downsampled timeseries\n",__func__); /**********************************************************************************/ /* OPEN INTERMEDIATE RESULTS FILE */ /**********************************************************************************/ /* if (XLALOpenSemiCoherentResultsFile(&cfp,newnewtemp,&pspace,clargs,&uvar,1)) { LogPrintf(LOG_CRITICAL,"%s : XLALOpenCoherentResultsFile() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : opened coherent results file.\n",__func__); */ /**********************************************************************************/ /* COMPUTE THE STATISTICS ON THE COARSE GRID */ /**********************************************************************************/ /* compute the demodulated power on the frequency derivitive grid */ if (XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector(&dmpower,dstimevec,freqgridparams,NULL)) { LogPrintf(LOG_CRITICAL,"%s : XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector() failed with error = %d\n",__func__,xlalErrno); return 1; } /* fclose(cfp); */ LogPrintf(LOG_NORMAL,"%s : computed the demodulated power\n",__func__); /**********************************************************************************/ /* OPEN RESULTS FILE */ /**********************************************************************************/ if (XLALOpenSemiCoherentResultsFile(&sfp,newnewtemp,&pspace,clargs,&uvar)) { LogPrintf(LOG_CRITICAL,"%s : XLALOutputBayesResults() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_NORMAL,"%s : output results to file.\n",__func__); /**********************************************************************************/ /* COMPUTE THE STATISTICS ON THE FINE GRID */ /**********************************************************************************/ /* compute the semi-coherent detection statistic on the fine grid */ if (XLALComputeSemiCoherentStat(sfp,dmpower,&pspace,freqgridparams,bingridparams,uvar.ntoplist,uvar.with_xbins)) { LogPrintf(LOG_CRITICAL,"%s : XLALComputeSemiCoherentStat() failed with error = %d\n",__func__,xlalErrno); return 1; } fclose(sfp); LogPrintf(LOG_NORMAL,"%s : computed the semi-coherent statistic\n",__func__); /**********************************************************************************/ /* CLEAN UP */ /**********************************************************************************/ /* move the temporary directory to the final location */ if (uvar.tempdir) { CHAR newoutputdir[LONGSTRINGLENGTH]; sprintf(newoutputdir,"%s/%.3f-%.3f",uvar.outputdir,uvar.freq,uvar.freq+uvar.freqband); if (rename(newnewtemp,newoutputdir)) { LogPrintf(LOG_CRITICAL,"%s : unable to move final results directory %s -> %s. Exiting.\n",__func__,newnewtemp,newoutputdir); return 1; } } LogPrintf(LOG_DEBUG,"%s : moved the results from the temp space.\n",__func__); /* clean up the parameter space */ if (XLALFreeParameterSpace(&pspace)) { LogPrintf(LOG_CRITICAL,"%s : XLALFreeParameterSpace() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_DEBUG,"%s : freed the parameter space\n",__func__); /* clean up the demodulated power */ if (XLALFreeREAL4DemodulatedPowerVector(dmpower)) { LogPrintf(LOG_CRITICAL,"%s : XLALFreeREAL4DemodulatedPowerVector() failed with error = %d\n",__func__,xlalErrno); return 1; } LogPrintf(LOG_DEBUG,"%s : freed the demodulated power\n",__func__); /* free un-needed downsampled timeseries */ for (i=0;i<dstimevec->length;i++) { XLALDestroyCOMPLEX8TimeSeries(dstimevec->data[i]); } XLALFree(dstimevec->data); XLALFree(dstimevec); LogPrintf(LOG_DEBUG,"%s : freed the downsampled timeseries memory\n",__func__); /* free frequency grid - the contents of each segment have been moved to the power structure and are freed later */ XLALFree(freqgridparams->segment); XLALFree(freqgridparams); /* free un-needed original SFT vector */ XLALDestroySFTVector(sftvec); LogPrintf(LOG_DEBUG,"%s : Freed the SFT memory\n",__func__); /* free semi-coherent results */ /* XLALDestroyREAL8Vector(SemiCo); */ /* LogPrintf(LOG_DEBUG,"%s : Freed the semi-coherent results memory\n",__func__); */ /* Free config-Variables and userInput stuff */ XLALDestroyUserVars(); XLALFree(clargs); /* did we forget anything ? */ LALCheckMemoryLeaks(); LogPrintf(LOG_DEBUG,"%s : successfully checked memory leaks.\n",__func__); LogPrintf(LOG_NORMAL,"%s : successfully completed.\n",__func__); return 0; } /* end of main */
int main(int argc, char *argv[]){ UserInput_t XLAL_INIT_DECL(uvar); static ConfigVariables config; /* sft related variables */ MultiSFTVector *inputSFTs = NULL; MultiPSDVector *multiPSDs = NULL; MultiNoiseWeights *multiWeights = NULL; MultiLIGOTimeGPSVector *multiTimes = NULL; MultiLALDetector multiDetectors; MultiDetectorStateSeries *multiStates = NULL; MultiAMCoeffs *multiCoeffs = NULL; SFTIndexList *sftIndices = NULL; SFTPairIndexList *sftPairs = NULL; REAL8Vector *shiftedFreqs = NULL; UINT4Vector *lowestBins = NULL; COMPLEX8Vector *expSignalPhases = NULL; REAL8VectorSequence *sincList = NULL; PulsarDopplerParams XLAL_INIT_DECL(dopplerpos); PulsarDopplerParams thisBinaryTemplate, binaryTemplateSpacings; PulsarDopplerParams minBinaryTemplate, maxBinaryTemplate; SkyPosition XLAL_INIT_DECL(skyPos); MultiSSBtimes *multiBinaryTimes = NULL; INT4 k; UINT4 j; REAL8 fMin, fMax; /* min and max frequencies read from SFTs */ REAL8 deltaF; /* frequency resolution associated with time baseline of SFTs */ REAL8 diagff = 0; /*diagonal metric components*/ REAL8 diagaa = 0; REAL8 diagTT = 0; REAL8 diagpp = 1; REAL8 ccStat = 0; REAL8 evSquared=0; REAL8 estSens=0; /*estimated sensitivity(4.13)*/ BOOLEAN dopplerShiftFlag = TRUE; toplist_t *ccToplist=NULL; CrossCorrBinaryOutputEntry thisCandidate; UINT4 checksum; LogPrintf (LOG_CRITICAL, "Starting time\n"); /*for debug convenience to record calculating time*/ /* initialize and register user variables */ LIGOTimeGPS computingStartGPSTime, computingEndGPSTime; XLALGPSTimeNow (&computingStartGPSTime); /* record the rough starting GPS time*/ if ( XLALInitUserVars( &uvar ) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read user input from the command line or config file */ if ( XLALUserVarReadAllInput ( argc, argv ) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALUserVarReadAllInput() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if (uvar.help) /* if help was requested, then exit */ return 0; CHAR *VCSInfoString = XLALGetVersionString(0); /**<LAL + LALapps Vsersion string*/ /*If the version information was requested, output it and exit*/ if ( uvar.version ){ XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); printf ("%s\n", VCSInfoString ); exit (0); } /* configure useful variables based on user input */ if ( XLALInitializeConfigVars ( &config, &uvar) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } deltaF = config.catalog->data[0].header.deltaF; REAL8 Tsft = 1.0 / deltaF; if (XLALUserVarWasSet(&uvar.spacingF) && XLALUserVarWasSet(&uvar.mismatchF)) LogPrintf (LOG_CRITICAL, "spacingF and mismatchF are both set, use spacingF %.9g by default\n\n", uvar.spacingF); if (XLALUserVarWasSet(&uvar.spacingA) && XLALUserVarWasSet(&uvar.mismatchA)) LogPrintf (LOG_CRITICAL, "spacingA and mismatchA are both set, use spacingA %.9g by default\n\n", uvar.spacingA); if (XLALUserVarWasSet(&uvar.spacingT) && XLALUserVarWasSet(&uvar.mismatchT)) LogPrintf (LOG_CRITICAL, "spacingT and mismatchT are both set, use spacingT %.9g by default\n\n", uvar.spacingT); if (XLALUserVarWasSet(&uvar.spacingP) && XLALUserVarWasSet(&uvar.mismatchP)) LogPrintf (LOG_CRITICAL, "spacingP and mismatchP are both set, use spacingP %.9g by default\n\n", uvar.spacingP); /* create the toplist */ create_crossCorrBinary_toplist( &ccToplist, uvar.numCand); /* now read the data */ /* /\* get SFT parameters so that we can initialise search frequency resolutions *\/ */ /* /\* calculate deltaF_SFT *\/ */ /* deltaF_SFT = catalog->data[0].header.deltaF; /\* frequency resolution *\/ */ /* timeBase= 1.0/deltaF_SFT; /\* sft baseline *\/ */ /* /\* catalog is ordered in time so we can get start, end time and tObs *\/ */ /* firstTimeStamp = catalog->data[0].header.epoch; */ /* lastTimeStamp = catalog->data[catalog->length - 1].header.epoch; */ /* tObs = XLALGPSDiff( &lastTimeStamp, &firstTimeStamp ) + timeBase; */ /* /\*set pulsar reference time *\/ */ /* if (LALUserVarWasSet ( &uvar_refTime )) { */ /* XLALGPSSetREAL8(&refTime, uvar_refTime); */ /* } */ /* else { /\*if refTime is not set, set it to midpoint of sfts*\/ */ /* XLALGPSSetREAL8(&refTime, (0.5*tObs) + XLALGPSGetREAL8(&firstTimeStamp)); */ /* } */ /* /\* set frequency resolution defaults if not set by user *\/ */ /* if (!(LALUserVarWasSet (&uvar_fResolution))) { */ /* uvar_fResolution = 1/tObs; */ /* } */ /* { */ /* /\* block for calculating frequency range to read from SFTs *\/ */ /* /\* user specifies freq and fdot range at reftime */ /* we translate this range of fdots to start and endtime and find */ /* the largest frequency band required to cover the */ /* frequency evolution *\/ */ /* PulsarSpinRange spinRange_startTime; /\**< freq and fdot range at start-time of observation *\/ */ /* PulsarSpinRange spinRange_endTime; /\**< freq and fdot range at end-time of observation *\/ */ /* PulsarSpinRange spinRange_refTime; /\**< freq and fdot range at the reference time *\/ */ /* REAL8 startTime_freqLo, startTime_freqHi, endTime_freqLo, endTime_freqHi, freqLo, freqHi; */ /* REAL8Vector *fdotsMin=NULL; */ /* REAL8Vector *fdotsMax=NULL; */ /* UINT4 k; */ /* fdotsMin = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */ /* fdotsMin->length = N_SPINDOWN_DERIVS; */ /* fdotsMin->data = (REAL8 *)LALCalloc(fdotsMin->length, sizeof(REAL8)); */ /* fdotsMax = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */ /* fdotsMax->length = N_SPINDOWN_DERIVS; */ /* fdotsMax->data = (REAL8 *)LALCalloc(fdotsMax->length, sizeof(REAL8)); */ /* XLAL_INIT_MEM(spinRange_startTime); */ /* XLAL_INIT_MEM(spinRange_endTime); */ /* XLAL_INIT_MEM(spinRange_refTime); */ /* spinRange_refTime.refTime = refTime; */ /* spinRange_refTime.fkdot[0] = uvar_f0; */ /* spinRange_refTime.fkdotBand[0] = uvar_fBand; */ /* } */ /* FIXME: need to correct fMin and fMax for Doppler shift, rngmedian bins and spindown range */ /* this is essentially just a place holder for now */ /* FIXME: this running median buffer is overkill, since the running median block need not be centered on the search frequency */ REAL8 vMax = LAL_TWOPI * (uvar.orbitAsiniSec + uvar.orbitAsiniSecBand) / uvar.orbitPSec + LAL_TWOPI * LAL_REARTH_SI / (LAL_DAYSID_SI * LAL_C_SI) + LAL_TWOPI * LAL_AU_SI/(LAL_YRSID_SI * LAL_C_SI); /*calculate the maximum relative velocity in speed of light*/ fMin = uvar.fStart * (1 - vMax) - 0.5 * uvar.rngMedBlock * deltaF; fMax = (uvar.fStart + uvar.fBand) * (1 + vMax) + 0.5 * uvar.rngMedBlock * deltaF; /* read the SFTs*/ if ((inputSFTs = XLALLoadMultiSFTs ( config.catalog, fMin, fMax)) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALLoadMultiSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* calculate the psd and normalize the SFTs */ if (( multiPSDs = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.rngMedBlock, NULL )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALNormalizeMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* compute the noise weights for the AM coefficients */ if (( multiWeights = XLALComputeMultiNoiseWeights ( multiPSDs, uvar.rngMedBlock, 0 )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiNoiseWeights() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read the timestamps from the SFTs */ if ((multiTimes = XLALExtractMultiTimestampsFromSFTs ( inputSFTs )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALExtractMultiTimestampsFromSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read the detector information from the SFTs */ if ( XLALMultiLALDetectorFromMultiSFTs ( &multiDetectors, inputSFTs ) != XLAL_SUCCESS){ LogPrintf ( LOG_CRITICAL, "%s: XLALMultiLALDetectorFromMultiSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Find the detector state for each SFT */ /* Offset by Tsft/2 to get midpoint as timestamp */ if ((multiStates = XLALGetMultiDetectorStates ( multiTimes, &multiDetectors, config.edat, 0.5 * Tsft )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiDetectorStates() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Note this is specialized to a single sky position */ /* This might need to be moved into the config variables */ skyPos.system = COORDINATESYSTEM_EQUATORIAL; skyPos.longitude = uvar.alphaRad; skyPos.latitude = uvar.deltaRad; /* Calculate the AM coefficients (a,b) for each SFT */ if ((multiCoeffs = XLALComputeMultiAMCoeffs ( multiStates, multiWeights, skyPos )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiAMCoeffs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Construct the flat list of SFTs (this sort of replicates the catalog, but there's not an obvious way to get the information back) */ if ( ( XLALCreateSFTIndexListFromMultiSFTVect( &sftIndices, inputSFTs ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTIndexListFromMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Construct the list of SFT pairs */ #define PCC_SFTPAIR_HEADER "# The length of SFT-pair list is %u #\n" #define PCC_SFTPAIR_BODY "%u %u\n" #define PCC_SFT_HEADER "# The length of SFT list is %u #\n" #define PCC_SFT_BODY "%s %d %d\n" FILE *fp = NULL; if (XLALUserVarWasSet(&uvar.pairListInputFilename)) { /* If the user provided a list for reading, use it */ if((sftPairs = XLALCalloc(1, sizeof(sftPairs))) == NULL){ XLAL_ERROR(XLAL_ENOMEM); } if((fp = fopen(uvar.pairListInputFilename, "r")) == NULL){ LogPrintf ( LOG_CRITICAL, "didn't find SFT-pair list file with given input name\n"); XLAL_ERROR( XLAL_EFUNC ); } if(fscanf(fp,PCC_SFTPAIR_HEADER,&sftPairs->length)==EOF){ LogPrintf ( LOG_CRITICAL, "can't read the length of SFT-pair list from the header\n"); XLAL_ERROR( XLAL_EFUNC ); } if((sftPairs->data = XLALCalloc(sftPairs->length, sizeof(*sftPairs->data)))==NULL){ XLALFree(sftPairs); XLAL_ERROR(XLAL_ENOMEM); } for(j = 0; j < sftPairs->length; j++){ /*read in the SFT-pair list */ if(fscanf(fp,PCC_SFTPAIR_BODY, &sftPairs->data[j].sftNum[0], &sftPairs->data[j].sftNum[1])==EOF){ LogPrintf ( LOG_CRITICAL, "The length of SFT-pair list doesn't match!"); XLAL_ERROR( XLAL_EFUNC ); } } fclose(fp); } else { /* if not, construct the list of pairs */ if ( ( XLALCreateSFTPairIndexList( &sftPairs, sftIndices, inputSFTs, uvar.maxLag, uvar.inclAutoCorr ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTPairIndexList() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } } if (XLALUserVarWasSet(&uvar.pairListOutputFilename)) { /* Write the list of pairs to a file, if a name was provided */ if((fp = fopen(uvar.pairListOutputFilename, "w")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in SFT-pair list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_SFTPAIR_HEADER, sftPairs->length ); /*output the length of SFT-pair list to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_SFTPAIR_BODY, sftPairs->data[j].sftNum[0], sftPairs->data[j].sftNum[1]); } fclose(fp); } if (XLALUserVarWasSet(&uvar.sftListOutputFilename)) { /* Write the list of SFTs to a file for sanity-checking purposes */ if((fp = fopen(uvar.sftListOutputFilename, "w")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in flat SFT list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_SFT_HEADER, sftIndices->length ); /*output the length of SFT list to the header*/ for(j = 0; j < sftIndices->length; j++){ /*output the SFT list */ fprintf(fp,PCC_SFT_BODY, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds); } fclose(fp); } else if(XLALUserVarWasSet(&uvar.sftListInputFilename)){ /*do a sanity check of the order of SFTs list if the name of input SFT list is given*/ UINT4 numofsft=0; if((fp = fopen(uvar.sftListInputFilename, "r")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't read in flat SFT list \n"); XLAL_ERROR( XLAL_EFUNC ); } if (fscanf(fp, PCC_SFT_HEADER, &numofsft)==EOF){ LogPrintf ( LOG_CRITICAL, "can't read in the length of SFT list from header\n"); XLAL_ERROR( XLAL_EFUNC ); } CHARVectorSequence *checkDet=NULL; if ((checkDet = XLALCreateCHARVectorSequence (numofsft, LALNameLength) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateCHARVector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } INT4 checkGPS[numofsft], checkGPSns[numofsft]; if(numofsft == sftIndices->length){ for (j=0; j<numofsft; j++){ if( fscanf(fp,PCC_SFT_BODY,&checkDet->data[j * LALNameLength], &checkGPS[j], &checkGPSns[j])==EOF){ LogPrintf ( LOG_CRITICAL, "The length of SFT list doesn't match\n"); XLAL_ERROR( XLAL_EFUNC ); } if(strcmp( inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, &checkDet->data[j * LALNameLength] ) != 0 ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds != checkGPS[j] ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds != checkGPSns[j] ){ LogPrintf ( LOG_CRITICAL, "The order of SFTs has been changed, it's the end of civilization\n"); XLAL_ERROR( XLAL_EFUNC ); } } fclose(fp); XLALDestroyCHARVectorSequence(checkDet); } else{ LogPrintf ( LOG_CRITICAL, "Run for your life, the length of SFT list doesn't match"); XLAL_ERROR( XLAL_EFUNC ); } } else { } /* Get weighting factors for calculation of metric */ /* note that the sigma-squared is now absorbed into the curly G because the AM coefficients are noise-weighted. */ REAL8Vector *GammaAve = NULL; REAL8Vector *GammaCirc = NULL; if ( ( XLALCalculateCrossCorrGammas( &GammaAve, &GammaCirc, sftPairs, sftIndices, multiCoeffs) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrGammas() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } #define PCC_GAMMA_HEADER "# The normalization Sinv_Tsft is %g #\n" #define PCC_GAMMA_BODY "%.10g\n" if (XLALUserVarWasSet(&uvar.gammaAveOutputFilename)) { /* Write the aa+bb weight for each pair to a file, if a name was provided */ if((fp = fopen(uvar.gammaAveOutputFilename, "w")) == NULL) { LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_ave list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_GAMMA_BODY, GammaAve->data[j]); } fclose(fp); } if (XLALUserVarWasSet(&uvar.gammaCircOutputFilename)) { /* Write the ab-ba weight for each pair to a file, if a name was provided */ if((fp = fopen(uvar.gammaCircOutputFilename, "w")) == NULL) { LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_circ list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_GAMMA_BODY, GammaCirc->data[j]); } fclose(fp); } /*initialize binary parameters structure*/ XLAL_INIT_MEM(minBinaryTemplate); XLAL_INIT_MEM(maxBinaryTemplate); XLAL_INIT_MEM(thisBinaryTemplate); XLAL_INIT_MEM(binaryTemplateSpacings); /*fill in minbinaryOrbitParams*/ XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc); minBinaryTemplate.argp = 0.0; minBinaryTemplate.asini = uvar.orbitAsiniSec; minBinaryTemplate.ecc = 0.0; minBinaryTemplate.period = uvar.orbitPSec; minBinaryTemplate.fkdot[0] = uvar.fStart; /*fill in maxBinaryParams*/ XLALGPSSetREAL8( &maxBinaryTemplate.tp, uvar.orbitTimeAsc + uvar.orbitTimeAscBand); maxBinaryTemplate.argp = 0.0; maxBinaryTemplate.asini = uvar.orbitAsiniSec + uvar.orbitAsiniSecBand; maxBinaryTemplate.ecc = 0.0; maxBinaryTemplate.period = uvar.orbitPSec; maxBinaryTemplate.fkdot[0] = uvar.fStart + uvar.fBand; /*fill in thisBinaryTemplate*/ XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * uvar.orbitTimeAscBand); thisBinaryTemplate.argp = 0.0; thisBinaryTemplate.asini = 0.5*(minBinaryTemplate.asini + maxBinaryTemplate.asini); thisBinaryTemplate.ecc = 0.0; thisBinaryTemplate.period =0.5*(minBinaryTemplate.period + maxBinaryTemplate.period); thisBinaryTemplate.fkdot[0]=0.5*(minBinaryTemplate.fkdot[0] + maxBinaryTemplate.fkdot[0]); /*Get metric diagonal components, also estimate sensitivity i.e. E[rho]/(h0)^2 (4.13)*/ if ( (XLALCalculateLMXBCrossCorrDiagMetric(&estSens, &diagff, &diagaa, &diagTT, thisBinaryTemplate, GammaAve, sftPairs, sftIndices, inputSFTs, multiWeights /*, kappaValues*/) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateLMXBCrossCorrDiagMetric() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* spacing in frequency from diagff */ /* set spacings in new dopplerparams struct */ if (XLALUserVarWasSet(&uvar.spacingF)) /* If spacing was given by CMD line, use it, else calculate spacing by mismatch*/ binaryTemplateSpacings.fkdot[0] = uvar.spacingF; else binaryTemplateSpacings.fkdot[0] = sqrt(uvar.mismatchF / diagff); if (XLALUserVarWasSet(&uvar.spacingA)) binaryTemplateSpacings.asini = uvar.spacingA; else binaryTemplateSpacings.asini = sqrt(uvar.mismatchA / diagaa); /* this is annoying: tp is a GPS time while we want a difference in time which should be just REAL8 */ if (XLALUserVarWasSet(&uvar.spacingT)) XLALGPSSetREAL8( &binaryTemplateSpacings.tp, uvar.spacingT); else XLALGPSSetREAL8( &binaryTemplateSpacings.tp, sqrt(uvar.mismatchT / diagTT)); if (XLALUserVarWasSet(&uvar.spacingP)) binaryTemplateSpacings.period = uvar.spacingP; else binaryTemplateSpacings.period = sqrt(uvar.mismatchP / diagpp); /* metric elements for eccentric case not considered? */ UINT8 fCount = 0, aCount = 0, tCount = 0 , pCount = 0; const UINT8 fSpacingNum = floor( uvar.fBand / binaryTemplateSpacings.fkdot[0]); const UINT8 aSpacingNum = floor( uvar.orbitAsiniSecBand / binaryTemplateSpacings.asini); const UINT8 tSpacingNum = floor( uvar.orbitTimeAscBand / XLALGPSGetREAL8(&binaryTemplateSpacings.tp)); const UINT8 pSpacingNum = floor( uvar.orbitPSecBand / binaryTemplateSpacings.period); /*reset minbinaryOrbitParams to shift the first point a factor so as to make the center of all seaching points centers at the center of searching band*/ minBinaryTemplate.fkdot[0] = uvar.fStart + 0.5 * (uvar.fBand - fSpacingNum * binaryTemplateSpacings.fkdot[0]); minBinaryTemplate.asini = uvar.orbitAsiniSec + 0.5 * (uvar.orbitAsiniSecBand - aSpacingNum * binaryTemplateSpacings.asini); XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * (uvar.orbitTimeAscBand - tSpacingNum * XLALGPSGetREAL8(&binaryTemplateSpacings.tp))); minBinaryTemplate.period = uvar.orbitPSec + 0.5 * (uvar.orbitPSecBand - pSpacingNum * binaryTemplateSpacings.period); /* initialize the doppler scan struct which stores the current template information */ XLALGPSSetREAL8(&dopplerpos.refTime, config.refTime); dopplerpos.Alpha = uvar.alphaRad; dopplerpos.Delta = uvar.deltaRad; dopplerpos.fkdot[0] = minBinaryTemplate.fkdot[0]; /* set all spindowns to zero */ for (k=1; k < PULSAR_MAX_SPINS; k++) dopplerpos.fkdot[k] = 0.0; dopplerpos.asini = minBinaryTemplate.asini; dopplerpos.period = minBinaryTemplate.period; dopplerpos.tp = minBinaryTemplate.tp; dopplerpos.ecc = minBinaryTemplate.ecc; dopplerpos.argp = minBinaryTemplate.argp; /* now set the initial values of binary parameters */ /* thisBinaryTemplate.asini = uvar.orbitAsiniSec; thisBinaryTemplate.period = uvar.orbitPSec; XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc); thisBinaryTemplate.ecc = 0.0; thisBinaryTemplate.argp = 0.0;*/ /* copy to dopplerpos */ /* Calculate SSB times (can do this once since search is currently only for one sky position, and binary doppler shift is added later) */ MultiSSBtimes *multiSSBTimes = NULL; if ((multiSSBTimes = XLALGetMultiSSBtimes ( multiStates, skyPos, dopplerpos.refTime, SSBPREC_RELATIVISTICOPT )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* "New" general metric computation */ /* For now hard-code circular parameter space */ const DopplerCoordinateSystem coordSys = { .dim = 4, .coordIDs = { DOPPLERCOORD_FREQ, DOPPLERCOORD_ASINI, DOPPLERCOORD_TASC, DOPPLERCOORD_PORB, }, }; REAL8VectorSequence *phaseDerivs = NULL; if ( ( XLALCalculateCrossCorrPhaseDerivatives ( &phaseDerivs, &thisBinaryTemplate, config.edat, sftIndices, multiSSBTimes, &coordSys ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseDerivatives() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* fill in metric and parameter offsets */ gsl_matrix *g_ij = NULL; gsl_vector *eps_i = NULL; REAL8 sumGammaSq = 0; if ( ( XLALCalculateCrossCorrPhaseMetric ( &g_ij, &eps_i, &sumGammaSq, phaseDerivs, sftPairs, GammaAve, GammaCirc, &coordSys ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseMetric() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } XLALDestroyREAL8VectorSequence ( phaseDerivs ); XLALDestroyREAL8Vector ( GammaCirc ); if ((fp = fopen("gsldata.dat","w"))==NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in gsl matrix file"); XLAL_ERROR( XLAL_EFUNC ); } XLALfprintfGSLvector(fp, "%g", eps_i); XLALfprintfGSLmatrix(fp, "%g", g_ij); /* Allocate structure for binary doppler-shifting information */ if ((multiBinaryTimes = XLALDuplicateMultiSSBtimes ( multiSSBTimes )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALDuplicateMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } UINT8 numSFTs = sftIndices->length; if ((shiftedFreqs = XLALCreateREAL8Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((lowestBins = XLALCreateUINT4Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateUINT4Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((expSignalPhases = XLALCreateCOMPLEX8Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((sincList = XLALCreateREAL8VectorSequence ( numSFTs, uvar.numBins ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8VectorSequence() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* args should be : spacings, min and max doppler params */ BOOLEAN firstPoint = TRUE; /* a boolean to help to search at the beginning point in parameter space, after the search it is set to be FALSE to end the loop*/ if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /*Need to apply additional doppler shifting before the loop, or the first point in parameter space will be lost and return a wrong SNR when fBand!=0*/ while ( GetNextCrossCorrTemplate(&dopplerShiftFlag, &firstPoint, &dopplerpos, &binaryTemplateSpacings, &minBinaryTemplate, &maxBinaryTemplate, &fCount, &aCount, &tCount, &pCount, fSpacingNum, aSpacingNum, tSpacingNum, pSpacingNum) == 0) { /* do useful stuff here*/ /* Apply additional Doppler shifting using current binary orbital parameters */ /* Might want to be clever about checking whether we've changed the orbital parameters or only the frequency */ if (dopplerShiftFlag == TRUE) { if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } } if ( (XLALGetDopplerShiftedFrequencyInfo( shiftedFreqs, lowestBins, expSignalPhases, sincList, uvar.numBins, &dopplerpos, sftIndices, inputSFTs, multiBinaryTimes, Tsft ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALGetDopplerShiftedFrequencyInfo() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ( (XLALCalculatePulsarCrossCorrStatistic( &ccStat, &evSquared, GammaAve, expSignalPhases, lowestBins, sincList, sftPairs, sftIndices, inputSFTs, multiWeights, uvar.numBins) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculatePulsarCrossCorrStatistic() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* fill candidate struct and insert into toplist if necessary */ thisCandidate.freq = dopplerpos.fkdot[0]; thisCandidate.tp = XLALGPSGetREAL8( &dopplerpos.tp ); thisCandidate.argp = dopplerpos.argp; thisCandidate.asini = dopplerpos.asini; thisCandidate.ecc = dopplerpos.ecc; thisCandidate.period = dopplerpos.period; thisCandidate.rho = ccStat; thisCandidate.evSquared = evSquared; thisCandidate.estSens = estSens; insert_into_crossCorrBinary_toplist(ccToplist, thisCandidate); } /* end while loop over templates */ /* write candidates to file */ sort_crossCorrBinary_toplist( ccToplist ); /* add error checking */ final_write_crossCorrBinary_toplist_to_file( ccToplist, uvar.toplistFilename, &checksum); REAL8 h0Sens = sqrt((10 / sqrt(estSens))); /*for a SNR=10 signal, the h0 we can detect*/ XLALGPSTimeNow (&computingEndGPSTime); /*record the rough end time*/ UINT4 computingTime = computingEndGPSTime.gpsSeconds - computingStartGPSTime.gpsSeconds; /* make a meta-data file*/ if(XLALUserVarWasSet(&uvar.logFilename)){ CHAR *CMDInputStr = XLALUserVarGetLog ( UVAR_LOGFMT_CFGFILE ); if ((fp = fopen(uvar.logFilename,"w"))==NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in logfile"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp, "[UserInput]\n\n"); fprintf(fp, "%s\n", CMDInputStr); fprintf(fp, "[CalculatedValues]\n\n"); fprintf(fp, "g_ff = %.9f\n", diagff ); fprintf(fp, "g_aa = %.9f\n", diagaa ); fprintf(fp, "g_TT = %.9f\n", diagTT ); fprintf(fp, "FSpacing = %.9g\n", binaryTemplateSpacings.fkdot[0]); fprintf(fp, "ASpacing = %.9g\n", binaryTemplateSpacings.asini); fprintf(fp, "TSpacing = %.9g\n", XLALGPSGetREAL8(&binaryTemplateSpacings.tp)); /* fprintf(fp, "PSpacing = %.9g\n", binaryTemplateSpacings.period );*/ fprintf(fp, "TemplatenumF = %" LAL_UINT8_FORMAT "\n", (fSpacingNum + 1)); fprintf(fp, "TemplatenumA = %" LAL_UINT8_FORMAT "\n", (aSpacingNum + 1)); fprintf(fp, "TemplatenumT = %" LAL_UINT8_FORMAT "\n", (tSpacingNum + 1)); fprintf(fp, "TemplatenumP = %" LAL_UINT8_FORMAT "\n", (pSpacingNum + 1)); fprintf(fp, "TemplatenumTotal = %" LAL_UINT8_FORMAT "\n",(fSpacingNum + 1) * (aSpacingNum + 1) * (tSpacingNum + 1) * (pSpacingNum + 1)); fprintf(fp, "Sens = %.9g\n", estSens);/*(E[rho]/h0^2)^2*/ fprintf(fp, "h0_min_SNR10 = %.9g\n", h0Sens);/*for rho = 10 in our pipeline*/ fprintf(fp, "startTime = %" LAL_INT4_FORMAT "\n", computingStartGPSTime.gpsSeconds );/*start time in GPS-time*/ fprintf(fp, "endTime = %" LAL_INT4_FORMAT "\n", computingEndGPSTime.gpsSeconds );/*end time in GPS-time*/ fprintf(fp, "computingTime = %" LAL_UINT4_FORMAT "\n", computingTime );/*total time in sec*/ fprintf(fp, "SFTnum = %" LAL_UINT4_FORMAT "\n", sftIndices->length);/*total number of SFT*/ fprintf(fp, "pairnum = %" LAL_UINT4_FORMAT "\n", sftPairs->length);/*total number of pair of SFT*/ fprintf(fp, "Tsft = %.6g\n", Tsft);/*SFT duration*/ fprintf(fp, "\n[Version]\n\n"); fprintf(fp, "%s", VCSInfoString); fclose(fp); XLALFree(CMDInputStr); } XLALFree(VCSInfoString); XLALDestroyCOMPLEX8Vector ( expSignalPhases ); XLALDestroyUINT4Vector ( lowestBins ); XLALDestroyREAL8Vector ( shiftedFreqs ); XLALDestroyREAL8VectorSequence ( sincList ); XLALDestroyMultiSSBtimes ( multiBinaryTimes ); XLALDestroyMultiSSBtimes ( multiSSBTimes ); XLALDestroyREAL8Vector ( GammaAve ); XLALDestroySFTPairIndexList( sftPairs ); XLALDestroySFTIndexList( sftIndices ); XLALDestroyMultiAMCoeffs ( multiCoeffs ); XLALDestroyMultiDetectorStateSeries ( multiStates ); XLALDestroyMultiTimestamps ( multiTimes ); XLALDestroyMultiNoiseWeights ( multiWeights ); XLALDestroyMultiPSDVector ( multiPSDs ); XLALDestroyMultiSFTVector ( inputSFTs ); /* de-allocate memory for configuration variables */ XLALDestroyConfigVars ( &config ); /* de-allocate memory for user input variables */ XLALDestroyUserVars(); /* free toplist memory */ free_crossCorr_toplist(&ccToplist); /* check memory leaks if we forgot to de-allocate anything */ LALCheckMemoryLeaks(); LogPrintf (LOG_CRITICAL, "End time\n");/*for debug convenience to record calculating time*/ return 0; } /* main */ /* initialize and register user variables */ int XLALInitUserVars (UserInput_t *uvar) { /* initialize with some defaults */ uvar->help = FALSE; uvar->maxLag = 0.0; uvar->inclAutoCorr = FALSE; uvar->fStart = 100.0; uvar->fBand = 0.1; /* uvar->fdotStart = 0.0; */ /* uvar->fdotBand = 0.0; */ uvar->alphaRad = 0.0; uvar->deltaRad = 0.0; uvar->refTime = 0.0; uvar->rngMedBlock = 50; uvar->numBins = 1; /* zero binary orbital parameters means not a binary */ uvar->orbitAsiniSec = 0.0; uvar->orbitAsiniSecBand = 0.0; uvar->orbitPSec = 0.0; uvar->orbitPSecBand = 0.0; uvar->orbitTimeAsc = 0; uvar->orbitTimeAscBand = 0; /*default mismatch values */ /* set to 0.1 by default -- for no real reason */ /* make 0.1 a macro? */ uvar->mismatchF = 0.1; uvar->mismatchA = 0.1; uvar->mismatchT = 0.1; uvar->mismatchP = 0.1; uvar->ephemEarth = XLALStringDuplicate("earth00-19-DE405.dat.gz"); uvar->ephemSun = XLALStringDuplicate("sun00-19-DE405.dat.gz"); uvar->sftLocation = XLALCalloc(1, MAXFILENAMELENGTH+1); /* initialize number of candidates in toplist -- default is just to return the single best candidate */ uvar->numCand = 1; uvar->toplistFilename = XLALStringDuplicate("toplist_crosscorr.dat"); uvar->version = FALSE; /* register user-variables */ XLALregBOOLUserStruct ( help, 'h', UVAR_HELP, "Print this message"); XLALregINTUserStruct ( startTime, 0, UVAR_REQUIRED, "Desired start time of analysis in GPS seconds"); XLALregINTUserStruct ( endTime, 0, UVAR_REQUIRED, "Desired end time of analysis in GPS seconds"); XLALregREALUserStruct ( maxLag, 0, UVAR_OPTIONAL, "Maximum lag time in seconds between SFTs in correlation"); XLALregBOOLUserStruct ( inclAutoCorr, 0, UVAR_OPTIONAL, "Include auto-correlation terms (an SFT with itself)"); XLALregREALUserStruct ( fStart, 0, UVAR_OPTIONAL, "Start frequency in Hz"); XLALregREALUserStruct ( fBand, 0, UVAR_OPTIONAL, "Frequency band to search over in Hz "); /* XLALregREALUserStruct ( fdotStart, 0, UVAR_OPTIONAL, "Start value of spindown in Hz/s"); */ /* XLALregREALUserStruct ( fdotBand, 0, UVAR_OPTIONAL, "Band for spindown values in Hz/s"); */ XLALregREALUserStruct ( alphaRad, 0, UVAR_OPTIONAL, "Right ascension for directed search (radians)"); XLALregREALUserStruct ( deltaRad, 0, UVAR_OPTIONAL, "Declination for directed search (radians)"); XLALregREALUserStruct ( refTime, 0, UVAR_OPTIONAL, "SSB reference time for pulsar-parameters [Default: midPoint]"); XLALregREALUserStruct ( orbitAsiniSec, 0, UVAR_OPTIONAL, "Start of search band for projected semimajor axis (seconds) [0 means not a binary]"); XLALregREALUserStruct ( orbitAsiniSecBand, 0, UVAR_OPTIONAL, "Width of search band for projected semimajor axis (seconds)"); XLALregREALUserStruct ( orbitPSec, 0, UVAR_OPTIONAL, "Binary orbital period (seconds) [0 means not a binary]"); XLALregREALUserStruct ( orbitPSecBand, 0, UVAR_OPTIONAL, "Band for binary orbital period (seconds) "); XLALregREALUserStruct ( orbitTimeAsc, 0, UVAR_OPTIONAL, "Start of orbital time-of-ascension band in GPS seconds"); XLALregREALUserStruct ( orbitTimeAscBand, 0, UVAR_OPTIONAL, "Width of orbital time-of-ascension band (seconds)"); XLALregSTRINGUserStruct( ephemEarth, 0, UVAR_OPTIONAL, "Earth ephemeris file to use"); XLALregSTRINGUserStruct( ephemSun, 0, UVAR_OPTIONAL, "Sun ephemeris file to use"); XLALregSTRINGUserStruct( sftLocation, 0, UVAR_REQUIRED, "Filename pattern for locating SFT data"); XLALregINTUserStruct ( rngMedBlock, 0, UVAR_OPTIONAL, "Running median block size for PSD estimation"); XLALregINTUserStruct ( numBins, 0, UVAR_OPTIONAL, "Number of frequency bins to include in calculation"); XLALregREALUserStruct ( mismatchF, 0, UVAR_OPTIONAL, "Desired mismatch for frequency spacing"); XLALregREALUserStruct ( mismatchA, 0, UVAR_OPTIONAL, "Desired mismatch for asini spacing"); XLALregREALUserStruct ( mismatchT, 0, UVAR_OPTIONAL, "Desired mismatch for periapse passage time spacing"); XLALregREALUserStruct ( mismatchP, 0, UVAR_OPTIONAL, "Desired mismatch for period spacing"); XLALregREALUserStruct ( spacingF, 0, UVAR_OPTIONAL, "Desired frequency spacing"); XLALregREALUserStruct ( spacingA, 0, UVAR_OPTIONAL, "Desired asini spacing"); XLALregREALUserStruct ( spacingT, 0, UVAR_OPTIONAL, "Desired periapse passage time spacing"); XLALregREALUserStruct ( spacingP, 0, UVAR_OPTIONAL, "Desired period spacing"); XLALregINTUserStruct ( numCand, 0, UVAR_OPTIONAL, "Number of candidates to keep in toplist"); XLALregSTRINGUserStruct( pairListInputFilename, 0, UVAR_OPTIONAL, "Name of file from which to read list of SFT pairs"); XLALregSTRINGUserStruct( pairListOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write list of SFT pairs"); XLALregSTRINGUserStruct( sftListOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write list of SFTs (for sanity checks)"); XLALregSTRINGUserStruct( sftListInputFilename, 0, UVAR_OPTIONAL, "Name of file to which to read in list of SFTs (for sanity checks)"); XLALregSTRINGUserStruct( gammaAveOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write aa+bb weights (for e.g., false alarm estimation)"); XLALregSTRINGUserStruct( gammaCircOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write ab-ba weights (for e.g., systematic error)"); XLALregSTRINGUserStruct( toplistFilename, 0, UVAR_OPTIONAL, "Output filename containing candidates in toplist"); XLALregSTRINGUserStruct( logFilename, 0, UVAR_OPTIONAL, "Output a meta-data file for the search"); XLALregBOOLUserStruct ( version, 'V', UVAR_SPECIAL, "Output version(VCS) information"); if ( xlalErrno ) { XLALPrintError ("%s: user variable initialization failed with errno = %d.\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } return XLAL_SUCCESS; }
/** * Generate a (heterodyned) REAL4 timeseries of a CW signal for given pulsarParams, * site, start-time, duration, and sampling-rate * * NOTE: this is mostly an API-wrapper to the more 'old-style' function * XLALGeneratePulsarSignal() [which will become deprecated in the future], * extended for the option to generate transient-CW signals */ REAL4TimeSeries * XLALGenerateCWSignalTS ( const PulsarParams *pulsarParams, ///< input CW pulsar-signal parameters const LALDetector *site, ///< detector LIGOTimeGPS startTime, ///< time-series start-time GPS REAL8 duration, ///< time-series duration to generate REAL8 fSamp, ///< sampling frequency REAL8 fHet, ///< heterodyning frequency const EphemerisData *edat ///< ephemeris data ) { XLAL_CHECK_NULL ( pulsarParams != NULL, XLAL_EINVAL ); XLAL_CHECK_NULL ( site != NULL, XLAL_EINVAL ); XLAL_CHECK_NULL ( duration > 0, XLAL_EDOM ); XLAL_CHECK_NULL ( fSamp > 0, XLAL_EDOM ); XLAL_CHECK_NULL ( fHet >= 0, XLAL_EDOM ); // translate amplitude params REAL8 h0 = pulsarParams->Amp.h0; REAL8 cosi = pulsarParams->Amp.cosi; REAL8 aPlus = 0.5 * h0 * ( 1.0 + SQ(cosi) ); REAL8 aCross = h0 * cosi; // translate 'modern' fkdot into 'old-style' spindown-vector UINT4 s_max; for ( s_max = PULSAR_MAX_SPINS-1; s_max > 0; s_max -- ) { if ( pulsarParams->Doppler.fkdot[s_max] != 0 ) break; } // for s_max = max ... 0 REAL8Vector *spindown = NULL; if ( s_max > 0 ) { XLAL_CHECK_NULL ( (spindown = XLALCreateREAL8Vector ( s_max )) != NULL, XLAL_EFUNC ); for ( UINT4 s = 0; s < s_max; s ++ ) { spindown->data[s] = pulsarParams->Doppler.fkdot[s+1]; } } /*---------------------------------------- * fill old-style PulsarSignalParams struct *----------------------------------------*/ PulsarSignalParams XLAL_INIT_DECL(params); params.pulsar.refTime = pulsarParams->Doppler.refTime; params.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; params.pulsar.position.longitude = pulsarParams->Doppler.Alpha; params.pulsar.position.latitude = pulsarParams->Doppler.Delta; params.pulsar.aPlus = aPlus; params.pulsar.aCross = aCross; params.pulsar.phi0 = pulsarParams->Amp.phi0; params.pulsar.psi = pulsarParams->Amp.psi; params.pulsar.f0 = pulsarParams->Doppler.fkdot[0]; params.pulsar.spindown = spindown; params.orbit.tp = pulsarParams->Doppler.tp; params.orbit.argp = pulsarParams->Doppler.argp; params.orbit.asini = pulsarParams->Doppler.asini; params.orbit.ecc = pulsarParams->Doppler.ecc; params.orbit.period = pulsarParams->Doppler.period; params.transfer = NULL; params.ephemerides = edat; params.fHeterodyne = fHet; // detector-specific settings params.startTimeGPS = startTime; params.duration = ceil ( duration ); params.samplingRate = fSamp; params.site = site; /*---------------------------------------- * generate the signal time-series *----------------------------------------*/ REAL4TimeSeries *Tseries; XLAL_CHECK_NULL ( (Tseries = XLALGeneratePulsarSignal ( ¶ms )) != NULL, XLAL_EFUNC ); // ----- free internal memory XLALDestroyREAL8Vector ( spindown ); // ----- apply transient-CW window XLAL_CHECK_NULL ( XLALApplyTransientWindow ( Tseries, pulsarParams->Transient ) == XLAL_SUCCESS, XLAL_EFUNC ); return Tseries; } // XLALGenerateCWSignalTS()
int test_XLALSincInterpolateCOMPLEX8TimeSeries ( void ) { COMPLEX8TimeSeries* tsIn; REAL8 f0 = 100; // heterodyning frequency REAL8 dt = 0.1; // sampling frequency = 10Hz LIGOTimeGPS epoch = { 100, 0 }; REAL8 tStart = XLALGPSGetREAL8 ( &epoch ); UINT4 numSamples = 1000; REAL8 Tspan = numSamples * dt; XLAL_CHECK ( (tsIn = XLALCreateCOMPLEX8TimeSeries ( "test TS_in", &epoch, f0, dt, &emptyLALUnit, numSamples )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamples; j ++ ) { tsIn->data->data[j] = testSignal ( tStart + j * dt, 0 ); } // for j < numSamples // ---------- interpolate this onto new time-samples UINT4 Dterms = 16; REAL8 safety = (Dterms+1.0) * dt; // avoid truncated interpolation to minimize errors, set to 0 for seeing boundary-effects [they're not so bad...] LIGOTimeGPS epochOut = epoch; XLALGPSAdd ( &epochOut, safety ); REAL8 TspanOut = Tspan - 2 * safety; REAL8 dtOut = dt / 10; UINT4 numSamplesOut = lround ( TspanOut / dtOut ); COMPLEX8TimeSeries *tsOut; XLAL_CHECK ( (tsOut = XLALCreateCOMPLEX8TimeSeries ( "test TS_out", &epochOut, f0, dtOut, &emptyLALUnit, numSamplesOut )) != NULL, XLAL_EFUNC ); REAL8 tStartOut = XLALGPSGetREAL8 ( &epochOut ); REAL8Vector *times_out; XLAL_CHECK ( (times_out = XLALCreateREAL8Vector ( numSamplesOut )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamplesOut; j ++ ) { REAL8 t_j = tStartOut + j * dtOut; times_out->data[j] = t_j; } // for j < numSamplesOut XLAL_CHECK ( XLALSincInterpolateCOMPLEX8TimeSeries ( tsOut->data, times_out, tsIn, Dterms ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyREAL8Vector ( times_out ); // ---------- check accuracy of interpolation COMPLEX8TimeSeries *tsFull; XLAL_CHECK ( (tsFull = XLALCreateCOMPLEX8TimeSeries ( "test TS_full", &epochOut, f0, dtOut, &emptyLALUnit, numSamplesOut )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamplesOut; j ++ ) { tsFull->data->data[j] = testSignal ( tStartOut + j * dtOut, 0 ); } // for j < numSamplesOut // ----- out debug info if ( lalDebugLevel & LALINFO ) { XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_in.dat", tsIn ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_out.dat", tsOut ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_full.dat", tsFull ) == XLAL_SUCCESS, XLAL_EFUNC ); } // if LALINFO VectorComparison XLAL_INIT_DECL(tol); tol.relErr_L1 = 2e-2; tol.relErr_L2 = 2e-2; tol.angleV = 2e-2; tol.relErr_atMaxAbsx = 2e-2; tol.relErr_atMaxAbsy = 2e-2; XLALPrintInfo ("Comparing sinc-interpolated timeseries to exact signal timeseries:\n"); VectorComparison XLAL_INIT_DECL(cmp); XLAL_CHECK ( XLALCompareCOMPLEX8Vectors ( &cmp, tsOut->data, tsFull->data, &tol ) == XLAL_SUCCESS, XLAL_EFUNC ); // ---------- free memory XLALDestroyCOMPLEX8TimeSeries ( tsIn ); XLALDestroyCOMPLEX8TimeSeries ( tsOut ); XLALDestroyCOMPLEX8TimeSeries ( tsFull ); return XLAL_SUCCESS; } // test_XLALSincInterpolateCOMPLEX8TimeSeries()
int main(int argc, char *argv[]) { LALStatus status = blank_status; ConfigVariables XLAL_INIT_DECL(config); UserVariables_t XLAL_INIT_DECL(uvar); /* register user-variables */ XLAL_CHECK ( XLALInitUserVars ( &uvar ) == XLAL_SUCCESS, XLAL_EFUNC ); /* read cmdline & cfgfile */ BOOLEAN should_exit = 0; XLAL_CHECK( XLALUserVarReadAllInput( &should_exit, argc, argv ) == XLAL_SUCCESS, XLAL_EFUNC ); if ( should_exit ) { exit(1); } if ( uvar.version ) { XLALOutputVersionString ( stdout, lalDebugLevel ); exit(0); } /* basic setup and initializations */ XLAL_CHECK ( XLALInitCode( &config, &uvar, argv[0] ) == XLAL_SUCCESS, XLAL_EFUNC ); /* ----- allocate memory for AM-coeffs ----- */ AMCoeffs AMold, AMnew1, AMnew2; /**< containers holding AM-coefs computed by 3 different AM functions */ AMold.a = XLALCreateREAL4Vector ( 1 ); AMold.b = XLALCreateREAL4Vector ( 1 ); AMnew1.a = XLALCreateREAL4Vector ( 1 ); AMnew1.b = XLALCreateREAL4Vector ( 1 ); AMnew2.a = XLALCreateREAL4Vector ( 1 ); AMnew2.b = XLALCreateREAL4Vector ( 1 ); XLAL_CHECK ( AMold.a && AMold.b && AMnew1.a && AMnew1.b && AMnew2.a && AMnew2.a, XLAL_ENOMEM, "Failed to XLALCreateREAL4Vector ( 1 )\n" ); /* ----- get detector-state series ----- */ DetectorStateSeries *detStates = NULL; XLAL_CHECK ( (detStates = XLALGetDetectorStates ( config.timestamps, config.det, config.edat, 0 )) != NULL, XLAL_EFUNC ); /* ----- compute associated SSB timing info ----- */ SSBtimes *tSSB = XLALGetSSBtimes ( detStates, config.skypos, config.timeGPS, SSBPREC_RELATIVISTIC ); XLAL_CHECK ( tSSB != NULL, XLAL_EFUNC, "XLALGetSSBtimes() failed with xlalErrno = %d\n", xlalErrno ); /* ===== 1) compute AM-coeffs the 'old way': [used in CFSv1] ===== */ BarycenterInput XLAL_INIT_DECL(baryinput); AMCoeffsParams XLAL_INIT_DECL(amParams); EarthState earth; baryinput.site.location[0] = config.det->location[0]/LAL_C_SI; baryinput.site.location[1] = config.det->location[1]/LAL_C_SI; baryinput.site.location[2] = config.det->location[2]/LAL_C_SI; baryinput.alpha = config.skypos.longitude; baryinput.delta = config.skypos.latitude; baryinput.dInv = 0.e0; /* amParams structure to compute a(t) and b(t) */ amParams.das = XLALMalloc(sizeof(*amParams.das)); amParams.das->pSource = XLALMalloc(sizeof(*amParams.das->pSource)); amParams.baryinput = &baryinput; amParams.earth = &earth; amParams.edat = config.edat; amParams.das->pDetector = config.det; amParams.das->pSource->equatorialCoords.longitude = config.skypos.longitude; amParams.das->pSource->equatorialCoords.latitude = config.skypos.latitude; amParams.das->pSource->orientation = 0.0; amParams.das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; amParams.polAngle = 0; LAL_CALL ( LALComputeAM ( &status, &AMold, config.timestamps->data, &amParams), &status); XLALFree ( amParams.das->pSource ); XLALFree ( amParams.das ); /* ===== 2) compute AM-coeffs the 'new way' using LALNewGetAMCoeffs() */ LALGetAMCoeffs ( &status, &AMnew1, detStates, config.skypos ); if ( status.statusCode ) { XLALPrintError ("%s: call to LALGetAMCoeffs() failed, status = %d\n\n", __func__, status.statusCode ); XLAL_ERROR ( status.statusCode & XLAL_EFUNC ); } /* ===== 3) compute AM-coeffs the 'newer way' using LALNewGetAMCoeffs() [used in CFSv2] */ LALNewGetAMCoeffs ( &status, &AMnew2, detStates, config.skypos ); if ( status.statusCode ) { XLALPrintError ("%s: call to LALNewGetAMCoeffs() failed, status = %d\n\n", __func__, status.statusCode ); XLAL_ERROR ( status.statusCode & XLAL_EFUNC ); } /* ===== 4) use standalone version of the above [used in FstatMetric_v2] */ REAL8 a0,b0; if ( XLALComputeAntennaPatternCoeffs ( &a0, &b0, &config.skypos, &config.timeGPS, config.det, config.edat ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALComputeAntennaPatternCoeffs() failed.\n", __func__ ); XLAL_ERROR ( XLAL_EFUNC ); } /* ==================== output the results ==================== */ printf ("\n"); printf ("----- Input parameters:\n"); printf ("tGPS = { %d, %d }\n", config.timeGPS.gpsSeconds, config.timeGPS.gpsNanoSeconds ); printf ("Detector = %s\n", config.det->frDetector.name ); printf ("Sky position: longitude = %g rad, latitude = %g rad [equatorial coordinates]\n", config.skypos.longitude, config.skypos.latitude ); printf ("\n"); printf ("----- Antenna pattern functions (a,b):\n"); printf ("LALComputeAM: ( %-12.8g, %-12.8g) [REAL4]\n", AMold.a->data[0], AMold.b->data[0] ); printf ("LALGetAMCoeffs: ( %-12.8g, %-12.8g) [REAL4]\n", AMnew1.a->data[0], AMnew1.b->data[0] ); printf ("LALNewGetAMCoeffs: ( %-12.8g, %-12.8g) [REAL4]\n", AMnew2.a->data[0]/config.sinzeta, AMnew2.b->data[0]/config.sinzeta ); printf ("XLALComputeAntennaPatternCoeffs: ( %-12.8g, %-12.8g) [REAL8]\n", a0/config.sinzeta, b0/config.sinzeta ); printf ("\n"); printf ("----- Detector & Earth state:\n"); REAL8 *pos = detStates->data[0].rDetector; printf ("Detector position [ICRS J2000. Units=sec]: rDet = {%g, %g, %g}\n", pos[0], pos[1], pos[2] ); REAL8 *vel = detStates->data[0].vDetector; printf ("Detector velocity [ICRS J2000. Units=c]: vDet = {%g, %g, %g}\n", vel[0], vel[1], vel[2] ); printf ("Local mean sideral time: LMST = %g rad\n", detStates->data[0].LMST); printf ("\n"); printf ("----- SSB timing data:\n"); printf ("TOA difference tSSB - tDet = %g s\n", tSSB->DeltaT->data[0] ); printf ("TOA rate of change dtSSB/dtDet - 1 = %g\n", tSSB->Tdot->data[0] - 1.0 ); printf ("\n\n"); /* ----- done: free all memory */ XLAL_CHECK ( XLALDestroyConfig( &config ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyDetectorStateSeries ( detStates ); XLALDestroyREAL4Vector ( AMold.a ); XLALDestroyREAL4Vector ( AMold.b ); XLALDestroyREAL4Vector ( AMnew1.a ); XLALDestroyREAL4Vector ( AMnew1.b ); XLALDestroyREAL4Vector ( AMnew2.a ); XLALDestroyREAL4Vector ( AMnew2.b ); XLALDestroyREAL8Vector ( tSSB->DeltaT ); XLALDestroyREAL8Vector ( tSSB->Tdot ); XLALFree (tSSB); LALCheckMemoryLeaks(); return 0; } /* main */