// ----- 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[]) { ConfigVariables config = empty_ConfigVariables; UserVariables_t uvar = empty_UserVariables; /* register user-variables */ XLAL_CHECK ( XLALInitUserVars ( &uvar ) == XLAL_SUCCESS, XLAL_EFUNC ); /* read cmdline & cfgfile */ XLAL_CHECK ( XLALUserVarReadAllInput ( argc,argv ) == XLAL_SUCCESS, XLAL_EFUNC ); if (uvar.help) { /* help requested: we're done */ exit(0); } if ( uvar.version ) { XLALOutputVersionString ( stdout, lalDebugLevel ); exit(0); } /* basic setup and initializations */ XLAL_CHECK ( XLALInitCode( &config, &uvar, argv[0] ) == XLAL_SUCCESS, XLAL_EFUNC ); /* prepare output files */ FILE *fpOutab = NULL; if ( uvar.outab ) { XLAL_CHECK ( (fpOutab = fopen (uvar.outab, "wb")) != NULL, XLAL_EIO, "Error opening file '%s' for writing...", uvar.outab ); /* write header info in comments */ XLAL_CHECK ( XLAL_SUCCESS == XLALOutputVersionString ( fpOutab, 0 ), XLAL_EFUNC ); /* write the command-line */ for (int a = 0; a < argc; a++) { fprintf(fpOutab,"%%%% argv[%d]: '%s'\n", a, argv[a]); } /* write column headings */ fprintf(fpOutab, "%%%% columns:\n%%%% Alpha Delta tGPS "); if ( config.numDetectors == 1 ) { fprintf(fpOutab, " a(t) b(t)"); } else { for ( UINT4 X=0; X < config.numDetectors; X++ ) { fprintf(fpOutab, " a[%d](t) b[%d](t)", X, X); } } fprintf(fpOutab, "\n"); } FILE *fpOutABCD = NULL; if ( uvar.outABCD ) { XLAL_CHECK ( (fpOutABCD = fopen (uvar.outABCD, "wb")) != NULL, XLAL_EIO, "Error opening file '%s' for writing...", uvar.outABCD ); /* write header info in comments */ XLAL_CHECK ( XLAL_SUCCESS == XLALOutputVersionString ( fpOutABCD, 0 ), XLAL_EFUNC ); /* write the command-line */ for (int a = 0; a < argc; a++) { fprintf(fpOutABCD,"%%%% argv[%d]: '%s'\n", a, argv[a]); } /* write column headings */ fprintf(fpOutABCD, "%%%% columns:\n%%%% Alpha Delta"); fprintf(fpOutABCD, " A B C D"); if ( config.numDetectors > 1 ) { fprintf(fpOutABCD, " "); for ( UINT4 X=0; X < config.numDetectors; X++ ) { fprintf(fpOutABCD, " A[%d] B[%d] C[%d] D[%d]", X, X, X, X); } } fprintf(fpOutABCD, "\n"); } /* loop over sky positions (outer loop, could allow for buffering if necessary) */ for (UINT4 n = 0; n < config.numSkyPoints; n++) { SkyPosition skypos; skypos.system = COORDINATESYSTEM_EQUATORIAL; skypos.longitude = config.Alpha->data[n]; skypos.latitude = config.Delta->data[n]; /* do the actual computation of the antenna pattern functions */ MultiAMCoeffs *multiAM; XLAL_CHECK ( ( multiAM = XLALComputeMultiAMCoeffs ( config.multiDetStates, config.multiNoiseWeights, skypos ) ) != NULL, XLAL_EFUNC, "XLALComputeAMCoeffs() failed." ); /* for multi-IFO run with weights, do it again, without weights, to get single-IFO quantities consistent with single-IFO runs * FIXME: remove this temporary hack when MultiAmCoeffs have been changed to include non-weighted single-IFO quantities */ MultiAMCoeffs *multiAMforSingle = NULL; MultiAMCoeffs *multiAMunweighted = NULL; if ( ( config.numDetectors > 1 ) && ( config.multiNoiseWeights != NULL ) ) { XLAL_CHECK ( ( multiAMunweighted = XLALComputeMultiAMCoeffs ( config.multiDetStates, NULL, skypos ) ) != NULL, XLAL_EFUNC, "XLALComputeAMCoeffs() failed." ); multiAMforSingle = multiAMunweighted; } else { multiAMforSingle = multiAM; } /* write out the data for this sky point */ if ( uvar.outab ) { // output a(t), b(t) at each timestamp for (UINT4 t = 0; t < config.numTimeStamps; t++) { // FIXME: does not work for different multi-IFO numTimeStampsX fprintf (fpOutab, "%.7f %.7f %d", config.Alpha->data[n], config.Delta->data[n], config.multiTimestamps->data[0]->data[t].gpsSeconds ); for ( UINT4 X=0; X < config.numDetectors; X++ ) { fprintf(fpOutab, " %12.8f %12.8f", multiAMforSingle->data[X]->a->data[t], multiAMforSingle->data[X]->b->data[t]); } // for ( UINT4 X=0; X < config.numDetectors; X++ ) fprintf(fpOutab, "\n"); } // for (UINT4 t = 0; t < config.numTimeStamps; t++) } // if ( uvar.outab ) if ( uvar.outABCD ) { // output ABCD averaged over all timestamps // FIXME: stop doing average manually when AMCoeffs is changed to contain averaged values REAL8 A = multiAM->Mmunu.Ad/config.numTimeStamps; REAL8 B = multiAM->Mmunu.Bd/config.numTimeStamps; REAL8 C = multiAM->Mmunu.Cd/config.numTimeStamps; REAL8 D = A*B-SQ(C); fprintf (fpOutABCD, "%.7f %.7f %12.8f %12.8f %12.8f %12.8f", config.Alpha->data[n], config.Delta->data[n], A, B, C, D ); if ( config.numDetectors > 1 ) { for ( UINT4 X=0; X < config.numDetectors; X++ ) { REAL4 AX = multiAMforSingle->data[X]->A/config.numTimeStampsX->data[X]; REAL4 BX = multiAMforSingle->data[X]->B/config.numTimeStampsX->data[X]; REAL4 CX = multiAMforSingle->data[X]->C/config.numTimeStampsX->data[X]; REAL4 DX = AX*BX-SQ(CX); fprintf(fpOutABCD, " %12.8f %12.8f %12.8f %12.8f", AX, BX, CX, DX); } } fprintf(fpOutABCD, "\n"); } // if ( uvar.outABCD ) XLALDestroyMultiAMCoeffs ( multiAM ); if ( multiAMunweighted ) { XLALDestroyMultiAMCoeffs ( multiAMunweighted ); } } // for (UINT4 n = 0; n < config.numSkyPoints; n++) /* ----- close output files ----- */ if ( fpOutab ) { fprintf (fpOutab, "\n"); fclose ( fpOutab ); } if ( fpOutABCD ) { fprintf (fpOutABCD, "\n"); fclose ( fpOutABCD ); } /* ----- done: free all memory */ XLAL_CHECK ( XLALDestroyConfig( &config ) == XLAL_SUCCESS, XLAL_EFUNC ); LALCheckMemoryLeaks(); return 0; } /* main */
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; }
int main(int argc, char *argv[]) { UserVariables_t XLAL_INIT_DECL(uvar); XLAL_CHECK ( InitUserVars(&uvar, argc, argv) == XLAL_SUCCESS, XLAL_EFUNC ); MultiLALDetector *detectors = NULL; XLAL_CHECK( (detectors = XLALMalloc(sizeof(MultiLALDetector))) != NULL, XLAL_ENOMEM ); detectors->length = uvar.IFO->length; for (UINT4 ii=0; ii<detectors->length; ii++) { if (strcmp("H1", uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_LHO_4K_DETECTOR]; //H1 } else if (strcmp("L1",uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_LLO_4K_DETECTOR]; //L1 } else if (strcmp("V1", uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_VIRGO_DETECTOR]; //V1 } else if (strcmp("H2", uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_LHO_2K_DETECTOR]; //H2 } else if (strcmp("H2r", uvar.IFO->data[ii])==0) { LALDetector H2 = lalCachedDetectors[LAL_LHO_2K_DETECTOR]; //H2 rotated H2.frDetector.xArmAzimuthRadians -= 0.25*LAL_PI; H2.frDetector.yArmAzimuthRadians -= 0.25*LAL_PI; memset(&(H2.frDetector.name), 0, sizeof(CHAR)*LALNameLength); snprintf(H2.frDetector.name, LALNameLength, "%s", "LHO_2k_rotatedPiOver4"); XLAL_CHECK( (XLALCreateDetector(&(detectors->sites[ii]), &(H2.frDetector), LALDETECTORTYPE_IFODIFF)) != NULL, XLAL_EFUNC ); } else { XLAL_ERROR(XLAL_EINVAL, "Not using valid interferometer! Expected 'H1', 'H2', 'H2r' (rotated H2), 'L1', or 'V1' not %s.\n", uvar.IFO->data[ii]); } } EphemerisData *edat = NULL; XLAL_CHECK( (edat = XLALInitBarycenter(uvar.ephemEarth, uvar.ephemSun)) != NULL, XLAL_EFUNC ); LIGOTimeGPS tStart; XLALGPSSetREAL8 ( &tStart, uvar.t0 ); XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC, "XLALGPSSetREAL8 failed\n" ); MultiLIGOTimeGPSVector *multiTimestamps = NULL; XLAL_CHECK( (multiTimestamps = XLALMakeMultiTimestamps(tStart, uvar.Tobs, uvar.Tsft, uvar.SFToverlap, detectors->length)) != NULL, XLAL_EFUNC ); LIGOTimeGPS refTime = multiTimestamps->data[0]->data[0]; MultiDetectorStateSeries *multiStateSeries = NULL; XLAL_CHECK( (multiStateSeries = XLALGetMultiDetectorStates(multiTimestamps, detectors, edat, uvar.SFToverlap)) != NULL, XLAL_EFUNC ); gsl_rng *rng = NULL; XLAL_CHECK( (rng = gsl_rng_alloc(gsl_rng_mt19937)) != NULL, XLAL_EFUNC ); gsl_rng_set(rng, 0); FILE *OUTPUT; XLAL_CHECK( (OUTPUT = fopen(uvar.outfilename,"w")) != NULL, XLAL_EIO, "Output file %s could not be opened\n", uvar.outfilename ); for (INT4 n=0; n<uvar.skylocations; n++) { SkyPosition skypos; if (XLALUserVarWasSet(&(uvar.alpha)) && XLALUserVarWasSet(&(uvar.delta)) && n==0) { skypos.longitude = uvar.alpha; skypos.latitude = uvar.delta; skypos.system = COORDINATESYSTEM_EQUATORIAL; } else { skypos.longitude = LAL_TWOPI*gsl_rng_uniform(rng); skypos.latitude = LAL_PI*gsl_rng_uniform(rng) - LAL_PI_2; skypos.system = COORDINATESYSTEM_EQUATORIAL; } REAL8 cosi0, psi0; if (XLALUserVarWasSet(&(uvar.cosi)) && n==0) cosi0 = uvar.cosi; else cosi0 = 2.0*gsl_rng_uniform(rng) - 1.0; if (XLALUserVarWasSet(&(uvar.psi)) && n==0) psi0 = uvar.psi; else psi0 = LAL_PI*gsl_rng_uniform(rng); MultiAMCoeffs *multiAMcoefficients = NULL; XLAL_CHECK( (multiAMcoefficients = XLALComputeMultiAMCoeffs(multiStateSeries, NULL, skypos)) != NULL, XLAL_EFUNC ); MultiSSBtimes *multissb = NULL; XLAL_CHECK( (multissb = XLALGetMultiSSBtimes(multiStateSeries, skypos, refTime, SSBPREC_RELATIVISTICOPT)) != NULL, XLAL_EFUNC ); REAL8 frequency = 1000.0; REAL8 frequency0 = frequency + (gsl_rng_uniform(rng)-0.5)/uvar.Tsft; for (UINT4 ii=0; ii<multiAMcoefficients->data[0]->a->length; ii++) { REAL4 Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi0) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi0); REAL4 Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi0) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi0); REAL4 Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi0) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi0); REAL4 Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi0) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi0); COMPLEX16 RatioTerm0 = crect(0.5*Fplus1*(1.0+cosi0*cosi0), Fcross1*cosi0)/crect(0.5*Fplus0*(1.0+cosi0*cosi0), Fcross0*cosi0); //real det-sig ratio term REAL4 detPhaseArg = 0.0, detPhaseMag = 0.0; BOOLEAN loopbroken = 0; for (INT4 jj=0; jj<16 && !loopbroken; jj++) { REAL4 psi = 0.0625*jj*LAL_PI; Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi); Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi); Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi); Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi); for (INT4 kk=0; kk<21 && !loopbroken; kk++) { REAL4 cosi = 1.0 - 2.0*0.05*kk; if (!uvar.unrestrictedCosi) { if (cosi0<0.0) cosi = -0.05*kk; else cosi = 0.05*kk; } COMPLEX16 complexnumerator = crect(0.5*Fplus1*(1.0+cosi*cosi), Fcross1*cosi); COMPLEX16 complexdenominator = crect(0.5*Fplus0*(1.0+cosi*cosi) , Fcross0*cosi); if (cabs(complexdenominator)>1.0e-6) { COMPLEX16 complexval = complexnumerator/complexdenominator; detPhaseMag += fmin(cabs(complexval), 10.0); detPhaseArg += gsl_sf_angle_restrict_pos(carg(complexval)); } else { loopbroken = 1; detPhaseMag = 0.0; detPhaseArg = 0.0; } } } detPhaseMag /= 336.0; detPhaseArg /= 336.0; COMPLEX16 RatioTerm = cpolar(detPhaseMag, detPhaseArg); //Bin of interest REAL8 signalFrequencyBin = round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft) - frequency*uvar.Tsft; //estimated nearest freq in ref IFO REAL8 timediff0 = multissb->data[0]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[0]->Tdot->data[ii]; REAL8 timediff1 = multissb->data[1]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[1]->Tdot->data[ii]; REAL8 tau = timediff1 - timediff0; REAL8 freqshift0 = -LAL_TWOPI*tau*frequency0; //real freq shift REAL8 freqshift = -LAL_TWOPI*tau*(round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft)/uvar.Tsft); //estimated freq shift COMPLEX16 phaseshift0 = cpolar(1.0, freqshift0); COMPLEX16 phaseshift = cpolar(1.0, freqshift); REAL8 delta0_0 = (multissb->data[0]->Tdot->data[ii]*frequency0-frequency)*uvar.Tsft - signalFrequencyBin; REAL8 delta1_0 = (multissb->data[1]->Tdot->data[ii]*frequency0-frequency)*uvar.Tsft - signalFrequencyBin; REAL8 realSigBinDiff = round(delta0_0) - round(delta1_0); delta1_0 += realSigBinDiff; REAL8 delta0 = round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft)*(multissb->data[0]->Tdot->data[ii] - 1.0); REAL8 delta1 = round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft)*(multissb->data[1]->Tdot->data[ii] - 1.0); REAL8 estSigBinDiff = round(delta0) - round(delta1); delta1 += estSigBinDiff; COMPLEX16 dirichlet0; if (!uvar.rectWindow) { if (fabsf((REAL4)delta1_0)<(REAL4)1.0e-6) { if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = crect(1.0, 0.0); else if (fabsf((REAL4)(delta0_0*delta0_0-1.0))<(REAL4)1.0e-6) dirichlet0 = crect(-2.0, 0.0); else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) { dirichlet0 = crect(0.0, 0.0); continue; } else dirichlet0 = -LAL_PI*crectf(cos(LAL_PI*delta0_0), -sin(LAL_PI*delta0_0))*delta0_0*(delta0_0*delta0_0 - 1.0)/sin(LAL_PI*delta0_0); } else if (fabsf((REAL4)(delta1_0*delta1_0-1.0))<(REAL4)1.0e-6) { if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = crect(-0.5, 0.0); else if (fabsf((REAL4)(delta0_0*delta0_0-1.0))<(REAL4)1.0e-6) dirichlet0 = crect(1.0, 0.0); else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) { dirichlet0 = crect(0.0, 0.0); continue; } else dirichlet0 = -LAL_PI_2*crectf(-cos(LAL_PI*delta0_0), sin(LAL_PI*delta0_0))*delta0_0*(delta0_0*delta0_0 - 1.0)/sin(LAL_PI*delta0_0); } else if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = -LAL_1_PI*crectf(cos(LAL_PI*delta1_0), sin(LAL_PI*delta1_0))*sin(LAL_PI*delta1_0)/(delta1_0*(delta1_0*delta1_0-1.0)); else if (fabsf((REAL4)(delta0_0*delta0_0-1.0))<(REAL4)1.0e-6) dirichlet0 = LAL_2_PI*crectf(cos(LAL_PI*delta1_0), sin(LAL_PI*delta1_0))*sin(LAL_PI*delta1_0)/(delta1_0*(delta1_0*delta1_0-1.0)); else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) { dirichlet0 = crect(0.0, 0.0); continue; } else dirichlet0 = sin(LAL_PI*delta1_0)/sin(LAL_PI*delta0_0)*(delta0_0*(delta0_0*delta0_0-1.0))/(delta1_0*(delta1_0*delta1_0-1.0))*cpolarf(1.0,LAL_PI*(delta1_0-delta0_0)); } else { if (fabsf((REAL4)delta1_0)<(REAL4)1.0e-6) { if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = crect(1.0, 0.0); else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) { dirichlet0 = crect(0.0, 0.0); continue; } else dirichlet0 = conj(1.0/((cpolar(1.0,LAL_TWOPI*delta0_0)-1.0)/crect(0.0,LAL_TWOPI*delta0_0))); } else if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = conj((cpolar(1.0,LAL_TWOPI*delta1_0)-1.0)/crect(0.0,LAL_TWOPI*delta1_0)); else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) { dirichlet0 = crect(0.0, 0.0); continue; } else dirichlet0 = conj(((cpolar(1.0,LAL_TWOPI*delta1_0)-1.0)/crect(0.0,LAL_TWOPI*delta1_0))/((cpolar(1.0,LAL_TWOPI*delta0_0)-1.0)/crect(0.0,LAL_TWOPI*delta0_0))); } COMPLEX16 dirichlet; if (!uvar.rectWindow) { if (fabsf((REAL4)delta1)<(REAL4)1.0e-6) { if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = crect(1.0, 0.0); else if (fabsf((REAL4)(delta0*delta0-1.0))<(REAL4)1.0e-6) dirichlet = crect(-2.0, 0.0); else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0); else dirichlet = -LAL_PI*crectf(cos(LAL_PI*delta0), -sin(LAL_PI*delta0))*delta0*(delta0*delta0 - 1.0)/sin(LAL_PI*delta0); } else if (fabsf((REAL4)(delta1*delta1-1.0))<(REAL4)1.0e-6) { if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = crect(-0.5, 0.0); else if (fabsf((REAL4)(delta0*delta0-1.0))<(REAL4)1.0e-6) dirichlet = crect(1.0, 0.0); else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0); else dirichlet = -LAL_PI_2*crectf(-cos(LAL_PI*delta0), sin(LAL_PI*delta0))*delta0*(delta0*delta0 - 1.0)/sin(LAL_PI*delta0); } else if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = -LAL_1_PI*crectf(cos(LAL_PI*delta1), sin(LAL_PI*delta1))*sin(LAL_PI*delta1)/(delta1*(delta1*delta1-1.0)); else if (fabsf((REAL4)(delta0*delta0-1.0))<(REAL4)1.0e-6) dirichlet = LAL_2_PI*crectf(cos(LAL_PI*delta1), sin(LAL_PI*delta1))*sin(LAL_PI*delta1)/(delta1*(delta1*delta1-1.0)); else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0); else dirichlet = sin(LAL_PI*delta1)/sin(LAL_PI*delta0)*(delta0*(delta0*delta0-1.0))/(delta1*(delta1*delta1-1.0))*cpolarf(1.0,LAL_PI*(delta1-delta0)); } else { if (fabsf((REAL4)delta1)<(REAL4)1.0e-6) { if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = crect(1.0, 0.0); else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0); else dirichlet = conj(1.0/((cpolar(1.0,LAL_TWOPI*delta0)-1.0)/crect(0.0,LAL_TWOPI*delta0))); } else if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = conj((cpolar(1.0,LAL_TWOPI*delta1)-1.0)/crect(0.0,LAL_TWOPI*delta1)); else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0); else dirichlet = conj(((cpolar(1.0,LAL_TWOPI*delta1)-1.0)/crect(0.0,LAL_TWOPI*delta1))/((cpolar(1.0,LAL_TWOPI*delta0)-1.0)/crect(0.0,LAL_TWOPI*delta0))); } dirichlet = cpolar(1.0, carg(dirichlet)); if (fabs(floor(delta0)-floor(delta1))>=1.0) dirichlet *= -1.0; COMPLEX16 realRatio = RatioTerm0*phaseshift0*conj(dirichlet0); COMPLEX16 estRatio = RatioTerm*phaseshift*conj(dirichlet); fprintf(OUTPUT, "%g %g %g %g\n", cabs(realRatio), gsl_sf_angle_restrict_pos(carg(realRatio)), cabs(estRatio), gsl_sf_angle_restrict_pos(carg(estRatio))); } XLALDestroyMultiAMCoeffs(multiAMcoefficients); XLALDestroyMultiSSBtimes(multissb); } fclose(OUTPUT); gsl_rng_free(rng); XLALDestroyMultiDetectorStateSeries(multiStateSeries); XLALDestroyMultiTimestamps(multiTimestamps); XLALDestroyEphemerisData(edat); XLALFree(detectors); XLALDestroyUserVars(); }
/* Function to compute (multi-IFO) F-statistic for given parameter-space point \a doppler, * normalized SFT-data (normalized by <em>double-sided</em> PSD Sn), noise-weights * and detector state-series * * NOTE: for better efficiency some quantities that need to be recomputed only for different * sky-positions are buffered in \a cfBuffer if given. * - In order to 'empty' this buffer (at the end) use XLALEmptyComputeFBuffer() * - You CAN pass NULL for the \a cfBuffer if you don't want to use buffering (slower). * * NOTE2: there's a spaceholder for binary-pulsar parameters in \a psPoint, but this * it not implemented yet. * */ static int ComputeFStat ( Fcomponents *Fstat, /* [out] Fstatistic + Fa, Fb */ const PulsarDopplerParams *doppler, /* parameter-space point to compute F for */ const MultiSFTVector *multiSFTs, /* normalized (by DOUBLE-sided Sn!) data-SFTs of all IFOs */ const MultiNoiseWeights *multiWeights, /* noise-weights of all SFTs */ const MultiDetectorStateSeries *multiDetStates, /* 'trajectories' of the different IFOs */ const ComputeFParams *params, /* addition computational params */ ComputeFBuffer *cfBuffer /* CF-internal buffering structure */ ) { /* check input */ XLAL_CHECK ( Fstat != NULL, XLAL_EINVAL ); XLAL_CHECK ( multiSFTs != NULL, XLAL_EINVAL ); XLAL_CHECK ( doppler != NULL, XLAL_EINVAL ); XLAL_CHECK ( multiDetStates != NULL, XLAL_EINVAL ); XLAL_CHECK ( params != NULL, XLAL_EINVAL ); UINT4 numDetectors = multiSFTs->length; XLAL_CHECK ( multiDetStates->length == numDetectors, XLAL_EINVAL ); XLAL_CHECK ( multiWeights==NULL || (multiWeights->length == numDetectors), XLAL_EINVAL ); Fcomponents retF = empty_Fcomponents; MultiSSBtimes *multiSSB = NULL; MultiSSBtimes *multiBinary = NULL; const MultiSSBtimes *multiSSBTotal = NULL; MultiAMCoeffs *multiAMcoef = NULL; /* ----- prepare return of 'FstatAtoms' if requested */ if ( params->returnAtoms ) { XLAL_CHECK ( (retF.multiFstatAtoms = XLALMalloc ( sizeof(*retF.multiFstatAtoms) )) != NULL, XLAL_ENOMEM ); retF.multiFstatAtoms->length = numDetectors; XLAL_CHECK ( (retF.multiFstatAtoms->data = XLALMalloc ( numDetectors * sizeof(*retF.multiFstatAtoms->data) )) != NULL, XLAL_ENOMEM ); } /* if returnAtoms */ /* ----- check if that skyposition SSB+AMcoef were already buffered */ if ( cfBuffer && ( cfBuffer->multiDetStates == multiDetStates ) && ( cfBuffer->Alpha == doppler->Alpha ) && ( cfBuffer->Delta == doppler->Delta ) && cfBuffer->multiSSB && cfBuffer->multiAMcoef ) { /* yes ==> reuse */ multiSSB = cfBuffer->multiSSB; multiAMcoef = cfBuffer->multiAMcoef; } /* if have buffered stuff to reuse */ else { SkyPosition skypos; skypos.system = COORDINATESYSTEM_EQUATORIAL; skypos.longitude = doppler->Alpha; skypos.latitude = doppler->Delta; /* compute new AM-coefficients and SSB-times */ XLAL_CHECK ( (multiSSB = XLALGetMultiSSBtimes ( multiDetStates, skypos, doppler->refTime, params->SSBprec )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (multiAMcoef = XLALComputeMultiAMCoeffs ( multiDetStates, multiWeights, skypos )) != NULL, XLAL_EFUNC ); /* store these in buffer if available */ if ( cfBuffer ) { XLALEmptyComputeFBuffer ( cfBuffer ); cfBuffer->multiSSB = multiSSB; cfBuffer->multiAMcoef = multiAMcoef; cfBuffer->Alpha = doppler->Alpha; cfBuffer->Delta = doppler->Delta; cfBuffer->multiDetStates = multiDetStates ; } /* if cfBuffer */ } /* could not reuse previously buffered quantites */ /* new orbital parameter corrections if not already buffered */ if ( doppler->asini > 0 ) { /* compute binary time corrections to the SSB time delays and SSB time derivitive */ XLAL_CHECK ( XLALAddMultiBinaryTimes ( &multiBinary, multiSSB, doppler ) == XLAL_SUCCESS, XLAL_EFUNC ); multiSSBTotal = multiBinary; } else { multiSSBTotal = multiSSB; } REAL8 Ad = multiAMcoef->Mmunu.Ad; REAL8 Bd = multiAMcoef->Mmunu.Bd; REAL8 Cd = multiAMcoef->Mmunu.Cd; REAL8 Dd_inv = 1.0 / multiAMcoef->Mmunu.Dd; REAL8 Ed = 0; /* if requested, prepare for returning single-IFO F-stat vector */ if ( params->returnSingleF ) { retF.numDetectors = numDetectors; XLAL_CHECK ( numDetectors <= PULSAR_MAX_DETECTORS, XLAL_EINVAL, "numDetectors = %d exceeds currently allowed upper value (%d) for returnSingleF=TRUE\n", numDetectors, PULSAR_MAX_DETECTORS ); } /* ----- loop over detectors and compute all detector-specific quantities ----- */ for ( UINT4 X=0; X < numDetectors; X ++) { Fcomponents FcX = empty_Fcomponents; /* for detector-specific FaX, FbX */ if ( (params->Dterms != DTERMS) || params->returnAtoms ) { XLAL_CHECK ( XLALComputeFaFb (&FcX, multiSFTs->data[X], doppler->fkdot, multiSSBTotal->data[X], multiAMcoef->data[X], params) == XLAL_SUCCESS, XLAL_EFUNC ); } else { XLAL_CHECK ( LocalXLALComputeFaFb (&FcX, multiSFTs->data[X], doppler->fkdot, multiSSBTotal->data[X], multiAMcoef->data[X], params) == XLAL_SUCCESS, XLAL_EFUNC ); } if ( params->returnAtoms ) { retF.multiFstatAtoms->data[X] = FcX.multiFstatAtoms->data[0]; /* copy pointer to IFO-specific Fstat-atoms 'contents' */ /* free 'container', but not *contents*, which have been linked above */ XLALFree ( FcX.multiFstatAtoms->data ); XLALFree ( FcX.multiFstatAtoms ); } XLAL_CHECK ( isfinite(creal(FcX.Fa)) && isfinite(cimag(FcX.Fa)) && isfinite(creal(FcX.Fb)) && isfinite(cimag(FcX.Fb)), XLAL_EFPOVRFLW ); /* compute single-IFO F-stats, if requested */ if ( params->returnSingleF ) { REAL8 AdX = multiAMcoef->data[X]->A; REAL8 BdX = multiAMcoef->data[X]->B; REAL8 CdX = multiAMcoef->data[X]->C; REAL8 DdX_inv = 1.0 / multiAMcoef->data[X]->D; REAL8 EdX = 0; REAL8 FXa_re = creal(FcX.Fa); REAL8 FXa_im = cimag(FcX.Fa); REAL8 FXb_re = creal(FcX.Fb); REAL8 FXb_im = cimag(FcX.Fb); /* compute final single-IFO F-stat */ retF.FX[X] = DdX_inv * ( BdX * ( SQ(FXa_re) + SQ(FXa_im) ) + AdX * ( SQ(FXb_re) + SQ(FXb_im) ) - 2.0 * CdX * ( FXa_re * FXb_re + FXa_im * FXb_im ) - 2.0 * EdX * ( - FXa_re * FXb_im + FXa_im * FXb_re ) // nonzero only in RAA case where Ed!=0 ); } /* if returnSingleF */ /* Fa = sum_X Fa_X */ retF.Fa += FcX.Fa; /* Fb = sum_X Fb_X */ retF.Fb += FcX.Fb; } /* for X < numDetectors */ /* ----- compute final Fstatistic-value ----- */ /* NOTE: the data MUST be normalized by the DOUBLE-SIDED PSD (using LALNormalizeMultiSFTVect), * therefore there is a factor of 2 difference with respect to the equations in JKS, which * where based on the single-sided PSD. */ REAL8 Fa_re = creal(retF.Fa); REAL8 Fa_im = cimag(retF.Fa); REAL8 Fb_re = creal(retF.Fb); REAL8 Fb_im = cimag(retF.Fb); retF.F = Dd_inv * ( Bd * ( SQ(Fa_re) + SQ(Fa_im) ) + Ad * ( SQ(Fb_re) + SQ(Fb_im) ) - 2.0 * Cd * ( Fa_re * Fb_re + Fa_im * Fb_im ) - 2.0 * Ed * ( - Fa_re * Fb_im + Fa_im * Fb_re ) // nonzero only in RAA case where Ed!=0 ); /* set correct F-stat reference time (taken from template 'doppler') [relevant only for phase of {Fa,Fb}] */ retF.refTime = doppler->refTime; /* free memory if no buffer was available */ if ( !cfBuffer ) { XLALDestroyMultiSSBtimes ( multiSSB ); XLALDestroyMultiAMCoeffs ( multiAMcoef ); } /* if !cfBuffer */ /* this always needs to be free'ed, as it's no longer buffered */ XLALDestroyMultiSSBtimes ( multiBinary ); /* return final Fstat result */ (*Fstat) = retF; return XLAL_SUCCESS; } // ComputeFStat()
int main(int argc, char *argv[]) { UserVariables_t XLAL_INIT_DECL(uvar); XLAL_CHECK ( InitUserVars(&uvar, argc, argv) == XLAL_SUCCESS, XLAL_EFUNC ); MultiLALDetector *detectors = NULL; XLAL_CHECK( (detectors = XLALMalloc(sizeof(MultiLALDetector))) != NULL, XLAL_ENOMEM ); detectors->length = uvar.IFO->length; for (UINT4 ii=0; ii<detectors->length; ii++) { if (strcmp("H1", uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_LHO_4K_DETECTOR]; //H1 } else if (strcmp("L1",uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_LLO_4K_DETECTOR]; //L1 } else if (strcmp("V1", uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_VIRGO_DETECTOR]; //V1 } else if (strcmp("H2", uvar.IFO->data[ii])==0) { detectors->sites[ii] = lalCachedDetectors[LAL_LHO_2K_DETECTOR]; //H2 } else if (strcmp("H2r", uvar.IFO->data[ii])==0) { LALDetector H2 = lalCachedDetectors[LAL_LHO_2K_DETECTOR]; //H2 rotated H2.frDetector.xArmAzimuthRadians -= 0.25*LAL_PI; H2.frDetector.yArmAzimuthRadians -= 0.25*LAL_PI; memset(&(H2.frDetector.name), 0, sizeof(CHAR)*LALNameLength); snprintf(H2.frDetector.name, LALNameLength, "%s", "LHO_2k_rotatedPiOver4"); XLAL_CHECK( (XLALCreateDetector(&(detectors->sites[ii]), &(H2.frDetector), LALDETECTORTYPE_IFODIFF)) != NULL, XLAL_EFUNC ); } else { XLAL_ERROR(XLAL_EINVAL, "Not using valid interferometer! Expected 'H1', 'H2', 'H2r' (rotated H2), 'L1', or 'V1' not %s.\n", uvar.IFO->data[ii]); } } EphemerisData *edat = NULL; XLAL_CHECK( (edat = XLALInitBarycenter(uvar.ephemEarth, uvar.ephemSun)) != NULL, XLAL_EFUNC ); LIGOTimeGPS tStart; XLALGPSSetREAL8 ( &tStart, uvar.t0 ); XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC, "XLALGPSSetREAL8 failed\n" ); MultiLIGOTimeGPSVector *multiTimestamps = NULL; XLAL_CHECK( (multiTimestamps = XLALMakeMultiTimestamps(tStart, uvar.Tobs, uvar.Tsft, uvar.SFToverlap, detectors->length)) != NULL, XLAL_EFUNC ); LIGOTimeGPS refTime = multiTimestamps->data[0]->data[0]; MultiDetectorStateSeries *multiStateSeries = NULL; XLAL_CHECK( (multiStateSeries = XLALGetMultiDetectorStates(multiTimestamps, detectors, edat, uvar.SFToverlap)) != NULL, XLAL_EFUNC ); gsl_rng *rng = NULL; XLAL_CHECK( (rng = gsl_rng_alloc(gsl_rng_mt19937)) != NULL, XLAL_EFUNC ); gsl_rng_set(rng, 0); FILE *OUTPUT; XLAL_CHECK( (OUTPUT = fopen(uvar.outfilename,"w")) != NULL, XLAL_EIO, "Output file %s could not be opened\n", uvar.outfilename ); for (INT4 n=0; n<uvar.skylocations; n++) { SkyPosition skypos; if (XLALUserVarWasSet(&(uvar.alpha)) && XLALUserVarWasSet(&(uvar.delta)) && n==0) { skypos.longitude = uvar.alpha; skypos.latitude = uvar.delta; skypos.system = COORDINATESYSTEM_EQUATORIAL; } else { skypos.longitude = LAL_TWOPI*gsl_rng_uniform(rng); skypos.latitude = LAL_PI*gsl_rng_uniform(rng) - LAL_PI_2; skypos.system = COORDINATESYSTEM_EQUATORIAL; } REAL8 cosi0, psi0; if (XLALUserVarWasSet(&(uvar.cosi)) && n==0) cosi0 = uvar.cosi; else cosi0 = 2.0*gsl_rng_uniform(rng) - 1.0; if (XLALUserVarWasSet(&(uvar.psi)) && n==0) psi0 = uvar.psi; else psi0 = LAL_PI*gsl_rng_uniform(rng); MultiAMCoeffs *multiAMcoefficients = NULL; XLAL_CHECK( (multiAMcoefficients = XLALComputeMultiAMCoeffs(multiStateSeries, NULL, skypos)) != NULL, XLAL_EFUNC ); MultiSSBtimes *multissb = NULL; XLAL_CHECK( (multissb = XLALGetMultiSSBtimes(multiStateSeries, skypos, refTime, SSBPREC_RELATIVISTICOPT)) != NULL, XLAL_EFUNC ); REAL8 frequency0 = 1000.0 + (gsl_rng_uniform(rng)-0.5)/uvar.Tsft; REAL8 frequency = 1000.0; for (UINT4 ii=0; ii<multiAMcoefficients->data[0]->a->length; ii++) { REAL4 Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi0) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi0); REAL4 Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi0) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi0); REAL4 Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi0) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi0); REAL4 Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi0) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi0); COMPLEX16 RatioTerm0 = crect(0.5*Fplus1*(1.0+cosi0*cosi0), Fcross1*cosi0)/crect(0.5*Fplus0*(1.0+cosi0*cosi0), Fcross0*cosi0); REAL4 detPhaseArg = 0.0, detPhaseMag = 0.0; BOOLEAN loopbroken = 0; for (INT4 jj=0; jj<50 && !loopbroken; jj++) { REAL4 psi = 0.02*jj*LAL_PI; Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi); Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi); Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi); Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi); for (INT4 kk=0; kk<51 && !loopbroken; kk++) { //REAL4 cosi = 1.0 - 2.0*0.02*kk; REAL4 cosi; if (cosi0<0.0) cosi = -0.02*kk; else cosi = 0.02*kk; COMPLEX16 complexnumerator = crect(0.5*Fplus1*(1.0+cosi*cosi), Fcross1*cosi); COMPLEX16 complexdenominator = crect(0.5*Fplus0*(1.0+cosi*cosi) , Fcross0*cosi); if (cabs(complexdenominator)>1.0e-7) { COMPLEX16 complexval = complexnumerator/complexdenominator; detPhaseMag += fmin(cabs(complexval), 10.0); detPhaseArg += gsl_sf_angle_restrict_pos(carg(complexval)); } else { loopbroken = 1; detPhaseMag = 0.0; detPhaseArg = 0.0; } } } detPhaseMag /= 2550.0; detPhaseArg /= 2550.0; REAL8 timediff0 = multissb->data[0]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[0]->Tdot->data[ii]; REAL8 timediff1 = multissb->data[1]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[1]->Tdot->data[ii]; REAL8 tau = timediff1 - timediff0; REAL8 freqshift0 = -LAL_TWOPI*tau*frequency0; REAL8 freqshift = -LAL_TWOPI*tau*frequency; REAL8 nearestFrequency = round(multissb->data[0]->Tdot->data[ii]*frequency*uvar.Tsft)/uvar.Tsft; COMPLEX16 dirichlet0 = conj(DirichletKernelLargeNHann((multissb->data[1]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft)/DirichletKernelLargeNHann((multissb->data[0]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft)); COMPLEX16 dirichlet = conj(DirichletKernelLargeNHann((multissb->data[1]->Tdot->data[ii]*frequency-nearestFrequency)*uvar.Tsft)/DirichletKernelLargeNHann((multissb->data[0]->Tdot->data[ii]*frequency-nearestFrequency)*uvar.Tsft)); COMPLEX16 signal0 = 0.5*crect(0.5*Fplus0*(1.0+cosi0*cosi0), Fcross0*cosi0)*cpolar(1.0, LAL_TWOPI*frequency0*0.5*uvar.Tsft+LAL_TWOPI*frequency0*(multissb->data[0]->DeltaT->data[ii]+multissb->data[0]->Tdot->data[ii]*0.5*uvar.Tsft))*uvar.Tsft*DirichletKernelLargeNHann((multissb->data[0]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft); COMPLEX16 signal1 = 0.5*crect(0.5*Fplus1*(1.0+cosi0*cosi0), Fcross1*cosi0)*cpolar(1.0, LAL_TWOPI*frequency0*0.5*uvar.Tsft+LAL_TWOPI*frequency0*(multissb->data[1]->DeltaT->data[ii]+multissb->data[1]->Tdot->data[ii]*0.5*uvar.Tsft))*uvar.Tsft*DirichletKernelLargeNHann((multissb->data[1]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft); fprintf(OUTPUT, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g\n", cabs(signal0), gsl_sf_angle_restrict_pos(carg(signal0)), cabs(signal1), gsl_sf_angle_restrict_pos(carg(signal1)), cabs(RatioTerm0), gsl_sf_angle_restrict_pos(carg(RatioTerm0)), detPhaseMag, detPhaseArg, freqshift0, freqshift, cabs(dirichlet0), gsl_sf_angle_restrict_pos(carg(dirichlet0)), cabs(dirichlet), gsl_sf_angle_restrict_pos(carg(dirichlet))); //fprintf(OUTPUT, "%g %g %g %g\n", cabs(signal0), gsl_sf_angle_restrict_pos(carg(signal0)), cabs(signal1), gsl_sf_angle_restrict_pos(carg(signal1))); } XLALDestroyMultiAMCoeffs(multiAMcoefficients); XLALDestroyMultiSSBtimes(multissb); } fclose(OUTPUT); gsl_rng_free(rng); XLALDestroyMultiDetectorStateSeries(multiStateSeries); XLALDestroyMultiTimestamps(multiTimestamps); XLALDestroyEphemerisData(edat); XLALFree(detectors); XLALDestroyUserVars(); }
/* ----- function definitions ---------- */ int main(int argc, char *argv[]) { int opt; /* Command-line option. */ UINT4 numIFOs = 2; const CHAR *sites[2] = {"H1", "V1"}; UINT4 startTime = 714180733; UINT4 duration = 180000; /* 50 hours */ UINT4 Tsft = 1800; /* assume 30min SFTs */ REAL8 tolerance = 2e-6; /* same algorithm, should be basically identical results */ char earthEphem[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz"; char sunEphem[] = TEST_DATA_DIR "sun00-19-DE405.dat.gz"; UINT4 numChecks = 1; /* Number of times to check */ /* read user input */ while ((opt = LALgetopt( argc, argv, "n:qv:" )) != -1) { switch (opt) { case 'v': /* set lalDebugLevel */ break; case 'n': /* number of times to check */ numChecks = atoi( LALoptarg ); break; } } /* init random-generator */ struct tms buf; UINT4 seed = times(&buf); srand ( seed ); XLALPrintInfo ("%s: seed used = %d\n", __func__, seed ); /* ----- init ephemeris ----- */ EphemerisData *edat; if ( (edat = XLALInitBarycenter ( earthEphem, sunEphem )) == NULL ) { XLALPrintError ("%s: XLALInitBarycenter() failed with xlalErrno = %d\n", __func__, xlalErrno ); return XLAL_EFAILED; } /* ----- init detector info ---------- */ UINT4 X; MultiLALDetector multiDet; multiDet.length = numIFOs; for (X=0; X < numIFOs; X ++ ) { LALDetector *site; if ( (site = XLALGetSiteInfo ( sites[X] )) == NULL ) { XLALPrintError ("%s: Failed to get site-info for detector '%s'\n", __func__, sites[X] ); return XLAL_EFAILED; } multiDet.sites[X] = (*site); /* copy! */ XLALFree ( site ); } /* ----- init multi-IFO timestamps vector ---------- */ UINT4 numSteps = (UINT4) ceil ( duration / Tsft ); MultiLIGOTimeGPSVector * multiTS; if ( (multiTS = XLALCalloc ( 1, sizeof(*multiTS))) == NULL ) { XLAL_ERROR ( XLAL_ENOMEM ); } multiTS->length = numIFOs; if ( (multiTS->data = XLALCalloc (numIFOs, sizeof(*multiTS->data))) == NULL ) { XLAL_ERROR ( XLAL_ENOMEM ); } for ( X=0; X < numIFOs; X ++ ) { if ( (multiTS->data[X] = XLALCreateTimestampVector (numSteps)) == NULL ) { XLALPrintError ("%s: XLALCreateTimestampVector(%d) failed.\n", __func__, numSteps ); return XLAL_EFAILED; } multiTS->data[X]->deltaT = Tsft; UINT4 i; for ( i=0; i < numSteps; i ++ ) { UINT4 ti = startTime + i * Tsft; multiTS->data[X]->data[i].gpsSeconds = ti; multiTS->data[X]->data[i].gpsNanoSeconds = 0; } /* for i < numSteps */ } /* for X < numIFOs */ /* ---------- compute multi-detector states -------------------- */ MultiDetectorStateSeries *multiDetStates; if ( (multiDetStates = XLALGetMultiDetectorStates ( multiTS, &multiDet, edat, 0.5 * Tsft )) == NULL ) { XLALPrintError ( "%s: XLALGetMultiDetectorStates() failed.\n", __func__ ); return XLAL_EFAILED; } XLALDestroyMultiTimestamps ( multiTS ); XLALDestroyEphemerisData ( edat ); /* ========== MAIN LOOP: N-trials of comparisons XLAL <--> LAL multiAM functions ========== */ while ( numChecks-- ) { LALStatus XLAL_INIT_DECL(status); /* ----- pick skyposition at random ----- */ SkyPosition skypos; skypos.longitude = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) ); /* uniform in [0, 2pi) */ skypos.latitude = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX ); /* sin(delta) uniform in [-1,1] */ skypos.system = COORDINATESYSTEM_EQUATORIAL; MultiNoiseWeights *weights = NULL; /* for now we only deal with unit-weights case */ /* ----- compute multiAM using LAL function ----- */ MultiAMCoeffs *multiAM_LAL = NULL; LALGetMultiAMCoeffs ( &status, &multiAM_LAL, multiDetStates, skypos ); if ( status.statusCode ) { XLALPrintError ("%s: LALGetMultiAMCoeffs() failed with statusCode = %d : %s\n", __func__, status.statusCode, status.statusDescription ); return XLAL_EFAILED; } if ( XLALWeightMultiAMCoeffs ( multiAM_LAL, weights ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALWeightMultiAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); return XLAL_EFAILED; } /* ----- compute multiAM using XLAL function ----- */ MultiAMCoeffs *multiAM_XLAL; if ( ( multiAM_XLAL = XLALComputeMultiAMCoeffs ( multiDetStates, weights, skypos )) == NULL ) { XLALPrintError ("%s: XLALComputeMultiAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); return XLAL_EFAILED; } /* now run comparison */ if ( XLALCompareMultiAMCoeffs ( multiAM_XLAL, multiAM_LAL, tolerance ) != XLAL_SUCCESS ) { XLALPrintError ("%s: comparison between multiAM_XLAL and multiAM_LAL failed.\n", __func__ ); return XLAL_EFAILED; } /* free memory created inside this loop */ XLALDestroyMultiAMCoeffs ( multiAM_LAL ); XLALDestroyMultiAMCoeffs ( multiAM_XLAL ); } /* for numChecks */ /* we're done: free memory */ XLALDestroyMultiDetectorStateSeries ( multiDetStates ); LALCheckMemoryLeaks(); printf ("OK. All tests passed successfully\n\n"); return 0; /* OK */ } /* main() */
/** * Generates a multi-Fstat atoms vector for given parameters, drawing random parameters wherever required. * * Input: detector states, signal sky-pos (or allsky), amplitudes (or range), transient window range * */ MultiFstatAtomVector * XLALSynthesizeTransientAtoms ( InjParams_t *injParamsOut, /**< [out] return summary of injected signal parameters (can be NULL) */ SkyPosition skypos, /**< (Alpha,Delta,system). Use Alpha < 0 to signal 'allsky' */ AmplitudePrior_t AmpPrior, /**< [in] amplitude-parameter priors to draw signals from */ transientWindowRange_t transientInjectRange, /**< transient-window range for injections (flat priors) */ const MultiDetectorStateSeries *multiDetStates, /**< [in] multi-detector state series covering observation time */ BOOLEAN SignalOnly, /**< [in] switch to generate signal draws without noise */ multiAMBuffer_t *multiAMBuffer, /**< [in/out] buffer for AM-coefficients if re-using same skyposition (must be !=NULL) */ gsl_rng *rng, /**< [in/out] gsl random-number generator */ INT4 lineX, /**< [in] if >= 0: generate signal only for detector 'lineX': must be within 0,...(Ndet-1) */ const MultiNoiseWeights *multiNoiseWeights /** [in] per-detector noise weights SX^-1/S^-1, no per-SFT variation (can be NULL for unit weights) */ ) { /* check input */ XLAL_CHECK_NULL ( rng && multiAMBuffer && multiDetStates, XLAL_EINVAL, "Invalid NULL input!\n"); XLAL_CHECK_NULL ( !multiNoiseWeights || multiNoiseWeights->data, XLAL_EINVAL, "Invalid NULL input for multiNoiseWeights->data!\n" ); /* ----- if Alpha < 0 ==> draw skyposition isotropically from all-sky */ if ( skypos.longitude < 0 ) { skypos.longitude = gsl_ran_flat ( rng, 0, LAL_TWOPI ); /* alpha uniform in [ 0, 2pi ] */ skypos.latitude = acos ( gsl_ran_flat ( rng, -1, 1 ) ) - LAL_PI_2; /* cos(delta) uniform in [ -1, 1 ] */ skypos.system = COORDINATESYSTEM_EQUATORIAL; /* never re-using buffered AM-coeffs here, as we randomly draw new skypositions */ if ( multiAMBuffer->multiAM ) XLALDestroyMultiAMCoeffs ( multiAMBuffer->multiAM ); multiAMBuffer->multiAM = NULL; } /* if random skypos to draw */ else /* otherwise: re-use AM-coeffs if already computed, or initialize them if for the first time */ { if ( multiAMBuffer->multiAM ) if ( multiAMBuffer->skypos.longitude != skypos.longitude || multiAMBuffer->skypos.latitude != skypos.latitude || multiAMBuffer->skypos.system != skypos.system ) { XLALDestroyMultiAMCoeffs ( multiAMBuffer->multiAM ); multiAMBuffer->multiAM = NULL; } } /* if single skypos given */ /* ----- generate antenna-pattern functions for this sky-position */ if ( !multiAMBuffer->multiAM && (multiAMBuffer->multiAM = XLALComputeMultiAMCoeffs ( multiDetStates, multiNoiseWeights, skypos )) == NULL ) { XLALPrintError ( "%s: XLALComputeMultiAMCoeffs() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } multiAMBuffer->skypos = skypos; /* store buffered skyposition */ /* ----- generate a pre-initialized F-stat atom vector containing only the antenna-pattern coefficients */ MultiFstatAtomVector *multiAtoms; if ( (multiAtoms = XLALGenerateMultiFstatAtomVector ( multiDetStates, multiAMBuffer->multiAM )) == NULL ) { XLALPrintError ( "%s: XLALGenerateMultiFstatAtomVector() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* ----- draw amplitude vector A^mu from given ranges in {h0, cosi, psi, phi0} */ PulsarAmplitudeParams Amp; if ( AmpPrior.fixedSNR > 0 ) /* special treatment of fixed-SNR: use h0=1, later rescale signal */ Amp.h0 = 1.0; else if ( AmpPrior.fixedSNR == 0 )/* same as setting h0 = 0 */ Amp.h0 = 0; else /* otherwise, draw from h0-prior */ Amp.h0 = XLALDrawFromPDF1D ( AmpPrior.pdf_h0Nat, rng ); Amp.cosi = XLALDrawFromPDF1D ( AmpPrior.pdf_cosi, rng ); Amp.psi = XLALDrawFromPDF1D ( AmpPrior.pdf_psi, rng ); Amp.phi0 = XLALDrawFromPDF1D ( AmpPrior.pdf_phi0, rng ); /* convert amplitude params to 'canonical' vector coordinates */ PulsarAmplitudeVect A_Mu; if ( XLALAmplitudeParams2Vect ( A_Mu, Amp ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALAmplitudeParams2Vect() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* ----- draw transient-window parameters from given ranges using flat priors */ transientWindow_t XLAL_INIT_DECL(injectWindow); injectWindow.type = transientInjectRange.type; if ( injectWindow.type != TRANSIENT_NONE ) /* nothing to be done if no window */ { injectWindow.t0 = (UINT4) gsl_ran_flat ( rng, transientInjectRange.t0, transientInjectRange.t0 + transientInjectRange.t0Band ); injectWindow.tau = (UINT4) gsl_ran_flat ( rng, transientInjectRange.tau, transientInjectRange.tau + transientInjectRange.tauBand ); } /* ----- add transient signal to the Fstat atoms */ AntennaPatternMatrix M_mu_nu; REAL8 rho2 = XLALAddSignalToMultiFstatAtomVector ( multiAtoms, &M_mu_nu, A_Mu, injectWindow, lineX ); if ( xlalErrno ) { XLALPrintError ( "%s: XLALAddSignalToMultiFstatAtomVector() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* ----- special signal rescaling if 1) fixedSNR OR 2) fixed rhohMax */ REAL8 detM1o8 = sqrt ( M_mu_nu.Sinv_Tsft ) * pow ( M_mu_nu.Dd, 0.25 ); // (detM)^(1/8) = sqrt(Tsft/Sn) * (Dp)^(1/4) /* 1) if fixedSNR signal is requested: rescale everything to the desired SNR now */ if ( (AmpPrior.fixedSNR > 0) || AmpPrior.fixRhohMax ) { if ( (AmpPrior.fixedSNR > 0) && AmpPrior.fixRhohMax ) { /* double-check consistency: only one is allowed */ XLALPrintError ("%s: Something went wrong: both [fixedSNR = %f > 0] and [fixedRhohMax==true] are not allowed!\n", __func__, AmpPrior.fixedSNR ); XLAL_ERROR_NULL ( XLAL_EDOM ); } REAL8 rescale = 1.0; if ( AmpPrior.fixedSNR > 0 ) rescale = AmpPrior.fixedSNR / sqrt(rho2); // rescale atoms by this factor, such that SNR = fixedSNR if ( AmpPrior.fixRhohMax ) rescale = 1.0 / detM1o8; // we drew h0 in [0, rhohMax], so we now need to rescale as h0Max = rhohMax/(detM)^(1/8) if ( XLALRescaleMultiFstatAtomVector ( multiAtoms, rescale ) != XLAL_SUCCESS ) { /* rescale atoms */ XLALPrintError ( "%s: XLALRescaleMultiFstatAtomVector() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } Amp.h0 *= rescale; /* rescale amplitude-params for consistency */ UINT4 i; for (i=0; i < 4; i ++) A_Mu[i] *= rescale; rho2 *= SQ(rescale); /* rescale reported optimal SNR */ } /* if fixedSNR > 0 OR fixedRhohMax */ /* ----- add noise to the Fstat atoms, unless --SignalOnly was specified */ if ( !SignalOnly ) if ( XLALAddNoiseToMultiFstatAtomVector ( multiAtoms, rng ) != XLAL_SUCCESS ) { XLALPrintError ("%s: XLALAddNoiseToMultiFstatAtomVector() failed with xlalErrno = %d\n", __func__, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* ----- if requested: return all inject signal parameters */ if ( injParamsOut ) { injParamsOut->skypos = skypos; injParamsOut->ampParams = Amp; UINT4 i; for (i=0; i < 4; i ++) injParamsOut->ampVect[i] = A_Mu[i]; injParamsOut->multiAM = *multiAMBuffer->multiAM; injParamsOut->transientWindow = injectWindow; injParamsOut->SNR = sqrt(rho2); injParamsOut->detM1o8 = detM1o8; } /* if injParamsOut */ return multiAtoms; } /* XLALSynthesizeTransientAtoms() */