/** * Multi-IFO version of XLALComputeAMCoeffs(). * Computes noise-weighted combined multi-IFO antenna pattern functions. * * \note *) contrary to LALGetMultiAMCoeffs(), and XLALComputeAMCoeffs(), this function applies * the noise-weights and computes the multi-IFO antenna-pattern matrix components * {A, B, C}, and single-IFO matrix components {A_X,B_X,C_X} for detector X. * * Therefore: DONT use XLALWeightMultiAMCoeffs() on the result! * * \note *) an input of multiWeights = NULL corresponds to unit-weights */ MultiAMCoeffs * XLALComputeMultiAMCoeffs ( const MultiDetectorStateSeries *multiDetStates, /**< [in] detector-states at timestamps t_i */ const MultiNoiseWeights *multiWeights, /**< [in] noise-weigths at timestamps t_i (can be NULL) */ SkyPosition skypos /**< source sky-position [in equatorial coords!] */ ) { /* check input consistency */ if ( !multiDetStates ) { XLALPrintError ("%s: invalid NULL input argument 'multiDetStates'\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } UINT4 numDetectors = multiDetStates->length; /* prepare output vector */ MultiAMCoeffs *ret; if ( ( ret = XLALCalloc( 1, sizeof( *ret ) )) == NULL ) { XLALPrintError ("%s: failed to XLALCalloc( 1, %d)\n", __func__, sizeof( *ret ) ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } ret->length = numDetectors; if ( ( ret->data = XLALCalloc ( numDetectors, sizeof ( *ret->data ) )) == NULL ) { XLALPrintError ("%s: failed to XLALCalloc(%d, %d)\n", __func__, numDetectors, sizeof ( *ret->data ) ); XLALFree ( ret ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } /* loop over detectors and generate AMCoeffs for each one */ UINT4 X; for ( X=0; X < numDetectors; X ++ ) { if ( (ret->data[X] = XLALComputeAMCoeffs ( multiDetStates->data[X], skypos )) == NULL ) { XLALPrintError ("%s: call to XLALComputeAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLALDestroyMultiAMCoeffs ( ret ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } } /* for X < numDetectors */ /* apply noise-weights and compute antenna-pattern matrix {A,B,C} */ if ( XLALWeightMultiAMCoeffs ( ret, multiWeights ) != XLAL_SUCCESS ) { XLALPrintError ("%s: call to XLALWeightMultiAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLALDestroyMultiAMCoeffs ( ret ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* return result */ return ret; } /* XLALComputeMultiAMCoeffs() */
/** Initialized Fstat-code: handle user-input and set everything up. */ void InitPFS ( LALStatus *status, ConfigVariables *cfg, const UserInput_t *uvar ) { static const char *fn = "InitPFS()"; SFTCatalog *catalog = NULL; SFTConstraints constraints = empty_SFTConstraints; SkyPosition skypos; LIGOTimeGPS startTime, endTime; REAL8 duration, Tsft; LIGOTimeGPS minStartTimeGPS, maxEndTimeGPS; EphemerisData *edat = NULL; /* ephemeris data */ MultiAMCoeffs *multiAMcoef = NULL; MultiPSDVector *multiRngmed = NULL; MultiNoiseWeights *multiNoiseWeights = NULL; MultiSFTVector *multiSFTs = NULL; /* multi-IFO SFT-vectors */ MultiDetectorStateSeries *multiDetStates = NULL; /* pos, vel and LMSTs for detector at times t_i */ UINT4 X, i; INITSTATUS(status); ATTATCHSTATUSPTR (status); { /* Check user-input consistency */ BOOLEAN have_h0, have_cosi, have_cosiota, have_Ap, have_Ac; REAL8 cosi = 0; have_h0 = LALUserVarWasSet ( &uvar->h0 ); have_cosi = LALUserVarWasSet ( &uvar->cosi ); have_cosiota = LALUserVarWasSet ( &uvar->cosiota ); have_Ap = LALUserVarWasSet ( &uvar->aPlus ); have_Ac = LALUserVarWasSet ( &uvar->aCross ); /* ----- handle cosi/cosiota ambiguity */ if ( (have_cosi && have_cosiota) ) { LogPrintf (LOG_CRITICAL, "Need EITHER --cosi [preferred] OR --cosiota [deprecated]!\n"); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT ); } if ( have_cosiota ) { cosi = uvar->cosiota; have_cosi = TRUE; } else if ( have_cosi ) { cosi = uvar->cosi; have_cosi = TRUE; } /* ----- handle {h0,cosi} || {aPlus,aCross} freedom ----- */ if ( ( have_h0 && !have_cosi ) || ( !have_h0 && have_cosi ) ) { LogPrintf (LOG_CRITICAL, "Need both (h0, cosi) to specify signal!\n"); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT ); } if ( ( have_Ap && !have_Ac) || ( !have_Ap && have_Ac ) ) { LogPrintf (LOG_CRITICAL, "Need both (aPlus, aCross) to specify signal!\n"); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT ); } if ( have_h0 && have_Ap ) { LogPrintf (LOG_CRITICAL, "Overdetermined: specify EITHER (h0,cosi) OR (aPlus,aCross)!\n"); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT ); } /* ----- internally we always use Aplus, Across */ if ( have_h0 ) { cfg->aPlus = 0.5 * uvar->h0 * ( 1.0 + SQ( cosi) ); cfg->aCross = uvar->h0 * uvar->cosi; } else { cfg->aPlus = uvar->aPlus; cfg->aCross = uvar->aCross; } }/* check user-input */ /* ----- prepare SFT-reading ----- */ if ( LALUserVarWasSet ( &uvar->IFO ) ) if ( (constraints.detector = XLALGetChannelPrefix ( uvar->IFO )) == NULL ) { ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT); } minStartTimeGPS.gpsSeconds = uvar->minStartTime; minStartTimeGPS.gpsNanoSeconds = 0; maxEndTimeGPS.gpsSeconds = uvar->maxEndTime; maxEndTimeGPS.gpsNanoSeconds = 0; constraints.minStartTime = &minStartTimeGPS; constraints.maxEndTime = &maxEndTimeGPS; /* ----- get full SFT-catalog of all matching (multi-IFO) SFTs */ LogPrintf (LOG_DEBUG, "Finding all SFTs to load ... "); TRY ( LALSFTdataFind ( status->statusPtr, &catalog, uvar->DataFiles, &constraints ), status); LogPrintfVerbatim (LOG_DEBUG, "done. (found %d SFTs)\n", catalog->length); if ( constraints.detector ) LALFree ( constraints.detector ); if ( catalog->length == 0 ) { LogPrintf (LOG_CRITICAL, "No matching SFTs for pattern '%s'!\n", uvar->DataFiles ); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT); } /* ----- deduce start- and end-time of the observation spanned by the data */ { GV.numSFTs = catalog->length; /* total number of SFTs */ Tsft = 1.0 / catalog->data[0].header.deltaF; startTime = catalog->data[0].header.epoch; endTime = catalog->data[GV.numSFTs-1].header.epoch; XLALGPSAdd(&endTime, Tsft); duration = GPS2REAL8(endTime) - GPS2REAL8 (startTime); } { /* ----- load ephemeris-data ----- */ edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun ); if ( !edat ) { XLALPrintError("XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", uvar->ephemEarth, uvar->ephemSun); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT); } } {/* ----- load the multi-IFO SFT-vectors ----- */ UINT4 wings = uvar->RngMedWindow/2 + 10; /* extra frequency-bins needed for rngmed */ REAL8 fMax = uvar->Freq + 1.0 * wings / Tsft; REAL8 fMin = uvar->Freq - 1.0 * wings / Tsft; LogPrintf (LOG_DEBUG, "Loading SFTs ... "); TRY ( LALLoadMultiSFTs ( status->statusPtr, &multiSFTs, catalog, fMin, fMax ), status ); LogPrintfVerbatim (LOG_DEBUG, "done.\n"); TRY ( LALDestroySFTCatalog ( status->statusPtr, &catalog ), status ); } TRY ( LALNormalizeMultiSFTVect (status->statusPtr, &multiRngmed, multiSFTs, uvar->RngMedWindow ), status); TRY ( LALComputeMultiNoiseWeights (status->statusPtr, &multiNoiseWeights, multiRngmed, uvar->RngMedWindow, 0 ), status ); /* correctly handle the --SignalOnly case: * set noise-weights to 1, and * set Sh->1 (single-sided) */ if ( uvar->SignalOnly ) { multiNoiseWeights->Sinv_Tsft = Tsft; for ( X=0; X < multiNoiseWeights->length; X ++ ) for ( i=0; i < multiNoiseWeights->data[X]->length; i ++ ) multiNoiseWeights->data[X]->data[i] = 1.0; } /* ----- handle transient-signal window if given ----- */ if ( LALUserVarWasSet ( &uvar->transientWindowType ) && strcmp ( uvar->transientWindowType, "none") ) { transientWindow_t transientWindow; /**< properties of transient-signal window */ MultiLIGOTimeGPSVector *mTS; if ( !strcmp ( uvar->transientWindowType, "rect" ) ) transientWindow.type = TRANSIENT_RECTANGULAR; /* rectangular window [t0, t0+tau] */ else if ( !strcmp ( uvar->transientWindowType, "exp" ) ) transientWindow.type = TRANSIENT_EXPONENTIAL; /* exponential decay window e^[-(t-t0)/tau for t>t0, 0 otherwise */ else { XLALPrintError ("Illegal transient window '%s' specified: valid are 'none', 'rect' or 'exp'\n", uvar->transientWindowType); ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT ); } if ( LALUserVarWasSet ( &uvar->transientStartTime ) ) transientWindow.t0 = uvar->transientStartTime; else transientWindow.t0 = XLALGPSGetREAL8( &startTime ); /* if not set, default window startTime == startTime here */ transientWindow.tau = uvar->transientTauDays; if ( (mTS = XLALExtractMultiTimestampsFromSFTs ( multiSFTs )) == NULL ) { XLALPrintError ("%s: failed to XLALExtractMultiTimestampsFromSFTs() from SFTs. xlalErrno = %d.\n", fn, xlalErrno ); ABORT ( status, PREDICTFSTAT_EXLAL, PREDICTFSTAT_MSGEXLAL ); } if ( XLALApplyTransientWindow2NoiseWeights ( multiNoiseWeights, mTS, transientWindow ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALApplyTransientWindow2NoiseWeights() failed! xlalErrno = %d\n", fn, xlalErrno ); ABORT ( status, PREDICTFSTAT_EXLAL, PREDICTFSTAT_MSGEXLAL ); } XLALDestroyMultiTimestamps ( mTS ); } /* apply transient window to noise-weights */ /* ----- obtain the (multi-IFO) 'detector-state series' for all SFTs ----- */ TRY (LALGetMultiDetectorStates( status->statusPtr, &multiDetStates, multiSFTs, edat), status ); /* normalize skyposition: correctly map into [0,2pi]x[-pi/2,pi/2] */ skypos.longitude = uvar->Alpha; skypos.latitude = uvar->Delta; skypos.system = COORDINATESYSTEM_EQUATORIAL; TRY (LALNormalizeSkyPosition ( status->statusPtr, &skypos, &skypos), status); TRY ( LALGetMultiAMCoeffs ( status->statusPtr, &multiAMcoef, multiDetStates, skypos ), status); /* noise-weighting of Antenna-patterns and compute A,B,C */ if ( XLALWeightMultiAMCoeffs ( multiAMcoef, multiNoiseWeights ) != XLAL_SUCCESS ) { LogPrintf (LOG_CRITICAL, "XLALWeightMultiAMCoeffs() failed with error = %d\n\n", xlalErrno ); ABORT ( status, PREDICTFSTAT_EXLAL, PREDICTFSTAT_MSGEXLAL ); } /* OK: we only need the antenna-pattern matrix M_mu_nu */ cfg->Mmunu = multiAMcoef->Mmunu; /* ----- produce a log-string describing the data-specific setup ----- */ { struct tm utc; time_t tp; CHAR dateStr[512], line[512], summary[1024]; UINT4 j, numDet; numDet = multiSFTs->length; tp = time(NULL); sprintf (summary, "%%%% Date: %s", asctime( gmtime( &tp ) ) ); strcat (summary, "%% Loaded SFTs: [ " ); for ( j=0; j < numDet; j ++ ) { sprintf (line, "%s:%d%s", multiSFTs->data[j]->data->name, multiSFTs->data[j]->length, (j < numDet - 1)?", ":" ]\n"); strcat ( summary, line ); } utc = *XLALGPSToUTC( &utc, (INT4)GPS2REAL8(startTime) ); strcpy ( dateStr, asctime(&utc) ); dateStr[ strlen(dateStr) - 1 ] = 0; sprintf (line, "%%%% Start GPS time tStart = %12.3f (%s GMT)\n", GPS2REAL8(startTime), dateStr); strcat ( summary, line ); sprintf (line, "%%%% Total time spanned = %12.3f s (%.1f hours)\n", duration, duration/3600 ); strcat ( summary, line ); if ( (cfg->dataSummary = LALCalloc(1, strlen(summary) + 1 )) == NULL ) { ABORT (status, PREDICTFSTAT_EMEM, PREDICTFSTAT_MSGEMEM); } strcpy ( cfg->dataSummary, summary ); LogPrintfVerbatim( LOG_DEBUG, cfg->dataSummary ); } /* write dataSummary string */ /* free everything not needed any more */ TRY ( LALDestroyMultiPSDVector (status->statusPtr, &multiRngmed ), status ); TRY ( LALDestroyMultiNoiseWeights (status->statusPtr, &multiNoiseWeights ), status ); TRY ( LALDestroyMultiSFTVector (status->statusPtr, &multiSFTs ), status ); XLALDestroyMultiDetectorStateSeries ( multiDetStates ); XLALDestroyMultiAMCoeffs ( multiAMcoef ); /* Free ephemeris data */ XLALDestroyEphemerisData (edat); DETATCHSTATUSPTR (status); RETURN (status); } /* InitPFS() */
/* ----- function definitions ---------- */ int main(int argc, char *argv[]) { int opt; /* Command-line option. */ UINT4 numIFOs = 2; const CHAR *sites[2] = {"H1", "V1"}; UINT4 startTime = 714180733; UINT4 duration = 180000; /* 50 hours */ UINT4 Tsft = 1800; /* assume 30min SFTs */ REAL8 tolerance = 2e-6; /* same algorithm, should be basically identical results */ char earthEphem[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz"; char sunEphem[] = TEST_DATA_DIR "sun00-19-DE405.dat.gz"; UINT4 numChecks = 1; /* Number of times to check */ /* read user input */ while ((opt = LALgetopt( argc, argv, "n:qv:" )) != -1) { switch (opt) { case 'v': /* set lalDebugLevel */ break; case 'n': /* number of times to check */ numChecks = atoi( LALoptarg ); break; } } /* init random-generator */ struct tms buf; UINT4 seed = times(&buf); srand ( seed ); XLALPrintInfo ("%s: seed used = %d\n", __func__, seed ); /* ----- init ephemeris ----- */ EphemerisData *edat; if ( (edat = XLALInitBarycenter ( earthEphem, sunEphem )) == NULL ) { XLALPrintError ("%s: XLALInitBarycenter() failed with xlalErrno = %d\n", __func__, xlalErrno ); return XLAL_EFAILED; } /* ----- init detector info ---------- */ UINT4 X; MultiLALDetector multiDet; multiDet.length = numIFOs; for (X=0; X < numIFOs; X ++ ) { LALDetector *site; if ( (site = XLALGetSiteInfo ( sites[X] )) == NULL ) { XLALPrintError ("%s: Failed to get site-info for detector '%s'\n", __func__, sites[X] ); return XLAL_EFAILED; } multiDet.sites[X] = (*site); /* copy! */ XLALFree ( site ); } /* ----- init multi-IFO timestamps vector ---------- */ UINT4 numSteps = (UINT4) ceil ( duration / Tsft ); MultiLIGOTimeGPSVector * multiTS; if ( (multiTS = XLALCalloc ( 1, sizeof(*multiTS))) == NULL ) { XLAL_ERROR ( XLAL_ENOMEM ); } multiTS->length = numIFOs; if ( (multiTS->data = XLALCalloc (numIFOs, sizeof(*multiTS->data))) == NULL ) { XLAL_ERROR ( XLAL_ENOMEM ); } for ( X=0; X < numIFOs; X ++ ) { if ( (multiTS->data[X] = XLALCreateTimestampVector (numSteps)) == NULL ) { XLALPrintError ("%s: XLALCreateTimestampVector(%d) failed.\n", __func__, numSteps ); return XLAL_EFAILED; } multiTS->data[X]->deltaT = Tsft; UINT4 i; for ( i=0; i < numSteps; i ++ ) { UINT4 ti = startTime + i * Tsft; multiTS->data[X]->data[i].gpsSeconds = ti; multiTS->data[X]->data[i].gpsNanoSeconds = 0; } /* for i < numSteps */ } /* for X < numIFOs */ /* ---------- compute multi-detector states -------------------- */ MultiDetectorStateSeries *multiDetStates; if ( (multiDetStates = XLALGetMultiDetectorStates ( multiTS, &multiDet, edat, 0.5 * Tsft )) == NULL ) { XLALPrintError ( "%s: XLALGetMultiDetectorStates() failed.\n", __func__ ); return XLAL_EFAILED; } XLALDestroyMultiTimestamps ( multiTS ); XLALDestroyEphemerisData ( edat ); /* ========== MAIN LOOP: N-trials of comparisons XLAL <--> LAL multiAM functions ========== */ while ( numChecks-- ) { LALStatus XLAL_INIT_DECL(status); /* ----- pick skyposition at random ----- */ SkyPosition skypos; skypos.longitude = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) ); /* uniform in [0, 2pi) */ skypos.latitude = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX ); /* sin(delta) uniform in [-1,1] */ skypos.system = COORDINATESYSTEM_EQUATORIAL; MultiNoiseWeights *weights = NULL; /* for now we only deal with unit-weights case */ /* ----- compute multiAM using LAL function ----- */ MultiAMCoeffs *multiAM_LAL = NULL; LALGetMultiAMCoeffs ( &status, &multiAM_LAL, multiDetStates, skypos ); if ( status.statusCode ) { XLALPrintError ("%s: LALGetMultiAMCoeffs() failed with statusCode = %d : %s\n", __func__, status.statusCode, status.statusDescription ); return XLAL_EFAILED; } if ( XLALWeightMultiAMCoeffs ( multiAM_LAL, weights ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALWeightMultiAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); return XLAL_EFAILED; } /* ----- compute multiAM using XLAL function ----- */ MultiAMCoeffs *multiAM_XLAL; if ( ( multiAM_XLAL = XLALComputeMultiAMCoeffs ( multiDetStates, weights, skypos )) == NULL ) { XLALPrintError ("%s: XLALComputeMultiAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); return XLAL_EFAILED; } /* now run comparison */ if ( XLALCompareMultiAMCoeffs ( multiAM_XLAL, multiAM_LAL, tolerance ) != XLAL_SUCCESS ) { XLALPrintError ("%s: comparison between multiAM_XLAL and multiAM_LAL failed.\n", __func__ ); return XLAL_EFAILED; } /* free memory created inside this loop */ XLALDestroyMultiAMCoeffs ( multiAM_LAL ); XLALDestroyMultiAMCoeffs ( multiAM_XLAL ); } /* for numChecks */ /* we're done: free memory */ XLALDestroyMultiDetectorStateSeries ( multiDetStates ); LALCheckMemoryLeaks(); printf ("OK. All tests passed successfully\n\n"); return 0; /* OK */ } /* main() */