EphemerisData *InitEphemeris (const CHAR *ephemType, const CHAR *ephemDir){
  const CHAR *fn = __func__;
#define FNAME_LENGTH 1024
  CHAR EphemEarth[FNAME_LENGTH];  /* filename of earth-ephemeris data */
  CHAR EphemSun[FNAME_LENGTH];    /* filename of sun-ephemeris data */

  /* check input consistency */
  if ( !ephemType ) {
    XLALPrintError ("%s: invalid NULL input for 'ephemType'\n", fn );
    XLAL_ERROR_NULL ( XLAL_EINVAL );
  }

  snprintf(EphemEarth, FNAME_LENGTH, "%s/earth00-19-%s.dat.gz", ephemDir, ephemType);
  snprintf(EphemSun, FNAME_LENGTH, "%s/sun00-19-%s.dat.gz", ephemDir, ephemType);

  EphemEarth[FNAME_LENGTH-1]=0;
  EphemSun[FNAME_LENGTH-1]=0;

  EphemerisData *edat;
  if ( (edat = XLALInitBarycenter ( EphemEarth, EphemSun)) == NULL ) {
    XLALPrintError ("%s: XLALInitBarycenter() failed.\n", fn );
    XLAL_ERROR_NULL ( XLAL_EFUNC );
  }

  /* return ephemeris */
  return edat;
} /* InitEphemeris() */
/**
 * basic initializations: deal with user input and return standardized 'ConfigVariables'
 */
int
XLALInitCode ( ConfigVariables *cfg, const UserVariables_t *uvar, const char *app_name)
{
  if ( !cfg || !uvar || !app_name ) {
    XLALPrintError ("%s: illegal NULL pointer input.\n\n", __func__ );
    XLAL_ERROR ( XLAL_EINVAL );
  }

  /* init ephemeris data */
  XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC );

  /* convert input REAL8 time into LIGOTimeGPS */
  if ( XLALGPSSetREAL8( &cfg->timeGPS, uvar->timeGPS ) == NULL ) {
    XLALPrintError ("%s: failed to convert input GPS %g into LIGOTimeGPS\n", __func__, uvar->timeGPS );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  /* set up dummy timestamps vector containing just this one timestamps
   * (used to interface with LALComputeAM(), LALGetAMCoeffs() and LALNewGetAMCoeffs())
   */
  if ( (cfg->timestamps = XLALCreateTimestampVector( 1 )) == NULL ) {
    XLALPrintError ("%s: XLALCreateTimestampVector( 1 ) failed.", __func__ );
    XLAL_ERROR ( XLAL_EFUNC );
  }
  cfg->timestamps->data[0] = cfg->timeGPS;

  /* convert detector name into site-info */
  if ( ( cfg->det = XLALGetSiteInfo ( uvar->detector )) == NULL )
    {
      XLALPrintError ("%s: XLALGetSiteInfo('%s') failed.\n", __func__, uvar->detector );
      XLAL_ERROR ( XLAL_EFUNC );
    }

  /* NOTE: contrary to ComputeAM() and LALGetAMCoffs(), the new function LALNewGetAMCoeffs()
   * computes 'a * sinzeta' and 'b * sinzeta': for the comparison we therefore need to correct
   * for GEO's opening-angle of 94.33degrees [JKS98]: */
  if ( ! strcmp ( cfg->det->frDetector.name, "GEO_600" ) )
    cfg->sinzeta = 0.997146;
  else
    cfg->sinzeta = 1;


  /* convert input skyposition to radians Alpha/Delta [trivial here] */
  cfg->skypos.system = COORDINATESYSTEM_EQUATORIAL;
  cfg->skypos.longitude = uvar->Alpha;
  cfg->skypos.latitude  = uvar->Delta;


  return XLAL_SUCCESS;

} /* XLALInitCode() */
/* initialize and register user variables */
int XLALInitializeConfigVars (ConfigVariables *config, const UserInput_t *uvar)
{

  static SFTConstraints constraints;
  LIGOTimeGPS startTime, endTime;

  /* set sft catalog constraints */
  constraints.detector = NULL;
  constraints.timestamps = NULL;
  constraints.minStartTime = &startTime;
  constraints.maxStartTime = &endTime;
  XLALGPSSet( constraints.minStartTime, uvar->startTime, 0 );
  XLALGPSSet( constraints.maxStartTime, uvar->endTime, 0 );

  if (XLALUserVarWasSet(&(uvar->refTime)))
    config->refTime = uvar->refTime;
  else
    config->refTime = uvar->startTime + 0.5 * ( (REAL8) (uvar->endTime - uvar->startTime) );


  /* This check doesn't seem to work, since XLALGPSSet doesn't set its
     first argument.

     if ( (constraints.minStartTime == NULL)&& (constraints.maxStartTime == NULL) ) {
     LogPrintf ( LOG_CRITICAL, "%s: XLALGPSSet() failed with errno=%d\n", __func__, xlalErrno );
     XLAL_ERROR( XLAL_EFUNC );
     }

  */

  /* get catalog of SFTs */
  if ((config->catalog = XLALSFTdataFind (uvar->sftLocation, &constraints)) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALSFTdataFind() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* initialize ephemeris data*/
  XLAL_CHECK ( (config->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC );

  return XLAL_SUCCESS;

}
Beispiel #4
0
/**
 * \ingroup LALBarycenter_h
 * \brief [DEPRECATED] Reads Earth and Sun ephemeris files. Simple wrapper around XLALInitBarycenter()
 * \deprecated Use XLALInitBarycenter() instead.
 */
void
LALInitBarycenter ( LALStatus *stat,	/**< LAL-status pointer */
                    EphemerisData *edat	/**< [in/out] initialized ephemeris-data */
                    )
{
    INITSTATUS(stat);

    if( edat == NULL )
      ABORT( stat, LALINITBARYCENTERH_EOPEN, "Ephemeris structure is NULL" );

    if( edat->ephiles.earthEphemeris == NULL )
      ABORT( stat, LALINITBARYCENTERH_EOPEN, LALINITBARYCENTERH_MSGEOPEN );

    if( edat->ephiles.sunEphemeris == NULL )
      ABORT( stat, LALINITBARYCENTERH_EOPEN, LALINITBARYCENTERH_MSGEOPEN );

    /* use XLALInitBarycenter */
    EphemerisData *edattmp = XLALInitBarycenter( edat->ephiles.earthEphemeris, edat->ephiles.sunEphemeris );
    if( edattmp == NULL ){
      ABORT( stat, LALINITBARYCENTERH_EOPEN, LALINITBARYCENTERH_MSGEOPEN );
    }

    // We need to be careful about returning this, due to the unfortunate input/output method
    // of this deprecated LAL function: 'edat' is both used as input and output, where only
    // the 'ephiles' entry is supposed to be initialized in the input data, and so we need to
    // preserve that entry:
    EphemerisFilenames tmp;
    memcpy ( &tmp, &edat->ephiles, sizeof(edat->ephiles) );
    // now copy new ephemeris-struct over the input one:
    memcpy ( edat, edattmp, sizeof(*edat) );
    // restore the original 'ephiles' pointer entries
    memcpy ( &edat->ephiles, &tmp, sizeof(edat->ephiles) );
    // free the new 'ephiles' strings (allocated in XLALInitBarycenter())
    XLALFree ( edattmp->ephiles.earthEphemeris );
    XLALFree ( edattmp->ephiles.sunEphemeris );
    // and free the interal 'edattmp' container (but *not* the ephemE/ephemS arrays, which we return in 'edat' !)
    XLALFree ( edattmp );

    /* successful return */
    RETURN(stat);

} /* LALInitBarycenter() */
Beispiel #5
0
/**
 * basic initializations: set-up 'ConfigVariables'
 */
int
XLALInitCode ( ConfigVariables *cfg, const UserVariables_t *uvar, const char *app_name)
{
  if ( !cfg || !uvar || !app_name ) {
    LogPrintf (LOG_CRITICAL, "%s: illegal NULL pointer input.\n\n", __func__ );
    XLAL_ERROR (XLAL_EINVAL );
  }

  /* Init ephemerides */
  XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC );

  // ----- figure out which segments to use
  BOOLEAN manualSegments = XLALUserVarWasSet(&uvar->duration) || XLALUserVarWasSet(&uvar->startTime) || XLALUserVarWasSet(&uvar->Nseg);
  if ( manualSegments && uvar->segmentList ) {
    XLAL_ERROR ( XLAL_EDOM, "Can specify EITHER {--startTime, --duration, --Nseg} OR --segmentList\n");
  }
  LIGOTimeGPS startTimeGPS;
  REAL8 duration;
  if ( uvar->segmentList == NULL )
    {
      XLAL_CHECK ( uvar->Nseg >= 1, XLAL_EDOM, "Invalid input --Nseg=%d: number of segments must be >= 1\n", uvar->Nseg );
      XLAL_CHECK ( uvar->duration >= 1, XLAL_EDOM, "Invalid input --duration=%f: duration must be >= 1 s\n", uvar->duration );
      startTimeGPS = uvar->startTime;
      int ret = XLALSegListInitSimpleSegments ( &cfg->segmentList, startTimeGPS, uvar->Nseg, uvar->duration / uvar->Nseg );
      XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno );
      duration = uvar->duration;
    }
  else
    {
      LALSegList *segList = XLALReadSegmentsFromFile ( uvar->segmentList );
      XLAL_CHECK ( segList != NULL, XLAL_EIO, "XLALReadSegmentsFromFile() failed to load segment list from file '%s', xlalErrno = %d\n", uvar->segmentList, xlalErrno );
      cfg->segmentList = (*segList);	// copy *contents*
      XLALFree ( segList );
      startTimeGPS = cfg->segmentList.segs[0].start;
      UINT4 Nseg = cfg->segmentList.length;
      LIGOTimeGPS endTimeGPS = cfg->segmentList.segs[Nseg-1].end;
      duration = XLALGPSDiff( &endTimeGPS, &startTimeGPS );
    }

  /* ----- figure out reference time */
  LIGOTimeGPS refTimeGPS;

  /* treat special values first */
  if ( uvar->refTime.gpsSeconds == 0 )		/* 0 = use startTime */
    {
      refTimeGPS = uvar->startTime;
    }
  else if ( !XLALUserVarWasSet ( &uvar->refTime ) )	/* default = use mid-time of observation */
    {
      refTimeGPS = startTimeGPS;
      XLALGPSAdd( &refTimeGPS, duration / 2.0 );
    }
  else
    {
      refTimeGPS = uvar->refTime;
    }

  /* ----- get parameter-space point from user-input) */
  cfg->signalParams.Amp.h0 = uvar->h0;
  cfg->signalParams.Amp.cosi = uvar->cosi;
  cfg->signalParams.Amp.psi = uvar->psi;
  cfg->signalParams.Amp.phi0 = uvar->phi0;

  {
    PulsarDopplerParams *dop = &(cfg->signalParams.Doppler);
    XLAL_INIT_MEM((*dop));
    dop->refTime = refTimeGPS;
    dop->Alpha    = uvar->Alpha;
    dop->Delta    = uvar->Delta;
    dop->fkdot[0] = uvar->Freq;
    dop->fkdot[1] = uvar->f1dot;
    dop->fkdot[2] = uvar->f2dot;
    dop->fkdot[3] = uvar->f3dot;
    dop->asini    = uvar->orbitasini;
    dop->period   = uvar->orbitPeriod;
    dop->tp       = uvar->orbitTp;
    dop->ecc      = uvar->orbitEcc;
    dop->argp     = uvar->orbitArgp;
  }

  /* ----- initialize IFOs and (Multi-)DetectorStateSeries  ----- */
  XLAL_CHECK ( XLALParseMultiLALDetector ( &cfg->multiIFO, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC );
  UINT4 numDet = cfg->multiIFO.length;
  XLAL_CHECK ( numDet >= 1, XLAL_EINVAL );

  if ( uvar->sqrtSX ) {
    XLAL_CHECK ( XLALParseMultiNoiseFloor ( &cfg->multiNoiseFloor, uvar->sqrtSX, numDet ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  /* ---------- translate coordinate system into internal representation ---------- */
  if ( XLALDopplerCoordinateNames2System ( &cfg->coordSys, uvar->coords ) ) {
    LogPrintf (LOG_CRITICAL, "%s: Call to XLALDopplerCoordinateNames2System() failed. errno = %d\n\n", __func__, xlalErrno );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  /* ---------- record full 'history' up to and including this application ---------- */
  {
    CHAR *cmdline = NULL;
    CHAR *tmp;
    size_t len = strlen ( app_name ) + 1;

    if ( (cfg->history = XLALCalloc ( 1, sizeof(*cfg->history))) == NULL ) {
      LogPrintf (LOG_CRITICAL, "%s: XLALCalloc(1,%zu) failed.\n\n", __func__, sizeof(*cfg->history));
      XLAL_ERROR ( XLAL_ENOMEM );
    }

    if ( (tmp = XLALMalloc ( len )) == NULL ) {
      LogPrintf (LOG_CRITICAL, "%s: XLALMalloc (%zu) failed.\n\n", __func__, len );
      XLAL_ERROR ( XLAL_ENOMEM );
    }
    strcpy ( tmp, app_name );
    cfg->history->app_name = tmp;

    /* get commandline describing search*/
    if ( (cmdline = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) == NULL ) {
      LogPrintf (LOG_CRITICAL, "%s: XLALUserVarGetLog() failed with xlalErrno = %d.\n\n", __func__, xlalErrno );
      XLAL_ERROR ( XLAL_EFUNC );
    }
    cfg->history->cmdline = cmdline;
  } /* record history */


  return XLAL_SUCCESS;

} /* XLALInitCode() */
Beispiel #6
0
/**
 * Handle user-input and set up shop accordingly, and do all
 * consistency-checks on user-input.
 */
int
XLALInitMakefakedata ( ConfigVars_t *cfg, UserVariables_t *uvar )
{
  XLAL_CHECK ( cfg != NULL, XLAL_EINVAL, "Invalid NULL input 'cfg'\n" );
  XLAL_CHECK ( uvar != NULL, XLAL_EINVAL, "Invalid NULL input 'uvar'\n");

  cfg->VCSInfoString = XLALGetVersionString(0);
  XLAL_CHECK ( cfg->VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" );

  // version info was requested: output then exit
  if ( uvar->version )
    {
      printf ("%s\n", cfg->VCSInfoString );
      exit (0);
    }

  /* if requested, log all user-input and code-versions */
  if ( uvar->logfile ) {
    XLAL_CHECK ( XLALWriteMFDlog ( uvar->logfile, cfg ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALWriteMFDlog() failed with xlalErrno = %d\n", xlalErrno );
  }

  /* Init ephemerides */
  XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC );

  /* check for negative fMin and Band, which would break the fMin_eff, fBand_eff calculation below */
  XLAL_CHECK ( uvar->fmin >= 0, XLAL_EDOM, "Invalid negative frequency fMin=%f!\n\n", uvar->fmin );
  XLAL_CHECK ( uvar->Band > 0, XLAL_EDOM, "Invalid non-positive frequency band Band=%f!\n\n", uvar->Band );

  // ---------- check user-input consistency ----------

  // ----- check if frames + frame channels given
  BOOLEAN have_frames  = (uvar->inFrames != NULL);
  BOOLEAN have_channels= (uvar->inFrChannels != NULL);
  XLAL_CHECK ( !(have_frames || have_channels) || (have_frames && have_channels), XLAL_EINVAL, "Need both --inFrames and --inFrChannels, or NONE\n");

  // ----- IFOs : only from one of {--IFOs, --noiseSFTs, --inFrChannels}: mutually exclusive
  BOOLEAN have_IFOs      = (uvar->IFOs != NULL);
  BOOLEAN have_noiseSFTs = (uvar->noiseSFTs != NULL);
  XLAL_CHECK ( have_frames || have_IFOs || have_noiseSFTs, XLAL_EINVAL, "Need one of --IFOs, --noiseSFTs or --inFrChannels to determine detectors\n");

  if ( have_frames ) {
    XLAL_CHECK ( !have_IFOs && !have_noiseSFTs, XLAL_EINVAL, "If --inFrames given, cannot handle --IFOs or --noiseSFTs input\n");
    XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->inFrChannels ) == XLAL_SUCCESS, XLAL_EFUNC );
  } else { // !have_frames
    XLAL_CHECK ( !(have_IFOs && have_noiseSFTs), XLAL_EINVAL, "Cannot handle both --IFOs and --noiseSFTs input\n");
  }
  if ( have_IFOs ) {
    XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // ----- TIMESTAMPS: either from --timestampsFiles, --startTime+duration, or --noiseSFTs
  BOOLEAN have_startTime = XLALUserVarWasSet ( &uvar->startTime );
  BOOLEAN have_duration = XLALUserVarWasSet ( &uvar->duration );
  BOOLEAN have_timestampsFiles = ( uvar->timestampsFiles != NULL );
  // need BOTH startTime+duration or none
  XLAL_CHECK ( ( have_duration && have_startTime) || !( have_duration || have_startTime ), XLAL_EINVAL, "Need BOTH {--startTime,--duration} or NONE\n");
  // at least one of {startTime,timestamps,noiseSFTs,inFrames} required
  XLAL_CHECK ( have_timestampsFiles || have_startTime || have_noiseSFTs || have_frames, XLAL_EINVAL, "Need at least one of {--timestampsFiles, --startTime+duration, --noiseSFTs, --inFrames}\n" );
  // don't allow timestamps + {startTime+duration OR noiseSFTs}
  XLAL_CHECK ( !have_timestampsFiles || !(have_startTime||have_noiseSFTs), XLAL_EINVAL, "--timestampsFiles incompatible with {--noiseSFTs or --startTime+duration}\n");
  // note, however, that we DO allow --noiseSFTs and --startTime+duration, which will act as a constraint
  // on the noise-SFTs to load in

  // don't allow --SFToverlap with either --noiseSFTs OR --timestampsFiles
  XLAL_CHECK ( uvar->SFToverlap >= 0, XLAL_EDOM );
  BOOLEAN haveOverlap = ( uvar->SFToverlap > 0 );
  XLAL_CHECK ( !haveOverlap || !( have_noiseSFTs || have_timestampsFiles ), XLAL_EINVAL, "--SFToverlap incompatible with {--noiseSFTs or --timestampsFiles}\n" );

  // now handle the 3 mutually-exclusive cases: have_noiseSFTs || have_timestampsFiles || have_startTime (only)
  if ( have_noiseSFTs )
    {
      SFTConstraints XLAL_INIT_DECL(constraints);
      if ( have_startTime && have_duration )	 // use optional (startTime+duration) as constraints,
        {
          LIGOTimeGPS minStartTime, maxStartTime;
          minStartTime = uvar->startTime;
          maxStartTime = uvar->startTime;
          XLALGPSAdd ( &maxStartTime, uvar->duration );
          constraints.minStartTime = &minStartTime;
          constraints.maxStartTime = &maxStartTime;
          char bufGPS1[32], bufGPS2[32];
          XLALPrintWarning ( "Only noise-SFTs between GPS [%s, %s] will be used!\n", XLALGPSToStr(bufGPS1, &minStartTime), XLALGPSToStr(bufGPS2, &maxStartTime) );
        } /* if start+duration given */
      XLAL_CHECK ( (cfg->noiseCatalog = XLALSFTdataFind ( uvar->noiseSFTs, &constraints )) != NULL, XLAL_EFUNC );
      XLAL_CHECK (  cfg->noiseCatalog->length > 0, XLAL_EINVAL, "No noise-SFTs matching (start+duration, timestamps) were found!\n" );
      XLAL_CHECK ( (cfg->multiNoiseCatalogView = XLALGetMultiSFTCatalogView ( cfg->noiseCatalog )) != NULL, XLAL_EFUNC );

      // extract multi-timestamps from the multi-SFT-catalog view
      XLAL_CHECK ( (cfg->multiTimestamps = XLALTimestampsFromMultiSFTCatalogView ( cfg->multiNoiseCatalogView )) != NULL, XLAL_EFUNC );
      // extract IFOs from multi-SFT catalog
      XLAL_CHECK ( XLALMultiLALDetectorFromMultiSFTCatalogView ( &(cfg->multiIFO), cfg->multiNoiseCatalogView ) == XLAL_SUCCESS, XLAL_EFUNC );

    } // endif have_noiseSFTs
  else if ( have_timestampsFiles )
    {
      XLAL_CHECK ( (cfg->multiTimestamps = XLALReadMultiTimestampsFiles ( uvar->timestampsFiles )) != NULL, XLAL_EFUNC );

      XLAL_CHECK ( (cfg->multiTimestamps->length > 0) && (cfg->multiTimestamps->data != NULL), XLAL_EINVAL, "Got empty timestamps-list from XLALReadMultiTimestampsFiles()\n" );

      for ( UINT4 X=0; X < cfg->multiTimestamps->length; X ++ ) {
        cfg->multiTimestamps->data[X]->deltaT = uvar->Tsft;	// Tsft information not given by timestamps-file
      }
    } // endif have_timestampsFiles
  else if ( have_startTime && have_duration )
    {
      XLAL_CHECK ( ( cfg->multiTimestamps = XLALMakeMultiTimestamps ( uvar->startTime, uvar->duration, uvar->Tsft, uvar->SFToverlap, cfg->multiIFO.length )) != NULL, XLAL_EFUNC );
    } // endif have_startTime

  // check if the user asked for Gaussian white noise to be produced (sqrtSn[X]!=0), otherwise leave noise-floors at 0
  if ( uvar->sqrtSX != NULL ) {
    XLAL_CHECK ( XLALParseMultiNoiseFloor ( &(cfg->multiNoiseFloor), uvar->sqrtSX, cfg->multiIFO.length ) == XLAL_SUCCESS, XLAL_EFUNC );
  } else {
    cfg->multiNoiseFloor.length = cfg->multiIFO.length;
    // values remain at their default sqrtSn[X] = 0;
  }

#ifdef HAVE_LIBLALFRAME
  // if user requested time-series data from frames to be added: try to read the frames now
  if ( have_frames )
    {
      UINT4 numDetectors = uvar->inFrChannels->length;
      XLAL_CHECK ( uvar->inFrames->length == numDetectors, XLAL_EINVAL, "Need equal number of channel names (%d) as frame specifications (%d)\n", uvar->inFrChannels->length, numDetectors );

      XLAL_CHECK ( (cfg->inputMultiTS = XLALCalloc ( 1, sizeof(*cfg->inputMultiTS))) != NULL, XLAL_ENOMEM );
      cfg->inputMultiTS->length = numDetectors;
      XLAL_CHECK ( (cfg->inputMultiTS->data = XLALCalloc ( numDetectors, sizeof(cfg->inputMultiTS->data[0]) )) != NULL, XLAL_ENOMEM );
      if ( cfg->multiTimestamps == NULL )
        {
          XLAL_CHECK ( (cfg->multiTimestamps = XLALCalloc ( 1, sizeof(*cfg->multiTimestamps) )) != NULL, XLAL_ENOMEM );
          XLAL_CHECK ( (cfg->multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(cfg->multiTimestamps->data[0]))) != NULL, XLAL_ENOMEM );
          cfg->multiTimestamps->length = numDetectors;
        }
      for ( UINT4 X = 0; X < numDetectors; X ++ )
        {
          LALCache *cache;
          XLAL_CHECK ( (cache = XLALCacheImport ( uvar->inFrames->data[X] )) != NULL, XLAL_EFUNC, "Failed to import cache file '%s'\n", uvar->inFrames->data[X] );
          // this is a sorted cache, so extract its time-range:
          REAL8 cache_tStart = cache->list[0].t0;
          REAL8 cache_tEnd   = cache->list[cache->length-1].t0 + cache->list[cache->length-1].dt;
          REAL8 cache_duration = (cache_tEnd - cache_tStart);
          LIGOTimeGPS ts_start;
          REAL8 ts_duration;
          // check that it's consistent with timestamps, if given, otherwise create timestamps from this
          if ( cfg->multiTimestamps->data[X] != NULL )	// FIXME: implicitly assumes timestamps are sorted, which is not guaranteed by timestamps-reading from file
            {
              const LIGOTimeGPSVector *timestampsX = cfg->multiTimestamps->data[X];
              REAL8 tStart = XLALGPSGetREAL8( &timestampsX->data[0] );
              REAL8 tEnd   = XLALGPSGetREAL8( &timestampsX->data[timestampsX->length-1]) + timestampsX->deltaT;
              XLAL_CHECK ( tStart >= cache_tStart && tEnd <= cache_tEnd, XLAL_EINVAL, "Detector X=%d: Requested timestamps-range [%.0f, %.0f]s outside of cache range [%.0f,%.0f]s\n",
                           X, tStart, tEnd, cache_tStart, cache_tEnd );
              XLALGPSSetREAL8 ( &ts_start, tStart );
              ts_duration = (tEnd - tStart);
            }
          else
            {
              XLALGPSSetREAL8 ( &ts_start, (REAL8)cache_tStart + 1); // cache times can apparently be by rounded up or down by 1s, so shift by 1s to be safe
              ts_duration = cache_duration - 1;
              XLAL_CHECK ( (cfg->multiTimestamps->data[X] = XLALMakeTimestamps ( ts_start, ts_duration, uvar->Tsft, uvar->SFToverlap ) ) != NULL, XLAL_EFUNC );
            }
          // ----- now open frame stream and read *all* the data within this time-range [FIXME] ----------
          LALFrStream *stream;
          XLAL_CHECK ( (stream = XLALFrStreamCacheOpen ( cache )) != NULL, XLAL_EFUNC, "Failed to open stream from cache file '%s'\n", uvar->inFrames->data[X] );
          XLALDestroyCache ( cache );

          const char *channel = uvar->inFrChannels->data[X];
          size_t limit = 0;	// unlimited read
          REAL8TimeSeries *ts;
          XLAL_CHECK ( (ts = XLALFrStreamInputREAL8TimeSeries ( stream, channel, &ts_start, ts_duration, limit )) != NULL,
                       XLAL_EFUNC, "Frame reading failed for stream created for '%s': ts_start = {%d,%d}, duration=%.0f\n", uvar->inFrames->data[X], ts_start.gpsSeconds, ts_start.gpsNanoSeconds, ts_duration );
          cfg->inputMultiTS->data[X] = ts;

          XLAL_CHECK ( XLALFrStreamClose ( stream ) == XLAL_SUCCESS, XLAL_EFUNC, "Stream closing failed for cache file '%s'\n", uvar->inFrames->data[X] );
        } // for X < numDetectors
    } // if inFrames

  // if user requested timeseries *output* to frame files, handle deprecated options
  XLAL_CHECK ( !(uvar->TDDframedir && uvar->outFrameDir), XLAL_EINVAL, "Specify only ONE of {--TDDframedir or --outFrameDir} or NONE\n");
  if ( uvar->TDDframedir ) {
    cfg->outFrameDir = uvar->TDDframedir;
  } else if ( uvar->outFrameDir ) {
    cfg->outFrameDir = uvar->outFrameDir;
  }
#endif

  return XLAL_SUCCESS;

} /* XLALInitMakefakedata() */
int
main(int argc, char *argv[])
{
  FILE *fp = NULL;
  BarycenterInput XLAL_INIT_DECL(baryinput);
  INT4 leap0,leap;
  LIGOTimeGPS epoch;
  LIGOTimeGPS TstartSSB, TendSSB, TendGPS;
  INT4 n;
  LIGOTimeGPS *TSSB = NULL;
  MJDTime TstartUTCMJD;
  LIGOTimeGPS TDET;
  REAL8 temp;
  INT4 i;
  MJDTime tempTOA;
  REAL8 dt;
  LIGOTimeGPS TstartGPS;
  MJDTime *TOA = NULL;
  CHAR tempstr[18];
  CHAR *tempstr2;
  CHAR TstartMJDstr[20],TfinishMJDstr[20],TOAstr[22];
  PulsarSignalParams pulsarparams;
  CHAR parfile[256];
  CHAR timfile[256];
  CHAR detcode[16];
  REAL8 TstartUTCMJDtest;
  REAL8 diff;
  MJDTime MJDdiff, MJDtest;

  MJDTime TrefTDBMJD;
  LIGOTimeGPS TrefSSB_TDB_GPS;

  // ----------------------------------------------------------------------
  UserVariables_t XLAL_INIT_DECL(uvar);
  XLAL_CHECK ( initUserVars (argc, argv, &uvar) == XLAL_SUCCESS, XLAL_EFUNC );

  unsigned int seed = uvar.randSeed;
  if ( uvar.randSeed == 0 ) {
    seed = clock();
  }
  srand ( seed );

  // ----- sky position: random or user-specified ----------
  REAL8 alpha, delta;
  CHAR *RAJ = NULL, *DECJ = NULL;

  BOOLEAN have_RAJ  = XLALUserVarWasSet ( &uvar.RAJ );
  BOOLEAN have_DECJ = XLALUserVarWasSet ( &uvar.DECJ );
  if ( have_RAJ )
    {
      XLAL_CHECK ( XLALTranslateHMStoRAD ( &alpha, uvar.RAJ ) == XLAL_SUCCESS, XLAL_EFUNC );
      RAJ = XLALStringDuplicate ( uvar.RAJ );
    }
  else
    { // pick randomly
      alpha = LAL_TWOPI * (1.0 * rand() / ( RAND_MAX + 1.0 ) );  // alpha uniform in [0, 2pi)
      XLAL_CHECK ( (RAJ = XLALTranslateRADtoHMS ( alpha )) != NULL, XLAL_EFUNC );
    }
  if ( have_DECJ )
    {
      XLAL_CHECK ( XLALTranslateDMStoRAD ( &delta, uvar.DECJ ) == XLAL_SUCCESS, XLAL_EFUNC );
      DECJ = XLALStringDuplicate ( uvar.DECJ );
    }
  else
    { // pick randomly
      delta = LAL_PI_2 - acos ( 1 - 2.0 * rand()/RAND_MAX );	// sin(delta) uniform in [-1,1]
      XLAL_CHECK ( (DECJ = XLALTranslateRADtoDMS ( delta )) != NULL, XLAL_EFUNC );
    }

  /* define start time in an MJD structure */
  REAL8toMJD ( &TstartUTCMJD, uvar.TstartUTCMJD );
  XLALPrintInfo ( "TstartUTCMJD=%f converted to MJD days = %d fracdays = %6.12f\n", uvar.TstartUTCMJD, TstartUTCMJD.days, TstartUTCMJD.fracdays );

  /* convert back to test conversions */
  TstartUTCMJDtest = MJDtoREAL8 (TstartUTCMJD);
  diff = uvar.TstartUTCMJD - TstartUTCMJDtest;
  if ( fabs(diff) > 1e-9) {
    fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff);
    return(-1);
  }
  XLALPrintInfo ( "MJD conversion gives discrepancies of %e sec\n", diff);

  /* use start time to define an epoch for the leap seconds */
  /* Note that epochs are defined in TDB !!! but here we only need to be rough to get a leap second value */
  TDBMJDtoGPS(&epoch,TstartUTCMJD);
  XLALPrintInfo ( "leap second epoch = %d %d\n",epoch.gpsSeconds,epoch.gpsNanoSeconds);

  /* deal with ephemeris files and compute leap seconds */
  EphemerisData *edat;
  XLAL_CHECK ( (edat = XLALInitBarycenter( uvar.ephemEarth, uvar.ephemSun )) != NULL, XLAL_EFUNC );

  leap0 = XLALGPSLeapSeconds (epoch.gpsSeconds);
  XLALPrintInfo ( "leap seconds = %d\n",leap0);

  /* select detector location */
  if (strcmp(uvar.Observatory,"GBT")==0) {
    baryinput.site.location[0] = GBT_LOCATION_X;
    baryinput.site.location[1] = GBT_LOCATION_Y;
    baryinput.site.location[2] = GBT_LOCATION_Z;
    sprintf(detcode,"gbt");
  }
  else if (strcmp(uvar.Observatory,"NARRABRI")==0) {
    baryinput.site.location[0] = NARRABRI_LOCATION_X;
    baryinput.site.location[1] = NARRABRI_LOCATION_Y;
    baryinput.site.location[2] = NARRABRI_LOCATION_Z;
    sprintf(detcode,"atca");
  }
   else if (strcmp(uvar.Observatory,"ARECIBO")==0) {
    baryinput.site.location[0] = ARECIBO_LOCATION_X;
    baryinput.site.location[1] = ARECIBO_LOCATION_Y;
    baryinput.site.location[2] = ARECIBO_LOCATION_Z;
    sprintf(detcode,"ao");
  }
   else if (strcmp(uvar.Observatory,"NANSHAN")==0) {
    baryinput.site.location[0] = NANSHAN_LOCATION_X;
    baryinput.site.location[1] = NANSHAN_LOCATION_Y;
    baryinput.site.location[2] = NANSHAN_LOCATION_Z;
    sprintf(detcode,"nanshan");
  }
   else if (strcmp(uvar.Observatory,"DSS_43")==0) {
    baryinput.site.location[0] = DSS_43_LOCATION_X;
    baryinput.site.location[1] = DSS_43_LOCATION_Y;
    baryinput.site.location[2] = DSS_43_LOCATION_Z;
    sprintf(detcode,"tid43");
  }
  else if (strcmp(uvar.Observatory,"PARKES")==0) {
    baryinput.site.location[0] = PARKES_LOCATION_X;
    baryinput.site.location[1] = PARKES_LOCATION_Y;
    baryinput.site.location[2] = PARKES_LOCATION_Z;
    sprintf(detcode,"pks");
  }
   else if (strcmp(uvar.Observatory,"JODRELL")==0) {
    baryinput.site.location[0] = JODRELL_LOCATION_X;
    baryinput.site.location[1] = JODRELL_LOCATION_Y;
    baryinput.site.location[2] = JODRELL_LOCATION_Z;
    sprintf(detcode,"jb");
  }
   else if (strcmp(uvar.Observatory,"VLA")==0) {
    baryinput.site.location[0] = VLA_LOCATION_X;
    baryinput.site.location[1] = VLA_LOCATION_Y;
    baryinput.site.location[2] = VLA_LOCATION_Z;
    sprintf(detcode,"vla");
  }
   else if (strcmp(uvar.Observatory,"NANCAY")==0) {
    baryinput.site.location[0] = NANCAY_LOCATION_X;
    baryinput.site.location[1] = NANCAY_LOCATION_Y;
    baryinput.site.location[2] = NANCAY_LOCATION_Z;
    sprintf(detcode,"ncy");
  }
  else if (strcmp(uvar.Observatory,"EFFELSBERG")==0) {
    baryinput.site.location[0] = EFFELSBERG_LOCATION_X;
    baryinput.site.location[1] = EFFELSBERG_LOCATION_Y;
    baryinput.site.location[2] = EFFELSBERG_LOCATION_Z;
    sprintf(detcode,"eff");
  }
  else if (strcmp(uvar.Observatory,"JODRELLM4")==0) {
    baryinput.site.location[0] = JODRELLM4_LOCATION_X;
    baryinput.site.location[1] = JODRELLM4_LOCATION_Y;
    baryinput.site.location[2] = JODRELLM4_LOCATION_Z;
    sprintf(detcode,"jbm4");
  }
  else if (strcmp(uvar.Observatory,"GB300")==0) {
    baryinput.site.location[0] = GB300_LOCATION_X;
    baryinput.site.location[1] = GB300_LOCATION_Y;
    baryinput.site.location[2] = GB300_LOCATION_Z;
    sprintf(detcode,"gb300");
  }
  else if (strcmp(uvar.Observatory,"GB140")==0) {
    baryinput.site.location[0] = GB140_LOCATION_X;
    baryinput.site.location[1] = GB140_LOCATION_Y;
    baryinput.site.location[2] = GB140_LOCATION_Z;
    sprintf(detcode,"gb140");
  }
  else if (strcmp(uvar.Observatory,"GB853")==0) {
    baryinput.site.location[0] = GB853_LOCATION_X;
    baryinput.site.location[1] = GB853_LOCATION_Y;
    baryinput.site.location[2] = GB853_LOCATION_Z;
    sprintf(detcode,"gb853");
  }
  else if (strcmp(uvar.Observatory,"LA_PALMA")==0) {
    baryinput.site.location[0] = LA_PALMA_LOCATION_X;
    baryinput.site.location[1] = LA_PALMA_LOCATION_Y;
    baryinput.site.location[2] = LA_PALMA_LOCATION_Z;
    sprintf(detcode,"lap");
  }
  else if (strcmp(uvar.Observatory,"Hobart")==0) {
    baryinput.site.location[0] = Hobart_LOCATION_X;
    baryinput.site.location[1] = Hobart_LOCATION_Y;
    baryinput.site.location[2] = Hobart_LOCATION_Z;
    sprintf(detcode,"hob");
  }
  else if (strcmp(uvar.Observatory,"Hartebeesthoek")==0) {
    baryinput.site.location[0] = Hartebeesthoek_LOCATION_X;
    baryinput.site.location[1] = Hartebeesthoek_LOCATION_Y;
    baryinput.site.location[2] = Hartebeesthoek_LOCATION_Z;
    sprintf(detcode,"hart");
  }
  else if (strcmp(uvar.Observatory,"WSRT")==0) {
    baryinput.site.location[0] = WSRT_LOCATION_X;
    baryinput.site.location[1] = WSRT_LOCATION_Y;
    baryinput.site.location[2] = WSRT_LOCATION_Z;
    sprintf(detcode,"wsrt");
  }
  else if (strcmp(uvar.Observatory,"COE")==0) {
    baryinput.site.location[0] = COE_LOCATION_X;
    baryinput.site.location[1] = COE_LOCATION_Y;
    baryinput.site.location[2] = COE_LOCATION_Z;
    sprintf(detcode,"coe");
  }
  else if (strcmp(uvar.Observatory,"SSB")!=0) {
    fprintf(stderr,"ERROR. Unknown Observatory %s. Exiting.\n",uvar.Observatory);
    return(-1);
  }
  XLALPrintInfo ( "selected observatory %s - observatoryt code = %s\n",uvar.Observatory,detcode);
  XLALPrintInfo ( "baryinput location = %6.12f %6.12f %6.12f\n",baryinput.site.location[0],baryinput.site.location[1],baryinput.site.location[2]);

  /* convert start time to UTC GPS */
  UTCMJDtoGPS(&TstartGPS, TstartUTCMJD, leap0);
  XLALPrintInfo ( "TstartGPS = %d %d\n",TstartGPS.gpsSeconds,TstartGPS.gpsNanoSeconds);

  /* convert back to test conversion */
  UTCGPStoMJD(&MJDtest,&TstartGPS,leap0);
  deltaMJD ( &MJDdiff, &MJDtest, &TstartUTCMJD );
  diff = (MJDdiff.days+MJDdiff.fracdays)*86400;
  if ( fabs(diff)  > 1e-9) {
    fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff);
    return(-1);
  }
  XLALPrintInfo ( "MJD conversion gives discrepancies of %e sec\n",diff);

  /* define reference time in an MJD structure */
  REAL8toMJD ( &TrefTDBMJD, uvar.TrefTDBMJD );
  XLALPrintInfo ( "TrefTDBMJD converted to MJD days = %d fracdays = %6.12f\n",TrefTDBMJD.days,TrefTDBMJD.fracdays);

  /* convert reference time to TDB GPS */
  TDBMJDtoGPS(&TrefSSB_TDB_GPS,TrefTDBMJD);
  XLALPrintInfo ( "TrefSSB_TDB_GPS = %d %d\n",TrefSSB_TDB_GPS.gpsSeconds,TrefSSB_TDB_GPS.gpsNanoSeconds);

  /* convert back to test conversion */
  TDBGPStoMJD ( &MJDtest, TrefSSB_TDB_GPS, leap0 );
  deltaMJD ( &MJDdiff, &MJDtest, &TrefTDBMJD );
  diff = (MJDdiff.days+MJDdiff.fracdays)*86400;
  if ( fabs(diff)  > 1e-9) {
    fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff);
    return(-1);
  }
  XLALPrintInfo ( "MJD conversion gives discrepancies of %e sec\n",diff);

  /* fill in required pulsar params structure for Barycentering */
  LALDetector *site = NULL;
  site = (LALDetector *)LALMalloc(sizeof(LALDetector));
  site->location[0] = baryinput.site.location[0];
  site->location[1] = baryinput.site.location[1];
  site->location[2] = baryinput.site.location[2];
  pulsarparams.site = site;

  pulsarparams.pulsar.position.longitude = alpha;
  pulsarparams.pulsar.position.latitude = delta;
  pulsarparams.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL;
  pulsarparams.ephemerides = edat;

  /* generate SSB initial TOA in GPS */
  XLALConvertGPS2SSB ( &TstartSSB, TstartGPS, &pulsarparams);
  XLALPrintInfo ( "TstartSSB = %d %d\n",TstartSSB.gpsSeconds,TstartSSB.gpsNanoSeconds);

  /* define TOA end time in GPS */
  temp = uvar.DurationMJD*86400.0;
  TendGPS = TstartGPS;
  XLALGPSAdd(&TendGPS, temp);
  XLALPrintInfo ( "GPS end time of TOAs = %d %d\n",TendGPS.gpsSeconds,TendGPS.gpsNanoSeconds);

  /* generate SSB end time in GPS (force integer seconds) */
  XLALConvertGPS2SSB (&TendSSB,TendGPS,&pulsarparams);
  XLALPrintInfo  ( "TendSSB = %d %d\n",TendSSB.gpsSeconds,TendSSB.gpsNanoSeconds);

  /* define TOA seperation in the SSB */
  dt = uvar.DeltaTMJD*86400.0;
  n = (INT4)ceil(uvar.DurationMJD/uvar.DeltaTMJD);
  XLALPrintInfo ( "TOA seperation at SSB = %g sec\n",dt);
  XLALPrintInfo ( "number of TOAs to generate = %d\n",n);

  /* allocate memory for artificial SSB TOAs */
  TSSB = (LIGOTimeGPS *)LALMalloc(n*sizeof(LIGOTimeGPS));
  TOA = (MJDTime *)LALMalloc(n*sizeof(MJDTime));

  /* generate artificial SSB TOAs given the phase model phi = 2*pi*(f0*(t-tref) + 0.5*fdot*(t-tref)^2) */
  for  (i=0;i<n;i++)
    {
      REAL8 dtref,fnow,cyclefrac,dtcor;
      LIGOTimeGPS tnow;

      /* define current interval */
      XLALPrintInfo ( "current (t-tstart) = %g sec\n", i * dt);

      /* define current t */
      tnow = TstartSSB;
      XLALGPSAdd(&tnow, i * dt);
      XLALPrintInfo ( "current t = %d %d\n",tnow.gpsSeconds,tnow.gpsNanoSeconds);

      /* define current t-tref */
      dtref = XLALGPSDiff(&tnow,&TrefSSB_TDB_GPS);
      XLALPrintInfo ( "current (t - tref) = %9.12f\n",dtref);

      dtcor = 1;
      while (dtcor>1e-9)
        {

          /* define actual cycle fraction at requested time */
          cyclefrac = fmod(uvar.f0*dtref + 0.5*uvar.fdot*dtref*dtref,1.0);
          XLALPrintInfo ( "cyclefrac = %9.12f\n",cyclefrac);

          /* define instantaneous frequency */
          fnow = uvar.f0 + uvar.fdot*dtref;
          XLALPrintInfo ( "instananeous frequency = %9.12f\n",fnow);

          /* add correction to time */
          dtcor = cyclefrac/fnow;
          dtref -= dtcor;
          XLALPrintInfo ( "timing correction = %9.12f\n",dtcor);
          XLALPrintInfo ( "corrected dtref to = %9.12f\n",dtref);
        } // while dtcor>1e-9

      /* define time of zero phase */
      TSSB[i] = TrefSSB_TDB_GPS;
      XLALGPSAdd(&TSSB[i], dtref);
      XLALPrintInfo ( "TSSB[%d] = %d %d\n",i,TSSB[i].gpsSeconds,TSSB[i].gpsNanoSeconds);
    } // for i < n

  /* loop over SSB time of arrivals and compute detector time of arrivals */
  for (i=0;i<n;i++)
    {
      LIGOTimeGPS TSSBtest;
      LIGOTimeGPS GPStest;

      /* convert SSB to Detector time */
      int ret = XLALConvertSSB2GPS ( &TDET, TSSB[i], &pulsarparams);
      if ( ret != XLAL_SUCCESS ) {
        XLALPrintError ("XLALConvertSSB2GPS() failed with xlalErrno = %d\n", xlalErrno );
	return(-1);
      }

      XLALPrintInfo ( "converted SSB TOA %d %d -> Detector TOA %d %d\n",TSSB[i].gpsSeconds,TSSB[i].gpsNanoSeconds,TDET.gpsSeconds,TDET.gpsNanoSeconds);

      /* convert back for testing conversion */
      XLALConvertGPS2SSB (&TSSBtest,TDET,&pulsarparams);
      diff = XLALGPSDiff(&TSSBtest,&TSSB[i]);
      if ( fabs(diff)  > 1e-9) {
	fprintf(stderr,"ERROR : Time conversion gives discrepancy of %e sec. Exiting.\n",diff);
	return(-1);
      }
      XLALPrintInfo ( "SSB -> detector conversion gives discrepancies of %e sec\n",diff);

      /* recompute leap seconds incase they've changed */
      leap = XLALGPSLeapSeconds (TDET.gpsSeconds);

      /* must now convert to an MJD time for TEMPO */
      /* Using UTC conversion as used by Matt in his successful comparison */
      UTCGPStoMJD (&tempTOA,&TDET,leap);
      XLALPrintInfo ( "output MJD time = %d %6.12f\n",tempTOA.days,tempTOA.fracdays);

      /* convert back to test conversion */
      UTCMJDtoGPS ( &GPStest, tempTOA, leap );
      diff = XLALGPSDiff(&TDET,&GPStest);
      if ( fabs(diff)  > 1e-9) {
	fprintf(stderr,"ERROR. Time conversion gives discrepancy of %e sec. Exiting.\n",diff);
	return(-1);
      }
      XLALPrintInfo ( "MJD time conversion gives discrepancies of %e sec\n",diff);

      /* fill in results */
      TOA[i].days = tempTOA.days;
      TOA[i].fracdays = tempTOA.fracdays;

    } // for i < n

  snprintf(tempstr,15,"%1.13f",TOA[0].fracdays);
  tempstr2 = tempstr+2;
  snprintf(TstartMJDstr,19,"%d.%s",TOA[0].days,tempstr2);
  XLALPrintInfo ( "Converted initial TOA MJD %d %6.12f to the string %s\n",TOA[0].days,TOA[0].fracdays,TstartMJDstr);

  snprintf(tempstr,15,"%1.13f",TOA[n-1].fracdays);
  tempstr2 = tempstr+2;
  snprintf(TfinishMJDstr,19,"%d.%s",TOA[n-1].days,tempstr2);
  XLALPrintInfo ( "*** Converted MJD to a string %s\n",TfinishMJDstr);
  XLALPrintInfo ( "Converted final TOA MJD %d %6.12f to the string %s\n",TOA[n-1].days,TOA[n-1].fracdays,TfinishMJDstr);

  /* define output file names */
  sprintf(parfile,"%s.par",uvar.PSRJ);
  sprintf(timfile,"%s.tim",uvar.PSRJ);

  /* output to par file in format required by TEMPO 2 */
  if ((fp = fopen(parfile,"w")) == NULL) {
    fprintf(stderr,"ERROR. Could not open file %s. Exiting.\n",parfile);
    return(-1);
  }
  fprintf(fp,"PSRJ\t%s\n",uvar.PSRJ);
  fprintf(fp,"RAJ\t%s\t1\n",RAJ);
  fprintf(fp,"DECJ\t%s\t1\n",DECJ);
  fprintf(fp,"PEPOCH\t%6.12f\n",uvar.TrefTDBMJD);
  fprintf(fp,"POSEPOCH\t%6.12f\n",uvar.TrefTDBMJD);
  fprintf(fp,"DMEPOCH\t%6.12f\n",uvar.TrefTDBMJD);
  fprintf(fp,"DM\t0.0\n");
  fprintf(fp,"F0\t%6.16f\t1\n",uvar.f0);
  fprintf(fp,"F1\t%6.16f\t0\n",uvar.fdot);
  fprintf(fp,"START\t%s\n",TstartMJDstr);
  fprintf(fp,"FINISH\t%s\n",TfinishMJDstr);
  fprintf(fp,"TZRSITE\t%s\n",detcode);
  fprintf(fp,"CLK\tUTC(NIST)\n");
  fprintf(fp,"EPHEM\tDE405\n");
  fprintf(fp,"UNITS\tTDB\n");
  fprintf(fp,"MODE\t0\n");

  /* close par file */
  fclose(fp);

  /* output to tim file in format required by TEMPO 2 */
  if ((fp = fopen(timfile,"w")) == NULL) {
    fprintf(stderr,"ERROR. Could not open file %s. Exiting.\n",timfile);
    return(-1);
  }

  fprintf(fp,"FORMAT 1\n");
  for (i=0;i<n;i++)
    {
      /* convert each TOA to a string for output */
      snprintf(tempstr,18,"%1.16f",TOA[i].fracdays);
      tempstr2 = tempstr+2;
      snprintf(TOAstr,22,"%d.%s",TOA[i].days,tempstr2);
      fprintf(fp,"blank.dat\t1000.0\t%s\t1.0\t%s\n",TOAstr,detcode);
      XLALPrintInfo ( "Converting MJD time %d %6.16f to string %s\n",TOA[i].days,TOA[i].fracdays,TOAstr);
    } // for i < n

  /* close tim file */
  fclose(fp);

  /* free memory */
  XLALFree ( TSSB );
  XLALFree ( TOA );
  XLALFree ( site );
  XLALDestroyEphemerisData ( edat );
  XLALDestroyUserVars ();
  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} /* main() */
/* void RunGeneratePulsarSignalTest(LALStatus *status, int argc, char **argv) */ /* 02/02/05 gam */
void RunGeneratePulsarSignalTest(LALStatus *status)
{
  INT4    i, j, k;         /* all purpose indices */
  INT4    iSky = 0;        /* for loop over sky positions */
  INT4    jDeriv = 0;      /* for loop over spindowns */
  INT4    testNumber = 0;  /* which test is being run */

  /* The input and output structs used by the functions being tested */
  PulsarSignalParams *pPulsarSignalParams = NULL;
  REAL4TimeSeries *signalvec = NULL;
  SFTParams *pSFTParams = NULL;
  SkyConstAndZeroPsiAMResponse *pSkyConstAndZeroPsiAMResponse;
  SFTandSignalParams *pSFTandSignalParams;
  SFTVector *outputSFTs = NULL;
  SFTVector *fastOutputSFTs = NULL;
  REAL4 renorm; /* to renormalize SFTs to account for different effective sample rates */

  /* containers for detector and ephemeris data */
  LALDetector cachedDetector;
  CHAR IFO[6] = "LHO";
  EphemerisData *edat = NULL;

  char earthFile[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz";
  char sunFile[]   = TEST_DATA_DIR "sun00-19-DE405.dat.gz";

  /* containers for sky position and spindown data */
  REAL8 **skyPosData;
  REAL8 **freqDerivData;
  INT4 numSkyPosTotal = 8;
  INT4 numSpinDown = 1;
  INT4 numFreqDerivTotal = 2;
  INT4 numFreqDerivIncludingNoSpinDown; /* set below */
  INT4 iFreq = 0;
  REAL8 cosTmpDEC;
  REAL8 tmpDeltaRA;
  REAL8 DeltaRA = 0.01;
  REAL8 DeltaDec = 0.01;
  REAL8 DeltaFDeriv1 = -1.0e-10;
  REAL8 DeltaFDeriv2 = 0.0;
  REAL8 DeltaFDeriv3 = 0.0;
  REAL8 DeltaFDeriv4 = 0.0;
  REAL8 DeltaFDeriv5 = 0.0;

  /* containers for number of SFTs, times to generate SFTs, reference time, and gap */
  INT4 numSFTs = 4;
  REAL8 f0SFT = 943.12;
  REAL8 bandSFT = 0.5;
  UINT4 gpsStartTimeSec = 765432109; /* GPS start time of data requested seconds; example = Apr 08 2004 04:01:36 UTC */
  UINT4 gpsStartTimeNan = 0;          /* GPS start time of data requested nanoseconds */
  LIGOTimeGPSVector *timeStamps;
  LIGOTimeGPS GPSin;   /* holder for reference-time for pulsar parameters at the detector; will convert to SSB! */
  REAL8 sftGap = 73.0; /* extra artificial gap between SFTs */
  REAL8 tSFT   = 1800.0;
  REAL8 duration = tSFT + (numSFTs - 1)*(tSFT + sftGap);
  INT4 nBinsSFT = (INT4)(bandSFT*tSFT + 0.5);

  /* additional parameters that determine what signals to test; note f0SGNL and bandSGNL must be compatible with f0SFT and bandSFT */
  REAL8 f0SGNL = f0SFT + bandSFT/2.0;
  REAL8 dfSGNL = 1.0/tSFT;
  REAL8 bandSGNL = 0.005;
  INT4  nBinsSGNL = (INT4)(bandSGNL*tSFT + 0.5);
  INT4  nsamples = 18000; /* nsamples from SFT header; 2 x this would be the effective number of time samples used to create an SFT from raw data */
  INT4  Dterms = 3;       /* 09/07/05 gam; use Dterms to fill in SFT bins with fake data as per LALDemod else fill in bin with zero */
  REAL8 h_0 = 7.0e-22;    /* Source amplitude; use arbitrary small number for default */
  REAL8 cosIota;        /* cosine of inclination angle iota of the source */

  /* variables for comparing differences */
  REAL4 maxDiffSFTMod, diffAtMaxPower;
  REAL4 overallMaxDiffSFTMod;
  REAL4 maxMod, fastMaxMod;
  INT4  jMaxMod, jFastMaxMod;
  REAL4 tmpDiffSFTMod, sftMod, fastSFTMod;
  REAL4 smallMod = 1.e-30;
  REAL4 epsDiffMod;
  REAL4 epsBinErrorRate;   /* 10/12/04 gam; Allowed bin error rate */
  INT4  binErrorCount = 0; /* 10/12/04 gam; Count number of bin errors  */

  /* randval is always set to a default value or given a random value to generate certain signal parameters or mismatch */
  REAL4 randval;
  #ifdef INCLUDE_RANDVAL_MISMATCH
   INT4 seed=0;
   INT4 rndCount;
   RandomParams *randPar=NULL;
   FILE *fpRandom;
  #endif

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* generate timeStamps */
  timeStamps = (LIGOTimeGPSVector *)LALMalloc(sizeof(LIGOTimeGPSVector));
  timeStamps->data =(LIGOTimeGPS *)LALMalloc (numSFTs*sizeof(LIGOTimeGPS));
  timeStamps->length = numSFTs;
  for (i = 0; i < numSFTs; i++) {
      timeStamps->data[i].gpsSeconds = gpsStartTimeSec + (UINT4)(i*(tSFT + sftGap));
      timeStamps->data[i].gpsNanoSeconds = 0;
  } /* for i < numSFTs */

  /* generate skyPosData */
  skyPosData=(REAL8 **)LALMalloc(numSkyPosTotal*sizeof(REAL8 *));
  for(iSky=0;iSky<numSkyPosTotal;iSky++)
  {
        skyPosData[iSky] = (REAL8 *)LALMalloc(2*sizeof(REAL8));
        /* Try fairly random sky positions skyPosData[iSky][0] = RA, skyPosData[iSky][1] = DEC */
        if (iSky == 0) {
          skyPosData[iSky][0] = 0.02*LAL_TWOPI;
          skyPosData[iSky][1] = 0.03*LAL_PI/2.0;
        } else if (iSky == 1) {
          skyPosData[iSky][0] = 0.23*LAL_TWOPI;
          skyPosData[iSky][1] = -0.57*LAL_PI/2.0;
        } else if (iSky == 2) {
          skyPosData[iSky][0] = 0.47*LAL_TWOPI;
          skyPosData[iSky][1] = 0.86*LAL_PI/2.0;
        } else if (iSky == 3) {
          skyPosData[iSky][0] = 0.38*LAL_TWOPI;
          skyPosData[iSky][1] = -0.07*LAL_PI/2.0;
        } else if (iSky == 4) {
          skyPosData[iSky][0] = 0.65*LAL_TWOPI;
          skyPosData[iSky][1] = 0.99*LAL_PI/2.0;
        } else if (iSky == 5) {
          skyPosData[iSky][0] = 0.72*LAL_TWOPI;
          skyPosData[iSky][1] = -0.99*LAL_PI/2.0;
        } else if (iSky == 6) {
          skyPosData[iSky][0] = 0.81*LAL_TWOPI;
          skyPosData[iSky][1] = 0.19*LAL_PI/2.0;
        } else if (iSky == 7) {
          skyPosData[iSky][0] = 0.99*LAL_TWOPI;
          skyPosData[iSky][1] = 0.01*LAL_PI/2.0;
        } else {
          skyPosData[iSky][0] = 0.0;
          skyPosData[iSky][1] = 0.0;
        } /* END if (k == 0) ELSE ... */
  } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */

  freqDerivData = NULL; /* 02/02/05 gam */
  if (numSpinDown > 0) {
    freqDerivData=(REAL8 **)LALMalloc(numFreqDerivTotal*sizeof(REAL8 *));
    for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) {
        freqDerivData[jDeriv] = (REAL8 *)LALMalloc(numSpinDown*sizeof(REAL8));
        if (jDeriv == 0) {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 0.0;
          }
        } else if (jDeriv == 1) {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 1.e-9; /* REALLY THIS IS ONLY GOOD FOR numSpinDown = 1; */
          }
        } else {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 0.0;
          }
        } /* END if (k == 0) ELSE ... */
    } /* END for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) */
    numFreqDerivIncludingNoSpinDown = numFreqDerivTotal;
  } else {
    numFreqDerivIncludingNoSpinDown = 1;  /* Even if numSpinDown = 0 still need to count case of zero spindown. */
  }  /* END if (numSpinDown > 0) ELSE ... */

  /* Initialize ephemeris data */
  XLAL_CHECK_LAL (status, ( edat = XLALInitBarycenter( earthFile, sunFile ) ) != NULL, XLAL_EFUNC);

  /* Allocate memory for PulsarSignalParams and initialize */
  pPulsarSignalParams = (PulsarSignalParams *)LALMalloc(sizeof(PulsarSignalParams));
  pPulsarSignalParams->pulsar.position.system = COORDINATESYSTEM_EQUATORIAL;
  pPulsarSignalParams->pulsar.spindown = NULL;
  if (numSpinDown > 0) {
    LALDCreateVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown),((UINT4)numSpinDown));
    CHECKSTATUSPTR (status);
  }
  pPulsarSignalParams->orbit.asini = 0 /* isolated pulsar */;
  pPulsarSignalParams->transfer = NULL;
  pPulsarSignalParams->dtDelayBy2 = 0;
  pPulsarSignalParams->dtPolBy2 = 0;
  /* Set up pulsar site */
  if (strstr(IFO, "LHO")) {
       cachedDetector = lalCachedDetectors[LALDetectorIndexLHODIFF];
  } else if (strstr(IFO, "LLO")) {
       cachedDetector = lalCachedDetectors[LALDetectorIndexLLODIFF];
  } else if (strstr(IFO, "GEO")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexGEO600DIFF];
  } else if (strstr(IFO, "VIRGO")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexVIRGODIFF];
  } else if (strstr(IFO, "TAMA")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexTAMA300DIFF];
  } else {
      /* "Invalid or null IFO" */
      ABORT( status, GENERATEPULSARSIGNALTESTC_EIFO, GENERATEPULSARSIGNALTESTC_MSGEIFO);
  }
  pPulsarSignalParams->site = &cachedDetector;
  pPulsarSignalParams->ephemerides = edat;
  pPulsarSignalParams->startTimeGPS.gpsSeconds = (INT4)gpsStartTimeSec;
  pPulsarSignalParams->startTimeGPS.gpsNanoSeconds = (INT4)gpsStartTimeNan;
  pPulsarSignalParams->duration = (UINT4)duration;
  pPulsarSignalParams->samplingRate = (REAL8)ceil(2.0*bandSFT); /* Make sampleRate an integer so that T*samplingRate = integer for integer T */
  pPulsarSignalParams->fHeterodyne = f0SFT;

  GPSin.gpsSeconds = timeStamps->data[0].gpsSeconds;
  GPSin.gpsNanoSeconds = timeStamps->data[0].gpsNanoSeconds;

  /* Allocate memory for SFTParams and initialize */
  pSFTParams = (SFTParams *)LALCalloc(1, sizeof(SFTParams));
  pSFTParams->Tsft = tSFT;
  pSFTParams->timestamps = timeStamps;
  pSFTParams->noiseSFTs = NULL;

  #ifdef INCLUDE_RANDVAL_MISMATCH
    /* Initial seed and randPar to use LALUniformDeviate to generate random mismatch during Monte Carlo. */
    fpRandom = fopen("/dev/urandom","r");
    rndCount = fread(&seed, sizeof(INT4),1, fpRandom);
    fclose(fpRandom);
    /* seed = 1234; */ /* Test value */
    LALCreateRandomParams(status->statusPtr, &randPar, seed);
    CHECKSTATUSPTR (status);
  #endif

  /* allocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */
  pSkyConstAndZeroPsiAMResponse = (SkyConstAndZeroPsiAMResponse *)LALMalloc(sizeof(SkyConstAndZeroPsiAMResponse));
  pSkyConstAndZeroPsiAMResponse->skyConst = (REAL8 *)LALMalloc((2*numSpinDown*(numSFTs+1)+2*numSFTs+3)*sizeof(REAL8));
  pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4));
  pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4));
  pSFTandSignalParams = (SFTandSignalParams *)LALMalloc(sizeof(SFTandSignalParams));
  /* create lookup table (LUT) values for doing trig */
  /* pSFTandSignalParams->resTrig = 64; */ /* length sinVal and cosVal; resolution of trig functions = 2pi/resTrig */
  /* pSFTandSignalParams->resTrig = 128; */ /* 10/08/04 gam; length sinVal and cosVal; domain = -2pi to 2pi inclusive; resolution = 4pi/resTrig */
  pSFTandSignalParams->resTrig = 0; /* 10/12/04 gam; turn off using LUTs since this is more typical. */
  /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */
  if (pSFTandSignalParams->resTrig > 0) {
    pSFTandSignalParams->trigArg = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    pSFTandSignalParams->sinVal  = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    pSFTandSignalParams->cosVal  = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    for (k=0; k<=pSFTandSignalParams->resTrig; k++) {
       /* pSFTandSignalParams->trigArg[k]= ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig); */ /* 10/08/04 gam */
       pSFTandSignalParams->trigArg[k]= -1.0*((REAL8)LAL_TWOPI) + 2.0 * ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig);
       pSFTandSignalParams->sinVal[k]=sin( pSFTandSignalParams->trigArg[k] );
       pSFTandSignalParams->cosVal[k]=cos( pSFTandSignalParams->trigArg[k] );
    }
  }
  pSFTandSignalParams->pSigParams = pPulsarSignalParams;
  pSFTandSignalParams->pSFTParams = pSFTParams;
  pSFTandSignalParams->nSamples = nsamples;
  pSFTandSignalParams->Dterms = Dterms;  /* 09/07/05 gam */

  /* ********************************************************/
  /*                                                       */
  /* START SECTION: LOOP OVER SKY POSITIONS                */
  /*                                                       */
  /* ********************************************************/
  for(iSky=0;iSky<numSkyPosTotal;iSky++) {

    /* set source sky position declination (DEC) */
    randval = 0.5; /* Gives default value */
    #ifdef INCLUDE_SEQUENTIAL_MISMATCH
      randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
    #endif
    #ifdef INCLUDE_RANDVAL_MISMATCH
       LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
    #endif
    pPulsarSignalParams->pulsar.position.latitude = skyPosData[iSky][1] + (((REAL8)randval) - 0.5)*DeltaDec;
    cosTmpDEC = cos(skyPosData[iSky][1]);
    if (cosTmpDEC != 0.0) {
          tmpDeltaRA = DeltaRA/cosTmpDEC;
    } else {
          tmpDeltaRA = 0.0; /* We are at a celestial pole */
    }

    /* set source sky position right ascension (RA) */
    randval = 0.5; /* Gives default value */
    #ifdef INCLUDE_SEQUENTIAL_MISMATCH
      randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
    #endif
    #ifdef INCLUDE_RANDVAL_MISMATCH
      LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
    #endif
    pPulsarSignalParams->pulsar.position.longitude = skyPosData[iSky][0] + (((REAL8)randval) - 0.5)*tmpDeltaRA;

    /* Find reference time in SSB for this sky positions */
    int ret = XLALConvertGPS2SSB ( &(pPulsarSignalParams->pulsar.refTime), GPSin, pPulsarSignalParams );
    if ( ret != XLAL_SUCCESS ) {
      XLALPrintError ("XLALConvertGPS2SSB() failed with xlalErrno = %d\n", xlalErrno );
      ABORTXLAL (status);
    }

    /* one per sky position fill in SkyConstAndZeroPsiAMResponse for use with LALFastGeneratePulsarSFTs */
    LALComputeSkyAndZeroPsiAMResponse (status->statusPtr, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams);
    CHECKSTATUSPTR (status);

    /* ********************************************************/
    /*                                                       */
    /* START SECTION: LOOP OVER SPINDOWN                     */
    /*                                                       */
    /* ********************************************************/
    for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) {
     /* source spindown parameters */
     if (numSpinDown > 0) {
       for(k=0;k<numSpinDown;k++) {
         randval = 0.5; /* Gives default value */
         #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            if (freqDerivData[jDeriv][k] < 0.0) {
               randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
            } else {
               randval = 0.5; /* If derivative is not negative (i.e., it is zero) then do not add in mismatch; keep it zero. */
            }
         #endif
         #ifdef INCLUDE_RANDVAL_MISMATCH
           LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
         #endif
         if (k == 0) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv1;
         } else if (k == 1) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv2;
         } else if (k == 2) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv3;
         } else if (k == 3) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv4;
         } else if (k == 4) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv5;
         } /* END if (k == 0) ELSE ... */
       }
     }

     /* ***************************************************/
     /*                                                  */
     /* START SECTION: LOOP OVER FREQUENCIES             */
     /*                                                  */
     /* ***************************************************/
     for(iFreq=0;iFreq<nBinsSGNL;iFreq++) {

       /* set source orientation psi */
       randval = 0.5; /* Gives default value */
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.psi = (randval - 0.5) * ((REAL4)LAL_PI_2);

       /* set angle between source spin axis and direction from source to SSB, cosIota */
       randval = 1.0; /* Gives default value */
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       cosIota = 2.0*((REAL8)randval) - 1.0;

       /* h_0 is fixed above; get A_+ and A_x from h_0 and cosIota */
       pPulsarSignalParams->pulsar.aPlus = (REAL4)(0.5*h_0*(1.0 + cosIota*cosIota));
       pPulsarSignalParams->pulsar.aCross = (REAL4)(h_0*cosIota);

       /* get random value for phi0 */
       randval = 0.125; /* Gives default value pi/4*/
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.phi0 = ((REAL8)randval) * ((REAL8)LAL_TWOPI);

       /* randval steps through various mismatches to frequencies centered on a bin */
       /* Note that iFreq = nBinsSGNL/2 gives randval = 0.5 gives no mismatch from frequency centered on a bin */
       randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.f0 = f0SGNL + iFreq*dfSGNL + (((REAL8)randval) - 0.5)*dfSGNL;

       testNumber++; /* Update count of which test we about to do. */

       /* FIRST: Use LALGeneratePulsarSignal and LALSignalToSFTs to generate outputSFTs */
       signalvec = NULL;
       LALGeneratePulsarSignal(status->statusPtr, &signalvec, pPulsarSignalParams);
       CHECKSTATUSPTR (status);
       outputSFTs = NULL;
       LALSignalToSFTs(status->statusPtr, &outputSFTs, signalvec, pSFTParams);
       CHECKSTATUSPTR (status);

       #ifdef PRINT_OUTPUTSFT
           if (testNumber == TESTNUMBER_TO_PRINT) {
              i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */
              fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0);
              fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross);
              fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi);
              fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0);
              fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0);
              fprintf(stdout,"outputSFTs->data[%i].data->length = %i \n",i,outputSFTs->data[i].data->length);
              renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1));
              for(j=0;j<nBinsSFT;j++) {
                /* fprintf(stdout,"%i %g %g \n", j, renorm*outputSFTs->data[i].data->data[j].re, renorm*outputSFTs->data[i].data->data[j].im); */
                fprintf(stdout,"%i %g \n",j,renorm*renorm*outputSFTs->data[i].data->data[j].re*outputSFTs->data[i].data->data[j].re + renorm*renorm*outputSFTs->data[i].data->data[j].im*outputSFTs->data[i].data->data[j].im);
                fflush(stdout);
              }
           }
       #endif

       /* SECOND: Use LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs to generate outputSFTs */
       LALFastGeneratePulsarSFTs (status->statusPtr, &fastOutputSFTs, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams);
       CHECKSTATUSPTR (status);

       #ifdef PRINT_FASTOUTPUTSFT
          if (testNumber == TESTNUMBER_TO_PRINT) {
            REAL4  fPlus;
            REAL4  fCross;
            i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */
            fPlus = pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) + pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi);
            fCross = pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) - pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi);
            fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0);
            fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross);
            fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi);
            fprintf(stdout,"iFreq = %i, fPlus, fCross = %23.10e,  %23.10e \n",iFreq,fPlus,fCross);
            fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0);
            fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0);
            fprintf(stdout,"fastOutputSFTs->data[%i].data->length = %i \n",i,fastOutputSFTs->data[i].data->length);
            fflush(stdout);
            for(j=0;j<nBinsSFT;j++) {
               /* fprintf(stdout,"%i %g %g \n",j,fastOutputSFTs->data[i].data->data[j].re,fastOutputSFTs->data[i].data->data[j].im); */
               fprintf(stdout,"%i %g \n",j,fastOutputSFTs->data[i].data->data[j].re*fastOutputSFTs->data[i].data->data[j].re + fastOutputSFTs->data[i].data->data[j].im*fastOutputSFTs->data[i].data->data[j].im);
               fflush(stdout);
            }
          }
       #endif

       /* find maximum difference in power */
       epsDiffMod = 0.20; /* maximum allowed percent difference */ /* 10/12/04 gam */
       overallMaxDiffSFTMod = 0.0;
       for (i = 0; i < numSFTs; i++) {
          renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1));
          maxDiffSFTMod = 0.0;
          diffAtMaxPower = 0.0;
          maxMod = 0.0;
          fastMaxMod = 0.0;
          jMaxMod = -1;
          jFastMaxMod = -1;
          /* Since doppler shifts can move the signal by an unknown number of bins search the whole band for max modulus: */
          for(j=0;j<nBinsSFT;j++) {
               sftMod = renorm*renorm*crealf(outputSFTs->data[i].data->data[j])*crealf(outputSFTs->data[i].data->data[j]) + renorm*renorm*cimagf(outputSFTs->data[i].data->data[j])*cimagf(outputSFTs->data[i].data->data[j]);
               sftMod = sqrt(sftMod);
               fastSFTMod = crealf(fastOutputSFTs->data[i].data->data[j])*crealf(fastOutputSFTs->data[i].data->data[j]) + cimagf(fastOutputSFTs->data[i].data->data[j])*cimagf(fastOutputSFTs->data[i].data->data[j]);
               fastSFTMod = sqrt(fastSFTMod);
               if (fabs(sftMod) > smallMod) {
                   tmpDiffSFTMod = fabs((sftMod - fastSFTMod)/sftMod);
                   if (tmpDiffSFTMod > maxDiffSFTMod) {
                       maxDiffSFTMod = tmpDiffSFTMod;
                   }
                   if (tmpDiffSFTMod > overallMaxDiffSFTMod) {
                       overallMaxDiffSFTMod = tmpDiffSFTMod;
                   }
                   if (sftMod > maxMod) {
                       maxMod = sftMod;
                       jMaxMod = j;
                   }
                   if (fastSFTMod > fastMaxMod) {
                       fastMaxMod = fastSFTMod;
                       jFastMaxMod = j;
                   }
               }
          }
          if (fabs(maxMod) > smallMod) {
             diffAtMaxPower = fabs((maxMod - fastMaxMod)/maxMod);
          }
          #ifdef PRINT_MAXSFTPOWER
            fprintf(stdout,"maxSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxMod,maxMod);
            fprintf(stdout,"maxFastSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jFastMaxMod,fastMaxMod);
            fflush(stdout);
          #endif
          #ifdef PRINT_MAXDIFFSFTPOWER
            fprintf(stdout,"maxDiffSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxDiff,maxDiffSFTMod);
            fflush(stdout);
          #endif
          #ifdef PRINT_DIFFATMAXPOWER
            fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower);
            fflush(stdout);
          #endif
          #ifdef PRINT_ERRORATMAXPOWER
            if (diffAtMaxPower > epsDiffMod) {
              fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g exceeded epsDiffMod = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower,epsDiffMod);
              fflush(stdout);
              /* break; */ /* only report 1 error per test */
            }
            if (jMaxMod != jFastMaxMod) {
              fprintf(stdout,"MaxPower occurred in different bins: testNumber %i, SFT %i, bins %i and %i\n",testNumber,i,jMaxMod,jFastMaxMod);
              fflush(stdout);
              /* break; */ /* only report 1 error per test */
            }
          #endif
          if (jMaxMod != jFastMaxMod) {
              binErrorCount++; /* 10/12/04 gam; count up bin errors; if too ABORT at bottom of code */
          }
          if ( diffAtMaxPower > epsDiffMod ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EMOD, GENERATEPULSARSIGNALTESTC_MSGEMOD);
          }
          /* 10/12/04 gam; turn on test above and add test below */
          if ( fabs(((REAL8)(jMaxMod - jFastMaxMod))) >  1.1 ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EBIN,   GENERATEPULSARSIGNALTESTC_MSGEBIN);
          }
       } /* END for(i = 0; i < numSFTs; i++) */
       #ifdef PRINT_OVERALLMAXDIFFSFTPOWER
         fprintf(stdout,"overallMaxDiffSFTMod, testNumber = %i, SFT %i, bin %i = %g \n",testNumber,iOverallMaxDiffSFTMod,jOverallMaxDiff,overallMaxDiffSFTMod);
         fflush(stdout);
       #endif

       /* 09/07/05 gam; Initialize fastOutputSFTs since only 2*Dterms bins are changed by LALFastGeneratePulsarSFTs */
       for (i = 0; i < numSFTs; i++) {
          for(j=0;j<nBinsSFT;j++) {
             fastOutputSFTs->data[i].data->data[j] = 0.0;
          }
       }

       XLALDestroySFTVector( outputSFTs);

       LALFree(signalvec->data->data);
       LALFree(signalvec->data);
       LALFree(signalvec);

     } /* END for(iFreq=0;iFreq<nBinsSGNL;iFreq++) */
     /* ***************************************************/
     /*                                                  */
     /* END SECTION: LOOP OVER FREQUENCIES               */
     /*                                                  */
     /* ***************************************************/
   } /* END for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) */
  /* ********************************************************/
  /*                                                       */
  /* END SECTION: LOOP OVER SPINDOWN                       */
  /*                                                       */
  /* ********************************************************/

  } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */
  /* ********************************************************/
  /*                                                       */
  /* END SECTION: LOOP OVER SKY POSITIONS                  */
  /*                                                       */
  /* ********************************************************/

  /* 10/12/04 gam; check if too many bin errors */
  epsBinErrorRate = 0.20;  /* 10/12/04 gam; maximum allowed bin errors */
  if ( (((REAL4)binErrorCount)/((REAL4)testNumber)) > epsBinErrorRate ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EBINS, GENERATEPULSARSIGNALTESTC_MSGEBINS);
  }

  #ifdef INCLUDE_RANDVAL_MISMATCH
    LALDestroyRandomParams(status->statusPtr, &randPar);
    CHECKSTATUSPTR (status);
  #endif

  /* fprintf(stdout,"Total number of tests completed = %i. \n", testNumber);
  fflush(stdout); */

  LALFree(pSFTParams);
  if (numSpinDown > 0) {
    LALDDestroyVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown));
    CHECKSTATUSPTR (status);
  }
  LALFree(pPulsarSignalParams);

  /* deallocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */
  XLALDestroySFTVector( fastOutputSFTs);
  LALFree(pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi);
  LALFree(pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi);
  LALFree(pSkyConstAndZeroPsiAMResponse->skyConst);
  LALFree(pSkyConstAndZeroPsiAMResponse);
  /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */
  if (pSFTandSignalParams->resTrig > 0) {
    LALFree(pSFTandSignalParams->trigArg);
    LALFree(pSFTandSignalParams->sinVal);
    LALFree(pSFTandSignalParams->cosVal);
  }
  LALFree(pSFTandSignalParams);

  /* deallocate skyPosData */
  for(i=0;i<numSkyPosTotal;i++)
  {
      LALFree(skyPosData[i]);
  }
  LALFree(skyPosData);

  if (numSpinDown > 0) {
    /* deallocate freqDerivData */
    for(i=0;i<numFreqDerivTotal;i++)
    {
        LALFree(freqDerivData[i]);
    }
    LALFree(freqDerivData);
  }

  LALFree(timeStamps->data);
  LALFree(timeStamps);

  XLALDestroyEphemerisData(edat);

  CHECKSTATUSPTR (status);
  DETATCHSTATUSPTR (status);
}
Beispiel #9
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() */
Beispiel #10
0
// ---------- 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()
Beispiel #11
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() */
/**
 * Unit test for metric functions XLALComputeDopplerPhaseMetric()
 * and XLALComputeDopplerFstatMetric()
 *
 * Initially modelled afer testMetricCodes.py script:
 * Check metric codes 'getMetric' 'FstatMetric' and 'FstatMetric_v2' by
 * comparing them against each other.
 * Given that they represent 3 very different implementations of
 * metric calculations, this provides a very powerful consistency test
 *
 */
static int
test_XLALComputeDopplerMetrics ( void )
{
  int ret;
  const REAL8 tolPh = 0.01;	// 1% tolerance on phase metrics [taken from testMetricCodes.py]

  // ----- load ephemeris
  const char earthEphem[] = TEST_DATA_DIR "earth00-19-DE200.dat.gz";
  const char sunEphem[]   = TEST_DATA_DIR "sun00-19-DE200.dat.gz";
  EphemerisData *edat = XLALInitBarycenter ( earthEphem, sunEphem );
  XLAL_CHECK ( edat != NULL, XLAL_EFUNC, "XLALInitBarycenter('%s','%s') failed with xlalErrno = %d\n", earthEphem, sunEphem, xlalErrno );

  // ----- set test-parameters ----------
  const LIGOTimeGPS startTimeGPS = { 792576013, 0 };
  const REAL8 Tseg = 60000;

  const REAL8 Alpha = 1.0;
  const REAL8 Delta = 0.5;
  const REAL8 Freq  = 100;
  const REAL8 f1dot = 0;// -1e-8;

  LALStringVector *detNames = XLALCreateStringVector ( "H1", "L1", "V1",  NULL );
  LALStringVector *sqrtSX   = XLALCreateStringVector ( "1.0", "0.5", "1.5", NULL );

  MultiLALDetector multiIFO;
  XLAL_CHECK ( XLALParseMultiLALDetector ( &multiIFO, detNames ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALDestroyStringVector ( detNames );

  MultiNoiseFloor multiNoiseFloor;
  XLAL_CHECK ( XLALParseMultiNoiseFloor ( &multiNoiseFloor, sqrtSX, multiIFO.length ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALDestroyStringVector ( sqrtSX );

  // prepare metric parameters for modern XLALComputeDopplerFstatMetric() and mid-old XLALOldDopplerFstatMetric()
  const DopplerCoordinateSystem coordSys = { 4, { DOPPLERCOORD_FREQ, DOPPLERCOORD_ALPHA, DOPPLERCOORD_DELTA, DOPPLERCOORD_F1DOT } };
  const PulsarAmplitudeParams Amp = { 0.03, -0.3, 0.5, 0.0 };	// h0, cosi, psi, phi0
  const PulsarDopplerParams dop = {
    .refTime  = startTimeGPS,
    .Alpha    = Alpha,
    .Delta    = Delta,
    .fkdot    = { Freq, f1dot },
  };

  LALSegList XLAL_INIT_DECL(segList);
  ret = XLALSegListInitSimpleSegments ( &segList, startTimeGPS, 1, Tseg );
  XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno );

  const DopplerMetricParams master_pars2 = {
    .coordSys			= coordSys,
    .detMotionType		= DETMOTION_SPIN | DETMOTION_ORBIT,
    .segmentList		= segList,
    .multiIFO			= multiIFO,
    .multiNoiseFloor		= multiNoiseFloor,
    .signalParams		= { .Amp = Amp, .Doppler = dop },
    .projectCoord		= - 1,	// -1==no projection
    .approxPhase		= 0,
  };


  // ========== BEGINNING OF TEST CALLS ==========


  XLALPrintWarning("\n---------- ROUND 1: ephemeris-based, single-IFO phase metrics ----------\n");
  {
    OldDopplerMetric *metric1;
    DopplerPhaseMetric *metric2P;
    REAL8 diff_2_1;

    DopplerMetricParams pars2 = master_pars2;

    pars2.multiIFO.length = 1;	// truncate to first detector
    pars2.multiNoiseFloor.length = 1;	// truncate to first detector

    // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric()
    XLAL_CHECK ( (metric1 = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_PHASE, &pars2, edat )) != NULL, XLAL_EFUNC );
    // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2)
    XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC );

    // compare metrics against each other:
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2P->g_ij, metric1->g_ij )) < tolPh, XLAL_ETOL, "Error(g2,g1)= %g exceeds tolerance of %g\n", diff_2_1, tolPh );
    XLALPrintWarning ("diff_2_1 = %e\n", diff_2_1 );

    XLALDestroyOldDopplerMetric ( metric1 );
    XLALDestroyDopplerPhaseMetric ( metric2P );
  }


  XLALPrintWarning("\n---------- ROUND 2: Ptolemaic-based, single-IFO phase metrics ----------\n");
  {
    OldDopplerMetric *metric1;
    DopplerPhaseMetric *metric2P;
    REAL8 diff_2_1;

    DopplerMetricParams pars2 = master_pars2;

    pars2.multiIFO.length = 1;	// truncate to first detector
    pars2.multiNoiseFloor.length = 1;	// truncate to first detector

    pars2.detMotionType = DETMOTION_SPIN | DETMOTION_PTOLEORBIT;

    // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric()
    XLAL_CHECK ( (metric1 = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_PHASE, &pars2, edat )) != NULL, XLAL_EFUNC );
    // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2)
    XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC );

    // compare all 3 metrics against each other:
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2P->g_ij, metric1->g_ij )) < tolPh, XLAL_ETOL, "Error(g2,g1)= %g exceeds tolerance of %g\n", diff_2_1, tolPh );
    XLALPrintWarning ("diff_2_1 = %e\n", diff_2_1 );

    XLALDestroyOldDopplerMetric ( metric1 );
    XLALDestroyDopplerPhaseMetric ( metric2P );
  }


  XLALPrintWarning("\n---------- ROUND 3: ephemeris-based, multi-IFO F-stat metrics ----------\n");
  {
    OldDopplerMetric *metric1;
    DopplerFstatMetric *metric2F;
    REAL8 diff_2_1;

    DopplerMetricParams pars2 = master_pars2;

    pars2.detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT;
    pars2.multiIFO      = multiIFO;	// 3 IFOs
    pars2.multiNoiseFloor = multiNoiseFloor;// 3 IFOs

    // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric()
    XLAL_CHECK ( (metric1 = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_FSTAT, &pars2, edat )) != NULL, XLAL_EFUNC );
    // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2)
    XLAL_CHECK ( (metric2F = XLALComputeDopplerFstatMetric ( &pars2, edat )) != NULL, XLAL_EFUNC );

    // compare both metrics against each other:
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2F->gF_ij,   metric1->gF_ij ))   < tolPh, XLAL_ETOL, "Error(gF2,gF1)= %e exceeds tolerance of %e\n", diff_2_1, tolPh );
    XLALPrintWarning ("gF:   diff_2_1 = %e\n", diff_2_1 );
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2F->gFav_ij, metric1->gFav_ij )) < tolPh, XLAL_ETOL, "Error(gFav2,gFav1)= %e exceeds tolerance of %e\n", diff_2_1, tolPh );
    XLALPrintWarning ("gFav: diff_2_1 = %e\n", diff_2_1 );

    XLALDestroyOldDopplerMetric ( metric1 );
    XLALDestroyDopplerFstatMetric ( metric2F );
  }


  XLALPrintWarning("\n---------- ROUND 4: compare analytic {f,f1dot,f2dot,f3dot} phase metric vs XLALComputeDopplerPhaseMetric() ----------\n");
  {
    DopplerPhaseMetric *metric2P;
    REAL8 diff_2_1;

    DopplerMetricParams pars2 = master_pars2;

    pars2.multiIFO.length  = 1;	// truncate to 1st detector
    pars2.multiNoiseFloor.length  = 1;	// truncate to 1st detector
    pars2.detMotionType   = DETMOTION_SPIN | DETMOTION_ORBIT;
    pars2.approxPhase     = 1;	// use same phase-approximation as in analytic solution to improve comparison

    DopplerCoordinateSystem coordSys2 = { 4, { DOPPLERCOORD_FREQ, DOPPLERCOORD_F1DOT, DOPPLERCOORD_F2DOT, DOPPLERCOORD_F3DOT } };
    pars2.coordSys = coordSys2;
    gsl_matrix* gN_ij;

    // a) compute metric at refTime = startTime
    pars2.signalParams.Doppler.refTime = startTimeGPS;
    XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC );
    gN_ij = NULL;
    XLAL_CHECK ( XLALNaturalizeMetric ( &gN_ij, NULL, metric2P->g_ij, &pars2 ) == XLAL_SUCCESS, XLAL_EFUNC );

    REAL8 gStart_ij[] = {   1.0/3,      2.0/3,    6.0/5,    32.0/15,      \
                            2.0/3,    64.0/45,    8.0/3,  512.0/105,      \
                            6.0/5,      8.0/3,   36.0/7,     48.0/5,      \
                            32.0/15,  512.0/105, 48.0/5, 4096.0/225 };
    const gsl_matrix_view gStart = gsl_matrix_view_array ( gStart_ij, 4, 4 );

    // compare natural-units metric against analytic solution
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( gN_ij,   &(gStart.matrix) )) < tolPh, XLAL_ETOL,
                 "RefTime=StartTime: Error(g_ij,g_analytic)= %e exceeds tolerance of %e\n", diff_2_1, tolPh );
    XLALPrintWarning ("Analytic (refTime=startTime): diff_2_1 = %e\n", diff_2_1 );

    XLALDestroyDopplerPhaseMetric ( metric2P );
    gsl_matrix_free ( gN_ij );

    // b) compute metric at refTime = midTime
    pars2.signalParams.Doppler.refTime = startTimeGPS;
    pars2.signalParams.Doppler.refTime.gpsSeconds += Tseg / 2;

    XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC );
    gN_ij = NULL;
    XLAL_CHECK ( XLALNaturalizeMetric ( &gN_ij, NULL, metric2P->g_ij, &pars2 ) == XLAL_SUCCESS, XLAL_EFUNC );

    REAL8 gMid_ij[] = { 1.0/3,    0,        1.0/5,         0,       \
                        0,        4.0/45,       0,   8.0/105,       \
                        1.0/5,    0,        1.0/7,         0,       \
                        0,        8.0/105,      0,  16.0/225  };
    const gsl_matrix_view gMid = gsl_matrix_view_array ( gMid_ij, 4, 4 );

    // compare natural-units metric against analytic solution
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( gN_ij,   &(gMid.matrix) )) < tolPh, XLAL_ETOL,
                 "RefTime=MidTime: Error(g_ij,g_analytic)= %e exceeds tolerance of %e\n", diff_2_1, tolPh );
    XLALPrintWarning ("Analytic (refTime=midTime):   diff_2_1 = %e\n\n", diff_2_1 );

    XLALDestroyDopplerPhaseMetric ( metric2P );
    gsl_matrix_free ( gN_ij );
  }


  XLALPrintWarning("\n---------- ROUND 5: ephemeris-based, single-IFO, segment-averaged phase metrics ----------\n");
  {
    OldDopplerMetric *metric1;
    DopplerPhaseMetric *metric2P;
    REAL8 diff_2_1;

    DopplerMetricParams pars2 = master_pars2;

    pars2.detMotionType = DETMOTION_SPIN | DETMOTION_ORBIT;
    pars2.multiIFO.length = 1;	// truncate to first detector
    pars2.multiNoiseFloor.length = 1;	// truncate to first detector
    pars2.approxPhase = 1;

    const UINT4 Nseg = 10;
    LALSegList XLAL_INIT_DECL(NsegList);
    ret = XLALSegListInitSimpleSegments ( &NsegList, startTimeGPS, Nseg, Tseg );
    XLAL_CHECK ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALSegListInitSimpleSegments() failed with xlalErrno = %d\n", xlalErrno );
    pars2.segmentList = NsegList;

    LALSegList XLAL_INIT_DECL(segList_k);
    LALSeg segment_k;
    XLALSegListInit( &segList_k );	// prepare single-segment list containing segment k
    segList_k.arraySize = 1;
    segList_k.length = 1;
    segList_k.segs = &segment_k;

    // 1) compute metric using old FstatMetric code, now wrapped into XLALOldDopplerFstatMetric()
    metric1 = NULL;
    for (UINT4 k = 0; k < Nseg; ++k) {
      // setup 1-segment segment-list pointing k-th segment
      DopplerMetricParams pars2_k = pars2;
      pars2_k.segmentList = segList_k;
      pars2_k.segmentList.segs[0] = pars2.segmentList.segs[k];
      // XLALOldDopplerFstatMetric() does not agree numerically with UniversalDopplerMetric when using refTime != startTime
      pars2_k.signalParams.Doppler.refTime = pars2_k.segmentList.segs[0].start;

      OldDopplerMetric *metric1_k;   // per-segment coherent metric
      XLAL_CHECK ( (metric1_k = XLALOldDopplerFstatMetric ( OLDMETRIC_TYPE_PHASE, &pars2_k, edat )) != NULL, XLAL_EFUNC );

      // manually correct reference time of metric1_k->g_ij; see Prix, "Frequency metric for CW searches" (2014-08-17), p. 4
      const double dt = XLALGPSDiff( &(pars2_k.signalParams.Doppler.refTime), &(pars2.signalParams.Doppler.refTime) );
      const double gFF = gsl_matrix_get( metric1_k->g_ij, 0, 0 );
      const double gFA = gsl_matrix_get( metric1_k->g_ij, 0, 1 );
      const double gFD = gsl_matrix_get( metric1_k->g_ij, 0, 2 );
      const double gFf = gsl_matrix_get( metric1_k->g_ij, 0, 3 );
      const double gAf = gsl_matrix_get( metric1_k->g_ij, 1, 3 );
      const double gDf = gsl_matrix_get( metric1_k->g_ij, 2, 3 );
      const double gff = gsl_matrix_get( metric1_k->g_ij, 3, 3 );
      gsl_matrix_set( metric1_k->g_ij, 0, 3, gFf + gFF*dt ); gsl_matrix_set( metric1_k->g_ij, 3, 0, gsl_matrix_get( metric1_k->g_ij, 0, 3 ) );
      gsl_matrix_set( metric1_k->g_ij, 1, 3, gAf + gFA*dt ); gsl_matrix_set( metric1_k->g_ij, 3, 1, gsl_matrix_get( metric1_k->g_ij, 1, 3 ) );
      gsl_matrix_set( metric1_k->g_ij, 2, 3, gDf + gFD*dt ); gsl_matrix_set( metric1_k->g_ij, 3, 2, gsl_matrix_get( metric1_k->g_ij, 2, 3 ) );
      gsl_matrix_set( metric1_k->g_ij, 3, 3, gff + 2*gFf*dt + gFF*dt*dt );

      XLAL_CHECK ( XLALAddOldDopplerMetric ( &metric1, metric1_k ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLALDestroyOldDopplerMetric ( metric1_k );
    }
    XLAL_CHECK ( XLALScaleOldDopplerMetric ( metric1, 1.0 / Nseg ) == XLAL_SUCCESS, XLAL_EFUNC );

    // 2) compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2)
    XLAL_CHECK ( (metric2P = XLALComputeDopplerPhaseMetric ( &pars2, edat )) != NULL, XLAL_EFUNC );

    GPMAT( metric1->g_ij, "%0.4e" );
    GPMAT( metric2P->g_ij, "%0.4e" );

    // compare both metrics against each other:
    XLAL_CHECK ( (diff_2_1 = XLALCompareMetrics ( metric2P->g_ij, metric1->g_ij )) < tolPh, XLAL_ETOL, "Error(g2,g1)= %g exceeds tolerance of %g\n", diff_2_1, tolPh );
    XLALPrintWarning ("diff_2_1 = %e\n", diff_2_1 );

    XLALDestroyOldDopplerMetric ( metric1 );
    XLALDestroyDopplerPhaseMetric ( metric2P );

    XLALSegListClear ( &NsegList );
  }


  XLALPrintWarning("\n---------- ROUND 6: directed binary orbital metric ----------\n");
  {
    REAL8 Period = 68023.70496;
    REAL8 Omega = LAL_TWOPI / Period;
    REAL8 asini = 1.44;
    REAL8 tAsc = 897753994;
    REAL8 argp = 0;
    LIGOTimeGPS tP; XLALGPSSetREAL8 ( &tP, tAsc + argp / Omega );

    const PulsarDopplerParams dopScoX1 = {
      .refTime  = startTimeGPS,
      .Alpha    = Alpha,
      .Delta    = Delta,
      .fkdot    = { Freq },
      .asini    = asini,
      .period   = Period,
      .tp       = tP
    };
    REAL8 TspanScoX1 = 20 * 19 * 3600;	// 20xPorb for long-segment regime
    LALSegList XLAL_INIT_DECL(segListScoX1);
    XLAL_CHECK ( XLALSegListInitSimpleSegments ( &segListScoX1, startTimeGPS, 1, TspanScoX1 ) == XLAL_SUCCESS, XLAL_EFUNC );
    REAL8 tMid = XLALGPSGetREAL8(&startTimeGPS) + 0.5 * TspanScoX1;
    REAL8 DeltaMidAsc = tMid - tAsc;
    const DopplerCoordinateSystem coordSysScoX1 = { 6, { DOPPLERCOORD_FREQ, DOPPLERCOORD_ASINI, DOPPLERCOORD_TASC, DOPPLERCOORD_PORB, DOPPLERCOORD_KAPPA, DOPPLERCOORD_ETA } };
    DopplerMetricParams pars_ScoX1 = {
      .coordSys			= coordSysScoX1,
      .detMotionType		= DETMOTION_SPIN | DETMOTION_ORBIT,
      .segmentList		= segListScoX1,
      .multiIFO			= multiIFO,
      .multiNoiseFloor		= multiNoiseFloor,
      .signalParams		= { .Amp = Amp, .Doppler = dopScoX1 },
      .projectCoord		= - 1,	// -1==no projection
      .approxPhase		= 1,
    };
    pars_ScoX1.multiIFO.length = 1;	// truncate to first detector
    pars_ScoX1.multiNoiseFloor.length = 1;	// truncate to first detector

    // compute metric using modern UniversalDopplerMetric module: (used in lalapps_FstatMetric_v2)
    DopplerPhaseMetric *metric_ScoX1;
    XLAL_CHECK ( (metric_ScoX1 = XLALComputeDopplerPhaseMetric ( &pars_ScoX1, edat )) != NULL, XLAL_EFUNC );

    // compute analytic metric computed from Eq.(47) in Leaci,Prix PRD91, 102003 (2015):
    gsl_matrix *g0_ij;
    XLAL_CHECK ( (g0_ij = gsl_matrix_calloc ( 6, 6 )) != NULL, XLAL_ENOMEM, "Failed to gsl_calloc a 6x6 matrix\n");
    gsl_matrix_set ( g0_ij, 0, 0, pow ( LAL_PI * TspanScoX1, 2 ) / 3.0 );
    gsl_matrix_set ( g0_ij, 1, 1, 2.0 * pow ( LAL_PI * Freq, 2 ) );
    gsl_matrix_set ( g0_ij, 2, 2, 2.0 * pow ( LAL_PI * Freq * asini * Omega, 2 ) );
    gsl_matrix_set ( g0_ij, 3, 3, 0.5 * pow ( Omega, 4 ) * pow ( Freq * asini, 2 ) * ( pow ( TspanScoX1, 2 ) / 12.0 + pow ( DeltaMidAsc, 2 ) ) );
    REAL8 gPAsc = LAL_PI * pow ( Freq * asini, 2 ) * pow ( Omega, 3 ) * DeltaMidAsc;
    gsl_matrix_set ( g0_ij, 2, 3, gPAsc );
    gsl_matrix_set ( g0_ij, 3, 2, gPAsc );
    gsl_matrix_set ( g0_ij, 4, 4, 0.5 * pow ( LAL_PI * Freq * asini, 2 ) );
    gsl_matrix_set ( g0_ij, 5, 5, 0.5 * pow ( LAL_PI * Freq * asini, 2 ) );

    GPMAT ( metric_ScoX1->g_ij, "%0.4e" );
    GPMAT ( g0_ij, "%0.4e" );

    // compare metrics against each other
    REAL8 diff, tolScoX1 = 0.05;
    XLAL_CHECK ( (diff = XLALCompareMetrics ( metric_ScoX1->g_ij, g0_ij )) < tolScoX1, XLAL_ETOL, "Error(gNum,gAn)= %g exceeds tolerance of %g\n", diff, tolScoX1 );
    XLALPrintWarning ("diff_Num_An = %e\n", diff );

    gsl_matrix_free ( g0_ij );
    XLALDestroyDopplerPhaseMetric ( metric_ScoX1 );
    XLALSegListClear ( &segListScoX1 );
  }
Beispiel #13
0
//Main program
int main(int argc, char *argv[])
{
   
   FILE *OUTPUT;
   LALDetector det;
   LALStatus XLAL_INIT_DECL(status);

   UserVariables_t XLAL_INIT_DECL(uvar);
   XLAL_CHECK ( InitUserVars(&uvar, argc, argv) == XLAL_SUCCESS, XLAL_EFUNC );

   XLAL_CHECK( (OUTPUT = fopen(uvar.outfilename,"w")) != NULL, XLAL_EIO, "Output file %s could not be opened\n", uvar.outfilename );
   
   //Interferometer
   if (strcmp("L1", uvar.IFO)==0) {
      fprintf(stderr,"IFO = %s\n", uvar.IFO);
      det = lalCachedDetectors[LAL_LLO_4K_DETECTOR]; //L1
   } else if (strcmp("H1", uvar.IFO)==0) {
      fprintf(stderr,"IFO = %s\n", uvar.IFO);
      det = lalCachedDetectors[LAL_LHO_4K_DETECTOR]; //H1
   } else if (strcmp("V1", uvar.IFO)==0) {
      fprintf(stderr,"IFO = %s\n", uvar.IFO);
      det = lalCachedDetectors[LAL_VIRGO_DETECTOR]; //V1
   } else {
      XLAL_ERROR( XLAL_EINVAL, "Not using valid interferometer! Expected 'H1', 'L1', or 'V1' not %s.\n", uvar.IFO);
   }
   
   //Parameters for the sky-grid
   fprintf(stderr, "Sky region = %s\n", uvar.skyRegion);
   DopplerSkyScanInit XLAL_INIT_DECL(scanInit);
   DopplerSkyScanState XLAL_INIT_DECL(scan);
   PulsarDopplerParams dopplerpos;
   scanInit.gridType = GRID_ISOTROPIC;     //Default value for an approximate-isotropic grid
   scanInit.skyRegionString = uvar.skyRegion;      //"allsky" = Default value for all-sky search
   scanInit.numSkyPartitions = 1;   //Default value so sky is not broken into chunks
   scanInit.Freq = uvar.fmin+0.5*uvar.fspan;  //Mid-point of the frequency band
   
   //Initialize ephemeris data structure
   EphemerisData *edat = NULL;
   XLAL_CHECK( (edat = XLALInitBarycenter(uvar.ephemEarth, uvar.ephemSun)) != NULL, XLAL_EFUNC );
   
   //v1: Maximum orbital earth speed in units of c from start of S6 TwoSpect data for 104 weeks total time
   //else: maximum detector velocity around the time of observation
   REAL4 detectorVmax = 0.0;
   if (uvar.v1) detectorVmax = CompDetectorVmax(931081500.0+uvar.SFToverlap, uvar.Tsft, uvar.SFToverlap, 62899200.0-uvar.SFToverlap, det, edat);
   else detectorVmax = CompDetectorVmax(uvar.t0-uvar.Tsft, uvar.Tsft, uvar.SFToverlap, uvar.Tobs+2.0*uvar.Tsft, det, edat);
   XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC, "CompDetectorVmax() failed\n" );
   
   //Initialize the sky-grid
   scanInit.dAlpha = 0.5/((uvar.fmin+0.5*uvar.fspan) * uvar.Tsft * detectorVmax);
   scanInit.dDelta = scanInit.dAlpha;
   InitDopplerSkyScan(&status, &scan, &scanInit);
   XLAL_CHECK( status.statusCode == 0, XLAL_EFUNC );
   
   //Start at first location
   XLAL_CHECK( XLALNextDopplerSkyPos(&dopplerpos, &scan) == XLAL_SUCCESS, XLAL_EFUNC );
   
   //loop through and output to the specified file
   while (scan.state != STATE_FINISHED) {
      fprintf(OUTPUT, "%.6f %.6f\n", dopplerpos.Alpha, dopplerpos.Delta);
      
      //Iterate to next sky location
      XLAL_CHECK( XLALNextDopplerSkyPos(&dopplerpos, &scan) == XLAL_SUCCESS, XLAL_EFUNC );
   }

   //Destroy
   XLALDestroyUserVars();
   XLALDestroyEphemerisData(edat);
   fclose(OUTPUT);
   
   return 0;
   
}
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();
}
Beispiel #15
0
/**
 * Handle user-input and check its validity.
 * Load ephemeris and calculate AM-coefficients (stored globally)
 */
void
Initialize (LALStatus *status, struct CommandLineArgsTag *CLA)
{
  EphemerisData *edat=NULL;          /* Stores earth/sun ephemeris data for barycentering */
  BarycenterInput baryinput;         /* Stores detector location and other barycentering data */
  EarthState earth;
  AMCoeffsParams *amParams;
  LIGOTimeGPS *midTS=NULL;           /* Time stamps for amplitude modulation coefficients */
  LALDetector *Detector;              /* Our detector*/
  INT4 k;

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  if ( XLALUserVarWasSet ( &(CLA->nTsft) ) )
    CLA->duration = 1.0 * CLA->nTsft * CLA->Tsft;

  /* read or generate SFT timestamps */
  if ( XLALUserVarWasSet(&(CLA->timestamps)) ) 
    { 
      XLAL_CHECK_LAL ( status, ( timestamps = XLALReadTimestampsFile ( CLA->timestamps ) ) != NULL, XLAL_EFUNC );
      if ( (CLA->nTsft > 0) && ( (UINT4)CLA->nTsft < timestamps->length ) )	/* truncate if required */
	timestamps->length = CLA->nTsft;
      
      CLA->nTsft = timestamps->length;
    } /* if have_timestamps */
  else 
    {
      LIGOTimeGPS tStart;
      tStart.gpsSeconds = CLA->gpsStart;
      tStart.gpsNanoSeconds = 0;

      XLAL_CHECK_LAL ( status, ( timestamps = XLALMakeTimestamps( tStart, CLA->duration, CLA->Tsft, 0 ) ) != NULL, XLAL_EFUNC );
      CLA->nTsft = timestamps->length;

    } /* no timestamps */

  /*---------- initialize detector ---------- */
  {
    BOOLEAN have_IFO       = XLALUserVarWasSet ( &CLA->IFO );
    BOOLEAN have_detector  = XLALUserVarWasSet ( &CLA->detector );
    CHAR *IFO;

    if ( !have_IFO  && !have_detector ) {
      fprintf (stderr, "\nNeed to specify the detector (--IFO) !\n\n");
      ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT);
    }
    if ( have_IFO )
      IFO = CLA->IFO;
    else
      IFO = CLA->detector;

    if ( ( Detector = XLALGetSiteInfo ( IFO ) ) == NULL ) {
      ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT);
    }
  }

  /* ---------- load ephemeris-files ---------- */
  {
    edat = XLALInitBarycenter( CLA->ephemEarth, CLA->ephemSun );
    if ( !edat ) {
      XLALPrintError("XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", CLA->ephemEarth, CLA->ephemSun);
      ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT);
    }
  } /* ephemeris-reading */


  /* ---------- calculate AM-coefficients ---------- */

  /* prepare call to barycentering routing */
  baryinput.site.location[0] = Detector->location[0]/LAL_C_SI;
  baryinput.site.location[1] = Detector->location[1]/LAL_C_SI;
  baryinput.site.location[2] = Detector->location[2]/LAL_C_SI;
  baryinput.alpha = CLA->Alpha;
  baryinput.delta = CLA->Delta;
  baryinput.dInv = 0.e0;

  /* amParams structure to compute a(t) and b(t) */

  /* Allocate space for amParams stucture */
  /* Here, amParams->das is the Detector and Source info */
  amParams = (AMCoeffsParams *)LALMalloc(sizeof(AMCoeffsParams));
  amParams->das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource));
  amParams->das->pSource = (LALSource *)LALMalloc(sizeof(LALSource));
  /* Fill up AMCoeffsParams structure */
  amParams->baryinput = &baryinput;
  amParams->earth = &earth; 
  amParams->edat = edat;
  amParams->das->pDetector = Detector; 
  amParams->das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
  amParams->das->pSource->equatorialCoords.longitude = CLA->Alpha;
  amParams->das->pSource->equatorialCoords.latitude = CLA->Delta;
  amParams->das->pSource->orientation = 0.0;

  amParams->polAngle = amParams->das->pSource->orientation ; /* These two have to be the same!!!!!!!!!*/
  
  /* Allocate space for AMCoeffs */
  XLAL_INIT_MEM(amc);
  TRY ( LALSCreateVector(status->statusPtr, &(amc.a), (UINT4)  CLA->nTsft), status);
  TRY ( LALSCreateVector(status->statusPtr, &(amc.b), (UINT4)  CLA->nTsft), status);
  
  /* Mid point of each SFT */
  midTS = (LIGOTimeGPS *)LALCalloc(CLA->nTsft,sizeof(LIGOTimeGPS));
  for(k=0; k < CLA->nTsft; k++)
    {
      /* FIXME:  loss of precision; consider
      midTS[k] = timestamps->data[k];
      XLALGPSAdd(&midTS[k], 0.5*CLA->Tsft);
      */
      REAL8 teemp=0.0;
      teemp = XLALGPSGetREAL8(&(timestamps->data[k]));
      teemp += 0.5*CLA->Tsft;
      XLALGPSSetREAL8(&(midTS[k]), teemp);
    }
  
  TRY ( LALComputeAM(status->statusPtr, &amc, midTS, amParams), status);

  /* Free memory */
  XLALDestroyTimestampVector ( timestamps);

  LALFree(midTS);
  LALFree(Detector);
  XLALDestroyEphemerisData(edat);

  LALFree(amParams->das->pSource);
  LALFree(amParams->das);
  LALFree(amParams);


  DETATCHSTATUSPTR (status);
  RETURN(status);

} /* ParseUserInput() */
/**
 * Unit test function for XLALComputeOrbitalDerivatives()
 */
static int
test_XLALComputeOrbitalDerivatives ( void )
{
  // ----- load an example ephemeris, describing a pure cicular 2D
  // orbit w period of one year
  CHAR earthEphem[] = TEST_DATA_DIR "circularEphem.dat";
  CHAR sunEphem[]   = TEST_DATA_DIR "sun00-19-DE405.dat";

  EphemerisData *edat = XLALInitBarycenter ( earthEphem, sunEphem );
  XLAL_CHECK ( edat != NULL, XLAL_EFUNC, "XLALInitBarycenter('%s','%s') failed with xlalErrno = %d\n", earthEphem, sunEphem, xlalErrno );

  /* Unit test for XLALComputeOrbitalDerivatives() */
  // ----------------------------------------
  // the tests consists in using a purely 2D circular orbit to
  // compute the derivatives, so we can analytically check them!

  // one line from the middle of cicularEphem.dat:
  // 700244800    498.41220200278  24.31154155846971  0    -4.84039532365306e-06  9.923320107134072e-05  0    -1.975719726623028e-11 -9.63716218195963e-13 0

  // we can use this to check derivatives '0-'2'
  vect3Dlist_t *rOrb_n = NULL;
  LIGOTimeGPS t0 = { 700244800, 0 };
  vect3D_t r_0 = {498.41220200278, 24.31154155846971,  0 };
  vect3D_t r_1 = {-4.84039532365306e-06,   9.923320107134072e-05,  0 };
  vect3D_t r_2 = { -1.975719726623028e-11, -9.63716218195963e-13,  0 };
  UINT4 maxorder = 4;

  rOrb_n = XLALComputeOrbitalDerivatives ( maxorder, &t0, edat );
  XLAL_CHECK ( rOrb_n != NULL, XLAL_EFUNC, "XLALComputeOrbitalDerivatives() failed with xlalErrno = %d!.\n", xlalErrno );

  // ----- first check differences to known first derivatives 0 - 2:
  vect3D_t diff;
  REAL8 reldiff;
  REAL8 reltol = 1e-6;
  UINT4 i;

  /* order = 0 */
  for (i=0; i<3; i++) diff[i] = r_0[i] - rOrb_n->data[0][i];
  reldiff = sqrt ( NORM(diff) / NORM(r_0) );
  XLAL_CHECK ( reldiff <= reltol, XLAL_ETOL, "Relative error %g on 0th order r_0 exceeds tolerance of %g.\n", reldiff, reltol );

  /* order = 1 */
  for (i=0; i<3; i++) diff[i] = r_1[i] - rOrb_n->data[1][i];
  reldiff = sqrt ( NORM(diff) / NORM(r_0) );
  XLAL_CHECK ( reldiff <= reltol, XLAL_ETOL, "Relative error %g on 1st order r_1 exceeds tolerance of %g.\n", reldiff, reltol );

  /* order = 1 */
  for (i=0; i<3; i++) diff[i] = r_2[i] - rOrb_n->data[2][i];
  reldiff = sqrt ( NORM(diff) / NORM(r_0) );
  XLAL_CHECK ( reldiff <= reltol, XLAL_ETOL, "Relative error %g on 2n order r_2 exceeds tolerance of %g.\n", reldiff, reltol );

  // ----- second check derivatives against known analytic results
  REAL8 RorbC = LAL_AU_SI / LAL_C_SI;
  REAL8 Om = LAL_TWOPI / LAL_YRSID_SI;
  vect3D_t nR, nV;
  REAL8 norm;
  vect3D_t rTest_n[maxorder+1];

  norm = NORM( r_0 );
  DIV_VECT (nR, r_0, norm );
  norm = NORM( r_1 );
  DIV_VECT (nV, r_1, norm );

  /* r_0 */
  COPY_VECT(rTest_n[0], nR );
  MULT_VECT(rTest_n[0], RorbC );
  /* r_1 */
  COPY_VECT(rTest_n[1], nV );
  MULT_VECT(rTest_n[1], RorbC*Om );
  /* r_2 */
  COPY_VECT(rTest_n[2], nR );
  MULT_VECT(rTest_n[2], -RorbC*Om*Om );
  /* r_3 */
  COPY_VECT(rTest_n[3], nV );
  MULT_VECT(rTest_n[3], -RorbC*Om*Om*Om );
  /* r_4 */
  COPY_VECT(rTest_n[4], nR );
  MULT_VECT(rTest_n[4], RorbC*Om*Om*Om*Om );


  UINT4 n;
  reltol = 1e-2;	/* 1% error should be enough to enforce order 0-2 are ~1e-5 - 1e-8, order 3-4 are ~ 5e-3*/
  XLALPrintInfo ("\nComparing Earth orbital derivatives:\n");
  for ( n=0; n <= maxorder; n ++ )
    {
      for (i=0; i<3; i++) {
        diff[i] = rTest_n[n][i] - rOrb_n->data[n][i];
      }
      reldiff = sqrt ( NORM(diff) / NORM(rTest_n[n]) );
      XLALPrintInfo ("order %d: relative difference = %g\n", n, reldiff );
      XLAL_CHECK ( reldiff <= reltol, XLAL_ETOL,
                   "Relative error %g on r_%d exceeds tolerance of %g.\n"
                   "rd[%d] = {%g, %g, %g},  rTest[%d] = {%g, %g, %g}\n",
                   reldiff, n, reltol,
                   n, rOrb_n->data[n][0], rOrb_n->data[n][1], rOrb_n->data[n][2],
                   n, rTest_n[n][0], rTest_n[n][1], rTest_n[n][2] );
    } /* for n <= maxorder */

  /* free memory */
  XLALDestroyVect3Dlist ( rOrb_n );
  XLALDestroyEphemerisData ( edat );

  return XLAL_SUCCESS;

} /* test_XLALComputeOrbitalDerivatives() */
Beispiel #17
0
static int SuperskyTest(
  const double T,
  const double max_mismatch,
  const char *lattice_name,
  const UINT8 patch_count,
  const double freq,
  const double freqband,
  const UINT8 total_ref,
  const double mism_hist_ref[MISM_HIST_BINS]
  )
{

  // Create lattice tiling
  LatticeTiling *tiling = XLALCreateLatticeTiling(3);
  XLAL_CHECK(tiling != NULL, XLAL_EFUNC);

  // Compute reduced supersky metric
  const double Tspan = T * 86400;
  LIGOTimeGPS ref_time;
  XLALGPSSetREAL8(&ref_time, 900100100);
  LALSegList segments;
  {
    XLAL_CHECK(XLALSegListInit(&segments) == XLAL_SUCCESS, XLAL_EFUNC);
    LALSeg segment;
    LIGOTimeGPS start_time = ref_time, end_time = ref_time;
    XLALGPSAdd(&start_time, -0.5 * Tspan);
    XLALGPSAdd(&end_time, 0.5 * Tspan);
    XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
    XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
  }
  MultiLALDetector detectors = {
    .length = 1,
    .sites = { lalCachedDetectors[LAL_LLO_4K_DETECTOR] }
  };
  EphemerisData *edat =  XLALInitBarycenter(TEST_DATA_DIR "earth00-19-DE405.dat.gz",
                                            TEST_DATA_DIR "sun00-19-DE405.dat.gz");
  XLAL_CHECK(edat != NULL, XLAL_EFUNC);
  SuperskyMetrics *metrics = XLALComputeSuperskyMetrics(0, &ref_time, &segments, freq, &detectors, NULL, DETMOTION_SPIN | DETMOTION_PTOLEORBIT, edat);
  XLAL_CHECK(metrics != NULL, XLAL_EFUNC);
  gsl_matrix *rssky_metric = metrics->semi_rssky_metric, *rssky_transf = metrics->semi_rssky_transf;
  metrics->semi_rssky_metric = metrics->semi_rssky_transf = NULL;
  XLALDestroySuperskyMetrics(metrics);
  XLALSegListClear(&segments);
  XLALDestroyEphemerisData(edat);

  // Add bounds
  printf("Bounds: supersky, sky patch 0/%" LAL_UINT8_FORMAT ", freq=%0.3g, freqband=%0.3g\n", patch_count, freq, freqband);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSkyPatch(tiling, rssky_metric, rssky_transf, patch_count, 0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(tiling, rssky_transf, 0, freq, freq + freqband) == XLAL_SUCCESS, XLAL_EFUNC);
  GFMAT(rssky_transf);

  // Set metric
  printf("Lattice type: %s\n", lattice_name);
  XLAL_CHECK(XLALSetTilingLatticeAndMetric(tiling, lattice_name, rssky_metric, max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch test
  XLAL_CHECK(MismatchTest(tiling, rssky_metric, max_mismatch, total_ref, mism_hist_ref) == XLAL_SUCCESS, XLAL_EFUNC);

  return XLAL_SUCCESS;

}

static int MultiSegSuperskyTest(void)
{
  printf("Performing multiple-segment tests ...\n");

  // Compute reduced supersky metrics
  const double Tspan = 86400;
  LIGOTimeGPS ref_time;
  XLALGPSSetREAL8(&ref_time, 900100100);
  LALSegList segments;
  {
    XLAL_CHECK(XLALSegListInit(&segments) == XLAL_SUCCESS, XLAL_EFUNC);
    LALSeg segment;
    {
      LIGOTimeGPS start_time = ref_time, end_time = ref_time;
      XLALGPSAdd(&start_time, -4 * Tspan);
      XLALGPSAdd(&end_time, -3 * Tspan);
      XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
      XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
    }
    {
      LIGOTimeGPS start_time = ref_time, end_time = ref_time;
      XLALGPSAdd(&start_time, -0.5 * Tspan);
      XLALGPSAdd(&end_time, 0.5 * Tspan);
      XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
      XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
    }
    {
      LIGOTimeGPS start_time = ref_time, end_time = ref_time;
      XLALGPSAdd(&start_time, 3.5 * Tspan);
      XLALGPSAdd(&end_time, 4.5 * Tspan);
      XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
      XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
    }
  }
  MultiLALDetector detectors = {
    .length = 1,
    .sites = { lalCachedDetectors[LAL_LLO_4K_DETECTOR] }
  };
  EphemerisData *edat =  XLALInitBarycenter(TEST_DATA_DIR "earth00-19-DE405.dat.gz",
                                            TEST_DATA_DIR "sun00-19-DE405.dat.gz");
  XLAL_CHECK(edat != NULL, XLAL_EFUNC);
  SuperskyMetrics *metrics = XLALComputeSuperskyMetrics(1, &ref_time, &segments, 50, &detectors, NULL, DETMOTION_SPIN | DETMOTION_PTOLEORBIT, edat);
  XLAL_CHECK(metrics != NULL, XLAL_EFUNC);

  // Project and rescale semicoherent metric to give equal frequency spacings
  const double coh_max_mismatch = 0.2, semi_max_mismatch = 0.4;
  XLAL_CHECK(XLALEqualizeReducedSuperskyMetricsFreqSpacing(metrics, coh_max_mismatch, semi_max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);

  // Create lattice tilings
  LatticeTiling *coh_tiling[metrics->num_segments];
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    coh_tiling[n] = XLALCreateLatticeTiling(4);
    XLAL_CHECK(coh_tiling[n] != NULL, XLAL_EFUNC);
  }
  LatticeTiling *semi_tiling = XLALCreateLatticeTiling(4);
  XLAL_CHECK(semi_tiling != NULL, XLAL_EFUNC);

  // Add bounds
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSkyPatch(coh_tiling[n], metrics->coh_rssky_metric[n], metrics->coh_rssky_transf[n], 1, 0) == XLAL_SUCCESS, XLAL_EFUNC);
    XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(coh_tiling[n], metrics->coh_rssky_transf[n], 0, 50, 50 + 1e-4) == XLAL_SUCCESS, XLAL_EFUNC);
    XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(coh_tiling[n], metrics->coh_rssky_transf[n], 1, 0, -5e-10) == XLAL_SUCCESS, XLAL_EFUNC);
  }
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSkyPatch(semi_tiling, metrics->semi_rssky_metric, metrics->semi_rssky_transf, 1, 0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(semi_tiling, metrics->semi_rssky_transf, 0, 50, 50 + 1e-4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(semi_tiling, metrics->semi_rssky_transf, 1, 0, -5e-10) == XLAL_SUCCESS, XLAL_EFUNC);

  // Set metric
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    XLAL_CHECK(XLALSetTilingLatticeAndMetric(coh_tiling[n], "Ans", metrics->coh_rssky_metric[n], coh_max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);
  }
  XLAL_CHECK(XLALSetTilingLatticeAndMetric(semi_tiling, "Ans", metrics->semi_rssky_metric, semi_max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);

  // Check lattice step sizes in frequency
  const size_t ifreq = 3;
  const double semi_dfreq = XLALLatticeTilingStepSizes(semi_tiling, ifreq);
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    const double coh_dfreq = XLALLatticeTilingStepSizes(coh_tiling[n], ifreq);
    const double tol = 1e-8;
    XLAL_CHECK(fabs(coh_dfreq - semi_dfreq) < tol * semi_dfreq, XLAL_EFAILED,
               "  ERROR: semi_dfreq=%0.15e, coh_dfreq[%zu]=%0.15e, |coh_dfreq - semi_dfreq| >= %g * semi_dfreq", semi_dfreq, n, coh_dfreq, tol);
  }

  // Check computation of spindown range for coherent tilings
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    PulsarSpinRange spin_range;
    XLAL_CHECK(XLALSuperskyLatticePulsarSpinRange(&spin_range, coh_tiling[n], metrics->coh_rssky_transf[n]) == XLAL_SUCCESS, XLAL_EFUNC);
  }

  // Cleanup
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    XLALDestroyLatticeTiling(coh_tiling[n]);
  }
  XLALDestroyLatticeTiling(semi_tiling);
  XLALDestroySuperskyMetrics(metrics);
  XLALSegListClear(&segments);
  XLALDestroyEphemerisData(edat);
  LALCheckMemoryLeaks();
  printf("\n");
  fflush(stdout);

  return XLAL_SUCCESS;

}

int main(void)
{

  // Perform basic tests
  XLAL_CHECK_MAIN(BasicTest(1, 0, 0, 0, 0, "Zn" ,    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(1, 1, 1, 1, 1, "Ans",   93,    0,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(1, 1, 1, 1, 1, "Zn" ,   93,    0,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(2, 0, 0, 0, 0, "Ans",    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(2, 1, 1, 1, 1, "Ans",   12,  144,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(2, 1, 1, 1, 1, "Zn" ,   13,  190,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(3, 0, 0, 0, 0, "Zn" ,    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(3, 1, 1, 1, 1, "Ans",    8,   46,  332,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(3, 1, 1, 1, 1, "Zn" ,    8,   60,  583,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 0, 0, "Ans",    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 0, 1, "Ans",    1,    1,    1,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 1, 0, "Ans",    1,    1,    4,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 1, 1, "Ans",    1,    1,    4,   20) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 0, 0, "Ans",    1,    4,    4,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 0, 1, "Ans",    1,    5,    5,   25) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 1, 0, "Ans",    1,    5,   24,   24) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 1, 1, "Ans",    1,    5,   20,  115) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 0, 0, "Ans",    4,    4,    4,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 0, 1, "Ans",    5,    5,    5,   23) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 1, 0, "Ans",    5,    5,   23,   23) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 1, 1, "Ans",    6,    6,   24,  139) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 0, 0, "Ans",    5,   25,   25,   25) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 0, 1, "Ans",    6,   30,   30,  162) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 1, 0, "Ans",    6,   27,  151,  151) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 1, 1, "Ans",    6,   30,  145,  897) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 1, 1, "Zn" ,    7,   46,  287, 2543) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch tests with a square parameter space
  XLAL_CHECK_MAIN(MismatchSquareTest("Zn",  0.03,     0,     0, 21460,  Z1_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Zn",  2e-4, -2e-9,     0, 23763,  Z2_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Zn",  1e-4, -1e-9, 1e-17, 19550,  Z3_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Ans", 0.03,     0,     0, 21460, A1s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Ans", 2e-4, -2e-9,     0, 18283, A2s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Ans", 1e-4, -2e-9, 2e-17, 20268, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch tests with an age--braking index parameter space
  XLAL_CHECK_MAIN(MismatchAgeBrakeTest("Ans", 100, 4.0e-5, 37872, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchAgeBrakeTest("Ans", 200, 1.5e-5, 37232, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchAgeBrakeTest("Ans", 300, 1.0e-5, 37022, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch tests with the reduced supersky parameter space and metric
  XLAL_CHECK_MAIN(SuperskyTest(1.1, 0.8, "Ans",  1, 50, 2.0e-5, 20548, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(SuperskyTest(1.5, 0.8, "Ans",  3, 50, 2.0e-5, 20202, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(SuperskyTest(2.5, 0.8, "Ans", 17, 50, 2.0e-5, 29147, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform tests with the reduced supersky parameter space metric and multiple segments
  XLAL_CHECK_MAIN(MultiSegSuperskyTest() == XLAL_SUCCESS, XLAL_EFUNC);

  return EXIT_SUCCESS;

}
/**
 * basic initializations: deal with user input and return standardized 'ConfigVariables'
 */
int
XLALInitCode ( ConfigVariables *cfg, const UserVariables_t *uvar, const char *app_name)
{
  XLAL_CHECK ( cfg && uvar && app_name, XLAL_EINVAL, "Illegal NULL pointer input." );

  /* init ephemeris data */
  XLAL_CHECK ( ( cfg->edat = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun ) ) != NULL, XLAL_EFUNC, "XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s.", uvar->ephemEarth, uvar->ephemSun);

  cfg->numDetectors = uvar->IFOs->length;

  cfg->numTimeStamps = 0;
  XLAL_CHECK ( (cfg->numTimeStampsX = XLALCreateUINT4Vector ( cfg->numDetectors )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(%d) failed.", cfg->numDetectors );

  BOOLEAN haveTimeGPS = XLALUserVarWasSet( &uvar->timeGPS );
  BOOLEAN haveTimeStampsFile = XLALUserVarWasSet( &uvar->timeStampsFile );
  BOOLEAN haveTimeStampsFiles = XLALUserVarWasSet( &uvar->timeStampsFiles );

  XLAL_CHECK ( !(haveTimeStampsFiles && haveTimeStampsFile), XLAL_EINVAL, "Can't handle both timeStampsFiles and (deprecated) haveTimeStampsFiles input options." );
  XLAL_CHECK ( !(haveTimeGPS && haveTimeStampsFile), XLAL_EINVAL, "Can't handle both (deprecated) timeStampsFile and timeGPS input options." );
  XLAL_CHECK ( !(haveTimeGPS && haveTimeStampsFiles), XLAL_EINVAL, "Can't handle both timeStampsFiles and timeGPS input options." );
  XLAL_CHECK ( haveTimeGPS || haveTimeStampsFiles || haveTimeStampsFile, XLAL_EINVAL, "Need either timeStampsFiles or timeGPS input option." );
  if ( haveTimeStampsFiles ) {
    XLAL_CHECK ( (uvar->timeStampsFiles->length == 1 ) || ( uvar->timeStampsFiles->length == cfg->numDetectors ), XLAL_EINVAL, "Length of timeStampsFiles list is neither 1 (one file for all detectors) nor does it match the number of detectors. (%d != %d)", uvar->timeStampsFiles->length, cfg->numDetectors );
    XLAL_CHECK ( (uvar->timeStampsFiles->length == 1 ) || !uvar->outab, XLAL_EINVAL, "At the moment, can't produce a(t), b(t) output (--outab) when given per-IFO --timeStampsFiles.");
  }

  if ( haveTimeStampsFiles && ( uvar->timeStampsFiles->length == cfg->numDetectors ) ) {

    XLAL_CHECK ( ( cfg->multiTimestamps = XLALReadMultiTimestampsFiles ( uvar->timeStampsFiles ) ) != NULL, XLAL_EFUNC );

    XLAL_CHECK ( (cfg->multiTimestamps->length > 0) && (cfg->multiTimestamps->data != NULL), XLAL_EINVAL, "Got empty timestamps-list from '%s'.", uvar->timeStampsFiles );

  }

  else {

    /* prepare multiTimestamps structure */
    UINT4 nTS = 0;
    XLAL_CHECK ( ( cfg->multiTimestamps = XLALCalloc ( 1, sizeof(*cfg->multiTimestamps))) != NULL, XLAL_ENOMEM, "Allocating multiTimestamps failed." );
    XLAL_CHECK ( ( cfg->multiTimestamps->data = XLALCalloc ( cfg->numDetectors, sizeof(cfg->multiTimestamps->data) )) != NULL, XLAL_ENOMEM, "Allocating multiTimestamps->data failed." );
    cfg->multiTimestamps->length = cfg->numDetectors;

    if ( haveTimeGPS ) { /* set up timestamps vector from timeGPS, use same for all IFOs */

      nTS = uvar->timeGPS->length;
      XLAL_CHECK ( (cfg->multiTimestamps->data[0] = XLALCreateTimestampVector ( nTS ) ) != NULL, XLAL_EFUNC, "XLALCreateTimestampVector( %d ) failed.",  nTS );

      /* convert input REAL8 times into LIGOTimeGPS for first detector */
      for (UINT4 t = 0; t < nTS; t++) {
        REAL8 temp_real8_timestamp = 0;
        XLAL_CHECK ( 1 == sscanf ( uvar->timeGPS->data[t], "%" LAL_REAL8_FORMAT, &temp_real8_timestamp ), XLAL_EINVAL, "Illegal REAL8 commandline argument to --timeGPS[%d]: '%s'", t, uvar->timeGPS->data[t] );
        XLAL_CHECK ( XLALGPSSetREAL8( &cfg->multiTimestamps->data[0]->data[t], temp_real8_timestamp ) != NULL, XLAL_EFUNC, "Failed to convert input GPS %g into LIGOTimeGPS", temp_real8_timestamp );
       } // for (UINT4 t = 0; t < nTS; t++)

    } // if ( haveTimeGPS )

    else { // haveTimeStampsFiles || haveTimeStampsFile

     CHAR *singleTimeStampsFile = NULL;
     if ( haveTimeStampsFiles ) {
      singleTimeStampsFile = uvar->timeStampsFiles->data[0];
     }
     else if ( haveTimeStampsFile ) {
      singleTimeStampsFile = uvar->timeStampsFile;
     }

     XLAL_CHECK ( ( cfg->multiTimestamps->data[0] = XLALReadTimestampsFile ( singleTimeStampsFile ) ) != NULL, XLAL_EFUNC );
     nTS = cfg->multiTimestamps->data[0]->length;

    } // else: haveTimeStampsFiles || haveTimeStampsFile

    /* copy timestamps from first detector to all others */
    if ( cfg->numDetectors > 1 ) {
      for ( UINT4 X=1; X < cfg->numDetectors; X++ ) {
        XLAL_CHECK ( (cfg->multiTimestamps->data[X] = XLALCreateTimestampVector ( nTS ) ) != NULL, XLAL_EFUNC, "XLALCreateTimestampVector( %d ) failed.", nTS );
        for (UINT4 t = 0; t < nTS; t++) {
          cfg->multiTimestamps->data[X]->data[t].gpsSeconds = cfg->multiTimestamps->data[0]->data[t].gpsSeconds;
          cfg->multiTimestamps->data[X]->data[t].gpsNanoSeconds = cfg->multiTimestamps->data[0]->data[t].gpsNanoSeconds;
        } // for (UINT4 t = 0; t < nTS; t++)
      } // for ( UINT4 X=1; X < cfg->numDetectors X++ )
    } // if ( cfg->numDetectors > 1 )

  } // if !( haveTimeStampsFiles && ( uvar->timeStampsFiles->length == cfg->numDetectors ) )

  for ( UINT4 X=0; X < cfg->numDetectors; X++ ) {
    cfg->numTimeStampsX->data[X] = cfg->multiTimestamps->data[X]->length;
    cfg->numTimeStamps += cfg->numTimeStampsX->data[X];
  }

  /* convert detector names into site-info */
  MultiLALDetector multiDet;
  XLAL_CHECK ( XLALParseMultiLALDetector ( &multiDet, uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* get detector states */
  XLAL_CHECK ( (cfg->multiDetStates = XLALGetMultiDetectorStates ( cfg->multiTimestamps, &multiDet, cfg->edat, 0.5 * uvar->Tsft )) != NULL, XLAL_EFUNC, "XLALGetDetectorStates() failed." );

  BOOLEAN haveAlphaDelta = ( XLALUserVarWasSet(&uvar->Alpha) && XLALUserVarWasSet(&uvar->Delta) );
  BOOLEAN haveSkyGrid = XLALUserVarWasSet( &uvar->skyGridFile );

  XLAL_CHECK ( !(haveAlphaDelta && haveSkyGrid), XLAL_EINVAL, "Can't handle both Alpha/Delta and skyGridFile input options." );
  XLAL_CHECK ( haveAlphaDelta || haveSkyGrid, XLAL_EINVAL, "Need either Alpha/Delta or skyGridFile input option." );

  if (haveAlphaDelta) { /* parse this into one-element Alpha, Delta vectors */
    XLAL_CHECK ( (cfg->Alpha = XLALCreateREAL8Vector ( 1 )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(1) failed." );
    cfg->Alpha->data[0] = uvar->Alpha;
    XLAL_CHECK ( (cfg->Delta = XLALCreateREAL8Vector ( 1 )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(1) failed." );
    cfg->Delta->data[0] = uvar->Delta;
    cfg->numSkyPoints = 1;
  } // if (haveAlphaDelta)

  else if ( haveSkyGrid ) {
    LALParsedDataFile *data = NULL;
    XLAL_CHECK ( XLALParseDataFile (&data, uvar->skyGridFile) == XLAL_SUCCESS, XLAL_EFUNC, "Failed to parse data file '%s'.", uvar->skyGridFile );
    cfg->numSkyPoints = data->lines->nTokens;
    XLAL_CHECK ( (cfg->Alpha = XLALCreateREAL8Vector ( cfg->numSkyPoints )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector( %d ) failed.", cfg->numSkyPoints  );
    XLAL_CHECK ( (cfg->Delta = XLALCreateREAL8Vector ( cfg->numSkyPoints )) != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector( %d ) failed.", cfg->numSkyPoints  );
    for (UINT4 n=0; n < cfg->numSkyPoints; n++) {
      XLAL_CHECK ( 2 == sscanf( data->lines->tokens[n], "%" LAL_REAL8_FORMAT "%" LAL_REAL8_FORMAT, &cfg->Alpha->data[n], &cfg->Delta->data[n] ), XLAL_EDATA, "Could not parse 2 numbers from line %d in candidate-file '%s':\n'%s'", n, uvar->skyGridFile, data->lines->tokens[n] );
    } // for (UINT4 n=0; n < cfg->numSkyPoints; n++)
    XLALDestroyParsedDataFile ( data );
  } // else if ( haveSkyGrid )

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

    if (  uvar->noiseSqrtShX->length != cfg->numDetectors ) {
      fprintf(stderr, "Length of noiseSqrtShX vector does not match number of detectors! (%d != %d)\n", uvar->noiseSqrtShX->length, cfg->numDetectors);
      XLAL_ERROR ( XLAL_EINVAL );
    }
    REAL8Vector *noiseSqrtShX = NULL;
    if ( (noiseSqrtShX = XLALCreateREAL8Vector ( cfg->numDetectors )) == NULL ) {
      fprintf(stderr, "Failed call to XLALCreateREAL8Vector( %d )\n", cfg->numDetectors );
      XLAL_ERROR ( XLAL_EFUNC );
    }

    REAL8 psd_normalization = 0;

    for (UINT4 X = 0; X < cfg->numDetectors; X++) {

      if ( 1 != sscanf ( uvar->noiseSqrtShX->data[X], "%" LAL_REAL8_FORMAT, &noiseSqrtShX->data[X] ) ) {
        fprintf(stderr, "Illegal REAL8 commandline argument to --noiseSqrtShX[%d]: '%s'\n", X, uvar->noiseSqrtShX->data[X]);
        XLAL_ERROR ( XLAL_EINVAL );
      }

      if ( noiseSqrtShX->data[X] <= 0.0 ) {
        fprintf(stderr, "Non-positive input PSD ratio for detector X=%d: noiseSqrtShX[X]=%f\n", X, noiseSqrtShX->data[X] );
        XLAL_ERROR ( XLAL_EINVAL );
      }

      psd_normalization += 1.0/SQ(noiseSqrtShX->data[X]);

    } /* for X < cfg->numDetectors */

    psd_normalization = (REAL8)cfg->numDetectors/psd_normalization; /* S = NSFT / sum S_Xalpha^-1, no per-SFT variation here -> S = Ndet / sum S_X^-1 */

    /* create multi noise weights */
    if ( (cfg->multiNoiseWeights = XLALCalloc(1, sizeof(*cfg->multiNoiseWeights))) == NULL ) {
     XLALPrintError ("%s: failed to XLALCalloc ( 1, %d )\n", __func__, sizeof(*cfg->multiNoiseWeights) );
     XLAL_ERROR ( XLAL_ENOMEM );
    }
    if ( (cfg->multiNoiseWeights->data = XLALCalloc(cfg->numDetectors, sizeof(*cfg->multiNoiseWeights->data))) == NULL ) {
     XLALPrintError ("%s: failed to XLALCalloc ( %d, %d )\n", __func__, cfg->numDetectors, sizeof(*cfg->multiNoiseWeights->data) );
     XLAL_ERROR ( XLAL_ENOMEM );
    }
    cfg->multiNoiseWeights->length = cfg->numDetectors;

    for (UINT4 X = 0; X < cfg->numDetectors; X++) {

      REAL8 noise_weight_X = psd_normalization/SQ(noiseSqrtShX->data[X]); /* w_Xalpha = S_Xalpha^-1/S^-1 = S / S_Xalpha */

      /* create k^th weights vector */
      if( ( cfg->multiNoiseWeights->data[X] = XLALCreateREAL8Vector ( cfg->numTimeStampsX->data[X] ) ) == NULL )
        {
          /* free weights vectors created previously in loop */
          XLALDestroyMultiNoiseWeights ( cfg->multiNoiseWeights );
          XLAL_ERROR ( XLAL_EFUNC, "Failed to allocate noiseweights for IFO X = %d\n", X );
        } /* if XLALCreateREAL8Vector() failed */

      /* loop over rngmeds and calculate weights -- one for each sft */
      for ( UINT4 alpha = 0; alpha < cfg->numTimeStampsX->data[X]; alpha++) {
        cfg->multiNoiseWeights->data[X]->data[alpha] = noise_weight_X;
      }

    } /* for X < cfg->numDetectors */

    XLALDestroyREAL8Vector ( noiseSqrtShX );

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

  else {
    cfg->multiNoiseWeights =  NULL;
  }

  return XLAL_SUCCESS;

} /* XLALInitCode() */
int
main( void )
{
  static LALStatus status;

  char eEphFileBad[] = TEST_DATA_DIR "earth47.dat";
  char eEphFile[] = TEST_DATA_DIR "earth98.dat";
  char sEphFile[] = TEST_DATA_DIR "sun98.dat";

  /* Checking response if data files not present */
  EphemerisData edat;
  edat.ephiles.earthEphemeris = eEphFileBad;
  edat.ephiles.sunEphemeris   = sEphFile;
  LALInitBarycenter(&status, &edat);
  if ( status.statusCode != LALINITBARYCENTERH_EOPEN)
    {
      XLALPrintError( "Got error code %d and message '%s', but expected error code %d\n", status.statusCode, status.statusDescription, LALINITBARYCENTERH_EOPEN);
      return LALBARYCENTERTESTC_EOPEN;
    }
  else
    {
      // XLALPrintError ("==================== this error is as expected and OK!! ==================== \n");
      xlalErrno = 0;
    }

  /* Now inputting kosher ephemeris. files and leap sec, to illustrate
   * proper usage. The real, serious TEST of the code is a script written
   * by Rejean Dupuis comparing LALBarycenter to TEMPO for thousands
   * of source positions and times.
   */
  edat.ephiles.earthEphemeris = eEphFile;
  edat.ephiles.sunEphemeris = sEphFile;
  LALInitBarycenter(&status, &edat);
  if ( status.statusCode ) {
    XLALPrintError ("LALInitBarycenter() failed with code %d\n", status.statusCode);
    return XLAL_EFAILED;
  }

  /* ===== now test equivalence of new XLALInitBarycenter() function ========== */
  EphemerisData *edat_xlal;
  if ( ( edat_xlal = XLALInitBarycenter ( eEphFile, sEphFile )) == NULL ) {
    XLALPrintError ("Something failed in XLALInitBarycenter(), errno =%d\n", xlalErrno );
    return XLAL_EFAILED;
  }
  if ( compare_ephemeris ( &edat, edat_xlal ) != XLAL_SUCCESS ) {
    XLALPrintError ("Equivalence test failed between XLALInitEphemeris() and LALInitEphemeris()\n" );
    return XLAL_EFAILED;
  }
  XLALDestroyEphemerisData ( edat_xlal );

  /* ========================================================================== */


 /* The routines using LALBarycenter package, the code above, leading
    up LALInitBarycenter call, should be near top of main. The idea is
    that ephemeris data is read into RAM once, at the beginning.

    NOTE that the only part of the piece of the LALDetector structure
    baryinput.site that has to be filled in by the driver code is
    the 3-vector: baryinput.site.location[] .

    NOTE that the driver code that calls LALInitBarycenter must
    LALFree(edat->ephemE) and LALFree(edat->ephemS).
    The driver code that calls LALBarycenter must LALFree(edat).
 */

  /* Now getting coords for detector */
  LALDetector cachedDetector;
  cachedDetector = lalCachedDetectors[LALDetectorIndexGEO600DIFF];

  BarycenterInput XLAL_INIT_DECL(baryinput);
  baryinput.site.location[0]=cachedDetector.location[0]/LAL_C_SI;
  baryinput.site.location[1]=cachedDetector.location[1]/LAL_C_SI;
  baryinput.site.location[2]=cachedDetector.location[2]/LAL_C_SI;

  EarthState earth;
  EarthState earth_xlal;
  EmissionTime  emit, emit_xlal, emit_opt;

  /* ----- Checking error messages when the timestamp is not within the 1-yr ephemeris files */
  LIGOTimeGPS tGPS = {t1998+5e7, 0 };
  LALBarycenterEarth ( &status, &earth, &tGPS, &edat );
  if ( status.statusCode == 0 ) {
    XLALPrintError ( "LALBarycenterEarth() succeeded but expected to get error\n");
    return LALBARYCENTERTESTC_EOUTOFRANGEE;
  } else {
    XLALPrintError ("==================== this error is as expected and OK!! ==================== \n");
    xlalErrno = 0;
  }

  /* next try calling for bad choice of RA,DEC (e.g., something sensible in degrees, but radians)*/
  tGPS.gpsSeconds = t1998+3600;
  LALBarycenterEarth ( &status, &earth, &tGPS, &edat );

  baryinput.alpha= 120;
  baryinput.delta = 60;
  baryinput.dInv = 0;

  LALBarycenter ( &status, &emit, &baryinput, &earth );
  if ( status.statusCode == 0 ) {
    XLALPrintError( "LALBarycenter() succeeded but expected to get error\n" );
    return LALBARYCENTERTESTC_EBADSOURCEPOS;
  } else {
    XLALPrintError ("==================== this error is as expected and OK!! ==================== \n");
    xlalErrno = 0;
  }

  /* ---------- Now running program w/o errors, to illustrate proper use. ---------- */
  EmissionTime XLAL_INIT_DECL(maxDiff);
  EmissionTime XLAL_INIT_DECL(maxDiffOpt);
  REAL8 tic, toc;
  UINT4 NRepeat = 1;
  UINT4 counter = 0;
  REAL8 tau_lal = 0, tau_xlal = 0, tau_opt = 0;
  BarycenterBuffer *buffer = NULL;

  unsigned int seed = XLALGetTimeOfDay();
  srand ( seed );

  /* Outer loop over different sky positions */
  for ( UINT4 k=0; k < 300; k++)
    {
      baryinput.alpha = ( 1.0 * rand() / RAND_MAX ) * LAL_TWOPI;	// in [0, 2pi]
      baryinput.delta = ( 1.0 * rand() / RAND_MAX ) * LAL_PI - LAL_PI_2;// in [-pi/2, pi/2]
      baryinput.dInv = 0.e0;

      /* inner loop over pulse arrival times */
      for ( UINT4 i=0; i < 100; i++ )
        {
          REAL8 tPulse = t1998 + ( 1.0 * rand() / RAND_MAX ) * LAL_YRSID_SI;	// t in [1998, 1999]
          XLALGPSSetREAL8( &tGPS, tPulse );
          baryinput.tgps = tGPS;

          /* ----- old LAL interface ---------- */
          LALBarycenterEarth ( &status, &earth, &tGPS, &edat);
          if ( status.statusCode ) {
            XLALPrintError ("LALBarycenterEarth() failed with code %d\n", status.statusCode);
            return XLAL_EFAILED;
          }

          tic = XLALGetTimeOfDay();
          for ( UINT4 l = 0; l < NRepeat; l++ )
            LALBarycenter ( &status, &emit, &baryinput, &earth );
          toc = XLALGetTimeOfDay();
          tau_lal += ( toc - tic ) / NRepeat;
          if ( status.statusCode ) {
            XLALPrintError ("LALBarycenter() failed with code %d\n", status.statusCode);
            return XLAL_EFAILED;
          }

          /* ----- new XLAL interface ---------- */
          XLAL_CHECK ( XLALBarycenterEarth ( &earth_xlal, &tGPS, &edat ) == XLAL_SUCCESS, XLAL_EFAILED );
          tic = XLALGetTimeOfDay();
          for ( UINT4 l = 0; l < NRepeat; l ++ )
            XLAL_CHECK ( XLALBarycenter ( &emit_xlal, &baryinput, &earth_xlal ) == XLAL_SUCCESS, XLAL_EFAILED );
          toc = XLALGetTimeOfDay();
          tau_xlal += ( toc - tic ) / NRepeat;

          /* collect maximal deviations over all struct-fields of 'emit' */
          EmissionTime thisDiff;
          diffEmissionTime ( &thisDiff, &emit, &emit_xlal );
          absmaxEmissionTime ( &maxDiff, &maxDiff, &thisDiff );

          /* ----- optimized XLAL version with buffering ---------- */
          tic = XLALGetTimeOfDay();
          for ( UINT4 l = 0; l < NRepeat; l ++ )
            XLAL_CHECK ( XLALBarycenterOpt ( &emit_opt, &baryinput, &earth_xlal, &buffer ) == XLAL_SUCCESS, XLAL_EFAILED );
          toc = XLALGetTimeOfDay();
          tau_opt += ( toc - tic ) / NRepeat;

          /* collect maximal deviations over all struct-fields of 'emit' */
          diffEmissionTime ( &thisDiff, &emit, &emit_opt );
          absmaxEmissionTime ( &maxDiffOpt, &maxDiffOpt, &thisDiff );

          counter ++;
        } /* for i */

    } /* for k */

  XLALFree ( buffer );
  buffer = NULL;

  /* ----- check differences in results ---------- */
  REAL8 tolerance = 1e-9;	// in seconds: can't go beyond nanosecond precision due to GPS limitation
  REAL8 maxEmitDiff = maxErrInEmissionTime ( &maxDiff );
  REAL8 maxEmitDiffOpt = maxErrInEmissionTime ( &maxDiffOpt );
  XLALPrintInfo ( "Max error (in seconds) between LALBarycenter() and XLALBarycenter()     = %g s (tolerance = %g s)\n", maxEmitDiff, tolerance );
  XLAL_CHECK ( maxEmitDiff < tolerance, XLAL_EFAILED,
               "Max error (in seconds) between LALBarycenter() and XLALBarycenter()  = %g s, exceeding tolerance of %g s\n", maxEmitDiff, tolerance );

  XLALPrintInfo ( "Max error (in seconds) between LALBarycenter() and XLALBarycenterOpt()  = %g s (tolerance = %g s)\n", maxEmitDiffOpt, tolerance );
  XLAL_CHECK ( maxEmitDiffOpt < tolerance, XLAL_EFAILED,
               "Max error (in seconds) between LALBarycenter() and XLALBarycenterOpt()  = %g s, exceeding tolerance of %g s\n",
               maxEmitDiffOpt, tolerance );
  printf ( "%g	%g %d %d %g	%g %g %g	%g %g %g\n",
           maxEmitDiffOpt,
           maxDiffOpt.deltaT, maxDiffOpt.te.gpsSeconds, maxDiffOpt.te.gpsNanoSeconds, maxDiffOpt.tDot,
           maxDiffOpt.rDetector[0], maxDiffOpt.rDetector[1], maxDiffOpt.rDetector[2],
           maxDiffOpt.vDetector[0], maxDiffOpt.vDetector[1], maxDiffOpt.vDetector[2]
           );

  /* ----- output runtimes ---------- */
  XLALPrintError ("Runtimes per function-call, averaged over %g calls\n", 1.0 * NRepeat * counter );
  XLALPrintError ("LALBarycenter() 	%g s\n", tau_lal / counter );
  XLALPrintError ("XLALBarycenter()	%g s (= %.1f %%)\n", tau_xlal / counter, - 100 * (tau_lal - tau_xlal ) / tau_lal );
  XLALPrintError ("XLALBarycenterOpt()	%g s (= %.1f %%)\n", tau_opt / counter,  - 100 * (tau_lal - tau_opt ) / tau_lal );

  /* ===== test XLALRestrictEphemerisData() ===== */
  XLALPrintInfo("\n\nTesting XLALRestrictEphemerisData() ... ");
  {
    XLAL_CHECK( edat.nentriesS >= 100, XLAL_EFAILED );
    const INT4 orig_nentriesS = edat.nentriesS;
    for (INT4 i = 1; i <= 4; ++i) {
      REAL8 start, end;
      LIGOTimeGPS startGPS, endGPS;
      INT4 diff_nentriesS;

      start = edat.ephemS[2*i].gps;
      end = edat.ephemS[edat.nentriesS - 1 - 3*i].gps;
      XLAL_CHECK( XLALGPSSetREAL8(&startGPS, start) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALGPSSetREAL8(&endGPS, end) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALRestrictEphemerisData(&edat, &startGPS, &endGPS) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( edat.ephemS[0].gps == start, XLAL_EFAILED, "\nTest S%dA FAILED: %0.9f != start %0.9f\n", i, edat.ephemS[0].gps, start );
      XLAL_CHECK( edat.ephemS[edat.nentriesS - 1].gps == end, XLAL_EFAILED, "\nTest S%dA FAILED: end %0.9f != %0.9f\n", i, edat.ephemS[edat.nentriesS - 1].gps, end );
      diff_nentriesS = ((i*i + i) * 5) / 2 + 2*(i-1);
      XLAL_CHECK( orig_nentriesS - edat.nentriesS == diff_nentriesS, XLAL_EFAILED, "\nTest S%dA FAILED: nentries %d != %d\n", i, orig_nentriesS - edat.nentriesS, diff_nentriesS );

      XLAL_CHECK( XLALGPSSetREAL8(&startGPS, start + 0.5*edat.dtStable) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALGPSSetREAL8(&endGPS, end - 0.5*edat.dtStable) != NULL, XLAL_EFUNC );
      start = edat.ephemS[0].gps;
      end = edat.ephemS[edat.nentriesS - 1].gps;
      XLAL_CHECK( XLALRestrictEphemerisData(&edat, &startGPS, &endGPS) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( edat.ephemS[0].gps == start, XLAL_EFAILED, "\nTest S%dB FAILED: start %0.9f != %0.9f\n", i, edat.ephemS[0].gps, start );
      XLAL_CHECK( edat.ephemS[edat.nentriesS - 1].gps == end, XLAL_EFAILED, "\nTest S%dB FAILED: end %0.9f != %0.9f\n", i, edat.ephemS[edat.nentriesS - 1].gps, end );
      diff_nentriesS = ((i*i + i) * 5) / 2 + 2*(i-1);
      XLAL_CHECK( orig_nentriesS - edat.nentriesS == diff_nentriesS, XLAL_EFAILED, "\nTest S%dB FAILED: nentries %d != %d\n", i, orig_nentriesS - edat.nentriesS, diff_nentriesS );

      XLAL_CHECK( XLALGPSSetREAL8(&startGPS, start + 1.5*edat.dtStable) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALGPSSetREAL8(&endGPS, end - 1.5*edat.dtStable) != NULL, XLAL_EFUNC );
      start = edat.ephemS[1].gps;
      end = edat.ephemS[edat.nentriesS - 2].gps;
      XLAL_CHECK( XLALRestrictEphemerisData(&edat, &startGPS, &endGPS) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( edat.ephemS[0].gps == start, XLAL_EFAILED, "\nTest S%dC FAILED: start %0.9f != %0.9f\n", i, edat.ephemS[0].gps, start );
      XLAL_CHECK( edat.ephemS[edat.nentriesS - 1].gps == end, XLAL_EFAILED, "\nTest S%dC FAILED: end %0.9f != %0.9f\n", i, edat.ephemS[edat.nentriesS - 1].gps, end );
      diff_nentriesS = ((i*i + i) * 5) / 2 + 2*i;
      XLAL_CHECK( orig_nentriesS - edat.nentriesS == diff_nentriesS, XLAL_EFAILED, "\nTest S%dC FAILED: nentries %d != %d\n", i, orig_nentriesS - edat.nentriesS, diff_nentriesS );
    }

    XLAL_CHECK( edat.nentriesE >= 100, XLAL_EFAILED );
    const INT4 orig_nentriesE = edat.nentriesE;
    for (INT4 i = 1; i <= 4; ++i) {
      REAL8 start, end;
      LIGOTimeGPS startGPS, endGPS;
      INT4 diff_nentriesE;

      start = edat.ephemE[2*i].gps;
      end = edat.ephemE[edat.nentriesE - 1 - 3*i].gps;
      XLAL_CHECK( XLALGPSSetREAL8(&startGPS, start) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALGPSSetREAL8(&endGPS, end) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALRestrictEphemerisData(&edat, &startGPS, &endGPS) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( edat.ephemE[0].gps == start, XLAL_EFAILED, "\nTest E%dA FAILED: %0.9f != start %0.9f\n", i, edat.ephemE[0].gps, start );
      XLAL_CHECK( edat.ephemE[edat.nentriesE - 1].gps == end, XLAL_EFAILED, "\nTest E%dA FAILED: end %0.9f != %0.9f\n", i, edat.ephemE[edat.nentriesE - 1].gps, end );
      diff_nentriesE = ((i*i + i) * 5) / 2 + 2*(i-1);
      XLAL_CHECK( orig_nentriesE - edat.nentriesE == diff_nentriesE, XLAL_EFAILED, "\nTest E%dA FAILED: nentries %d != %d\n", i, orig_nentriesE - edat.nentriesE, diff_nentriesE );

      XLAL_CHECK( XLALGPSSetREAL8(&startGPS, start + 0.5*edat.dtEtable) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALGPSSetREAL8(&endGPS, end - 0.5*edat.dtEtable) != NULL, XLAL_EFUNC );
      start = edat.ephemE[0].gps;
      end = edat.ephemE[edat.nentriesE - 1].gps;
      XLAL_CHECK( XLALRestrictEphemerisData(&edat, &startGPS, &endGPS) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( edat.ephemE[0].gps == start, XLAL_EFAILED, "\nTest E%dB FAILED: start %0.9f != %0.9f\n", i, edat.ephemE[0].gps, start );
      XLAL_CHECK( edat.ephemE[edat.nentriesE - 1].gps == end, XLAL_EFAILED, "\nTest E%dB FAILED: end %0.9f != %0.9f\n", i, edat.ephemE[edat.nentriesE - 1].gps, end );
      diff_nentriesE = ((i*i + i) * 5) / 2 + 2*(i-1);
      XLAL_CHECK( orig_nentriesE - edat.nentriesE == diff_nentriesE, XLAL_EFAILED, "\nTest E%dB FAILED: nentries %d != %d\n", i, orig_nentriesE - edat.nentriesE, diff_nentriesE );

      XLAL_CHECK( XLALGPSSetREAL8(&startGPS, start + 1.5*edat.dtEtable) != NULL, XLAL_EFUNC );
      XLAL_CHECK( XLALGPSSetREAL8(&endGPS, end - 1.5*edat.dtEtable) != NULL, XLAL_EFUNC );
      start = edat.ephemE[1].gps;
      end = edat.ephemE[edat.nentriesE - 2].gps;
      XLAL_CHECK( XLALRestrictEphemerisData(&edat, &startGPS, &endGPS) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( edat.ephemE[0].gps == start, XLAL_EFAILED, "\nTest E%dC FAILED: start %0.9f != %0.9f\n", i, edat.ephemE[0].gps, start );
      XLAL_CHECK( edat.ephemE[edat.nentriesE - 1].gps == end, XLAL_EFAILED, "\nTest E%dC FAILED: end %0.9f != %0.9f\n", i, edat.ephemE[edat.nentriesE - 1].gps, end );
      diff_nentriesE = ((i*i + i) * 5) / 2 + 2*i;
      XLAL_CHECK( orig_nentriesE - edat.nentriesE == diff_nentriesE, XLAL_EFAILED, "\nTest E%dC FAILED: nentries %d != %d\n", i, orig_nentriesE - edat.nentriesE, diff_nentriesE );
    }
  }
  XLALPrintInfo("PASSED\n\n");

  LALFree(edat.ephemE);
  LALFree(edat.ephemS);

  LALCheckMemoryLeaks();

  XLALPrintError ("==> OK. All tests successful!\n\n");

  return 0;

} /* main() */
int main( void )
{

  // Load ephemeris data
  EphemerisData *edat = XLALInitBarycenter( TEST_DATA_DIR "earth00-19-DE405.dat.gz",
                                            TEST_DATA_DIR "sun00-19-DE405.dat.gz" );
  XLAL_CHECK_MAIN( edat != NULL, XLAL_EFUNC );

  // Create segment list
  LALSegList segments;
  XLAL_CHECK_MAIN( XLALSegListInit( &segments ) == XLAL_SUCCESS, XLAL_EFUNC );
  for ( size_t n = 0; n < NUM_SEGS; ++n ) {
    const double Tspan = 3 * 86400;
    const double deltat[NUM_SEGS] = { -8 * 86400, 0, 8 * 86400 };
    LALSeg segment;
    LIGOTimeGPS start_time = REF_TIME, end_time = REF_TIME;
    XLALGPSAdd( &start_time, deltat[n] - 0.5 * Tspan );
    XLALGPSAdd( &end_time, deltat[n] + 0.5 * Tspan );
    XLAL_CHECK_MAIN( XLALSegSet( &segment, &start_time, &end_time, 0 ) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK_MAIN( XLALSegListAppend( &segments, &segment ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Compute supersky metrics
  SuperskyMetrics *metrics = NULL;
  {
    const LIGOTimeGPS ref_time = REF_TIME;
    const MultiLALDetector detectors = { .length = 1, .sites = { lalCachedDetectors[LAL_LLO_4K_DETECTOR] } };
    metrics = XLALComputeSuperskyMetrics( 1, &ref_time, &segments, FIDUCIAL_FREQ, &detectors, NULL, DETMOTION_SPIN | DETMOTION_PTOLEORBIT, edat );
  }
  XLAL_CHECK_MAIN( metrics != NULL, XLAL_EFUNC );

  // Check coherent metrics
  for ( size_t n = 0; n < NUM_SEGS; ++n ) {
    XLAL_CHECK_MAIN( CheckSuperskyMetrics(
                       metrics->coh_rssky_metric[n], coh_rssky_metric_refs[n],
                       metrics->coh_rssky_transf[n], coh_rssky_transf_refs[n],
                       coh_phys_mismatches[n], 1e-2
                       ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Check semicoherent metric
  XLAL_CHECK_MAIN( CheckSuperskyMetrics(
                     metrics->semi_rssky_metric, semi_rssky_metric_ref,
                     metrics->semi_rssky_transf, semi_rssky_transf_ref,
                     semi_phys_mismatch, 3e-2
                     ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Check semicoherent metric after round-trip frequency rescaling
  XLAL_CHECK_MAIN( XLALScaleSuperskyMetricsFiducialFreq( metrics, 257.52 ) == XLAL_SUCCESS, XLAL_EFUNC );
  {
    double semi_rssky_metric_rescale[4][4];
    memcpy( semi_rssky_metric_rescale, semi_rssky_metric_ref, sizeof( semi_rssky_metric_ref ) );
    gsl_matrix_view semi_rssky_metric_rescale_view = gsl_matrix_view_array( ( double * )semi_rssky_metric_rescale, 4, 4 );
    gsl_matrix_view sky_sky = gsl_matrix_submatrix( &semi_rssky_metric_rescale_view.matrix, 0, 0, 2, 2 );
    gsl_matrix_scale( &sky_sky.matrix, ( 257.52 / FIDUCIAL_FREQ ) * ( 257.52 / FIDUCIAL_FREQ ) );
    const double err = XLALCompareMetrics( metrics->semi_rssky_metric, &semi_rssky_metric_rescale_view.matrix ), err_tol = 1e-6;
    XLAL_CHECK( err <= err_tol, XLAL_ETOL, "'rssky_metric' check failed: err = %0.3e > %0.3e = err_tol", err, err_tol );
  }
  XLAL_CHECK_MAIN( XLALScaleSuperskyMetricsFiducialFreq( metrics, FIDUCIAL_FREQ ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK_MAIN( CheckSuperskyMetrics(
                     metrics->semi_rssky_metric, semi_rssky_metric_ref,
                     metrics->semi_rssky_transf, semi_rssky_transf_ref,
                     semi_phys_mismatch, 3e-2
                     ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Cleanup
  XLALDestroyEphemerisData( edat );
  XLALSegListClear( &segments );
  XLALDestroySuperskyMetrics( metrics );
  LALCheckMemoryLeaks();

  return EXIT_SUCCESS;

}
/** 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() */
Beispiel #22
0
int main(int argc, char *argv[]){

  static LALStatus  status;  

  static LALDetector          *detector;
  static LIGOTimeGPSVector    timeV;
  static REAL8Cart3CoorVector velV;
  static REAL8Vector          timeDiffV;
  static REAL8                foft;
  static HoughPulsarTemplate  pulsarTemplate;

  EphemerisData   *edat = NULL;
  CHAR  *uvar_earthEphemeris = NULL; 
  CHAR  *uvar_sunEphemeris = NULL;
  SFTVector  *inputSFTs  = NULL;  
  REAL8 *alphaVec=NULL;
  REAL8 *deltaVec=NULL;
  REAL8 *freqVec=NULL;
  REAL8 *spndnVec=NULL;

  /* pgV is vector of peakgrams and pg1 is onepeakgram */
  static UCHARPeakGram    *pg1, **pgV; 
  UINT4  msp; /*number of spin-down parameters */
  CHAR   *uvar_ifo = NULL;
  CHAR   *uvar_sftDir = NULL; /* the directory where the SFT  could be */
  CHAR   *uvar_fnameOut = NULL;               /* The output prefix filename */
  CHAR   *uvar_fnameIn = NULL;  
  INT4   numberCount, ind;
  UINT8  nTemplates;   
  UINT4   mObsCoh;
  REAL8  uvar_peakThreshold;
  REAL8  f_min, f_max, fWings, timeBase;
  INT4  uvar_blocksRngMed;
  UINT4  sftlength; 
  INT4   sftFminBin;
  UINT4 loopId, tempLoopId;
  FILE  *fpOut = NULL;
  CHAR *fnameLog=NULL;
  FILE *fpLog = NULL;
  CHAR *logstr=NULL;
  /*REAL8 asq, bsq;*/ /* square of amplitude modulation functions a and b */

  /******************************************************************/
  /*    Set up the default parameters.      */
  /* ****************************************************************/

  /* LAL error-handler */
  lal_errhandler = LAL_ERR_EXIT;
  
  msp = 1; /*only one spin-down */
 
  /* memory allocation for spindown */
  pulsarTemplate.spindown.length = msp;
  pulsarTemplate.spindown.data = NULL;
  pulsarTemplate.spindown.data = (REAL8 *)LALMalloc(msp*sizeof(REAL8));
 
 
  uvar_peakThreshold = THRESHOLD;

  uvar_earthEphemeris = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_earthEphemeris,EARTHEPHEMERIS);

  uvar_sunEphemeris = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_sunEphemeris,SUNEPHEMERIS);

  uvar_sftDir = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_sftDir,SFTDIRECTORY);

  uvar_fnameOut = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_fnameOut,VALIDATEOUT);

  uvar_fnameIn = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_fnameIn,VALIDATEIN);

  uvar_blocksRngMed = BLOCKSRNGMED;

  /* register user input variables */
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_ifo,            "ifo",            STRING, 'i', OPTIONAL, "Detector GEO(1) LLO(2) LHO(3)" ) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_earthEphemeris, "earthEphemeris", STRING, 'E', OPTIONAL, "Earth Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sunEphemeris,   "sunEphemeris",   STRING, 'S', OPTIONAL, "Sun Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sftDir,         "sftDir",         STRING, 'D', OPTIONAL, "SFT Directory") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fnameIn,        "fnameIn",        STRING, 'T', OPTIONAL, "Input template file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fnameOut,       "fnameOut",       STRING, 'o', OPTIONAL, "Output filename") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_blocksRngMed,   "blocksRngMed",   INT4,   'w', OPTIONAL, "RngMed block size") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_peakThreshold,  "peakThreshold",  REAL8,  't', OPTIONAL, "Peak selection threshold") == XLAL_SUCCESS, XLAL_EFUNC);

  /* read all command line variables */
  BOOLEAN should_exit = 0;
  XLAL_CHECK_MAIN( XLALUserVarReadAllInput(&should_exit, argc, argv, lalAppsVCSInfoList) == XLAL_SUCCESS, XLAL_EFUNC);
  if (should_exit)
    exit(1);
 
  /* open log file for writing */
  fnameLog = LALCalloc( (strlen(uvar_fnameOut) + strlen(".log") + 10),1);
  strcpy(fnameLog,uvar_fnameOut);
  strcat(fnameLog,".log");
  if ((fpLog = fopen(fnameLog, "w")) == NULL) {
    fprintf(stderr, "Unable to open file %s for writing\n", fnameLog);
    LALFree(fnameLog);
    exit(1);
  }
  
  /* get the log string */
  XLAL_CHECK_MAIN( ( logstr = XLALUserVarGetLog(UVAR_LOGFMT_CFGFILE) ) != NULL, XLAL_EFUNC);  

  fprintf( fpLog, "## Log file for HoughValidate\n\n");
  fprintf( fpLog, "# User Input:\n");
  fprintf( fpLog, "#-------------------------------------------\n");
  fprintf( fpLog, "%s", logstr);
  LALFree(logstr);

  /* append an ident-string defining the exact CVS-version of the code used */
  {
    CHAR command[1024] = "";
    fprintf (fpLog, "\n\n# CVS-versions of executable:\n");
    fprintf (fpLog, "# -----------------------------------------\n");
    fclose (fpLog);
    
    sprintf (command, "ident %s | sort -u >> %s", argv[0], fnameLog);
    /* we don't check this. If it fails, we assume that */
    /* one of the system-commands was not available, and */
    /* therefore the CVS-versions will not be logged */
    if ( system(command) ) fprintf (stderr, "\nsystem('%s') returned non-zero status!\n\n", command );

    LALFree(fnameLog);
  }

  /* open output file for writing */
  fpOut= fopen(uvar_fnameOut, "w");
  /*setlinebuf(fpOut);*/  /* line buffered on */  
  setvbuf(fpOut, (char *)NULL, _IOLBF, 0);

  /*****************************************************************/
  /* read template file */
  /*****************************************************************/
  {
    FILE  *fpIn = NULL;
    INT4   r;
    REAL8  temp1, temp2, temp3, temp4, temp5;
    UINT8  templateCounter; 
    
    fpIn = fopen(uvar_fnameIn, "r");
    if ( !fpIn )
      {
	fprintf(stderr, "Unable to fine file %s\n", uvar_fnameIn);
	return DRIVEHOUGHCOLOR_EFILE;
      }


    nTemplates = 0;
    do 
      {
	r=fscanf(fpIn,"%lf%lf%lf%lf%lf\n", &temp1, &temp2, &temp3, &temp4, &temp5);
	/* make sure the line has the right number of entries or is EOF */
	if (r==5) nTemplates++;
      } while ( r != EOF);
    rewind(fpIn);
    
    alphaVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));
    deltaVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));     
    freqVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));
    spndnVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));     
    
    
    for (templateCounter = 0; templateCounter < nTemplates; templateCounter++)
      {
	r=fscanf(fpIn,"%lf%lf%lf%lf%lf\n", &temp1, alphaVec + templateCounter, deltaVec + templateCounter, 
		 freqVec + templateCounter,  spndnVec + templateCounter);
      }     
    fclose(fpIn);      
  }


  /**************************************************/
  /* read sfts */     
  /*************************************************/
  f_min = freqVec[0];     /* initial frequency to be analyzed */
  /* assume that the last frequency in the templates file is also the highest frequency */
  f_max = freqVec[nTemplates-1] ; 
  
  /* we need to add wings to fmin and fmax to account for 
     the Doppler shift, the size of the rngmed block size
     and also nfsizecylinder.  The block size and nfsizecylinder are
     specified in terms of frequency bins...this goes as one of the arguments of 
     LALReadSFTfiles */
  /* first correct for Doppler shift */
  fWings =  f_max * VTOT; 
  f_min -= fWings;    
  f_max += fWings; 
  
  /* create pattern to look for in SFT directory */   

  {
    CHAR *tempDir = NULL;
    SFTCatalog *catalog = NULL;
    static SFTConstraints constraints;

    /* set detector constraint */
    constraints.detector = NULL;
    if ( XLALUserVarWasSet( &uvar_ifo ) )    
      constraints.detector = XLALGetChannelPrefix ( uvar_ifo );

    /* get sft catalog */
    tempDir = (CHAR *)LALCalloc(512, sizeof(CHAR));
    strcpy(tempDir, uvar_sftDir);
    strcat(tempDir, "/*SFT*.*");
    XLAL_CHECK_MAIN( ( catalog = XLALSFTdataFind( tempDir, &constraints) ) != NULL, XLAL_EFUNC);
    
    detector = XLALGetSiteInfo( catalog->data[0].header.name);

    mObsCoh = catalog->length;
    timeBase = 1.0 / catalog->data->header.deltaF;

    XLAL_CHECK_MAIN( ( inputSFTs = XLALLoadSFTs ( catalog, f_min, f_max) ) != NULL, XLAL_EFUNC);

    XLAL_CHECK_MAIN( XLALNormalizeSFTVect( inputSFTs, uvar_blocksRngMed, 0.0 ) == XLAL_SUCCESS, XLAL_EFUNC);

    if ( XLALUserVarWasSet( &uvar_ifo ) )    
      LALFree( constraints.detector );
    LALFree( tempDir);
    XLALDestroySFTCatalog(catalog );  	

  }



  sftlength = inputSFTs->data->data->length;
  {
    INT4 tempFbin;
    sftFminBin = floor( (REAL4)(timeBase * inputSFTs->data->f0) + (REAL4)(0.5));
    tempFbin = floor( timeBase * inputSFTs->data->f0 + 0.5);

    if (tempFbin - sftFminBin)
      {
	fprintf(stderr, "Rounding error in calculating fminbin....be careful! \n");
      }
  }

  /* loop over sfts and select peaks */

  /* first the memory allocation for the peakgramvector */
  pgV = NULL;
  pgV = (UCHARPeakGram **)LALMalloc(mObsCoh*sizeof(UCHARPeakGram *));  

  /* memory for  peakgrams */
  for (tempLoopId=0; tempLoopId < mObsCoh; tempLoopId++)
    {
      pgV[tempLoopId] = (UCHARPeakGram *)LALMalloc(sizeof(UCHARPeakGram));
      pgV[tempLoopId]->length = sftlength; 
      pgV[tempLoopId]->data = NULL; 
      pgV[tempLoopId]->data = (UCHAR *)LALMalloc(sftlength* sizeof(UCHAR));
   
      LAL_CALL (SFTtoUCHARPeakGram( &status, pgV[tempLoopId], inputSFTs->data + tempLoopId, uvar_peakThreshold), &status);
    }


  /* having calculated the peakgrams we don't need the sfts anymore */
  XLALDestroySFTVector( inputSFTs);


  
  /* ****************************************************************/
  /* setting timestamps vector */
  /* ****************************************************************/
  timeV.length = mObsCoh;
  timeV.data = NULL;  
  timeV.data = (LIGOTimeGPS *)LALMalloc(mObsCoh*sizeof(LIGOTimeGPS));
  
  { 
    UINT4    j; 
    for (j=0; j < mObsCoh; j++){
      timeV.data[j].gpsSeconds = pgV[j]->epoch.gpsSeconds;
      timeV.data[j].gpsNanoSeconds = pgV[j]->epoch.gpsNanoSeconds;
    }    
  }
  
  /******************************************************************/
  /* compute the time difference relative to startTime for all SFTs */
  /******************************************************************/
  timeDiffV.length = mObsCoh;
  timeDiffV.data = NULL; 
  timeDiffV.data = (REAL8 *)LALMalloc(mObsCoh*sizeof(REAL8));
  
  {   
    REAL8   t0, ts, tn, midTimeBase;
    UINT4   j; 

    midTimeBase=0.5*timeBase;
    ts = timeV.data[0].gpsSeconds;
    tn = timeV.data[0].gpsNanoSeconds * 1.00E-9;
    t0=ts+tn;
    timeDiffV.data[0] = midTimeBase;

    for (j=1; j< mObsCoh; ++j){
      ts = timeV.data[j].gpsSeconds;
      tn = timeV.data[j].gpsNanoSeconds * 1.00E-9;  
      timeDiffV.data[j] = ts + tn -t0 + midTimeBase; 
    }  
  }

  /******************************************************************/
  /* compute detector velocity for those time stamps                */
  /******************************************************************/
  velV.length = mObsCoh;
  velV.data = NULL;
  velV.data = (REAL8Cart3Coor *)LALMalloc(mObsCoh*sizeof(REAL8Cart3Coor));
  
  {  
    VelocityPar   velPar;
    REAL8     vel[3]; 
    UINT4     j; 

    velPar.detector = *detector;
    velPar.tBase = timeBase;
    velPar.vTol = ACCURACY;
    velPar.edat = NULL;

    /* read in ephemeris data */
    XLAL_CHECK_MAIN( ( edat = XLALInitBarycenter( uvar_earthEphemeris, uvar_sunEphemeris ) ) != NULL, XLAL_EFUNC);
    velPar.edat = edat;

    /* now calculate average velocity */    
    for(j=0; j< velV.length; ++j){
      velPar.startTime.gpsSeconds     = timeV.data[j].gpsSeconds;
      velPar.startTime.gpsNanoSeconds = timeV.data[j].gpsNanoSeconds;
      
      LAL_CALL( LALAvgDetectorVel ( &status, vel, &velPar), &status );
      velV.data[j].x= vel[0];
      velV.data[j].y= vel[1];
      velV.data[j].z= vel[2];   
    }  
  }


  
  /* amplitude modulation stuff */
  {
    AMCoeffs XLAL_INIT_DECL(amc);
    AMCoeffsParams *amParams;
    EarthState earth;
    BarycenterInput baryinput;  /* Stores detector location and other barycentering data */

    /* detector location */
    baryinput.site.location[0] = detector->location[0]/LAL_C_SI;
    baryinput.site.location[1] = detector->location[1]/LAL_C_SI;
    baryinput.site.location[2] = detector->location[2]/LAL_C_SI;
    baryinput.dInv = 0.e0;
    /* alpha and delta must come from the skypatch */
    /* for now set it to something arbitrary */
    baryinput.alpha = 0.0;
    baryinput.delta = 0.0;

    /* Allocate space for amParams stucture */
    /* Here, amParams->das is the Detector and Source info */
    amParams = (AMCoeffsParams *)LALMalloc(sizeof(AMCoeffsParams));
    amParams->das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource));
    amParams->das->pSource = (LALSource *)LALMalloc(sizeof(LALSource));
    /* Fill up AMCoeffsParams structure */
    amParams->baryinput = &baryinput;
    amParams->earth = &earth; 
    amParams->edat = edat;
    amParams->das->pDetector = detector; 
    /* make sure alpha and delta are correct */
    amParams->das->pSource->equatorialCoords.latitude = baryinput.delta;
    amParams->das->pSource->equatorialCoords.longitude = baryinput.alpha;
    amParams->das->pSource->orientation = 0.0;
    amParams->das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
    amParams->polAngle = amParams->das->pSource->orientation ; /* These two have to be the same!!*/

    /* timeV is start time ---> change to mid time */    
    LAL_CALL (LALComputeAM(&status, &amc, timeV.data, amParams), &status); 

    /* calculate a^2 and b^2 */
    /* for (ii=0, asq=0.0, bsq=0.0; ii<mObsCoh; ii++) */
    /*       { */
    /* 	REAL8 *a, *b; */
    /*        	a = amc.a + ii; */
    /* 	b = amc.b + ii; */
    /* 	asq += (*a) * (*a); */
    /* 	bsq += (*b) * (*b); */
    /*       } */
    
    /* free amParams */
    LALFree(amParams->das->pSource);
    LALFree(amParams->das);
    LALFree(amParams);

  }

  /* loop over templates */    
  for(loopId=0; loopId < nTemplates; ++loopId){
    
    /* set template parameters */    
    pulsarTemplate.f0 = freqVec[loopId];
    pulsarTemplate.longitude = alphaVec[loopId];
    pulsarTemplate.latitude = deltaVec[loopId];
    pulsarTemplate.spindown.data[0] = spndnVec[loopId];
	   
 
    {
      REAL8   f0new, vcProdn, timeDiffN;
      REAL8   sourceDelta, sourceAlpha, cosDelta, factorialN;
      UINT4   j, i, f0newBin; 
      REAL8Cart3Coor       sourceLocation;
      
      sourceDelta = pulsarTemplate.latitude;
      sourceAlpha = pulsarTemplate.longitude;
      cosDelta = cos(sourceDelta);
      
      sourceLocation.x = cosDelta* cos(sourceAlpha);
      sourceLocation.y = cosDelta* sin(sourceAlpha);
      sourceLocation.z = sin(sourceDelta);      

      /* loop for all different time stamps,calculate frequency and produce number count*/ 
      /* first initialize number count */
      numberCount=0;
      for (j=0; j<mObsCoh; ++j)
	{  
	  /* calculate v/c.n */
	  vcProdn = velV.data[j].x * sourceLocation.x
	    + velV.data[j].y * sourceLocation.y
	    + velV.data[j].z * sourceLocation.z;

	  /* loop over spindown values to find f_0 */
	  f0new = pulsarTemplate.f0;
	  factorialN = 1.0;
	  timeDiffN = timeDiffV.data[j];	  
	  for (i=0; i<msp;++i)
	    { 
	      factorialN *=(i+1.0);
	      f0new += pulsarTemplate.spindown.data[i]*timeDiffN / factorialN;
	      timeDiffN *= timeDiffN;
	    }
	  
	  f0newBin = floor(f0new*timeBase + 0.5);
	  foft = f0newBin * (1.0 +vcProdn) / timeBase;    
	  
	  /* get the right peakgram */      
	  pg1 = pgV[j];
	  
	  /* calculate frequency bin for template */
	  ind =  floor( foft * timeBase + 0.5 ) - sftFminBin; 
	  
	  /* update the number count */
	  numberCount+=pg1->data[ind]; 
	}      
      
    } /* end of block calculating frequency path and number count */      
    

    /******************************************************************/
    /* printing result in the output file */
    /******************************************************************/
    
    fprintf(fpOut,"%d %f %f %f %g \n", 
	    numberCount, pulsarTemplate.longitude, pulsarTemplate.latitude, pulsarTemplate.f0,
	    pulsarTemplate.spindown.data[0] );
    
  } /* end of loop over templates */

  /******************************************************************/
  /* Closing files */
  /******************************************************************/  
  fclose(fpOut); 

  
  /******************************************************************/
  /* Free memory and exit */
  /******************************************************************/

  LALFree(alphaVec);
  LALFree(deltaVec);
  LALFree(freqVec);
  LALFree(spndnVec);
  

  for (tempLoopId = 0; tempLoopId < mObsCoh; tempLoopId++){
    pg1 = pgV[tempLoopId];  
    LALFree(pg1->data);
    LALFree(pg1);
  }
  LALFree(pgV);
  
  LALFree(timeV.data);
  LALFree(timeDiffV.data);
  LALFree(velV.data);
  
  LALFree(pulsarTemplate.spindown.data);
   
  XLALDestroyEphemerisData(edat);
  
  XLALDestroyUserVars();

  LALCheckMemoryLeaks();
    
  return DRIVEHOUGHCOLOR_ENORM;
}
Beispiel #23
0
//Main program
int main(int argc, char *argv[])
{
   
  INT4 ii, jj;               //counter variables
   
   //Turn off gsl error handler
   gsl_set_error_handler_off();
   
   //Initiate command line interpreter and config file loader
   struct gengetopt_args_info args_info;
   struct cmdline_parser_params *configparams;
   configparams = cmdline_parser_params_create();  //initialize parameters structure
   configparams->check_required = 0;  //don't check for required values at the step
   if ( cmdline_parser_ext(argc, argv, &args_info, configparams) ) {
       fprintf(stderr, "%s: cmdline_parser_ext() failed.\n", __func__);
       XLAL_ERROR(XLAL_FAILURE);
   }
   configparams->initialize = 0;  //don't reinitialize the parameters structure
   if ( args_info.config_given && cmdline_parser_config_file(args_info.config_arg, &args_info, configparams) ) {
      fprintf(stderr, "%s: cmdline_parser_config_file() failed.\n", __func__);
      XLAL_ERROR(XLAL_FAILURE);
   }
   //Check required
   if ( cmdline_parser_required(&args_info, argv[0]) ) {
      fprintf(stderr, "%s: cmdline_parser_required() failed.\n", __func__);
      XLAL_ERROR(XLAL_FAILURE);
   }
   
   //Set lalDebugLevel to user input or 0 if no input
   
   //Allocate input parameters structure memory
   inputParamsStruct *inputParams = new_inputParams(args_info.IFO_given);
   if (inputParams==NULL) {
      fprintf(stderr, "%s: new_inputParams() failed.\n", __func__);
      XLAL_ERROR(XLAL_EFUNC);
   }
   
   //Read TwoSpect input parameters
   if ( (readTwoSpectInputParams(inputParams, args_info)) != 0 ) {
      fprintf(stderr, "%s: readTwoSpectInputParams() failed.\n", __func__);
      XLAL_ERROR(XLAL_EFUNC);
   }
   
   //Initialize ephemeris data structure
   EphemerisData *edat = XLALInitBarycenter(earth_ephemeris, sun_ephemeris);
   if (edat==NULL) {
      fprintf(stderr, "%s: XLALInitBarycenter() failed.\n", __func__);
      XLAL_ERROR(XLAL_EFUNC);
   }
   
   //Maximum detector velocity in units of c from start of observation time - Tcoh to end of observation + Tcoh
   REAL4 detectorVmax = CompDetectorVmax(inputParams->searchstarttime-inputParams->Tcoh, inputParams->Tcoh, inputParams->SFToverlap, inputParams->Tobs+2.0*inputParams->Tcoh, inputParams->det[0], edat);
   if (xlalErrno!=0) {
      fprintf(stderr, "%s: CompDetectorVmax() failed.\n", __func__);
      XLAL_ERROR(XLAL_EFUNC);
   }
   
   //Assume maximum bin shift possible
   inputParams->maxbinshift = (INT4)round(detectorVmax * (inputParams->fmin+0.5*inputParams->fspan) * inputParams->Tcoh)+1;

   //Read in the T-F data from SFTs
   fprintf(stderr, "Loading in SFTs... ");
   REAL8 tfnormalization = 2.0/inputParams->Tcoh/(args_info.avesqrtSh_arg*args_info.avesqrtSh_arg);
   REAL4Vector *tfdata = readInSFTs(inputParams, &(tfnormalization));
   if (tfdata==NULL) {
      fprintf(stderr, "\n%s: readInSFTs() failed.\n", __func__);
      XLAL_ERROR(XLAL_EFUNC);
   }
   fprintf(stderr, "done\n");
   
   //Removing bad SFTs using K-S test and Kuiper's test
   if (inputParams->markBadSFTs!=0 && inputParams->signalOnly==0) {
      fprintf(stderr, "Marking and removing bad SFTs... ");
      INT4 numffts = (INT4)floor(inputParams->Tobs/(inputParams->Tcoh-inputParams->SFToverlap)-1);    //Number of FFTs
      INT4 numfbins = (INT4)(round(inputParams->fspan*inputParams->Tcoh+2.0*inputParams->dfmax*inputParams->Tcoh)+12+1)+2*inputParams->maxbinshift+inputParams->blksize-1;     //Number of frequency bins
      REAL4Vector *tempvect = XLALCreateREAL4Vector(numfbins);
      if (tempvect==NULL) {
         fprintf(stderr, "%s: XLALCreateREAL4Vector(%d) failed.\n", __func__, numfbins);
         XLAL_ERROR(XLAL_EFUNC);
      }
      REAL8 ksthreshold = 1.358/(sqrt(numfbins)+0.12+0.11/sqrt(numfbins));
      REAL8 kuiperthreshold = 1.747/(sqrt(numfbins)+0.155+0.24/sqrt(numfbins));
      //fprintf(stderr, "%f %f\n", ksthreshold, kuiperthreshold);
      INT4 badsfts = 0, badsfts0 = 0, kuiperoverlap1 = 0, kuiperoverlap2 = 0, totalsfts = 0;
      FILE *OUTPUT = fopen("./output/kskoutput.dat","a");
      for (ii=0; ii<numffts; ii++) {
         if (tfdata->data[ii*numfbins]!=0.0) {
            totalsfts++;
            memcpy(tempvect->data, &(tfdata->data[ii*numfbins]), sizeof(REAL4)*tempvect->length);
            qsort(tempvect->data, tempvect->length, sizeof(REAL4), qsort_REAL4_compar);
            REAL4 vector_median = 0.0;
            if (tempvect->length % 2 != 1) vector_median = 0.5*(tempvect->data[(INT4)(0.5*tempvect->length)-1] + tempvect->data[(INT4)(0.5*tempvect->length)]);
            else vector_median = tempvect->data[(INT4)(0.5*tempvect->length)];
            REAL4 vector_mean = (REAL4)(vector_median/LAL_LN2);

            REAL8 ksvalue = 0.0, testval1, testval2, testval;
            REAL8 oneoverlength = 1.0/tempvect->length;
            for (jj=0; jj<(INT4)tempvect->length; jj++) {
               testval1 = fabs((1.0+jj)*oneoverlength - gsl_cdf_exponential_P(tempvect->data[jj], vector_mean));
               testval2 = fabs(jj*oneoverlength - gsl_cdf_exponential_P(tempvect->data[jj], vector_mean));
               testval = fmax(testval1, testval2);
               if (testval>ksvalue) ksvalue = testval;
            }

            REAL8 loval = 0.0, hival = 0.0;
            for (jj=0; jj<(INT4)tempvect->length; jj++) {
              testval1 = (1.0+jj)*oneoverlength - gsl_cdf_exponential_P(tempvect->data[jj], vector_mean);
              testval2 = jj*oneoverlength - gsl_cdf_exponential_P(tempvect->data[jj], vector_mean);
              if (hival<testval1) hival = testval1;
              if (loval<testval2) loval = testval2;
            }
            REAL8 kuiperval1 = hival + loval;

            loval = -1.0, hival = -1.0;
            for (jj=0; jj<(INT4)tempvect->length; jj++) {
              testval1 = (1.0+jj)*oneoverlength - gsl_cdf_exponential_P(tempvect->data[jj], vector_mean);
              testval2 = jj*oneoverlength - gsl_cdf_exponential_P(tempvect->data[jj], vector_mean);
              if (hival<testval1) hival = testval1;
              if (hival<testval2) hival = testval2;
              if (loval<-testval1) loval = -testval1;
              if (loval<-testval2) loval = -testval2;
            }
            REAL8 kuiperval = hival + loval;

            //fprintf(OUTPUT, "%g %g %g\n", ksvalue, kuiperval1, kuiperval);

            if (ksvalue>ksthreshold || kuiperval1>kuiperthreshold) badsfts0++;
            if (ksvalue>ksthreshold || kuiperval>kuiperthreshold) badsfts++;
            if (kuiperval1>kuiperthreshold && kuiperval>kuiperthreshold) kuiperoverlap1++;
            if (kuiperval1>kuiperthreshold || kuiperval>kuiperthreshold) kuiperoverlap2++;

         }
      }
      fprintf(OUTPUT, "%f %d %d %d %d\n", inputParams->fmin, badsfts0, badsfts, kuiperoverlap1, kuiperoverlap2);
      fclose(OUTPUT);
      fprintf(stderr, "Fraction excluded in K-S and Kuiper's tests = %f\n", (REAL4)badsfts/(REAL4)totalsfts);
      XLALDestroyREAL4Vector(tempvect);
   }

   XLALDestroyREAL4Vector(tfdata);
   XLALDestroyEphemerisData(edat);
   cmdline_parser_free(&args_info);
   free_inputParams(inputParams);

   return 0;

}
Beispiel #24
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() */
Beispiel #25
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()
Beispiel #26
0
int main(int argc, char *argv[])
{
   UserVariables_t XLAL_INIT_DECL(uvar);
   XLAL_CHECK ( InitUserVars(&uvar, argc, argv) == XLAL_SUCCESS, XLAL_EFUNC );
   
   MultiLALDetector *detectors = NULL;
   XLAL_CHECK( (detectors = XLALMalloc(sizeof(MultiLALDetector))) != NULL, XLAL_ENOMEM );
   detectors->length = uvar.IFO->length;
   for (UINT4 ii=0; ii<detectors->length; ii++) {
      if (strcmp("H1", uvar.IFO->data[ii])==0) {
         detectors->sites[ii] = lalCachedDetectors[LAL_LHO_4K_DETECTOR]; //H1
      } else if (strcmp("L1",uvar.IFO->data[ii])==0) {
         detectors->sites[ii] = lalCachedDetectors[LAL_LLO_4K_DETECTOR]; //L1
      } else if (strcmp("V1", uvar.IFO->data[ii])==0) {
         detectors->sites[ii] = lalCachedDetectors[LAL_VIRGO_DETECTOR];  //V1
      } else if (strcmp("H2", uvar.IFO->data[ii])==0) {
         detectors->sites[ii] = lalCachedDetectors[LAL_LHO_2K_DETECTOR]; //H2
      } else if (strcmp("H2r", uvar.IFO->data[ii])==0) {
         LALDetector H2 = lalCachedDetectors[LAL_LHO_2K_DETECTOR]; //H2 rotated
         H2.frDetector.xArmAzimuthRadians -= 0.25*LAL_PI;
         H2.frDetector.yArmAzimuthRadians -= 0.25*LAL_PI;
         memset(&(H2.frDetector.name), 0, sizeof(CHAR)*LALNameLength);
         snprintf(H2.frDetector.name, LALNameLength, "%s", "LHO_2k_rotatedPiOver4");
         XLAL_CHECK( (XLALCreateDetector(&(detectors->sites[ii]), &(H2.frDetector), LALDETECTORTYPE_IFODIFF)) != NULL, XLAL_EFUNC );
      } else {
         XLAL_ERROR(XLAL_EINVAL, "Not using valid interferometer! Expected 'H1', 'H2', 'H2r' (rotated H2), 'L1', or 'V1' not %s.\n", uvar.IFO->data[ii]);
      }
   }

   EphemerisData *edat = NULL;
   XLAL_CHECK( (edat = XLALInitBarycenter(uvar.ephemEarth, uvar.ephemSun)) != NULL, XLAL_EFUNC );

   LIGOTimeGPS tStart;
   XLALGPSSetREAL8 ( &tStart, uvar.t0 );
   XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC, "XLALGPSSetREAL8 failed\n" );

   MultiLIGOTimeGPSVector *multiTimestamps = NULL;
   XLAL_CHECK( (multiTimestamps = XLALMakeMultiTimestamps(tStart, uvar.Tobs, uvar.Tsft, uvar.SFToverlap, detectors->length)) != NULL, XLAL_EFUNC );

   LIGOTimeGPS refTime = multiTimestamps->data[0]->data[0];
   
   MultiDetectorStateSeries *multiStateSeries = NULL;
   XLAL_CHECK( (multiStateSeries = XLALGetMultiDetectorStates(multiTimestamps, detectors, edat, uvar.SFToverlap)) != NULL, XLAL_EFUNC );

   gsl_rng *rng = NULL;
   XLAL_CHECK( (rng = gsl_rng_alloc(gsl_rng_mt19937)) != NULL, XLAL_EFUNC );
   gsl_rng_set(rng, 0);

   FILE *OUTPUT;
   XLAL_CHECK( (OUTPUT = fopen(uvar.outfilename,"w")) != NULL, XLAL_EIO, "Output file %s could not be opened\n", uvar.outfilename );

   for (INT4 n=0; n<uvar.skylocations; n++) {
      SkyPosition skypos;
      if (XLALUserVarWasSet(&(uvar.alpha)) && XLALUserVarWasSet(&(uvar.delta)) && n==0) {
         skypos.longitude = uvar.alpha;
         skypos.latitude = uvar.delta;
         skypos.system = COORDINATESYSTEM_EQUATORIAL;
      } else {
         skypos.longitude = LAL_TWOPI*gsl_rng_uniform(rng);
         skypos.latitude = LAL_PI*gsl_rng_uniform(rng) - LAL_PI_2;
         skypos.system = COORDINATESYSTEM_EQUATORIAL;
      }

      REAL8 cosi0, psi0;
      if (XLALUserVarWasSet(&(uvar.cosi)) && n==0) cosi0 = uvar.cosi;
      else cosi0 = 2.0*gsl_rng_uniform(rng) - 1.0;
      if (XLALUserVarWasSet(&(uvar.psi)) && n==0) psi0 = uvar.psi;
      else psi0 = LAL_PI*gsl_rng_uniform(rng);

      MultiAMCoeffs *multiAMcoefficients = NULL;
      XLAL_CHECK( (multiAMcoefficients = XLALComputeMultiAMCoeffs(multiStateSeries, NULL, skypos)) != NULL, XLAL_EFUNC );

      MultiSSBtimes *multissb = NULL;
      XLAL_CHECK( (multissb = XLALGetMultiSSBtimes(multiStateSeries, skypos, refTime, SSBPREC_RELATIVISTICOPT)) != NULL, XLAL_EFUNC );

      REAL8 frequency0 = 1000.0 + (gsl_rng_uniform(rng)-0.5)/uvar.Tsft;
      REAL8 frequency = 1000.0;

      for (UINT4 ii=0; ii<multiAMcoefficients->data[0]->a->length; ii++) {
         REAL4 Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi0) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi0);
         REAL4 Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi0) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi0);
         REAL4 Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi0) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi0);
         REAL4 Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi0) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi0);
         COMPLEX16 RatioTerm0 = crect(0.5*Fplus1*(1.0+cosi0*cosi0), Fcross1*cosi0)/crect(0.5*Fplus0*(1.0+cosi0*cosi0), Fcross0*cosi0);

         REAL4 detPhaseArg = 0.0, detPhaseMag = 0.0;
         BOOLEAN loopbroken = 0;
         for (INT4 jj=0; jj<50 && !loopbroken; jj++) {
            REAL4 psi = 0.02*jj*LAL_PI;
            Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi);
            Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi);
            Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi);
            Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi);
            for (INT4 kk=0; kk<51 && !loopbroken; kk++) {
               //REAL4 cosi = 1.0 - 2.0*0.02*kk;
               REAL4 cosi;
               if (cosi0<0.0) cosi = -0.02*kk;
               else cosi = 0.02*kk;
               COMPLEX16 complexnumerator = crect(0.5*Fplus1*(1.0+cosi*cosi), Fcross1*cosi);
               COMPLEX16 complexdenominator = crect(0.5*Fplus0*(1.0+cosi*cosi) , Fcross0*cosi);
               if (cabs(complexdenominator)>1.0e-7) {
                  COMPLEX16 complexval = complexnumerator/complexdenominator;
                  detPhaseMag += fmin(cabs(complexval), 10.0);
                  detPhaseArg += gsl_sf_angle_restrict_pos(carg(complexval));
               } else {
                  loopbroken = 1;
                  detPhaseMag = 0.0;
                  detPhaseArg = 0.0;
               }
            }
         }
         detPhaseMag /= 2550.0;
         detPhaseArg /= 2550.0;

         REAL8 timediff0 = multissb->data[0]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[0]->Tdot->data[ii];
         REAL8 timediff1 = multissb->data[1]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[1]->Tdot->data[ii];
         REAL8 tau = timediff1 - timediff0;
         REAL8 freqshift0 = -LAL_TWOPI*tau*frequency0;
         REAL8 freqshift = -LAL_TWOPI*tau*frequency;

         REAL8 nearestFrequency = round(multissb->data[0]->Tdot->data[ii]*frequency*uvar.Tsft)/uvar.Tsft;

         COMPLEX16 dirichlet0 = conj(DirichletKernelLargeNHann((multissb->data[1]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft)/DirichletKernelLargeNHann((multissb->data[0]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft));
         COMPLEX16 dirichlet = conj(DirichletKernelLargeNHann((multissb->data[1]->Tdot->data[ii]*frequency-nearestFrequency)*uvar.Tsft)/DirichletKernelLargeNHann((multissb->data[0]->Tdot->data[ii]*frequency-nearestFrequency)*uvar.Tsft));

         COMPLEX16 signal0 = 0.5*crect(0.5*Fplus0*(1.0+cosi0*cosi0), Fcross0*cosi0)*cpolar(1.0, LAL_TWOPI*frequency0*0.5*uvar.Tsft+LAL_TWOPI*frequency0*(multissb->data[0]->DeltaT->data[ii]+multissb->data[0]->Tdot->data[ii]*0.5*uvar.Tsft))*uvar.Tsft*DirichletKernelLargeNHann((multissb->data[0]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft);
         COMPLEX16 signal1 = 0.5*crect(0.5*Fplus1*(1.0+cosi0*cosi0), Fcross1*cosi0)*cpolar(1.0, LAL_TWOPI*frequency0*0.5*uvar.Tsft+LAL_TWOPI*frequency0*(multissb->data[1]->DeltaT->data[ii]+multissb->data[1]->Tdot->data[ii]*0.5*uvar.Tsft))*uvar.Tsft*DirichletKernelLargeNHann((multissb->data[1]->Tdot->data[ii]*frequency0-nearestFrequency)*uvar.Tsft);
      
         fprintf(OUTPUT, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g\n", cabs(signal0), gsl_sf_angle_restrict_pos(carg(signal0)), cabs(signal1), gsl_sf_angle_restrict_pos(carg(signal1)), cabs(RatioTerm0), gsl_sf_angle_restrict_pos(carg(RatioTerm0)), detPhaseMag, detPhaseArg, freqshift0, freqshift, cabs(dirichlet0), gsl_sf_angle_restrict_pos(carg(dirichlet0)), cabs(dirichlet), gsl_sf_angle_restrict_pos(carg(dirichlet)));

         //fprintf(OUTPUT, "%g %g %g %g\n", cabs(signal0), gsl_sf_angle_restrict_pos(carg(signal0)), cabs(signal1), gsl_sf_angle_restrict_pos(carg(signal1)));
      }

      XLALDestroyMultiAMCoeffs(multiAMcoefficients);
      XLALDestroyMultiSSBtimes(multissb);
   }

   fclose(OUTPUT);
   gsl_rng_free(rng);
   XLALDestroyMultiDetectorStateSeries(multiStateSeries);
   XLALDestroyMultiTimestamps(multiTimestamps);
   XLALDestroyEphemerisData(edat);
   XLALFree(detectors);
   XLALDestroyUserVars();
}
/* ----- function definitions ---------- */
int
main ( int argc, char *argv[] )
{
  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()
Beispiel #28
0
int main( int argc, char *argv[]){

  static LALStatus            status;  
  static LALDetector          detector;
  static LIGOTimeGPSVector    timeV;
  static REAL8Cart3CoorVector velV;
  static REAL8Vector          timeDiffV;
  static REAL8Vector          foft;
  static PulsarSignalParams  params;
  static SFTParams sftParams;

  static UCHARPeakGram     pg1;
  static COMPLEX8SFTData1  sft1;
  static REAL8PeriodoPSD   periPSD;

  REAL4TimeSeries   *signalTseries = NULL;
  SFTVector    *inputSFTs  = NULL;  
  SFTVector    *outputSFTs = NULL;
  /* data about injected signal */
  static PulsarData           pulsarInject;

  /* the template */
  static HoughTemplate  pulsarTemplate, pulsarTemplate1;

  /*FILE  *fpOUT = NULL;  output file pointer */
  FILE  *fpLog = NULL; /* log file pointer */
  CHAR  *logstr=NULL; /* log string containing user input variables */
  CHAR  *fnamelog=NULL; /* name of log file */
  INT4  nfSizeCylinder;
  
  EphemerisData   *edat = NULL;

  INT4   mObsCoh, numberCount;
  REAL8  sftBand;  
  REAL8  timeBase, deltaF, normalizeThr, threshold;
  UINT4  sftlength; 
  INT4   sftFminBin;
  REAL8  fHeterodyne;
  REAL8  tSamplingRate;


  /* grid spacings */
  REAL8 deltaTheta;
  INT4 mmP, mmT; /* for loop over mismatched templates */

  /* user input variables */
  INT4 uvar_ifo, uvar_blocksRngMed;
  REAL8 uvar_peakThreshold;
  REAL8 uvar_alpha, uvar_delta, uvar_h0, uvar_f0;
  REAL8 uvar_psi, uvar_phi0, uvar_fdot, uvar_cosiota;
  CHAR *uvar_earthEphemeris=NULL;
  CHAR *uvar_sunEphemeris=NULL;
  CHAR *uvar_sftDir=NULL;
  CHAR *uvar_fnameout=NULL;

  /*  set up the default parameters  */

  nfSizeCylinder = NFSIZE;

  /* set other user input variables */
  uvar_peakThreshold = THRESHOLD;
  uvar_ifo = IFO;
  uvar_blocksRngMed = BLOCKSRNGMED;

  /* set default pulsar parameters */
  uvar_h0 = H0;
  uvar_alpha = ALPHA;
  uvar_delta = DELTA;
  uvar_f0 =  F0;
  uvar_fdot = FDOT;
  uvar_psi = PSI;
  uvar_cosiota = COSIOTA;
  uvar_phi0 = PHI0;

  /* now set the default filenames */
  uvar_earthEphemeris = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_earthEphemeris,EARTHEPHEMERIS);

  uvar_sunEphemeris = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_sunEphemeris,SUNEPHEMERIS);

  uvar_sftDir = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_sftDir,SFTDIRECTORY);

  uvar_fnameout = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_fnameout, FILEOUT);

  /* register user input variables */
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_ifo,            "ifo",            INT4,   'i', OPTIONAL, "Detector GEO(1) LLO(2) LHO(3)" ) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_blocksRngMed,   "blocksRngMed",   INT4,   'w', OPTIONAL, "RngMed block size") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_peakThreshold,  "peakThreshold",  REAL8,  't', OPTIONAL, "Peak selection threshold") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_earthEphemeris, "earthEphemeris", STRING, 'E', OPTIONAL, "Earth Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sunEphemeris,   "sunEphemeris",   STRING, 'S', OPTIONAL, "Sun Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sftDir,         "sftDir",         STRING, 'D', OPTIONAL, "SFT Directory") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fnameout,       "fnameout",       STRING, 'o', OPTIONAL, "Output file prefix") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_alpha,          "alpha",          REAL8,  'r', OPTIONAL, "Right ascension") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_delta,          "delta",          REAL8,  'l', OPTIONAL, "Declination") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_h0,             "h0",             REAL8,  'm', OPTIONAL, "h0 to inject") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_f0,             "f0",             REAL8,  'f', OPTIONAL, "Start search frequency") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_psi,            "psi",            REAL8,  'p', OPTIONAL, "Polarization angle") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_phi0,           "phi0",           REAL8,  'P', OPTIONAL, "Initial phase") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_cosiota,        "cosiota",        REAL8,  'c', OPTIONAL, "Cosine of iota") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fdot,           "fdot",           REAL8,  'd', OPTIONAL, "Spindown parameter") == XLAL_SUCCESS, XLAL_EFUNC);

  /* read all command line variables */
  BOOLEAN should_exit = 0;
  XLAL_CHECK_MAIN( XLALUserVarReadAllInput(&should_exit, argc, argv, lalAppsVCSInfoList) == XLAL_SUCCESS, XLAL_EFUNC);
  if (should_exit)
    exit(1);
  
  /* write the log file */
  fnamelog = (CHAR *)LALMalloc( 512*sizeof(CHAR));
  strcpy(fnamelog, uvar_fnameout);
  strcat(fnamelog, "_log");
  /* open the log file for writing */
  if ((fpLog = fopen(fnamelog, "w")) == NULL) {
    fprintf(stderr, "Unable to open file %s for writing\n", fnamelog);
    LALFree(fnamelog);
    exit(1);
  }

  /* get the log string */
  XLAL_CHECK_MAIN( ( logstr = XLALUserVarGetLog(UVAR_LOGFMT_CFGFILE) ) != NULL, XLAL_EFUNC);  

  fprintf( fpLog, "## Log file for HoughMismatch\n\n");
  fprintf( fpLog, "# User Input:\n");
  fprintf( fpLog, "#-------------------------------------------\n");
  fprintf( fpLog, "%s", logstr);
  LALFree(logstr);

  /* append an ident-string defining the exact CVS-version of the code used */
  {
    CHAR command[1024] = "";
    fprintf (fpLog, "\n\n# CVS-versions of executable:\n");
    fprintf (fpLog, "# -----------------------------------------\n");
    fclose (fpLog);
    
    sprintf (command, "ident %s | sort -u >> %s", argv[0], fnamelog);
    /* we don't check this. If it fails, we assume that */
    /* one of the system-commands was not available, and */
    /* therefore the CVS-versions will not be logged */
    if ( system(command) ) fprintf (stderr, "\nsystem('%s') returned non-zero status!\n\n", command );

    LALFree(fnamelog); 
  }

  /* set peak selection threshold */
  SUB( LALRngMedBias( &status, &normalizeThr, uvar_blocksRngMed ), &status ); 
  threshold = uvar_peakThreshold/normalizeThr; 

  /* set detector */
  if (uvar_ifo ==1) detector=lalCachedDetectors[LALDetectorIndexGEO600DIFF];
  if (uvar_ifo ==2) detector=lalCachedDetectors[LALDetectorIndexLLODIFF];
  if (uvar_ifo ==3) detector=lalCachedDetectors[LALDetectorIndexLHODIFF];


  /* copy user input values */
  pulsarInject.f0 = uvar_f0;
  pulsarInject.latitude = uvar_delta;
  pulsarInject.longitude = uvar_alpha;
  pulsarInject.aPlus = 0.5 * uvar_h0 * ( 1.0 + uvar_cosiota * uvar_cosiota );
  pulsarInject.aCross = uvar_h0 * uvar_cosiota;
  pulsarInject.psi = uvar_psi;
  pulsarInject.phi0 = uvar_phi0;
  pulsarInject.spindown.length = 1;
  pulsarInject.spindown.data = NULL;
  pulsarInject.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));
  pulsarInject.spindown.data[0] = uvar_fdot;

  /* copy these values also to the pulsar template */
  /* template is complately matched at this point */
  pulsarTemplate.f0 = uvar_f0;
  pulsarTemplate.latitude = uvar_delta;
  pulsarTemplate.longitude = uvar_alpha;
  pulsarTemplate.spindown.length = 1;
  pulsarTemplate.spindown.data = NULL;
  pulsarTemplate.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));
  pulsarTemplate.spindown.data[0] = uvar_fdot;

  /* allocate memory for mismatched spindown template */
  pulsarTemplate1.spindown.length = 1;
  pulsarTemplate1.spindown.data = NULL;
  pulsarTemplate1.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));

  /* read sfts */
  {
    CHAR *tempDir;
    tempDir = (CHAR *)LALMalloc(512*sizeof(CHAR));
    strcpy(tempDir, uvar_sftDir);
    strcat(tempDir, "/*SFT*.*"); 
    sftBand = 0.5; 
    SUB( LALReadSFTfiles ( &status, &inputSFTs, uvar_f0 - sftBand, uvar_f0 + sftBand, nfSizeCylinder + uvar_blocksRngMed , tempDir), &status);
    LALFree(tempDir);
  }


  /* get sft parameters */
  mObsCoh = inputSFTs->length;
  sftlength = inputSFTs->data->data->length;
  deltaF = inputSFTs->data->deltaF;
  timeBase = 1.0/deltaF;
  sftFminBin = floor( timeBase * inputSFTs->data->f0 + 0.5);
  fHeterodyne = sftFminBin*deltaF;
  tSamplingRate = 2.0*deltaF*(sftlength -1.);

  /* create timestamp vector */
  timeV.length = mObsCoh;
  timeV.data = NULL;  
  timeV.data = (LIGOTimeGPS *)LALMalloc(mObsCoh*sizeof(LIGOTimeGPS));

  /* read timestamps */
  { 
    INT4    i; 
    SFTtype  *sft= NULL; 
    
    sft = inputSFTs->data;
    for (i=0; i < mObsCoh; i++){
      timeV.data[i].gpsSeconds = sft->epoch.gpsSeconds;
      timeV.data[i].gpsNanoSeconds = sft->epoch.gpsNanoSeconds;
      ++sft;
    }    
  }

  /* compute the time difference relative to startTime for all SFT */
  timeDiffV.length = mObsCoh;
  timeDiffV.data = NULL; 
  timeDiffV.data = (REAL8 *)LALMalloc(mObsCoh*sizeof(REAL8));

  {   
    REAL8   t0, ts, tn, midTimeBase;
    INT4   j; 

    midTimeBase=0.5*timeBase;
    ts = timeV.data[0].gpsSeconds;
    tn = timeV.data[0].gpsNanoSeconds * 1.00E-9;
    t0=ts+tn;
    timeDiffV.data[0] = midTimeBase;

    for (j=1; j< mObsCoh; ++j){
      ts = timeV.data[j].gpsSeconds;
      tn = timeV.data[j].gpsNanoSeconds * 1.00E-9;  
      timeDiffV.data[j] = ts+tn -t0+midTimeBase; 
    }  
  }

  /* compute detector velocity for those time stamps  */ 
  velV.length = mObsCoh; 
  velV.data = NULL;
  velV.data = (REAL8Cart3Coor *)LALMalloc(mObsCoh*sizeof(REAL8Cart3Coor));
  
  {  
    VelocityPar   velPar;
    REAL8     vel[3]; 
    UINT4     j; 

    velPar.detector = detector;
    velPar.tBase = timeBase;
    velPar.vTol = 0.0; /* irrelevant */
    velPar.edat = NULL;

    /* read in ephemeris data */
    XLAL_CHECK_MAIN( ( edat = XLALInitBarycenter( uvar_earthEphemeris, uvar_sunEphemeris ) ) != NULL, XLAL_EFUNC);
    velPar.edat = edat;

    /* calculate detector velocity */    
    for(j=0; j< velV.length; ++j){
      velPar.startTime.gpsSeconds     = timeV.data[j].gpsSeconds;
      velPar.startTime.gpsNanoSeconds = timeV.data[j].gpsNanoSeconds;
      
      SUB( LALAvgDetectorVel ( &status, vel, &velPar), &status );
      velV.data[j].x= vel[0];
      velV.data[j].y= vel[1];
      velV.data[j].z= vel[2];   
    }  
  }

  /* set grid spacings */
  {
    deltaTheta = 1.0 / ( VTOT * uvar_f0 * timeBase );
    /* currently unused: REAL8 deltaFdot = deltaF / timeBase; */
  }

  /* allocate memory for f(t) pattern */
  foft.length = mObsCoh;
  foft.data = NULL;
  foft.data = (REAL8 *)LALMalloc(mObsCoh*sizeof(REAL8));

  /* allocate memory for Hough peripsd structure */
  periPSD.periodogram.length = sftlength;
  periPSD.periodogram.data = NULL;
  periPSD.periodogram.data = (REAL8 *)LALMalloc(sftlength* sizeof(REAL8));
  periPSD.psd.length = sftlength;
  periPSD.psd.data = NULL;
  periPSD.psd.data = (REAL8 *)LALMalloc(sftlength* sizeof(REAL8));

  /* allocate memory for peakgram */
  pg1.length = sftlength;
  pg1.data = NULL;
  pg1.data = (UCHAR *)LALMalloc(sftlength* sizeof(UCHAR));

  /* generate signal and add to input sfts */  
  /* parameters for output sfts */
  sftParams.Tsft = timeBase;
  sftParams.timestamps = &(timeV);
  sftParams.noiseSFTs = inputSFTs;  
  
  /* signal generation parameters */
  params.orbit.asini = 0 /* isolated pulsar */;
  /* params.transferFunction = NULL; */
  params.site = &(detector);
  params.ephemerides = edat;
  params.startTimeGPS.gpsSeconds = timeV.data[0].gpsSeconds;   /* start time of output time series */
  params.startTimeGPS.gpsNanoSeconds = timeV.data[0].gpsNanoSeconds;   /* start time of output time series */
  params.duration = timeDiffV.data[mObsCoh-1] + 0.5 * timeBase; /* length of time series in seconds */
  params.samplingRate = tSamplingRate;
  params.fHeterodyne = fHeterodyne;
  /* reference time for frequency and spindown is first timestamp */
  params.pulsar.refTime.gpsSeconds = timeV.data[0].gpsSeconds; 
  params.pulsar.refTime.gpsNanoSeconds = timeV.data[0].gpsNanoSeconds;

  params.pulsar.position.longitude = pulsarInject.longitude;
  params.pulsar.position.latitude = pulsarInject.latitude ;
  params.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; 
  params.pulsar.psi = pulsarInject.psi;
  params.pulsar.aPlus = pulsarInject.aPlus;
  params.pulsar.aCross = pulsarInject.aCross;
  params.pulsar.phi0 = pulsarInject.phi0;
  params.pulsar.f0 = pulsarInject.f0;
  params.pulsar.spindown = &pulsarInject.spindown ;

  SUB( LALGeneratePulsarSignal(&status, &signalTseries, &params ), &status);
  SUB( LALSignalToSFTs(&status, &outputSFTs, signalTseries, &sftParams), &status); 

  
  /* fill in elements of sft structure sft1 used in peak selection */
  sft1.length = sftlength;
  sft1.fminBinIndex = sftFminBin;
  sft1.timeBase = timeBase;

  /* loop over mismatched templates */
  for (mmT = -2; mmT <= 2; mmT++)
    { 
      for (mmP = -2; mmP <= 2; mmP++)
	{
	  INT4 mmFactor;
	  
	  /* displace the template */
	  mmFactor = 1.0;
	  pulsarTemplate1.f0 = pulsarTemplate.f0 /*+ mmFactor * mm * deltaF*/; 
	  pulsarTemplate1.latitude = pulsarTemplate.latitude + mmFactor * mmT * deltaTheta;
	  pulsarTemplate1.longitude = pulsarTemplate.longitude + mmFactor * mmP * deltaTheta;
	  pulsarTemplate1.spindown.data[0] = pulsarTemplate.spindown.data[0] /*+ mmFactor * mm * deltaFdot*/;
	  
	  numberCount = 0;
	  /* now calculate the number count for the template */
          INT4 j;
	  for (j=0; j < mObsCoh; j++)  
	    {
	      INT4 ind;
	      
	      sft1.epoch.gpsSeconds = timeV.data[j].gpsSeconds;
	      sft1.epoch.gpsNanoSeconds = timeV.data[j].gpsNanoSeconds;
	      sft1.data = outputSFTs->data[j].data->data;
	      
	      SUB( COMPLEX8SFT2Periodogram1(&status, &periPSD.periodogram, &sft1), &status );	
	      
	      SUB( LALPeriodo2PSDrng( &status, 
				      &periPSD.psd, &periPSD.periodogram, &uvar_blocksRngMed), &status );	
	      
	      SUB( LALSelectPeakColorNoise(&status,&pg1,&threshold,&periPSD), &status); 	 
	      
	      SUB( ComputeFoft(&status, &foft, &pulsarTemplate1, &timeDiffV, &velV, timeBase), &status);
	      
	      ind = floor( foft.data[j]*timeBase - sftFminBin + 0.5); 
	      
	      numberCount += pg1.data[ind]; 
	    } 
	  /* print the number count */
	  fprintf(stdout, "%d    %d    %d\n", mmT, mmP, numberCount);
	}
    }
  
  /* free structures created by signal generation routines */
  LALFree(signalTseries->data->data);
  LALFree(signalTseries->data);
  LALFree(signalTseries);
  signalTseries =NULL;
  XLALDestroySFTVector( outputSFTs);

  /* destroy input sfts */
  XLALDestroySFTVector( inputSFTs);

  /* free other structures */
  LALFree(foft.data);  
  LALFree(pulsarInject.spindown.data);
  LALFree(pulsarTemplate.spindown.data);
  LALFree(pulsarTemplate1.spindown.data);
  LALFree(timeV.data);
  LALFree(timeDiffV.data);
  LALFree(velV.data);
  XLALDestroyEphemerisData(edat);
  LALFree(periPSD.periodogram.data);
  LALFree(periPSD.psd.data);

  LALFree(pg1.data);

  XLALDestroyUserVars();  
  LALCheckMemoryLeaks();
  
  INFO( DRIVEHOUGHCOLOR_MSGENORM );
  return DRIVEHOUGHCOLOR_ENORM;
}