/** Initialize Fstat-code: handle user-input and set everything up. */ int XLALInitCode ( ConfigVariables *cfg, const UserInput_t *uvar ) { /* generate log-string for file-output, containing cmdline-options + code VCS version info */ char *vcs; if ( (vcs = XLALGetVersionString(0)) == NULL ) { /* short VCS version string */ XLALPrintError ( "%s: XLALGetVersionString(0) failed with errno=%d.\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } char *cmdline; if ( (cmdline = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) == NULL ) { XLALPrintError ( "%s: XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE ) failed with errno=%d.\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } const char fmt[] = "%%%% cmdline: %s\n%%%%\n%s%%%%\n"; UINT4 len = strlen(vcs) + strlen(cmdline) + strlen(fmt) + 1; if ( ( cfg->logString = XLALMalloc ( len )) == NULL ) { XLALPrintError ("%s: XLALMalloc ( %d ) failed.\n", __func__, len ); XLAL_ERROR ( XLAL_ENOMEM ); } sprintf ( cfg->logString, fmt, cmdline, vcs ); XLALFree ( cmdline ); XLALFree ( vcs ); /* trivial settings from user-input */ cfg->SignalOnly = uvar->SignalOnly; /* ----- parse user-input on signal amplitude-paramters + ranges ----- */ /* skypos */ cfg->skypos.longitude = uvar->Alpha; /* Alpha < 0 indicates 'allsky' */ cfg->skypos.latitude = uvar->Delta; cfg->skypos.system = COORDINATESYSTEM_EQUATORIAL; /* ----- amplitude-params: create prior pdfs reflecting the user-input */ if ( XLALInitAmplitudePrior ( &cfg->AmpPrior, uvar ) != XLAL_SUCCESS ) XLAL_ERROR ( XLAL_EFUNC ); /* ----- initialize random-number generator ----- */ /* read out environment variables GSL_RNG_xxx * GSL_RNG_SEED: use to set random seed: default = 0, override by using --randSeed on cmdline * GSL_RNG_TYPE: type of random-number generator to use: default = 'mt19937' */ gsl_rng_env_setup (); /* allow overriding the random-seed per command-line */ if ( XLALUserVarWasSet ( &uvar->randSeed ) ) gsl_rng_default_seed = uvar->randSeed; cfg->rng = gsl_rng_alloc (gsl_rng_default); LogPrintf ( LOG_DEBUG, "random-number generator type: %s\n", gsl_rng_name (cfg->rng)); LogPrintf ( LOG_DEBUG, "seed = %lu\n", gsl_rng_default_seed ); /* init ephemeris-data */ EphemerisData *edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun ); if ( !edat ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", __func__, uvar->ephemEarth, uvar->ephemSun); XLAL_ERROR ( XLAL_EFUNC ); } UINT4 numDetectors = uvar->IFOs->length; MultiLALDetector multiDet; XLAL_CHECK ( XLALParseMultiLALDetector ( &multiDet, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); /* init timestamps vector covering observation time */ UINT4 numSteps = (UINT4) ceil ( uvar->dataDuration / uvar->TAtom ); MultiLIGOTimeGPSVector * multiTS; if ( (multiTS = XLALCreateMultiLIGOTimeGPSVector (numDetectors)) == NULL ) { XLALPrintError ("%s: XLALCreateMultiLIGOTimeGPSVector(%d) failed.\n", __func__, numDetectors ); } for ( UINT4 X=0; X < numDetectors; X++ ) { if ( (multiTS->data[X] = XLALCreateTimestampVector (numSteps)) == NULL ) { XLALPrintError ("%s: XLALCreateTimestampVector(%d) failed.\n", __func__, numSteps ); } multiTS->data[X]->deltaT = uvar->TAtom; UINT4 i; for ( i=0; i < numSteps; i ++ ) { UINT4 ti = uvar->dataStartGPS + i * uvar->TAtom; multiTS->data[X]->data[i].gpsSeconds = ti; multiTS->data[X]->data[i].gpsNanoSeconds = 0; } } /* get detector states */ if ( (cfg->multiDetStates = XLALGetMultiDetectorStates ( multiTS, &multiDet, edat, 0.5 * uvar->TAtom )) == NULL ) { XLALPrintError ( "%s: XLALGetMultiDetectorStates() failed.\n", __func__ ); XLAL_ERROR ( XLAL_EFUNC ); } if ( uvar->sqrtSX ) { /* translate user-input PSD sqrt(SX) to noise-weights (this actually does not care whether they were normalized or not) */ /* parse input comma-separated list */ MultiNoiseFloor multiNoiseFloor; XLAL_CHECK ( XLALParseMultiNoiseFloor ( &multiNoiseFloor, uvar->sqrtSX, numDetectors ) == XLAL_SUCCESS, XLAL_EFUNC ); /* translate to noise weights */ XLAL_CHECK ( ( cfg->multiNoiseWeights = XLALComputeConstantMultiNoiseWeightsFromNoiseFloor ( &multiNoiseFloor, multiTS, uvar->TAtom ) ) != NULL, XLAL_EFUNC ); } /* if ( uvar->sqrtSX ) */ /* get rid of all temporary memory allocated for this step */ XLALDestroyEphemerisData ( edat ); XLALDestroyMultiTimestamps ( multiTS ); multiTS = NULL; /* ---------- initialize transient window ranges, for injection ... ---------- */ cfg->transientInjectRange.type = TRANSIENT_NONE; /* default: no transient signal window */ /* apply correct defaults if unset: t0=dataStart, t0Band=dataDuration-3*tauMax */ // cfg->transientInjectRange.t0 = uvar->dataStartGPS + uvar->injectWindow_t0Days * DAY24; cfg->transientSearchRange = cfg->transientInjectRange; return XLAL_SUCCESS; } /* XLALInitCode() */
/** * basic initializations: set-up 'ConfigVariables' */ int XLALInitCode ( ConfigVariables *cfg, const UserVariables_t *uvar, const char *app_name) { if ( !cfg || !uvar || !app_name ) { LogPrintf (LOG_CRITICAL, "%s: illegal NULL pointer input.\n\n", __func__ ); XLAL_ERROR (XLAL_EINVAL ); } /* Init ephemerides */ XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC ); // ----- figure out which segments to use BOOLEAN manualSegments = XLALUserVarWasSet(&uvar->duration) || XLALUserVarWasSet(&uvar->startTime) || XLALUserVarWasSet(&uvar->Nseg); if ( manualSegments && uvar->segmentList ) { XLAL_ERROR ( XLAL_EDOM, "Can specify EITHER {--startTime, --duration, --Nseg} OR --segmentList\n"); } LIGOTimeGPS startTimeGPS; REAL8 duration; if ( uvar->segmentList == NULL ) { XLAL_CHECK ( uvar->Nseg >= 1, XLAL_EDOM, "Invalid input --Nseg=%d: number of segments must be >= 1\n", uvar->Nseg ); XLAL_CHECK ( uvar->duration >= 1, XLAL_EDOM, "Invalid input --duration=%f: duration must be >= 1 s\n", uvar->duration ); startTimeGPS = uvar->startTime; int ret = XLALSegListInitSimpleSegments ( &cfg->segmentList, startTimeGPS, uvar->Nseg, uvar->duration / uvar->Nseg ); XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno ); duration = uvar->duration; } else { LALSegList *segList = XLALReadSegmentsFromFile ( uvar->segmentList ); XLAL_CHECK ( segList != NULL, XLAL_EIO, "XLALReadSegmentsFromFile() failed to load segment list from file '%s', xlalErrno = %d\n", uvar->segmentList, xlalErrno ); cfg->segmentList = (*segList); // copy *contents* XLALFree ( segList ); startTimeGPS = cfg->segmentList.segs[0].start; UINT4 Nseg = cfg->segmentList.length; LIGOTimeGPS endTimeGPS = cfg->segmentList.segs[Nseg-1].end; duration = XLALGPSDiff( &endTimeGPS, &startTimeGPS ); } /* ----- figure out reference time */ LIGOTimeGPS refTimeGPS; /* treat special values first */ if ( uvar->refTime.gpsSeconds == 0 ) /* 0 = use startTime */ { refTimeGPS = uvar->startTime; } else if ( !XLALUserVarWasSet ( &uvar->refTime ) ) /* default = use mid-time of observation */ { refTimeGPS = startTimeGPS; XLALGPSAdd( &refTimeGPS, duration / 2.0 ); } else { refTimeGPS = uvar->refTime; } /* ----- get parameter-space point from user-input) */ cfg->signalParams.Amp.h0 = uvar->h0; cfg->signalParams.Amp.cosi = uvar->cosi; cfg->signalParams.Amp.psi = uvar->psi; cfg->signalParams.Amp.phi0 = uvar->phi0; { PulsarDopplerParams *dop = &(cfg->signalParams.Doppler); XLAL_INIT_MEM((*dop)); dop->refTime = refTimeGPS; dop->Alpha = uvar->Alpha; dop->Delta = uvar->Delta; dop->fkdot[0] = uvar->Freq; dop->fkdot[1] = uvar->f1dot; dop->fkdot[2] = uvar->f2dot; dop->fkdot[3] = uvar->f3dot; dop->asini = uvar->orbitasini; dop->period = uvar->orbitPeriod; dop->tp = uvar->orbitTp; dop->ecc = uvar->orbitEcc; dop->argp = uvar->orbitArgp; } /* ----- initialize IFOs and (Multi-)DetectorStateSeries ----- */ XLAL_CHECK ( XLALParseMultiLALDetector ( &cfg->multiIFO, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); UINT4 numDet = cfg->multiIFO.length; XLAL_CHECK ( numDet >= 1, XLAL_EINVAL ); if ( uvar->sqrtSX ) { XLAL_CHECK ( XLALParseMultiNoiseFloor ( &cfg->multiNoiseFloor, uvar->sqrtSX, numDet ) == XLAL_SUCCESS, XLAL_EFUNC ); } /* ---------- translate coordinate system into internal representation ---------- */ if ( XLALDopplerCoordinateNames2System ( &cfg->coordSys, uvar->coords ) ) { LogPrintf (LOG_CRITICAL, "%s: Call to XLALDopplerCoordinateNames2System() failed. errno = %d\n\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } /* ---------- record full 'history' up to and including this application ---------- */ { CHAR *cmdline = NULL; CHAR *tmp; size_t len = strlen ( app_name ) + 1; if ( (cfg->history = XLALCalloc ( 1, sizeof(*cfg->history))) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: XLALCalloc(1,%zu) failed.\n\n", __func__, sizeof(*cfg->history)); XLAL_ERROR ( XLAL_ENOMEM ); } if ( (tmp = XLALMalloc ( len )) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: XLALMalloc (%zu) failed.\n\n", __func__, len ); XLAL_ERROR ( XLAL_ENOMEM ); } strcpy ( tmp, app_name ); cfg->history->app_name = tmp; /* get commandline describing search*/ if ( (cmdline = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) == NULL ) { LogPrintf (LOG_CRITICAL, "%s: XLALUserVarGetLog() failed with xlalErrno = %d.\n\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } cfg->history->cmdline = cmdline; } /* record history */ return XLAL_SUCCESS; } /* XLALInitCode() */
/** * 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() */
/** * Handle user-input and set up shop accordingly, and do all * consistency-checks on user-input. */ int XLALInitMakefakedata ( ConfigVars_t *cfg, UserVariables_t *uvar ) { XLAL_CHECK ( cfg != NULL, XLAL_EINVAL, "Invalid NULL input 'cfg'\n" ); XLAL_CHECK ( uvar != NULL, XLAL_EINVAL, "Invalid NULL input 'uvar'\n"); cfg->VCSInfoString = XLALGetVersionString(0); XLAL_CHECK ( cfg->VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); // version info was requested: output then exit if ( uvar->version ) { printf ("%s\n", cfg->VCSInfoString ); exit (0); } /* if requested, log all user-input and code-versions */ if ( uvar->logfile ) { XLAL_CHECK ( XLALWriteMFDlog ( uvar->logfile, cfg ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALWriteMFDlog() failed with xlalErrno = %d\n", xlalErrno ); } /* Init ephemerides */ XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC ); /* check for negative fMin and Band, which would break the fMin_eff, fBand_eff calculation below */ XLAL_CHECK ( uvar->fmin >= 0, XLAL_EDOM, "Invalid negative frequency fMin=%f!\n\n", uvar->fmin ); XLAL_CHECK ( uvar->Band > 0, XLAL_EDOM, "Invalid non-positive frequency band Band=%f!\n\n", uvar->Band ); // ---------- check user-input consistency ---------- // ----- check if frames + frame channels given BOOLEAN have_frames = (uvar->inFrames != NULL); BOOLEAN have_channels= (uvar->inFrChannels != NULL); XLAL_CHECK ( !(have_frames || have_channels) || (have_frames && have_channels), XLAL_EINVAL, "Need both --inFrames and --inFrChannels, or NONE\n"); // ----- IFOs : only from one of {--IFOs, --noiseSFTs, --inFrChannels}: mutually exclusive BOOLEAN have_IFOs = (uvar->IFOs != NULL); BOOLEAN have_noiseSFTs = (uvar->noiseSFTs != NULL); XLAL_CHECK ( have_frames || have_IFOs || have_noiseSFTs, XLAL_EINVAL, "Need one of --IFOs, --noiseSFTs or --inFrChannels to determine detectors\n"); if ( have_frames ) { XLAL_CHECK ( !have_IFOs && !have_noiseSFTs, XLAL_EINVAL, "If --inFrames given, cannot handle --IFOs or --noiseSFTs input\n"); XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->inFrChannels ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { // !have_frames XLAL_CHECK ( !(have_IFOs && have_noiseSFTs), XLAL_EINVAL, "Cannot handle both --IFOs and --noiseSFTs input\n"); } if ( have_IFOs ) { XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); } // ----- TIMESTAMPS: either from --timestampsFiles, --startTime+duration, or --noiseSFTs BOOLEAN have_startTime = XLALUserVarWasSet ( &uvar->startTime ); BOOLEAN have_duration = XLALUserVarWasSet ( &uvar->duration ); BOOLEAN have_timestampsFiles = ( uvar->timestampsFiles != NULL ); // need BOTH startTime+duration or none XLAL_CHECK ( ( have_duration && have_startTime) || !( have_duration || have_startTime ), XLAL_EINVAL, "Need BOTH {--startTime,--duration} or NONE\n"); // at least one of {startTime,timestamps,noiseSFTs,inFrames} required XLAL_CHECK ( have_timestampsFiles || have_startTime || have_noiseSFTs || have_frames, XLAL_EINVAL, "Need at least one of {--timestampsFiles, --startTime+duration, --noiseSFTs, --inFrames}\n" ); // don't allow timestamps + {startTime+duration OR noiseSFTs} XLAL_CHECK ( !have_timestampsFiles || !(have_startTime||have_noiseSFTs), XLAL_EINVAL, "--timestampsFiles incompatible with {--noiseSFTs or --startTime+duration}\n"); // note, however, that we DO allow --noiseSFTs and --startTime+duration, which will act as a constraint // on the noise-SFTs to load in // don't allow --SFToverlap with either --noiseSFTs OR --timestampsFiles XLAL_CHECK ( uvar->SFToverlap >= 0, XLAL_EDOM ); BOOLEAN haveOverlap = ( uvar->SFToverlap > 0 ); XLAL_CHECK ( !haveOverlap || !( have_noiseSFTs || have_timestampsFiles ), XLAL_EINVAL, "--SFToverlap incompatible with {--noiseSFTs or --timestampsFiles}\n" ); // now handle the 3 mutually-exclusive cases: have_noiseSFTs || have_timestampsFiles || have_startTime (only) if ( have_noiseSFTs ) { SFTConstraints XLAL_INIT_DECL(constraints); if ( have_startTime && have_duration ) // use optional (startTime+duration) as constraints, { LIGOTimeGPS minStartTime, maxStartTime; minStartTime = uvar->startTime; maxStartTime = uvar->startTime; XLALGPSAdd ( &maxStartTime, uvar->duration ); constraints.minStartTime = &minStartTime; constraints.maxStartTime = &maxStartTime; char bufGPS1[32], bufGPS2[32]; XLALPrintWarning ( "Only noise-SFTs between GPS [%s, %s] will be used!\n", XLALGPSToStr(bufGPS1, &minStartTime), XLALGPSToStr(bufGPS2, &maxStartTime) ); } /* if start+duration given */ XLAL_CHECK ( (cfg->noiseCatalog = XLALSFTdataFind ( uvar->noiseSFTs, &constraints )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( cfg->noiseCatalog->length > 0, XLAL_EINVAL, "No noise-SFTs matching (start+duration, timestamps) were found!\n" ); XLAL_CHECK ( (cfg->multiNoiseCatalogView = XLALGetMultiSFTCatalogView ( cfg->noiseCatalog )) != NULL, XLAL_EFUNC ); // extract multi-timestamps from the multi-SFT-catalog view XLAL_CHECK ( (cfg->multiTimestamps = XLALTimestampsFromMultiSFTCatalogView ( cfg->multiNoiseCatalogView )) != NULL, XLAL_EFUNC ); // extract IFOs from multi-SFT catalog XLAL_CHECK ( XLALMultiLALDetectorFromMultiSFTCatalogView ( &(cfg->multiIFO), cfg->multiNoiseCatalogView ) == XLAL_SUCCESS, XLAL_EFUNC ); } // endif have_noiseSFTs else if ( have_timestampsFiles ) { 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 XLALReadMultiTimestampsFiles()\n" ); for ( UINT4 X=0; X < cfg->multiTimestamps->length; X ++ ) { cfg->multiTimestamps->data[X]->deltaT = uvar->Tsft; // Tsft information not given by timestamps-file } } // endif have_timestampsFiles else if ( have_startTime && have_duration ) { XLAL_CHECK ( ( cfg->multiTimestamps = XLALMakeMultiTimestamps ( uvar->startTime, uvar->duration, uvar->Tsft, uvar->SFToverlap, cfg->multiIFO.length )) != NULL, XLAL_EFUNC ); } // endif have_startTime // check if the user asked for Gaussian white noise to be produced (sqrtSn[X]!=0), otherwise leave noise-floors at 0 if ( uvar->sqrtSX != NULL ) { XLAL_CHECK ( XLALParseMultiNoiseFloor ( &(cfg->multiNoiseFloor), uvar->sqrtSX, cfg->multiIFO.length ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { cfg->multiNoiseFloor.length = cfg->multiIFO.length; // values remain at their default sqrtSn[X] = 0; } #ifdef HAVE_LIBLALFRAME // if user requested time-series data from frames to be added: try to read the frames now if ( have_frames ) { UINT4 numDetectors = uvar->inFrChannels->length; XLAL_CHECK ( uvar->inFrames->length == numDetectors, XLAL_EINVAL, "Need equal number of channel names (%d) as frame specifications (%d)\n", uvar->inFrChannels->length, numDetectors ); XLAL_CHECK ( (cfg->inputMultiTS = XLALCalloc ( 1, sizeof(*cfg->inputMultiTS))) != NULL, XLAL_ENOMEM ); cfg->inputMultiTS->length = numDetectors; XLAL_CHECK ( (cfg->inputMultiTS->data = XLALCalloc ( numDetectors, sizeof(cfg->inputMultiTS->data[0]) )) != NULL, XLAL_ENOMEM ); if ( cfg->multiTimestamps == NULL ) { XLAL_CHECK ( (cfg->multiTimestamps = XLALCalloc ( 1, sizeof(*cfg->multiTimestamps) )) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( (cfg->multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(cfg->multiTimestamps->data[0]))) != NULL, XLAL_ENOMEM ); cfg->multiTimestamps->length = numDetectors; } for ( UINT4 X = 0; X < numDetectors; X ++ ) { LALCache *cache; XLAL_CHECK ( (cache = XLALCacheImport ( uvar->inFrames->data[X] )) != NULL, XLAL_EFUNC, "Failed to import cache file '%s'\n", uvar->inFrames->data[X] ); // this is a sorted cache, so extract its time-range: REAL8 cache_tStart = cache->list[0].t0; REAL8 cache_tEnd = cache->list[cache->length-1].t0 + cache->list[cache->length-1].dt; REAL8 cache_duration = (cache_tEnd - cache_tStart); LIGOTimeGPS ts_start; REAL8 ts_duration; // check that it's consistent with timestamps, if given, otherwise create timestamps from this if ( cfg->multiTimestamps->data[X] != NULL ) // FIXME: implicitly assumes timestamps are sorted, which is not guaranteed by timestamps-reading from file { const LIGOTimeGPSVector *timestampsX = cfg->multiTimestamps->data[X]; REAL8 tStart = XLALGPSGetREAL8( ×tampsX->data[0] ); REAL8 tEnd = XLALGPSGetREAL8( ×tampsX->data[timestampsX->length-1]) + timestampsX->deltaT; XLAL_CHECK ( tStart >= cache_tStart && tEnd <= cache_tEnd, XLAL_EINVAL, "Detector X=%d: Requested timestamps-range [%.0f, %.0f]s outside of cache range [%.0f,%.0f]s\n", X, tStart, tEnd, cache_tStart, cache_tEnd ); XLALGPSSetREAL8 ( &ts_start, tStart ); ts_duration = (tEnd - tStart); } else { XLALGPSSetREAL8 ( &ts_start, (REAL8)cache_tStart + 1); // cache times can apparently be by rounded up or down by 1s, so shift by 1s to be safe ts_duration = cache_duration - 1; XLAL_CHECK ( (cfg->multiTimestamps->data[X] = XLALMakeTimestamps ( ts_start, ts_duration, uvar->Tsft, uvar->SFToverlap ) ) != NULL, XLAL_EFUNC ); } // ----- now open frame stream and read *all* the data within this time-range [FIXME] ---------- LALFrStream *stream; XLAL_CHECK ( (stream = XLALFrStreamCacheOpen ( cache )) != NULL, XLAL_EFUNC, "Failed to open stream from cache file '%s'\n", uvar->inFrames->data[X] ); XLALDestroyCache ( cache ); const char *channel = uvar->inFrChannels->data[X]; size_t limit = 0; // unlimited read REAL8TimeSeries *ts; XLAL_CHECK ( (ts = XLALFrStreamInputREAL8TimeSeries ( stream, channel, &ts_start, ts_duration, limit )) != NULL, XLAL_EFUNC, "Frame reading failed for stream created for '%s': ts_start = {%d,%d}, duration=%.0f\n", uvar->inFrames->data[X], ts_start.gpsSeconds, ts_start.gpsNanoSeconds, ts_duration ); cfg->inputMultiTS->data[X] = ts; XLAL_CHECK ( XLALFrStreamClose ( stream ) == XLAL_SUCCESS, XLAL_EFUNC, "Stream closing failed for cache file '%s'\n", uvar->inFrames->data[X] ); } // for X < numDetectors } // if inFrames // if user requested timeseries *output* to frame files, handle deprecated options XLAL_CHECK ( !(uvar->TDDframedir && uvar->outFrameDir), XLAL_EINVAL, "Specify only ONE of {--TDDframedir or --outFrameDir} or NONE\n"); if ( uvar->TDDframedir ) { cfg->outFrameDir = uvar->TDDframedir; } else if ( uvar->outFrameDir ) { cfg->outFrameDir = uvar->outFrameDir; } #endif return XLAL_SUCCESS; } /* XLALInitMakefakedata() */
/** * 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, }; // ========== BEGINNING OF TEST CALLS ========== XLALPrintWarning("\n---------- ROUND 1: ephemeris-based, single-IFO phase metrics ----------\n"); { OldDopplerMetric *metric1; DopplerPhaseMetric *metric2P; REAL8 diff_2_1; DopplerMetricParams pars2 = master_pars2; pars2.multiIFO.length = 1; // truncate to first detector pars2.multiNoiseFloor.length = 1; // truncate to first detector // 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 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 ); } XLALPrintWarning("\n---------- ROUND 2: Ptolemaic-based, single-IFO phase metrics ----------\n"); { OldDopplerMetric *metric1; DopplerPhaseMetric *metric2P; REAL8 diff_2_1; DopplerMetricParams pars2 = master_pars2; pars2.multiIFO.length = 1; // truncate to first detector pars2.multiNoiseFloor.length = 1; // truncate to first detector pars2.detMotionType = DETMOTION_SPIN | DETMOTION_PTOLEORBIT; // 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_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 ); } 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 ); }