/// /// Read setup data from a FITS file /// int XLALWeaveSetupDataRead( FITSFile *file, WeaveSetupData *setup ) { // Check input XLAL_CHECK( file != NULL, XLAL_EFAULT ); XLAL_CHECK( setup != NULL, XLAL_EFAULT ); // Erase memory XLAL_INIT_MEM( *setup ); // Read reference time XLAL_CHECK( XLALFITSHeaderReadGPSTime( file, "date-obs", &setup->ref_time ) == XLAL_SUCCESS, XLAL_EFUNC ); // Read list of detector names XLAL_CHECK( XLALFITSHeaderReadStringVector( file, "detect", &setup->detectors ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK( setup->detectors != NULL, XLAL_EFAULT ); // Read ephemerides XLAL_CHECK( XLALFITSReadEphemerisData( file, &setup->ephemerides ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK( setup->ephemerides != NULL, XLAL_EFAULT ); // Read segment list XLAL_CHECK( XLALFITSReadSegmentList( file, "segments", &setup->segments ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK( setup->ephemerides != NULL, XLAL_EFAULT ); // Read supersky metrics XLAL_CHECK( XLALFITSReadSuperskyMetrics( file, &setup->metrics ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK( setup->metrics != NULL, XLAL_EFAULT ); return XLAL_SUCCESS; }
/** * Add given signal s_mu = M_mu_nu A^nu within the given transient-window * to multi-IFO noise-atoms. * * RETURN: SNR^2 of the injected signal * and the effective AntennaPatternMatrix M_mu_nu for this signal. */ REAL8 XLALAddSignalToMultiFstatAtomVector ( MultiFstatAtomVector* multiAtoms, /**< [in/out] multi atoms vectors containing antenna-functions and possibly noise {Fa,Fb} */ AntennaPatternMatrix *M_mu_nu, /**< [out] effective multi-IFO antenna-pattern matrix for the injected signal */ const PulsarAmplitudeVect A_Mu, /**< [in] input canonical amplitude vector A^mu = {A1,A2,A3,A4} */ transientWindow_t transientWindow, /**< [in] transient signal window */ INT4 lineX /**< [in] if >= 0: generate signal only for detector 'lineX': must be within 0,...(Ndet-1) */ ) { /* check input consistency */ if ( !multiAtoms || !multiAtoms->data ) { XLALPrintError ( "%s: Invalid NULL input 'multiAtoms'\n", __func__ ); XLAL_ERROR_REAL8 ( XLAL_EINVAL ); } if ( !M_mu_nu ) { XLALPrintError ( "%s: Invalid NULL input 'M_mu_nu'\n", __func__ ); XLAL_ERROR_REAL8 ( XLAL_EINVAL ); } UINT4 numDet = multiAtoms->length; XLAL_CHECK ( (lineX < 0) || ((UINT4)lineX < numDet), XLAL_EINVAL, "Inconsistent input of lineX = %d, not within 0 ... Ndet-1 (= %d)\n", lineX, numDet ); UINT4 X; REAL8 rho2 = 0; XLAL_INIT_MEM( (*M_mu_nu)); for ( X=0; X < numDet; X ++ ) { REAL8 rho2X; AntennaPatternMatrix M_mu_nu_X; PulsarAmplitudeVect A0_Mu = {0,0,0,0}; // zero amplitude signal for simulating single-IFO line if ( (lineX >= 0) && ((UINT4)lineX != X) ) { rho2X = XLALAddSignalToFstatAtomVector ( multiAtoms->data[X], &M_mu_nu_X, A0_Mu, transientWindow ); // zero-signal injection } else { rho2X = XLALAddSignalToFstatAtomVector ( multiAtoms->data[X], &M_mu_nu_X, A_Mu, transientWindow ); // actual signal injection } XLAL_CHECK_REAL8 ( xlalErrno == 0, XLAL_EFUNC ); rho2 += rho2X; /* multi-IFO SNR^2 = sum_X SNR_X^2 */ M_mu_nu->Ad += M_mu_nu_X.Ad; /* multi-IFO M_mu_nu = sum_X M_mu_nu_X */ M_mu_nu->Bd += M_mu_nu_X.Bd; M_mu_nu->Cd += M_mu_nu_X.Cd; M_mu_nu->Sinv_Tsft += M_mu_nu_X.Sinv_Tsft; /* noise adds harmonically 1/S = sum_X (1/S_X) */ } /* for X < numDet */ /* update sub-determinant */ M_mu_nu->Dd = M_mu_nu->Ad * M_mu_nu->Bd - SQ(M_mu_nu->Cd); /* return SNR^2 */ return rho2; } /* XLALAddSignalToMultiFstatAtomVector() */
// ----- local function definitions ---------- static int XLALComputeFstatDemod ( FstatResults* Fstats, const FstatCommon *common, void *method_data ) { // Check input XLAL_CHECK(Fstats != NULL, XLAL_EFAULT); XLAL_CHECK(common != NULL, XLAL_EFAULT); XLAL_CHECK(method_data != NULL, XLAL_EFAULT); DemodMethodData *demod = (DemodMethodData*) method_data; // get internal timing info DemodTimingInfo *ti = &(demod->timingInfo); REAL8 tic = 0, toc = 0; // Get which F-statistic quantities to compute const FstatQuantities whatToCompute = Fstats->whatWasComputed; // handy shortcuts BOOLEAN returnAtoms = (whatToCompute & FSTATQ_ATOMS_PER_DET); PulsarDopplerParams thisPoint = Fstats->doppler; const REAL8 fStart = thisPoint.fkdot[0]; const MultiSFTVector *multiSFTs = demod->multiSFTs; const MultiNoiseWeights *multiWeights = common->multiNoiseWeights; const MultiDetectorStateSeries *multiDetStates = common->multiDetectorStates; UINT4 numDetectors = multiSFTs->length; XLAL_CHECK ( multiDetStates->length == numDetectors, XLAL_EINVAL ); XLAL_CHECK ( multiWeights==NULL || (multiWeights->length == numDetectors), XLAL_EINVAL ); UINT4 numSFTs = 0; for ( UINT4 X = 0; X < numDetectors; X ++ ) { numSFTs += multiDetStates->data[X]->length; } // initialize timing info struct if ( ti->collectTiming ) { XLAL_INIT_MEM ( (*ti) ); ti->collectTiming = 1; ti->numDetectors = numDetectors; ti->numFreqBins = Fstats->numFreqBins; ti->numSFTs = numSFTs; tic = XLALGetCPUTime(); } MultiSSBtimes *multiSSB = NULL; MultiAMCoeffs *multiAMcoef = NULL; // ----- check if we have buffered SSB+AMcoef for current sky-position if ( (demod->prevAlpha == thisPoint.Alpha) && (demod->prevDelta == thisPoint.Delta ) && (demod->prevMultiSSBtimes != NULL) && ( XLALGPSDiff(&demod->prevRefTime, &thisPoint.refTime) == 0 ) && // have SSB times for same reftime? (demod->prevMultiAMcoef != NULL) ) { // if yes ==> reuse multiSSB = demod->prevMultiSSBtimes; multiAMcoef = demod->prevMultiAMcoef; } else { // if not, compute SSB + AMcoef for this skyposition SkyPosition skypos; skypos.system = COORDINATESYSTEM_EQUATORIAL; skypos.longitude = thisPoint.Alpha; skypos.latitude = thisPoint.Delta; XLAL_CHECK ( (multiSSB = XLALGetMultiSSBtimes ( multiDetStates, skypos, thisPoint.refTime, common->SSBprec )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (multiAMcoef = XLALComputeMultiAMCoeffs ( multiDetStates, multiWeights, skypos )) != NULL, XLAL_EFUNC ); // store these for possible later re-use in buffer XLALDestroyMultiSSBtimes ( demod->prevMultiSSBtimes ); demod->prevMultiSSBtimes = multiSSB; demod->prevRefTime = thisPoint.refTime; XLALDestroyMultiAMCoeffs ( demod->prevMultiAMcoef ); demod->prevMultiAMcoef = multiAMcoef; demod->prevAlpha = thisPoint.Alpha; demod->prevDelta = thisPoint.Delta; } // if could not reuse previously buffered quantites MultiSSBtimes *multiBinary = NULL; MultiSSBtimes *multiSSBTotal = NULL; // handle binary-orbital timing corrections, if applicable if ( thisPoint.asini > 0 ) { // compute binary time corrections to the SSB time delays and SSB time derivitive XLAL_CHECK ( XLALAddMultiBinaryTimes ( &multiBinary, multiSSB, &thisPoint ) == XLAL_SUCCESS, XLAL_EFUNC ); multiSSBTotal = multiBinary; } else { multiSSBTotal = multiSSB; } if ( ti->collectTiming ) { toc = XLALGetCPUTime(); ti->tauBary = (toc - tic); } // ----- compute final Fstatistic-value ----- REAL4 Ad = multiAMcoef->Mmunu.Ad; REAL4 Bd = multiAMcoef->Mmunu.Bd; REAL4 Cd = multiAMcoef->Mmunu.Cd; REAL4 Ed = multiAMcoef->Mmunu.Ed;; REAL4 Dd_inv = 1.0 / multiAMcoef->Mmunu.Dd; // ---------- Compute F-stat for each frequency bin ---------- for ( UINT4 k = 0; k < Fstats->numFreqBins; k++ ) { // Set frequency to search at thisPoint.fkdot[0] = fStart + k * Fstats->dFreq; COMPLEX8 Fa = 0; // complex amplitude Fa COMPLEX8 Fb = 0; // complex amplitude Fb MultiFstatAtomVector *multiFstatAtoms = NULL; // per-IFO, per-SFT arrays of F-stat 'atoms', ie quantities required to compute F-stat // prepare return of 'FstatAtoms' if requested if ( returnAtoms ) { XLAL_CHECK ( (multiFstatAtoms = XLALMalloc ( sizeof(*multiFstatAtoms) )) != NULL, XLAL_ENOMEM ); multiFstatAtoms->length = numDetectors; XLAL_CHECK ( (multiFstatAtoms->data = XLALMalloc ( numDetectors * sizeof(*multiFstatAtoms->data) )) != NULL, XLAL_ENOMEM ); } // if returnAtoms // loop over detectors and compute all detector-specific quantities for ( UINT4 X=0; X < numDetectors; X ++) { COMPLEX8 FaX, FbX; FstatAtomVector *FstatAtoms = NULL; FstatAtomVector **FstatAtoms_p = returnAtoms ? (&FstatAtoms) : NULL; // call XLALComputeFaFb_...() function for the user-requested hotloop variant XLAL_CHECK ( (demod->computefafb_func) ( &FaX, &FbX, FstatAtoms_p, multiSFTs->data[X], thisPoint.fkdot, multiSSBTotal->data[X], multiAMcoef->data[X], demod->Dterms ) == XLAL_SUCCESS, XLAL_EFUNC ); if ( returnAtoms ) { multiFstatAtoms->data[X] = FstatAtoms; // copy pointer to IFO-specific Fstat-atoms 'contents' } XLAL_CHECK ( isfinite(creal(FaX)) && isfinite(cimag(FaX)) && isfinite(creal(FbX)) && isfinite(cimag(FbX)), XLAL_EFPOVRFLW ); if ( whatToCompute & FSTATQ_FAFB_PER_DET ) { Fstats->FaPerDet[X][k] = FaX; Fstats->FbPerDet[X][k] = FbX; } // compute single-IFO F-stats, if requested if ( whatToCompute & FSTATQ_2F_PER_DET ) { REAL4 AdX = multiAMcoef->data[X]->A; REAL4 BdX = multiAMcoef->data[X]->B; REAL4 CdX = multiAMcoef->data[X]->C; REAL4 EdX = 0; REAL4 DdX_inv = 1.0 / multiAMcoef->data[X]->D; // compute final single-IFO F-stat Fstats->twoFPerDet[X][k] = XLALComputeFstatFromFaFb ( FaX, FbX, AdX, BdX, CdX, EdX, DdX_inv ); } // if FSTATQ_2F_PER_DET /* Fa = sum_X Fa_X */ Fa += FaX; /* Fb = sum_X Fb_X */ Fb += FbX; } // for X < numDetectors if ( whatToCompute & FSTATQ_2F ) { Fstats->twoF[k] = XLALComputeFstatFromFaFb ( Fa, Fb, Ad, Bd, Cd, Ed, Dd_inv ); } // Return multi-detector Fa & Fb if ( whatToCompute & FSTATQ_FAFB ) { Fstats->Fa[k] = Fa; Fstats->Fb[k] = Fb; } // Return F-atoms per detector if ( whatToCompute & FSTATQ_ATOMS_PER_DET ) { XLALDestroyMultiFstatAtomVector ( Fstats->multiFatoms[k] ); Fstats->multiFatoms[k] = multiFstatAtoms; } } // for k < Fstats->numFreqBins // this needs to be free'ed, as it's currently not buffered XLALDestroyMultiSSBtimes ( multiBinary ); // Return amplitude modulation coefficients Fstats->Mmunu = demod->prevMultiAMcoef->Mmunu; // return per-detector antenna-pattern matrices for ( UINT4 X=0; X < numDetectors; X ++ ) { Fstats->MmunuX[X].Ad = multiAMcoef->data[X]->A; Fstats->MmunuX[X].Bd = multiAMcoef->data[X]->B; Fstats->MmunuX[X].Cd = multiAMcoef->data[X]->C; Fstats->MmunuX[X].Dd = multiAMcoef->data[X]->D; Fstats->MmunuX[X].Ed = 0; } if ( ti->collectTiming ) { toc = XLALGetCPUTime(); ti->tauTotal = (toc - tic); ti->tauF1NoBuf = ti->tauTotal / ( Fstats->numFreqBins * numDetectors ); ti->tauF1Buf = (ti->tauTotal - ti->tauBary) / ( Fstats->numFreqBins * numDetectors ); } return XLAL_SUCCESS; } // XLALComputeFstatDemod()
int main(int argc, char *argv[]){ UserInput_t XLAL_INIT_DECL(uvar); static ConfigVariables config; /* sft related variables */ MultiSFTVector *inputSFTs = NULL; MultiPSDVector *multiPSDs = NULL; MultiNoiseWeights *multiWeights = NULL; MultiLIGOTimeGPSVector *multiTimes = NULL; MultiLALDetector multiDetectors; MultiDetectorStateSeries *multiStates = NULL; MultiAMCoeffs *multiCoeffs = NULL; SFTIndexList *sftIndices = NULL; SFTPairIndexList *sftPairs = NULL; REAL8Vector *shiftedFreqs = NULL; UINT4Vector *lowestBins = NULL; COMPLEX8Vector *expSignalPhases = NULL; REAL8VectorSequence *sincList = NULL; PulsarDopplerParams XLAL_INIT_DECL(dopplerpos); PulsarDopplerParams thisBinaryTemplate, binaryTemplateSpacings; PulsarDopplerParams minBinaryTemplate, maxBinaryTemplate; SkyPosition XLAL_INIT_DECL(skyPos); MultiSSBtimes *multiBinaryTimes = NULL; INT4 k; UINT4 j; REAL8 fMin, fMax; /* min and max frequencies read from SFTs */ REAL8 deltaF; /* frequency resolution associated with time baseline of SFTs */ REAL8 diagff = 0; /*diagonal metric components*/ REAL8 diagaa = 0; REAL8 diagTT = 0; REAL8 diagpp = 1; REAL8 ccStat = 0; REAL8 evSquared=0; REAL8 estSens=0; /*estimated sensitivity(4.13)*/ BOOLEAN dopplerShiftFlag = TRUE; toplist_t *ccToplist=NULL; CrossCorrBinaryOutputEntry thisCandidate; UINT4 checksum; LogPrintf (LOG_CRITICAL, "Starting time\n"); /*for debug convenience to record calculating time*/ /* initialize and register user variables */ LIGOTimeGPS computingStartGPSTime, computingEndGPSTime; XLALGPSTimeNow (&computingStartGPSTime); /* record the rough starting GPS time*/ if ( XLALInitUserVars( &uvar ) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read user input from the command line or config file */ if ( XLALUserVarReadAllInput ( argc, argv ) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALUserVarReadAllInput() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if (uvar.help) /* if help was requested, then exit */ return 0; CHAR *VCSInfoString = XLALGetVersionString(0); /**<LAL + LALapps Vsersion string*/ /*If the version information was requested, output it and exit*/ if ( uvar.version ){ XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); printf ("%s\n", VCSInfoString ); exit (0); } /* configure useful variables based on user input */ if ( XLALInitializeConfigVars ( &config, &uvar) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } deltaF = config.catalog->data[0].header.deltaF; REAL8 Tsft = 1.0 / deltaF; if (XLALUserVarWasSet(&uvar.spacingF) && XLALUserVarWasSet(&uvar.mismatchF)) LogPrintf (LOG_CRITICAL, "spacingF and mismatchF are both set, use spacingF %.9g by default\n\n", uvar.spacingF); if (XLALUserVarWasSet(&uvar.spacingA) && XLALUserVarWasSet(&uvar.mismatchA)) LogPrintf (LOG_CRITICAL, "spacingA and mismatchA are both set, use spacingA %.9g by default\n\n", uvar.spacingA); if (XLALUserVarWasSet(&uvar.spacingT) && XLALUserVarWasSet(&uvar.mismatchT)) LogPrintf (LOG_CRITICAL, "spacingT and mismatchT are both set, use spacingT %.9g by default\n\n", uvar.spacingT); if (XLALUserVarWasSet(&uvar.spacingP) && XLALUserVarWasSet(&uvar.mismatchP)) LogPrintf (LOG_CRITICAL, "spacingP and mismatchP are both set, use spacingP %.9g by default\n\n", uvar.spacingP); /* create the toplist */ create_crossCorrBinary_toplist( &ccToplist, uvar.numCand); /* now read the data */ /* /\* get SFT parameters so that we can initialise search frequency resolutions *\/ */ /* /\* calculate deltaF_SFT *\/ */ /* deltaF_SFT = catalog->data[0].header.deltaF; /\* frequency resolution *\/ */ /* timeBase= 1.0/deltaF_SFT; /\* sft baseline *\/ */ /* /\* catalog is ordered in time so we can get start, end time and tObs *\/ */ /* firstTimeStamp = catalog->data[0].header.epoch; */ /* lastTimeStamp = catalog->data[catalog->length - 1].header.epoch; */ /* tObs = XLALGPSDiff( &lastTimeStamp, &firstTimeStamp ) + timeBase; */ /* /\*set pulsar reference time *\/ */ /* if (LALUserVarWasSet ( &uvar_refTime )) { */ /* XLALGPSSetREAL8(&refTime, uvar_refTime); */ /* } */ /* else { /\*if refTime is not set, set it to midpoint of sfts*\/ */ /* XLALGPSSetREAL8(&refTime, (0.5*tObs) + XLALGPSGetREAL8(&firstTimeStamp)); */ /* } */ /* /\* set frequency resolution defaults if not set by user *\/ */ /* if (!(LALUserVarWasSet (&uvar_fResolution))) { */ /* uvar_fResolution = 1/tObs; */ /* } */ /* { */ /* /\* block for calculating frequency range to read from SFTs *\/ */ /* /\* user specifies freq and fdot range at reftime */ /* we translate this range of fdots to start and endtime and find */ /* the largest frequency band required to cover the */ /* frequency evolution *\/ */ /* PulsarSpinRange spinRange_startTime; /\**< freq and fdot range at start-time of observation *\/ */ /* PulsarSpinRange spinRange_endTime; /\**< freq and fdot range at end-time of observation *\/ */ /* PulsarSpinRange spinRange_refTime; /\**< freq and fdot range at the reference time *\/ */ /* REAL8 startTime_freqLo, startTime_freqHi, endTime_freqLo, endTime_freqHi, freqLo, freqHi; */ /* REAL8Vector *fdotsMin=NULL; */ /* REAL8Vector *fdotsMax=NULL; */ /* UINT4 k; */ /* fdotsMin = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */ /* fdotsMin->length = N_SPINDOWN_DERIVS; */ /* fdotsMin->data = (REAL8 *)LALCalloc(fdotsMin->length, sizeof(REAL8)); */ /* fdotsMax = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */ /* fdotsMax->length = N_SPINDOWN_DERIVS; */ /* fdotsMax->data = (REAL8 *)LALCalloc(fdotsMax->length, sizeof(REAL8)); */ /* XLAL_INIT_MEM(spinRange_startTime); */ /* XLAL_INIT_MEM(spinRange_endTime); */ /* XLAL_INIT_MEM(spinRange_refTime); */ /* spinRange_refTime.refTime = refTime; */ /* spinRange_refTime.fkdot[0] = uvar_f0; */ /* spinRange_refTime.fkdotBand[0] = uvar_fBand; */ /* } */ /* FIXME: need to correct fMin and fMax for Doppler shift, rngmedian bins and spindown range */ /* this is essentially just a place holder for now */ /* FIXME: this running median buffer is overkill, since the running median block need not be centered on the search frequency */ REAL8 vMax = LAL_TWOPI * (uvar.orbitAsiniSec + uvar.orbitAsiniSecBand) / uvar.orbitPSec + LAL_TWOPI * LAL_REARTH_SI / (LAL_DAYSID_SI * LAL_C_SI) + LAL_TWOPI * LAL_AU_SI/(LAL_YRSID_SI * LAL_C_SI); /*calculate the maximum relative velocity in speed of light*/ fMin = uvar.fStart * (1 - vMax) - 0.5 * uvar.rngMedBlock * deltaF; fMax = (uvar.fStart + uvar.fBand) * (1 + vMax) + 0.5 * uvar.rngMedBlock * deltaF; /* read the SFTs*/ if ((inputSFTs = XLALLoadMultiSFTs ( config.catalog, fMin, fMax)) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALLoadMultiSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* calculate the psd and normalize the SFTs */ if (( multiPSDs = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.rngMedBlock, NULL )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALNormalizeMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* compute the noise weights for the AM coefficients */ if (( multiWeights = XLALComputeMultiNoiseWeights ( multiPSDs, uvar.rngMedBlock, 0 )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiNoiseWeights() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read the timestamps from the SFTs */ if ((multiTimes = XLALExtractMultiTimestampsFromSFTs ( inputSFTs )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALExtractMultiTimestampsFromSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read the detector information from the SFTs */ if ( XLALMultiLALDetectorFromMultiSFTs ( &multiDetectors, inputSFTs ) != XLAL_SUCCESS){ LogPrintf ( LOG_CRITICAL, "%s: XLALMultiLALDetectorFromMultiSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Find the detector state for each SFT */ /* Offset by Tsft/2 to get midpoint as timestamp */ if ((multiStates = XLALGetMultiDetectorStates ( multiTimes, &multiDetectors, config.edat, 0.5 * Tsft )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiDetectorStates() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Note this is specialized to a single sky position */ /* This might need to be moved into the config variables */ skyPos.system = COORDINATESYSTEM_EQUATORIAL; skyPos.longitude = uvar.alphaRad; skyPos.latitude = uvar.deltaRad; /* Calculate the AM coefficients (a,b) for each SFT */ if ((multiCoeffs = XLALComputeMultiAMCoeffs ( multiStates, multiWeights, skyPos )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiAMCoeffs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Construct the flat list of SFTs (this sort of replicates the catalog, but there's not an obvious way to get the information back) */ if ( ( XLALCreateSFTIndexListFromMultiSFTVect( &sftIndices, inputSFTs ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTIndexListFromMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Construct the list of SFT pairs */ #define PCC_SFTPAIR_HEADER "# The length of SFT-pair list is %u #\n" #define PCC_SFTPAIR_BODY "%u %u\n" #define PCC_SFT_HEADER "# The length of SFT list is %u #\n" #define PCC_SFT_BODY "%s %d %d\n" FILE *fp = NULL; if (XLALUserVarWasSet(&uvar.pairListInputFilename)) { /* If the user provided a list for reading, use it */ if((sftPairs = XLALCalloc(1, sizeof(sftPairs))) == NULL){ XLAL_ERROR(XLAL_ENOMEM); } if((fp = fopen(uvar.pairListInputFilename, "r")) == NULL){ LogPrintf ( LOG_CRITICAL, "didn't find SFT-pair list file with given input name\n"); XLAL_ERROR( XLAL_EFUNC ); } if(fscanf(fp,PCC_SFTPAIR_HEADER,&sftPairs->length)==EOF){ LogPrintf ( LOG_CRITICAL, "can't read the length of SFT-pair list from the header\n"); XLAL_ERROR( XLAL_EFUNC ); } if((sftPairs->data = XLALCalloc(sftPairs->length, sizeof(*sftPairs->data)))==NULL){ XLALFree(sftPairs); XLAL_ERROR(XLAL_ENOMEM); } for(j = 0; j < sftPairs->length; j++){ /*read in the SFT-pair list */ if(fscanf(fp,PCC_SFTPAIR_BODY, &sftPairs->data[j].sftNum[0], &sftPairs->data[j].sftNum[1])==EOF){ LogPrintf ( LOG_CRITICAL, "The length of SFT-pair list doesn't match!"); XLAL_ERROR( XLAL_EFUNC ); } } fclose(fp); } else { /* if not, construct the list of pairs */ if ( ( XLALCreateSFTPairIndexList( &sftPairs, sftIndices, inputSFTs, uvar.maxLag, uvar.inclAutoCorr ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTPairIndexList() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } } if (XLALUserVarWasSet(&uvar.pairListOutputFilename)) { /* Write the list of pairs to a file, if a name was provided */ if((fp = fopen(uvar.pairListOutputFilename, "w")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in SFT-pair list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_SFTPAIR_HEADER, sftPairs->length ); /*output the length of SFT-pair list to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_SFTPAIR_BODY, sftPairs->data[j].sftNum[0], sftPairs->data[j].sftNum[1]); } fclose(fp); } if (XLALUserVarWasSet(&uvar.sftListOutputFilename)) { /* Write the list of SFTs to a file for sanity-checking purposes */ if((fp = fopen(uvar.sftListOutputFilename, "w")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in flat SFT list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_SFT_HEADER, sftIndices->length ); /*output the length of SFT list to the header*/ for(j = 0; j < sftIndices->length; j++){ /*output the SFT list */ fprintf(fp,PCC_SFT_BODY, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds); } fclose(fp); } else if(XLALUserVarWasSet(&uvar.sftListInputFilename)){ /*do a sanity check of the order of SFTs list if the name of input SFT list is given*/ UINT4 numofsft=0; if((fp = fopen(uvar.sftListInputFilename, "r")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't read in flat SFT list \n"); XLAL_ERROR( XLAL_EFUNC ); } if (fscanf(fp, PCC_SFT_HEADER, &numofsft)==EOF){ LogPrintf ( LOG_CRITICAL, "can't read in the length of SFT list from header\n"); XLAL_ERROR( XLAL_EFUNC ); } CHARVectorSequence *checkDet=NULL; if ((checkDet = XLALCreateCHARVectorSequence (numofsft, LALNameLength) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateCHARVector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } INT4 checkGPS[numofsft], checkGPSns[numofsft]; if(numofsft == sftIndices->length){ for (j=0; j<numofsft; j++){ if( fscanf(fp,PCC_SFT_BODY,&checkDet->data[j * LALNameLength], &checkGPS[j], &checkGPSns[j])==EOF){ LogPrintf ( LOG_CRITICAL, "The length of SFT list doesn't match\n"); XLAL_ERROR( XLAL_EFUNC ); } if(strcmp( inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, &checkDet->data[j * LALNameLength] ) != 0 ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds != checkGPS[j] ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds != checkGPSns[j] ){ LogPrintf ( LOG_CRITICAL, "The order of SFTs has been changed, it's the end of civilization\n"); XLAL_ERROR( XLAL_EFUNC ); } } fclose(fp); XLALDestroyCHARVectorSequence(checkDet); } else{ LogPrintf ( LOG_CRITICAL, "Run for your life, the length of SFT list doesn't match"); XLAL_ERROR( XLAL_EFUNC ); } } else { } /* Get weighting factors for calculation of metric */ /* note that the sigma-squared is now absorbed into the curly G because the AM coefficients are noise-weighted. */ REAL8Vector *GammaAve = NULL; REAL8Vector *GammaCirc = NULL; if ( ( XLALCalculateCrossCorrGammas( &GammaAve, &GammaCirc, sftPairs, sftIndices, multiCoeffs) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrGammas() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } #define PCC_GAMMA_HEADER "# The normalization Sinv_Tsft is %g #\n" #define PCC_GAMMA_BODY "%.10g\n" if (XLALUserVarWasSet(&uvar.gammaAveOutputFilename)) { /* Write the aa+bb weight for each pair to a file, if a name was provided */ if((fp = fopen(uvar.gammaAveOutputFilename, "w")) == NULL) { LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_ave list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_GAMMA_BODY, GammaAve->data[j]); } fclose(fp); } if (XLALUserVarWasSet(&uvar.gammaCircOutputFilename)) { /* Write the ab-ba weight for each pair to a file, if a name was provided */ if((fp = fopen(uvar.gammaCircOutputFilename, "w")) == NULL) { LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_circ list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_GAMMA_BODY, GammaCirc->data[j]); } fclose(fp); } /*initialize binary parameters structure*/ XLAL_INIT_MEM(minBinaryTemplate); XLAL_INIT_MEM(maxBinaryTemplate); XLAL_INIT_MEM(thisBinaryTemplate); XLAL_INIT_MEM(binaryTemplateSpacings); /*fill in minbinaryOrbitParams*/ XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc); minBinaryTemplate.argp = 0.0; minBinaryTemplate.asini = uvar.orbitAsiniSec; minBinaryTemplate.ecc = 0.0; minBinaryTemplate.period = uvar.orbitPSec; minBinaryTemplate.fkdot[0] = uvar.fStart; /*fill in maxBinaryParams*/ XLALGPSSetREAL8( &maxBinaryTemplate.tp, uvar.orbitTimeAsc + uvar.orbitTimeAscBand); maxBinaryTemplate.argp = 0.0; maxBinaryTemplate.asini = uvar.orbitAsiniSec + uvar.orbitAsiniSecBand; maxBinaryTemplate.ecc = 0.0; maxBinaryTemplate.period = uvar.orbitPSec; maxBinaryTemplate.fkdot[0] = uvar.fStart + uvar.fBand; /*fill in thisBinaryTemplate*/ XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * uvar.orbitTimeAscBand); thisBinaryTemplate.argp = 0.0; thisBinaryTemplate.asini = 0.5*(minBinaryTemplate.asini + maxBinaryTemplate.asini); thisBinaryTemplate.ecc = 0.0; thisBinaryTemplate.period =0.5*(minBinaryTemplate.period + maxBinaryTemplate.period); thisBinaryTemplate.fkdot[0]=0.5*(minBinaryTemplate.fkdot[0] + maxBinaryTemplate.fkdot[0]); /*Get metric diagonal components, also estimate sensitivity i.e. E[rho]/(h0)^2 (4.13)*/ if ( (XLALCalculateLMXBCrossCorrDiagMetric(&estSens, &diagff, &diagaa, &diagTT, thisBinaryTemplate, GammaAve, sftPairs, sftIndices, inputSFTs, multiWeights /*, kappaValues*/) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateLMXBCrossCorrDiagMetric() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* spacing in frequency from diagff */ /* set spacings in new dopplerparams struct */ if (XLALUserVarWasSet(&uvar.spacingF)) /* If spacing was given by CMD line, use it, else calculate spacing by mismatch*/ binaryTemplateSpacings.fkdot[0] = uvar.spacingF; else binaryTemplateSpacings.fkdot[0] = sqrt(uvar.mismatchF / diagff); if (XLALUserVarWasSet(&uvar.spacingA)) binaryTemplateSpacings.asini = uvar.spacingA; else binaryTemplateSpacings.asini = sqrt(uvar.mismatchA / diagaa); /* this is annoying: tp is a GPS time while we want a difference in time which should be just REAL8 */ if (XLALUserVarWasSet(&uvar.spacingT)) XLALGPSSetREAL8( &binaryTemplateSpacings.tp, uvar.spacingT); else XLALGPSSetREAL8( &binaryTemplateSpacings.tp, sqrt(uvar.mismatchT / diagTT)); if (XLALUserVarWasSet(&uvar.spacingP)) binaryTemplateSpacings.period = uvar.spacingP; else binaryTemplateSpacings.period = sqrt(uvar.mismatchP / diagpp); /* metric elements for eccentric case not considered? */ UINT8 fCount = 0, aCount = 0, tCount = 0 , pCount = 0; const UINT8 fSpacingNum = floor( uvar.fBand / binaryTemplateSpacings.fkdot[0]); const UINT8 aSpacingNum = floor( uvar.orbitAsiniSecBand / binaryTemplateSpacings.asini); const UINT8 tSpacingNum = floor( uvar.orbitTimeAscBand / XLALGPSGetREAL8(&binaryTemplateSpacings.tp)); const UINT8 pSpacingNum = floor( uvar.orbitPSecBand / binaryTemplateSpacings.period); /*reset minbinaryOrbitParams to shift the first point a factor so as to make the center of all seaching points centers at the center of searching band*/ minBinaryTemplate.fkdot[0] = uvar.fStart + 0.5 * (uvar.fBand - fSpacingNum * binaryTemplateSpacings.fkdot[0]); minBinaryTemplate.asini = uvar.orbitAsiniSec + 0.5 * (uvar.orbitAsiniSecBand - aSpacingNum * binaryTemplateSpacings.asini); XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * (uvar.orbitTimeAscBand - tSpacingNum * XLALGPSGetREAL8(&binaryTemplateSpacings.tp))); minBinaryTemplate.period = uvar.orbitPSec + 0.5 * (uvar.orbitPSecBand - pSpacingNum * binaryTemplateSpacings.period); /* initialize the doppler scan struct which stores the current template information */ XLALGPSSetREAL8(&dopplerpos.refTime, config.refTime); dopplerpos.Alpha = uvar.alphaRad; dopplerpos.Delta = uvar.deltaRad; dopplerpos.fkdot[0] = minBinaryTemplate.fkdot[0]; /* set all spindowns to zero */ for (k=1; k < PULSAR_MAX_SPINS; k++) dopplerpos.fkdot[k] = 0.0; dopplerpos.asini = minBinaryTemplate.asini; dopplerpos.period = minBinaryTemplate.period; dopplerpos.tp = minBinaryTemplate.tp; dopplerpos.ecc = minBinaryTemplate.ecc; dopplerpos.argp = minBinaryTemplate.argp; /* now set the initial values of binary parameters */ /* thisBinaryTemplate.asini = uvar.orbitAsiniSec; thisBinaryTemplate.period = uvar.orbitPSec; XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc); thisBinaryTemplate.ecc = 0.0; thisBinaryTemplate.argp = 0.0;*/ /* copy to dopplerpos */ /* Calculate SSB times (can do this once since search is currently only for one sky position, and binary doppler shift is added later) */ MultiSSBtimes *multiSSBTimes = NULL; if ((multiSSBTimes = XLALGetMultiSSBtimes ( multiStates, skyPos, dopplerpos.refTime, SSBPREC_RELATIVISTICOPT )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* "New" general metric computation */ /* For now hard-code circular parameter space */ const DopplerCoordinateSystem coordSys = { .dim = 4, .coordIDs = { DOPPLERCOORD_FREQ, DOPPLERCOORD_ASINI, DOPPLERCOORD_TASC, DOPPLERCOORD_PORB, }, }; REAL8VectorSequence *phaseDerivs = NULL; if ( ( XLALCalculateCrossCorrPhaseDerivatives ( &phaseDerivs, &thisBinaryTemplate, config.edat, sftIndices, multiSSBTimes, &coordSys ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseDerivatives() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* fill in metric and parameter offsets */ gsl_matrix *g_ij = NULL; gsl_vector *eps_i = NULL; REAL8 sumGammaSq = 0; if ( ( XLALCalculateCrossCorrPhaseMetric ( &g_ij, &eps_i, &sumGammaSq, phaseDerivs, sftPairs, GammaAve, GammaCirc, &coordSys ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseMetric() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } XLALDestroyREAL8VectorSequence ( phaseDerivs ); XLALDestroyREAL8Vector ( GammaCirc ); if ((fp = fopen("gsldata.dat","w"))==NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in gsl matrix file"); XLAL_ERROR( XLAL_EFUNC ); } XLALfprintfGSLvector(fp, "%g", eps_i); XLALfprintfGSLmatrix(fp, "%g", g_ij); /* Allocate structure for binary doppler-shifting information */ if ((multiBinaryTimes = XLALDuplicateMultiSSBtimes ( multiSSBTimes )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALDuplicateMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } UINT8 numSFTs = sftIndices->length; if ((shiftedFreqs = XLALCreateREAL8Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((lowestBins = XLALCreateUINT4Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateUINT4Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((expSignalPhases = XLALCreateCOMPLEX8Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((sincList = XLALCreateREAL8VectorSequence ( numSFTs, uvar.numBins ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8VectorSequence() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* args should be : spacings, min and max doppler params */ BOOLEAN firstPoint = TRUE; /* a boolean to help to search at the beginning point in parameter space, after the search it is set to be FALSE to end the loop*/ if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /*Need to apply additional doppler shifting before the loop, or the first point in parameter space will be lost and return a wrong SNR when fBand!=0*/ while ( GetNextCrossCorrTemplate(&dopplerShiftFlag, &firstPoint, &dopplerpos, &binaryTemplateSpacings, &minBinaryTemplate, &maxBinaryTemplate, &fCount, &aCount, &tCount, &pCount, fSpacingNum, aSpacingNum, tSpacingNum, pSpacingNum) == 0) { /* do useful stuff here*/ /* Apply additional Doppler shifting using current binary orbital parameters */ /* Might want to be clever about checking whether we've changed the orbital parameters or only the frequency */ if (dopplerShiftFlag == TRUE) { if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } } if ( (XLALGetDopplerShiftedFrequencyInfo( shiftedFreqs, lowestBins, expSignalPhases, sincList, uvar.numBins, &dopplerpos, sftIndices, inputSFTs, multiBinaryTimes, Tsft ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALGetDopplerShiftedFrequencyInfo() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ( (XLALCalculatePulsarCrossCorrStatistic( &ccStat, &evSquared, GammaAve, expSignalPhases, lowestBins, sincList, sftPairs, sftIndices, inputSFTs, multiWeights, uvar.numBins) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculatePulsarCrossCorrStatistic() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* fill candidate struct and insert into toplist if necessary */ thisCandidate.freq = dopplerpos.fkdot[0]; thisCandidate.tp = XLALGPSGetREAL8( &dopplerpos.tp ); thisCandidate.argp = dopplerpos.argp; thisCandidate.asini = dopplerpos.asini; thisCandidate.ecc = dopplerpos.ecc; thisCandidate.period = dopplerpos.period; thisCandidate.rho = ccStat; thisCandidate.evSquared = evSquared; thisCandidate.estSens = estSens; insert_into_crossCorrBinary_toplist(ccToplist, thisCandidate); } /* end while loop over templates */ /* write candidates to file */ sort_crossCorrBinary_toplist( ccToplist ); /* add error checking */ final_write_crossCorrBinary_toplist_to_file( ccToplist, uvar.toplistFilename, &checksum); REAL8 h0Sens = sqrt((10 / sqrt(estSens))); /*for a SNR=10 signal, the h0 we can detect*/ XLALGPSTimeNow (&computingEndGPSTime); /*record the rough end time*/ UINT4 computingTime = computingEndGPSTime.gpsSeconds - computingStartGPSTime.gpsSeconds; /* make a meta-data file*/ if(XLALUserVarWasSet(&uvar.logFilename)){ CHAR *CMDInputStr = XLALUserVarGetLog ( UVAR_LOGFMT_CFGFILE ); if ((fp = fopen(uvar.logFilename,"w"))==NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in logfile"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp, "[UserInput]\n\n"); fprintf(fp, "%s\n", CMDInputStr); fprintf(fp, "[CalculatedValues]\n\n"); fprintf(fp, "g_ff = %.9f\n", diagff ); fprintf(fp, "g_aa = %.9f\n", diagaa ); fprintf(fp, "g_TT = %.9f\n", diagTT ); fprintf(fp, "FSpacing = %.9g\n", binaryTemplateSpacings.fkdot[0]); fprintf(fp, "ASpacing = %.9g\n", binaryTemplateSpacings.asini); fprintf(fp, "TSpacing = %.9g\n", XLALGPSGetREAL8(&binaryTemplateSpacings.tp)); /* fprintf(fp, "PSpacing = %.9g\n", binaryTemplateSpacings.period );*/ fprintf(fp, "TemplatenumF = %" LAL_UINT8_FORMAT "\n", (fSpacingNum + 1)); fprintf(fp, "TemplatenumA = %" LAL_UINT8_FORMAT "\n", (aSpacingNum + 1)); fprintf(fp, "TemplatenumT = %" LAL_UINT8_FORMAT "\n", (tSpacingNum + 1)); fprintf(fp, "TemplatenumP = %" LAL_UINT8_FORMAT "\n", (pSpacingNum + 1)); fprintf(fp, "TemplatenumTotal = %" LAL_UINT8_FORMAT "\n",(fSpacingNum + 1) * (aSpacingNum + 1) * (tSpacingNum + 1) * (pSpacingNum + 1)); fprintf(fp, "Sens = %.9g\n", estSens);/*(E[rho]/h0^2)^2*/ fprintf(fp, "h0_min_SNR10 = %.9g\n", h0Sens);/*for rho = 10 in our pipeline*/ fprintf(fp, "startTime = %" LAL_INT4_FORMAT "\n", computingStartGPSTime.gpsSeconds );/*start time in GPS-time*/ fprintf(fp, "endTime = %" LAL_INT4_FORMAT "\n", computingEndGPSTime.gpsSeconds );/*end time in GPS-time*/ fprintf(fp, "computingTime = %" LAL_UINT4_FORMAT "\n", computingTime );/*total time in sec*/ fprintf(fp, "SFTnum = %" LAL_UINT4_FORMAT "\n", sftIndices->length);/*total number of SFT*/ fprintf(fp, "pairnum = %" LAL_UINT4_FORMAT "\n", sftPairs->length);/*total number of pair of SFT*/ fprintf(fp, "Tsft = %.6g\n", Tsft);/*SFT duration*/ fprintf(fp, "\n[Version]\n\n"); fprintf(fp, "%s", VCSInfoString); fclose(fp); XLALFree(CMDInputStr); } XLALFree(VCSInfoString); XLALDestroyCOMPLEX8Vector ( expSignalPhases ); XLALDestroyUINT4Vector ( lowestBins ); XLALDestroyREAL8Vector ( shiftedFreqs ); XLALDestroyREAL8VectorSequence ( sincList ); XLALDestroyMultiSSBtimes ( multiBinaryTimes ); XLALDestroyMultiSSBtimes ( multiSSBTimes ); XLALDestroyREAL8Vector ( GammaAve ); XLALDestroySFTPairIndexList( sftPairs ); XLALDestroySFTIndexList( sftIndices ); XLALDestroyMultiAMCoeffs ( multiCoeffs ); XLALDestroyMultiDetectorStateSeries ( multiStates ); XLALDestroyMultiTimestamps ( multiTimes ); XLALDestroyMultiNoiseWeights ( multiWeights ); XLALDestroyMultiPSDVector ( multiPSDs ); XLALDestroyMultiSFTVector ( inputSFTs ); /* de-allocate memory for configuration variables */ XLALDestroyConfigVars ( &config ); /* de-allocate memory for user input variables */ XLALDestroyUserVars(); /* free toplist memory */ free_crossCorr_toplist(&ccToplist); /* check memory leaks if we forgot to de-allocate anything */ LALCheckMemoryLeaks(); LogPrintf (LOG_CRITICAL, "End time\n");/*for debug convenience to record calculating time*/ return 0; } /* main */ /* initialize and register user variables */ int XLALInitUserVars (UserInput_t *uvar) { /* initialize with some defaults */ uvar->help = FALSE; uvar->maxLag = 0.0; uvar->inclAutoCorr = FALSE; uvar->fStart = 100.0; uvar->fBand = 0.1; /* uvar->fdotStart = 0.0; */ /* uvar->fdotBand = 0.0; */ uvar->alphaRad = 0.0; uvar->deltaRad = 0.0; uvar->refTime = 0.0; uvar->rngMedBlock = 50; uvar->numBins = 1; /* zero binary orbital parameters means not a binary */ uvar->orbitAsiniSec = 0.0; uvar->orbitAsiniSecBand = 0.0; uvar->orbitPSec = 0.0; uvar->orbitPSecBand = 0.0; uvar->orbitTimeAsc = 0; uvar->orbitTimeAscBand = 0; /*default mismatch values */ /* set to 0.1 by default -- for no real reason */ /* make 0.1 a macro? */ uvar->mismatchF = 0.1; uvar->mismatchA = 0.1; uvar->mismatchT = 0.1; uvar->mismatchP = 0.1; uvar->ephemEarth = XLALStringDuplicate("earth00-19-DE405.dat.gz"); uvar->ephemSun = XLALStringDuplicate("sun00-19-DE405.dat.gz"); uvar->sftLocation = XLALCalloc(1, MAXFILENAMELENGTH+1); /* initialize number of candidates in toplist -- default is just to return the single best candidate */ uvar->numCand = 1; uvar->toplistFilename = XLALStringDuplicate("toplist_crosscorr.dat"); uvar->version = FALSE; /* register user-variables */ XLALregBOOLUserStruct ( help, 'h', UVAR_HELP, "Print this message"); XLALregINTUserStruct ( startTime, 0, UVAR_REQUIRED, "Desired start time of analysis in GPS seconds"); XLALregINTUserStruct ( endTime, 0, UVAR_REQUIRED, "Desired end time of analysis in GPS seconds"); XLALregREALUserStruct ( maxLag, 0, UVAR_OPTIONAL, "Maximum lag time in seconds between SFTs in correlation"); XLALregBOOLUserStruct ( inclAutoCorr, 0, UVAR_OPTIONAL, "Include auto-correlation terms (an SFT with itself)"); XLALregREALUserStruct ( fStart, 0, UVAR_OPTIONAL, "Start frequency in Hz"); XLALregREALUserStruct ( fBand, 0, UVAR_OPTIONAL, "Frequency band to search over in Hz "); /* XLALregREALUserStruct ( fdotStart, 0, UVAR_OPTIONAL, "Start value of spindown in Hz/s"); */ /* XLALregREALUserStruct ( fdotBand, 0, UVAR_OPTIONAL, "Band for spindown values in Hz/s"); */ XLALregREALUserStruct ( alphaRad, 0, UVAR_OPTIONAL, "Right ascension for directed search (radians)"); XLALregREALUserStruct ( deltaRad, 0, UVAR_OPTIONAL, "Declination for directed search (radians)"); XLALregREALUserStruct ( refTime, 0, UVAR_OPTIONAL, "SSB reference time for pulsar-parameters [Default: midPoint]"); XLALregREALUserStruct ( orbitAsiniSec, 0, UVAR_OPTIONAL, "Start of search band for projected semimajor axis (seconds) [0 means not a binary]"); XLALregREALUserStruct ( orbitAsiniSecBand, 0, UVAR_OPTIONAL, "Width of search band for projected semimajor axis (seconds)"); XLALregREALUserStruct ( orbitPSec, 0, UVAR_OPTIONAL, "Binary orbital period (seconds) [0 means not a binary]"); XLALregREALUserStruct ( orbitPSecBand, 0, UVAR_OPTIONAL, "Band for binary orbital period (seconds) "); XLALregREALUserStruct ( orbitTimeAsc, 0, UVAR_OPTIONAL, "Start of orbital time-of-ascension band in GPS seconds"); XLALregREALUserStruct ( orbitTimeAscBand, 0, UVAR_OPTIONAL, "Width of orbital time-of-ascension band (seconds)"); XLALregSTRINGUserStruct( ephemEarth, 0, UVAR_OPTIONAL, "Earth ephemeris file to use"); XLALregSTRINGUserStruct( ephemSun, 0, UVAR_OPTIONAL, "Sun ephemeris file to use"); XLALregSTRINGUserStruct( sftLocation, 0, UVAR_REQUIRED, "Filename pattern for locating SFT data"); XLALregINTUserStruct ( rngMedBlock, 0, UVAR_OPTIONAL, "Running median block size for PSD estimation"); XLALregINTUserStruct ( numBins, 0, UVAR_OPTIONAL, "Number of frequency bins to include in calculation"); XLALregREALUserStruct ( mismatchF, 0, UVAR_OPTIONAL, "Desired mismatch for frequency spacing"); XLALregREALUserStruct ( mismatchA, 0, UVAR_OPTIONAL, "Desired mismatch for asini spacing"); XLALregREALUserStruct ( mismatchT, 0, UVAR_OPTIONAL, "Desired mismatch for periapse passage time spacing"); XLALregREALUserStruct ( mismatchP, 0, UVAR_OPTIONAL, "Desired mismatch for period spacing"); XLALregREALUserStruct ( spacingF, 0, UVAR_OPTIONAL, "Desired frequency spacing"); XLALregREALUserStruct ( spacingA, 0, UVAR_OPTIONAL, "Desired asini spacing"); XLALregREALUserStruct ( spacingT, 0, UVAR_OPTIONAL, "Desired periapse passage time spacing"); XLALregREALUserStruct ( spacingP, 0, UVAR_OPTIONAL, "Desired period spacing"); XLALregINTUserStruct ( numCand, 0, UVAR_OPTIONAL, "Number of candidates to keep in toplist"); XLALregSTRINGUserStruct( pairListInputFilename, 0, UVAR_OPTIONAL, "Name of file from which to read list of SFT pairs"); XLALregSTRINGUserStruct( pairListOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write list of SFT pairs"); XLALregSTRINGUserStruct( sftListOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write list of SFTs (for sanity checks)"); XLALregSTRINGUserStruct( sftListInputFilename, 0, UVAR_OPTIONAL, "Name of file to which to read in list of SFTs (for sanity checks)"); XLALregSTRINGUserStruct( gammaAveOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write aa+bb weights (for e.g., false alarm estimation)"); XLALregSTRINGUserStruct( gammaCircOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write ab-ba weights (for e.g., systematic error)"); XLALregSTRINGUserStruct( toplistFilename, 0, UVAR_OPTIONAL, "Output filename containing candidates in toplist"); XLALregSTRINGUserStruct( logFilename, 0, UVAR_OPTIONAL, "Output a meta-data file for the search"); XLALregBOOLUserStruct ( version, 'V', UVAR_SPECIAL, "Output version(VCS) information"); if ( xlalErrno ) { XLALPrintError ("%s: user variable initialization failed with errno = %d.\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } return XLAL_SUCCESS; }
/** * 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() */
/** * Function to step through the full template grid point by point. * Normal return = 0, * errors return -1, * end of scan is signalled by return = 1 */ int XLALNextDopplerPos(PulsarDopplerParams *pos, DopplerFullScanState *scan) { /* This traps coding errors in the calling routine. */ if ( pos == NULL || scan == NULL ) { XLAL_ERROR ( XLAL_EINVAL ); } if ( scan->state == STATE_IDLE ) { XLALPrintError ("\nCalled XLALNextDopplerPos() on un-initialized DopplerFullScanState !\n\n"); XLAL_ERROR ( XLAL_EINVAL ); } /* is this search finished? then return '1' */ if ( scan->state == STATE_FINISHED ) return 1; // set refTime in returned template to the refTime of the grid pos->refTime = scan->spinRange.refTime; /* ----- step foward one template in full grid ----- */ /* Which "class" of template grid are we dealing with: factored, or full-multidim ? */ switch ( scan->gridType ) { /* emulate old 'factored' grids 'sky x f0dot x f1dot x f2dot x f3dot': */ case GRID_FLAT: case GRID_ISOTROPIC: case GRID_METRIC: case GRID_FILE_SKYGRID: case GRID_METRIC_SKYFILE: /* backwards-compatibility mode */ nextPointInFactoredGrid ( pos, scan ); break; case GRID_FILE_FULLGRID: XLAL_INIT_MEM(pos->fkdot); pos->fkdot[0] = scan->thisGridPoint->entry.data[0]; pos->Alpha = scan->thisGridPoint->entry.data[1]; pos->Delta = scan->thisGridPoint->entry.data[2]; pos->fkdot[1] = scan->thisGridPoint->entry.data[3]; pos->fkdot[2] = scan->thisGridPoint->entry.data[4]; pos->fkdot[3] = scan->thisGridPoint->entry.data[5]; pos->asini = 0; // isolated pulsar /* advance to next grid point */ if ( ( scan->thisGridPoint = scan->thisGridPoint->next ) == NULL ) scan->state = STATE_FINISHED; break; /* case GRID_METRIC_LATTICE: */ /* if ( XLALgetCurrentDopplerPos ( pos, scan->latticeScan, COORDINATESYSTEM_EQUATORIAL ) ) { */ /* XLAL_ERROR ( XLAL_EFUNC ); */ /* } */ /* /\* advance to next point *\/ */ /* ret = XLALadvanceLatticeIndex ( scan->latticeScan ); */ /* if ( ret < 0 ) { */ /* XLAL_ERROR ( XLAL_EFUNC ); */ /* } */ /* else if ( ret == 1 ) */ /* { */ /* XLALPrintError ( "\n\nXLALadvanceLatticeIndex(): this was the last lattice points!\n\n"); */ /* scan->state = STATE_FINISHED; */ /* } */ /* #if 0 */ /* { /\* debugging *\/ */ /* gsl_vector_int *lal_index = NULL; */ /* XLALgetCurrentLatticeIndex ( &lal)index, scan->latticeScan ); */ /* XLALfprintfGSLvector_int ( stderr, "%d", lal_index ); */ /* gsl_vector_int_free ( lal_index ); */ /* } */ /* #endif */ break; case GRID_SPINDOWN_SQUARE: /* square parameter space */ case GRID_SPINDOWN_AGEBRK: /* age-braking index parameter space */ { /* Advance to next tile */ int retn = XLALNextLatticeTilingPoint(scan->spindownTilingItr, scan->spindownTilingPoint); if (retn < 0) { XLALPrintError("\nGRID_SPINDOWN_{SQUARE,AGEBRK}: XLALNextLatticeTilingPoint() failed\n"); return -1; } if (retn > 0) { /* Found a point */ pos->Alpha = gsl_vector_get(scan->spindownTilingPoint, 0); pos->Delta = gsl_vector_get(scan->spindownTilingPoint, 1); pos->fkdot[0] = gsl_vector_get(scan->spindownTilingPoint, 2); for (size_t i = 1; i < PULSAR_MAX_SPINS; ++i) { pos->fkdot[i] = gsl_vector_get(scan->spindownTilingPoint, i + 2); } return 0; } else { /* No more points */ scan->state = STATE_FINISHED; return 1; } } break; default: XLALPrintError("\nInvalid grid type '%d'\n\n", scan->gridType ); xlalErrno = XLAL_EINVAL; return -1; break; } /* switch gridType */ return 0; } /* XLALNextDopplerPos() */
// ---------- 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()
/** * 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() */
/** * Function to parse a config-file-type string (or section thereof) * into a PulsarParams struct. * * NOTE: The section-name is optional, and can be given as NULL, * in which case the top of the file (ie the "default section") * is used. * * NOTE2: eventually ATNF/TEMPO2-style 'par-file' variables will also * be understood by this function, but we start out with a simpler version * that just deals with our 'CW-style' input variable for now * * NOTE3: The config-file must be of a special "SourceParamsIO" form, * defining the following required and optional parameters: * * REQUIRED: * Alpha, Delta, Freq, refTime * * OPTIONAL: * f1dot, f2dot, f3dot, f4dot, f5dot, f6dot * {h0, cosi} or {aPlus, aCross}, psi, phi0 * transientWindowType, transientStartTime, transientTauDays * * Other config-variables found in the file will ... ?? error or accept? */ int XLALReadPulsarParams ( PulsarParams *pulsarParams, ///< [out] pulsar parameters to fill in from config string LALParsedDataFile *cfgdata, ///< [in] pre-parsed "SourceParamsIO" config-file contents const CHAR *secName ///< [in] section-name to use from config-file string (can be NULL) ) { XLAL_CHECK ( pulsarParams != NULL, XLAL_EINVAL ); XLAL_CHECK ( cfgdata != NULL, XLAL_EINVAL ); XLAL_INIT_MEM ( (*pulsarParams) ); // wipe input struct clean // ---------- PulsarAmplitudeParams ---------- // ----- h0, cosi REAL8 h0 = 0; BOOLEAN have_h0; REAL8 cosi = 0; BOOLEAN have_cosi; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &h0, cfgdata, secName, "h0", &have_h0 ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigREAL8Variable ( &cosi, cfgdata, secName, "cosi", &have_cosi ) == XLAL_SUCCESS, XLAL_EFUNC ); // ----- ALTERNATIVE: aPlus, aCross REAL8 aPlus = 0; BOOLEAN have_aPlus; REAL8 aCross = 0; BOOLEAN have_aCross; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &aPlus, cfgdata, secName, "aPlus", &have_aPlus ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigREAL8Variable ( &aCross, cfgdata, secName, "aCross", &have_aCross ) == XLAL_SUCCESS, XLAL_EFUNC ); // if h0 then also need cosi, and vice-versa XLAL_CHECK ( (have_h0 && have_cosi) || ( !have_h0 && !have_cosi ), XLAL_EINVAL ); // if aPlus then also need aCross, and vice-versa XLAL_CHECK ( (have_aPlus && have_aCross) || ( !have_aPlus && !have_aCross ), XLAL_EINVAL ); // {h0,cosi} or {aPlus, aCross} mutually exclusive sets XLAL_CHECK ( ! ( have_h0 && have_aPlus ), XLAL_EINVAL ); if ( have_aPlus ) /* translate A_{+,x} into {h_0, cosi} */ { XLAL_CHECK ( fabs ( aCross ) <= aPlus, XLAL_EDOM, "ERROR: |aCross| (= %g) must be <= aPlus (= %g).\n", fabs(aCross), aPlus ); REAL8 disc = sqrt ( SQ(aPlus) - SQ(aCross) ); h0 = aPlus + disc; if ( h0 > 0 ) { cosi = aCross / h0; // avoid division by 0! } } //if {aPlus, aCross} XLAL_CHECK ( h0 >= 0, XLAL_EDOM ); pulsarParams->Amp.h0 = h0; XLAL_CHECK ( (cosi >= -1) && (cosi <= 1), XLAL_EDOM ); pulsarParams->Amp.cosi= cosi; // ----- psi REAL8 psi = 0; BOOLEAN have_psi; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &psi, cfgdata, secName, "psi", &have_psi ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Amp.psi = psi; // ----- phi0 REAL8 phi0 = 0; BOOLEAN have_phi0; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &phi0, cfgdata, secName, "phi0", &have_phi0 ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Amp.phi0 = phi0; // ---------- PulsarDopplerParams ---------- // ----- refTime LIGOTimeGPS refTime_GPS; BOOLEAN have_refTime; XLAL_CHECK ( XLALReadConfigEPOCHVariable ( &refTime_GPS, cfgdata, secName, "refTime", &have_refTime ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( have_refTime, XLAL_EINVAL ); pulsarParams->Doppler.refTime = refTime_GPS; // ----- Alpha REAL8 Alpha_Rad = 0; BOOLEAN have_Alpha; XLAL_CHECK ( XLALReadConfigRAJVariable ( &Alpha_Rad, cfgdata, secName, "Alpha", &have_Alpha ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( have_Alpha, XLAL_EINVAL ); XLAL_CHECK ( (Alpha_Rad >= 0) && (Alpha_Rad < LAL_TWOPI), XLAL_EDOM ); pulsarParams->Doppler.Alpha = Alpha_Rad; // ----- Delta REAL8 Delta_Rad = 0; BOOLEAN have_Delta; XLAL_CHECK ( XLALReadConfigDECJVariable ( &Delta_Rad, cfgdata, secName, "Delta", &have_Delta ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( have_Delta, XLAL_EINVAL ); XLAL_CHECK ( (Delta_Rad >= -LAL_PI_2) && (Delta_Rad <= LAL_PI_2), XLAL_EDOM ); pulsarParams->Doppler.Delta = Delta_Rad; // ----- fkdot // Freq REAL8 Freq = 0; BOOLEAN have_Freq; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &Freq, cfgdata, secName, "Freq", &have_Freq ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( have_Freq, XLAL_EINVAL ); XLAL_CHECK ( Freq > 0, XLAL_EDOM ); pulsarParams->Doppler.fkdot[0] = Freq; // f1dot REAL8 f1dot = 0; BOOLEAN have_f1dot; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &f1dot, cfgdata, secName, "f1dot", &have_f1dot ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Doppler.fkdot[1] = f1dot; // f2dot REAL8 f2dot = 0; BOOLEAN have_f2dot; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &f2dot, cfgdata, secName, "f2dot", &have_f2dot ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Doppler.fkdot[2] = f2dot; // f3dot REAL8 f3dot = 0; BOOLEAN have_f3dot; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &f3dot, cfgdata, secName, "f3dot", &have_f3dot ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Doppler.fkdot[3] = f3dot; // f4dot REAL8 f4dot = 0; BOOLEAN have_f4dot; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &f4dot, cfgdata, secName, "f4dot", &have_f4dot ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Doppler.fkdot[4] = f4dot; // f5dot REAL8 f5dot = 0; BOOLEAN have_f5dot; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &f5dot, cfgdata, secName, "f5dot", &have_f5dot ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Doppler.fkdot[5] = f5dot; // f6dot REAL8 f6dot = 0; BOOLEAN have_f6dot; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &f6dot, cfgdata, secName, "f6dot", &have_f6dot ) == XLAL_SUCCESS, XLAL_EFUNC ); pulsarParams->Doppler.fkdot[6] = f6dot; // ----- orbit LIGOTimeGPS orbitTp; BOOLEAN have_orbitTp; XLAL_CHECK ( XLALReadConfigEPOCHVariable ( &orbitTp, cfgdata, secName, "orbitTp", &have_orbitTp ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 orbitArgp = 0; BOOLEAN have_orbitArgp; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &orbitArgp, cfgdata, secName, "orbitArgp", &have_orbitArgp ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 orbitasini = 0 /* isolated pulsar */; BOOLEAN have_orbitasini; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &orbitasini, cfgdata, secName, "orbitasini", &have_orbitasini ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 orbitEcc = 0; BOOLEAN have_orbitEcc; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &orbitEcc, cfgdata, secName, "orbitEcc", &have_orbitEcc ) == XLAL_SUCCESS, XLAL_EFUNC ); REAL8 orbitPeriod = 0;BOOLEAN have_orbitPeriod; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &orbitPeriod, cfgdata, secName, "orbitPeriod", &have_orbitPeriod ) == XLAL_SUCCESS, XLAL_EFUNC ); if ( have_orbitasini || have_orbitEcc || have_orbitPeriod || have_orbitArgp || have_orbitTp ) { XLAL_CHECK ( orbitasini >= 0, XLAL_EDOM ); XLAL_CHECK ( (orbitasini == 0) || ( have_orbitEcc && have_orbitPeriod && have_orbitArgp && have_orbitTp ), XLAL_EINVAL ); XLAL_CHECK ( (orbitEcc >= 0) && (orbitEcc <= 1), XLAL_EDOM ); /* fill in orbital parameter structure */ pulsarParams->Doppler.tp = orbitTp; pulsarParams->Doppler.argp = orbitArgp; pulsarParams->Doppler.asini = orbitasini; pulsarParams->Doppler.ecc = orbitEcc; pulsarParams->Doppler.period = orbitPeriod; } // if have non-trivial orbit // ---------- transientWindow_t ---------- // ----- type char *transientWindowType = NULL; BOOLEAN have_transientWindowType; XLAL_CHECK ( XLALReadConfigSTRINGVariable ( &transientWindowType, cfgdata, secName, "transientWindowType", &have_transientWindowType ) == XLAL_SUCCESS, XLAL_EFUNC ); // ----- t0 REAL8 transientStartTime = 0; BOOLEAN have_transientStartTime; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &transientStartTime, cfgdata, secName, "transientStartTime", &have_transientStartTime ) == XLAL_SUCCESS, XLAL_EFUNC ); // ----- tau REAL8 transientTauDays = 0; BOOLEAN have_transientTauDays; XLAL_CHECK ( XLALReadConfigREAL8Variable ( &transientTauDays, cfgdata, secName, "transientTauDays", &have_transientTauDays ) == XLAL_SUCCESS, XLAL_EFUNC ); int twtype = TRANSIENT_NONE; if ( have_transientWindowType ) { XLAL_CHECK ( (twtype = XLALParseTransientWindowName ( transientWindowType )) >= 0, XLAL_EFUNC ); XLALFree ( transientWindowType ); } pulsarParams->Transient.type = twtype; if ( pulsarParams->Transient.type != TRANSIENT_NONE ) { XLAL_CHECK ( have_transientStartTime && have_transientTauDays, XLAL_EINVAL ); XLAL_CHECK ( transientStartTime >= 0, XLAL_EDOM ); XLAL_CHECK ( transientTauDays > 0, XLAL_EDOM ); pulsarParams->Transient.t0 = (UINT4) transientStartTime; pulsarParams->Transient.tau = (UINT4) ( transientTauDays * 86400 ); } /* if transient window != none */ else { XLAL_CHECK ( !(have_transientStartTime || have_transientTauDays), XLAL_EINVAL ); } return XLAL_SUCCESS; } // XLALParsePulsarParams()