Exemplo n.º 1
0
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 );

  if (uvar.help) {   /* exit if help was required */
    exit(0);
  }

  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() */
Exemplo n.º 2
0
/**
 * @brief Seeks a LALFrStream stream to data at a given time
 * @details
 * The position of a LALFrStream is set so that the net read will
 * be at the specified time.  #LAL_FR_STREAM_END and #LAL_FR_STREAM_GAP
 * bits are turned off in the #LALFrStreamState state.  If the time is before
 * the beginning of the stream, the stream position is set to the beginning of
 * the stream and the routine returns with code 1.  If the time is after the
 * end of the stream, the #LAL_FR_STREAM_END bit is set in the
 * #LALFrStreamState state, and the routine returns with code 2.  If the time
 * is in a gap in the data, the #LAL_FR_STREAM_GAP bit is set in the
 * #LALFrStreamState state, the position is advanced to the next data, and the
 * routine returns with code 3.  If, however, the
 * #LAL_FR_STREAM_IGNORETIME_MODE bit is not set in the LALFrStreamMode mode
 * then these conditions result in an error.
 * @param stream Pointer to a #LALFrStream structure.
 * @param epoch The LIGOTimeGPS time of the next data to read.
 * @retval 3 Time requested is in a gap in the data.
 * @retval 2 Time requested is after the end of the stream.
 * @retval 1 Time requested is before the beginning of the stream.
 * @retval 0 Normal success.
 * @retval <0 Failure.
 */
int XLALFrStreamSeek(LALFrStream * stream, const LIGOTimeGPS * epoch)
{
    double twant = XLALGPSGetREAL8(epoch);
    LALCacheEntry *entry;

    /* close file if one is open */
    XLALFrStreamFileClose(stream);

    /* clear EOF or GAP states; preserve ERR state */
    if (stream->state & LAL_FR_STREAM_ERR)
        stream->state = LAL_FR_STREAM_ERR;
    else
        stream->state = LAL_FR_STREAM_OK;

    /* is epoch before first file? */
    if (epoch->gpsSeconds < stream->cache->list->t0) {
        XLALFrStreamRewind(stream);
        stream->state |= LAL_FR_STREAM_GAP;
        /* is this reported as an error? */
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
            /* FIXME:  if this is an error, should the stream state say so? */
            /* stream->state |= LAL_FR_STREAM_ERR; */
            XLAL_ERROR(XLAL_ETIME);
        }
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %d before first frame",
                epoch->gpsSeconds);
        return 1;       /* before first file code */
    }

    /* seek for the time in the cache */
    entry = XLALCacheEntrySeek(stream->cache, twant);
    if (!entry) {       /* seek failed: only happens if time is past end of cache */
        stream->fnum = stream->cache->length;
        stream->epoch = *epoch;
        stream->state |= LAL_FR_STREAM_END;
        /* is this reported as an error? */
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
            /* FIXME:  if this is an error, should the stream state say so? */
            /* stream->state |= LAL_FR_STREAM_ERR; */
            XLAL_ERROR(XLAL_ETIME);
        }
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %d after last frame",
                epoch->gpsSeconds);
        return 2;       /* after last file code */
    }

    /* now we must find the position within the frame file */
    for (stream->fnum = entry - stream->cache->list;
        stream->fnum < stream->cache->length; ++stream->fnum) {
        /* check the file contents to determine the position that matches */
        size_t nFrame;
        if (XLALFrStreamFileOpen(stream, stream->fnum) < 0)
            XLAL_ERROR(XLAL_EFUNC);
        if (epoch->gpsSeconds < stream->cache->list[stream->fnum].t0) {
            /* detect a gap between files */
            stream->state |= LAL_FR_STREAM_GAP;
            break;
        }
        nFrame = XLALFrFileQueryNFrame(stream->file);
        for (stream->pos = 0; stream->pos < (int)nFrame; ++stream->pos) {
            LIGOTimeGPS start;
            int cmp;
            XLALFrFileQueryGTime(&start, stream->file, stream->pos);
            cmp = XLALGPSCmp(epoch, &start);
            if (cmp >= 0
                && XLALGPSDiff(epoch,
                    &start) < XLALFrFileQueryDt(stream->file, stream->pos))
                break;  /* this is the frame! */
            if (cmp < 0) {
                /* detect a gap between frames within a file */
                stream->state |= LAL_FR_STREAM_GAP;
                break;
            }
        }
        if (stream->pos < (int)nFrame)  /* we've found the frame */
            break;
        /* oops... not in this frame file, go on to the next one */
        /* probably the frame file was mis-named.... */
        XLALFrStreamFileClose(stream);
    }

    if (stream->fnum >= stream->cache->length) {
        /* we've gone right to the end without finding it! */
        stream->fnum = stream->cache->length;
        stream->epoch = *epoch;
        stream->state |= LAL_FR_STREAM_END;
        /* is this reported as an error? */
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
            /* FIXME:  if this is an error, should the stream state say so? */
            /* stream->state |= LAL_FR_STREAM_ERR; */
            XLAL_ERROR(XLAL_ETIME);
        }
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %d after last frame",
                epoch->gpsSeconds);
        return 2;       /* after last file code */
    }

    /* set the time of the stream */
    if (stream->state & LAL_FR_STREAM_GAP) {
        XLALFrFileQueryGTime(&stream->epoch, stream->file, stream->pos);
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %.6f in gap in frame data",
                twant);
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE))
            XLAL_ERROR(XLAL_ETIME);
        return 3;       /* in a gap code */
    }
    stream->epoch = *epoch;
    return 0;
}
Exemplo n.º 3
0
/** The main function of Intermittent.c
 *
 */
int main( int argc, char *argv[] )  {

  UserInput_t uvar = empty_UserInput;           /* user input variables */
  INT4 i,k,m;                                     /* counter */
  CHAR newtemp[LONGSTRINGLENGTH];
  FILE *ifp = NULL;
  CHAR *clargs = NULL;                          /* store the command line args */

  /**********************************************************************************/
  /* register and read all user-variables */
  if (XLALReadUserVars(argc,argv,&uvar)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALReadUserVars() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  if (uvar.verbose) fprintf(stdout,"%s : read in uservars\n",__func__);

  /**********************************************************************************/
  /* make temporary directory */
  if (uvar.tempdir) {

    /* initialise the random number generator  - use the clock */
    gsl_rng * q;
    if (XLALInitgslrand(&q,0)) {
      LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno);
      XLAL_ERROR(XLAL_EFAULT);
    }

    INT4 id = (INT4)(1e9*gsl_rng_uniform(q));
    sprintf(newtemp,"%s/%09d",uvar.tempdir,id);
    fprintf(stdout,"temp dir = %s\n",newtemp);
    if (mkdir(newtemp,0755)) {
      if (uvar.verbose) fprintf(stdout,"%s : Unable to make temporary directory %s.  Might be a problem.\n",__func__,newtemp);
      return 1;
    }
  }

  /**********************************************************************************/
  /* read in the cache file and find the correct entry for the binary file */
  FILE *cachefp = NULL;
  if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) {
    LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile);
    return 1;
  }
  i = 0;
  INT4 idx = -1;
  CHAR filename[LONGSTRINGLENGTH];
  CHAR dummy[LONGSTRINGLENGTH];
  LIGOTimeGPS fileStart;
  INT4 dummysec = 0;
  INT4 dummynan = 0;
  while (fscanf(cachefp,"%s %d %d",dummy,&dummysec,&dummynan)!=EOF) {
    if (strstr(dummy,uvar.binfile)) {
      idx = i;
      strcpy(filename,dummy);
      fileStart.gpsSeconds = dummysec;
      fileStart.gpsNanoSeconds = (INT4)1e9*(floor(1e-9*dummynan/uvar.tsamp + 0.5)*uvar.tsamp);    /* round to make sure we get samples at GPS seconds */
    }
  i++;
  }
  if (idx < 0) {
    LogPrintf(LOG_CRITICAL,"%s : failed to find binary input file %s in cache file %s\n",__func__,filename,uvar.cachefile);
    return 1;
  }
  fclose(cachefp);
  if (uvar.verbose) fprintf(stdout,"%s : found the requested binary file entry in the cache file.\n",__func__);

  /***********************************************************************************/
  /* setup the fixed binaryToSFT parameters */
  BinaryToSFTparams par;
  par.tsamp = uvar.tsamp;
  par.highpassf = uvar.highpassf;
  par.amp_inj = 0.0;
  par.f_inj = 0.0;
  par.asini_inj = 0.0;
  XLALGPSSetREAL8(&(par.tasc_inj),0);
  par.tref = fileStart;
  par.P_inj = 0;
  par.phi_inj = 0;
  par.r = NULL;

  /* setup the gridding over coherent times - which we make sure are integers */
  INT4 dummyT = uvar.Tmin;
  INT4 NT = 0;
  while (dummyT<uvar.Tmax) {
    dummyT = (INT4)((REAL8)dummyT*(1.0 + uvar.mismatch));
    NT++;
  }
  if (uvar.verbose) fprintf(stdout,"%s : Going to do %d different coherent lengths.\n",__func__,NT);

  /**********************************************************************************/
  /* OPEN INTERMEDIATE RESULTS FILE */
  /**********************************************************************************/
  CHAR intname[LONGSTRINGLENGTH];
  if (XLALOpenIntermittentResultsFile(&ifp,intname,newtemp,clargs,&uvar,&fileStart)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALOpenCoherentResultsFile() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  if (uvar.verbose) fprintf(stdout,"%s : opened coherent results file %s.\n",__func__,intname);

  /**********************************************************************************/
  /* loop over the different coherent lengths */
  INT4 currentT = uvar.Tmin;
  for (i=0;i<NT;i++) {

    if (uvar.verbose) fprintf(stdout,"%s : working on segment length %d/%d using a segment time of %d sec\n",__func__,i,NT,currentT);

    /* define SFT frequency bounds */
    REAL8 wings = LAL_TWOPI*uvar.maxasini/uvar.minorbperiod;
    REAL8 fmin_read = MINBAND*floor((uvar.freq - WINGS_FACTOR*uvar.freq*wings - (REAL8)uvar.blocksize/(REAL8)uvar.Tmin)/MINBAND);
    REAL8 fmax_read = MINBAND*ceil((uvar.freq + (REAL8)uvar.blocksize/(REAL8)uvar.Tmin + uvar.freqband + WINGS_FACTOR*(uvar.freq + uvar.freqband)*wings)/MINBAND);
    REAL8 fband_read = fmax_read - fmin_read;
    if (uvar.verbose) fprintf(stdout,"%s : reading in SFT frequency band [%f -> %f]\n",__func__,fmin_read,fmax_read);

    /* define the number of different start times */
    INT4 Ns = ceil(1.0/uvar.mismatch);
    INT4 Tstep = (INT4)floor(currentT/(REAL8)Ns);
    if (Tstep == 0) Ns = 1;
    else Ns = (INT4)ceil((REAL8)currentT/(REAL8)Tstep);
    if (uvar.verbose) fprintf(stdout,"%s : number of start times is %d and time step is %d sec\n",__func__,Ns,Tstep);
    par.tsft = currentT;
    par.freq = fmin_read;
    par.freqband = fband_read;

    /* loop over different start times - make sure they are integer GPS time for simplicity */
    LIGOTimeGPS currentStart;
    currentStart.gpsSeconds = (INT4)ceil((REAL8)fileStart.gpsSeconds + 1e-9*(REAL8)fileStart.gpsNanoSeconds);
    currentStart.gpsNanoSeconds = 0;
    for (k=0;k<Ns;k++) {

      if (uvar.verbose) fprintf(stdout,"%s : working on offset start %d/%d using a start time of %d %d sec\n",__func__,k,Ns,currentStart.gpsSeconds,currentStart.gpsNanoSeconds);
      memcpy(&(par.tstart),&currentStart,sizeof(LIGOTimeGPS));

      ParameterSpace pspace = empty_ParameterSpace;   /* the search parameter space */
      COMPLEX8TimeSeriesArray *dstimevec = NULL;      /* contains the downsampled inverse FFT'd SFTs */
      REAL4DemodulatedPowerVector *dmpower = NULL;   /* contains the demodulated power for all SFTs */
      GridParametersVector *freqgridparams = NULL; /* the coherent grid on the frequency derivitive parameter space */
      SFTVector *sftvec = NULL;
      INT8Vector *np = NULL;
      REAL8Vector *R = NULL;

      /**********************************************************************************/
      /* GENERATE SFTS FROM BINARY INPUT FILE */
      /**********************************************************************************/

      /* converts a binary input file into sfts */
      if (XLALBinaryToSFTVector(&sftvec,filename,&fileStart,&par,&np,&R)) {
        LogPrintf(LOG_CRITICAL,"%s : failed to convert binary input file %s to sfts\n",__func__,uvar.binfile);
        return 1;
      }
      XLALDestroyINT8Vector(np);
      XLALDestroyREAL8Vector(R);
      if (uvar.verbose) fprintf(stdout,"%s : generated SFTs for file %s\n",__func__,filename);

      /* if we have any SFTs */
      if (sftvec->length>0) {

        /* define SFT length and the start and span of the observations plus the definitive segment time */
        pspace.tseg = 1.0/sftvec->data[0].deltaF;
        memcpy(&(pspace.epoch),&(sftvec->data[0].epoch),sizeof(LIGOTimeGPS));
        pspace.span = XLALGPSDiff(&(sftvec->data[sftvec->length-1].epoch),&(sftvec->data[0].epoch)) + pspace.tseg;
        if (uvar.verbose) {
	  fprintf(stdout,"%s : SFT length = %f seconds\n",__func__,pspace.tseg);
 	  fprintf(stdout,"%s : entire dataset starts at GPS time %d contains %d SFTS and spans %.0f seconds\n",__func__,pspace.epoch.gpsSeconds,sftvec->length,pspace.span);
        }

        /**********************************************************************************/
        /* NORMALISE THE SFTS */
        /**********************************************************************************/

        /* compute the background noise using the sfts - this routine uses the running median at the edges to normalise the wings */
        if (XLALNormalizeSFTVect(sftvec,uvar.blocksize, 0)) {
    	  LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVect() failed with error = %d\n",__func__,xlalErrno);
          return 1;
        }
        if (uvar.verbose) fprintf(stdout,"%s : normalised the SFTs\n",__func__);

        /**********************************************************************************/
        /* DEFINE THE BINARY PARAMETER SPACE */
        /**********************************************************************************/

        /* define the binary parameter space */
        if (XLALDefineBinaryParameterSpace(&(pspace.space),pspace.epoch,pspace.span,&uvar)) {
          LogPrintf(LOG_CRITICAL,"%s : XLALDefineBinaryParameterSpace() failed with error = %d\n",__func__,xlalErrno);
          return 1;
        }
        if (uvar.verbose) fprintf(stdout,"%s : defined binary parameter prior space\n",__func__);

        /**********************************************************************************/
        /* COMPUTE THE COARSE GRID ON FREQUENCY DERIVITIVES */
        /**********************************************************************************/

        /* compute the grid parameters for all SFTs */
        if (XLALComputeFreqGridParamsVector(&freqgridparams,pspace.space,sftvec,uvar.mismatch)) {
          LogPrintf(LOG_CRITICAL,"%s : XLALComputeFreqGridParams() failed with error = %d\n",__func__,xlalErrno);
          return 1;
        }
        if (uvar.verbose) fprintf(stdout,"%s : computed the grid parameters for the sfts\n",__func__);

        /**********************************************************************************/
        /* CONVERT ALL SFTS TO DOWNSAMPLED TIMESERIES */
        /**********************************************************************************/

        if (XLALSFTVectorToCOMPLEX8TimeSeriesArray(&dstimevec,sftvec)) {
          LogPrintf(LOG_CRITICAL,"%s : XLALSFTVectorToCOMPLEX8TimeSeriesArray() failed with error = %d\n",__func__,xlalErrno);
          return 1;
        }
        if (uvar.verbose) fprintf(stdout,"%s : converted SFTs to downsampled timeseries\n",__func__);

        /**********************************************************************************/
        /* COMPUTE THE STATISTICS ON THE COARSE GRID */
        /**********************************************************************************/

        /* compute the demodulated power on the frequency derivitive grid */
        if (XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector(&dmpower,dstimevec,freqgridparams,ifp)) {
          LogPrintf(LOG_CRITICAL,"%s : XLALCOMPLEX8TimeSeriesArrayToDemodPowerVector() failed with error = %d\n",__func__,xlalErrno);
          return 1;
        }
        if (uvar.verbose) fprintf(stdout,"%s : computed the demodulated power\n",__func__);

        /**********************************************************************************/
        /* FREE MEMORY */
        /**********************************************************************************/

        /* free memory inside the loop */
        XLALFreeParameterSpace(&pspace);
        XLALFreeREAL4DemodulatedPowerVector(dmpower);
        for (m=0;m<(INT4)dstimevec->length;m++) {
 	  XLALDestroyCOMPLEX8TimeSeries(dstimevec->data[m]);
        }
        XLALFree(dstimevec->data);
        XLALFree(dstimevec);
        for (m=0;m<(INT4)freqgridparams->length;m++) {
          XLALFree(freqgridparams->segment[m]->grid);
          XLALFree(freqgridparams->segment[m]->prod);
          XLALFree(freqgridparams->segment[m]);
        }
        XLALFree(freqgridparams->segment);
        XLALFree(freqgridparams);
        if (uvar.verbose) fprintf(stdout,"%s : freed memory\n",__func__);
        XLALDestroySFTVector(sftvec);

      } /* end if statement on whether we have SFTs */

      /* update the start time of the segment */
      XLALGPSAdd(&currentStart,(REAL8)Tstep);

    } /* end loop over start times */

    /* update segment length */
    currentT = (INT4)((REAL8)currentT*(1.0 + uvar.mismatch));

  }  /* end loop over segment lengths */

  /* move the temporary directory to the final location */
  if (uvar.tempdir) {
    CHAR newoutputfile[LONGSTRINGLENGTH];
    snprintf(newoutputfile,LONGSTRINGLENGTH,"%s/IntermittentResults-%s-%d.txt",uvar.outputdir,uvar.outLabel,fileStart.gpsSeconds);
    if (rename(intname,newoutputfile)) {
      LogPrintf(LOG_CRITICAL,"%s : unable to move final results file %s -> %s.  Exiting.\n",__func__,intname,newoutputfile);
      return 1;
    }
  }

  /**********************************************************************************/
  /* FREE MEMORY */
  /**********************************************************************************/
  fclose(ifp);

  LALCheckMemoryLeaks();

  return 0;

}
/**
 * Simulate a pulsar signal to best accuracy possible.
 * \author Reinhard Prix
 * \date 2005
 *
 * The motivation for this function is to provide functions to
 * simulate pulsar signals <em>with the best possible accuracy</em>,
 * i.e. using no approximations, contrary to LALGeneratePulsarSignal().
 *
 * Obviously this is not meant as a fast code to be used in a Monte-Carlo
 * simulation, but rather as a <em>reference</em> to compare other (faster)
 * functions agains, in order to be able to gauge the quality of a given
 * signal-generation routine.
 *
 * We want to calculate \f$h(t)\f$, given by
 * \f[
 * h(t) = F_+(t)\, h_+(t) + F_\times(t) \,h_\times(t)\,,
 * \f]
 * where \f$F_+\f$ and \f$F_x\f$ are called the <em>beam-pattern</em> functions,
 * which depend of the wave polarization \f$\psi\f$,
 * the source position \f$\alpha\f$, \f$\delta\f$ and the detector position and
 * orientation (\f$\gamma\f$, \f$\lambda\f$, \f$L\f$ and \f$\xi\f$). The expressions for
 * the beam-pattern functions are given in \cite JKS98 , which we write as
 * \f{eqnarray}{
 * F_+(t) = \sin \zeta \cos 2\psi \, a(t)  + \sin \zeta \sin 2\psi \, b(t)\,,\\
 * F_\times(t) = \sin\zeta  \cos 2\psi \,b(t) - \sin\zeta \sin 2\psi \, a(t) \,,
 * \f}
 * where \f$\zeta\f$ is the angle between the interferometer arms, and
 * \f{eqnarray}{
 * a(t) &=& a_1 \cos[ 2 (\alpha - T)) ] + a_2 \sin[ 2(\alpha - T)]
 * + a_3 \cos[ \alpha - T ] + a_4 \sin [ \alpha - T ] + a_5\,,\\
 * b(t) &=& b_1 \cos[ 2(\alpha - T)] + b_2 \sin[ 2(\alpha - T) ]
 * + b_3 \cos[ \alpha - T ] + b_4 \sin[ \alpha - T]\,,
 * \f}
 * where \f$T\f$ is the local (mean) sidereal time of the detector, and the
 * time-independent coefficients \f$a_i\f$ and \f$b_i\f$ are given by
 * \f{eqnarray}{
 * a_1 &=& \frac{1}{16} \sin 2\gamma \,(3- \cos 2\lambda)\,(3 - \cos 2\delta)\,,\\
 * a_2 &=& -\frac{1}{4}\cos 2\gamma \,\sin \lambda \,(3 - \cos 2\delta) \,,\\
 * a_3 &=& \frac{1}{4} \sin 2\gamma \,\sin 2\lambda \,\sin 2\delta  \,\\
 * a_4 &=& -\frac{1}{2} \cos 2\gamma \,\cos \lambda \,\sin 2 \delta\,,\\
 * a_5 &=& \frac{3}{4} \sin 2\gamma \, \cos^2 \lambda \,\cos^2 \delta\,,
 * \f}
 * and
 * \f{eqnarray}{
 * b_1 &=& \cos 2\gamma \,\sin \lambda \,\sin \delta\,,\\
 * b_2 &=& \frac{1}{4} \sin 2\gamma \,(3-\cos 2\lambda)\, \sin \delta\,,\\
 * b_3 &=& \cos 2\gamma \,\cos \lambda \,\cos\delta \,, \\
 * b_4 &=& \frac{1}{2} \sin2\gamma \,\sin 2\lambda \,\cos\delta\,,
 * \f}
 *
 * The source model considered is a plane-wave
 * \f{eqnarray}{
 * h_+(t) &=& A_+\, \cos \Psi(t)\,,\\
 * h_\times(t) &=& A_\times \, \sin \Psi(t)\,,
 * \f}
 * where the wave-phase is \f$\Psi(t) = \Phi_0 + \Phi(t)\f$, and for an
 * isolated pulsar we have
 * \f{equation}{
 * \Phi(t) = 2\pi \left[\sum_{s=0} \frac{f^{(s)}(\tau_\mathrm{ref})}{
 * (s+1)!} \left( \tau(t) - \tau_\mathrm{ref} \right)^{s+1} \right]\,,
 * \f}
 * where \f$\tau_\mathrm{ref}\f$ is the "reference time" for the definition
 * of the pulsar-parameters \f$f^{(s)}\f$ in the solar-system barycenter
 * (SSB), and \f$\tau(t)\f$ is the SSB-time of the phase arriving at the
 * detector at UTC-time \f$t\f$, which depends on the source-position
 * (\f$\alpha\f$, \f$\delta\f$) and the detector-position, namely
 * \f{equation}{
 * \tau (t) = t + \frac{ \vec{r}(t)\cdot\vec{n}}{c}\,,
 * \f}
 * where \f$\vec{r}(t)\f$ is the vector from SSB to the detector, and \f$\vec{n}\f$
 * is the unit-vector pointing <em>to</em> the source.
 *
 * This is a standalone "clean-room" implementation using no other
 * outside-functions <em>except</em> for LALGPStoLMST1() to calculate
 * the local (mean) sidereal time at the detector for given GPS-time,
 * (which I double-checked with an independent Mathematica script),
 * and and XLALBarycenter() to calculate \f$\tau(t)\f$.
 *
 * NOTE: currently only isolated pulsars are supported
 *
 * NOTE2: we don't really use the highest possible accuracy right now,
 * as we blatently neglect all relativistic timing effects (i.e. using dT=v.n/c)
 *
 * NOTE3: no heterodyning is performed here, the time-series is generated and sampled
 * at the given rate, that's all! ==\> the caller needs to make sure about the
 * right sampling rate to use (-\>aliasing) and do the proper post-treatment...
 *
 */
REAL4TimeSeries *
XLALSimulateExactPulsarSignal ( const PulsarSignalParams *params )
{
  XLAL_CHECK_NULL ( params != NULL, XLAL_EINVAL, "Invalid NULL input 'params'\n");
  XLAL_CHECK_NULL ( params->samplingRate > 0, XLAL_EDOM, "Sampling rate must be positive, got samplingRate = %g\n", params->samplingRate );

  /* don't accept heterodyning frequency */
  XLAL_CHECK_NULL ( params->fHeterodyne == 0, XLAL_EINVAL, "Heterodyning frequency must be set to 0, got params->fHeterodyne = %g\n", params->fHeterodyne );

  UINT4 numSpins = 3;

  /* get timestamps of timeseries plus detector-states */
  REAL8 dt = 1.0 / params->samplingRate;
  LIGOTimeGPSVector *timestamps;
  XLAL_CHECK_NULL ( (timestamps = XLALMakeTimestamps ( params->startTimeGPS, params->duration, dt, 0 )) != NULL, XLAL_EFUNC );

  UINT4 numSteps = timestamps->length;

  DetectorStateSeries *detStates = XLALGetDetectorStates ( timestamps, params->site, params->ephemerides, 0 );
  XLAL_CHECK_NULL ( detStates != NULL, XLAL_EFUNC, "XLALGetDetectorStates() failed.\n");

  XLALDestroyTimestampVector ( timestamps );
  timestamps = NULL;

  AMCoeffs *amcoe = XLALComputeAMCoeffs ( detStates, params->pulsar.position );
  XLAL_CHECK_NULL ( amcoe != NULL, XLAL_EFUNC, "XLALComputeAMCoeffs() failed.\n");

  /* create output timeseries (FIXME: should really know *detector* here, not just site!!) */
  const LALFrDetector *site = &(params->site->frDetector);
  CHAR *channel = XLALGetChannelPrefix ( site->name );
  XLAL_CHECK_NULL ( channel != NULL, XLAL_EFUNC, "XLALGetChannelPrefix( %s ) failed.\n", site->name );

  REAL4TimeSeries *ts = XLALCreateREAL4TimeSeries ( channel, &(detStates->data[0].tGPS), 0, dt, &emptyUnit, numSteps );
  XLAL_CHECK_NULL ( ts != NULL, XLAL_EFUNC, "XLALCreateREAL4TimeSeries() failed.\n");
  XLALFree ( channel );
  channel = NULL;

  /* orientation of detector arms */
  REAL8 xAzi = site->xArmAzimuthRadians;
  REAL8 yAzi = site->yArmAzimuthRadians;
  REAL8 Zeta =  xAzi - yAzi;
  if (Zeta < 0) {
    Zeta = -Zeta;
  }
  if ( params->site->type == LALDETECTORTYPE_CYLBAR ) {
    Zeta = LAL_PI_2;
  }
  REAL8 sinZeta = sin(Zeta);

  /* get source skyposition */
  REAL8 Alpha = params->pulsar.position.longitude;
  REAL8 Delta = params->pulsar.position.latitude;
  REAL8 vn[3];
  vn[0] = cos(Delta) * cos(Alpha);
  vn[1] = cos(Delta) * sin(Alpha);
  vn[2] = sin(Delta);

  /* get spin-parameters (restricted to maximally 3 spindowns right now) */
  REAL8 phi0 = params->pulsar.phi0;
  REAL8 f0   = params->pulsar.f0;

  REAL8 f1dot = 0, f2dot = 0, f3dot = 0;
  if ( params->pulsar.spindown && (params->pulsar.spindown->length > numSpins) ) {
    XLAL_ERROR_NULL ( XLAL_EDOM, "Currently only supports up to %d spindowns!\n", numSpins );
  }
  if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 3 ) ) {
    f3dot = params->pulsar.spindown->data[2];
  }
  if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 2 ) ) {
    f2dot = params->pulsar.spindown->data[1];
  }
  if ( params->pulsar.spindown && (params->pulsar.spindown->length >= 1 ) ) {
    f1dot = params->pulsar.spindown->data[0];
  }

  /* internally we always work with refTime = startTime->SSB, therefore
   * we need to translate the pulsar spin-params and initial phase to the
   * startTime
   */
  REAL8 startTimeSSB = XLALGPSGetREAL8 ( &(detStates->data[0].tGPS) ) + SCALAR ( vn, detStates->data[0].rDetector );
  REAL8 refTime;
  if ( params->pulsar.refTime.gpsSeconds != 0 )
    {
      REAL8 refTime0 = XLALGPSGetREAL8 ( &(params->pulsar.refTime) );
      REAL8 deltaRef = startTimeSSB - refTime0;
      LIGOTimeGPS newEpoch;
      PulsarSpins fkdotNew;

      XLALGPSSetREAL8( &newEpoch, startTimeSSB );

      PulsarSpins XLAL_INIT_DECL(fkdotOld);
      fkdotOld[0] = f0;
      fkdotOld[1] = f1dot;
      fkdotOld[2] = f2dot;
      fkdotOld[3] = f3dot;
      REAL8 DeltaTau = XLALGPSDiff ( &newEpoch, &(params->pulsar.refTime) );

      int ret = XLALExtrapolatePulsarSpins ( fkdotNew, fkdotOld, DeltaTau );
      XLAL_CHECK_NULL ( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALExtrapolatePulsarSpins() failed.\n");

      /* Finally, need to propagate phase */
      phi0 += LAL_TWOPI * (               f0    * deltaRef
			    + (1.0/2.0) * f1dot * deltaRef * deltaRef
			    + (1.0/6.0) * f2dot * deltaRef * deltaRef * deltaRef
			    + (1.0/24.0)* f3dot * deltaRef * deltaRef * deltaRef * deltaRef
			    );

      f0    = fkdotNew[0];
      f1dot = fkdotNew[1];
      f2dot = fkdotNew[2];
      f3dot = fkdotNew[3];

      refTime = startTimeSSB;

    } /* if refTime given */
  else  { /* if not given: use startTime -> SSB */
    refTime = startTimeSSB;
  }

  /* get 4 amplitudes A_\mu */
  REAL8 aPlus  = sinZeta * params->pulsar.aPlus;
  REAL8 aCross = sinZeta * params->pulsar.aCross;
  REAL8 twopsi = 2.0 * params->pulsar.psi;

  REAL8 A1 =  aPlus * cos(phi0) * cos(twopsi) - aCross * sin(phi0) * sin(twopsi);
  REAL8 A2 =  aPlus * cos(phi0) * sin(twopsi) + aCross * sin(phi0) * cos(twopsi);
  REAL8 A3 = -aPlus * sin(phi0) * cos(twopsi) - aCross * cos(phi0) * sin(twopsi);
  REAL8 A4 = -aPlus * sin(phi0) * sin(twopsi) + aCross * cos(phi0) * cos(twopsi);

  /* main loop: generate time-series */
  for ( UINT4 i = 0; i < numSteps; i++)
    {
      LIGOTimeGPS *tiGPS = &(detStates->data[i].tGPS);

      REAL8 ti = XLALGPSGetREAL8 ( tiGPS );
      REAL8 deltati = ti - refTime;
      REAL8 dT = SCALAR(vn, detStates->data[i].rDetector );
      REAL8 taui = deltati + dT;

      REAL8 phi_i = LAL_TWOPI * ( f0 * taui
			    + (1.0/2.0) * f1dot * taui*taui
			    + (1.0/6.0) * f2dot * taui*taui*taui
			    + (1.0/24.0)* f3dot * taui*taui*taui*taui
			    );

      REAL8 cosphi_i = cos(phi_i);
      REAL8 sinphi_i = sin(phi_i);

      REAL8 ai = amcoe->a->data[i];
      REAL8 bi = amcoe->b->data[i];

      REAL8 hi = A1 * ai * cosphi_i
	+  A2 * bi * cosphi_i
	+  A3 * ai * sinphi_i
	+  A4 * bi * sinphi_i;

      ts->data->data[i] = (REAL4)hi;

    } /* for i < numSteps */

  XLALDestroyDetectorStateSeries( detStates );
  XLALDestroyAMCoeffs ( amcoe );

  return ts;

} /* XLALSimulateExactPulsarSignal() */
Exemplo n.º 5
0
int
XLALOutputDopplerMetric ( FILE *fp, const DopplerPhaseMetric *Pmetric, const DopplerFstatMetric *Fmetric, const ResultHistory_t *history )
{
  UINT4 i;
  REAL8 A, B, C, D;

  // ----- input sanity checks
  XLAL_CHECK ( fp != NULL, XLAL_EFAULT );
  XLAL_CHECK ( Pmetric != NULL || Fmetric != NULL, XLAL_EFAULT );
  const DopplerMetricParams *meta = (Pmetric != NULL) ? &(Pmetric->meta) : &(Fmetric->meta);
  XLAL_CHECK ( XLALSegListIsInitialized ( &(meta->segmentList) ), XLAL_EINVAL, "Got un-initialized segment list in 'metric->meta.segmentList'\n" );
  UINT4 Nseg = meta->segmentList.length;
  XLAL_CHECK ( Nseg >= 1, XLAL_EDOM, "Got invalid zero-length segment list 'metric->meta.segmentList'\n" );

  /* useful shortcuts */
  const PulsarDopplerParams *doppler = &(meta->signalParams.Doppler);
  const PulsarAmplitudeParams *Amp = &(meta->signalParams.Amp);

  /* output history info */
  if ( history )
    {
      if ( history->app_name ) fprintf (fp, "%%%% app_name: %s\n", history->app_name );
      if ( history->cmdline) fprintf (fp, "%%%% commandline: %s\n", history->cmdline );
      if ( history->VCSInfoString ) fprintf (fp, "%%%% Code Version: %s\n", history->VCSInfoString );
    }

  fprintf ( fp, "DopplerCoordinates = { " );
  for ( i=0; i < meta->coordSys.dim; i ++ )
    {
      if ( i > 0 ) fprintf ( fp, ", " );
      fprintf ( fp, "\"%s\"", XLALDopplerCoordinateName(meta->coordSys.coordIDs[i]));
    }
  fprintf ( fp, "};\n");

  { /* output projection info */
    const char *pname;
    if ( meta->projectCoord < 0 )
      pname = "None";
    else
      pname = XLALDopplerCoordinateName ( meta->coordSys.coordIDs[meta->projectCoord] );

    fprintf ( fp, "%%%% Projection onto subspace orthogonal to coordinate: '%s'\n", pname);
  }

  fprintf ( fp, "%%%% DetectorMotionType = '%s'\n", XLALDetectorMotionName(meta->detMotionType) );
  fprintf ( fp, "h0 = %g;\ncosi = %g;\npsi = %g;\nphi0 = %g;\n", Amp->h0, Amp->cosi, Amp->psi, Amp->phi0 );
  fprintf ( fp, "%%%% DopplerPoint = {\n");
  fprintf ( fp, "refTime = %.1f;\n", XLALGPSGetREAL8 ( &doppler->refTime ) );
  fprintf ( fp, "Alpha   = %f;\nDelta = %f;\n", doppler->Alpha, doppler->Delta );
  fprintf ( fp, "fkdot   = [%f, %g, %g, %g ];\n", doppler->fkdot[0], doppler->fkdot[1], doppler->fkdot[2], doppler->fkdot[3] );
  if ( doppler->asini > 0 )
    {
      fprintf ( fp, "%%%% 	   orbit = { \n");
      fprintf ( fp, "%%%% 		tp = {%d, %d}\n", doppler->tp.gpsSeconds, doppler->tp.gpsNanoSeconds );
      fprintf ( fp, "%%%% 		argp  = %g\n", doppler->argp );
      fprintf ( fp, "%%%% 		asini = %g\n", doppler->asini );
      fprintf ( fp, "%%%% 		ecc = %g\n", doppler->ecc );
      fprintf ( fp, "%%%% 		period = %g\n", doppler->period );
      fprintf ( fp, "%%%% 	   }\n");
    } /* if doppler->orbit */
  fprintf ( fp, "%%%% }\n");

  LIGOTimeGPS *tStart = &(meta->segmentList.segs[0].start);
  LIGOTimeGPS *tEnd   = &(meta->segmentList.segs[Nseg-1].end);
  REAL8 Tspan = XLALGPSDiff ( tEnd, tStart );
  fprintf ( fp, "startTime = %.1f;\n", XLALGPSGetREAL8 ( tStart ) );
  fprintf ( fp, "Tspan     = %.1f;\n", Tspan );
  fprintf ( fp, "Nseg      = %d;\n", Nseg );
  fprintf ( fp, "detectors = {");
  for ( i=0; i < meta->multiIFO.length; i ++ )
    {
      if ( i > 0 ) fprintf ( fp, ", ");
      fprintf ( fp, "\"%s\"", meta->multiIFO.sites[i].frDetector.name );
    }
  fprintf ( fp, "};\n");
  fprintf ( fp, "detectorWeights = [");
  for ( i=0; i < meta->multiNoiseFloor.length; i ++ )
    {
      if ( i > 0 ) fprintf ( fp, ", ");
      fprintf ( fp, "%f", meta->multiNoiseFloor.sqrtSn[i] );
    }
  fprintf ( fp, "];\n");

  /* ----- output phase metric ---------- */
  if ( Pmetric != NULL )
    {
      fprintf ( fp, "\ng_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Pmetric->g_ij );
      fprintf ( fp, "maxrelerr_gPh = %.2e;\n", Pmetric->maxrelerr );

      gsl_matrix *gN_ij = NULL;
      if ( XLALNaturalizeMetric ( &gN_ij, NULL, Pmetric->g_ij, meta ) != XLAL_SUCCESS ) {
        XLALPrintError ("%s: something failed Naturalizing phase metric g_ij!\n", __func__ );
        XLAL_ERROR ( XLAL_EFUNC );
      }
      fprintf ( fp, "\ngN_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  gN_ij );
      gsl_matrix_free ( gN_ij );

      gsl_matrix *gDN_ij = NULL;
      if ( XLALDiagNormalizeMetric ( &gDN_ij, NULL, Pmetric->g_ij ) != XLAL_SUCCESS ) {
        XLALPrintError ("%s: something failed NormDiagonalizing phase metric g_ij!\n", __func__ );
        XLAL_ERROR ( XLAL_EFUNC );
      }
      fprintf ( fp, "\ngDN_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  gDN_ij );
      gsl_matrix_free ( gDN_ij );
    }

  /* ----- output F-metric (and related matrices ---------- */
  if ( Fmetric != NULL )
    {
      fprintf ( fp, "\ngF_ij = " );   XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Fmetric->gF_ij );
      fprintf ( fp, "\ngFav_ij = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Fmetric->gFav_ij );
      fprintf ( fp, "\nm1_ij = " );   XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Fmetric->m1_ij );
      fprintf ( fp, "\nm2_ij = " );   XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Fmetric->m2_ij );
      fprintf ( fp, "\nm3_ij = " );   XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Fmetric->m3_ij );
      fprintf ( fp, "maxrelerr_gF = %.2e;\n", Fmetric->maxrelerr );
    }

  /*  ----- output Fisher matrix ---------- */
  if ( Fmetric != NULL && Fmetric->Fisher_ab != NULL )
    {
      A = gsl_matrix_get ( Fmetric->Fisher_ab, 0, 0 );
      B = gsl_matrix_get ( Fmetric->Fisher_ab, 1, 1 );
      C = gsl_matrix_get ( Fmetric->Fisher_ab, 0, 1 );

      D = A * B - C * C;

      fprintf ( fp, "\nA = %.16g;\nB = %.16g;\nC = %.16g;\nD = %.16g;\n", A, B, C, D );
      fprintf ( fp, "\nrho2 = %.16g;\n", Fmetric->rho2 );

      fprintf (fp, "\nFisher_ab = " ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT,  Fmetric->Fisher_ab );
    }

  // ---------- output segment list at the end, as this can potentially become quite long and distracting
  char *seglist_octave;
  XLAL_CHECK ( (seglist_octave = XLALSegList2String ( &(meta->segmentList) )) != NULL, XLAL_EFUNC, "XLALSegList2String() with xlalErrno = %d\n", xlalErrno );
  fprintf ( fp, "\n\nsegmentList = %s;\n", seglist_octave );
  XLALFree ( seglist_octave );


  return XLAL_SUCCESS;

} /* XLALOutputDopplerMetric() */
Exemplo n.º 6
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() */
Exemplo n.º 7
0
/**
 * Wrapper to iterate over the entries in a sim_burst linked list and
 * inject them into a time series.  Passing NULL for the response disables
 * it (input time series is strain).
 */
int XLALBurstInjectSignals(
	REAL8TimeSeries *series,
	const SimBurst *sim_burst,
	const TimeSlide *time_slide_table_head,
	const COMPLEX16FrequencySeries *response
)
{
	/* to be deduced from the time series' channel name */
	const LALDetector *detector;
	/* FIXME:  fix the const entanglement so as to get rid of this */
	LALDetector detector_copy;
	/* + and x time series for injection waveform */
	REAL8TimeSeries *hplus = NULL;
	REAL8TimeSeries *hcross = NULL;
	/* injection time series as added to detector's */
	REAL8TimeSeries *h;
	/* skip injections whose geocentre times are more than this many
	 * seconds outside of the target time series */
	const double injection_window = 100.0;

	/* turn the first two characters of the channel name into a
	 * detector */

	detector = XLALDetectorPrefixToLALDetector(series->name);
	if(!detector)
		XLAL_ERROR(XLAL_EFUNC);
	XLALPrintInfo("%s(): channel name is '%s', instrument appears to be '%s'\n", __func__, series->name, detector->frDetector.prefix);
	detector_copy = *detector;

	/* iterate over injections */

	for(; sim_burst; sim_burst = sim_burst->next) {
		LIGOTimeGPS time_geocent_gps;
		const TimeSlide *time_slide_row;

		/* determine the offset to be applied to this injection */

		time_slide_row = XLALTimeSlideConstGetByIDAndInstrument(time_slide_table_head, sim_burst->time_slide_id, detector->frDetector.prefix);
		if(!time_slide_row) {
			XLALPrintError("%s(): cannot find time shift offset for injection 'sim_burst:simulation_id:%ld'.  need 'time_slide:time_slide_id:%ld' for instrument '%s'", __func__, sim_burst->simulation_id, sim_burst->time_slide_id, detector->frDetector.prefix);
			XLAL_ERROR(XLAL_EINVAL);
		}

		/* skip injections whose "times" are too far outside of the
		 * target time series */

		time_geocent_gps = sim_burst->time_geocent_gps;
		XLALGPSAdd(&time_geocent_gps, -time_slide_row->offset);
		if(XLALGPSDiff(&series->epoch, &time_geocent_gps) > injection_window || XLALGPSDiff(&time_geocent_gps, &series->epoch) > (series->data->length * series->deltaT + injection_window))
			continue;
		XLALPrintInfo("%s(): injection 'sim_burst:simulation_id:%ld' in '%s' at %d.%09u s (GPS) will be shifted by %.16g s to %d.%09u s (GPS)\n", __func__, sim_burst->simulation_id, series->name, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, -time_slide_row->offset, time_geocent_gps.gpsSeconds, time_geocent_gps.gpsNanoSeconds);

		/* construct the h+ and hx time series for the injection
		 * waveform. */

		if(XLALGenerateSimBurst(&hplus, &hcross, sim_burst, series->deltaT))
			XLAL_ERROR(XLAL_EFUNC);
#if 0
		{
		char name[100];
		FILE *f;
		unsigned i;
		sprintf(name, "%d.%09u_%s.txt", sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, series->name);
		f = fopen(name, "w");
		for(i = 0; i < hplus->data->length; i++) {
			LIGOTimeGPS t = hplus->epoch;
			XLALGPSAdd(&t, i * hplus->deltaT);
			fprintf(f, "%.16g %.16g %.16g\n", XLALGPSGetREAL8(&t), hplus->data->data[i], hcross->data->data[i]);
		}
		fclose(f);
		}
#endif

		/* project the wave onto the detector to produce the strain
		 * in the detector. */

		h = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross, sim_burst->ra, sim_burst->dec, sim_burst->psi, &detector_copy);
		XLALDestroyREAL8TimeSeries(hplus);
		XLALDestroyREAL8TimeSeries(hcross);
		hplus = hcross = NULL;
		if(!h)
			XLAL_ERROR(XLAL_EFUNC);

		/* shift the waveform by the time slide offset */

		XLALGPSAdd(&h->epoch, -time_slide_row->offset);
#if 0
		{
		char name[100];
		FILE *f;
		unsigned i;
		sprintf(name, "%d.%09u_%s.txt", sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, series->name);
		f = fopen(name, "w");
		for(i = 0; i < h->data->length; i++) {
			LIGOTimeGPS t = h->epoch;
			XLALGPSAdd(&t, i * h->deltaT);
			fprintf(f, "%d.%09u %.16g\n", t.gpsSeconds, t.gpsNanoSeconds, h->data->data[i]);
		}
		fclose(f);
		}
#endif

		/* add the injection strain time series to the detector
		 * data */

		if(XLALSimAddInjectionREAL8TimeSeries(series, h, response)) {
			XLALDestroyREAL8TimeSeries(h);
			XLAL_ERROR(XLAL_EFUNC);
		}
		XLALDestroyREAL8TimeSeries(h);
	}

	/* done */

	return 0;
}