Exemple #1
0
/**
 * Get the 'detector state' (ie detector-tensor, position, velocity, etc) for the given
 * multi-vector of SFTs, shifted by a common time-shift \a tOffset.
 *
 * \a tOffset allows one to easily use the midpoints of SFT-timestamps, for example.
 *
 */
MultiDetectorStateSeries *
XLALGetMultiDetectorStatesFromMultiSFTs(
  const MultiSFTVector *multiSFTs,		/**< [in] multi-IFO SFTs */
  const EphemerisData *edat,			/**< [in] ephemeris data */
  REAL8 tOffset					/**< [in] shift all timestamps by this amount */
  )
{

  // Check input
  XLAL_CHECK_NULL( multiSFTs != NULL, XLAL_EFAULT );
  XLAL_CHECK_NULL( edat != NULL, XLAL_EFAULT );

  // XLALGetMultiDetectorStates() wants detector-array and timestamps-vectors directly,
  // instead of a multi-SFT vector. We therefore need to extract this info from the
  // multi-SFT vector first
  MultiLALDetector multiIFO;
  XLAL_CHECK_NULL( XLALMultiLALDetectorFromMultiSFTs ( &multiIFO, multiSFTs ) == XLAL_SUCCESS, XLAL_EFUNC );
  MultiLIGOTimeGPSVector *multiTS;
  XLAL_CHECK_NULL( ( multiTS = XLALExtractMultiTimestampsFromSFTs ( multiSFTs )) != NULL, XLAL_EFUNC );

  // call XLALGetMultiDetectorStates()
  MultiDetectorStateSeries *ret = NULL;
  XLAL_CHECK_NULL( ( ret = XLALGetMultiDetectorStates( multiTS, &multiIFO, edat, tOffset )) != NULL, XLAL_EFUNC );

  // free temporary mem
  XLALDestroyMultiTimestamps ( multiTS );

  return ret;

} /* XLALGetMultiDetectorStatesFromMultiSFTs() */
/**
 * This routine frees up all the memory.
 */
int
XLALFreeMem ( ConfigVars_t *cfg )
{
  XLAL_CHECK ( cfg != NULL, XLAL_EINVAL );

  /* Free config-Variables and userInput stuff */
  XLALDestroyUserVars();

  /* free timestamps if any */
  XLALDestroyMultiTimestamps ( cfg->multiTimestamps );

  XLALFree ( cfg->VCSInfoString );

  // free noise-SFT catalog
  XLALDestroySFTCatalog ( cfg->noiseCatalog );
  XLALDestroyMultiSFTCatalogView ( cfg->multiNoiseCatalogView );

  // free noise time-series data
  XLALDestroyMultiREAL8TimeSeries ( cfg->inputMultiTS );

  /* Clean up earth/sun Ephemeris tables */
  XLALDestroyEphemerisData ( cfg->edat );

  return XLAL_SUCCESS;

} /* XLALFreeMem() */
/**
 * Deprecated LAL wrapper to XLALGetMultiDetectorStates().
 * Get the detector-time series for the given MultiSFTVector.
 * (see LALGetDetectorStates() for more comments).
 *
 * \note The time-series is based on the <em>midpoints</em> of the SFT-timestamps.
 */
void
LALGetMultiDetectorStates( LALStatus *status,				/**< pointer to LALStatus structure */
			   MultiDetectorStateSeries **mdetStates, 	/**< [out] multi-IFO detector-states */
			   const MultiSFTVector *multiSFTs, 		/**< [in] multi-IFO SFTs */
			   const EphemerisData *edat )			/**< ephemeris data */
{
  INITSTATUS(status);

  ASSERT ( mdetStates, status, DETECTORSTATES_ENULL, DETECTORSTATES_MSGENULL);
  ASSERT ( multiSFTs, status, DETECTORSTATES_ENULL, DETECTORSTATES_MSGENULL);
  ASSERT ( *mdetStates == NULL, status, DETECTORSTATES_ENONULL, DETECTORSTATES_MSGENONULL);

  /* NOTE API change: XLAL-function wants detector-array and timestamps-vectors directly,
   * instead of a multi-SFT vector. We therefore need to extract this info from the
   * multi-SFT vector first
   */
  MultiLALDetector multiIFO;
  if ( XLALMultiLALDetectorFromMultiSFTs ( &multiIFO, multiSFTs ) != XLAL_SUCCESS ) {
    XLALPrintError ("%s: XLALMultiLALDetectorFromMultiSFTs() failed with code %d\n", __func__, xlalErrno );
    ABORT ( status, DETECTORSTATES_EXLAL, DETECTORSTATES_MSGEXLAL );
  }

  MultiLIGOTimeGPSVector *multiTS;
  if ( ( multiTS = XLALExtractMultiTimestampsFromSFTs ( multiSFTs )) == NULL ) {
    XLALPrintError ("%s: XLALExtractMultiTimestampsFromSFTs() failed with code %d\n", __func__, xlalErrno );
    ABORT ( status, DETECTORSTATES_EXLAL, DETECTORSTATES_MSGEXLAL );
  }

  /* ---------- central wrapper: call XLAL function XLALGetMultiDetectorStates() ---------- */
  MultiDetectorStateSeries *ret = NULL;
  /* the API of this LAL interface specifies a hardcoded shift by Tsft/2 of all timestamps */
  REAL8 Tsft = 1.0 / multiSFTs->data[0]->data[0].deltaF;
  REAL8 tOffset = 0.5 * Tsft;
  if ( ( ret = XLALGetMultiDetectorStates( multiTS, &multiIFO, edat, tOffset )) == NULL ) {
    XLALPrintError ("%s: XLALGetMultiDetectorStates() failed with code %d\n", __func__, xlalErrno );
    XLALDestroyMultiTimestamps ( multiTS );
    ABORT ( status, DETECTORSTATES_EXLAL, DETECTORSTATES_MSGEXLAL );
  }

  /* free temporary mem */
  XLALDestroyMultiTimestamps ( multiTS );

  (*mdetStates) = ret;

  RETURN ( status );

} /* LALGetMultiDetectorStates() */
/** Destructor for internal configuration struct */
int
XLALDestroyConfig ( ConfigVariables *cfg )
{
  XLAL_CHECK ( cfg != NULL, XLAL_EINVAL );

  XLALDestroyUserVars ();

  XLALDestroyREAL8Vector ( cfg->Alpha );
  XLALDestroyREAL8Vector ( cfg->Delta );

  XLALDestroyMultiTimestamps ( cfg->multiTimestamps );
  XLALDestroyUINT4Vector ( cfg->numTimeStampsX );

  XLALDestroyEphemerisData ( cfg->edat );

  XLALDestroyMultiDetectorStateSeries ( cfg->multiDetStates );
  XLALDestroyMultiNoiseWeights ( cfg->multiNoiseWeights );

  return XLAL_SUCCESS;

} /* XLALDestroyConfig() */
/* ----- function definitions ---------- */
int
main ( int argc, char *argv[] )
{
  LALStatus status;
  UserInput_t uvar_s;
  UserInput_t *uvar = &uvar_s;

  INIT_MEM ( status );
  INIT_MEM ( uvar_s );

  struct tms buf;
  uvar->randSeed = times(&buf);

  // ---------- register all our user-variable ----------
  XLALregBOOLUserStruct (  help,                'h', UVAR_HELP    , "Print this help/usage message");
  XLALregINTUserStruct (   randSeed,             's', UVAR_OPTIONAL, "Specify random-number seed for reproducible noise.");

  /* read cmdline & cfgfile  */
  XLAL_CHECK ( XLALUserVarReadAllInput ( argc, argv ) == XLAL_SUCCESS, XLAL_EFUNC );
  if ( uvar->help ) {	/* if help was requested, we're done */
    exit (0);
  }

  srand ( uvar->randSeed );

  REAL8 startTimeREAL8 	= 714180733;
  REAL8 duration 	= 180000;	/* 50 hours */
  REAL8 Tsft 		= 1800;		/* assume 30min SFTs */
  char earthEphem[] 	= TEST_DATA_DIR "earth00-19-DE200.dat.gz";
  char sunEphem[]   	= TEST_DATA_DIR "sun00-19-DE200.dat.gz";

  //REAL8 tolerance = 2e-10;	/* same algorithm, should be basically identical results */

  LIGOTimeGPS startTime, refTime;
  XLALGPSSetREAL8 ( &startTime, startTimeREAL8 );
  refTime = startTime;

  // pick skyposition at random ----- */
  SkyPosition skypos;
  skypos.longitude = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) );  // alpha 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;

  // pick binary orbital parameters:
  // somewhat inspired by Sco-X1 parameters from S2-paper (PRD76, 082001 (2007), gr-qc/0605028)
  // but with a more extreme eccentricity, and random argp
  REAL8 argp = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) );	// uniform in [0, 2pi)
  BinaryOrbitParams orbit;
  XLALGPSSetREAL8 ( &orbit.tp, 731163327 ); 	// time of observed periapsis passage (in SSB)
  orbit.argp = argp;		// argument of periapsis (radians)
  orbit.asini = 1.44;           // projected, normalized orbital semi-major axis (s) */
  orbit.ecc = 1e-2;             // relatively large value, for better testing
  orbit.period = 68023;		// period (s) : about ~18.9h

  // ----- step 0: prepare test-case input for calling the BinarySSB-functions
  // setup detectors
  const char *sites[3] = { "H1", "L1", "V1" };
  UINT4 numDetectors = sizeof( sites ) / sizeof ( sites[0] );

  MultiLALDetector multiIFO;
  multiIFO.length = numDetectors;
  for ( UINT4 X = 0; X < numDetectors; X ++ )
    {
      LALDetector *det = XLALGetSiteInfo ( sites[X] );
      XLAL_CHECK ( det != NULL, XLAL_EFUNC, "XLALGetSiteInfo ('%s') failed for detector X=%d\n", sites[X], X );
      multiIFO.sites[X] = (*det);	 // struct copy
      XLALFree ( det );
    }

  // load ephemeris
  EphemerisData *edat = XLALInitBarycenter ( earthEphem, sunEphem );
  XLAL_CHECK ( edat != NULL, XLAL_EFUNC, "XLALInitBarycenter('%s','%s') failed\n", earthEphem, sunEphem );

  // setup multi-timeseries
  MultiLIGOTimeGPSVector *multiTS;

  XLAL_CHECK ( (multiTS = XLALCalloc ( 1, sizeof(*multiTS))) != NULL, XLAL_ENOMEM );
  XLAL_CHECK ( (multiTS->data = XLALCalloc (numDetectors, sizeof(*multiTS->data))) != NULL, XLAL_ENOMEM );
  multiTS->length = numDetectors;

  for ( UINT4 X = 0; X < numDetectors; X ++ )
    {
      multiTS->data[X] = XLALMakeTimestamps ( startTime, duration, Tsft, 0 );
      XLAL_CHECK ( multiTS->data[X] != NULL, XLAL_EFUNC, "XLALMakeTimestamps() failed.\n");
    } /* for X < numIFOs */

  // generate detector-states
  MultiDetectorStateSeries *multiDetStates = XLALGetMultiDetectorStates ( multiTS, &multiIFO, edat, 0 );
  XLAL_CHECK ( multiDetStates != NULL, XLAL_EFUNC, "XLALGetMultiDetectorStates() failed.\n");

  // generate isolated-NS SSB times
  MultiSSBtimes *multiSSBIn = XLALGetMultiSSBtimes ( multiDetStates, skypos, refTime, SSBPREC_RELATIVISTICOPT );
  XLAL_CHECK ( multiSSBIn != NULL, XLAL_EFUNC, "XLALGetMultiSSBtimes() failed.\n");

  // ----- step 1: compute reference-result using old LALGetMultiBinarytimes()
  MultiSSBtimes *multiBinary_ref = NULL;
  LALGetMultiBinarytimes (&status, &(multiBinary_ref), multiSSBIn, multiDetStates, &orbit, refTime );
  XLAL_CHECK ( status.statusCode == 0, XLAL_EFAILED, "LALGetMultiBinarytimes() failed with status = %d : '%s'\n", status.statusCode, status.statusDescription );

  // ----- step 2: compute test-result using new XLALAddMultiBinaryTimes()
  MultiSSBtimes *multiBinary_test = NULL;
  PulsarDopplerParams doppler;
  memset(&doppler, 0, sizeof(doppler));
  doppler.tp = orbit.tp;
  doppler.argp = orbit.argp;
  doppler.asini = orbit.asini;
  doppler.ecc = orbit.ecc;
  doppler.period = orbit.period;
  XLAL_CHECK ( XLALAddMultiBinaryTimes ( &multiBinary_test, multiSSBIn, &doppler ) == XLAL_SUCCESS, XLAL_EFUNC );

  // ----- step 3: compare results
  REAL8 err_DeltaT, err_Tdot;
  REAL8 tolerance = 1e-10;
  int ret = XLALCompareMultiSSBtimes ( &err_DeltaT, &err_Tdot, multiBinary_ref, multiBinary_test );
  XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALCompareMultiSSBtimes() failed.\n");

  XLALPrintWarning ( "INFO: err(DeltaT) = %g, err(Tdot) = %g\n", err_DeltaT, err_Tdot );

  XLAL_CHECK ( err_DeltaT < tolerance, XLAL_ETOL, "error(DeltaT) = %g exceeds tolerance of %g\n", err_DeltaT, tolerance );
  XLAL_CHECK ( err_Tdot   < tolerance, XLAL_ETOL, "error(Tdot) = %g exceeds tolerance of %g\n", err_Tdot, tolerance );

  // ---- step 4: clean-up memory
  XLALDestroyUserVars();
  XLALDestroyEphemerisData ( edat );
  XLALDestroyMultiSSBtimes ( multiBinary_test );
  XLALDestroyMultiSSBtimes ( multiBinary_ref );
  XLALDestroyMultiSSBtimes ( multiSSBIn );
  XLALDestroyMultiTimestamps ( multiTS );
  XLALDestroyMultiDetectorStateSeries ( multiDetStates );

  // check for memory-leaks
  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} // 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;
}
Exemple #7
0
/** Initialize Fstat-code: handle user-input and set everything up. */
int
XLALInitCode ( ConfigVariables *cfg, const UserInput_t *uvar )
{
  /* generate log-string for file-output, containing cmdline-options + code VCS version info */
  char *vcs;
  if ( (vcs = XLALGetVersionString(0)) == NULL ) {	  /* short VCS version string */
    XLALPrintError ( "%s: XLALGetVersionString(0) failed with errno=%d.\n", __func__, xlalErrno );
    XLAL_ERROR ( XLAL_EFUNC );
  }
  char *cmdline;
  if ( (cmdline = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) == NULL ) {
    XLALPrintError ( "%s: XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE ) failed with errno=%d.\n", __func__, xlalErrno );
    XLAL_ERROR ( XLAL_EFUNC );
  }
  const char fmt[] = "%%%% cmdline: %s\n%%%%\n%s%%%%\n";
  UINT4 len = strlen(vcs) + strlen(cmdline) + strlen(fmt) + 1;
  if ( ( cfg->logString = XLALMalloc ( len  )) == NULL ) {
    XLALPrintError ("%s: XLALMalloc ( %d ) failed.\n", __func__, len );
    XLAL_ERROR ( XLAL_ENOMEM );
  }
  sprintf ( cfg->logString, fmt, cmdline, vcs );
  XLALFree ( cmdline );
  XLALFree ( vcs );

  /* trivial settings from user-input */
  cfg->SignalOnly = uvar->SignalOnly;

  /* ----- parse user-input on signal amplitude-paramters + ranges ----- */
  /* skypos */
  cfg->skypos.longitude = uvar->Alpha;	/* Alpha < 0 indicates 'allsky' */
  cfg->skypos.latitude  = uvar->Delta;
  cfg->skypos.system = COORDINATESYSTEM_EQUATORIAL;

  /* ----- amplitude-params: create prior pdfs reflecting the user-input */
  if ( XLALInitAmplitudePrior ( &cfg->AmpPrior, uvar ) != XLAL_SUCCESS )
    XLAL_ERROR ( XLAL_EFUNC );

  /* ----- initialize random-number generator ----- */
  /* read out environment variables GSL_RNG_xxx
   * GSL_RNG_SEED: use to set random seed: default = 0, override by using --randSeed on cmdline
   * GSL_RNG_TYPE: type of random-number generator to use: default = 'mt19937'
   */
  gsl_rng_env_setup ();
  /* allow overriding the random-seed per command-line */
  if ( XLALUserVarWasSet ( &uvar->randSeed ) )
    gsl_rng_default_seed = uvar->randSeed;
  cfg->rng = gsl_rng_alloc (gsl_rng_default);

  LogPrintf ( LOG_DEBUG, "random-number generator type: %s\n", gsl_rng_name (cfg->rng));
  LogPrintf ( LOG_DEBUG, "seed = %lu\n", gsl_rng_default_seed );

  /* init ephemeris-data */
  EphemerisData *edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun );
  if ( !edat ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", __func__, uvar->ephemEarth, uvar->ephemSun);
    XLAL_ERROR ( XLAL_EFUNC );
  }

  UINT4 numDetectors = uvar->IFOs->length;
  MultiLALDetector multiDet;
  XLAL_CHECK ( XLALParseMultiLALDetector ( &multiDet, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* init timestamps vector covering observation time */
  UINT4 numSteps = (UINT4) ceil ( uvar->dataDuration / uvar->TAtom );
  MultiLIGOTimeGPSVector * multiTS;
  if ( (multiTS = XLALCreateMultiLIGOTimeGPSVector (numDetectors)) == NULL ) {
     XLALPrintError ("%s: XLALCreateMultiLIGOTimeGPSVector(%d) failed.\n", __func__, numDetectors );
  }

  for ( UINT4 X=0; X < numDetectors; X++ )    {
    if ( (multiTS->data[X] = XLALCreateTimestampVector (numSteps)) == NULL ) {
      XLALPrintError ("%s: XLALCreateTimestampVector(%d) failed.\n", __func__, numSteps );
    }
    multiTS->data[X]->deltaT = uvar->TAtom;
    UINT4 i;
    for ( i=0; i < numSteps; i ++ )
      {
	UINT4 ti = uvar->dataStartGPS + i * uvar->TAtom;
	multiTS->data[X]->data[i].gpsSeconds = ti;
	multiTS->data[X]->data[i].gpsNanoSeconds = 0;
      }
  }

  /* get detector states */
  if ( (cfg->multiDetStates = XLALGetMultiDetectorStates ( multiTS, &multiDet, edat, 0.5 * uvar->TAtom )) == NULL ) {
    XLALPrintError ( "%s: XLALGetMultiDetectorStates() failed.\n", __func__ );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  if ( uvar->sqrtSX ) { /* translate user-input PSD sqrt(SX) to noise-weights (this actually does not care whether they were normalized or not) */

    /* parse input comma-separated list */
    MultiNoiseFloor multiNoiseFloor;
    XLAL_CHECK ( XLALParseMultiNoiseFloor ( &multiNoiseFloor, uvar->sqrtSX, numDetectors ) == XLAL_SUCCESS, XLAL_EFUNC );

    /* translate to noise weights */
    XLAL_CHECK ( ( cfg->multiNoiseWeights = XLALComputeConstantMultiNoiseWeightsFromNoiseFloor ( &multiNoiseFloor, multiTS, uvar->TAtom ) ) != NULL, XLAL_EFUNC );

  } /* if ( uvar->sqrtSX ) */

  /* get rid of all temporary memory allocated for this step */
  XLALDestroyEphemerisData ( edat );
  XLALDestroyMultiTimestamps ( multiTS );
  multiTS = NULL;

  /* ---------- initialize transient window ranges, for injection ... ---------- */
  cfg->transientInjectRange.type = TRANSIENT_NONE;			/* default: no transient signal window */
  /* apply correct defaults if unset: t0=dataStart, t0Band=dataDuration-3*tauMax */
//   cfg->transientInjectRange.t0 = uvar->dataStartGPS + uvar->injectWindow_t0Days * DAY24;

  cfg->transientSearchRange = cfg->transientInjectRange;
  return XLAL_SUCCESS;

} /* XLALInitCode() */
// ---------- main ----------
int
main ( int argc, char *argv[] )
{
  // ---------- handle user input ----------
  UserInput_t XLAL_INIT_DECL(uvar_s);
  UserInput_t *uvar = &uvar_s;

  uvar->FstatMethod = XLALStringDuplicate("ResampBest");
  uvar->Freq = 100;
  uvar->f1dot = -3e-9;
  uvar->FreqResolution = XLALCreateREAL8Vector ( 2 );
  uvar->FreqResolution->data[0] = 1;
  uvar->FreqResolution->data[1] = 10;
  uvar->numFreqBins = XLALCreateINT4Vector ( 2 );
  uvar->numFreqBins->data[0] = 1000;
  uvar->numFreqBins->data[1] = 100000;
  uvar->Tseg = 60 * 3600;
  uvar->numSegments = 90;
  uvar->numTrials = 1;

  uvar->Tsft = 1800;
  uvar->runBuffered = 0;

  XLAL_CHECK ( (uvar->IFOs = XLALCreateStringVector ( "H1", NULL )) != NULL, XLAL_EFUNC );
  uvar->outputInfo = NULL;

  XLAL_CHECK ( XLALRegisterUvarMember ( help,           BOOLEAN,        'h', HELP,    "Print help message" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( FstatMethod,    STRING,         0, OPTIONAL,  XLALFstatMethodHelpString() ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( Freq,           REAL8,          0, OPTIONAL,  "Search frequency in Hz" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( f1dot,          REAL8,          0, OPTIONAL,  "Search spindown f1dot in Hz/s" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( FreqResolution, REAL8Vector,    0, OPTIONAL,  "Range of frequency resolution factor 'r' (st dFreq = 1/(r*T)) [2-number range input]" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( Tseg,           REAL8,          0, OPTIONAL,  "Coherent segment length" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( numSegments,    INT4,           0, OPTIONAL,  "Number of semi-coherent segment" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( numFreqBins,    INT4Vector,     0, OPTIONAL,  "Range of number of frequency bins to search [2-number range input]" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( IFOs,    	STRINGVector,   0, OPTIONAL,  "IFOs to use" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( numTrials,    	INT4,           0, OPTIONAL,  "Number of repeated trials to run (with potentially randomized parameters)" ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLAL_CHECK ( XLALRegisterUvarMember ( outputInfo,     STRING,         0, OPTIONAL, "Append Resampling internal info into this file") == XLAL_SUCCESS, XLAL_EFUNC );

  XLAL_CHECK ( XLALRegisterUvarMember ( Tsft,           REAL8,          0, DEVELOPER, "SFT length" ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember ( runBuffered,    BOOLEAN,        0, DEVELOPER, "Explicitly time buffered Fstat call (only useful for double-checking and Demod timing)" ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLAL_CHECK ( XLALUserVarReadAllInput(argc, argv) == XLAL_SUCCESS, XLAL_EFUNC );
  if (uvar->help) {	// if help was requested, we're done here
    return XLAL_SUCCESS;
  }
  // check user input
  XLAL_CHECK ( uvar->numSegments >= 1, XLAL_EINVAL );
  XLAL_CHECK ( (uvar->FreqResolution->length == 1) || (uvar->FreqResolution->length == 2), XLAL_EINVAL );
  XLAL_CHECK ( uvar->FreqResolution->data[0] > 0, XLAL_EINVAL );
  REAL8 FreqResolutionMin, FreqResolutionMax;
  FreqResolutionMin = FreqResolutionMax = uvar->FreqResolution->data[0];
  if ( uvar->FreqResolution->length == 2 )
    {
      XLAL_CHECK ( uvar->FreqResolution->data[1] > 0, XLAL_EINVAL );
      XLAL_CHECK ( uvar->FreqResolution->data[1] > uvar->FreqResolution->data[0], XLAL_EINVAL );
      FreqResolutionMax = uvar->FreqResolution->data[1];
    }

  XLAL_CHECK ( uvar->Freq > 0, XLAL_EINVAL );
  XLAL_CHECK ( uvar->Tseg > uvar->Tsft, XLAL_EINVAL );
  XLAL_CHECK ( uvar->Tsft > 1, XLAL_EINVAL );
  XLAL_CHECK ( (uvar->numFreqBins->length == 1) || (uvar->numFreqBins->length == 2), XLAL_EINVAL );
  XLAL_CHECK ( uvar->numFreqBins->data[0] > 0, XLAL_EINVAL );
  UINT4 numFreqBinsMax, numFreqBinsMin;
  numFreqBinsMin = numFreqBinsMax = uvar->numFreqBins->data[0];
  if ( uvar->numFreqBins->length == 2 )
    {
      XLAL_CHECK ( uvar->numFreqBins->data[1] > 0, XLAL_EINVAL );
      XLAL_CHECK ( uvar->numFreqBins->data[1] > uvar->numFreqBins->data[0], XLAL_EINVAL );
      numFreqBinsMax = uvar->numFreqBins->data[1];
    }

  XLAL_CHECK ( uvar->numTrials >= 1, XLAL_EINVAL );
  // ---------- end: handle user input ----------

  // common setup over repeated trials
  FstatMethodType FstatMethod;
  XLAL_CHECK ( XLALParseFstatMethodString ( &FstatMethod, uvar->FstatMethod ) == XLAL_SUCCESS, XLAL_EFUNC );

  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 );
  REAL8 memBase = XLALGetPeakHeapUsageMB();

  UINT4 numDetectors = uvar->IFOs->length;
  // ----- setup injection and data parameters
  LIGOTimeGPS startTime = {711595934, 0};
  LIGOTimeGPS startTime_l = startTime;
  LIGOTimeGPS endTime_l;
  SFTCatalog **catalogs;
  XLAL_CHECK ( (catalogs = XLALCalloc ( uvar->numSegments, sizeof( catalogs[0] ))) != NULL, XLAL_ENOMEM );

  for ( INT4 l = 0; l < uvar->numSegments; l ++ )
    {
      endTime_l = startTime_l;
      XLALGPSAdd( &endTime_l, uvar->Tseg );
      MultiLIGOTimeGPSVector *multiTimestamps;
      XLAL_CHECK ( (multiTimestamps = XLALMakeMultiTimestamps ( startTime_l, uvar->Tseg, uvar->Tsft, 0, numDetectors )) != NULL, XLAL_EFUNC );
      XLAL_CHECK ( (catalogs[l] = XLALMultiAddToFakeSFTCatalog ( NULL, uvar->IFOs, multiTimestamps )) != NULL, XLAL_EFUNC );
      XLALDestroyMultiTimestamps ( multiTimestamps );
      startTime_l = endTime_l;
    } // for l < numSegments
  LIGOTimeGPS endTime = endTime_l;
  UINT4 numSFTsPerSeg = catalogs[0]->length;

  FILE *fpInfo = NULL;
  if ( (uvar->outputInfo != NULL) && (FstatMethod == FMETHOD_RESAMP_GENERIC) )
    {
      XLAL_CHECK ( (fpInfo = fopen (uvar->outputInfo, "ab")) != NULL, XLAL_ESYS, "Failed to open '%s' for appending\n", uvar->outputInfo );
      XLALAppendResampInfo2File ( fpInfo, NULL ); // create header comment line
    }

  PulsarSpinRange XLAL_INIT_DECL(spinRange);
  LIGOTimeGPS refTime = { startTime.gpsSeconds - 2.3 * uvar->Tseg, 0 };
  spinRange.refTime = refTime;
  spinRange.fkdot[0] = uvar->Freq;
  spinRange.fkdot[1] = uvar->f1dot;
  spinRange.fkdotBand[1] = 0;
  REAL8 asini = 0, Period = 0, ecc = 0;
  REAL8 minCoverFreq, maxCoverFreq;

  PulsarDopplerParams XLAL_INIT_DECL(Doppler);
  Doppler.refTime = refTime;
  Doppler.Alpha = 0.5;
  Doppler.Delta = 0.5;
  memcpy ( &Doppler.fkdot, &spinRange.fkdot, sizeof(Doppler.fkdot) );;
  Doppler.period = Period;
  Doppler.ecc = ecc;
  Doppler.asini = asini;

  // ----- setup optional Fstat arguments
  FstatOptionalArgs optionalArgs = FstatOptionalArgsDefaults;
  MultiNoiseFloor XLAL_INIT_DECL(injectSqrtSX);
  injectSqrtSX.length = numDetectors;
  for ( UINT4 X=0; X < numDetectors; X ++ ) {
    injectSqrtSX.sqrtSn[X] = 1;
  }
  optionalArgs.injectSqrtSX = &injectSqrtSX;
  optionalArgs.FstatMethod = FstatMethod;

  FstatWorkspace *sharedWorkspace = NULL;
  FstatInputVector *inputs;
  FstatQuantities whatToCompute = (FSTATQ_2F | FSTATQ_2F_PER_DET);
  FstatResults *results = NULL;
  REAL8 tauF1NoBuf = 0;
  REAL8 tauF1Buf = 0;
  // ---------- main loop over repeated trials ----------
  for ( INT4 i = 0; i < uvar->numTrials; i ++ )
    {
      // randomize numFreqBins
      UINT4 numFreqBins_i = numFreqBinsMin + (UINT4)round ( 1.0 * (numFreqBinsMax - numFreqBinsMin) * rand() / RAND_MAX );
      // randomize FreqResolution
      REAL8 FreqResolution_i = FreqResolutionMin + 1.0 * ( FreqResolutionMax - FreqResolutionMin ) * rand() / RAND_MAX;

      XLAL_CHECK ( (inputs = XLALCreateFstatInputVector ( uvar->numSegments )) != NULL, XLAL_EFUNC );

      REAL8 dFreq = 1.0 / ( FreqResolution_i * uvar->Tseg );

      REAL8 FreqBand = numFreqBins_i * dFreq;
      fprintf ( stderr, "trial %d/%d: Tseg = %.1f d, numSegments = %d, Freq = %.1f Hz, f1dot = %.1e Hz/s, FreqResolution r = %f, numFreqBins = %d [dFreq = %.2e Hz, FreqBand = %.2e Hz]\n",
                i+1, uvar->numTrials, uvar->Tseg / 86400.0, uvar->numSegments, uvar->Freq, uvar->f1dot, FreqResolution_i, numFreqBins_i, dFreq, FreqBand );

      spinRange.fkdotBand[0] = FreqBand;
      XLAL_CHECK ( XLALCWSignalCoveringBand ( &minCoverFreq, &maxCoverFreq, &startTime, &endTime, &spinRange, asini, Period, ecc ) == XLAL_SUCCESS, XLAL_EFUNC );

      UINT4 numBinsSFT = ceil ( (maxCoverFreq - minCoverFreq) * uvar->Tsft + 2 * 8 );
      REAL8 memSFTs = uvar->numSegments * numSFTsPerSeg * ( sizeof(SFTtype) + numBinsSFT * sizeof(COMPLEX8)) / 1e6;

      // create per-segment input structs
      for ( INT4 l = 0; l < uvar->numSegments; l ++ )
        {
          XLAL_CHECK ( (inputs->data[l] = XLALCreateFstatInput ( catalogs[l], minCoverFreq, maxCoverFreq, dFreq, ephem, &optionalArgs )) != NULL, XLAL_EFUNC );
          if ( l == 0 ) {
            sharedWorkspace = XLALGetSharedFstatWorkspace ( inputs->data[0] );
          }
          optionalArgs.sharedWorkspace = sharedWorkspace;
        }

      // ----- compute Fstatistics over segments
      REAL8 tauF1NoBuf_i = 0;
      REAL8 tauF1Buf_i = 0;
      for ( INT4 l = 0; l < uvar->numSegments; l ++ )
        {
          XLAL_CHECK ( XLALComputeFstat ( &results, inputs->data[l], &Doppler, numFreqBins_i, whatToCompute ) == XLAL_SUCCESS, XLAL_EFUNC );

          // ----- output timing details if requested
          if ( (fpInfo != NULL) ) {
            XLALAppendResampInfo2File ( fpInfo, inputs->data[l] );
          }
          REAL8 tauF1NoBuf_il, tauF1Buf_il;
          XLAL_CHECK ( XLALGetResampTimingInfo ( &tauF1NoBuf_il, &tauF1Buf_il, inputs->data[l] ) == XLAL_SUCCESS, XLAL_EFUNC );
          tauF1NoBuf_i += tauF1NoBuf_il;
          tauF1Buf_i   += tauF1Buf_il;
        } // for l < numSegments

      tauF1NoBuf_i /= uvar->numSegments;
      tauF1Buf_i   /= uvar->numSegments;
      REAL8 memMaxCompute = XLALGetPeakHeapUsageMB() - memBase;

      tauF1Buf   += tauF1Buf_i;
      tauF1NoBuf += tauF1NoBuf_i;

      fprintf (stderr, "%-15s: tauF1Buf = %.2g s, tauF1NoBuf = %.2g s, memSFTs = %.1f MB, memMaxCompute = %.1f MB\n",
               XLALGetFstatMethodName ( FstatMethod ), tauF1Buf_i, tauF1NoBuf_i, memSFTs, memMaxCompute  );

      XLALDestroyFstatInputVector ( inputs );
      XLALDestroyFstatWorkspace ( sharedWorkspace );
      optionalArgs.sharedWorkspace = NULL;

    } // for i < numTrials

  tauF1Buf   /= uvar->numTrials;
  tauF1NoBuf /= uvar->numTrials;

  fprintf (stderr, "\nAveraged timings: <tauF1Buf> = %.2g s, <tauF1NoBuf> = %.2g s\n", tauF1Buf, tauF1NoBuf );

  // ----- free memory ----------
  if ( fpInfo != NULL ) {
    fclose ( fpInfo );
  }

  for ( INT4 l = 0; l < uvar->numSegments; l ++ )
    {
      XLALDestroySFTCatalog ( catalogs[l] );
    }
  XLALFree ( catalogs );
  XLALDestroyFstatResults ( results );
  XLALDestroyUserVars();
  XLALDestroyEphemerisData ( ephem );

  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} // main()
/** Initialize Fstat-code: handle user-input and set everything up. */
int
XLALInitCode ( ConfigVariables *cfg, const UserInput_t *uvar )
{
  /* generate log-string for file-output, containing cmdline-options + code VCS version info */
  char *vcs;
  if ( (vcs = XLALGetVersionString(0)) == NULL ) {	  /* short VCS version string */
    XLALPrintError ( "%s: XLALGetVersionString(0) failed with errno=%d.\n", __func__, xlalErrno );
    XLAL_ERROR ( XLAL_EFUNC );
  }
  char *cmdline;
  if ( (cmdline = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) == NULL ) {
    XLALPrintError ( "%s: XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE ) failed with errno=%d.\n", __func__, xlalErrno );
    XLAL_ERROR ( XLAL_EFUNC );
  }
  const char fmt[] = "%%%% cmdline: %s\n%%%%\n%s%%%%\n";
  UINT4 len = strlen(vcs) + strlen(cmdline) + strlen(fmt) + 1;
  if ( ( cfg->logString = XLALMalloc ( len  )) == NULL ) {
    XLALPrintError ("%s: XLALMalloc ( %d ) failed.\n", __func__, len );
    XLAL_ERROR ( XLAL_ENOMEM );
  }
  sprintf ( cfg->logString, fmt, cmdline, vcs );
  XLALFree ( cmdline );
  XLALFree ( vcs );

  /* trivial settings from user-input */
  cfg->SignalOnly = uvar->SignalOnly;

  /* ----- parse user-input on signal amplitude-paramters + ranges ----- */
  /* skypos */
  cfg->skypos.longitude = uvar->Alpha;	/* Alpha < 0 indicates 'allsky' */
  cfg->skypos.latitude  = uvar->Delta;
  cfg->skypos.system = COORDINATESYSTEM_EQUATORIAL;

  /* ----- amplitude-params: create prior pdfs reflecting the user-input */
  if ( XLALInitAmplitudePrior ( &cfg->AmpPrior, uvar ) != XLAL_SUCCESS )
    XLAL_ERROR ( XLAL_EFUNC );

  /* ----- initialize random-number generator ----- */
  /* read out environment variables GSL_RNG_xxx
   * GSL_RNG_SEED: use to set random seed: default = 0, override by using --randSeed on cmdline
   * GSL_RNG_TYPE: type of random-number generator to use: default = 'mt19937'
   */
  gsl_rng_env_setup ();
  /* allow overriding the random-seed per command-line */
  if ( XLALUserVarWasSet ( &uvar->randSeed ) )
    gsl_rng_default_seed = uvar->randSeed;
  cfg->rng = gsl_rng_alloc (gsl_rng_default);

  LogPrintf ( LOG_DEBUG, "random-number generator type: %s\n", gsl_rng_name (cfg->rng));
  LogPrintf ( LOG_DEBUG, "seed = %lu\n", gsl_rng_default_seed );

  /* init ephemeris-data */
  EphemerisData *edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun );
  if ( !edat ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", __func__, uvar->ephemEarth, uvar->ephemSun);
    XLAL_ERROR ( XLAL_EFUNC );
  }

  /* init detector info */
  LALDetector *site;
  if ( (site = XLALGetSiteInfo ( uvar->IFO )) == NULL ) {
    XLALPrintError ("%s: Failed to get site-info for detector '%s'\n", __func__, uvar->IFO );
    XLAL_ERROR ( XLAL_EFUNC );
  }
  MultiLALDetector multiDet;
  multiDet.length = 1;
  multiDet.sites[0] = (*site); 	/* copy! */
  XLALFree ( site );

  /* init timestamps vector covering observation time */
  UINT4 numSteps = (UINT4) ceil ( uvar->dataDuration / uvar->TAtom );
  MultiLIGOTimeGPSVector * multiTS;
  if ( (multiTS = XLALCalloc ( 1, sizeof(*multiTS))) == NULL ) {
    XLAL_ERROR ( XLAL_ENOMEM );
  }
  multiTS->length = 1;
  if ( (multiTS->data = XLALCalloc (1, sizeof(*multiTS->data))) == NULL ) {
    XLAL_ERROR ( XLAL_ENOMEM );
  }
  if ( (multiTS->data[0] = XLALCreateTimestampVector (numSteps)) == NULL ) {
    XLALPrintError ("%s: XLALCreateTimestampVector(%d) failed.\n", __func__, numSteps );
  }
  multiTS->data[0]->deltaT = uvar->TAtom;
  UINT4 i;
  for ( i=0; i < numSteps; i ++ )
    {
      UINT4 ti = uvar->dataStartGPS + i * uvar->TAtom;
      multiTS->data[0]->data[i].gpsSeconds = ti;
      multiTS->data[0]->data[i].gpsNanoSeconds = 0;
    }

  /* get detector states */
  if ( (cfg->multiDetStates = XLALGetMultiDetectorStates ( multiTS, &multiDet, edat, 0.5 * uvar->TAtom )) == NULL ) {
    XLALPrintError ( "%s: XLALGetMultiDetectorStates() failed.\n", __func__ );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  /* get rid of all temporary memory allocated for this step */
  XLALDestroyEphemerisData ( edat );
  XLALDestroyMultiTimestamps ( multiTS );
  multiTS = NULL;


  /* ---------- initialize transient window ranges, for injection ... ---------- */
  transientWindowRange_t XLAL_INIT_DECL(InjectRange);
  int twtype;
  XLAL_CHECK ( (twtype = XLALParseTransientWindowName ( uvar->injectWindow_type )) >= 0, XLAL_EFUNC );
  InjectRange.type = twtype;

  /* make sure user doesn't set window=none but sets window-parameters => indicates she didn't mean 'none' */
  if ( InjectRange.type == TRANSIENT_NONE ) {
    if ( XLALUserVarWasSet ( &uvar->injectWindow_t0Days ) || XLALUserVarWasSet ( &uvar->injectWindow_t0DaysBand ) ||
         XLALUserVarWasSet ( &uvar->injectWindow_tauDays ) || XLALUserVarWasSet ( &uvar->injectWindow_tauDaysBand ) ) {
      XLALPrintError ("%s: ERROR: injectWindow_type == NONE, but window-parameters were set! Use a different window-type!\n", __func__ );
      XLAL_ERROR ( XLAL_EINVAL );
    }
  }

  if ( uvar->injectWindow_t0DaysBand < 0 || uvar->injectWindow_tauDaysBand < 0 ) {
    XLALPrintError ("%s: only positive t0/tau window injection bands allowed (%f, %f)\n", __func__, uvar->injectWindow_t0DaysBand, uvar->injectWindow_tauDaysBand );
    XLAL_ERROR ( XLAL_EINVAL );
  }

  /* apply correct defaults if unset: t0=dataStart, t0Band=dataDuration-3*tauMax */
  InjectRange.t0 = uvar->dataStartGPS + uvar->injectWindow_t0Days * DAY24;

  REAL8 tauMax = ( uvar->injectWindow_tauDays +  uvar->injectWindow_tauDaysBand ) * DAY24;
  if ( XLALUserVarWasSet (&uvar->injectWindow_t0DaysBand ) )
    InjectRange.t0Band  = uvar->injectWindow_t0DaysBand * DAY24;
  else
    InjectRange.t0Band  = fmax ( 0.0, uvar->dataDuration - TRANSIENT_EXP_EFOLDING * tauMax - InjectRange.t0 ); 	/* make sure it's >= 0 */

  InjectRange.tau     = (UINT4) ( uvar->injectWindow_tauDays * DAY24 );
  InjectRange.tauBand = (UINT4) ( uvar->injectWindow_tauDaysBand * DAY24 );

  cfg->transientInjectRange = InjectRange;

  /* ---------- ... and for search -------------------- */
  transientWindowRange_t XLAL_INIT_DECL(SearchRange);
  XLAL_CHECK ( (twtype = XLALParseTransientWindowName ( uvar->searchWindow_type )) >= 0, XLAL_EFUNC );
  SearchRange.type = twtype;

  /* apply correct defaults if unset: use inect window */
  if ( !XLALUserVarWasSet ( &uvar->searchWindow_type ) )
    SearchRange.type    = InjectRange.type;
  if ( !XLALUserVarWasSet ( &uvar->searchWindow_t0Days ) )
    SearchRange.t0      = InjectRange.t0;
  else
    SearchRange.t0      = uvar->dataStartGPS + uvar->searchWindow_t0Days * DAY24;
  if ( !XLALUserVarWasSet ( &uvar->searchWindow_t0DaysBand ) )
    SearchRange.t0Band = InjectRange.t0Band;
  else
    SearchRange.t0Band  = (UINT4) (uvar->searchWindow_t0DaysBand * DAY24);
  if ( !XLALUserVarWasSet ( &uvar->searchWindow_tauDays ) )
    SearchRange.tau = InjectRange.tau;
  else
    SearchRange.tau     = (UINT4) ( uvar->searchWindow_tauDays * DAY24 );
  if ( !XLALUserVarWasSet ( &uvar->searchWindow_tauDaysBand ) )
    SearchRange.tauBand = InjectRange.tauBand;
  else
    SearchRange.tauBand = (UINT4) ( uvar->searchWindow_tauDaysBand * DAY24 );

  if ( XLALUserVarWasSet ( &uvar->searchWindow_dt0 ) )
    SearchRange.dt0 = uvar->searchWindow_dt0;
  else
    SearchRange.dt0 = uvar->TAtom;

  if ( XLALUserVarWasSet ( &uvar->searchWindow_dtau ) )
    SearchRange.dtau = uvar->searchWindow_dtau;
  else
    SearchRange.dtau = uvar->TAtom;

  /* make sure user doesn't set window=none but sets window-parameters => indicates she didn't mean 'none' */
  if ( SearchRange.type == TRANSIENT_NONE )
    if ( XLALUserVarWasSet ( &uvar->searchWindow_t0Days ) || XLALUserVarWasSet ( &uvar->searchWindow_t0DaysBand ) ||
         XLALUserVarWasSet ( &uvar->searchWindow_tauDays ) || XLALUserVarWasSet ( &uvar->searchWindow_tauDaysBand ) ) {
      XLALPrintError ("%s: ERROR: searchWindow_type == NONE, but window-parameters were set! Use a different window-type!\n", __func__ );
      XLAL_ERROR ( XLAL_EINVAL );
    }

  if (   uvar->searchWindow_t0DaysBand < 0 || uvar->searchWindow_tauDaysBand < 0 ) {
    XLALPrintError ("%s: only positive t0/tau window injection bands allowed (%f, %f)\n", __func__, uvar->searchWindow_t0DaysBand, uvar->searchWindow_tauDaysBand );
    XLAL_ERROR ( XLAL_EINVAL );
  }

  cfg->transientSearchRange = SearchRange;

  return XLAL_SUCCESS;

} /* XLALInitCode() */
Exemple #10
0
// ---------- 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()
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();
}
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();
}
Exemple #13
0
/** Initialized Fstat-code: handle user-input and set everything up. */
void
InitPFS ( LALStatus *status, ConfigVariables *cfg, const UserInput_t *uvar )
{
  static const char *fn = "InitPFS()";

  SFTCatalog *catalog = NULL;
  SFTConstraints constraints = empty_SFTConstraints;
  SkyPosition skypos;

  LIGOTimeGPS startTime, endTime;
  REAL8 duration, Tsft;
  LIGOTimeGPS minStartTimeGPS, maxEndTimeGPS;

  EphemerisData *edat = NULL;		    	/* ephemeris data */
  MultiAMCoeffs *multiAMcoef = NULL;
  MultiPSDVector *multiRngmed = NULL;
  MultiNoiseWeights *multiNoiseWeights = NULL;
  MultiSFTVector *multiSFTs = NULL;	    	/* multi-IFO SFT-vectors */
  MultiDetectorStateSeries *multiDetStates = NULL; /* pos, vel and LMSTs for detector at times t_i */
  UINT4 X, i;


  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  { /* Check user-input consistency */
    BOOLEAN have_h0, have_cosi, have_cosiota, have_Ap, have_Ac;
    REAL8 cosi = 0;

    have_h0 = LALUserVarWasSet ( &uvar->h0 );
    have_cosi = LALUserVarWasSet ( &uvar->cosi );
    have_cosiota = LALUserVarWasSet ( &uvar->cosiota );
    have_Ap = LALUserVarWasSet ( &uvar->aPlus );
    have_Ac = LALUserVarWasSet ( &uvar->aCross );

    /* ----- handle cosi/cosiota ambiguity */
    if ( (have_cosi && have_cosiota)  ) {
      LogPrintf (LOG_CRITICAL, "Need EITHER --cosi [preferred] OR --cosiota [deprecated]!\n");
      ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT );
    }
    if ( have_cosiota ) {
      cosi = uvar->cosiota;
      have_cosi = TRUE;
    }
    else if ( have_cosi ) {
      cosi = uvar->cosi;
      have_cosi = TRUE;
    }

    /* ----- handle {h0,cosi} || {aPlus,aCross} freedom ----- */
    if ( ( have_h0 && !have_cosi ) || ( !have_h0 && have_cosi ) )
      {
	LogPrintf (LOG_CRITICAL, "Need both (h0, cosi) to specify signal!\n");
	ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT );
      }
    if ( ( have_Ap && !have_Ac) || ( !have_Ap && have_Ac ) )
      {
	LogPrintf (LOG_CRITICAL, "Need both (aPlus, aCross) to specify signal!\n");
	ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT );
      }
    if ( have_h0 && have_Ap )
      {
	LogPrintf (LOG_CRITICAL, "Overdetermined: specify EITHER (h0,cosi) OR (aPlus,aCross)!\n");
	ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT );
      }
    /* ----- internally we always use Aplus, Across */
    if ( have_h0 )
      {
	cfg->aPlus = 0.5 * uvar->h0 * ( 1.0 + SQ( cosi) );
	cfg->aCross = uvar->h0 * uvar->cosi;
      }
    else
      {
	cfg->aPlus = uvar->aPlus;
	cfg->aCross = uvar->aCross;
      }
  }/* check user-input */


  /* ----- prepare SFT-reading ----- */
  if ( LALUserVarWasSet ( &uvar->IFO ) )
    if ( (constraints.detector = XLALGetChannelPrefix ( uvar->IFO )) == NULL ) {
      ABORT ( status,  PREDICTFSTAT_EINPUT,  PREDICTFSTAT_MSGEINPUT);
    }

  minStartTimeGPS.gpsSeconds = uvar->minStartTime;
  minStartTimeGPS.gpsNanoSeconds = 0;
  maxEndTimeGPS.gpsSeconds = uvar->maxEndTime;
  maxEndTimeGPS.gpsNanoSeconds = 0;
  constraints.minStartTime = &minStartTimeGPS;
  constraints.maxEndTime = &maxEndTimeGPS;

  /* ----- get full SFT-catalog of all matching (multi-IFO) SFTs */
  LogPrintf (LOG_DEBUG, "Finding all SFTs to load ... ");
  TRY ( LALSFTdataFind ( status->statusPtr, &catalog, uvar->DataFiles, &constraints ), status);
  LogPrintfVerbatim (LOG_DEBUG, "done. (found %d SFTs)\n", catalog->length);
  if ( constraints.detector )
    LALFree ( constraints.detector );

  if ( catalog->length == 0 )
    {
      LogPrintf (LOG_CRITICAL, "No matching SFTs for pattern '%s'!\n", uvar->DataFiles );
      ABORT ( status,  PREDICTFSTAT_EINPUT,  PREDICTFSTAT_MSGEINPUT);
    }

  /* ----- deduce start- and end-time of the observation spanned by the data */
  {
    GV.numSFTs = catalog->length;	/* total number of SFTs */
    Tsft = 1.0 / catalog->data[0].header.deltaF;
    startTime = catalog->data[0].header.epoch;
    endTime   = catalog->data[GV.numSFTs-1].header.epoch;
    XLALGPSAdd(&endTime, Tsft);
    duration = GPS2REAL8(endTime) - GPS2REAL8 (startTime);
  }

  { /* ----- load ephemeris-data ----- */
    edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun );
    if ( !edat ) {
      XLALPrintError("XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", uvar->ephemEarth, uvar->ephemSun);
      ABORT ( status,  PREDICTFSTAT_EINPUT,  PREDICTFSTAT_MSGEINPUT);
    }
  }

  {/* ----- load the multi-IFO SFT-vectors ----- */
    UINT4 wings = uvar->RngMedWindow/2 + 10;   /* extra frequency-bins needed for rngmed */
    REAL8 fMax = uvar->Freq + 1.0 * wings / Tsft;
    REAL8 fMin = uvar->Freq - 1.0 * wings / Tsft;

    LogPrintf (LOG_DEBUG, "Loading SFTs ... ");
    TRY ( LALLoadMultiSFTs ( status->statusPtr, &multiSFTs, catalog, fMin, fMax ), status );
    LogPrintfVerbatim (LOG_DEBUG, "done.\n");
    TRY ( LALDestroySFTCatalog ( status->statusPtr, &catalog ), status );
  }

  TRY ( LALNormalizeMultiSFTVect (status->statusPtr, &multiRngmed, multiSFTs, uvar->RngMedWindow ), status);
  TRY ( LALComputeMultiNoiseWeights (status->statusPtr, &multiNoiseWeights, multiRngmed, uvar->RngMedWindow, 0 ), status );

  /* correctly handle the --SignalOnly case:
   * set noise-weights to 1, and
   * set Sh->1 (single-sided)
   */
  if ( uvar->SignalOnly )
    {
      multiNoiseWeights->Sinv_Tsft = Tsft;
      for ( X=0; X < multiNoiseWeights->length; X ++ )
        for ( i=0; i < multiNoiseWeights->data[X]->length; i ++ )
          multiNoiseWeights->data[X]->data[i] = 1.0;
    }

  /* ----- handle transient-signal window if given ----- */
  if ( LALUserVarWasSet ( &uvar->transientWindowType ) && strcmp ( uvar->transientWindowType, "none") )
    {
      transientWindow_t transientWindow;	/**< properties of transient-signal window */
      MultiLIGOTimeGPSVector *mTS;

      if ( !strcmp ( uvar->transientWindowType, "rect" ) )
        transientWindow.type = TRANSIENT_RECTANGULAR;		/* rectangular window [t0, t0+tau] */
      else if ( !strcmp ( uvar->transientWindowType, "exp" ) )
        transientWindow.type = TRANSIENT_EXPONENTIAL;		/* exponential decay window e^[-(t-t0)/tau for t>t0, 0 otherwise */
      else
	{
	  XLALPrintError ("Illegal transient window '%s' specified: valid are 'none', 'rect' or 'exp'\n", uvar->transientWindowType);
          ABORT ( status, PREDICTFSTAT_EINPUT, PREDICTFSTAT_MSGEINPUT );
	}

      if ( LALUserVarWasSet ( &uvar->transientStartTime ) )
        transientWindow.t0 = uvar->transientStartTime;
      else
        transientWindow.t0 = XLALGPSGetREAL8( &startTime ); /* if not set, default window startTime == startTime here */

      transientWindow.tau  = uvar->transientTauDays;

      if ( (mTS = XLALExtractMultiTimestampsFromSFTs ( multiSFTs )) == NULL ) {
        XLALPrintError ("%s: failed to XLALExtractMultiTimestampsFromSFTs() from SFTs. xlalErrno = %d.\n", fn, xlalErrno );
        ABORT ( status, PREDICTFSTAT_EXLAL, PREDICTFSTAT_MSGEXLAL );
      }

      if ( XLALApplyTransientWindow2NoiseWeights ( multiNoiseWeights, mTS, transientWindow ) != XLAL_SUCCESS ) {
        XLALPrintError ("%s: XLALApplyTransientWindow2NoiseWeights() failed! xlalErrno = %d\n", fn, xlalErrno );
        ABORT ( status, PREDICTFSTAT_EXLAL, PREDICTFSTAT_MSGEXLAL );
      }

      XLALDestroyMultiTimestamps ( mTS );

    } /* apply transient window to noise-weights */


  /* ----- obtain the (multi-IFO) 'detector-state series' for all SFTs ----- */
  TRY (LALGetMultiDetectorStates( status->statusPtr, &multiDetStates, multiSFTs, edat), status );

  /* normalize skyposition: correctly map into [0,2pi]x[-pi/2,pi/2] */
  skypos.longitude = uvar->Alpha;
  skypos.latitude = uvar->Delta;
  skypos.system = COORDINATESYSTEM_EQUATORIAL;
  TRY (LALNormalizeSkyPosition ( status->statusPtr, &skypos, &skypos), status);

  TRY ( LALGetMultiAMCoeffs ( status->statusPtr, &multiAMcoef, multiDetStates, skypos ), status);
  /* noise-weighting of Antenna-patterns and compute A,B,C */
  if ( XLALWeightMultiAMCoeffs ( multiAMcoef, multiNoiseWeights ) != XLAL_SUCCESS ) {
    LogPrintf (LOG_CRITICAL, "XLALWeightMultiAMCoeffs() failed with error = %d\n\n", xlalErrno );
    ABORT ( status, PREDICTFSTAT_EXLAL, PREDICTFSTAT_MSGEXLAL );
  }

  /* OK: we only need the antenna-pattern matrix M_mu_nu */
  cfg->Mmunu = multiAMcoef->Mmunu;

  /* ----- produce a log-string describing the data-specific setup ----- */
  {
    struct tm utc;
    time_t tp;
    CHAR dateStr[512], line[512], summary[1024];
    UINT4 j, numDet;
    numDet = multiSFTs->length;
    tp = time(NULL);
    sprintf (summary, "%%%% Date: %s", asctime( gmtime( &tp ) ) );
    strcat (summary, "%% Loaded SFTs: [ " );
    for ( j=0; j < numDet; j ++ ) {
      sprintf (line, "%s:%d%s",  multiSFTs->data[j]->data->name, multiSFTs->data[j]->length,
	       (j < numDet - 1)?", ":" ]\n");
      strcat ( summary, line );
    }
    utc = *XLALGPSToUTC( &utc, (INT4)GPS2REAL8(startTime) );
    strcpy ( dateStr, asctime(&utc) );
    dateStr[ strlen(dateStr) - 1 ] = 0;
    sprintf (line, "%%%% Start GPS time tStart = %12.3f    (%s GMT)\n", GPS2REAL8(startTime), dateStr);
    strcat ( summary, line );
    sprintf (line, "%%%% Total time spanned    = %12.3f s  (%.1f hours)\n", duration, duration/3600 );
    strcat ( summary, line );

    if ( (cfg->dataSummary = LALCalloc(1, strlen(summary) + 1 )) == NULL ) {
      ABORT (status, PREDICTFSTAT_EMEM, PREDICTFSTAT_MSGEMEM);
    }
    strcpy ( cfg->dataSummary, summary );

    LogPrintfVerbatim( LOG_DEBUG, cfg->dataSummary );
  } /* write dataSummary string */

  /* free everything not needed any more */
  TRY ( LALDestroyMultiPSDVector (status->statusPtr, &multiRngmed ), status );
  TRY ( LALDestroyMultiNoiseWeights (status->statusPtr, &multiNoiseWeights ), status );
  TRY ( LALDestroyMultiSFTVector (status->statusPtr, &multiSFTs ), status );
  XLALDestroyMultiDetectorStateSeries ( multiDetStates );
  XLALDestroyMultiAMCoeffs ( multiAMcoef );

  /* Free ephemeris data */
  XLALDestroyEphemerisData (edat);

  DETATCHSTATUSPTR (status);
  RETURN (status);

} /* InitPFS() */
Exemple #14
0
/* ----- 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() */