/** * Function to determine the PulsarParamsVector input from a user-input defining CW sources. * * This option supports a dual-type feature: if any string in the list is of the form '{...}', then * it determines the *contents* of a config-file, otherwise the name-pattern of config-files to be parsed by XLALFindFiles(), * NOTE: when specifying file-contents, options can be separated by ';' and/or newlines) */ PulsarParamsVector * XLALPulsarParamsFromUserInput ( const LALStringVector *UserInput ///< [in] user-input CSV list defining 'CW sources' ) { XLAL_CHECK_NULL ( UserInput, XLAL_EINVAL ); XLAL_CHECK_NULL ( UserInput->length > 0, XLAL_EINVAL ); PulsarParamsVector *allSources = NULL; for ( UINT4 l = 0; l < UserInput->length; l ++ ) { const char *thisInput = UserInput->data[l]; if ( thisInput[0] != '{' ) // if it's an actual file-specification { LALStringVector *file_list; XLAL_CHECK_NULL ( ( file_list = XLALFindFiles ( &thisInput[0] )) != NULL, XLAL_EFUNC ); UINT4 numFiles = file_list->length; for ( UINT4 i = 0; i < numFiles; i ++ ) { PulsarParamsVector *sources_i; XLAL_CHECK_NULL ( (sources_i = XLALPulsarParamsFromFile ( file_list->data[i] )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( (allSources = XLALPulsarParamsVectorAppend ( allSources, sources_i )) != NULL, XLAL_EFUNC ); XLALDestroyPulsarParamsVector ( sources_i ); } // for i < numFiles XLALDestroyStringVector ( file_list ); } // if file-pattern given else { UINT4 len = strlen(thisInput); XLAL_CHECK_NULL ( (thisInput[0] == '{') && (thisInput[len-1] == '}'), XLAL_EINVAL, "Invalid file-content input:\n%s\n", thisInput ); char *buf; XLAL_CHECK_NULL ( (buf = XLALStringDuplicate ( &thisInput[1] )) != NULL, XLAL_EFUNC ); len = strlen(buf); buf[len-1] = 0; // remove trailing '}' LALParsedDataFile *cfgdata = NULL; XLAL_CHECK_NULL ( XLALParseDataFileContent ( &cfgdata, buf ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALFree ( buf ); PulsarParamsVector *addSource; XLAL_CHECK_NULL ( (addSource = XLALCreatePulsarParamsVector ( 1 )) != NULL, XLAL_EFUNC ); XLAL_CHECK_NULL ( XLALReadPulsarParams ( &addSource->data[0], cfgdata, NULL ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK_NULL ( (addSource->data[0].name = XLALStringDuplicate ( "direct-string-input" )) != NULL, XLAL_EFUNC ); XLALDestroyParsedDataFile ( cfgdata ); XLAL_CHECK_NULL ( (allSources = XLALPulsarParamsVectorAppend ( allSources, addSource )) != NULL, XLAL_EFUNC ); XLALDestroyPulsarParamsVector ( addSource ); } // if direct config-string given } // for l < len(UserInput) return allSources; } // XLALPulsarParamsFromUserInput()
/*---------------------------------------------------------------------- * main function *----------------------------------------------------------------------*/ int main(int argc, char *argv[]) { size_t len; ConfigVars_t XLAL_INIT_DECL(GV); UserVariables_t XLAL_INIT_DECL(uvar); /* ------------------------------ * read user-input and set up shop *------------------------------*/ XLAL_CHECK ( XLALInitUserVars ( &uvar, argc, argv ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALInitMakefakedata ( &GV, &uvar ) == XLAL_SUCCESS, XLAL_EFUNC ); MultiSFTVector *mSFTs = NULL; MultiREAL8TimeSeries *mTseries = NULL; PulsarParamsVector *injectionSources = NULL; if ( uvar.injectionSources ) { XLAL_CHECK ( (injectionSources = XLALPulsarParamsFromUserInput ( uvar.injectionSources, NULL ) ) != NULL, XLAL_EFUNC ); } CWMFDataParams XLAL_INIT_DECL(DataParams); DataParams.multiIFO = GV.multiIFO; DataParams.multiNoiseFloor = GV.multiNoiseFloor; DataParams.multiTimestamps = (*GV.multiTimestamps); DataParams.randSeed = uvar.randSeed; DataParams.SFTWindowType = uvar.SFTWindowType; DataParams.SFTWindowBeta = uvar.SFTWindowBeta; if ( GV.inputMultiTS == NULL ) { DataParams.fMin = uvar.fmin; DataParams.Band = uvar.Band; DataParams.inputMultiTS = NULL; } else // current limitation: FIXME { DataParams.fMin = 0; DataParams.Band = 0; DataParams.inputMultiTS = GV.inputMultiTS; } XLAL_CHECK ( XLALCWMakeFakeMultiData ( &mSFTs, &mTseries, injectionSources, &DataParams, GV.edat ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyPulsarParamsVector ( injectionSources ); injectionSources = NULL; // if noiseSFTs specified, load them and add them to the resulting SFT-vector if ( GV.multiNoiseCatalogView ) { SFTtype *sft0 = &(mSFTs->data[0]->data[0]); /* load effective frequency-band from noise-SFTs */ UINT4 numBins = sft0->data->length; REAL8 dFreq = sft0->deltaF; REAL8 fMin = sft0->f0; REAL8 fMax = fMin + ( numBins - 1 ) * dFreq; MultiSFTVector *mNoiseSFTs; XLAL_CHECK ( (mNoiseSFTs = XLALLoadMultiSFTsFromView ( GV.multiNoiseCatalogView, fMin, fMax )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( XLALMultiSFTVectorAdd ( mSFTs, mNoiseSFTs ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyMultiSFTVector ( mNoiseSFTs ); } if (uvar.outSFTdir) { XLAL_CHECK ( is_directory ( uvar.outSFTdir ), XLAL_EINVAL ); /* generate comment string */ CHAR *logstr; XLAL_CHECK ( (logstr = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) != NULL, XLAL_EFUNC ); char *comment = XLALCalloc ( 1, len = strlen ( logstr ) + strlen(GV.VCSInfoString) + 512 ); XLAL_CHECK ( comment != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zu) failed.\n", len ); sprintf ( comment, "Generated by:\n%s\n%s\n", logstr, GV.VCSInfoString ); for ( UINT4 X=0; X < mSFTs->length; X ++ ) { SFTVector *sfts = mSFTs->data[X]; /* either write whole SFT-vector to single concatenated file */ if ( uvar.outSingleSFT ) { XLAL_CHECK ( XLALWriteSFTVector2File( sfts, uvar.outSFTdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { // or as individual SFT-files XLAL_CHECK ( XLALWriteSFTVector2Dir( sfts, uvar.outSFTdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); } } // for X < numIFOs XLALFree ( logstr ); XLALFree ( comment ); } /* if outSFTdir */ /* output ASCII time-series if requested */ if ( uvar.TDDfile ) { CHAR *fname = XLALCalloc (1, len = strlen(uvar.TDDfile) + 10 ); XLAL_CHECK ( fname != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zu) failed\n", len ); for ( UINT4 X=0; X < mTseries->length; X ++ ) { const REAL8TimeSeries *TS = mTseries->data[X]; sprintf (fname, "%c%c-%s", TS->name[0], TS->name[1], uvar.TDDfile ); XLAL_CHECK ( XLALdumpREAL8TimeSeries ( fname, TS ) == XLAL_SUCCESS, XLAL_EFUNC ); } // for X < numDet XLALFree (fname); } /* if outputting ASCII time-series */ /* output time-series to frames if requested */ #ifdef HAVE_LIBLALFRAME if ( GV.outFrameDir != NULL ) { XLAL_CHECK ( XLALCheckValidDescriptionField ( uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC ); len = strlen(GV.outFrameDir) + strlen(uvar.outLabel) + 100; char *fname; char *hist = XLALUserVarGetLog (UVAR_LOGFMT_CMDLINE); if ( XLALUserVarWasSet ( &uvar.outFrChannels ) ) { XLAL_CHECK ( uvar.outFrChannels->length == mTseries->length, XLAL_EINVAL, "--outFrChannels: number of channel names (%d) must agree with number of IFOs (%d)\n", uvar.outFrChannels->length, mTseries->length ); } for ( UINT4 X=0; X < mTseries->length; X ++ ) { REAL8TimeSeries *Tseries = mTseries->data[X]; /* use standard frame output filename format */ char IFO[2] = { Tseries->name[0], Tseries->name[1] }; LIGOTimeGPS startTimeGPS = Tseries->epoch; REAL8 duration = Tseries->data->length * Tseries->deltaT; XLAL_CHECK ( (fname = LALCalloc (1, len )) != NULL, XLAL_ENOMEM ); size_t written = snprintf ( fname, len, "%s/%c-%c%c_%s-%d-%d.gwf", GV.outFrameDir, IFO[0], IFO[0], IFO[1], uvar.outLabel, startTimeGPS.gpsSeconds, (int)duration ); XLAL_CHECK ( written < len, XLAL_ESIZE, "Frame-filename exceeds expected maximal length (%zu): '%s'\n", len, fname ); /* define the output frame */ LALFrameH *outFrame; XLAL_CHECK ( (outFrame = XLALFrameNew ( &startTimeGPS, duration, uvar.outLabel, 1, 0, 0 )) != NULL, XLAL_EFUNC ); /* add timeseries to the frame - make sure to change the timeseries name since this is used as the channel name */ char buffer[LALNameLength]; // if output frame channel names given, use those if ( XLALUserVarWasSet ( &uvar.outFrChannels ) ) { written = snprintf ( buffer, sizeof(buffer), "%s", uvar.outFrChannels->data[X] ); if ( buffer[2] == ':' ) { // check we got correct IFO association XLAL_CHECK ( (buffer[0] == Tseries->name[0]) && (buffer[1] == Tseries->name[1]), XLAL_EINVAL, "Possible IFO mismatch: outFrChannel[%d] = '%s', IFO = '%c%c': be careful about --outFrChannel ordering\n", X, buffer, Tseries->name[0], Tseries->name[1] ); } // if buffer[2]==':' } else if ( XLALUserVarWasSet ( &uvar.inFrChannels ) ) { // otherwise: if input frame channel names given, use them for output, append "-<outLabel>" written = snprintf ( buffer, sizeof(buffer), "%s-%s", uvar.inFrChannels->data[X], uvar.outLabel ); } else { // otherwise: fall back to <IFO>:<outLabel> channel name written = snprintf ( buffer, sizeof(buffer), "%c%c:%s", Tseries->name[0], Tseries->name[1], uvar.outLabel ); } XLAL_CHECK ( written < LALNameLength, XLAL_ESIZE, "Output frame name exceeded max length (%d): '%s'\n", LALNameLength, buffer ); strcpy ( Tseries->name, buffer ); XLAL_CHECK ( (XLALFrameAddREAL8TimeSeriesProcData ( outFrame, Tseries ) == XLAL_SUCCESS ) , XLAL_EFUNC ); /* Here's where we add extra information into the frame - first we add the command line args used to generate it */ XLALFrameAddFrHistory ( outFrame, __FILE__, hist ); /* then we add the version string */ XLALFrameAddFrHistory ( outFrame, __FILE__, GV.VCSInfoString ); /* output the frame to file - compression level 1 (higher values make no difference) */ XLAL_CHECK ( XLALFrameWrite ( outFrame, fname ) == XLAL_SUCCESS , XLAL_EFUNC ); /* free the frame, frame file name and history memory */ XLALFrameFree ( outFrame ); XLALFree ( fname ); } // for X < numDetectors XLALFree ( hist ); } /* if GV.outFrameDir: outputting time-series to frames */ #endif // HAVE_LIBLALFRAME /* ---------- free memory ---------- */ XLALDestroyMultiREAL8TimeSeries ( mTseries ); XLALDestroyMultiSFTVector ( mSFTs ); XLALFreeMem ( &GV ); /* free the config-struct */ LALCheckMemoryLeaks(); return 0; } /* main */
// ---------- main ---------- int main ( int argc, char *argv[] ) { XLAL_CHECK ( argc == 1, XLAL_EINVAL, "No input arguments allowed.\n" ); XLAL_CHECK ( argv != NULL, XLAL_EINVAL ); // ----- load ephemeris EphemerisData *ephem; XLAL_CHECK ( (ephem = XLALInitBarycenter ( TEST_DATA_DIR "earth00-19-DE405.dat.gz", TEST_DATA_DIR "sun00-19-DE405.dat.gz" )) != NULL, XLAL_EFUNC ); // ----- setup injection and data parameters LALStringVector *detNames = NULL; XLAL_CHECK ( (detNames = XLALCreateStringVector ( "H1", "L1", NULL )) != NULL, XLAL_EFUNC ); UINT4 numDetectors = detNames->length; // generate and assume some gaussian noise floors MultiNoiseFloor XLAL_INIT_DECL(injectSqrtSX); MultiNoiseFloor XLAL_INIT_DECL(assumeSqrtSX); injectSqrtSX.length = numDetectors; assumeSqrtSX.length = numDetectors; for ( UINT4 X = 0; X < numDetectors; X ++ ) { injectSqrtSX.sqrtSn[X] = 0; // don't inject random noise to keep errors deterministic and informative (resampling differs much more on noise) assumeSqrtSX.sqrtSn[X] = 1.0 + 2.0*X; } LIGOTimeGPS startTime = {711595934, 0}; REAL8 Tspan = 20 * 3600; LIGOTimeGPS endTime = startTime; XLALGPSAdd( &endTime, Tspan ); REAL8 Tsft = 1800; LIGOTimeGPS refTime = { startTime.gpsSeconds - 2.3 * Tspan, 0 }; MultiLIGOTimeGPSVector *multiTimestamps; XLAL_CHECK ( ( multiTimestamps = XLALCalloc ( 1, sizeof(*multiTimestamps))) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( ( multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(multiTimestamps->data[0]) )) != NULL, XLAL_ENOMEM ); multiTimestamps->length = numDetectors; LIGOTimeGPS startTimeX = startTime; for ( UINT4 X=0; X < numDetectors; X ++ ) { XLAL_CHECK ( (multiTimestamps->data[X] = XLALMakeTimestamps ( startTimeX, Tspan, Tsft, 0 ) ) != NULL, XLAL_EFUNC ); XLALGPSAdd ( &startTimeX, 0.5 * Tspan ); // shift start-times by 1/2 Tspan for each detector Tspan *= 2.0; } // for X < numDetectors // shift a few timestamps around to create gaps UINT4 numSFTsPerDet = multiTimestamps->data[0]->length; multiTimestamps->data[0]->data[numSFTsPerDet-1].gpsSeconds += 10000; multiTimestamps->data[0]->data[numSFTsPerDet-2].gpsSeconds += 5000; multiTimestamps->data[1]->data[0].gpsSeconds -= 10000; multiTimestamps->data[1]->data[1].gpsSeconds -= 5000; SFTCatalog *catalog; XLAL_CHECK ( (catalog = XLALMultiAddToFakeSFTCatalog ( NULL, detNames, multiTimestamps )) != NULL, XLAL_EFUNC ); // ----- CW sources to injet ---------- REAL8 Freq = 100.0; PulsarParamsVector *injectSources; XLAL_CHECK ( (injectSources = XLALCreatePulsarParamsVector(1)) != NULL, XLAL_EFUNC ); injectSources->data[0].Amp.h0 = 1; injectSources->data[0].Amp.cosi = 0.5; injectSources->data[0].Amp.psi = 0.1; injectSources->data[0].Amp.phi0 = 1.2; REAL8 asini = 0; // 1.4; // sco-X1 like REAL8 Period = 0; // 19 * 3600;// sco-X1 like REAL8 ecc = 0; // 0.1; // much larger than ScoX1 PulsarDopplerParams XLAL_INIT_DECL(Doppler); Doppler.Alpha = 0.5; Doppler.Delta = -0.5; Doppler.fkdot[0] = Freq; Doppler.fkdot[1] = -1e-9; Doppler.refTime = refTime; Doppler.asini = asini; Doppler.ecc = ecc; Doppler.tp = startTime; Doppler.period = Period; Doppler.argp = 0.5; injectSources->data[0].Doppler = Doppler; REAL8 dFreq = 0.1 / Tspan; // 10x finer than native FFT resolution REAL8 mis = 0.5; REAL8 df1dot = sqrt( 720.0 * mis ) / (LAL_PI * Tspan * Tspan); // metric (f-projected) stepsize for given mismatch mis REAL8 dSky = 1e4 / (Freq * Tspan); // rough estimate of a 'metric' sky step, eg. Eq.(118) in \cite Prix07 REAL8 dPeriod = 3600; UINT4 numFreqBins = 1000; UINT4 numf1dotPoints = 2; UINT4 numSkyPoints = 2; UINT4 numPeriodPoints = 2; PulsarSpinRange XLAL_INIT_DECL(spinRange); spinRange.refTime = refTime; memcpy ( &spinRange.fkdot, &injectSources->data[0].Doppler.fkdot, sizeof(spinRange.fkdot) ); spinRange.fkdotBand[0] = (numFreqBins - 1)*dFreq - 10*LAL_REAL8_EPS; spinRange.fkdotBand[1] = (numf1dotPoints - 1)*df1dot - 10*LAL_REAL8_EPS; Doppler.fkdot[0] -= 0.4 * spinRange.fkdotBand[0]; REAL8 minCoverFreq, maxCoverFreq; XLAL_CHECK ( XLALCWSignalCoveringBand ( &minCoverFreq, &maxCoverFreq, &startTime, &endTime, &spinRange, asini, Period, ecc ) == XLAL_SUCCESS, XLAL_EFUNC ); // ----- setup optional Fstat arguments FstatOptionalArgs optionalArgs = FstatOptionalArgsDefaults; optionalArgs.injectSources = injectSources; optionalArgs.injectSqrtSX = &injectSqrtSX; optionalArgs.assumeSqrtSX = &assumeSqrtSX; // ----- prepare input data with injection for all available methods FstatInput *input[FMETHOD_END]; FstatResults *results[FMETHOD_END]; for ( UINT4 iMethod = FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ ) { results[iMethod] = NULL; if ( !XLALFstatMethodIsAvailable(iMethod) ) { continue; } optionalArgs.FstatMethod = iMethod; XLAL_CHECK ( (input[iMethod] = XLALCreateFstatInput ( catalog, minCoverFreq, maxCoverFreq, dFreq, ephem, &optionalArgs )) != NULL, XLAL_EFUNC ); } FstatQuantities whatToCompute = (FSTATQ_2F | FSTATQ_FAFB); // ----- loop over all templates {sky, f1dot, period} for ( UINT4 iSky = 0; iSky < numSkyPoints; iSky ++ ) { for ( UINT4 if1dot = 0; if1dot < numf1dotPoints; if1dot ++ ) { for ( UINT4 iPeriod = 0; iPeriod < numPeriodPoints; iPeriod ++ ) { // ----- loop over all available methods and compare Fstat results FstatMethodType firstMethod = FMETHOD_START; for ( UINT4 iMethod = FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ ) { if ( !XLALFstatMethodIsAvailable(iMethod) ) { continue; } if ( firstMethod == FMETHOD_START ) { // keep track of first available method found firstMethod = iMethod; } XLAL_CHECK ( XLALComputeFstat ( &results[iMethod], input[iMethod], &Doppler, numFreqBins, whatToCompute ) == XLAL_SUCCESS, XLAL_EFUNC ); if ( lalDebugLevel & LALINFOBIT ) { FILE *fp; char fname[1024]; XLAL_INIT_MEM ( fname ); snprintf ( fname, sizeof(fname)-1, "twoF%s-iSky%02d-if1dot%02d-iPeriod%02d.dat", XLALGetFstatMethodName(iMethod), iSky, if1dot, iPeriod ); XLAL_CHECK ( (fp = fopen ( fname, "wb" )) != NULL, XLAL_EFUNC ); for ( UINT4 k = 0; k < results[iMethod]->numFreqBins; k ++ ) { REAL8 Freq0 = results[iMethod]->doppler.fkdot[0]; REAL8 Freq_k = Freq0 + k * results[iMethod]->dFreq; if ( whatToCompute & FSTATQ_FAFB ) { fprintf ( fp, "%20.16g %10.4g %10.4g %10.4g %10.4g %10.4g\n", Freq_k, results[iMethod]->twoF[k], crealf(results[iMethod]->Fa[k]), cimagf(results[iMethod]->Fa[k]), crealf(results[iMethod]->Fb[k]), cimagf(results[iMethod]->Fb[k]) ); } else { fprintf ( fp, "%20.16g %10.4g\n", Freq_k, results[iMethod]->twoF[k] ); } } // for k < numFreqBins fclose(fp); } // if info // compare to first result if ( iMethod != firstMethod ) { XLALPrintInfo ("Comparing results between method '%s' and '%s'\n", XLALGetFstatMethodName(firstMethod), XLALGetFstatMethodName(iMethod) ); if ( compareFstatResults ( results[firstMethod], results[iMethod] ) != XLAL_SUCCESS ) { XLALPrintError ("Comparison between method '%s' and '%s' failed\n", XLALGetFstatMethodName(firstMethod), XLALGetFstatMethodName(iMethod) ); XLAL_ERROR ( XLAL_EFUNC ); } } } // for i < FMETHOD_END Doppler.period += dPeriod; } // for iPeriod < numPeriodPoints Doppler.fkdot[1] += df1dot; } // for if1dot < numf1dotPoints Doppler.Alpha += dSky; } // for iSky < numSkyPoints // free remaining memory for ( UINT4 iMethod=FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ ) { if ( !XLALFstatMethodIsAvailable(iMethod) ) { continue; } XLALDestroyFstatInput ( input[iMethod] ); XLALDestroyFstatResults ( results[iMethod] ); } // for i < FMETHOD_END XLALDestroyPulsarParamsVector ( injectSources ); XLALDestroySFTCatalog ( catalog ); XLALDestroyMultiTimestamps ( multiTimestamps ); XLALDestroyStringVector ( detNames ); XLALDestroyEphemerisData ( ephem ); LALCheckMemoryLeaks(); return XLAL_SUCCESS; } // main()