/** Destructor for internal configuration struct */ int XLALDestroyConfig ( ConfigVariables *cfg ) { XLAL_CHECK ( cfg != NULL, XLAL_EINVAL ); XLALDestroyUserVars (); XLALDestroyTimestampVector ( cfg->timestamps ); XLALDestroyEphemerisData ( cfg->edat ); XLALFree ( cfg->det ); return XLAL_SUCCESS; } /* XLALDestroyConfig() */
/** * Load all SFTs according to user-input, returns multi-SFT vector. * \return cfg: * Returns 'effective' range of SFT-bins [firstBin, lastBin], which which the PSD will be estimated: * - if the user input {fStart, fBand} then these are loaded from SFTs and directly translated into bins * - if user input {Freq, FreqBand}, we load a wider frequency-band ADDING running-median/2 on either side * from the SFTs, and firstBind, lastBin correspond to {Freq,FreqBand} (rounded to closest bins) * Also returns the 'data-segment' for which SFTs were loaded * */ MultiSFTVector * XLALReadSFTs ( ConfigVariables_t *cfg, /**< [out] return derived configuration info (firstBin, lastBin, segment) */ const UserVariables_t *uvar /**< [in] complete user-input */ ) { SFTCatalog *catalog = NULL; SFTConstraints XLAL_INIT_DECL(constraints); LIGOTimeGPS startTimeGPS = {0,0}, endTimeGPS = {0,0}; LIGOTimeGPSVector *inputTimeStampsVector = NULL; /* check input */ if ( !uvar || !uvar->inputData ) { XLALPrintError ("%s: invalid NULL input 'uvar' or 'uvar->inputData'\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( !cfg ) { XLALPrintError ("%s: invalid NULL input 'cfg'", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* set detector constraint */ if ( XLALUserVarWasSet ( &uvar->IFO ) ) constraints.detector = uvar->IFO; else constraints.detector = NULL; if ( XLALUserVarWasSet( &uvar->startTime ) ) { XLALGPSSetREAL8 ( &startTimeGPS, uvar->startTime); constraints.minStartTime = &startTimeGPS; } if ( XLALUserVarWasSet( &uvar->endTime ) ) { XLALGPSSetREAL8 ( &endTimeGPS, uvar->endTime); constraints.maxStartTime = &endTimeGPS; } if ( XLALUserVarWasSet( &uvar->timeStampsFile ) ) { if ( (inputTimeStampsVector = XLALReadTimestampsFile ( uvar->timeStampsFile )) == NULL ) XLAL_ERROR_NULL ( XLAL_EFUNC ); constraints.timestamps = inputTimeStampsVector; } /* get sft catalog */ LogPrintf ( LOG_DEBUG, "Finding all SFTs to load ... "); if ( ( catalog = XLALSFTdataFind ( uvar->inputData, &constraints) ) == NULL ) { XLALPrintError ("%s: XLALSFTdataFind() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFAILED ); } if ( (catalog == NULL) || (catalog->length == 0) ) { XLALPrintError ("%s: Unable to match any SFTs with pattern '%s'\n", __func__, uvar->inputData ); XLAL_ERROR_NULL ( XLAL_EFAILED ); } LogPrintfVerbatim ( LOG_DEBUG, "done (found %i SFTs).\n", catalog->length); /* now we can free the inputTimeStampsVector */ if ( inputTimeStampsVector ) XLALDestroyTimestampVector ( inputTimeStampsVector ); /* ----- some user-input consistency checks */ BOOLEAN have_fStart = XLALUserVarWasSet ( &uvar->fStart ); BOOLEAN have_Freq = XLALUserVarWasSet ( &uvar->Freq ); BOOLEAN have_fBand = XLALUserVarWasSet ( &uvar->fBand ); BOOLEAN have_FreqBand = XLALUserVarWasSet ( &uvar->FreqBand ); if ( have_fStart && have_Freq ) { XLALPrintError ("%s: use only one of --fStart OR --Freq (see --help)\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( have_fBand && have_FreqBand ) { XLALPrintError ("%s: use only one of --fBand OR --FreqBand (see --help)\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( ( have_fStart && have_FreqBand ) || ( have_Freq && have_fBand ) ) { XLALPrintError ("%s: don't mix {--fStart,--fBand} with {--Freq,--FreqBand} inputs (see --help)\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* ---------- figure out the right frequency-band to read from the SFTs, depending on user-input ----- */ REAL8 fMin, fMax; UINT4 binsOffset; /* rngmed bin offset from start and end */ UINT4 binsBand=0; /* width of physical FreqBand in bins */ if ( have_Freq ) { REAL8 dFreq = catalog->data[0].header.deltaF; binsOffset = uvar->blocksRngMed / 2 + 1; /* truncates down plus add one bin extra safety! */ binsBand = ceil ( (uvar->FreqBand - 1e-9) / dFreq ) + 1; /* round up ! */ REAL8 rngmedSideBand = binsOffset * dFreq; fMin = uvar->Freq - rngmedSideBand; fMax = uvar->Freq + uvar->FreqBand + rngmedSideBand; } else /* NOTE: if no user-input on freq-band, we fall back to defaults on {fStart, fBand} */ { fMin = uvar->fStart; fMax = uvar->fStart + uvar->fBand; binsOffset = 0; /* no truncation of rngmed sidebands */ } /* ----- figure out the data-segment span from the user-input and SFT-catalog ----- */ /* if used passed these, then 'startTimeGPS' and 'endTimeGPS' are already set */ if ( startTimeGPS.gpsSeconds == 0 ) startTimeGPS = catalog->data[0].header.epoch; if ( endTimeGPS.gpsSeconds == 0 ) endTimeGPS = catalog->data[catalog->length-1].header.epoch; /* SFT 'constraints' only refer to SFT *start-times*, for segment we need the end-time */ REAL8 Tsft = 1.0 / catalog->data[0].header.deltaF; XLALGPSAdd ( &endTimeGPS, Tsft ); /* ---------- read the sfts ---------- */ LogPrintf (LOG_DEBUG, "Loading all SFTs ... "); MultiSFTVector *multi_sfts; if ( ( multi_sfts = XLALLoadMultiSFTs ( catalog, fMin, fMax ) ) == NULL ) { XLALPrintError ("%s: XLALLoadMultiSFTs( %f, %f ) failed with xlalErrno = %d\n", __func__, fMin, fMax, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } XLALDestroySFTCatalog ( catalog ); LogPrintfVerbatim ( LOG_DEBUG, "done.\n"); /* ---------- end loading SFTs ---------- */ /* figure out effective PSD bin-boundaries for user */ UINT4 numBins = multi_sfts->data[0]->data[0].data->length; INT4 bin0, bin1; if ( have_Freq ) { bin0 = 0 + binsOffset; bin1 = bin0 + binsBand - 1; } else /* output all bins loaded from SFTs (includes rngmed-sidebands) */ { bin0 = 0; bin1 = numBins - 1; } /* return results */ cfg->firstBin = (UINT4) bin0; cfg->lastBin = (UINT4) bin1; cfg->dataSegment.start = startTimeGPS; cfg->dataSegment.end = endTimeGPS; XLALPrintInfo ("%s: loaded SFTs have %d bins, effective PSD output band is [%d, %d]\n", __func__, numBins, bin0, bin1 ); return multi_sfts; } /* XLALReadSFTs() */
/*---------------------------------------------------------------------- * main function *----------------------------------------------------------------------*/ int main(int argc, char *argv[]) { SFTConstraints XLAL_INIT_DECL(constraints); LIGOTimeGPS XLAL_INIT_DECL(minStartTimeGPS); LIGOTimeGPS XLAL_INIT_DECL(maxStartTimeGPS); SFTCatalog *FullCatalog = NULL; CHAR *add_comment = NULL; UINT4 i; REAL8 fMin, fMax; UserInput_t XLAL_INIT_DECL(uvar); /* register all user-variables */ XLAL_CHECK_MAIN ( initUserVars ( &uvar ) == XLAL_SUCCESS, XLAL_EFUNC ); /* read cmdline & cfgfile */ XLAL_CHECK_MAIN ( XLALUserVarReadAllInput (argc, argv) == XLAL_SUCCESS, XLAL_EFUNC ); if (uvar.help) { /* help requested: we're done */ exit (0); } /* ----- make sure output directory exists ---------- */ if ( uvar.outputDir ) { int ret; ret = mkdir ( uvar.outputDir, 0777); if ( (ret == -1) && ( errno != EEXIST ) ) { int errsv = errno; LogPrintf (LOG_CRITICAL, "Failed to create directory '%s': %s\n", uvar.outputDir, strerror(errsv) ); return -1; } } LIGOTimeGPSVector *timestamps = NULL; if ( uvar.timestampsFile ) { if ( (timestamps = XLALReadTimestampsFile ( uvar.timestampsFile )) == NULL ) { XLALPrintError ("XLALReadTimestampsFile() failed to load timestamps from file '%s'\n", uvar.timestampsFile ); return -1; } } /* use IFO-contraint if one given by the user */ if ( LALUserVarWasSet ( &uvar.IFO ) ) { XLAL_CHECK_MAIN ( (constraints.detector = XLALGetChannelPrefix ( uvar.IFO )) != NULL, XLAL_EINVAL ); } minStartTimeGPS.gpsSeconds = uvar.minStartTime; maxStartTimeGPS.gpsSeconds = uvar.maxStartTime; constraints.minStartTime = &minStartTimeGPS; constraints.maxStartTime = &maxStartTimeGPS; constraints.timestamps = timestamps; /* get full SFT-catalog of all matching (multi-IFO) SFTs */ XLAL_CHECK_MAIN ( (FullCatalog = XLALSFTdataFind ( uvar.inputSFTs, &constraints )) != NULL, XLAL_EFUNC ); if ( constraints.detector ) { XLALFree ( constraints.detector ); } XLAL_CHECK_MAIN ( (FullCatalog != NULL) && (FullCatalog->length > 0), XLAL_EINVAL, "\nSorry, didn't find any matching SFTs with pattern '%s'!\n\n", uvar.inputSFTs ); /* build up full comment-string to be added to SFTs: 1) converted by ConvertToSFTv2, VCS ID 2) user extraComment */ { UINT4 len = 128; len += strlen ( uvar.inputSFTs ); if ( uvar.extraComment ) len += strlen ( uvar.extraComment ); XLAL_CHECK_MAIN ( ( add_comment = LALCalloc ( 1, len )) != NULL, XLAL_ENOMEM ); /** \deprecated FIXME: the following code uses obsolete CVS ID tags. * It should be modified to use git version information. */ sprintf ( add_comment, "Converted by $Id$, inputSFTs = '%s';", uvar.inputSFTs ); if ( uvar.extraComment ) { strcat ( add_comment, "\n"); strcat ( add_comment, uvar.extraComment ); } } /* construct comment-string */ /* which frequency-band to extract? */ fMin = -1; /* default: all */ fMax = -1; if ( LALUserVarWasSet ( &uvar.fmin ) ) fMin = uvar.fmin; if ( LALUserVarWasSet ( &uvar.fmax ) ) fMax = uvar.fmax; FILE *fpSingleSFT = NULL; if ( uvar.outputSingleSFT ) XLAL_CHECK ( ( fpSingleSFT = fopen ( uvar.outputSingleSFT, "wb" )) != NULL, XLAL_EIO, "Failed to open singleSFT file '%s' for writing\n", uvar.outputSingleSFT ); /* loop over all SFTs in SFTCatalog */ for ( i=0; i < FullCatalog->length; i ++ ) { SFTCatalog oneSFTCatalog; SFTVector *thisSFT = NULL; const CHAR *sft_comment; CHAR *new_comment; UINT4 comment_len = 0; /* set catalog containing only one SFT */ oneSFTCatalog.length = 1; oneSFTCatalog.data = &(FullCatalog->data[i]); comment_len = strlen ( add_comment ) + 10; sft_comment = oneSFTCatalog.data->comment; if ( sft_comment ) comment_len += strlen ( sft_comment ); XLAL_CHECK_MAIN ( ( new_comment = LALCalloc (1, comment_len )) != NULL, XLAL_ENOMEM ); if ( sft_comment ) { strcpy ( new_comment, sft_comment ); strcat ( new_comment, ";\n"); } strcat ( new_comment, add_comment ); XLAL_CHECK_MAIN ( (thisSFT = XLALLoadSFTs ( &oneSFTCatalog, fMin, fMax )) != NULL, XLAL_EFUNC ); if ( uvar.mysteryFactor != 1.0 ) { XLAL_CHECK_MAIN ( applyFactor2SFTs ( thisSFT, uvar.mysteryFactor ) == XLAL_SUCCESS, XLAL_EFUNC ); } // if user asked for single-SFT output, add this SFT to the open file if ( uvar.outputSingleSFT ) XLAL_CHECK ( XLAL_SUCCESS == XLALWriteSFT2fp( &(thisSFT->data[0]), fpSingleSFT, new_comment ), XLAL_EFUNC, "XLALWriteSFT2fp() failed to write SFT to '%s'!\n", uvar.outputSingleSFT ); // if user asked for directory output, write this SFT into that directory if ( uvar.outputDir ) { XLAL_CHECK_MAIN ( XLALWriteSFTVector2Dir ( thisSFT, uvar.outputDir, new_comment, uvar.descriptionMisc ) == XLAL_SUCCESS, XLAL_EFUNC ); } XLALDestroySFTVector ( thisSFT ); XLALFree ( new_comment ); } /* for i < numSFTs */ if ( fpSingleSFT ) { fclose ( fpSingleSFT ); } /* free memory */ XLALFree ( add_comment ); XLALDestroySFTCatalog ( FullCatalog ); XLALDestroyUserVars(); XLALDestroyTimestampVector ( timestamps ); LALCheckMemoryLeaks(); return 0; } /* main */
/** * Very simple test: pick random skyposition, compute a_i, b_i using * once LALComputeAM() and once LALNewGetAMCoeffs(), and look at the errors * sum_i (a_i - a_i')^2 */ int main(int argc, char *argv[]) { LALStatus XLAL_INIT_DECL(status); int opt; /* Command-line option. */ LIGOTimeGPS startTime = {714180733, 0}; REAL8 duration = 180000; /* 50 hours */ REAL8 Tsft = 1800; /* assume 30min SFTs */ LIGOTimeGPSVector *timestamps = NULL; DetectorStateSeries *detStates = NULL; SkyPosition XLAL_INIT_DECL(skypos); EphemerisData XLAL_INIT_DECL(edat); BarycenterInput XLAL_INIT_DECL(baryinput); LALDetector *det = NULL; AMCoeffs XLAL_INIT_DECL(AMold); AMCoeffs XLAL_INIT_DECL(AMnew1); AMCoeffs XLAL_INIT_DECL(AMnew2); REAL8 alpha, delta; AMCoeffsParams XLAL_INIT_DECL(amParams); EarthState earth; UINT4 i; REAL8 maxerr01, maxerr02, maxerr12, averr01, averr02, averr12; REAL8 tolerance = 1e-2; /* be generous: allow 1% error */ struct tms buf; const CHAR *sites[] = {"H1", "L1", "V2", "G1", "T1" }; REAL8 sinzeta; /* zeta = IFO opening angle */ UINT4 pickedSite; BOOLEAN ignoreErrors = 0; /* Don't fail if tolerance exceeded */ UINT4 numChecks = 1; /* Number of times to check */ char earthEphem[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz"; char sunEphem[] = TEST_DATA_DIR "sun00-19-DE405.dat.gz"; /* ----- old testing code to use 9 degree earth rotations ----- */ /* startTime.gpsSeconds = 714275242; duration = 86164; Tsft = 2154.1; */ while ((opt = LALgetopt( argc, argv, "n:qv:" )) != -1) { switch (opt) { case 'v': /* set lalDebugLevel */ break; case 'q': /* don't fail if tolerance exceeded */ ignoreErrors = 1; break; case 'n': /* number of times to check */ numChecks = atoi( LALoptarg ); break; } } /* init random-generator */ srand ( times(&buf) ); /* ----- init ephemeris ----- */ edat.ephiles.earthEphemeris = earthEphem; edat.ephiles.sunEphemeris = sunEphem; SUB ( LALInitBarycenter(&status, &edat), &status); /* ----- get timestamps ----- */ SUB ( LALMakeTimestamps ( &status, ×tamps, startTime, duration, Tsft ), &status ); /* ----- allocate memory for AM-coeffs ----- */ AMold.a = XLALCreateREAL4Vector ( timestamps->length ); AMold.b = XLALCreateREAL4Vector ( timestamps->length ); AMnew1.a = XLALCreateREAL4Vector ( timestamps->length ); AMnew1.b = XLALCreateREAL4Vector ( timestamps->length ); AMnew2.a = XLALCreateREAL4Vector ( timestamps->length ); AMnew2.b = XLALCreateREAL4Vector ( timestamps->length ); while ( numChecks-- ) { /* ----- pick detector-site at random ----- */ pickedSite = floor( 5 * (1.0 * rand() / (RAND_MAX + 1.0) ) ); /* int in [0,5) */ /* NOTE: contrary to ComputeAM() and LALGetAMCoffs(), the new function LALNewGetAMCoeffs() * computes 'a * sinzeta' and 'b * sinzeta': for the comparison we therefore need to correct * for GEO's opening-angle of 94.33degrees [JKS98]: */ if ( ! strcmp ( sites[pickedSite], "G1" ) ) sinzeta = 0.997146; else sinzeta = 1; if ( ( det = XLALGetSiteInfo ( sites[pickedSite] )) == NULL ) { XLALPrintError ("\nCall to XLALGetSiteInfo() has failed for site = '%s'... \n\n", sites[pickedSite]); return NEWGETAMCOEFFSTEST_ESUB; } /* ----- pick skyposition at random ----- */ alpha = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) ); /* uniform in [0, 2pi) */ delta = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX ); /* sin(delta) uniform in [-1,1] */ /* ----- old testing code to put source overhead ----- */ /* alpha = det->frDetector.vertexLongitudeRadians; delta = det->frDetector.vertexLatitudeRadians; */ /* ===== compute AM-coeffs the 'old way': ===== */ baryinput.site.location[0] = det->location[0]/LAL_C_SI; baryinput.site.location[1] = det->location[1]/LAL_C_SI; baryinput.site.location[2] = det->location[2]/LAL_C_SI; baryinput.alpha = alpha; baryinput.delta = delta; baryinput.dInv = 0.e0; /* amParams structure to compute a(t) and b(t) */ amParams.das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource)); amParams.das->pSource = (LALSource *)LALMalloc(sizeof(LALSource)); amParams.baryinput = &baryinput; amParams.earth = &earth; amParams.edat = &edat; amParams.das->pDetector = det; amParams.das->pSource->equatorialCoords.longitude = alpha; amParams.das->pSource->equatorialCoords.latitude = delta; amParams.das->pSource->orientation = 0.0; amParams.das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; amParams.polAngle = 0; SUB (LALComputeAM ( &status, &AMold, timestamps->data, &amParams), &status); /* ===== compute AM-coeffs the 'new way' using LALNewGetAMCoeffs() */ /* ----- get detector-state series ----- */ SUB ( LALGetDetectorStates (&status, &detStates, timestamps, det, &edat, 0 ), &status ); skypos.system = COORDINATESYSTEM_EQUATORIAL; skypos.longitude = alpha; skypos.latitude = delta; /* the 'new' and the 'newer' way ... */ SUB ( LALGetAMCoeffs ( &status, &AMnew1, detStates, skypos ), &status ); /* 'new1' */ SUB ( LALNewGetAMCoeffs ( &status, &AMnew2, detStates, skypos ), &status ); /* 'new2' */ /* ===== analyse relative errors ===== */ maxerr01 = maxerr02 = maxerr12 = 0; /* errors between 0='old', 1='new1', 2='new2' */ averr01 = averr02 = averr12 = 0; for ( i=0; i < timestamps->length; i ++ ) { /* printf("GPS time: %d s %d ns; GMST in radians: %f\n", detStates->data[i].tGPS.gpsSeconds, detStates->data[i].tGPS.gpsNanoSeconds, fmod(detStates->data[i].earthState.gmstRad,LAL_TWOPI)); printf("Old AM coeffs: a=%f, b=%f\nNew AM coeffs: a=%f, b=%f\nNEWER AM coeffs: a=%f b=%f", AMold.a->data[i], AMold.b->data[i], AMnew.a->data[i], AMnew.b->data[i], AMnewer.a->data[i], AMnewer.b->data[i]); */ REAL8 thisErr; /* compare 0-1 */ thisErr = sqrt( SQ ( AMold.a->data[i] - AMnew1.a->data[i] ) / AMold.A ); averr01 += thisErr; maxerr01 = MYMAX( thisErr, maxerr01 ); thisErr = sqrt( SQ ( AMold.b->data[i] - AMnew1.b->data[i] ) / AMold.B ); averr01 += thisErr; maxerr01 = MYMAX( thisErr, maxerr01 ); /* compare 0-2 */ thisErr = sqrt( SQ ( AMold.a->data[i] - AMnew2.a->data[i]/sinzeta ) / AMold.A ); averr02 += thisErr; maxerr02 = MYMAX( thisErr, maxerr02 ); thisErr = sqrt( SQ ( AMold.b->data[i] - AMnew2.b->data[i]/sinzeta ) / AMold.B ); averr02 += thisErr; maxerr02 = MYMAX( thisErr, maxerr02 ); /* compare 1-2 */ thisErr = sqrt( SQ ( AMnew1.a->data[i] - AMnew2.a->data[i]/sinzeta ) / AMold.A ); averr12 += thisErr; maxerr12 = MYMAX( thisErr, maxerr12 ); thisErr = sqrt( SQ ( AMnew1.b->data[i] - AMnew2.b->data[i]/sinzeta ) / AMold.B ); averr12 += thisErr; maxerr12 = MYMAX( thisErr, maxerr12 ); } averr01 /= 2.0 * timestamps->length; averr02 /= 2.0 * timestamps->length; averr12 /= 2.0 * timestamps->length; if ( lalDebugLevel ) { printf ("Parameters: IFO = %s, skypos = [%g, %g]\n", sites[pickedSite], alpha, delta ); printf ("Maximal relative errors: maxerr(0-1) = %g %%, maxerr(0-2) = %g %% maxerr(1-2) = %g %%\n", 100.0 * maxerr01, 100.0 * maxerr02, 100.0 * maxerr12 ); printf ("Average relative errors: averr(0-1) = %g %%, averr(0-2) = %g %% averr(1-2) = %g %%\n", 100.0 * averr01, 100.0 * averr02, 100.0 * averr12 ); } else printf ("%d %g %g \t %g %g %g \t %g %g %g\n", pickedSite, alpha, delta, averr01, averr02, averr12, maxerr01, maxerr02, maxerr12); if ( (averr01 > tolerance) || (averr02 > tolerance) || (averr12 > tolerance) || (maxerr01 > tolerance) ||(maxerr02 > tolerance) || (maxerr12 > tolerance) ) { XLALPrintError ("Maximal error-tolerance of %g %% was exceeded!\n", 100.0 * tolerance ); if (!ignoreErrors) return 1; } if ( lalDebugLevel ) printf("%d checks left\n", numChecks); /* ---- Clean up things that were created in this loop ---- */ XLALDestroyDetectorStateSeries ( detStates ); detStates = NULL; LALFree ( det ); LALFree ( amParams.das->pSource ); LALFree ( amParams.das ); } /* ----- free memory ----- */ XLALDestroyTimestampVector ( timestamps ); XLALDestroyREAL4Vector ( AMold.a ); XLALDestroyREAL4Vector ( AMold.b ); XLALDestroyREAL4Vector ( AMnew1.a ); XLALDestroyREAL4Vector ( AMnew1.b ); XLALDestroyREAL4Vector ( AMnew2.a ); XLALDestroyREAL4Vector ( AMnew2.b ); LALFree(edat.ephemE); LALFree(edat.ephemS); LALCheckMemoryLeaks(); return 0; /* OK */ } /* main() */
/** * Very simple test: pick random skyposition, compute a_i, b_i using * once LALComputeAM() and once LALGetAMCoeffs(), and look at the errors * sum_i (a_i - a_i')^2 */ int main(int argc, char *argv[]) { LALStatus XLAL_INIT_DECL(status); LIGOTimeGPS startTime = {714180733, 0}; REAL8 duration = 180000; /* 50 hours */ REAL8 Tsft = 1800; /* assume 30min SFTs */ LIGOTimeGPSVector *timestamps = NULL; DetectorStateSeries *detStates = NULL; SkyPosition XLAL_INIT_DECL(skypos); EphemerisData XLAL_INIT_DECL(edat); BarycenterInput XLAL_INIT_DECL(baryinput); LALDetector *det = NULL; AMCoeffs XLAL_INIT_DECL(AMold); AMCoeffs XLAL_INIT_DECL(AMnew); REAL8 alpha, delta; AMCoeffsParams XLAL_INIT_DECL(amParams); EarthState earth; UINT4 i; REAL8 maxerr_a, maxerr_b, averr_a, averr_b; REAL8 tolerance = 1e-2; /* be generous: allow 1% error */ struct tms buf; const CHAR *sites[] = {"H1", "L1", "V2", "G1", "T1" }; UINT4 pickedSite; char earthEphem[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz"; char sunEphem[] = TEST_DATA_DIR "sun00-19-DE405.dat.gz"; if ( argc == 2 && !strcmp(argv[1], "-v1") ) /* init random-generator */ srand ( times(&buf) ); /* ----- init ephemeris ----- */ edat.ephiles.earthEphemeris = earthEphem; edat.ephiles.sunEphemeris = sunEphem; SUB ( LALInitBarycenter(&status, &edat), &status); /* ----- get timestamps ----- */ SUB ( LALMakeTimestamps ( &status, ×tamps, startTime, duration, Tsft ), &status ); /* ----- allocate memory for AM-coeffs ----- */ AMold.a = XLALCreateREAL4Vector ( timestamps->length ); AMold.b = XLALCreateREAL4Vector ( timestamps->length ); AMnew.a = XLALCreateREAL4Vector ( timestamps->length ); AMnew.b = XLALCreateREAL4Vector ( timestamps->length ); /* ----- pick detector-site at random ----- */ pickedSite = floor( 5 * (1.0 * rand() / (RAND_MAX + 1.0) ) ); /* int in [0,5) */ if ( ( det = XLALGetSiteInfo ( sites[pickedSite] )) == NULL ) { XLALPrintError ("\nCall to XLALGetSiteInfo() has failed for site = '%s'... \n\n", sites[pickedSite]); return GETAMCOEFFSTEST_ESUB; } /* ----- pick skyposition at random ----- */ alpha = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) ); /* uniform in [0, 2pi) */ delta = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX ); /* sin(delta) uniform in [-1,1] */ /* ===== compute AM-coeffs the 'old way': ===== */ baryinput.site.location[0] = det->location[0]/LAL_C_SI; baryinput.site.location[1] = det->location[1]/LAL_C_SI; baryinput.site.location[2] = det->location[2]/LAL_C_SI; baryinput.alpha = alpha; baryinput.delta = delta; baryinput.dInv = 0.e0; /* amParams structure to compute a(t) and b(t) */ amParams.das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource)); amParams.das->pSource = (LALSource *)LALMalloc(sizeof(LALSource)); amParams.baryinput = &baryinput; amParams.earth = &earth; amParams.edat = &edat; amParams.das->pDetector = det; amParams.das->pSource->equatorialCoords.longitude = alpha; amParams.das->pSource->equatorialCoords.latitude = delta; amParams.das->pSource->orientation = 0.0; amParams.das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; amParams.polAngle = 0; SUB (LALComputeAM ( &status, &AMold, timestamps->data, &amParams), &status); /* ===== compute AM-coeffs the 'new way' using LALGetAMCoeffs() */ /* ----- get detector-state series ----- */ SUB ( LALGetDetectorStates (&status, &detStates, timestamps, det, &edat, 0 ), &status ); skypos.system = COORDINATESYSTEM_EQUATORIAL; skypos.longitude = alpha; skypos.latitude = delta; SUB ( LALGetAMCoeffs ( &status, &AMnew, detStates, skypos ), &status ); /* ===== analyse relative error ===== */ maxerr_a = maxerr_b = averr_a = averr_b = 0; for ( i=0; i < timestamps->length; i ++ ) { REAL8 thisErr; thisErr = sqrt( SQ ( AMold.a->data[i] - AMnew.a->data[i] ) / AMold.A ); averr_a += thisErr; maxerr_a = MYMAX( thisErr, maxerr_a ); thisErr = sqrt( SQ ( AMold.b->data[i] - AMnew.b->data[i] ) / AMold.B ); averr_b += thisErr; maxerr_b = MYMAX( thisErr, maxerr_b ); } averr_a /= timestamps->length; averr_b /= timestamps->length; if ( lalDebugLevel ) { printf ("Parameters: IFO = %s, skypos = [%g, %g]\n", sites[pickedSite], alpha, delta ); printf ("Maximal relative errors: maxerr(a) = %g %%, maxerr(b) = %g %% \n", 100.0 * maxerr_a, 100.0 * maxerr_b); printf ("Average relative errors: averr(a) = %g %%, averr(b) = %g %% \n", 100.0 * averr_a, 100.0 * averr_b ); } else printf ("%d %g %g %g %g %g %g \n", pickedSite, alpha, delta, averr_a, averr_b, maxerr_a, maxerr_b); if ( (averr_a > tolerance) || (averr_b > tolerance) || (maxerr_a > tolerance) ||(maxerr_b > tolerance)) { XLALPrintError ("Maximal error-tolerance of %g %% was exceeded!\n", 100.0 * tolerance ); return 1; } /* ----- free memory ----- */ XLALDestroyTimestampVector ( timestamps ); XLALDestroyREAL4Vector ( AMold.a ); XLALDestroyREAL4Vector ( AMold.b ); XLALDestroyREAL4Vector ( AMnew.a ); XLALDestroyREAL4Vector ( AMnew.b ); LALFree ( det ); XLALDestroyDetectorStateSeries ( detStates ); LALFree ( amParams.das->pSource ); LALFree ( amParams.das ); LALFree(edat.ephemE); LALFree(edat.ephemS); LALCheckMemoryLeaks(); return 0; /* OK */ } /* main() */
/** * Handle user-input and check its validity. * Load ephemeris and calculate AM-coefficients (stored globally) */ void Initialize (LALStatus *status, struct CommandLineArgsTag *CLA) { EphemerisData *edat=NULL; /* Stores earth/sun ephemeris data for barycentering */ BarycenterInput baryinput; /* Stores detector location and other barycentering data */ EarthState earth; AMCoeffsParams *amParams; LIGOTimeGPS *midTS=NULL; /* Time stamps for amplitude modulation coefficients */ LALDetector *Detector; /* Our detector*/ INT4 k; INITSTATUS(status); ATTATCHSTATUSPTR (status); if ( XLALUserVarWasSet ( &(CLA->nTsft) ) ) CLA->duration = 1.0 * CLA->nTsft * CLA->Tsft; /* read or generate SFT timestamps */ if ( XLALUserVarWasSet(&(CLA->timestamps)) ) { XLAL_CHECK_LAL ( status, ( timestamps = XLALReadTimestampsFile ( CLA->timestamps ) ) != NULL, XLAL_EFUNC ); if ( (CLA->nTsft > 0) && ( (UINT4)CLA->nTsft < timestamps->length ) ) /* truncate if required */ timestamps->length = CLA->nTsft; CLA->nTsft = timestamps->length; } /* if have_timestamps */ else { LIGOTimeGPS tStart; tStart.gpsSeconds = CLA->gpsStart; tStart.gpsNanoSeconds = 0; XLAL_CHECK_LAL ( status, ( timestamps = XLALMakeTimestamps( tStart, CLA->duration, CLA->Tsft, 0 ) ) != NULL, XLAL_EFUNC ); CLA->nTsft = timestamps->length; } /* no timestamps */ /*---------- initialize detector ---------- */ { BOOLEAN have_IFO = XLALUserVarWasSet ( &CLA->IFO ); BOOLEAN have_detector = XLALUserVarWasSet ( &CLA->detector ); CHAR *IFO; if ( !have_IFO && !have_detector ) { fprintf (stderr, "\nNeed to specify the detector (--IFO) !\n\n"); ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT); } if ( have_IFO ) IFO = CLA->IFO; else IFO = CLA->detector; if ( ( Detector = XLALGetSiteInfo ( IFO ) ) == NULL ) { ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT); } } /* ---------- load ephemeris-files ---------- */ { edat = XLALInitBarycenter( CLA->ephemEarth, CLA->ephemSun ); if ( !edat ) { XLALPrintError("XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", CLA->ephemEarth, CLA->ephemSun); ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT); } } /* ephemeris-reading */ /* ---------- calculate AM-coefficients ---------- */ /* prepare call to barycentering routing */ baryinput.site.location[0] = Detector->location[0]/LAL_C_SI; baryinput.site.location[1] = Detector->location[1]/LAL_C_SI; baryinput.site.location[2] = Detector->location[2]/LAL_C_SI; baryinput.alpha = CLA->Alpha; baryinput.delta = CLA->Delta; baryinput.dInv = 0.e0; /* amParams structure to compute a(t) and b(t) */ /* Allocate space for amParams stucture */ /* Here, amParams->das is the Detector and Source info */ amParams = (AMCoeffsParams *)LALMalloc(sizeof(AMCoeffsParams)); amParams->das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource)); amParams->das->pSource = (LALSource *)LALMalloc(sizeof(LALSource)); /* Fill up AMCoeffsParams structure */ amParams->baryinput = &baryinput; amParams->earth = &earth; amParams->edat = edat; amParams->das->pDetector = Detector; amParams->das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; amParams->das->pSource->equatorialCoords.longitude = CLA->Alpha; amParams->das->pSource->equatorialCoords.latitude = CLA->Delta; amParams->das->pSource->orientation = 0.0; amParams->polAngle = amParams->das->pSource->orientation ; /* These two have to be the same!!!!!!!!!*/ /* Allocate space for AMCoeffs */ XLAL_INIT_MEM(amc); TRY ( LALSCreateVector(status->statusPtr, &(amc.a), (UINT4) CLA->nTsft), status); TRY ( LALSCreateVector(status->statusPtr, &(amc.b), (UINT4) CLA->nTsft), status); /* Mid point of each SFT */ midTS = (LIGOTimeGPS *)LALCalloc(CLA->nTsft,sizeof(LIGOTimeGPS)); for(k=0; k < CLA->nTsft; k++) { /* FIXME: loss of precision; consider midTS[k] = timestamps->data[k]; XLALGPSAdd(&midTS[k], 0.5*CLA->Tsft); */ REAL8 teemp=0.0; teemp = XLALGPSGetREAL8(&(timestamps->data[k])); teemp += 0.5*CLA->Tsft; XLALGPSSetREAL8(&(midTS[k]), teemp); } TRY ( LALComputeAM(status->statusPtr, &amc, midTS, amParams), status); /* Free memory */ XLALDestroyTimestampVector ( timestamps); LALFree(midTS); LALFree(Detector); XLALDestroyEphemerisData(edat); LALFree(amParams->das->pSource); LALFree(amParams->das); LALFree(amParams); DETATCHSTATUSPTR (status); RETURN(status); } /* ParseUserInput() */
int main(int argc, char *argv[]) { const char *fn = __func__; LALStatus status = empty_status; SFTCatalog *catalog = NULL; SFTConstraints constraints = empty_constraints; SFTVector *sft_vect = NULL; SFTVector *sft_vect2 = NULL; MultiSFTVector *multsft_vect = NULL; MultiSFTVector *multsft_vect2 = NULL; CHAR detector[2] = "H1"; INT4 crc_check; /* band to read from infile.* SFTs */ REAL8 fMin = 1008.5; REAL8 fMax = 1009.1; if ( argc == 1) /* avoid warning */ argc = 1; /* check that mal-formated SFTs are properly detected */ SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad1", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad2", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad3", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad4", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad5", NULL ), &status); /* the following (SFT-bad6) has a wrong CRC64 checksum. However, this is * not checked in LALSFTdataFind, so it should succeed! */ SHOULD_WORK( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad6", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad7", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad8", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad9", NULL ), &status); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad10", NULL ), &status ); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad11", NULL ), &status ); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad12", NULL ), &status ); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad13", NULL ), &status ); SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad14", NULL ), &status ); /* now check some crc-checksums */ SHOULD_WORK( LALCheckSFTs ( &status, &crc_check, TEST_DATA_DIR "SFT-test1", NULL ), &status ); if ( crc_check != 0 ) { XLALPrintError ("\nLALCheckSFTs(): SFT-test1 has correct checksum but LALCheckSFTs claimed it hasn't.\n\n"); return crc_check; } SHOULD_WORK( LALCheckSFTs ( &status, &crc_check, TEST_DATA_DIR "SFT-bad6", NULL ), &status ); if ( crc_check != SFTFILEIO_ECRC64 ) { XLALPrintError ( "\nLALCheckSFTs() failed to catch invalid CRC checksum in SFT-bad6 \n\n"); return SFTFILEIOTESTC_ESUB; } /* check that proper v2-SFTs are read-in properly */ SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test1", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test2", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test3", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test4", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test5", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test6", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test7", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); /* now completely read-in a v2 merged-SFT */ SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test*", NULL ), &status ); /* skip sft nr 4 with has Tsft=50 instead of Tsft=60 */ SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test[123567]*", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); /* try the same with a ";" separated list of files and of patterns */ SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test1;" TEST_DATA_DIR "SFT-test2;" TEST_DATA_DIR "SFT-test3;" TEST_DATA_DIR "SFT-test5;" TEST_DATA_DIR "SFT-test6;" TEST_DATA_DIR "SFT-test7", NULL ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test[123]*;" TEST_DATA_DIR "SFT-test[5]*", NULL ), &status ); /* load once as a single SFT-vector (mix of detectors) */ SHOULD_WORK ( LALLoadSFTs ( &status, &sft_vect, catalog, -1, -1 ), &status ); /* load once as a multi-SFT vector */ SHOULD_WORK ( LALLoadMultiSFTs ( &status, &multsft_vect, catalog, -1, -1 ), &status ); /* load again, using XLAL API */ if ( ( multsft_vect2 = XLALLoadMultiSFTs ( catalog, -1, -1 )) == NULL ) { XLALPrintError ("%s: XLALLoadMultiSFTs (cat, -1, -1) failed with xlalErrno = %d\n", fn, xlalErrno ); return SFTFILEIOTESTC_ESUB; } SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); /* 6 SFTs from 2 IFOs should have been read */ if ( (sft_vect->length != 4) /* either as a single SFTVector */ || (multsft_vect->length != 2) /* or separated by detector */ || (multsft_vect->data[0]->length != 3) || ( multsft_vect->data[1]->length != 1 ) ) { XLALPrintError ( "\nFailed to read in multi-SFT from 2 IFOs 'SFT-test*'!\n\n"); return SFTFILEIOTESTC_ESUB; } /* compare results from LALLoadMultiSFTs() and XLALLoadMultiSFTs() */ { UINT4 numIFOs = multsft_vect->length; UINT4 X; for ( X=0; X < numIFOs; X ++ ) { if( CompareSFTVectors ( multsft_vect->data[X], multsft_vect2->data[X] ) ) { XLALPrintError ("%s: comparing (X)LALLoadMultiSFTs(): sft-vectors differ for X=%d\n", fn, X ); return SFTFILEIOTESTC_ESUB; } } /* for X < numIFOs */ } /* ------ */ /* ----- v2 SFT writing ----- */ /* write v2-SFT to disk */ SHOULD_WORK ( LALWriteSFT2file( &status, &(multsft_vect->data[0]->data[0]), "outputsftv2_v2.sft", "A v2-SFT file for testing!"), &status ); SHOULD_WORK ( LALWriteSFTVector2Dir( &status, multsft_vect->data[0], ".", "A v2-SFT file for testing!", "test"), &status); /* write v2-SFT to single file */ { const CHAR *currSingleSFT = NULL; UINT4 i = 0; FILE *fpConcat = NULL, *fpSingle = NULL; int concat = 0, single = 0; xlalErrno = 0; if (XLAL_SUCCESS != XLALWriteSFTVector2File ( multsft_vect->data[0], ".", "A v2-SFT file for testing!", "test_concat" )) { LALPrintError ( "\n XLALWriteSFTVector2File failed to write multi-SFT vector to file!\n\n"); return SFTFILEIOTESTC_ESUB; } /* check that the single file SFT is the same as the single SFTs */ const UINT4 numSingleSFTs = 3; const CHAR *singleSFTs[] = { "H-1_H1_60SFT_test-000012345-61.sft", "H-1_H1_60SFT_test-000012465-61.sft", "H-1_H1_60SFT_test-000012585-61.sft" }; printf("*** Comparing single and concatenated SFTs ***\n"); /* try to open concatenated SFT */ const CHAR *concatSFT = "H-3_H1_60SFT_test_concat-000012345-302.sft"; if ( ( fpConcat = fopen(concatSFT, "rb" ) ) == NULL ) { LALPrintError ( "\n Cound not open SFT '%s'!\n\n", concatSFT); return SFTFILEIOTESTC_ESUB; } /* do loop while concat. SFT has data */ while (!feof(fpConcat)) { /* get character from concat. SFT */ concat = fgetc(fpConcat); if ( ferror(fpConcat) ) { LALPrintError ( "\n IO error reading '%s'!\n\n", concatSFT); return SFTFILEIOTESTC_ESUB; } /* get character from single SFT */ while (1) { /* need to open next single SFT file */ if (fpSingle == NULL) { /* break if we've run out of single SFTs */ if (i == numSingleSFTs) break; /* try to open single SFT */ if ( ( fpSingle = fopen(singleSFTs[i], "rb" ) ) == NULL ) { LALPrintError ( "\n Cound not open SFT '%s'!\n\n", singleSFTs[i]); return SFTFILEIOTESTC_ESUB; } currSingleSFT = singleSFTs[i]; } /* get character from single SFT */ single = fgetc(fpSingle); if ( ferror(fpSingle) ) { LALPrintError ( "\n IO error reading '%s'!\n\n", singleSFTs[i]); return SFTFILEIOTESTC_ESUB; } /* if single SFT is out of data, close it (open next one at beginning of loop) */ if (feof(fpSingle)) { fclose(fpSingle); fpSingle = NULL; ++i; } /* otherwise we have a valid character */ else break; } /* do character-by-character comparison */ if ( concat != single ) { LALPrintError ( "\n Comparison failed between '%s'(last char = %i) and '%s'(last char = %i)!!\n\n", concatSFT, concat, currSingleSFT, single ); return SFTFILEIOTESTC_ESFTDIFF; } } fclose(fpConcat); printf( "*** Comparing was successful!!! ***\n"); } /* write v2-SFt as a v1-SFT to disk (correct normalization) */ multsft_vect->data[0]->data[0].epoch.gpsSeconds += 60; /* shift start-time so they don't look like segmented SFTs! */ SHOULD_WORK ( LALWrite_v2SFT_to_v1file( &status, &(multsft_vect->data[0]->data[0]), "outputsftv2_v1.sft"), &status ); SUB ( LALDestroySFTVector ( &status, &sft_vect ), &status ); SUB ( LALDestroyMultiSFTVector (&status, &multsft_vect ), &status ); SUB ( LALDestroyMultiSFTVector (&status, &multsft_vect2 ), &status ); /* ----- read the previous two SFTs back */ SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, "outputsftv2_*.sft", NULL ), &status ); /* need to set proper detector! */ constraints.detector = detector; SUB ( LALSFTdataFind ( &status, &catalog, "outputsftv2_*.sft", &constraints ), &status); SUB ( LALLoadSFTs ( &status, &sft_vect, catalog, -1, -1 ), &status ); if ( sft_vect->length != 2 ) { if ( lalDebugLevel ) XLALPrintError ("\nFailed to read back in 'outputsftv2_*.sft'\n\n"); return SFTFILEIOTESTC_ESUB; } sft_vect2 = XLALLoadSFTs ( catalog, -1, -1 ); if (!sft_vect2) { XLALPrintError ( "\nXLALLoadSFTs() call failed (where it should have succeeded)!\n\n"); return SFTFILEIOTESTC_ESUB; } /* compare the SFT vectors just read */ if(CompareSFTVectors(sft_vect, sft_vect2)) return SFTFILEIOTESTC_ESUB; /* the data of 'outputsftv2_v2.sft' and 'outputsftv2_v1.sft' should agree, as the normalization * should be corrected again when reading-in */ { UINT4 i; UINT4 numBins = sft_vect->data[0].data->length; for ( i=0; i < numBins; i++) { COMPLEX8 *data1 = &(sft_vect->data[0].data->data[i]); COMPLEX8 *data2 = &(sft_vect->data[1].data->data[i]); if ( (crealf(*data1) != crealf(*data2)) || (cimagf(*data1) != cimagf(*data2)) ) { XLALPrintError ("\nv1- and v2- SFT differ after writing/reading\n\n"); return SFTFILEIOTESTC_ESFTDIFF; } } /* for i < numBins */ } SUB ( LALDestroySFTVector (&status, &sft_vect2 ), &status ); SUB ( LALDestroySFTVector (&status, &sft_vect ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); /* `----- v1 SFT writing */ /* read v1-SFTs: 'inputsft.0' and 'inputsft.1' (one is big-endian, the other little-endian!) */ SUB ( LALSFTdataFind (&status, &catalog, TEST_DATA_DIR "inputsft.?", &constraints ), &status ); SUB ( LALLoadSFTs ( &status, &sft_vect, catalog, fMin, fMax ), &status ); if ( sft_vect->length != 2 ) { if ( lalDebugLevel ) XLALPrintError ("\nFailed to read in v1-SFTs 'inputsft.0' and 'inputsft.1'\n\n"); return SFTFILEIOTESTC_ESUB; } /* read with XLALLoadSFTs() */ sft_vect2 = XLALLoadSFTs ( catalog, fMin, fMax ); if (!sft_vect2) { XLALPrintError ( "\nXLALLoadSFTs() call failed (where it should have succeeded)!\n\n"); return SFTFILEIOTESTC_ESUB; } /* compare the SFT vectors just read */ if(CompareSFTVectors(sft_vect, sft_vect2)) return SFTFILEIOTESTC_ESUB; /* write v1-SFT to disk */ SUB ( LALWriteSFTfile (&status, &(sft_vect->data[0]), "outputsft_v1.sft"), &status); /* try to write this v1-SFTs as v2: should fail without detector-info ! */ strncpy( sft_vect->data[0].name, "??", 2 ); SHOULD_FAIL (LALWriteSFT2file( &status, &(sft_vect->data[0]), "outputsft_v2.sft", "Another v2-SFT file for testing!"), &status ); /* put detector there */ strcpy ( sft_vect->data[0].name, "H1" ); SHOULD_WORK (LALWriteSFT2file( &status, &(sft_vect->data[0]), "outputsft_v2.sft", "Another v2-SFT file for testing!"), &status ); SUB ( LALDestroySFTVector (&status, &sft_vect2 ), &status ); SUB ( LALDestroySFTVector (&status, &sft_vect ), &status ); SUB ( LALDestroySFTCatalog( &status, &catalog), &status ); /* ---------- test timestamps-reading functions by comparing LAL- and XLAL-versions against each other ---------- */ { #define TS_FNAME "testTimestamps.dat" LIGOTimeGPSVector *ts1 = NULL, *ts2 = NULL; /* ----- load timestamps with deprecated LAL function */ SUB ( LALReadTimestampsFile ( &status, &ts1, TEST_DATA_DIR TS_FNAME ), &status ); /* ----- load timestamps w new XLAL function */ if ( (ts2 = XLALReadTimestampsFile ( TEST_DATA_DIR TS_FNAME )) == NULL ) { XLALPrintError ("XLALReadTimestampsFile() failed to read timestamps from file '%s'. xlalErrno = %d\n", TS_FNAME ); return SFTFILEIOTESTC_ESUB; } /* ----- compare the two */ if ( ts1->length != ts2->length ) { XLALPrintError ("Read timestamps-lists differ in length %d != %d\n", ts1->length, ts2->length ); return 1; } if ( ts1->deltaT != ts2->deltaT ) { XLALPrintError ("Read timestamps-lists differ in deltaT %g != %g\n", ts1->deltaT, ts2->deltaT ); return 1; } UINT4 i, numTS = ts1->length; for ( i = 0; i < numTS; i ++ ) { if ( XLALGPSDiff( &ts1->data[i], &ts2->data[i]) != 0 ) { XLALPrintError ("Read timestamps-lists differ in entry %d: { %d, %d } != { %d, %d }\n", i + 1, ts1->data[i].gpsSeconds, ts1->data[i].gpsNanoSeconds, ts2->data[i].gpsSeconds, ts2->data[i].gpsNanoSeconds ); return 1; } } /* for i < numTS */ /* free mem */ XLALDestroyTimestampVector ( ts1 ); XLALDestroyTimestampVector ( ts2 ); } /* ------------------------------ */ LALCheckMemoryLeaks(); XLALPrintError ("\n\n--------------------------------------------------------------------------------\n"); XLALPrintError ("\n OK. All tests passed correctly ! (error-messages above are OK!)\n"); XLALPrintError ("\n--------------------------------------------------------------------------------\n"); INFO( SFTFILEIOTESTC_MSGENORM ); return SFTFILEIOTESTC_ENORM; }
/** * Simulate a pulsar signal to best accuracy possible. * \author Reinhard Prix * \date 2005 * * The motivation for this function is to provide functions to * simulate pulsar signals <em>with the best possible accuracy</em>, * i.e. using no approximations, contrary to LALGeneratePulsarSignal(). * * Obviously this is not meant as a fast code to be used in a Monte-Carlo * simulation, but rather as a <em>reference</em> to compare other (faster) * functions agains, in order to be able to gauge the quality of a given * signal-generation routine. * * We want to calculate \f$h(t)\f$, given by * \f[ * h(t) = F_+(t)\, h_+(t) + F_\times(t) \,h_\times(t)\,, * \f] * where \f$F_+\f$ and \f$F_x\f$ are called the <em>beam-pattern</em> functions, * which depend of the wave polarization \f$\psi\f$, * the source position \f$\alpha\f$, \f$\delta\f$ and the detector position and * orientation (\f$\gamma\f$, \f$\lambda\f$, \f$L\f$ and \f$\xi\f$). The expressions for * the beam-pattern functions are given in \cite JKS98 , which we write as * \f{eqnarray}{ * F_+(t) = \sin \zeta \cos 2\psi \, a(t) + \sin \zeta \sin 2\psi \, b(t)\,,\\ * F_\times(t) = \sin\zeta \cos 2\psi \,b(t) - \sin\zeta \sin 2\psi \, a(t) \,, * \f} * where \f$\zeta\f$ is the angle between the interferometer arms, and * \f{eqnarray}{ * a(t) &=& a_1 \cos[ 2 (\alpha - T)) ] + a_2 \sin[ 2(\alpha - T)] * + a_3 \cos[ \alpha - T ] + a_4 \sin [ \alpha - T ] + a_5\,,\\ * b(t) &=& b_1 \cos[ 2(\alpha - T)] + b_2 \sin[ 2(\alpha - T) ] * + b_3 \cos[ \alpha - T ] + b_4 \sin[ \alpha - T]\,, * \f} * where \f$T\f$ is the local (mean) sidereal time of the detector, and the * time-independent coefficients \f$a_i\f$ and \f$b_i\f$ are given by * \f{eqnarray}{ * a_1 &=& \frac{1}{16} \sin 2\gamma \,(3- \cos 2\lambda)\,(3 - \cos 2\delta)\,,\\ * a_2 &=& -\frac{1}{4}\cos 2\gamma \,\sin \lambda \,(3 - \cos 2\delta) \,,\\ * a_3 &=& \frac{1}{4} \sin 2\gamma \,\sin 2\lambda \,\sin 2\delta \,\\ * a_4 &=& -\frac{1}{2} \cos 2\gamma \,\cos \lambda \,\sin 2 \delta\,,\\ * a_5 &=& \frac{3}{4} \sin 2\gamma \, \cos^2 \lambda \,\cos^2 \delta\,, * \f} * and * \f{eqnarray}{ * b_1 &=& \cos 2\gamma \,\sin \lambda \,\sin \delta\,,\\ * b_2 &=& \frac{1}{4} \sin 2\gamma \,(3-\cos 2\lambda)\, \sin \delta\,,\\ * b_3 &=& \cos 2\gamma \,\cos \lambda \,\cos\delta \,, \\ * b_4 &=& \frac{1}{2} \sin2\gamma \,\sin 2\lambda \,\cos\delta\,, * \f} * * The source model considered is a plane-wave * \f{eqnarray}{ * h_+(t) &=& A_+\, \cos \Psi(t)\,,\\ * h_\times(t) &=& A_\times \, \sin \Psi(t)\,, * \f} * where the wave-phase is \f$\Psi(t) = \Phi_0 + \Phi(t)\f$, and for an * isolated pulsar we have * \f{equation}{ * \Phi(t) = 2\pi \left[\sum_{s=0} \frac{f^{(s)}(\tau_\mathrm{ref})}{ * (s+1)!} \left( \tau(t) - \tau_\mathrm{ref} \right)^{s+1} \right]\,, * \f} * where \f$\tau_\mathrm{ref}\f$ is the "reference time" for the definition * of the pulsar-parameters \f$f^{(s)}\f$ in the solar-system barycenter * (SSB), and \f$\tau(t)\f$ is the SSB-time of the phase arriving at the * detector at UTC-time \f$t\f$, which depends on the source-position * (\f$\alpha\f$, \f$\delta\f$) and the detector-position, namely * \f{equation}{ * \tau (t) = t + \frac{ \vec{r}(t)\cdot\vec{n}}{c}\,, * \f} * where \f$\vec{r}(t)\f$ is the vector from SSB to the detector, and \f$\vec{n}\f$ * is the unit-vector pointing <em>to</em> the source. * * This is a standalone "clean-room" implementation using no other * outside-functions <em>except</em> for LALGPStoLMST1() to calculate * the local (mean) sidereal time at the detector for given GPS-time, * (which I double-checked with an independent Mathematica script), * and and XLALBarycenter() to calculate \f$\tau(t)\f$. * * NOTE: currently only isolated pulsars are supported * * NOTE2: we don't really use the highest possible accuracy right now, * as we blatently neglect all relativistic timing effects (i.e. using dT=v.n/c) * * NOTE3: no heterodyning is performed here, the time-series is generated and sampled * at the given rate, that's all! ==\> the caller needs to make sure about the * right sampling rate to use (-\>aliasing) and do the proper post-treatment... * */ REAL4TimeSeries * XLALSimulateExactPulsarSignal ( const PulsarSignalParams *params ) { XLAL_CHECK_NULL ( params != NULL, XLAL_EINVAL, "Invalid NULL input 'params'\n"); XLAL_CHECK_NULL ( params->samplingRate > 0, XLAL_EDOM, "Sampling rate must be positive, got samplingRate = %g\n", params->samplingRate ); /* don't accept heterodyning frequency */ XLAL_CHECK_NULL ( params->fHeterodyne == 0, XLAL_EINVAL, "Heterodyning frequency must be set to 0, got params->fHeterodyne = %g\n", params->fHeterodyne ); UINT4 numSpins = 3; /* get timestamps of timeseries plus detector-states */ REAL8 dt = 1.0 / params->samplingRate; LIGOTimeGPSVector *timestamps; XLAL_CHECK_NULL ( (timestamps = XLALMakeTimestamps ( params->startTimeGPS, params->duration, dt, 0 )) != NULL, XLAL_EFUNC ); UINT4 numSteps = timestamps->length; DetectorStateSeries *detStates = XLALGetDetectorStates ( timestamps, params->site, params->ephemerides, 0 ); XLAL_CHECK_NULL ( detStates != NULL, XLAL_EFUNC, "XLALGetDetectorStates() failed.\n"); XLALDestroyTimestampVector ( timestamps ); timestamps = NULL; AMCoeffs *amcoe = XLALComputeAMCoeffs ( detStates, params->pulsar.position ); XLAL_CHECK_NULL ( amcoe != NULL, XLAL_EFUNC, "XLALComputeAMCoeffs() failed.\n"); /* create output timeseries (FIXME: should really know *detector* here, not just site!!) */ const LALFrDetector *site = &(params->site->frDetector); CHAR *channel = XLALGetChannelPrefix ( site->name ); XLAL_CHECK_NULL ( channel != NULL, XLAL_EFUNC, "XLALGetChannelPrefix( %s ) failed.\n", site->name ); REAL4TimeSeries *ts = XLALCreateREAL4TimeSeries ( channel, &(detStates->data[0].tGPS), 0, dt, &emptyUnit, numSteps ); XLAL_CHECK_NULL ( ts != NULL, XLAL_EFUNC, "XLALCreateREAL4TimeSeries() failed.\n"); XLALFree ( channel ); channel = NULL; /* orientation of detector arms */ REAL8 xAzi = site->xArmAzimuthRadians; REAL8 yAzi = site->yArmAzimuthRadians; REAL8 Zeta = xAzi - yAzi; if (Zeta < 0) { Zeta = -Zeta; } if ( params->site->type == LALDETECTORTYPE_CYLBAR ) { Zeta = LAL_PI_2; } REAL8 sinZeta = sin(Zeta); /* get source skyposition */ REAL8 Alpha = params->pulsar.position.longitude; REAL8 Delta = params->pulsar.position.latitude; REAL8 vn[3]; vn[0] = cos(Delta) * cos(Alpha); vn[1] = cos(Delta) * sin(Alpha); vn[2] = sin(Delta); /* get spin-parameters (restricted to maximally 3 spindowns right now) */ REAL8 phi0 = params->pulsar.phi0; REAL8 f0 = params->pulsar.f0; REAL8 f1dot = 0, f2dot = 0, f3dot = 0; if ( params->pulsar.spindown && (params->pulsar.spindown->length > numSpins) ) { XLAL_ERROR_NULL ( XLAL_EDOM, "Currently only supports up to %d spindowns!\n", numSpins ); } if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 3 ) ) { f3dot = params->pulsar.spindown->data[2]; } if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 2 ) ) { f2dot = params->pulsar.spindown->data[1]; } if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 1 ) ) { f1dot = params->pulsar.spindown->data[0]; } /* internally we always work with refTime = startTime->SSB, therefore * we need to translate the pulsar spin-params and initial phase to the * startTime */ REAL8 startTimeSSB = XLALGPSGetREAL8 ( &(detStates->data[0].tGPS) ) + SCALAR ( vn, detStates->data[0].rDetector ); REAL8 refTime; if ( params->pulsar.refTime.gpsSeconds != 0 ) { REAL8 refTime0 = XLALGPSGetREAL8 ( &(params->pulsar.refTime) ); REAL8 deltaRef = startTimeSSB - refTime0; LIGOTimeGPS newEpoch; PulsarSpins fkdotNew; XLALGPSSetREAL8( &newEpoch, startTimeSSB ); PulsarSpins XLAL_INIT_DECL(fkdotOld); fkdotOld[0] = f0; fkdotOld[1] = f1dot; fkdotOld[2] = f2dot; fkdotOld[3] = f3dot; REAL8 DeltaTau = XLALGPSDiff ( &newEpoch, &(params->pulsar.refTime) ); int ret = XLALExtrapolatePulsarSpins ( fkdotNew, fkdotOld, DeltaTau ); XLAL_CHECK_NULL ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALExtrapolatePulsarSpins() failed.\n"); /* Finally, need to propagate phase */ phi0 += LAL_TWOPI * ( f0 * deltaRef + (1.0/2.0) * f1dot * deltaRef * deltaRef + (1.0/6.0) * f2dot * deltaRef * deltaRef * deltaRef + (1.0/24.0)* f3dot * deltaRef * deltaRef * deltaRef * deltaRef ); f0 = fkdotNew[0]; f1dot = fkdotNew[1]; f2dot = fkdotNew[2]; f3dot = fkdotNew[3]; refTime = startTimeSSB; } /* if refTime given */ else { /* if not given: use startTime -> SSB */ refTime = startTimeSSB; } /* get 4 amplitudes A_\mu */ REAL8 aPlus = sinZeta * params->pulsar.aPlus; REAL8 aCross = sinZeta * params->pulsar.aCross; REAL8 twopsi = 2.0 * params->pulsar.psi; REAL8 A1 = aPlus * cos(phi0) * cos(twopsi) - aCross * sin(phi0) * sin(twopsi); REAL8 A2 = aPlus * cos(phi0) * sin(twopsi) + aCross * sin(phi0) * cos(twopsi); REAL8 A3 = -aPlus * sin(phi0) * cos(twopsi) - aCross * cos(phi0) * sin(twopsi); REAL8 A4 = -aPlus * sin(phi0) * sin(twopsi) + aCross * cos(phi0) * cos(twopsi); /* main loop: generate time-series */ for ( UINT4 i = 0; i < numSteps; i++) { LIGOTimeGPS *tiGPS = &(detStates->data[i].tGPS); REAL8 ti = XLALGPSGetREAL8 ( tiGPS ); REAL8 deltati = ti - refTime; REAL8 dT = SCALAR(vn, detStates->data[i].rDetector ); REAL8 taui = deltati + dT; REAL8 phi_i = LAL_TWOPI * ( f0 * taui + (1.0/2.0) * f1dot * taui*taui + (1.0/6.0) * f2dot * taui*taui*taui + (1.0/24.0)* f3dot * taui*taui*taui*taui ); REAL8 cosphi_i = cos(phi_i); REAL8 sinphi_i = sin(phi_i); REAL8 ai = amcoe->a->data[i]; REAL8 bi = amcoe->b->data[i]; REAL8 hi = A1 * ai * cosphi_i + A2 * bi * cosphi_i + A3 * ai * sinphi_i + A4 * bi * sinphi_i; ts->data->data[i] = (REAL4)hi; } /* for i < numSteps */ XLALDestroyDetectorStateSeries( detStates ); XLALDestroyAMCoeffs ( amcoe ); return ts; } /* XLALSimulateExactPulsarSignal() */