/* ----- function definitions ---------- */
int
main (  void )
{
  LALStatus XLAL_INIT_DECL(status);
  SFTCatalog *catalog = NULL;
  SFTConstraints XLAL_INIT_DECL(constraints);
  MultiSFTVector *multiSFTs = NULL;
  MultiPSDVector *multiPSDs = NULL;
  MultiNoiseWeights *multiWeightsXLAL = NULL;
  MultiNoiseWeights *multiWeightsCorrect = NULL;
  UINT4 rngmedBins = 11;
  REAL8 tolerance = 2e-6;	/* same algorithm, should be basically identical results */

  /* Construct the "correct" weights, calculated using the old LAL routines */
  UINT4 numIFOsCorrect = 2;
  XLAL_CHECK ( ( multiWeightsCorrect = XLALCalloc ( 1, sizeof(*multiWeightsCorrect ) ) ) != NULL, XLAL_ENOMEM );
  multiWeightsCorrect->length = numIFOsCorrect;
  multiWeightsCorrect->Sinv_Tsft = 1.980867126449e+52;
  XLAL_CHECK ( ( multiWeightsCorrect->data = XLALCalloc ( numIFOsCorrect, sizeof(*multiWeightsCorrect->data ) ) ) != NULL, XLAL_ENOMEM );
  XLAL_CHECK ( ( multiWeightsCorrect->data[0] = XLALCreateREAL8Vector(4) ) != NULL, XLAL_ENOMEM );
  multiWeightsCorrect->data[0]->data[0] = 6.425160659487e-05;
  multiWeightsCorrect->data[0]->data[1] = 7.259453662367e-06;
  multiWeightsCorrect->data[0]->data[2] = 9.838893684664e-04;
  multiWeightsCorrect->data[0]->data[3] = 5.043766789923e-05;
  XLAL_CHECK ( ( multiWeightsCorrect->data[1] = XLALCreateREAL8Vector(3) ) != NULL, XLAL_ENOMEM );
  multiWeightsCorrect->data[1]->data[0] = 1.582309910283e-04;
  multiWeightsCorrect->data[1]->data[1] = 5.345673753744e-04;
  multiWeightsCorrect->data[1]->data[2] = 6.998201363537e+00;

  /* Construct the catalog */
  XLAL_CHECK ( ( catalog = XLALSFTdataFind ( TEST_DATA_DIR "MultiNoiseWeightsTest*.sft", &constraints ) ) != NULL, XLAL_EFUNC, " XLALSFTdataFind failed\n" );

  /* Load the SFTs */
  XLAL_CHECK ( ( multiSFTs = XLALLoadMultiSFTs ( catalog, -1, -1 ) ) != NULL, XLAL_EFUNC, " XLALLoadMultiSFTs failed\n" );

  /* calculate the psd and normalize the SFTs */
  XLAL_CHECK ( ( multiPSDs = XLALNormalizeMultiSFTVect ( multiSFTs, rngmedBins, NULL ) ) != NULL, XLAL_EFUNC, " XLALNormalizeMultiSFTVect failed\n" );

  /* Get weights using XLAL function */
  XLAL_CHECK ( ( multiWeightsXLAL = XLALComputeMultiNoiseWeights ( multiPSDs, rngmedBins, 0 ) ) != NULL, XLAL_EFUNC, " XLALComputeMultiNoiseWeights failed\n" );

  /* Compare XLAL weights to reference */
  XLAL_CHECK ( XLALCompareMultiNoiseWeights ( multiWeightsXLAL, multiWeightsCorrect, tolerance ) == XLAL_SUCCESS, XLAL_EFAILED, "Comparison between XLAL and reference MultiNoiseWeights failed\n" );

  /* Clean up memory */
  XLALDestroyMultiNoiseWeights ( multiWeightsCorrect );
  XLALDestroyMultiNoiseWeights ( multiWeightsXLAL );
  XLALDestroyMultiPSDVector ( multiPSDs );
  XLALDestroyMultiSFTVector ( multiSFTs );
  XLALDestroySFTCatalog ( catalog );
  /* check for memory-leaks */
  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} /* main() */
/** (Complex)Sinc-interpolate an input SFT to an output SFT.
 * This is a simple convenience wrapper to XLALSincInterpolateCOMPLEX8FrequencySeries()
 * for the special case of interpolating onto new SFT frequency bins
 */
SFTtype *
XLALSincInterpolateSFT ( const SFTtype *sft_in,		///< [in] input SFT
                              REAL8 f0Out,		///< [in] new start frequency
                              REAL8 dfOut,		///< [in] new frequency step-size
                              UINT4 numBinsOut,		///< [in] new number of bins
                              UINT4 Dterms		///< [in] truncate interpolation kernel sum to +-Dterms around max
                              )
{
  XLAL_CHECK_NULL ( sft_in != NULL, XLAL_EINVAL );
  XLAL_CHECK_NULL ( dfOut > 0, XLAL_EINVAL );
  XLAL_CHECK_NULL ( numBinsOut > 0, XLAL_EINVAL );

  // setup frequency vector
  REAL8Vector *f_out;
  XLAL_CHECK_NULL ( (f_out = XLALCreateREAL8Vector ( numBinsOut )) != NULL, XLAL_EFUNC );
  for ( UINT4 k = 0; k < numBinsOut; k ++ ) {
    f_out->data[k] = f0Out + k * dfOut;
  } // for k < numBinsOut

  SFTtype *out;
  XLAL_CHECK_NULL ( (out = XLALCalloc ( 1, sizeof(*out))) != NULL, XLAL_EFUNC );
  (*out) = (*sft_in);	// copy header
  out->f0 = f0Out;
  out->deltaF = dfOut;
  XLAL_CHECK_NULL ( (out->data = XLALCreateCOMPLEX8Vector ( numBinsOut )) != NULL, XLAL_EFUNC );

  XLAL_CHECK_NULL ( XLALSincInterpolateCOMPLEX8FrequencySeries ( out->data, f_out, sft_in, Dterms ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLALDestroyREAL8Vector ( f_out );

  return out;

} // XLALSincInterpolateSFT()
int XLALSQTPNAllocateCoherentGW(CoherentGW *wave, UINT4 length) {

	if (!wave) {
		XLAL_ERROR(XLAL_EFAULT);
	}
	if (length <= 0) {
		XLAL_ERROR(XLAL_EBADLEN);
	}
	if (wave->a || wave->f || wave->phi || wave->shift) {
		XLAL_ERROR(XLAL_EFAULT);
	}
	wave->a = (REAL4TimeVectorSeries *)LALMalloc(sizeof(REAL4TimeVectorSeries));
	wave->f = (REAL4TimeSeries *)LALMalloc(sizeof(REAL4TimeSeries));
	wave->phi = (REAL8TimeSeries *)LALMalloc(sizeof(REAL8TimeSeries));
	wave->shift = (REAL4TimeSeries *)LALMalloc(sizeof(REAL4TimeSeries));
	if (!(wave->a && wave->f && wave->phi && wave->shift)) {
		XLALSQTPNDestroyCoherentGW(wave);
		XLAL_ERROR(XLAL_ENOMEM);
	}
	xlalErrno = 0;
	wave->a->data = XLALCreateREAL4VectorSequence(length, 2);
	wave->f->data = XLALCreateREAL4Vector(length);
	wave->phi->data = XLALCreateREAL8Vector(length);
	wave->shift->data = XLALCreateREAL4Vector(length);
	if (!(wave->a->data && wave->f->data && wave->phi->data && wave->shift->data)) {
		XLALSQTPNDestroyCoherentGW(wave);
		XLAL_ERROR(XLAL_ENOMEM);
	}
	return XLAL_SUCCESS;
}
示例#4
0
/**
 * Function for interpolating PSD to a given sample rate
 */
REAL8FrequencySeries *
XLALInterpolatePSD( REAL8FrequencySeries *in,      /**< input strain time series */
                    REAL8                deltaFout /**< sample rate of time series */)
{
  REAL8FrequencySeries *ret=NULL;
  REAL8 deltaFin, r, y_1, y_2;
  UINT4 k, lo, numPoints;

  deltaFin = in->deltaF;

  /* length of output vector */
  numPoints = (UINT4) (in->data->length * deltaFin / deltaFout);

  /* allocate memory */
  ret = LALCalloc(1, sizeof(*ret));
  if (!ret)
  {
    XLAL_ERROR_NULL( XLAL_ENOMEM );
  }

  ret->data = XLALCreateREAL8Vector( numPoints );
  if (! ret->data)
  {
    XLAL_ERROR_NULL( XLAL_ENOMEM );
  }

  ret->deltaF = deltaFout;

  /* copy values from in which should be the same */
  ret->epoch       = in->epoch;
  ret->f0          = in->f0;
  ret->sampleUnits = in->sampleUnits;
  strcpy(ret->name, in->name);

  /* go over points of output vector and interpolate linearly
     using closest points of input */
  for (k = 0; k < numPoints; k++) {
    lo = (UINT4)( k*deltaFout / deltaFin);

    /* y_1 and y_2 are the input values at x1 and x2 */
    /* here we need to make sure that we don't exceed
       bounds of input vector */
    if ( lo < in->data->length - 1) {
      y_1 = in->data->data[lo];
      y_2 = in->data->data[lo+1];

      /* we want to calculate y_2*r + y_1*(1-r) where
         r = (x-x1)/(x2-x1) */
      r = k*deltaFout / deltaFin - lo;

      ret->data->data[k] = y_2 * r + y_1 * (1 - r);
    }
    else {
      ret->data->data[k] = 0.0;
    }
  }

  return ret;
}
UNUSED static UINT4 XLALSimInspiralNRWaveformGetDataFromHDF5File(
  UNUSED REAL8Vector** output,            /**< Returned vector uncompressed */
  UNUSED LALH5File* pointer,              /**< Pointer to HDF5 file */
  UNUSED REAL8 totalMass,                 /**< Total mass of system for scaling */
  UNUSED REAL8 startTime,                 /**< Start time of veturn vector */
  UNUSED size_t length,                   /**< Length of returned vector */
  UNUSED REAL8 deltaT,                    /**< Sample rate of returned vector */
  UNUSED const char *keyName              /**< Name of vector to uncompress */
  )
{
  #ifndef LAL_HDF5_ENABLED
  XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled");
  #else
  UINT4 idx;
  size_t comp_data_length;
  REAL8 massTime;
  gsl_interp_accel *acc;
  gsl_spline *spline;
  gsl_vector *knotsVector, *dataVector;
  LALH5File *group = XLALH5GroupOpen(pointer, keyName);
  knotsVector=dataVector=NULL;

  ReadHDF5RealVectorDataset(group, "X", &knotsVector);
  ReadHDF5RealVectorDataset(group, "Y", &dataVector);

  *output = XLALCreateREAL8Vector(length);

  comp_data_length = dataVector->size;
  /* SPLINE STUFF */
  acc = gsl_interp_accel_alloc();
  spline = gsl_spline_alloc(gsl_interp_cspline, comp_data_length);
  gsl_spline_init(spline, knotsVector->data, dataVector->data,
                  comp_data_length);

  for (idx = 0; idx < length; idx++)
  {
    massTime = (startTime + idx*deltaT) / (totalMass * LAL_MTSUN_SI);
    /* This if statement is used to catch the case where massTime at idx=0
     * ends up at double precision smaller than the first point in the
     * interpolation. In this case set it back to exactly the first point.
     * Sanity checking that we are not trying to use data below the
     * interpolation range is done elsewhere.
     */
    if ((idx == 0) && (massTime < knotsVector->data[0]))
    {
      massTime = knotsVector->data[0];
    }
    (*output)->data[idx] = gsl_spline_eval(spline, massTime, acc);
  }

  gsl_vector_free(knotsVector);
  gsl_vector_free(dataVector);
  gsl_spline_free (spline);
  gsl_interp_accel_free (acc);

  return XLAL_SUCCESS;
  #endif
}
int main( int argc, char *argv[]) {


  /* sanity check for input arguments */
  if ( argc != 1 )
    XLAL_ERROR ( XLAL_EINVAL, "The executable '%s' doesn't support any input arguments right now.\n", argv[0] );

  printf ("Starting test...\n");

  /* set up single- and multi-IFO F-stat input */
  REAL4 TwoF = 7.0;
  UINT4 numDetectors = 2;
  REAL4Vector *TwoFX = NULL;
  if ( (TwoFX = XLALCreateREAL4Vector ( numDetectors )) == NULL ) {
    XLAL_ERROR ( XLAL_EFUNC, "failed to XLALCreateREAL4Vector( %d )\n", numDetectors );
    return XLAL_EFAILED;
  }
  TwoFX->data[0] = 4.0;
  TwoFX->data[1] = 12.0;
  REAL8 rhomaxline = 0.0; /* prior from LV-stat derivation, 0 means pure line veto, +inf means pure multi-Fstat */
  REAL8Vector *lX = NULL; /* per-IFO prior odds ratio for line vs. Gaussian noise, NULL is interpreted as l[X]=1 for all X */

  /* maximum allowed difference between recalculated and XLAL result */
  REAL4 tolerance_allterms = 2e-04;
  REAL4 tolerance_leadterm = 2e-02;

  /* compute and compare the results for one set of rhomaxline, lX values */
  printf ("Computing LV-stat for TwoF_multi=%f, TwoFX[0]=%f, TwoFX[1]=%f, rhomaxline=%f, priors lX=NULL...\n", TwoF, TwoFX->data[0], TwoFX->data[1], rhomaxline );
  if ( XLALCompareLVComputations( TwoF, TwoFX, rhomaxline, lX, tolerance_allterms, tolerance_leadterm ) != XLAL_SUCCESS ) {
    XLAL_ERROR ( XLAL_EFUNC, "Test failed.\n" );
    return XLAL_EFAILED;
  }

  /* change the priors to catch more possible problems */
  rhomaxline = 5.0;
  if ( (lX = XLALCreateREAL8Vector ( numDetectors )) == NULL ) {
    XLAL_ERROR ( XLAL_EFUNC, "failed to XLALCreateREAL8Vector( %d )\n", numDetectors );
    return XLAL_EFAILED;
  }
  lX->data[0] = 0.5;
  lX->data[1] = 0.8;

  /* compute and compare the results for second set of rhomaxline, lX values */
  printf ("Computing LV-stat for TwoF_multi=%f, TwoFX[0]=%f, TwoFX[1]=%f, rhomaxline=%f, priors lX=(%f,%f)...\n", TwoF, TwoFX->data[0], TwoFX->data[1], rhomaxline, lX->data[0], lX->data[1] );
  if ( XLALCompareLVComputations( TwoF, TwoFX, rhomaxline, lX, tolerance_allterms, tolerance_leadterm ) != XLAL_SUCCESS ) {
    XLAL_ERROR ( XLAL_EFUNC, "Test failed.\n" );
    return XLAL_EFAILED;
  }

  /* free memory */
  XLALDestroyREAL4Vector(TwoFX);
  XLALDestroyREAL8Vector(lX);

  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;
} /* main */
示例#7
0
MultiNoiseWeights *
XLALComputeConstantMultiNoiseWeightsFromNoiseFloor ( const MultiNoiseFloor *multiNoiseFloor,	/**< [in] noise floor values sqrt(S) for all detectors */
                                                     const MultiLIGOTimeGPSVector *multiTS,	/**< [in] timestamps vectors for all detectors, only needed for their lengths */
                                                     const UINT4 Tsft				/**< [in] length of SFTs in secons, needed for normalization factor Sinv_Tsft */
                                                     )
{

  /* check input parameters */
  XLAL_CHECK_NULL ( multiNoiseFloor != NULL, XLAL_EINVAL );
  XLAL_CHECK_NULL ( multiTS != NULL, XLAL_EINVAL );
  UINT4 numDet = multiNoiseFloor->length;
  XLAL_CHECK_NULL ( numDet == multiTS->length, XLAL_EINVAL, "Inconsistent length between multiNoiseFloor (%d) and multiTimeStamps (%d) structs.\n", numDet, multiTS->length );

  /* create multi noise weights for output */
  MultiNoiseWeights *multiWeights = NULL;
  XLAL_CHECK_NULL ( (multiWeights = XLALCalloc(1, sizeof(*multiWeights))) != NULL, XLAL_ENOMEM, "Failed call to XLALCalloc ( 1, %zu )\n", sizeof(*multiWeights) );
  XLAL_CHECK_NULL ( (multiWeights->data = XLALCalloc(numDet, sizeof(*multiWeights->data))) != NULL, XLAL_ENOMEM, "Failed call to XLALCalloc ( %d, %zu )\n", numDet, sizeof(*multiWeights->data) );
  multiWeights->length = numDet;

  REAL8 sqrtSnTotal = 0;
  UINT4 numSFTsTotal = 0;
  for (UINT4 X = 0; X < numDet; X++) { /* first loop over detectors: compute total noise floor normalization */
    sqrtSnTotal  += multiTS->data[X]->length / SQ ( multiNoiseFloor->sqrtSn[X] ); /* actually summing up 1/Sn, not sqrtSn yet */
    numSFTsTotal += multiTS->data[X]->length;
  }
  sqrtSnTotal = sqrt ( numSFTsTotal / sqrtSnTotal ); /* SnTotal = harmonicMean{S_X} assuming per-detector stationarity */

  for (UINT4 X = 0; X < numDet; X++) { /* second loop over detectors: compute the weights */

    /* compute per-IFO weights */
    REAL8 noise_weight_X = SQ(sqrtSnTotal/multiNoiseFloor->sqrtSn[X]); /* w_Xalpha = S_Xalpha^-1/S^-1 = S / S_Xalpha */

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

    /* loop over SFT timestamps and use same weights for all */
    for ( UINT4 alpha = 0; alpha < multiTS->data[X]->length; alpha++) {
      multiWeights->data[X]->data[alpha] = noise_weight_X;
    }

  } /* for X < numDet */

  multiWeights->Sinv_Tsft = Tsft / SQ ( sqrtSnTotal );

  return multiWeights;

} /* XLALComputeConstantMultiNoiseWeightsFromNoiseFloor() */
UNUSED static UINT4 XLALSimInspiralNRWaveformGetDataFromHDF5File(
  UNUSED REAL8Vector** output,            /**< Returned vector uncompressed */
  UNUSED LALH5File* pointer,              /**< Pointer to HDF5 file */
  UNUSED REAL8 totalMass,                 /**< Total mass of system for scaling */
  UNUSED REAL8 startTime,                 /**< Start time of veturn vector */
  UNUSED size_t length,                   /**< Length of returned vector */
  UNUSED REAL8 deltaT,                    /**< Sample rate of returned vector */
  UNUSED const char *keyName              /**< Name of vector to uncompress */
  )
{
  #ifndef LAL_HDF5_ENABLED
  XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled");
  #else
  UINT4 idx;
  size_t comp_data_length;
  REAL8 massTime;
  gsl_interp_accel *acc;
  gsl_spline *spline;
  gsl_vector *knotsVector, *dataVector;
  LALH5File *group = XLALH5GroupOpen(pointer, keyName);
  knotsVector=dataVector=NULL;

  ReadHDF5RealVectorDataset(group, "knots", &knotsVector);
  ReadHDF5RealVectorDataset(group, "data", &dataVector);

  *output = XLALCreateREAL8Vector(length);

  comp_data_length = dataVector->size;
  /* SPLINE STUFF */
  acc = gsl_interp_accel_alloc();
  spline = gsl_spline_alloc(gsl_interp_cspline, comp_data_length);
  gsl_spline_init(spline, knotsVector->data, dataVector->data,
                  comp_data_length);

  for (idx = 0; idx < length; idx++)
  {
    massTime = (startTime + idx*deltaT) / (totalMass * LAL_MTSUN_SI);
    (*output)->data[idx] = gsl_spline_eval(spline, massTime, acc);
  }

  gsl_vector_free(knotsVector);
  gsl_vector_free(dataVector);
  gsl_spline_free (spline);
  gsl_interp_accel_free (acc);

  return XLAL_SUCCESS;
  #endif
}
/*--------------main function---------------*/
int main(int argc, char **argv){
  const CHAR *fn = __func__;

  InputParams XLAL_INIT_DECL(inputs);

  REAL8 srate = 16384.0; /*sample rate defaulted to 16384 */

  /* read in command line input args */
  ReadInput( &inputs, argc, argv );

  LALStatus XLAL_INIT_DECL(status);

  EphemerisData *edat;
  if ( (edat = InitEphemeris ( inputs.ephemType, inputs.ephemDir)) == NULL ){
    XLALPrintError ( "%s: Failed to init ephemeris data\n", fn );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  /*init detector info */
  LALDetector *site;
  if ( ( site = XLALGetSiteInfo ( inputs.det )) == NULL ){
    XLALPrintError("%s: Failed to get site-info for detector '%s'\n", fn,
                   inputs.det );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  if( inputs.geocentre ){ /* set site to the geocentre */
    site->location[0] = 0.0;
    site->location[1] = 0.0;
    site->location[2] = 0.0;
  }

  struct dirent **pulsars;
  INT4 n=scandir(inputs.pulsarDir, &pulsars, 0, alphasort);
  if ( n < 0){
    XLALPrintError("scandir failed\n");
    XLAL_ERROR(XLAL_EIO);
  }

  UINT4 numpulsars = (UINT4)n;
  UINT4 h=0;

  CHAR parname[256];
  PulsarParameters *pulparams[numpulsars];

  for(h=2; h<numpulsars; h++){
    if(strstr(pulsars[h]->d_name,".par") == NULL){
      free(pulsars[h]);
      continue;
    }
    else{
      sprintf(parname,"%s/%s", inputs.pulsarDir, pulsars[h]->d_name);
      fprintf(stderr, "%s\n", parname);
      FILE *inject;

      if (( inject = fopen ( parname, "r" )) == NULL ){
        fprintf(stderr,"Error opening file: %s\n", parname);
        XLAL_ERROR ( XLAL_EIO );
      }

      pulparams[h] = XLALReadTEMPOParFile( parname );

      fclose( inject );
    }
  }
  LIGOTimeGPS epoch;

  UINT4 ndata;

  epoch.gpsSeconds = inputs.epoch;
  epoch.gpsNanoSeconds = 0;

  ndata = inputs.frDur;

  REAL8TimeSeries *series=NULL;

  CHAR out_file[256];
  sprintf(out_file, "%s-%s-%d-%d.gwf", inputs.det, inputs.outStr,
          epoch.gpsSeconds, ndata );

  LALFrameH *outFrame = NULL;

  if ((outFrame = XLALFrameNew( &epoch, (REAL8)ndata, inputs.channel, 1, 0,
       0 )) == NULL) {
    LogPrintf(LOG_CRITICAL, "%s : XLALFrameNew() filed with error = %d.\n", fn, xlalErrno);
    XLAL_ERROR( XLAL_EFAILED);
  }

  if ((series = XLALCreateREAL8TimeSeries( inputs.channel, &epoch, 0.,
    1./srate,&lalSecondUnit, (int)(ndata*srate) )) == NULL) {
    XLAL_ERROR( XLAL_EFUNC );
  }

  UINT4 counter=0;
  for (counter = 0; counter < series->data->length; counter++)
    series->data->data[counter] = 0;

  /*** Read Pulsar Data ***/
  for (h=0; h < numpulsars; h++){
    if(strstr(pulsars[h]->d_name,".par")==NULL){
      free(pulsars[h]);
      continue;
    }
    else{
      PulsarSignalParams XLAL_INIT_DECL(params);

      /* set signal generation barycenter delay look-up table step size */
      params.dtDelayBy2 = 10.; /* generate table every 10 seconds */

      if (( params.pulsar.spindown = XLALCreateREAL8Vector(1)) == NULL ){
        XLALPrintError("Out of memory");
        XLAL_ERROR ( XLAL_EFUNC );
      }

      INT4 dtpos = 0;
      if ( PulsarCheckParam(pulparams[h], "POSEPOCH") )
        dtpos = epoch.gpsSeconds - (INT4)PulsarGetREAL8Param(pulparams[h], "POSEPOCH");
      else
        dtpos = epoch.gpsSeconds - (INT4)PulsarGetREAL8Param(pulparams[h], "PEPOCH");

      REAL8 ra = 0., dec = 0.;
      if ( PulsarCheckParam( pulparams[h], "RAJ" ) ) {
        ra = PulsarGetREAL8Param( pulparams[h], "RAJ" );
      }
      else if ( PulsarCheckParam( pulparams[h], "RA" ) ){
        ra = PulsarGetREAL8Param( pulparams[h], "RA" );
      }
      else{
        XLALPrintError("No right ascension found");
        XLAL_ERROR ( XLAL_EFUNC );
      }
      if ( PulsarCheckParam( pulparams[h], "DECJ" ) ) {
        dec = PulsarGetREAL8Param( pulparams[h], "DECJ" );
      }
      else if ( PulsarCheckParam( pulparams[h], "DEC" ) ){
        dec = PulsarGetREAL8Param( pulparams[h], "DEC" );
      }
      else{
        XLALPrintError("No declination found");
        XLAL_ERROR ( XLAL_EFUNC );
      }

      params.pulsar.position.latitude = dec + (REAL8)dtpos * PulsarGetREAL8ParamOrZero(pulparams[h], "PMDEC");
      params.pulsar.position.longitude = ra + (REAL8)dtpos * PulsarGetREAL8ParamOrZero(pulparams[h], "PMRA") / cos(params.pulsar.position.latitude);
      params.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL;

      REAL8Vector *fs = PulsarGetREAL8VectorParam(pulparams[h], "F");
      if ( fs->length == 0 ){
        XLALPrintError("No frequencies found");
        XLAL_ERROR ( XLAL_EFUNC );
      }

      params.pulsar.f0 = 2.*fs->data[0];
      if ( fs->length > 1 ){
        params.pulsar.spindown->data[0] = 2.*fs->data[1];
      }
      if (( XLALGPSSetREAL8(&(params.pulsar.refTime), PulsarGetREAL8Param(pulparams[h], "PEPOCH")) ) == NULL )
        XLAL_ERROR ( XLAL_EFUNC );
      params.pulsar.psi = PulsarGetREAL8ParamOrZero(pulparams[h], "PSI");
      params.pulsar.phi0 = PulsarGetREAL8ParamOrZero(pulparams[h], "PHI0");
      REAL8 cosiota = PulsarGetREAL8ParamOrZero(pulparams[h], "COSIOTA");
      REAL8 h0 = PulsarGetREAL8ParamOrZero(pulparams[h], "H0");
      params.pulsar.aPlus = 0.5 * h0 * (1. + cosiota * cosiota );
      params.pulsar.aCross = h0 * cosiota;

      /*Add binary later if needed!*/

      params.site = site;
      params.ephemerides = edat;
      params.startTimeGPS = epoch;
      params.duration = ndata;
      params.samplingRate = srate;
      params.fHeterodyne = 0.;

      REAL4TimeSeries *TSeries = NULL;

      LALGeneratePulsarSignal( &status, &TSeries, &params );

      if (status.statusCode){
        fprintf(stderr, "LAL Routine failed!\n");
        XLAL_ERROR (XLAL_EFAILED);
      }
      UINT4 i;
      for (i=0; i < TSeries->data->length; i++)
        series->data->data[i] += TSeries->data->data[i];

      XLALDestroyREAL4TimeSeries(TSeries);
      XLALDestroyREAL8Vector(params.pulsar.spindown);
    }
  }

  if (XLALFrameAddREAL8TimeSeriesProcData(outFrame,series)){
      LogPrintf(LOG_CRITICAL, "%s : XLALFrameAddREAL8TimeSeries() failed with error = %d.\n",fn,xlalErrno);
      XLAL_ERROR(XLAL_EFAILED);
  }

  CHAR OUTFILE[256];
  sprintf(OUTFILE, "%s/%s", inputs.outDir, out_file);

  if (  XLALFrameWrite(outFrame, OUTFILE)){
    LogPrintf(LOG_CRITICAL, "%s : XLALFrameWrite() failed with error = %d.\n", fn, xlalErrno);
    XLAL_ERROR( XLAL_EFAILED );
  }

  XLALFrameFree(outFrame);
  XLALDestroyREAL8TimeSeries( series );

  return 0;
}
/**
 * The main workhorse function for performing the ringdown attachment for EOB
 * models EOBNRv2 and SEOBNRv1. This is the function which gets called by the
 * code generating the full IMR waveform once generation of the inspiral part
 * has been completed.
 * The ringdown is attached using the hybrid comb matching detailed in
 * The method is describe in Sec. II C of Pan et al. PRD 84, 124052 (2011),
 * specifically Eqs. 30 - 32.. Further details of the
 * implementation of the found in the DCC document T1100433.
 * In SEOBNRv1, the last physical overtone is replace by a pseudoQNM. See
 * Taracchini et al. PRD 86, 024011 (2012) for details.
 * STEP 1) Get mass and spin of the final black hole and the complex ringdown frequencies
 * STEP 2) Based on least-damped-mode decay time, allocate memory for rigndown waveform
 * STEP 3) Get values and derivatives of inspiral waveforms at matching comb points
 * STEP 4) Solve QNM coefficients and generate ringdown waveforms
 * STEP 5) Stitch inspiral and ringdown waveoforms
 */
static INT4 XLALSimIMREOBHybridAttachRingdown(
  REAL8Vector *signal1,    /**<< OUTPUT, Real of inspiral waveform to which we attach ringdown */
  REAL8Vector *signal2,    /**<< OUTPUT, Imag of inspiral waveform to which we attach ringdown */
  const INT4   l,          /**<< Current mode l */
  const INT4   m,          /**<< Current mode m */
  const REAL8  dt,         /**<< Sample time step (in seconds) */
  const REAL8  mass1,      /**<< First component mass (in Solar masses) */
  const REAL8  mass2,      /**<< Second component mass (in Solar masses) */
  const REAL8  spin1x,     /**<<The spin of the first object; only needed for spin waveforms */
  const REAL8  spin1y,     /**<<The spin of the first object; only needed for spin waveforms */
  const REAL8  spin1z,     /**<<The spin of the first object; only needed for spin waveforms */
  const REAL8  spin2x,     /**<<The spin of the second object; only needed for spin waveforms */
  const REAL8  spin2y,     /**<<The spin of the second object; only needed for spin waveforms */
  const REAL8  spin2z,     /**<<The spin of the second object; only needed for spin waveforms */
  REAL8Vector *timeVec,    /**<< Vector containing the time values */
  REAL8Vector *matchrange, /**<< Time values chosen as points for performing comb matching */
  Approximant  approximant /**<<The waveform approximant being used */
  )
{

      COMPLEX16Vector *modefreqs;
      UINT4 Nrdwave;
      UINT4 j;

      UINT4 nmodes;
      REAL8Vector		*rdwave1;
      REAL8Vector		*rdwave2;
      REAL8Vector		*rinspwave;
      REAL8Vector		*dinspwave;
      REAL8Vector		*ddinspwave;
      REAL8VectorSequence	*inspwaves1;
      REAL8VectorSequence	*inspwaves2;
      REAL8 eta, a, NRPeakOmega22; /* To generate pQNM frequency */
      REAL8 mTot; /* In geometric units */
      REAL8 spin1[3] = { spin1x, spin1y, spin1z };
      REAL8 spin2[3] = { spin2x, spin2y, spin2z };
      REAL8 finalMass, finalSpin;

      mTot  = (mass1 + mass2) * LAL_MTSUN_SI;
      eta       = mass1 * mass2 / ( (mass1 + mass2) * (mass1 + mass2) );

      /*
       * STEP 1) Get mass and spin of the final black hole and the complex ringdown frequencies
       */

      /* Create memory for the QNM frequencies */
      nmodes = 8;
      modefreqs = XLALCreateCOMPLEX16Vector( nmodes );
      if ( !modefreqs )
      {
        XLAL_ERROR( XLAL_ENOMEM );
      }

      if ( XLALSimIMREOBGenerateQNMFreqV2( modefreqs, mass1, mass2, spin1, spin2, l, m, nmodes, approximant ) == XLAL_FAILURE )
      {
        XLALDestroyCOMPLEX16Vector( modefreqs );
        XLAL_ERROR( XLAL_EFUNC );
      }

      /* Call XLALSimIMREOBFinalMassSpin() to get mass and spin of the final black hole */
      if ( XLALSimIMREOBFinalMassSpin(&finalMass, &finalSpin, mass1, mass2, spin1, spin2, approximant) == XLAL_FAILURE )
      {
        XLAL_ERROR( XLAL_EFUNC );
      }

      if ( approximant == SEOBNRv1 )
      {
          /* Replace the last QNM with pQNM */
          /* We assume aligned/antialigned spins here */
          a  = (spin1[2] + spin2[2]) / 2. * (1.0 - 2.0 * eta) + (spin1[2] - spin2[2]) / 2. * (mass1 - mass2) / (mass1 + mass2);
          NRPeakOmega22 = GetNRSpinPeakOmega( l, m, eta, a ) / mTot;
          /*printf("a and NRomega in QNM freq: %.16e %.16e %.16e %.16e %.16e\n",spin1[2],spin2[2],
                 mTot/LAL_MTSUN_SI,a,NRPeakOmega22*mTot);*/
          modefreqs->data[7] = (NRPeakOmega22/finalMass + creal(modefreqs->data[0])) / 2.;
          modefreqs->data[7] += I * 10./3. * cimag(modefreqs->data[0]);
      }

      /*for (j = 0; j < nmodes; j++)
      {
        printf("QNM frequencies: %d %d %d %e %e\n",l,m,j,modefreqs->data[j].re*mTot,1./modefreqs->data[j].im/mTot);
      }*/

      /* Ringdown signal length: 10 times the decay time of the n=0 mode */
      Nrdwave = (INT4) (EOB_RD_EFOLDS / cimag(modefreqs->data[0]) / dt);

      /* Check the value of attpos, to prevent memory access problems later */
      if ( matchrange->data[0] * mTot / dt < 5 || matchrange->data[1]*mTot/dt > matchrange->data[2] *mTot/dt - 2 )
      {
        XLALPrintError( "More inspiral points needed for ringdown matching.\n" );
        //printf("%.16e,%.16e,%.16e\n",matchrange->data[0] * mTot / dt, matchrange->data[1]*mTot/dt, matchrange->data[2] *mTot/dt - 2);
        XLALDestroyCOMPLEX16Vector( modefreqs );
        XLAL_ERROR( XLAL_EFAILED );
      }

      /*
       * STEP 2) Based on least-damped-mode decay time, allocate memory for rigndown waveform
       */

      /* Create memory for the ring-down and full waveforms, and derivatives of inspirals */

      rdwave1 = XLALCreateREAL8Vector( Nrdwave );
      rdwave2 = XLALCreateREAL8Vector( Nrdwave );
      rinspwave = XLALCreateREAL8Vector( 6 );
      dinspwave = XLALCreateREAL8Vector( 6 );
      ddinspwave = XLALCreateREAL8Vector( 6 );
      inspwaves1 = XLALCreateREAL8VectorSequence( 3, 6 );
      inspwaves2 = XLALCreateREAL8VectorSequence( 3, 6 );

      /* Check memory was allocated */
      if ( !rdwave1 || !rdwave2 || !rinspwave || !dinspwave 
	   || !ddinspwave || !inspwaves1 || !inspwaves2 )
      {
        XLALDestroyCOMPLEX16Vector( modefreqs );
        if (rdwave1)    XLALDestroyREAL8Vector( rdwave1 );
        if (rdwave2)    XLALDestroyREAL8Vector( rdwave2 );
        if (rinspwave)  XLALDestroyREAL8Vector( rinspwave );
        if (dinspwave)  XLALDestroyREAL8Vector( dinspwave );
        if (ddinspwave) XLALDestroyREAL8Vector( ddinspwave );
        if (inspwaves1) XLALDestroyREAL8VectorSequence( inspwaves1 );
        if (inspwaves2) XLALDestroyREAL8VectorSequence( inspwaves2 );
        XLAL_ERROR( XLAL_ENOMEM );
      }

      memset( rdwave1->data, 0, rdwave1->length * sizeof( REAL8 ) );
      memset( rdwave2->data, 0, rdwave2->length * sizeof( REAL8 ) );

      /*
       * STEP 3) Get values and derivatives of inspiral waveforms at matching comb points
       */

      /* Generate derivatives of the last part of inspiral waves */
      /* Get derivatives of signal1 */
      if ( XLALGenerateHybridWaveDerivatives( rinspwave, dinspwave, ddinspwave, timeVec, signal1, 
			matchrange, dt, mass1, mass2 ) == XLAL_FAILURE )
      {
        XLALDestroyCOMPLEX16Vector( modefreqs );
        XLALDestroyREAL8Vector( rdwave1 );
        XLALDestroyREAL8Vector( rdwave2 );
        XLALDestroyREAL8Vector( rinspwave );
        XLALDestroyREAL8Vector( dinspwave );
        XLALDestroyREAL8Vector( ddinspwave );
        XLALDestroyREAL8VectorSequence( inspwaves1 );
        XLALDestroyREAL8VectorSequence( inspwaves2 );
        XLAL_ERROR( XLAL_EFUNC );
      }
      for (j = 0; j < 6; j++)
      {
	    inspwaves1->data[j] = rinspwave->data[j];
	    inspwaves1->data[j + 6] = dinspwave->data[j];
	    inspwaves1->data[j + 12] = ddinspwave->data[j];
      }

      /* Get derivatives of signal2 */
      if ( XLALGenerateHybridWaveDerivatives( rinspwave, dinspwave, ddinspwave, timeVec, signal2, 
			matchrange, dt, mass1, mass2 ) == XLAL_FAILURE )
      {
        XLALDestroyCOMPLEX16Vector( modefreqs );
        XLALDestroyREAL8Vector( rdwave1 );
        XLALDestroyREAL8Vector( rdwave2 );
        XLALDestroyREAL8Vector( rinspwave );
        XLALDestroyREAL8Vector( dinspwave );
        XLALDestroyREAL8Vector( ddinspwave );
        XLALDestroyREAL8VectorSequence( inspwaves1 );
        XLALDestroyREAL8VectorSequence( inspwaves2 );
        XLAL_ERROR( XLAL_EFUNC );
      }
      for (j = 0; j < 6; j++)
      {
	    inspwaves2->data[j] = rinspwave->data[j];
	    inspwaves2->data[j + 6] = dinspwave->data[j];
	    inspwaves2->data[j + 12] = ddinspwave->data[j];
      }


      /*
       * STEP 4) Solve QNM coefficients and generate ringdown waveforms
       */

      /* Generate ring-down waveforms */
      if ( XLALSimIMREOBHybridRingdownWave( rdwave1, rdwave2, dt, mass1, mass2, inspwaves1, inspwaves2,
			  modefreqs, matchrange ) == XLAL_FAILURE )
      {
        XLALDestroyCOMPLEX16Vector( modefreqs );
        XLALDestroyREAL8Vector( rdwave1 );
        XLALDestroyREAL8Vector( rdwave2 );
        XLALDestroyREAL8Vector( rinspwave );
        XLALDestroyREAL8Vector( dinspwave );
        XLALDestroyREAL8Vector( ddinspwave );
        XLALDestroyREAL8VectorSequence( inspwaves1 );
        XLALDestroyREAL8VectorSequence( inspwaves2 );
        XLAL_ERROR( XLAL_EFUNC );
      }

      /*
       * STEP 5) Stitch inspiral and ringdown waveoforms
       */

      /* Generate full waveforms, by stitching inspiral and ring-down waveforms */
      UINT4 attachIdx = matchrange->data[1] * mTot / dt;
      for (j = 1; j < Nrdwave; ++j)
      {
	    signal1->data[j + attachIdx] = rdwave1->data[j];
	    signal2->data[j + attachIdx] = rdwave2->data[j];
      }

      memset( signal1->data+Nrdwave+attachIdx, 0, (signal1->length - Nrdwave - attachIdx)*sizeof(REAL8) );
      memset( signal2->data+Nrdwave+attachIdx, 0, (signal2->length - Nrdwave - attachIdx)*sizeof(REAL8) );

      /* Free memory */
      XLALDestroyCOMPLEX16Vector( modefreqs );
      XLALDestroyREAL8Vector( rdwave1 );
      XLALDestroyREAL8Vector( rdwave2 );
      XLALDestroyREAL8Vector( rinspwave );
      XLALDestroyREAL8Vector( dinspwave );
      XLALDestroyREAL8Vector( ddinspwave );
      XLALDestroyREAL8VectorSequence( inspwaves1 );
      XLALDestroyREAL8VectorSequence( inspwaves2 );

      return XLAL_SUCCESS;
}
/**
 * Calculate the derivative of the Hamiltonian w.r.t. a specific parameter
 * Used by generic spin EOB model, including initial conditions solver.
 */
static REAL8 XLALSpinHcapExactDerivWRTParam(
                                            const INT4 paramIdx,      /**<< Index of the parameters */
                                            const REAL8 values[],     /**<< Dynamical variables */
                                            SpinEOBParams *funcParams /**<< SEOB Parameters */
                                            )
{
  REAL8 result;

  REAL8Vector *sigmaKerr = funcParams->sigmaKerr;
  REAL8Vector *sigmaStar = funcParams->sigmaStar;
  SpinEOBHCoeffs *coeffs = funcParams->seobCoeffs;
  REAL8Vector *s1Vec = funcParams->s1Vec;
  REAL8Vector *s2Vec = funcParams->s2Vec;
  REAL8Vector *x=NULL;
  REAL8Vector *p=NULL;
  /* Note that this function is called a limited number of times in the initial condition setup,
   * so no worries about the below memory allocations slowing the code... at this point. */
  x=XLALCreateREAL8Vector(3);
  p=XLALCreateREAL8Vector(3);
  memcpy(x->data,&values[0],3*sizeof(REAL8));
  memcpy(p->data,&values[3],3*sizeof(REAL8));

  REAL8 eta = funcParams->eobParams->eta;
  REAL8 e3z = (0.0 <= sigmaKerr->data[2]) - (sigmaKerr->data[2] < 0.0); // This is a modified sign function: e3z = 1 if sigmaKerr->data[2]>=0, -1 otherwise

  /* Now calculate derivatives w.r.t. the required parameter */
  if (funcParams->tortoise==1){
    if (paramIdx==4){
#include "mathematica_codes/SEOBNRv2_opt_dp1tortoise.h"
      result = dHdp1/eta;
    } else if (paramIdx==3){
#include "mathematica_codes/SEOBNRv2_opt_dp0tortoise.h"
      result = dHdp0/eta;
    } else if (paramIdx==5){
#include "mathematica_codes/SEOBNRv2_opt_dp2tortoise.h"
      result = dHdp2/eta;
    } else if (paramIdx==0){
#include "mathematica_codes/SEOBNRv2_opt_dx0tortoise.h"
      result = dHdx0/eta;
    } else {
      XLAL_ERROR( XLAL_EFUNC );
    }
  }else if(funcParams->tortoise==0) {
    if (paramIdx==4){
#include "mathematica_codes/SEOBNRv2_opt_dp1.h"
      result = dHdp1/eta;
    } else if (paramIdx==3){
#include "mathematica_codes/SEOBNRv2_opt_dp0.h"
      result = dHdp0/eta;
    } else if (paramIdx==5){
#include "mathematica_codes/SEOBNRv2_opt_dp2.h"
      result = dHdp2/eta;
    } else if (paramIdx==0){
#include "mathematica_codes/SEOBNRv2_opt_dx0.h"
      result = dHdx0/eta;
    } else {
      XLAL_ERROR( XLAL_EFUNC );
    }
  } else {
      XLAL_ERROR( XLAL_EFUNC );
  }
  XLALDestroyREAL8Vector(x);
  XLALDestroyREAL8Vector(p);

  return result;
}
示例#12
0
 outputfile detector ephemerisfile\n");
    return 0;
  }

  sprintf(psrInput, "%s", argv[1]);
  sprintf(inputFile, "%s", argv[2]);
  sprintf(outputFile, "%s", argv[3]);
  sprintf(detName, "%s", argv[4]);
  input.filename = argv[5]; /* ephemeris file */

  /* read in Crab pulsar parameters used in heterodyning */
  XLALReadTEMPOParFile(&pulsarParams, psrInput);

  /* allocate memory for crab ephemeris */
  crabEphemerisData.f1 = NULL;
  crabEphemerisData.f1 = XLALCreateREAL8Vector(NUM);

  crabEphemerisData.f0 = NULL;
  crabEphemerisData.f0 = XLALCreateREAL8Vector(NUM);

  crabEphemerisData.tArr = NULL;
  crabEphemerisData.tArr = XLALCreateREAL8Vector(NUM);

  crabOutput.tArr = NULL;
  crabOutput.tArr = XLALCreateREAL8Vector(NUM);

  crabOutput.f0 = NULL;
  crabOutput.f0 = XLALCreateREAL8Vector(NUM);

  crabOutput.f1 = NULL;
  crabOutput.f1 = XLALCreateREAL8Vector(NUM);
示例#13
0
int main(int argc, char **argv)
{
    FILE *fp  = NULL;
    FILE *fp2 = NULL;
    FILE *fp3 = NULL;
    FILE *fp4 = NULL;
    LALStatus status = blank_status;
    
    SFTCatalog *catalog = NULL;
    SFTVector *sft_vect = NULL;
    INT4 i,j,k,l;
    INT4 numBins, nSFT;
    SFTConstraints constraints=empty_SFTConstraints;
    LIGOTimeGPS startTime, endTime; 
    REAL8 avg =0;
    REAL4 *timeavg =NULL;
    REAL4 PWR,SNR;
    REAL8 f =0;
    CHAR outbase[256],outfile[256],outfile2[256],outfile3[256], outfile4[256]; /*, outfile6[256]; */
    REAL8 NumBinsAvg =0;
    REAL8 timebaseline =0;
    
    BOOLEAN help = 0;
    CHAR *SFTpatt = NULL;
    CHAR *IFO = NULL;
    INT4 startGPS = 0;
    INT4 endGPS = 0;
    REAL8 f_min = 0.0;
    REAL8 f_max = 0.0;
    REAL8 freqres =0.0;
    INT4 blocksRngMed = 101;
    CHAR *outputBname = NULL;
    INT4 cur_epoch = 0, next_epoch = 0;
    
    /* these varibales are for converting GPS seconds into UTC time and date*/
    struct tm         date;
    CHARVector        *timestamp = NULL;
    CHARVector	     *year_date = NULL;
    REAL8Vector     *timestamps=NULL;
    
    CHAR *psrInput = NULL;
    CHAR *psrEphemeris = NULL;
    CHAR *earthFile = NULL;
    CHAR *sunFile = NULL;
  /*========================================================================================================================*/
    
    
    LAL_CALL(LALRegisterBOOLUserVar  (&status, "help",         'h', UVAR_HELP,     "Print this help message",     &help        ), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "SFTs",         'p', UVAR_REQUIRED, "SFT location/pattern",        &SFTpatt     ), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "IFO",          'I', UVAR_REQUIRED, "Detector",                    &IFO         ), &status);
    LAL_CALL(LALRegisterINTUserVar   (&status, "startGPS",     's', UVAR_REQUIRED, "Starting GPS time",           &startGPS    ), &status);
    LAL_CALL(LALRegisterINTUserVar   (&status, "endGPS",       'e', UVAR_REQUIRED, "Ending GPS time",             &endGPS      ), &status);
    LAL_CALL(LALRegisterREALUserVar  (&status, "fMin",         'f', UVAR_REQUIRED, "Minimum frequency",           &f_min       ), &status);
    LAL_CALL(LALRegisterREALUserVar  (&status, "fMax",         'F', UVAR_REQUIRED, "Maximum frequency",           &f_max       ), &status);
    LAL_CALL(LALRegisterINTUserVar   (&status, "blocksRngMed", 'w', UVAR_OPTIONAL, "Running Median window size",  &blocksRngMed), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "outputBname",  'o', UVAR_OPTIONAL, "Base name of output files",   &outputBname ), &status);
    LAL_CALL(LALRegisterREALUserVar  (&status, "freqRes",      'r', UVAR_REQUIRED, "Spectrogram freq resolution", &freqres     ), &status);
    LAL_CALL(LALRegisterREALUserVar  (&status, "timeBaseline", 't', UVAR_REQUIRED, "The time baseline of sfts",   &timebaseline), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "psrInput",     'P', UVAR_OPTIONAL, "name of tempo pulsar file",   &psrInput ), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "psrEphemeris", 'S', UVAR_OPTIONAL, "pulsar ephemeris file",   &psrEphemeris ), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "earthFile",  'y', UVAR_OPTIONAL, "earth .dat file",   &earthFile ), &status);
    LAL_CALL(LALRegisterSTRINGUserVar(&status, "sunFile",   'z', UVAR_OPTIONAL, "sun .dat file",   &sunFile ), &status);
    
    LAL_CALL(LALUserVarReadAllInput(&status, argc, argv), &status);
    if (help)
    return(0);
    
    startTime.gpsSeconds = startGPS;/*cg; startTime is a structure, and gpsSeconds is a member of that structure*/
    startTime.gpsNanoSeconds = 0;/*cg; gps NanoSeconds is also a member of the startTime structure */
    constraints.minStartTime = &startTime; /*cg; & operator gets the address of variable, &a is a pointer to a.  This line puts the startTime structure into the structure constraints*/
    
    endTime.gpsSeconds = endGPS;
    endTime.gpsNanoSeconds = 0;
    constraints.maxEndTime = &endTime;/*cg; This line puts the end time into the structure constraints*/
    constraints.detector = IFO;/*cg; this adds the interferometer into the contraints structure*/
    LALSFTdataFind ( &status, &catalog, SFTpatt, &constraints );/*cg; creates SFT catalog, uses the constraints structure*/

    if (catalog == NULL)/*need to check for a NULL pointer, and print info about circumstances if it is null*/
    {
        fprintf(stderr, "SFT catalog pointer is NULL!  There has been an error with LALSFTdataFind\n");
        fprintf(stderr, "LALStatus info.... status code: %d, message: %s, offending function: %s\n", status.statusCode, status.statusDescription, status.function);
        exit(0);
    }
    if (catalog->length == 0)
    {
        fprintf(stderr, "No SFTs found, please exmanine start time, end time, frequency range etc\n");
        exit(0);
    }

    LALLoadSFTs ( &status, &sft_vect, catalog, f_min,f_max);/*cg;reads the SFT data into the structure sft_vect*/

    if (sft_vect == NULL)
    {
        fprintf(stderr, "SFT vector pointer is NULL!  There has been an error with LALLoadSFTs\n");
        fprintf(stderr, "LALStatus info.... status code: %d, message: %s, offending function: %s\n", status.statusCode, status.statusDescription, status.function);
        exit(0);
    }

    LALDestroySFTCatalog( &status, &catalog);/*cg; desctroys the SFT catalogue*/
    numBins = sft_vect->data->data->length;/*the number of bins in the freq_range*/
    nSFT = sft_vect->length;/* the number of sfts.*/
    
    fprintf(stderr, "nSFT = %d\tnumBins = %d\tf0 = %f\n", nSFT, numBins,sft_vect->data->f0);/*print->logs/spectrumAverage_testcg_0.err */
    if (LALUserVarWasSet(&outputBname))
    strcpy(outbase, outputBname);
    else
    sprintf(outbase, "spec_%.2f_%.2f_%s_%d_%d", f_min,f_max,constraints.detector,startTime.gpsSeconds,endTime.gpsSeconds);/*cg; this is the default name for producing the output files, the different suffixes are just added to this*/
    sprintf(outfile,  "%s", outbase);/*cg; name of first file to be output*/
    sprintf(outfile2, "%s_timestamps", outbase);/*cg: name of second file to be output*/
    sprintf(outfile3, "%s.txt", outbase);/*cg; name of third file to be output*/
    sprintf(outfile4, "%s_date", outbase);/*cg;file for outputting the date, which is used in matlab plotting.*/

    fp = fopen(outfile, "w");/*cg;  open all three files for writing, if they don't exist create them, if they do exist overwrite them*/
    fp2 = fopen(outfile2, "w");
    fp3 = fopen(outfile3, "w");
    fp4 = fopen(outfile4, "w");

/*----------------------------------------------------------------------------------------------------------------*/
/*cg; Create the first file called spec_blah_blah.  This file outputs the power in each spectrogram bin.  The number of bins depends on the frequency range, freq resolution, and number of SFTs.*/

/*cg;  Create the second file, called    blah_b;ah_blah_timestamps.  This will simply contain the time in GPS seconds of each SFT.*/

    NumBinsAvg = freqres*numBins/(f_max-f_min);/*this calcs the number of bins over which to average the sft data, this is worked out so it produces the same freq resolution as specified in the arguments passed to fscanDriver.py. numBins is the total number of bins in the raw sft data*/

    l=0;/*l is used as a counter to count how many SFTs and fake zero SFTs (used for gaps) are output for specgram.*/
    timestamps = XLALCreateREAL8Vector(l);/*test for getting rid of second loop*/
    LALCHARCreateVector(&status, &year_date, (UINT4)128); 

  /*create output files and check for missing sfts*/
    for (j=0;j<nSFT;j++)/*cg;nSFT is the numnber of SFT files used for the time specified. So process is repeated for each SFT*/
    {
        cur_epoch = sft_vect->data[j].epoch.gpsSeconds;/*finds the gps time of the current sft in the sequence with index j*/
        fprintf(fp2, "%d.\t%d\n", l, cur_epoch);/*cg; this bit writes the second file, i.e. the timestamps*/
    
        XLALResizeREAL8Vector(timestamps, l+1);/*resizes the vector timestamps, so cur_epoch can be added*/
        timestamps->data[l]= cur_epoch;/*number of gaps is not know in advance, hence need for te resizing*/
        XLALGPSToUTC(&date, cur_epoch);/*cg; gets the UTC date in struct tm format from the GPS seconds.*/
        fprintf(fp4, "%d\t %i\t %i\t %i\t %i\t %i\t %i\n", l, (date.tm_year+1900), date.tm_mon+1, date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec);
    
        for ( i=0; i < (numBins-2); i+=NumBinsAvg)/*cg; this loop works out the powers and writes the first file.*/
        {/*cg; each SFT is split up into a number of bins, the number of bins is read in from the SFT file*/
            avg = 0.0;/*cg; the vairable avg is reset each time.*/
            if (i+NumBinsAvg>numBins) {printf("Error\n");return(2);}/*cg; error is detected, to prevent referencing data past the end of sft_vect.*/
            for (k=0;k<NumBinsAvg;k++)/*cg; for each bin, k goes trhough each entry from 0 to 180.*/
                avg += sqrt(2*(crealf(sft_vect->data[j].data->data[i+k])*crealf(sft_vect->data[j].data->data[i+k]) + 
                cimagf(sft_vect->data[j].data->data[i+k])*cimagf(sft_vect->data[j].data->data[i+k]))/timebaseline);/*cg; re amd im are real and imaginary parts of SFT, duh!*/
            fprintf(fp,"%e\t",avg/NumBinsAvg);
        }
        fprintf(fp,"\n");
        /*------------------------------*/
        /*Bit to check if there is a gap in the sfts*/
        if ( j < (nSFT-1) )/*in all cases except when we are examining the last sft, check that there is no gap to the next sft*/
        {
            next_epoch = sft_vect->data[j+1].epoch.gpsSeconds;
            /*test to see if SFT gap is longer than 3/2*timebaseline, if so create another entry in the matrix*/
            while ((cur_epoch+((3/2)*timebaseline)) < next_epoch)
            {
                for ( i=0; i < (numBins-2); i+=NumBinsAvg)
                {
                    avg = 0.0;
                    if (i+NumBinsAvg>numBins) {printf("Error\n");return(2);}
                    fprintf(fp,"%e\t",avg);
                }
                fprintf(fp,"\n");
                l=l+1;
                cur_epoch=cur_epoch+timebaseline;
                fprintf(fp2, "%d.\t%d\n", l, cur_epoch );
                    
                XLALResizeREAL8Vector(timestamps, l+1);
                timestamps->data[l]= cur_epoch;
                XLALGPSToUTC(&date, cur_epoch);/*cg; gets the UTC date in struct tm format from the GPS seconds.*/
                fprintf(fp4, "%d\t %i\t %i\t %i\t %i\t %i\t %i\n", l, (date.tm_year+1900), date.tm_mon+1, date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec);
            }
            
        }
        l=l+1;
    }
    fprintf(stderr,"finished checking for missing sfts, l=%d\n", l);
/*----------------------------------------------------------------------------------------------------------------*/
/*cg;  Create the third and final file, called   blah_blah_blah.txt.  This file will contain the data used in the matlab plot script to plot the normalised average power vs the frequency.*/

    /* Find time average of normalized SFTs */
    LALNormalizeSFTVect(&status, sft_vect, blocksRngMed);   
    LALNormalizeSFTVect(&status, sft_vect, blocksRngMed);   
    timeavg = XLALMalloc(numBins*sizeof(REAL4));
    if (timeavg == NULL) fprintf(stderr,"Timeavg memory not allocated\n");

    for (j=0;j<nSFT;j++)
    { 
        for ( i=0; i < numBins; i++)
        {
            if (j == 0) 
            {
                timeavg[i] = crealf(sft_vect->data[j].data->data[i])*crealf(sft_vect->data[j].data->data[i]) + 
                            cimagf(sft_vect->data[j].data->data[i])*cimagf(sft_vect->data[j].data->data[i]);
            } 
            else 
            {
                timeavg[i] += crealf(sft_vect->data[j].data->data[i])*crealf(sft_vect->data[j].data->data[i]) + 
                            cimagf(sft_vect->data[j].data->data[i])*cimagf(sft_vect->data[j].data->data[i]);
            }
        }
    }
    /*timeavg records the power of each bin*/
    for ( i=0; i < numBins; i++)
    {
        f = sft_vect->data->f0 + ((REAL4)i)*sft_vect->data->deltaF;
	PWR=timeavg[i]/((REAL4)nSFT);
	SNR=(PWR-1)*(sqrt(((REAL4)nSFT)));
        fprintf(fp3,"%16.8f %g %g\n",f, PWR, SNR);
    } 
/*------------------------------------------------------------------------------------------------------------------------*/ 
/*End of normal spec_avg code, the remaining code is for crab freq calc.*/
/*================================================================================================================*/
/*================================================================================================================*/
    /*This next block of code is for the crab specific changes to fscan*/
    #define CRAB 0
    /*change this to CRAB 0 to prevent this section of code from compiling, change to 1 to compile it.*/
    #if CRAB
    /*--------------------------------------------------------------------------------------------------------------*/
    /*some header files for the crab*/
    /*#include "../TDS_isolated/HeterodyneCrabPulsar.h"*/
    /*#include "../TDS_isolated/heterodyne_pulsar.h"*/
    #include<../TDS_isolated/HeterodyneCrabPulsar.h>

    if (psrInput != NULL){

    fprintf(stderr,"--------------------\n\n");
    fprintf(stderr,"start of crab stuff\n");
    LIGOTimeGPS dataEpoch;
    /*below 4 structures are from HeterodyneCrabPulsar.h*/
    GetCrabEphemerisInput input; /*this is needed to get the crab ephemeris*/
    CrabSpindownParamsInput crabEphemerisData;
    CrabSpindownParamsOutput crabOutput;
    ParamsForHeterodyne hetParams;
    
    /*CG; these lines allocate memory for the crab ephemeris and crab output variables...*/
    crabEphemerisData.f1 = NULL;
    LALDCreateVector( &status, &crabEphemerisData.f1, NUM);
    
    crabEphemerisData.f0 = NULL;
    LALDCreateVector( &status, &crabEphemerisData.f0, NUM);
    
    crabEphemerisData.tArr = NULL;
    LALDCreateVector( &status, &crabEphemerisData.tArr, NUM);
    
    crabOutput.tArr = NULL;
    LALDCreateVector( &status, &crabOutput.tArr, NUM);
        
    crabOutput.f0 = NULL;
    LALDCreateVector( &status, &crabOutput.f0, NUM);
    
    crabOutput.f1 = NULL;
    LALDCreateVector( &status, &crabOutput.f1, NUM);
    
    crabOutput.f2 = NULL;
    LALDCreateVector( &status, &crabOutput.f2, NUM);
    
    crabOutput.f3 = NULL;
    LALDCreateVector( &status, &crabOutput.f3, NUM);
    
    crabOutput.f4 = NULL;
    LALDCreateVector( &status, &crabOutput.f4, NUM);
        
        
    /*This next set of variables are to do with the doppler shifts that are then applied to to the crab feq.*/
    REAL8 t2=0., tdt=0.;
    EphemerisData *edat=NULL;
    BarycenterInput baryinput, baryinput2;
    EarthState earth, earth2;
    EmissionTime  emit, emit2;
    REAL8 df=0., freq, finalFreq, max_df, minf, maxf;
    REAL8 dtpos=0.; /* time between position epoch and data timestamp */
    BinaryPulsarParams pulsarParams; /*general pulsar params strcut, despite binary name*/
    /*CHAR *psrInput = NULL;*/ /* pulsar input file containing params f0, f1 etc. */
    LALDetector det;
    CHAR detName[256];
    REAL8 ecliptic_lat, e_tilt=0.409092627;/*the ecliptic latitude of the source, and hte earth's tilt in radians (23.439281 degrees)*/

    char outfile5[256];
    FILE *fp5 = NULL;
    sprintf(outfile5, "%s_crab", outbase);
    fp5 = fopen(outfile5, "w");

    /*----------------------------------------------------------------------------------------------------------------*/
    /*cg; calculating the crab freq, done in three steps. This is done for each sft*/
    /*----------------------------------------------------------------------------------------------------------------*/
    /*    ---1---   */
    /*Find rough guess of crabs freq from ephemeris*/
    /*----------------------------------------------------------------------------------------------------------------*/
    
    /*Get detector position, this is needed for barycentre calcs*/
    det = *XLALGetSiteInfo( IFO );

    /* read in tempo par file for pulsar, This is one of the optional command line arguments*/
    /*fprintf(stderr,"%s\n",psrInput);*/
    fprintf(stderr,"%s\n",psrInput);
    XLALReadTEMPOParFile(&pulsarParams, psrInput);

    /*Make sure that posepoch and pepoch are set*/
    if(pulsarParams.pepoch == 0. && pulsarParams.posepoch != 0.)
	pulsarParams.pepoch = pulsarParams.posepoch;
    else if(pulsarParams.posepoch == 0. && pulsarParams.pepoch != 0.)
	pulsarParams.posepoch = pulsarParams.pepoch;
    fprintf(stderr,"Check on read tempo file, pepoch: %f\n", pulsarParams.pepoch);

    /*input.filename=psrEphemeris;*/ /*/archive/home/colingill/lalsuite/lalapps/src/pulsar/fscan/ /archive/home/colingill/public_html/crab_ephemeris.txt*/
    input.filename = XLALMalloc(sizeof(CHAR)*256);
    if(input.filename == NULL) fprintf(stderr,"input.filename pointer memory not allocated\t");

    strcpy(input.filename,psrEphemeris);
    /*fprintf(stderr,"psrEphemeris:%s\n", input.filename);*/

    /*The first stage is to read in f and fdot from the ephemeris, the crab_ephemeris.txt file is part of lalapps and is maintained by matt*/
    LALGetCrabEphemeris( &status, &crabEphemerisData, &input );
    /*check on the outputs, crabEphemerisData is a struct of type CrabSpindownParamsInput, and has members tArr, f0, f1*/
    fprintf(stderr,"input crab ephemeris present, number of entries: %i\n", crabEphemerisData.numOfData);
    fprintf(stderr,"crabEphemerisData: \ttarr= %f\tf0= %f\tf_dot= %e\n", crabEphemerisData.tArr->data[0], crabEphemerisData.f0->data[0], crabEphemerisData.f1->data[0]);
    
    /*Now I have f and fdot, use function below to compute the higher order derrivatives of the crabs frequency*/
    LALComputeFreqDerivatives( &status, &crabOutput, &crabEphemerisData );
    /*check on this function, crabOutput is datatype CrabSpindownParamsOutput*/
    fprintf(stderr,"crabOutput:\tf0= %f\tf1= %e\tf2= %e\n", crabOutput.f0->data[0], crabOutput.f1->data[0], crabOutput.f2->data[0]);/*need to change the type of printf for F1 and f2 to exponentials.*/
    fprintf(stderr,"--------------------\n");

    /*Allocate memory for edat, no need to do in the loop*/
    edat = XLALMalloc(sizeof(*edat));
    (*edat).ephiles.earthEphemeris = earthFile; /*"/archive/home/colingill/lalsuite/lal/packages/pulsar/test/earth05-09.dat";*/
    (*edat).ephiles.sunEphemeris = sunFile;/*"/archive/home/colingill/lalsuite/lal/packages/pulsar/test/sun05-09.dat";*/

    /*work out the eclitptic lattitude of the source, used in max freq calc.*/
    ecliptic_lat=asin(cos(e_tilt)*sin(pulsarParams.dec)-sin(pulsarParams.ra)*cos(pulsarParams.dec)*sin(e_tilt));
    fprintf(stderr,"eqcliptic_lat: %e\t", ecliptic_lat);

    for (i=0;i<l;i++)
    {
        if (i == (l-1))/*catches the last iteration where there is no i+1 entry in timestamps*/
        {
            cur_epoch = timestamps->data[i]+(timebaseline/2);
        }
        else
        {
            cur_epoch = timestamps->data[i]+((timestamps->data[i+1] - timestamps->data[i])/2);
        }

        fprintf(stderr,"cur_epoch: %d\t", cur_epoch);
        /*The time has to be set so that the nearest entry to that time in the ephemeris can be used*/
        dataEpoch.gpsSeconds = cur_epoch; /*INT8)floor(time->data[j]);*/
        dataEpoch.gpsNanoSeconds = 0;
    
        /*prepare hetParams, which is then used to get the freq derrivatives out and also in the next sub-section for Bary functions*/
        LALSetSpindownParams( &status, &hetParams, &crabOutput, dataEpoch );
        fprintf(stderr,"hetparams epoch: %f\t f0= %f\tf1= %e\n", hetParams.epoch, hetParams.f0, hetParams.f1);
    
        /*----------------------------------------------------------------------------------------------------------------*/
        /*    ---2---   */
        /*Add corrections for timing noise to get a better guess at the freq*/
        /*----------------------------------------------------------------------------------------------------------------*/
    
        /*now I want to use these params to calc the freq at any point in time.  Using the higher order derrivatives is how we adjust for timing noise.*/
    
        /*Get the time difference between the current epoch and the epoch of the ephemeris entry*/
        tdt= cur_epoch - hetParams.epoch;
        fprintf(stderr,"dt: %f,\tf1= %e,\tf2= %e,\tf3= %e,\tf4=%e\n", tdt, hetParams.f1, hetParams.f2, hetParams.f3, hetParams.f4);
    
        freq = 2.0*( hetParams.f0 + ((hetParams.f1)*tdt) + (((hetParams.f2)*tdt*tdt)/2) + (((hetParams.f3)*tdt*tdt*tdt)/6) + (((hetParams.f4)*tdt*tdt*tdt*tdt)/24) );
        fprintf(stderr,"crab fcoarse: %f\t", freq);
    
        /*freq = 2.0*(params->f0 + params->f1*t1 + (params->f2)*t1*t1+ (params->f3)*t1*t1*t1 + (params->f4)*t1*t1*t1*t1);*/  /*cg;line 486 from hetcrabpulsar, works out freq, this is with one order of t removed for each of the derrivatives of f, and also each term is divided by a factorial, 1!, 2!, 3!, but this starts one term along from the oroginal code as we have integrated the orginal code to get freq not phase*/
    
        /*----------------------------------------------------------------------------------------------------------------*/
        /*    ---3---   */
        /*Add doppler shifts for earth's motion back onto the freq to get actual observed freq at detectors.*/
        /*----------------------------------------------------------------------------------------------------------------*/
        
        /*now I have the freq, I need to add the doppler shift for the earths motion around the sun */
        baryinput.dInv = 0.;/*I can always set this to zero, as Matt said so, I must ask him why*/

        LAL_CALL( LALInitBarycenter(&status, edat), &status );/*  */
    
        /*this lines take position of detector which are in xyz coords in meters from earths centre and converts them into seconds (time)*/
        baryinput.site.location[0] = det.location[0]/LAL_C_SI;
        baryinput.site.location[1] = det.location[1]/LAL_C_SI;
        baryinput.site.location[2] = det.location[2]/LAL_C_SI;
    
        /*dtpos should be the time between the entry in the ephemeris and the point in time for which doppler shifts are being calc.ed*/
        dtpos = cur_epoch - pulsarParams.posepoch;
    
        /* set up RA, DEC, and distance variables for LALBarycenter*/
        baryinput.delta = pulsarParams.dec + dtpos*pulsarParams.pmdec;
        baryinput.alpha = pulsarParams.ra + dtpos*pulsarParams.pmra/cos(baryinput.delta);
        
        t2=cur_epoch+1;
    
        baryinput2 = baryinput;
        
        baryinput.tgps.gpsSeconds = (INT4)floor(cur_epoch);
        baryinput.tgps.gpsNanoSeconds = (INT4)floor((fmod(cur_epoch,1.0)*1.e9));
    
        baryinput2.tgps.gpsSeconds = (INT4)floor(t2);
        baryinput2.tgps.gpsNanoSeconds = (INT4)floor((fmod(t2,1.0)*1.e9));
    
        /*the barycentre functions are needed to calc the inputs for the correction to fcoarse, namely emit, earth and baryinput*/
        LAL_CALL( LALBarycenterEarth(&status, &earth, &baryinput.tgps, edat), &status );
        LAL_CALL( LALBarycenter(&status, &emit, &baryinput, &earth), &status );
        
        LAL_CALL( LALBarycenterEarth(&status, &earth2, &baryinput2.tgps, edat), &status );
        LAL_CALL( LALBarycenter(&status, &emit2, &baryinput2, &earth2), &status );
    
        /* I need to calc the correction to the freq for the doppler shifts, the correction is df, from line 1074 heterdyne_pulsar.  deltaT is T_emission in TDB - T_arrrival in GPS + light travel time to SSB.  we are working out delta(delatT) over 1 second, so do not bother with the divide by one bit.*/
        df = freq*(emit2.deltaT - emit.deltaT);
        fprintf(stderr,"df: %f,\t", df);

        /*Calc maximum possible df and then subtract applied df from it, use the remaining df to plot range over which f will wander.*/
        max_df=freq*(( (29.783e3*cos(ecliptic_lat))+(465*cos(pulsarParams.dec)) )/3.0e8);/*max doppler shift, from speed of earth in plane of direction to source over c.*/
        fprintf(stderr,"max df: %f\tbeta: %e\n", max_df, ecliptic_lat);
        maxf=freq+max_df;
        minf=freq-max_df;

        finalFreq=freq+df;
        /*df = fcoarse*(emit2.deltaT - emit.deltaT + binOutput2.deltaT - binOutput.deltaT);*//*use when have binary calcs in here also.*/
        fprintf(fp5,"%f\t%f\t%f\t%f\t%f\n", freq, df, minf, finalFreq, maxf);
        fprintf(stderr,"crab freq calc, i:%d,  minf:%f,  f:%f,  maxf:%f\n", i, minf, finalFreq, maxf);

        /*----------------------------------------------------------------------------------------------------------------*/
    }
    fclose(fp5);
    fprintf(stderr,"end of crab stuff\n");
    
    /*Free up any memory allocated in crab section*/
    XLALFree(edat);
    
    }
    #endif

    /*fprintf(stderr,"end of spec_avg 1\n");*/

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


    /*release a;; the allocaeted memory*/
    LALCHARDestroyVector(&status, &timestamp);
    LALCHARDestroyVector(&status, &year_date);
    LALDestroySFTVector (&status, &sft_vect );

    /*fprintf(stderr,"end of spec_avg 2\n");*/

    if (timeavg != NULL) XLALFree(timeavg);

    /*fprintf(stderr,"end of spec_avg 3\n");*/

    LAL_CALL(LALDestroyUserVars(&status), &status);

    /*fprintf(stderr,"end of spec_avg 4\n");*/
    /*close all the files, spec_avg.c is done, all info written to the files.*/
    fclose(fp);
    fclose(fp2);
    fclose(fp3);
    fclose(fp4);

    fprintf(stderr,"end of spec_avg\n");

    return(0);


}
/**
 * Given the trajectory in an inertial frame, this computes Euler angles
 * of the roation from the inertial frame to the minimal-rotation frame
 * that co-precesses with LN(t) = rvec(t) x rdotvec(t)
 */
static int EulerAnglesI2P(REAL8Vector *Alpha, /**<< output: alpha Euler angle */
                 REAL8Vector *Beta, /**<< output: beta Euler angle */
                 REAL8Vector *Gamma, /**<< output: gamma Euler angle */
                 INT4 *phaseCounterA, /**<< output: counter for unwrapping of alpha */
                 INT4 *phaseCounterB, /**<< output: counter for unwrapping of beta */
                 const REAL8Vector tVec, /**<< time series */
                 const REAL8Vector posVecx, /**<< x time series */
                 const REAL8Vector posVecy, /**<< y time series */
                 const REAL8Vector posVecz, /**<< z time series */
                 const UINT4 retLenLow, /**<< Array length of the trajectory */
                 const REAL8 InitialAlpha, /**<< Initial alpha (used only if flag_highSR=1) */
                 const REAL8 InitialGamma, /**<< Initial gamma */
                 UINT4 flag_highSR /**<< Flag to indicate whether one is analyzing the high SR trajectory */) {
    UINT4 i = 0;
    REAL8Vector *LN_x = NULL, *LN_y = NULL, *LN_z = NULL;
    REAL8 tmpR[3], tmpRdot[3], magLN;
    REAL8 precEulerresult = 0, precEulererror = 0;
    gsl_integration_workspace * precEulerw = gsl_integration_workspace_alloc (1000);
    gsl_function precEulerF;
    PrecEulerAnglesIntegration precEulerparams;
    REAL8 inGamma = InitialGamma;

    LN_x = XLALCreateREAL8Vector( retLenLow );
    LN_y = XLALCreateREAL8Vector( retLenLow );
    LN_z = XLALCreateREAL8Vector( retLenLow );

    gsl_spline *x_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow );
    gsl_spline *y_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow );
    gsl_spline *z_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow );

    gsl_interp_accel *x_acc    = gsl_interp_accel_alloc();
    gsl_interp_accel *y_acc    = gsl_interp_accel_alloc();
    gsl_interp_accel *z_acc    = gsl_interp_accel_alloc();

    gsl_spline_init( x_spline, tVec.data, posVecx.data, retLenLow );
    gsl_spline_init( y_spline, tVec.data, posVecy.data, retLenLow );
    gsl_spline_init( z_spline, tVec.data, posVecz.data, retLenLow );

    for( i=0; i < retLenLow; i++ )
    {
        tmpR[0] = posVecx.data[i]; tmpR[1] = posVecy.data[i]; tmpR[2] = posVecz.data[i];
        tmpRdot[0] = gsl_spline_eval_deriv( x_spline, tVec.data[i], x_acc );
        tmpRdot[1] = gsl_spline_eval_deriv( y_spline, tVec.data[i], y_acc );
        tmpRdot[2] = gsl_spline_eval_deriv( z_spline, tVec.data[i], z_acc );

        LN_x->data[i] = tmpR[1] * tmpRdot[2] - tmpR[2] * tmpRdot[1];
        LN_y->data[i] = tmpR[2] * tmpRdot[0] - tmpR[0] * tmpRdot[2];
        LN_z->data[i] = tmpR[0] * tmpRdot[1] - tmpR[1] * tmpRdot[0];

        magLN = sqrt(LN_x->data[i] * LN_x->data[i] + LN_y->data[i] * LN_y->data[i]
                     + LN_z->data[i] * LN_z->data[i]);
        LN_x->data[i] /= magLN; LN_y->data[i] /= magLN; LN_z->data[i] /= magLN;

        /*  Eq. 19 of PRD 89, 084006 (2014) */
        /*  Also unwrap the two angles */
        if (fabs(LN_x->data[i]) <= 1.e-10 && fabs(LN_y->data[i]) <=1.e-10){
            Alpha->data[i] = 0.0;
            inGamma = 0.0;
        } else {
            Alpha->data[i] = atan2( LN_y->data[i], LN_x->data[i] )
                             +  *phaseCounterA * LAL_TWOPI;
            if (i==0 && flag_highSR != 1){
                inGamma = -Alpha->data[i];
            }
        }

        if( i>0 && Alpha->data[i] - Alpha->data[i-1] > 5. ) {
            *phaseCounterA = *phaseCounterA - 1;
            Alpha->data[i] -= LAL_TWOPI;
        }
        else if ( i && Alpha->data[i] - Alpha->data[i-1] < -5. ) {
            *phaseCounterA = *phaseCounterA + 1;
            Alpha->data[i] += LAL_TWOPI;
        }
        if (LN_z->data[i] >1.) {
            LN_z->data[i] = 1.;
        }
        if (LN_z->data[i] <-1.) {
            LN_z->data[i] = -1.;
        }
        if ( flag_highSR == 1) {
            Alpha->data[i] -= (Alpha->data[0] - InitialAlpha);
        }

        if (fabs(1.0 - LN_z->data[i]) < 1.e-12){
            REAL8 LN_xy;
            LN_xy = sqrt(LN_x->data[i]*LN_x->data[i] +
			 LN_y->data[i]*LN_y->data[i]);
            //LN_z->data[i] = sqrt(1.0 - LN_xy*LN_xy);
            Beta->data[i] = atan2(LN_xy, LN_z->data[i]);
            //printf("here   ");
        }else{
            Beta->data[i] = acos( LN_z->data[i] );
        }
        if( i>0 && Beta->data[i] > Beta->data[i-1] ) {
            *phaseCounterB = *phaseCounterB - 1;
        }
    }
    /* Integrate \dot{\alpha} \cos{\beta} to get the final Euler angle
     Eq. 20 of PRD 89, 084006 (2014) */
    gsl_spline_init( x_spline, tVec.data, Alpha->data, retLenLow );
    gsl_spline_init( y_spline, tVec.data, Beta->data, retLenLow );

    precEulerparams.alpha_spline = x_spline;
    precEulerparams.alpha_acc    = x_acc;
    precEulerparams.beta_spline  = y_spline;
    precEulerparams.beta_acc     = y_acc;

    precEulerF.function = &f_alphadotcosi;
    precEulerF.params   = &precEulerparams;

    for( i = 0; i < retLenLow; i++ )
    {
        //if( i==0 ) { Gamma->data[i] = InitialGamma; }
        if( i==0 ) { Gamma->data[i] = inGamma; }
        else
        {
            gsl_integration_qags (&precEulerF, tVec.data[i-1], tVec.data[i], 1e-9, 1e-9, 1000, precEulerw, &precEulerresult, &precEulererror);
            Gamma->data[i] = Gamma->data[i-1] + precEulerresult;
        }
    }
    gsl_integration_workspace_free( precEulerw );
    gsl_spline_free( x_spline );
    gsl_spline_free( y_spline );
    gsl_spline_free( z_spline );
    gsl_interp_accel_free( x_acc );
    gsl_interp_accel_free( y_acc );
    gsl_interp_accel_free( z_acc );
    XLALDestroyREAL8Vector( LN_x );
    XLALDestroyREAL8Vector( LN_y );
    XLALDestroyREAL8Vector( LN_z );
    return XLAL_SUCCESS;
}
示例#15
0
///
/// Make SFTs from given REAL8TimeSeries at given timestamps, potentially applying a time-domain window on each timestretch first
///
SFTVector *
XLALMakeSFTsFromREAL8TimeSeries ( const REAL8TimeSeries *timeseries,	//!< input time-series
                                  const LIGOTimeGPSVector *timestamps, 	//!< timestamps to produce SFTs for (can be NULL), if given must all lies within timeseries' time-span
                                  const char *windowType,		//!< optional time-domain window function to apply before FFTing
                                  REAL8 windowBeta			//!< window parameter, if any
                                  )
{
  XLAL_CHECK_NULL ( timeseries != NULL, XLAL_EINVAL, "Invalid NULL input 'timeseries'\n");
  XLAL_CHECK_NULL ( timestamps != NULL, XLAL_EINVAL, "Invalid NULL input 'timestamps'\n");

  REAL8 dt = timeseries->deltaT;	// timeseries timestep */
  REAL8 Tsft = timestamps->deltaT;
  REAL8 df = 1.0 / Tsft;		// SFT frequency spacing

  // make sure that number of timesamples/SFT is an integer (up to possible rounding error 'eps')
  REAL8 timestepsSFT0 = Tsft / dt;
  UINT4 timestepsSFT  = lround ( timestepsSFT0 );
  XLAL_CHECK_NULL ( fabs ( timestepsSFT0 - timestepsSFT ) / timestepsSFT0 < eps, XLAL_ETOL,
                    "Inconsistent sampling-step (dt=%g) and Tsft=%g: must be integer multiple Tsft/dt = %g >= %g\n",
                    dt, Tsft, timestepsSFT0, eps );

  // prepare window function if requested
  REAL8Window *window = NULL;
  if ( windowType != NULL ) {
    XLAL_CHECK_NULL ( (window = XLALCreateNamedREAL8Window ( windowType, windowBeta, timestepsSFT )) != NULL, XLAL_EFUNC );
  }

  // ---------- Prepare FFT ----------
  REAL8Vector *timeStretchCopy;	// input array of length N
  XLAL_CHECK_NULL ( (timeStretchCopy = XLALCreateREAL8Vector ( timestepsSFT )) != NULL, XLAL_EFUNC, "XLALCreateREAL4Vector(%d) failed.\n", timestepsSFT );
  UINT4 numSFTBins = timestepsSFT / 2 + 1;	// number of positive frequency-bins + 'DC' to be stored in SFT
  fftw_complex *fftOut;	// output array of length N/2 + 1
  XLAL_CHECK_NULL ( (fftOut = fftw_malloc ( numSFTBins * sizeof(fftOut[0]) )) != NULL, XLAL_ENOMEM, "fftw_malloc(%d*sizeof(complex)) failed\n", numSFTBins );
  fftw_plan fftplan;	// FFTW plan
  LAL_FFTW_WISDOM_LOCK;
  XLAL_CHECK_NULL ( (fftplan = fftw_plan_dft_r2c_1d ( timestepsSFT, timeStretchCopy->data, fftOut, FFTW_ESTIMATE)) != NULL, XLAL_EFUNC );	// FIXME: or try FFTW_MEASURE
  LAL_FFTW_WISDOM_UNLOCK;

  LIGOTimeGPS tStart = timeseries->epoch;

  // get last possible start-time for an SFT
  REAL8 duration =  round ( timeseries->data->length * dt ); // rounded to seconds
  LIGOTimeGPS tLast = tStart;
  XLALGPSAdd( &tLast, duration - Tsft );

  // check that all timestamps lie within [tStart, tLast]
  for ( UINT4 i = 0; i < timestamps->length; i ++ )
    {
      char buf1[256], buf2[256];
      XLAL_CHECK_NULL ( XLALGPSDiff ( &tStart, &(timestamps->data[i]) ) <= 0, XLAL_EDOM, "Timestamp i=%d: %s before start-time %s\n",
                        i, XLALGPSToStr ( buf1, &(timestamps->data[i]) ), XLALGPSToStr ( buf2, &tStart ) );
      XLAL_CHECK_NULL ( XLALGPSDiff ( &tLast,   &(timestamps->data[i]) ) >=0, XLAL_EDOM, "Timestamp i=%d: %s after last start-time %s\n",
                        i, XLALGPSToStr ( buf1, &(timestamps->data[i]) ), XLALGPSToStr ( buf2, &tLast ) );
    }

  UINT4 numSFTs = timestamps->length;

  // prepare output SFT-vector
  SFTVector *sftvect;
  XLAL_CHECK_NULL ( (sftvect = XLALCreateSFTVector ( numSFTs, numSFTBins )) != NULL, XLAL_EFUNC,
                    "XLALCreateSFTVector(numSFTs=%d, numBins=%d) failed.\n", numSFTs, numSFTBins );

  // main loop: apply FFT to the requested time-stretches and store in output SFTs
  for ( UINT4 iSFT = 0; iSFT < numSFTs; iSFT++ )
    {
      SFTtype *thisSFT = &(sftvect->data[iSFT]);	// point to current SFT-slot to store output in

      // find the start-bin for this SFT in the time-series
      REAL8 offset = XLALGPSDiff ( &(timestamps->data[iSFT]), &tStart );
      INT4 offsetBins = lround ( offset / dt );

      // copy timeseries-data for that SFT into local buffer
      memcpy ( timeStretchCopy->data, timeseries->data->data + offsetBins, timeStretchCopy->length * sizeof(timeStretchCopy->data[0]) );

      // window the current time series stretch if required
      REAL8 sigma_window = 1;
      if ( window != NULL )
        {
	  sigma_window = sqrt ( window->sumofsquares / window->data->length );
	  for( UINT4 iBin = 0; iBin < timeStretchCopy->length; iBin++ ) {
            timeStretchCopy->data[iBin] *= window->data->data[iBin];
          }
        } // if window

      // FFT this time-stretch
      fftw_execute ( fftplan );

      // fill the header of the i'th output SFT */
      strcpy ( thisSFT->name, timeseries->name );
      thisSFT->epoch = timestamps->data[iSFT];
      thisSFT->f0 = timeseries->f0;			// SFT starts at heterodyning frequency
      thisSFT->deltaF = df;

      // normalize DFT-data to conform to v2 specification ==> multiply DFT by (dt/sigma{window})
      // the SFT normalization in case of windowing follows the conventions detailed in the SFTv2 specification,
      // namely LIGO-T040164, and in particular Eqs.(3),(4) and (6) in T010095-00.pdf
      // https://dcc.ligo.org/cgi-bin/private/DocDB/ShowDocument?.submit=Number&docid=T010095
      // https://dcc.ligo.org/DocDB/0026/T010095/000/T010095-00.pdf
      REAL8 norm = dt / sigma_window;
      for ( UINT4 k = 0; k < numSFTBins ; k ++ ) {
        thisSFT->data->data[k] = (COMPLEX8) ( norm * fftOut[k] );
      }

      // correct heterodyning-phase, IF NECESSARY: ie if (fHet * tStart) is not an integer, such that phase-corr = multiple of 2pi
      if ( ( (INT4)timeseries->f0 != timeseries->f0  ) || (timeseries->epoch.gpsNanoSeconds != 0) || (thisSFT->epoch.gpsNanoSeconds != 0) ) {
        XLAL_CHECK_NULL ( XLALcorrect_phase ( thisSFT, timeseries->epoch) == XLAL_SUCCESS, XLAL_EFUNC );
      }

    } // for iSFT < numSFTs

  // free memory
  fftw_free ( fftOut );
  LAL_FFTW_WISDOM_LOCK;
  fftw_destroy_plan ( fftplan );
  LAL_FFTW_WISDOM_UNLOCK;
  XLALDestroyREAL8Vector ( timeStretchCopy );
  XLALDestroyREAL8Window ( window );

  return sftvect;

} // XLALMakeSFTsFromREAL8TimeSeries()
示例#16
0
void LALReadNRWave_raw_real8(LALStatus *status,	/**< pointer to LALStatus structure */
		       REAL8TimeVectorSeries **out, /**< [out] output time series for h+ and hx */
		       const CHAR  *filename        /**< [in] File containing numrel waveform */)
{

  UINT4 length, k, r;
  REAL8TimeVectorSeries *ret=NULL;
  REAL8VectorSequence *data=NULL;
  REAL8Vector *timeVec=NULL;
  LALParsedDataFile *cfgdata=NULL;
  REAL8 tmp1, tmp2, tmp3;

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  /* some consistency checks */
  ASSERT (filename != NULL, status, NRWAVEIO_ENULL, NRWAVEIO_MSGENULL );
  ASSERT ( out != NULL, status, NRWAVEIO_ENULL, NRWAVEIO_MSGENULL );
  ASSERT ( *out == NULL, status, NRWAVEIO_ENONULL, NRWAVEIO_MSGENONULL );

  if ( XLALParseDataFile ( &cfgdata, filename ) != XLAL_SUCCESS ) {
    ABORT( status, NRWAVEIO_EFILE, NRWAVEIO_MSGEFILE );
  }
  length = cfgdata->lines->nTokens; /*number of data points */


  /* allocate memory */
  ret = LALCalloc(1, sizeof(*ret));
  if (!ret) {
    ABORT( status, NRWAVEIO_ENOMEM, NRWAVEIO_MSGENOMEM );
  }
  strcpy(ret->name,filename);
  ret->f0 = 0;

  data =  XLALCreateREAL8VectorSequence (2, length);
  if (!data) {
    ABORT( status, NRWAVEIO_ENOMEM, NRWAVEIO_MSGENOMEM );
  }

  timeVec = XLALCreateREAL8Vector (length);
  if (!timeVec) {
    ABORT( status, NRWAVEIO_ENOMEM, NRWAVEIO_MSGENOMEM );
  }

  /* now get the data */
  for (k = 0; k < length; k++) {
    r = sscanf(cfgdata->lines->tokens[k], "%lf%lf%lf", &tmp1, &tmp2, &tmp3);

    /* Check the data file format */
    if ( r != 3) {
      /* there must be exactly 3 data entries -- time, h+, hx */
      ABORT( status, NRWAVEIO_EFORMAT, NRWAVEIO_MSGEFORMAT );
    }

    timeVec->data[k] = tmp1;
    data->data[k] = tmp2;
    data->data[data->vectorLength + k] = tmp3;

  }

  /*  scale time */
  ret->deltaT = timeVec->data[1] - timeVec->data[0];

  /* might also want to go through timeVec to make sure it is evenly spaced */


  ret->data = data;
  (*out) = ret;

  XLALDestroyREAL8Vector (timeVec);
  XLALDestroyParsedDataFile (cfgdata);

  DETATCHSTATUSPTR(status);
  RETURN(status);

} /* LALReadNRWave() */
int main(int argc, char *argv[]){

  UserInput_t XLAL_INIT_DECL(uvar);
  static ConfigVariables config;

  /* sft related variables */
  MultiSFTVector *inputSFTs = NULL;
  MultiPSDVector *multiPSDs = NULL;
  MultiNoiseWeights *multiWeights = NULL;
  MultiLIGOTimeGPSVector *multiTimes = NULL;
  MultiLALDetector multiDetectors;
  MultiDetectorStateSeries *multiStates = NULL;
  MultiAMCoeffs *multiCoeffs = NULL;
  SFTIndexList *sftIndices = NULL;
  SFTPairIndexList *sftPairs = NULL;
  REAL8Vector *shiftedFreqs = NULL;
  UINT4Vector *lowestBins = NULL;
  COMPLEX8Vector *expSignalPhases = NULL;
  REAL8VectorSequence *sincList = NULL;
  PulsarDopplerParams XLAL_INIT_DECL(dopplerpos);
  PulsarDopplerParams thisBinaryTemplate, binaryTemplateSpacings;
  PulsarDopplerParams minBinaryTemplate, maxBinaryTemplate;
  SkyPosition XLAL_INIT_DECL(skyPos);
  MultiSSBtimes *multiBinaryTimes = NULL;

  INT4  k;
  UINT4 j;
  REAL8 fMin, fMax; /* min and max frequencies read from SFTs */
  REAL8 deltaF; /* frequency resolution associated with time baseline of SFTs */

  REAL8 diagff = 0; /*diagonal metric components*/
  REAL8 diagaa = 0;
  REAL8 diagTT = 0;
  REAL8 diagpp = 1;
  REAL8 ccStat = 0;
  REAL8 evSquared=0;
  REAL8 estSens=0; /*estimated sensitivity(4.13)*/
  BOOLEAN dopplerShiftFlag = TRUE;
  toplist_t *ccToplist=NULL;
  CrossCorrBinaryOutputEntry thisCandidate;
  UINT4 checksum;

  LogPrintf (LOG_CRITICAL, "Starting time\n"); /*for debug convenience to record calculating time*/
  /* initialize and register user variables */
  LIGOTimeGPS computingStartGPSTime, computingEndGPSTime;
  XLALGPSTimeNow (&computingStartGPSTime); /* record the rough starting GPS time*/

  if ( XLALInitUserVars( &uvar ) != XLAL_SUCCESS ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* read user input from the command line or config file */
  if ( XLALUserVarReadAllInput ( argc, argv ) != XLAL_SUCCESS ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALUserVarReadAllInput() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  if (uvar.help)	/* if help was requested, then exit */
    return 0;

  CHAR *VCSInfoString = XLALGetVersionString(0);     /**<LAL + LALapps Vsersion string*/
  /*If the version information was requested, output it and exit*/
  if ( uvar.version ){
    XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" );
    printf ("%s\n", VCSInfoString );
    exit (0);
  }

  /* configure useful variables based on user input */
  if ( XLALInitializeConfigVars ( &config, &uvar) != XLAL_SUCCESS ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  deltaF = config.catalog->data[0].header.deltaF;
  REAL8 Tsft = 1.0 / deltaF;

  if (XLALUserVarWasSet(&uvar.spacingF) && XLALUserVarWasSet(&uvar.mismatchF))
    LogPrintf (LOG_CRITICAL, "spacingF and mismatchF are both set, use spacingF %.9g by default\n\n", uvar.spacingF);
  if (XLALUserVarWasSet(&uvar.spacingA) && XLALUserVarWasSet(&uvar.mismatchA))
    LogPrintf (LOG_CRITICAL, "spacingA and mismatchA are both set, use spacingA %.9g by default\n\n", uvar.spacingA);
  if (XLALUserVarWasSet(&uvar.spacingT) && XLALUserVarWasSet(&uvar.mismatchT))
    LogPrintf (LOG_CRITICAL, "spacingT and mismatchT are both set, use spacingT %.9g by default\n\n", uvar.spacingT);
  if (XLALUserVarWasSet(&uvar.spacingP) && XLALUserVarWasSet(&uvar.mismatchP))
    LogPrintf (LOG_CRITICAL, "spacingP and mismatchP are both set, use spacingP %.9g by default\n\n", uvar.spacingP);

  /* create the toplist */
  create_crossCorrBinary_toplist( &ccToplist, uvar.numCand);
  /* now read the data */

  /* /\* get SFT parameters so that we can initialise search frequency resolutions *\/ */
  /* /\* calculate deltaF_SFT *\/ */
  /* deltaF_SFT = catalog->data[0].header.deltaF;  /\* frequency resolution *\/ */
  /* timeBase= 1.0/deltaF_SFT; /\* sft baseline *\/ */

  /* /\* catalog is ordered in time so we can get start, end time and tObs *\/ */
  /* firstTimeStamp = catalog->data[0].header.epoch; */
  /* lastTimeStamp = catalog->data[catalog->length - 1].header.epoch; */
  /* tObs = XLALGPSDiff( &lastTimeStamp, &firstTimeStamp ) + timeBase; */

  /* /\*set pulsar reference time *\/ */
  /* if (LALUserVarWasSet ( &uvar_refTime )) { */
  /*   XLALGPSSetREAL8(&refTime, uvar_refTime); */
  /* }  */
  /* else {	/\*if refTime is not set, set it to midpoint of sfts*\/ */
  /*   XLALGPSSetREAL8(&refTime, (0.5*tObs) + XLALGPSGetREAL8(&firstTimeStamp));  */
  /* } */

  /* /\* set frequency resolution defaults if not set by user *\/ */
  /* if (!(LALUserVarWasSet (&uvar_fResolution))) { */
  /*   uvar_fResolution = 1/tObs; */
  /* } */

  /* { */
  /*   /\* block for calculating frequency range to read from SFTs *\/ */
  /*   /\* user specifies freq and fdot range at reftime */
  /*      we translate this range of fdots to start and endtime and find */
  /*      the largest frequency band required to cover the  */
  /*      frequency evolution  *\/ */
  /*   PulsarSpinRange spinRange_startTime; /\**< freq and fdot range at start-time of observation *\/ */
  /*   PulsarSpinRange spinRange_endTime;   /\**< freq and fdot range at end-time of observation *\/ */
  /*   PulsarSpinRange spinRange_refTime;   /\**< freq and fdot range at the reference time *\/ */

  /*   REAL8 startTime_freqLo, startTime_freqHi, endTime_freqLo, endTime_freqHi, freqLo, freqHi; */

  /*   REAL8Vector *fdotsMin=NULL; */
  /*   REAL8Vector *fdotsMax=NULL; */

  /*   UINT4 k; */

  /*   fdotsMin = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */
  /*   fdotsMin->length = N_SPINDOWN_DERIVS; */
  /*   fdotsMin->data = (REAL8 *)LALCalloc(fdotsMin->length, sizeof(REAL8)); */

  /*   fdotsMax = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */
  /*   fdotsMax->length = N_SPINDOWN_DERIVS; */
  /*   fdotsMax->data = (REAL8 *)LALCalloc(fdotsMax->length, sizeof(REAL8)); */

  /*   XLAL_INIT_MEM(spinRange_startTime); */
  /*   XLAL_INIT_MEM(spinRange_endTime); */
  /*   XLAL_INIT_MEM(spinRange_refTime); */

  /*   spinRange_refTime.refTime = refTime; */
  /*   spinRange_refTime.fkdot[0] = uvar_f0; */
  /*   spinRange_refTime.fkdotBand[0] = uvar_fBand; */
  /* } */

  /* FIXME: need to correct fMin and fMax for Doppler shift, rngmedian bins and spindown range */
  /* this is essentially just a place holder for now */
  /* FIXME: this running median buffer is overkill, since the running median block need not be centered on the search frequency */
  REAL8 vMax = LAL_TWOPI * (uvar.orbitAsiniSec + uvar.orbitAsiniSecBand) / uvar.orbitPSec + LAL_TWOPI * LAL_REARTH_SI / (LAL_DAYSID_SI * LAL_C_SI) + LAL_TWOPI * LAL_AU_SI/(LAL_YRSID_SI * LAL_C_SI); /*calculate the maximum relative velocity in speed of light*/
  fMin = uvar.fStart * (1 - vMax) - 0.5 * uvar.rngMedBlock * deltaF;
  fMax = (uvar.fStart + uvar.fBand) * (1 + vMax) + 0.5 * uvar.rngMedBlock * deltaF;

  /* read the SFTs*/
  if ((inputSFTs = XLALLoadMultiSFTs ( config.catalog, fMin, fMax)) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALLoadMultiSFTs() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* calculate the psd and normalize the SFTs */
  if (( multiPSDs =  XLALNormalizeMultiSFTVect ( inputSFTs, uvar.rngMedBlock, NULL )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALNormalizeMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* compute the noise weights for the AM coefficients */
  if (( multiWeights = XLALComputeMultiNoiseWeights ( multiPSDs, uvar.rngMedBlock, 0 )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiNoiseWeights() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* read the timestamps from the SFTs */
  if ((multiTimes = XLALExtractMultiTimestampsFromSFTs ( inputSFTs )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALExtractMultiTimestampsFromSFTs() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* read the detector information from the SFTs */
  if ( XLALMultiLALDetectorFromMultiSFTs ( &multiDetectors, inputSFTs ) != XLAL_SUCCESS){
    LogPrintf ( LOG_CRITICAL, "%s: XLALMultiLALDetectorFromMultiSFTs() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* Find the detector state for each SFT */
  /* Offset by Tsft/2 to get midpoint as timestamp */
  if ((multiStates = XLALGetMultiDetectorStates ( multiTimes, &multiDetectors, config.edat, 0.5 * Tsft )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiDetectorStates() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* Note this is specialized to a single sky position */
  /* This might need to be moved into the config variables */
  skyPos.system = COORDINATESYSTEM_EQUATORIAL;
  skyPos.longitude = uvar.alphaRad;
  skyPos.latitude  = uvar.deltaRad;

  /* Calculate the AM coefficients (a,b) for each SFT */
  if ((multiCoeffs = XLALComputeMultiAMCoeffs ( multiStates, multiWeights, skyPos )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiAMCoeffs() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* Construct the flat list of SFTs (this sort of replicates the
     catalog, but there's not an obvious way to get the information
     back) */

  if ( ( XLALCreateSFTIndexListFromMultiSFTVect( &sftIndices, inputSFTs ) != XLAL_SUCCESS ) ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTIndexListFromMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* Construct the list of SFT pairs */
#define PCC_SFTPAIR_HEADER "# The length of SFT-pair list is %u #\n"
#define PCC_SFTPAIR_BODY "%u %u\n"
#define PCC_SFT_HEADER "# The length of SFT list is %u #\n"
#define PCC_SFT_BODY "%s %d %d\n"
  FILE *fp = NULL;

  if (XLALUserVarWasSet(&uvar.pairListInputFilename)) { /* If the user provided a list for reading, use it */
    if((sftPairs = XLALCalloc(1, sizeof(sftPairs))) == NULL){
      XLAL_ERROR(XLAL_ENOMEM);
    }
    if((fp = fopen(uvar.pairListInputFilename, "r")) == NULL){
      LogPrintf ( LOG_CRITICAL, "didn't find SFT-pair list file with given input name\n");
      XLAL_ERROR( XLAL_EFUNC );
    }
    if(fscanf(fp,PCC_SFTPAIR_HEADER,&sftPairs->length)==EOF){
      LogPrintf ( LOG_CRITICAL, "can't read the length of SFT-pair list from the header\n");
      XLAL_ERROR( XLAL_EFUNC );
    }

    if((sftPairs->data = XLALCalloc(sftPairs->length, sizeof(*sftPairs->data)))==NULL){
      XLALFree(sftPairs);
      XLAL_ERROR(XLAL_ENOMEM);
    }

    for(j = 0; j < sftPairs->length; j++){ /*read in  the SFT-pair list */
      if(fscanf(fp,PCC_SFTPAIR_BODY, &sftPairs->data[j].sftNum[0], &sftPairs->data[j].sftNum[1])==EOF){
	LogPrintf ( LOG_CRITICAL, "The length of SFT-pair list doesn't match!");
	XLAL_ERROR( XLAL_EFUNC );
      }
    }
    fclose(fp);

  }

  else { /* if not, construct the list of pairs */
    if ( ( XLALCreateSFTPairIndexList( &sftPairs, sftIndices, inputSFTs, uvar.maxLag, uvar.inclAutoCorr ) != XLAL_SUCCESS ) ) {
      LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTPairIndexList() failed with errno=%d\n", __func__, xlalErrno );
      XLAL_ERROR( XLAL_EFUNC );
    }
  }

  if (XLALUserVarWasSet(&uvar.pairListOutputFilename)) { /* Write the list of pairs to a file, if a name was provided */
    if((fp = fopen(uvar.pairListOutputFilename, "w")) == NULL){
      LogPrintf ( LOG_CRITICAL, "Can't write in SFT-pair list \n");
      XLAL_ERROR( XLAL_EFUNC );
    }
    fprintf(fp,PCC_SFTPAIR_HEADER, sftPairs->length ); /*output the length of SFT-pair list to the header*/
    for(j = 0; j < sftPairs->length; j++){
      fprintf(fp,PCC_SFTPAIR_BODY, sftPairs->data[j].sftNum[0], sftPairs->data[j].sftNum[1]);
    }
    fclose(fp);
  }

  if (XLALUserVarWasSet(&uvar.sftListOutputFilename)) { /* Write the list of SFTs to a file for sanity-checking purposes */
    if((fp = fopen(uvar.sftListOutputFilename, "w")) == NULL){
      LogPrintf ( LOG_CRITICAL, "Can't write in flat SFT list \n");
      XLAL_ERROR( XLAL_EFUNC );
    }
    fprintf(fp,PCC_SFT_HEADER, sftIndices->length ); /*output the length of SFT list to the header*/
    for(j = 0; j < sftIndices->length; j++){ /*output the SFT list */
      fprintf(fp,PCC_SFT_BODY, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds);
    }
    fclose(fp);
  }

  else if(XLALUserVarWasSet(&uvar.sftListInputFilename)){ /*do a sanity check of the order of SFTs list if the name of input SFT list is given*/
    UINT4 numofsft=0;
    if((fp = fopen(uvar.sftListInputFilename, "r")) == NULL){
      LogPrintf ( LOG_CRITICAL, "Can't read in flat SFT list \n");
      XLAL_ERROR( XLAL_EFUNC );
    }
    if (fscanf(fp, PCC_SFT_HEADER, &numofsft)==EOF){
      LogPrintf ( LOG_CRITICAL, "can't read in the length of SFT list from header\n");
      XLAL_ERROR( XLAL_EFUNC );
    }

    CHARVectorSequence *checkDet=NULL;
    if ((checkDet = XLALCreateCHARVectorSequence (numofsft, LALNameLength) ) == NULL){
      LogPrintf ( LOG_CRITICAL, "%s: XLALCreateCHARVector() failed with errno=%d\n", __func__, xlalErrno );
      XLAL_ERROR( XLAL_EFUNC );
    }
    INT4 checkGPS[numofsft], checkGPSns[numofsft];
    if(numofsft == sftIndices->length){
      for (j=0; j<numofsft; j++){
	if( fscanf(fp,PCC_SFT_BODY,&checkDet->data[j * LALNameLength], &checkGPS[j], &checkGPSns[j])==EOF){
	  LogPrintf ( LOG_CRITICAL, "The length of SFT list doesn't match\n");
	  XLAL_ERROR( XLAL_EFUNC );
	}
	if(strcmp( inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, &checkDet->data[j * LALNameLength] ) != 0
	   ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds != checkGPS[j]
	   ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds != checkGPSns[j] ){
	  LogPrintf ( LOG_CRITICAL, "The order of SFTs has been changed, it's the end of civilization\n");
	  XLAL_ERROR( XLAL_EFUNC );
	}
      }
      fclose(fp);
      XLALDestroyCHARVectorSequence(checkDet);
    }
    else{
      LogPrintf ( LOG_CRITICAL, "Run for your life, the length of SFT list doesn't match");
      XLAL_ERROR( XLAL_EFUNC );
    }
  }
  else
    {

    }

  /* Get weighting factors for calculation of metric */
  /* note that the sigma-squared is now absorbed into the curly G
     because the AM coefficients are noise-weighted. */
  REAL8Vector *GammaAve = NULL;
  REAL8Vector *GammaCirc = NULL;
  if ( ( XLALCalculateCrossCorrGammas( &GammaAve, &GammaCirc, sftPairs, sftIndices, multiCoeffs)  != XLAL_SUCCESS ) ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrGammas() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

#define PCC_GAMMA_HEADER "# The normalization Sinv_Tsft is %g #\n"
#define PCC_GAMMA_BODY "%.10g\n"
  if (XLALUserVarWasSet(&uvar.gammaAveOutputFilename)) { /* Write the aa+bb weight for each pair to a file, if a name was provided */
    if((fp = fopen(uvar.gammaAveOutputFilename, "w")) == NULL) {
      LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_ave list \n");
      XLAL_ERROR( XLAL_EFUNC );
    }
    fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/
    for(j = 0; j < sftPairs->length; j++){
      fprintf(fp,PCC_GAMMA_BODY, GammaAve->data[j]);
    }
    fclose(fp);
  }
  if (XLALUserVarWasSet(&uvar.gammaCircOutputFilename)) { /* Write the ab-ba weight for each pair to a file, if a name was provided */
    if((fp = fopen(uvar.gammaCircOutputFilename, "w")) == NULL) {
      LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_circ list \n");
      XLAL_ERROR( XLAL_EFUNC );
    }
    fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/
    for(j = 0; j < sftPairs->length; j++){
      fprintf(fp,PCC_GAMMA_BODY, GammaCirc->data[j]);
    }
    fclose(fp);
  }

  /*initialize binary parameters structure*/
  XLAL_INIT_MEM(minBinaryTemplate);
  XLAL_INIT_MEM(maxBinaryTemplate);
  XLAL_INIT_MEM(thisBinaryTemplate);
  XLAL_INIT_MEM(binaryTemplateSpacings);
  /*fill in minbinaryOrbitParams*/
  XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc);
  minBinaryTemplate.argp = 0.0;
  minBinaryTemplate.asini = uvar.orbitAsiniSec;
  minBinaryTemplate.ecc = 0.0;
  minBinaryTemplate.period = uvar.orbitPSec;
  minBinaryTemplate.fkdot[0] = uvar.fStart;
  /*fill in maxBinaryParams*/
  XLALGPSSetREAL8( &maxBinaryTemplate.tp, uvar.orbitTimeAsc + uvar.orbitTimeAscBand);
  maxBinaryTemplate.argp = 0.0;
  maxBinaryTemplate.asini = uvar.orbitAsiniSec + uvar.orbitAsiniSecBand;
  maxBinaryTemplate.ecc = 0.0;
  maxBinaryTemplate.period = uvar.orbitPSec;
  maxBinaryTemplate.fkdot[0] = uvar.fStart + uvar.fBand;
  /*fill in thisBinaryTemplate*/
  XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * uvar.orbitTimeAscBand);
  thisBinaryTemplate.argp = 0.0;
  thisBinaryTemplate.asini = 0.5*(minBinaryTemplate.asini + maxBinaryTemplate.asini);
  thisBinaryTemplate.ecc = 0.0;
  thisBinaryTemplate.period =0.5*(minBinaryTemplate.period + maxBinaryTemplate.period);
  thisBinaryTemplate.fkdot[0]=0.5*(minBinaryTemplate.fkdot[0] + maxBinaryTemplate.fkdot[0]);

  /*Get metric diagonal components, also estimate sensitivity i.e. E[rho]/(h0)^2 (4.13)*/
  if ( (XLALCalculateLMXBCrossCorrDiagMetric(&estSens, &diagff, &diagaa, &diagTT, thisBinaryTemplate, GammaAve, sftPairs, sftIndices, inputSFTs, multiWeights /*, kappaValues*/)  != XLAL_SUCCESS ) ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateLMXBCrossCorrDiagMetric() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* spacing in frequency from diagff */ /* set spacings in new dopplerparams struct */
  if (XLALUserVarWasSet(&uvar.spacingF)) /* If spacing was given by CMD line, use it, else calculate spacing by mismatch*/
    binaryTemplateSpacings.fkdot[0] = uvar.spacingF;
  else
    binaryTemplateSpacings.fkdot[0] = sqrt(uvar.mismatchF / diagff);

  if (XLALUserVarWasSet(&uvar.spacingA))
    binaryTemplateSpacings.asini = uvar.spacingA;
  else
    binaryTemplateSpacings.asini = sqrt(uvar.mismatchA / diagaa);
  /* this is annoying: tp is a GPS time while we want a difference
     in time which should be just REAL8 */
  if (XLALUserVarWasSet(&uvar.spacingT))
    XLALGPSSetREAL8( &binaryTemplateSpacings.tp, uvar.spacingT);
  else
    XLALGPSSetREAL8( &binaryTemplateSpacings.tp, sqrt(uvar.mismatchT / diagTT));

  if (XLALUserVarWasSet(&uvar.spacingP))
    binaryTemplateSpacings.period = uvar.spacingP;
  else
    binaryTemplateSpacings.period = sqrt(uvar.mismatchP / diagpp);

  /* metric elements for eccentric case not considered? */

  UINT8 fCount = 0, aCount = 0, tCount = 0 , pCount = 0;
  const UINT8 fSpacingNum = floor( uvar.fBand / binaryTemplateSpacings.fkdot[0]);
  const UINT8 aSpacingNum = floor( uvar.orbitAsiniSecBand / binaryTemplateSpacings.asini);
  const UINT8 tSpacingNum = floor( uvar.orbitTimeAscBand / XLALGPSGetREAL8(&binaryTemplateSpacings.tp));
  const UINT8 pSpacingNum = floor( uvar.orbitPSecBand / binaryTemplateSpacings.period);

  /*reset minbinaryOrbitParams to shift the first point a factor so as to make the center of all seaching points centers at the center of searching band*/
  minBinaryTemplate.fkdot[0] = uvar.fStart + 0.5 * (uvar.fBand - fSpacingNum * binaryTemplateSpacings.fkdot[0]);
  minBinaryTemplate.asini = uvar.orbitAsiniSec + 0.5 * (uvar.orbitAsiniSecBand - aSpacingNum * binaryTemplateSpacings.asini);
  XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * (uvar.orbitTimeAscBand - tSpacingNum * XLALGPSGetREAL8(&binaryTemplateSpacings.tp)));
  minBinaryTemplate.period = uvar.orbitPSec + 0.5 * (uvar.orbitPSecBand - pSpacingNum * binaryTemplateSpacings.period);

  /* initialize the doppler scan struct which stores the current template information */
  XLALGPSSetREAL8(&dopplerpos.refTime, config.refTime);
  dopplerpos.Alpha = uvar.alphaRad;
  dopplerpos.Delta = uvar.deltaRad;
  dopplerpos.fkdot[0] = minBinaryTemplate.fkdot[0];
  /* set all spindowns to zero */
  for (k=1; k < PULSAR_MAX_SPINS; k++)
    dopplerpos.fkdot[k] = 0.0;
  dopplerpos.asini = minBinaryTemplate.asini;
  dopplerpos.period = minBinaryTemplate.period;
  dopplerpos.tp = minBinaryTemplate.tp;
  dopplerpos.ecc = minBinaryTemplate.ecc;
  dopplerpos.argp = minBinaryTemplate.argp;

  /* now set the initial values of binary parameters */
  /*  thisBinaryTemplate.asini = uvar.orbitAsiniSec;
  thisBinaryTemplate.period = uvar.orbitPSec;
  XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc);
  thisBinaryTemplate.ecc = 0.0;
  thisBinaryTemplate.argp = 0.0;*/
  /* copy to dopplerpos */

  /* Calculate SSB times (can do this once since search is currently only for one sky position, and binary doppler shift is added later) */
  MultiSSBtimes *multiSSBTimes = NULL;
  if ((multiSSBTimes = XLALGetMultiSSBtimes ( multiStates, skyPos, dopplerpos.refTime, SSBPREC_RELATIVISTICOPT )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* "New" general metric computation */
  /* For now hard-code circular parameter space */

  const DopplerCoordinateSystem coordSys = {
    .dim = 4,
    .coordIDs = { DOPPLERCOORD_FREQ,
		  DOPPLERCOORD_ASINI,
		  DOPPLERCOORD_TASC,
		  DOPPLERCOORD_PORB, },
  };

  REAL8VectorSequence *phaseDerivs = NULL;
  if ( ( XLALCalculateCrossCorrPhaseDerivatives ( &phaseDerivs, &thisBinaryTemplate, config.edat, sftIndices, multiSSBTimes, &coordSys )  != XLAL_SUCCESS ) ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseDerivatives() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* fill in metric and parameter offsets */
  gsl_matrix *g_ij = NULL;
  gsl_vector *eps_i = NULL;
  REAL8 sumGammaSq = 0;
  if ( ( XLALCalculateCrossCorrPhaseMetric ( &g_ij, &eps_i, &sumGammaSq, phaseDerivs, sftPairs, GammaAve, GammaCirc, &coordSys ) != XLAL_SUCCESS ) ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseMetric() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }
  XLALDestroyREAL8VectorSequence ( phaseDerivs );
  XLALDestroyREAL8Vector ( GammaCirc );

  if ((fp = fopen("gsldata.dat","w"))==NULL){
    LogPrintf ( LOG_CRITICAL, "Can't write in gsl matrix file");
    XLAL_ERROR( XLAL_EFUNC );
  }

  XLALfprintfGSLvector(fp, "%g", eps_i);
  XLALfprintfGSLmatrix(fp, "%g", g_ij);

  /* Allocate structure for binary doppler-shifting information */
  if ((multiBinaryTimes = XLALDuplicateMultiSSBtimes ( multiSSBTimes )) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALDuplicateMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  UINT8 numSFTs = sftIndices->length;
  if ((shiftedFreqs = XLALCreateREAL8Vector ( numSFTs ) ) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }
  if ((lowestBins = XLALCreateUINT4Vector ( numSFTs ) ) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALCreateUINT4Vector() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  if ((expSignalPhases = XLALCreateCOMPLEX8Vector ( numSFTs ) ) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }
  if ((sincList = XLALCreateREAL8VectorSequence ( numSFTs, uvar.numBins ) ) == NULL){
    LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8VectorSequence() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* args should be : spacings, min and max doppler params */
  BOOLEAN firstPoint = TRUE; /* a boolean to help to search at the beginning point in parameter space, after the search it is set to be FALSE to end the loop*/
  if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos )  != XLAL_SUCCESS ) ) {
    LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno );
    XLAL_ERROR( XLAL_EFUNC );
  } /*Need to apply additional doppler shifting before the loop, or the first point in parameter space will be lost and return a wrong SNR when fBand!=0*/

  while ( GetNextCrossCorrTemplate(&dopplerShiftFlag, &firstPoint, &dopplerpos, &binaryTemplateSpacings, &minBinaryTemplate, &maxBinaryTemplate, &fCount, &aCount, &tCount, &pCount, fSpacingNum, aSpacingNum, tSpacingNum, pSpacingNum) == 0)
    {
      /* do useful stuff here*/

      /* Apply additional Doppler shifting using current binary orbital parameters */
      /* Might want to be clever about checking whether we've changed the orbital parameters or only the frequency */
      if (dopplerShiftFlag == TRUE)
	{
	  if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos )  != XLAL_SUCCESS ) ) {
	    LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno );
	    XLAL_ERROR( XLAL_EFUNC );
	  }
	}

      if ( (XLALGetDopplerShiftedFrequencyInfo( shiftedFreqs, lowestBins, expSignalPhases, sincList, uvar.numBins, &dopplerpos, sftIndices, inputSFTs, multiBinaryTimes, Tsft )  != XLAL_SUCCESS ) ) {
	LogPrintf ( LOG_CRITICAL, "%s: XLALGetDopplerShiftedFrequencyInfo() failed with errno=%d\n", __func__, xlalErrno );
	XLAL_ERROR( XLAL_EFUNC );
      }

      if ( (XLALCalculatePulsarCrossCorrStatistic( &ccStat, &evSquared, GammaAve, expSignalPhases, lowestBins, sincList, sftPairs, sftIndices, inputSFTs, multiWeights, uvar.numBins)  != XLAL_SUCCESS ) ) {
	LogPrintf ( LOG_CRITICAL, "%s: XLALCalculatePulsarCrossCorrStatistic() failed with errno=%d\n", __func__, xlalErrno );
	XLAL_ERROR( XLAL_EFUNC );
      }

      /* fill candidate struct and insert into toplist if necessary */
      thisCandidate.freq = dopplerpos.fkdot[0];
      thisCandidate.tp = XLALGPSGetREAL8( &dopplerpos.tp );
      thisCandidate.argp = dopplerpos.argp;
      thisCandidate.asini = dopplerpos.asini;
      thisCandidate.ecc = dopplerpos.ecc;
      thisCandidate.period = dopplerpos.period;
      thisCandidate.rho = ccStat;
      thisCandidate.evSquared = evSquared;
      thisCandidate.estSens = estSens;

      insert_into_crossCorrBinary_toplist(ccToplist, thisCandidate);

    } /* end while loop over templates */

  /* write candidates to file */
  sort_crossCorrBinary_toplist( ccToplist );
  /* add error checking */

  final_write_crossCorrBinary_toplist_to_file( ccToplist, uvar.toplistFilename, &checksum);

  REAL8 h0Sens = sqrt((10 / sqrt(estSens))); /*for a SNR=10 signal, the h0 we can detect*/

  XLALGPSTimeNow (&computingEndGPSTime); /*record the rough end time*/
  UINT4 computingTime = computingEndGPSTime.gpsSeconds - computingStartGPSTime.gpsSeconds;
  /* make a meta-data file*/
  if(XLALUserVarWasSet(&uvar.logFilename)){
    CHAR *CMDInputStr = XLALUserVarGetLog ( UVAR_LOGFMT_CFGFILE );
    if ((fp = fopen(uvar.logFilename,"w"))==NULL){
    LogPrintf ( LOG_CRITICAL, "Can't write in logfile");
    XLAL_ERROR( XLAL_EFUNC );
    }
    fprintf(fp, "[UserInput]\n\n");
    fprintf(fp, "%s\n", CMDInputStr);
    fprintf(fp, "[CalculatedValues]\n\n");
    fprintf(fp, "g_ff = %.9f\n", diagff );
    fprintf(fp, "g_aa = %.9f\n", diagaa );
    fprintf(fp, "g_TT = %.9f\n", diagTT );
    fprintf(fp, "FSpacing = %.9g\n", binaryTemplateSpacings.fkdot[0]);
    fprintf(fp, "ASpacing = %.9g\n", binaryTemplateSpacings.asini);
    fprintf(fp, "TSpacing = %.9g\n", XLALGPSGetREAL8(&binaryTemplateSpacings.tp));
    /* fprintf(fp, "PSpacing = %.9g\n", binaryTemplateSpacings.period );*/
    fprintf(fp, "TemplatenumF = %" LAL_UINT8_FORMAT "\n", (fSpacingNum + 1));
    fprintf(fp, "TemplatenumA = %" LAL_UINT8_FORMAT "\n", (aSpacingNum + 1));
    fprintf(fp, "TemplatenumT = %" LAL_UINT8_FORMAT "\n", (tSpacingNum + 1));
    fprintf(fp, "TemplatenumP = %" LAL_UINT8_FORMAT "\n", (pSpacingNum + 1));
    fprintf(fp, "TemplatenumTotal = %" LAL_UINT8_FORMAT "\n",(fSpacingNum + 1) * (aSpacingNum + 1) * (tSpacingNum + 1) * (pSpacingNum + 1));
    fprintf(fp, "Sens = %.9g\n", estSens);/*(E[rho]/h0^2)^2*/
    fprintf(fp, "h0_min_SNR10 = %.9g\n", h0Sens);/*for rho = 10 in our pipeline*/
    fprintf(fp, "startTime = %" LAL_INT4_FORMAT "\n", computingStartGPSTime.gpsSeconds );/*start time in GPS-time*/
    fprintf(fp, "endTime = %" LAL_INT4_FORMAT "\n", computingEndGPSTime.gpsSeconds );/*end time in GPS-time*/
    fprintf(fp, "computingTime = %" LAL_UINT4_FORMAT "\n", computingTime );/*total time in sec*/
    fprintf(fp, "SFTnum = %" LAL_UINT4_FORMAT "\n", sftIndices->length);/*total number of SFT*/
    fprintf(fp, "pairnum = %" LAL_UINT4_FORMAT "\n", sftPairs->length);/*total number of pair of SFT*/
    fprintf(fp, "Tsft = %.6g\n", Tsft);/*SFT duration*/
    fprintf(fp, "\n[Version]\n\n");
    fprintf(fp, "%s",  VCSInfoString);
    fclose(fp);
    XLALFree(CMDInputStr);
  }

  XLALFree(VCSInfoString);
  XLALDestroyCOMPLEX8Vector ( expSignalPhases );
  XLALDestroyUINT4Vector ( lowestBins );
  XLALDestroyREAL8Vector ( shiftedFreqs );
  XLALDestroyREAL8VectorSequence ( sincList );
  XLALDestroyMultiSSBtimes ( multiBinaryTimes );
  XLALDestroyMultiSSBtimes ( multiSSBTimes );
  XLALDestroyREAL8Vector ( GammaAve );
  XLALDestroySFTPairIndexList( sftPairs );
  XLALDestroySFTIndexList( sftIndices );
  XLALDestroyMultiAMCoeffs ( multiCoeffs );
  XLALDestroyMultiDetectorStateSeries ( multiStates );
  XLALDestroyMultiTimestamps ( multiTimes );
  XLALDestroyMultiNoiseWeights ( multiWeights );
  XLALDestroyMultiPSDVector ( multiPSDs );
  XLALDestroyMultiSFTVector ( inputSFTs );

  /* de-allocate memory for configuration variables */
  XLALDestroyConfigVars ( &config );

  /* de-allocate memory for user input variables */
  XLALDestroyUserVars();

  /* free toplist memory */
  free_crossCorr_toplist(&ccToplist);

  /* check memory leaks if we forgot to de-allocate anything */
  LALCheckMemoryLeaks();

  LogPrintf (LOG_CRITICAL, "End time\n");/*for debug convenience to record calculating time*/

  return 0;


} /* main */


/* initialize and register user variables */
int XLALInitUserVars (UserInput_t *uvar)
{

  /* initialize with some defaults */
  uvar->help = FALSE;
  uvar->maxLag = 0.0;
  uvar->inclAutoCorr = FALSE;
  uvar->fStart = 100.0;
  uvar->fBand = 0.1;
  /* uvar->fdotStart = 0.0; */
  /* uvar->fdotBand = 0.0; */
  uvar->alphaRad = 0.0;
  uvar->deltaRad = 0.0;
  uvar->refTime = 0.0;
  uvar->rngMedBlock = 50;
  uvar->numBins = 1;

  /* zero binary orbital parameters means not a binary */
  uvar->orbitAsiniSec = 0.0;
  uvar->orbitAsiniSecBand = 0.0;
  uvar->orbitPSec = 0.0;
  uvar->orbitPSecBand = 0.0;
  uvar->orbitTimeAsc = 0;
  uvar->orbitTimeAscBand = 0;

  /*default mismatch values */
  /* set to 0.1 by default -- for no real reason */
  /* make 0.1 a macro? */
  uvar->mismatchF = 0.1;
  uvar->mismatchA = 0.1;
  uvar->mismatchT = 0.1;
  uvar->mismatchP = 0.1;

  uvar->ephemEarth = XLALStringDuplicate("earth00-19-DE405.dat.gz");
  uvar->ephemSun = XLALStringDuplicate("sun00-19-DE405.dat.gz");

  uvar->sftLocation = XLALCalloc(1, MAXFILENAMELENGTH+1);

  /* initialize number of candidates in toplist -- default is just to return the single best candidate */
  uvar->numCand = 1;
  uvar->toplistFilename = XLALStringDuplicate("toplist_crosscorr.dat");
  uvar->version = FALSE;

  /* register  user-variables */
  XLALregBOOLUserStruct  ( help, 	   'h',  UVAR_HELP, "Print this message");
  XLALregINTUserStruct   ( startTime,       0,  UVAR_REQUIRED, "Desired start time of analysis in GPS seconds");
  XLALregINTUserStruct   ( endTime,         0,  UVAR_REQUIRED, "Desired end time of analysis in GPS seconds");
  XLALregREALUserStruct  ( maxLag,          0,  UVAR_OPTIONAL, "Maximum lag time in seconds between SFTs in correlation");
  XLALregBOOLUserStruct  ( inclAutoCorr,    0,  UVAR_OPTIONAL, "Include auto-correlation terms (an SFT with itself)");
  XLALregREALUserStruct  ( fStart,          0,  UVAR_OPTIONAL, "Start frequency in Hz");
  XLALregREALUserStruct  ( fBand,           0,  UVAR_OPTIONAL, "Frequency band to search over in Hz ");
  /* XLALregREALUserStruct  ( fdotStart,     0,  UVAR_OPTIONAL, "Start value of spindown in Hz/s"); */
  /* XLALregREALUserStruct  ( fdotBand,      0,  UVAR_OPTIONAL, "Band for spindown values in Hz/s"); */
  XLALregREALUserStruct  ( alphaRad,        0,  UVAR_OPTIONAL, "Right ascension for directed search (radians)");
  XLALregREALUserStruct  ( deltaRad,        0,  UVAR_OPTIONAL, "Declination for directed search (radians)");
  XLALregREALUserStruct  ( refTime,         0,  UVAR_OPTIONAL, "SSB reference time for pulsar-parameters [Default: midPoint]");
  XLALregREALUserStruct  ( orbitAsiniSec,   0,  UVAR_OPTIONAL, "Start of search band for projected semimajor axis (seconds) [0 means not a binary]");
  XLALregREALUserStruct  ( orbitAsiniSecBand, 0,  UVAR_OPTIONAL, "Width of search band for projected semimajor axis (seconds)");
  XLALregREALUserStruct  ( orbitPSec,       0,  UVAR_OPTIONAL, "Binary orbital period (seconds) [0 means not a binary]");
  XLALregREALUserStruct  ( orbitPSecBand,       0,  UVAR_OPTIONAL, "Band for binary orbital period (seconds) ");
  XLALregREALUserStruct  ( orbitTimeAsc,    0,  UVAR_OPTIONAL, "Start of orbital time-of-ascension band in GPS seconds");
  XLALregREALUserStruct  ( orbitTimeAscBand, 0,  UVAR_OPTIONAL, "Width of orbital time-of-ascension band (seconds)");
  XLALregSTRINGUserStruct( ephemEarth,      0,  UVAR_OPTIONAL, "Earth ephemeris file to use");
  XLALregSTRINGUserStruct( ephemSun,        0,  UVAR_OPTIONAL, "Sun ephemeris file to use");
  XLALregSTRINGUserStruct( sftLocation,     0,  UVAR_REQUIRED, "Filename pattern for locating SFT data");
  XLALregINTUserStruct   ( rngMedBlock,     0,  UVAR_OPTIONAL, "Running median block size for PSD estimation");
  XLALregINTUserStruct   ( numBins,         0,  UVAR_OPTIONAL, "Number of frequency bins to include in calculation");
  XLALregREALUserStruct  ( mismatchF,       0,  UVAR_OPTIONAL, "Desired mismatch for frequency spacing");
  XLALregREALUserStruct  ( mismatchA,       0,  UVAR_OPTIONAL, "Desired mismatch for asini spacing");
  XLALregREALUserStruct  ( mismatchT,       0,  UVAR_OPTIONAL, "Desired mismatch for periapse passage time spacing");
  XLALregREALUserStruct  ( mismatchP,       0,  UVAR_OPTIONAL, "Desired mismatch for period spacing");
  XLALregREALUserStruct  ( spacingF,       0,  UVAR_OPTIONAL, "Desired frequency spacing");
  XLALregREALUserStruct  ( spacingA,       0,  UVAR_OPTIONAL, "Desired asini spacing");
  XLALregREALUserStruct  ( spacingT,       0,  UVAR_OPTIONAL, "Desired periapse passage time spacing");
  XLALregREALUserStruct  ( spacingP,       0,  UVAR_OPTIONAL, "Desired period spacing");
  XLALregINTUserStruct   ( numCand,         0,  UVAR_OPTIONAL, "Number of candidates to keep in toplist");
  XLALregSTRINGUserStruct( pairListInputFilename, 0,  UVAR_OPTIONAL, "Name of file from which to read list of SFT pairs");
  XLALregSTRINGUserStruct( pairListOutputFilename, 0,  UVAR_OPTIONAL, "Name of file to which to write list of SFT pairs");
  XLALregSTRINGUserStruct( sftListOutputFilename, 0,  UVAR_OPTIONAL, "Name of file to which to write list of SFTs (for sanity checks)");
  XLALregSTRINGUserStruct( sftListInputFilename, 0,  UVAR_OPTIONAL, "Name of file to which to read in list of SFTs (for sanity checks)");
  XLALregSTRINGUserStruct( gammaAveOutputFilename, 0,  UVAR_OPTIONAL, "Name of file to which to write aa+bb weights (for e.g., false alarm estimation)");
  XLALregSTRINGUserStruct( gammaCircOutputFilename, 0,  UVAR_OPTIONAL, "Name of file to which to write ab-ba weights (for e.g., systematic error)");
  XLALregSTRINGUserStruct( toplistFilename, 0,  UVAR_OPTIONAL, "Output filename containing candidates in toplist");
  XLALregSTRINGUserStruct( logFilename, 0,  UVAR_OPTIONAL, "Output a meta-data file for the search");
  XLALregBOOLUserStruct  ( version, 	   'V',  UVAR_SPECIAL, "Output version(VCS) information");
  if ( xlalErrno ) {
    XLALPrintError ("%s: user variable initialization failed with errno = %d.\n", __func__, xlalErrno );
    XLAL_ERROR ( XLAL_EFUNC );
  }

  return XLAL_SUCCESS;
}
/** The main function of semicoherentbinary.c
 *
 */
int main( int argc, char *argv[] )  {

  UserInput_t uvar = empty_UserInput;           /* user input variables */
  CHAR *clargs = NULL;                          /* store the command line args */
  SFTVector *sftvec = NULL;                     /* stores the input SFTs */
  /* REAL4VectorArray *background = NULL;                  /\* running median estimates of the background for each SFT *\/ */
  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 */
  GridParameters *bingridparams = NULL;
  CHAR newnewtemp[LONGSTRINGLENGTH];
 /*  REAL8Vector *SemiCo = NULL;                   /\* the semi-coherent statistic results *\/    */
  REAL8 fmin_read,fmax_read,fband_read;         /* the range of frequencies to be read from SFTs */
  UINT4 i;                                      /* counters */
  FILE *sfp = NULL;
  /* FILE *cfp = NULL; */

  vrbflg = 0;                           /* verbose error-messages */

  /* turn off default GSL error handler */
  gsl_set_error_handler_off();

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

  /* initialise sin-cosine lookup table */
  XLALSinCosLUTInit();

  /* initialise the random number generator */
  if (XLALInitgslrand(&r,uvar.seed)) {
    LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno);
    XLAL_ERROR(XLAL_EFAULT);
  }

  /* make output directory */
  {
    struct stat st;
    if (stat(uvar.outputdir, &st)) {
      if (mkdir(uvar.outputdir,0755) != 0 && errno != EEXIST) {
        LogPrintf(LOG_DEBUG,"%s : Unable to make output directory %s.  Might be a problem.\n",__func__,uvar.outputdir);
      }
    }
  }

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

    struct stat st;
    if (stat(uvar.tempdir, &st)) {
      if (mkdir(uvar.tempdir,0755) != 0 && errno != EEXIST) {
        LogPrintf(LOG_DEBUG,"%s : Unable to make temporary directory %s.  Might be a problem.\n",__func__,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);
    }

    CHAR newtemp[LONGSTRINGLENGTH];
    INT4 id = (INT4)(1e9*gsl_rng_uniform(q));
    sprintf(newtemp,"%s/%09d",uvar.tempdir,id);
    if (mkdir(newtemp,0755) != 0 && errno != EEXIST) {
      LogPrintf(LOG_DEBUG,"%s : Unable to make temporary directory %s.  Might be a problem.\n",__func__,newtemp);
    }
    sprintf(newnewtemp,"%s/%.3f-%.3f",newtemp,uvar.freq,uvar.freq+uvar.freqband);

  } else {
    sprintf(newnewtemp,"%s/%.3f-%.3f",uvar.outputdir,uvar.freq,uvar.freq+uvar.freqband);
  }

  /* make frequency+band directory inside output/temporary directory */
  if (mkdir(newnewtemp,0755) != 0 && errno != EEXIST) {
    LogPrintf(LOG_CRITICAL,"%s : Unable to make frequency+band directory %s\n",__func__,newnewtemp);
    return 1;
  }

  /* initialise the random number generator */
  if (XLALInitgslrand(&r,uvar.seed)) {
    LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno);
    XLAL_ERROR(XLAL_EFAULT);
  }

  /* make crude but safe estimate of the bandwidth required for the source - now includes running median wings */
  {
    REAL8 wings = LAL_TWOPI*uvar.maxasini/uvar.minorbperiod;
    fmin_read = MINBAND*floor((uvar.freq - WINGS_FACTOR*uvar.freq*wings - (REAL8)uvar.blocksize/(REAL8)uvar.tsft)/MINBAND);
    fmax_read = MINBAND*ceil((uvar.freq + (REAL8)uvar.blocksize/(REAL8)uvar.tsft + uvar.freqband + WINGS_FACTOR*(uvar.freq + uvar.freqband)*wings)/MINBAND);
    fband_read = fmax_read - fmin_read;
    LogPrintf(LOG_NORMAL,"%s : reading in SFT frequency band [%f -> %f]\n",__func__,fmin_read,fmax_read);
  }

  /* initialise the random number generator */
  if (XLALInitgslrand(&r,uvar.seed)) {
    LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno);
    XLAL_ERROR(XLAL_EFAULT);
  }

  /**********************************************************************************/
  /* READ THE SFT DATA */
  /**********************************************************************************/

  /* load in the SFTs - also fill in the segment parameters structure */
  if (XLALReadSFTs(&sftvec,uvar.sftbasename,fmin_read,fband_read,uvar.gpsstart,uvar.gpsend,uvar.tsft,uvar.bins_factor)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALReadSFTs() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_NORMAL,"%s : read in SFTs\n",__func__);

  /* 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;
  LogPrintf(LOG_NORMAL,"%s : SFT length = %f seconds\n",__func__,pspace.tseg);
  LogPrintf(LOG_NORMAL,"%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 */
  /**********************************************************************************/

  if (uvar.blocksize>0) {
    /* 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;
    }
  }
  else {
    REAL8Vector *means = XLALCreateREAL8Vector(sftvec->length);
    if (uvar.blocksize==0) {
      /* compute the background noise using the sfts - this routine simply divides by the median */
      if (XLALNormalizeSFTVectMedian(sftvec,means,1)) {
        LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVectMedian() failed with error = %d\n",__func__,xlalErrno);
        return 1;
      }
    }
    else {
      /* compute the background noise using the sfts - this routine simply divides by the mean */
      if (XLALNormalizeSFTVectMean(sftvec,means,1)) {
        LogPrintf(LOG_CRITICAL,"%s : XLALNormaliseSFTVectMean() failed with error = %d\n",__func__,xlalErrno);
        return 1;
      }
    }
    XLALDestroyREAL8Vector(means);
  }
  LogPrintf(LOG_NORMAL,"%s : normalised the SFTs\n",__func__);

  /* for (i=0;i<sftvec->length;i++) {
    for (j=0;j<sftvec->data[i].data->length;j++) {
      if (isnan(crealf(sftvec->data[i].data->data[j]))||isinf(crealf(sftvec->data[i].data->data[j]))||isnan(cimagf(sftvec->data[i].data->data[j]))||isinf(cimagf(sftvec->data[i].data->data[j]))) {
        LogPrintf(LOG_DEBUG,"SFT %d : %f %e %e\n",i,sftvec->data[i].f0 + j*sftvec->data[i].deltaF,crealf(sftvec->data[i].data->data[j]),cimagf(sftvec->data[i].data->data[j]));
      }
    }
  } */

  /**********************************************************************************/
  /* 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;
  }
  LogPrintf(LOG_NORMAL,"%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,&uvar.ndim,uvar.bins_factor)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALComputeFreqGridParams() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }

  /**********************************************************************************/
  /* COMPUTE THE FINE GRID PARAMETERS */
  /**********************************************************************************/

  /* compute the fine grid on the binary parameters */
  if (XLALComputeBinaryGridParams(&bingridparams,pspace.space,pspace.span,pspace.tseg,uvar.mismatch,uvar.coverage)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALComputeBinaryGridParams() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_NORMAL,"%s : computed the binary parameter space grid\n",__func__);

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

  /* convert sfts to downsample dtimeseries */
  if (XLALSFTVectorToCOMPLEX8TimeSeriesArray(&dstimevec,sftvec)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALSFTVectorToCOMPLEX8TimeSeriesArray() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_NORMAL,"%s : converted SFTs to downsampled timeseries\n",__func__);

  /**********************************************************************************/
  /* OPEN INTERMEDIATE RESULTS FILE */
  /**********************************************************************************/

  /* if (XLALOpenSemiCoherentResultsFile(&cfp,newnewtemp,&pspace,clargs,&uvar,1)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALOpenCoherentResultsFile() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_NORMAL,"%s : opened coherent results file.\n",__func__); */

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

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

  /**********************************************************************************/
  /* OPEN RESULTS FILE */
  /**********************************************************************************/

  if (XLALOpenSemiCoherentResultsFile(&sfp,newnewtemp,&pspace,clargs,&uvar)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALOutputBayesResults() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_NORMAL,"%s : output results to file.\n",__func__);

   /**********************************************************************************/
  /* COMPUTE THE STATISTICS ON THE FINE GRID */
  /**********************************************************************************/

  /* compute the semi-coherent detection statistic on the fine grid */
  if (XLALComputeSemiCoherentStat(sfp,dmpower,&pspace,freqgridparams,bingridparams,uvar.ntoplist,uvar.with_xbins)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALComputeSemiCoherentStat() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  fclose(sfp);
  LogPrintf(LOG_NORMAL,"%s : computed the semi-coherent statistic\n",__func__);

  /**********************************************************************************/
  /* CLEAN UP */
  /**********************************************************************************/

  /* move the temporary directory to the final location */
  if (uvar.tempdir) {
    CHAR newoutputdir[LONGSTRINGLENGTH];
    sprintf(newoutputdir,"%s/%.3f-%.3f",uvar.outputdir,uvar.freq,uvar.freq+uvar.freqband);
    if (rename(newnewtemp,newoutputdir)) {
      LogPrintf(LOG_CRITICAL,"%s : unable to move final results directory %s -> %s.  Exiting.\n",__func__,newnewtemp,newoutputdir);
      return 1;
    }
  }
  LogPrintf(LOG_DEBUG,"%s : moved the results from the temp space.\n",__func__);

  /* clean up the parameter space */
  if (XLALFreeParameterSpace(&pspace)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALFreeParameterSpace() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_DEBUG,"%s : freed the parameter space\n",__func__);

  /* clean up the demodulated power */
  if (XLALFreeREAL4DemodulatedPowerVector(dmpower)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALFreeREAL4DemodulatedPowerVector() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_DEBUG,"%s : freed the demodulated power\n",__func__);

  /* free un-needed downsampled timeseries */
  for (i=0;i<dstimevec->length;i++) {
    XLALDestroyCOMPLEX8TimeSeries(dstimevec->data[i]);
  }
  XLALFree(dstimevec->data);
  XLALFree(dstimevec);
  LogPrintf(LOG_DEBUG,"%s : freed the downsampled timeseries memory\n",__func__);

  /* free frequency grid - the contents of each segment have been moved to the power structure and are freed later */
  XLALFree(freqgridparams->segment);
  XLALFree(freqgridparams);

  /* free un-needed original SFT vector */
  XLALDestroySFTVector(sftvec);
  LogPrintf(LOG_DEBUG,"%s : Freed the SFT memory\n",__func__);

  /* free semi-coherent results */
 /*  XLALDestroyREAL8Vector(SemiCo); */
/*   LogPrintf(LOG_DEBUG,"%s : Freed the semi-coherent results memory\n",__func__); */

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

  /* did we forget anything ? */
  LALCheckMemoryLeaks();
  LogPrintf(LOG_DEBUG,"%s : successfully checked memory leaks.\n",__func__);

  LogPrintf(LOG_NORMAL,"%s : successfully completed.\n",__func__);
  return 0;

} /* end of main */
示例#19
0
/**
 * load a full multi-dim template grid from the file init->gridFile,
 * the file-format is: lines of 6 columns, which are:
 *
 * Freq   Alpha  Delta  f1dot  f2dot  f3dot
 *
 * \note
 * *) this function returns the effective spinRange covered by the read-in template bank
 * by storing it in scan->spinRange, potentially overwriting any previous user-input values in there.
 *
 * *) a possible future extension should probably *clip* the template-bank to the user-specified ranges,
 * then return the effective ranges spanned by the resultant template bank.
 *
 * *) in order to avoid surprises until such a feature is implemented, we currently return an error if
 * any of the input spinRanges are non-zero
 *
 */
int
XLALLoadFullGridFile ( DopplerFullScanState *scan,
                       const DopplerFullScanInit *init
                       )
{
  XLAL_CHECK ( (scan != NULL) && (init != NULL), XLAL_EINVAL );
  XLAL_CHECK ( init->gridFile != NULL, XLAL_EINVAL );
  XLAL_CHECK ( scan->state == STATE_IDLE, XLAL_EINVAL );

  REAL8VectorList XLAL_INIT_DECL(head);
  REAL8VectorList *tail = NULL;
  REAL8Vector *entry = NULL;
  UINT4 numTemplates;
  FILE *fp;


  /* Check that all user-input spin- and sky-ranges are zero, otherwise fail!
   *
   * NOTE: In the future we should allow combining the user-input ranges with
   * those found in the grid-file by forming the intersection, ie *clipping*
   * of the read-in grids to the user-input ranges.
   * Right now we require empty ranges input, and report back the ranges from the grid-file
   *
   */
  if ( init->searchRegion.skyRegionString != NULL ) {
    XLAL_ERROR ( XLAL_EINVAL, "\nnon-NULL skyRegion input currently not supported! skyRegion = '%s'\n\n", init->searchRegion.skyRegionString );
  }
  for ( UINT4 s = 0; s < PULSAR_MAX_SPINS; s ++ )
    {
      if ( (init->searchRegion.fkdot[s] != 0) || (init->searchRegion.fkdotBand[s] != 0 )) {
        XLAL_ERROR ( XLAL_EINVAL, "\nnon-zero input spinRanges currently not supported! fkdot[%d] = %g, fkdotBand[%d] = %g\n\n",
                     s, init->searchRegion.fkdot[s], s, init->searchRegion.fkdotBand[s] );
      }
    } /* for s < max_spins */

  /* open input data file */
  XLAL_CHECK ( (fp = LALFopen (init->gridFile, "r")) != NULL, XLAL_ESYS, "Could not open data-file: `%s`\n\n", init->gridFile );

  /* prepare grid-entry buffer */
  XLAL_CHECK ( (entry = XLALCreateREAL8Vector ( 6 ) ) != NULL, XLAL_EFUNC );

  /* keep track of the sky- and spinRanges spanned by the template bank */
  REAL8 FreqMax  = - LAL_REAL4_MAX, FreqMin  = LAL_REAL4_MAX;   // only using REAL4 ranges to avoid over/under flows, and should be enough
  REAL8 f1dotMax = - LAL_REAL4_MAX, f1dotMin = LAL_REAL4_MAX;
  REAL8 f2dotMax = - LAL_REAL4_MAX, f2dotMin = LAL_REAL4_MAX;
  REAL8 f3dotMax = - LAL_REAL4_MAX, f3dotMin = LAL_REAL4_MAX;

  REAL8 alphaMax = - LAL_REAL4_MAX, alphaMin = LAL_REAL4_MAX;
  REAL8 deltaMax = - LAL_REAL4_MAX, deltaMin = LAL_REAL4_MAX;

  /* parse this list of lines into a full grid */
  numTemplates = 0;
  tail = &head;         /* head will remain empty! */
  CHAR line[2048];
  while ( ! feof ( fp ) && ! ferror ( fp ) && fgets( line, sizeof(line), fp ) != NULL )
    {

      // Skip over any comment lines
      if ( line[0] == '#' || line[0] == '%' ) {
        continue;
      }

      // File format expects lines containing 6 columns: Freq   Alpha  Delta  f1dot  f2dot  f3dot
      REAL8 Freq, Alpha, Delta, f1dot, f2dot, f3dot;
      if ( 6 != sscanf( line, "%" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT " %" LAL_REAL8_FORMAT "\n",
                        &Freq, &Alpha, &Delta, &f1dot, &f2dot, &f3dot ) )
        {
          XLALPrintError ("ERROR: Failed to parse 6 REAL8's from line %d in grid-file '%s'\n\n", numTemplates + 1, init->gridFile);
          if ( head.next ) {
            XLALREAL8VectorListDestroy (head.next);
          }
          XLAL_ERROR ( XLAL_EINVAL );
        }

      /* keep track of maximal spans */
      alphaMin = fmin ( Alpha, alphaMin );
      deltaMin = fmin ( Delta, deltaMin );
      FreqMin  = fmin ( Freq,  FreqMin );
      f1dotMin = fmin ( f1dot, f1dotMin );
      f2dotMin = fmin ( f2dot, f2dotMin );
      f3dotMin = fmin ( f3dot, f3dotMin );

      alphaMax = fmax ( Alpha, alphaMax );
      deltaMax = fmax ( Delta, deltaMax );
      FreqMax  = fmax ( Freq,  FreqMax );
      f1dotMax = fmax ( f1dot, f1dotMax );
      f2dotMax = fmax ( f2dot, f2dotMax );
      f3dotMax = fmax ( f3dot, f3dotMax );

      /* add this entry to template-bank list */
      entry->data[0] = Freq;
      entry->data[1] = Alpha;
      entry->data[2] = Delta;
      entry->data[3] = f1dot;
      entry->data[4] = f2dot;
      entry->data[5] = f3dot;

      if ( (tail = XLALREAL8VectorListAddEntry (tail, entry)) == NULL )
        {
          if ( head.next ) {
            XLALREAL8VectorListDestroy (head.next);
          }
          XLAL_ERROR ( XLAL_EINVAL );
        }

      numTemplates ++ ;

    } /* while !feof(fp) && ... */
  if ( ferror ( fp ) ) {
    XLAL_ERROR ( XLAL_EIO );
  }

  XLALDestroyREAL8Vector ( entry );

  /* ---------- update scan-state  ---------- */

  // ----- report back ranges actually spanned by grid-file

  CHAR *skyRegionString = NULL;
  REAL8 eps = LAL_REAL8_EPS;
  XLAL_CHECK ( (skyRegionString = XLALSkySquare2String ( alphaMin, deltaMin, (alphaMax - alphaMin) + eps, (deltaMax - deltaMin) + eps )) != NULL, XLAL_EFUNC );

  // note: we slight expanded the enclosing sky-square by eps to avoid complaints when a grid-file contains
  // only points in a line, which is perfectly valid here.
  XLAL_CHECK ( XLALParseSkyRegionString ( &scan->skyRegion, skyRegionString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALFree ( skyRegionString );

  scan->spinRange.fkdot[0]     = FreqMin;
  scan->spinRange.fkdotBand[0] = FreqMax - FreqMin;

  scan->spinRange.fkdot[1]     = f1dotMin;
  scan->spinRange.fkdotBand[1] = f1dotMax - f1dotMin;

  scan->spinRange.fkdot[2]     = f2dotMin;
  scan->spinRange.fkdotBand[2] = f2dotMax - f2dotMin;

  scan->spinRange.fkdot[3]     = f3dotMin;
  scan->spinRange.fkdotBand[3] = f3dotMax - f3dotMin;

  scan->numTemplates = numTemplates;
  scan->covering = head.next;   /* pass result (without head!) */
  scan->thisGridPoint = scan->covering;         /* init to start */

  XLALPrintInfo ( "Template grid: nTot = %.0f\n", 1.0 * numTemplates );
  XLALPrintInfo ( "Spanned ranges: Freq in [%g, %g], f1dot in [%g, %g], f2dot in [%g, %g], f3dot in [%g, %g]\n",
                  FreqMin, FreqMax, f1dotMin, f1dotMax, f2dotMin, f2dotMax, f3dotMin, f3dotMax );

  return XLAL_SUCCESS;

} /* XLALLoadFullGridFile() */
示例#20
0
/**
 * Determine the 95% confidence level upper limit at a particular sky location from the loudest IHS value
 * \param [out] ul        Pointer to an UpperLimit struct
 * \param [in]  params    Pointer to UserInput_t
 * \param [in]  ffdata    Pointer to ffdataStruct
 * \param [in]  ihsmaxima Pointer to an ihsMaximaStruct
 * \param [in]  ihsfar    Pointer to an ihsfarStruct
 * \param [in]  fbinavgs  Pointer to a REAL4Vector of the 2nd FFT background powers
 * \return Status value
 */
INT4 skypoint95UL(UpperLimit *ul, UserInput_t *params, ffdataStruct *ffdata, ihsMaximaStruct *ihsmaxima, ihsfarStruct *ihsfar, REAL4Vector *fbinavgs)
{

    XLAL_CHECK( ul != NULL && params != NULL && ffdata != NULL && ihsmaxima != NULL && ihsfar!= NULL && fbinavgs != NULL, XLAL_EINVAL );

    INT4 ULdetermined = 0;

    INT4 minrows = (INT4)round(2.0*params->dfmin*params->Tsft)+1;

    //Allocate vectors
    XLAL_CHECK( (ul->fsig = XLALCreateREAL8Vector((ihsmaxima->rows-minrows)+1)) != NULL, XLAL_EFUNC );
    XLAL_CHECK( (ul->period = XLALCreateREAL8Vector((ihsmaxima->rows-minrows)+1)) != NULL, XLAL_EFUNC );
    XLAL_CHECK( (ul->moddepth = XLALCreateREAL8Vector((ihsmaxima->rows-minrows)+1)) != NULL, XLAL_EFUNC );
    XLAL_CHECK( (ul->ULval = XLALCreateREAL8Vector((ihsmaxima->rows-minrows)+1)) != NULL, XLAL_EFUNC );
    XLAL_CHECK( (ul->effSNRval = XLALCreateREAL8Vector((ihsmaxima->rows-minrows)+1)) != NULL, XLAL_EFUNC );

    //Initialize solver
    const gsl_root_fsolver_type *T = gsl_root_fsolver_brent;
    gsl_root_fsolver *s = NULL;
    XLAL_CHECK( (s = gsl_root_fsolver_alloc (T)) != NULL, XLAL_EFUNC );
    gsl_function F;
    switch (params->ULsolver) {
    case 1:
        F.function = &gsl_ncx2cdf_withouttinyprob_solver;           //double precision, without the extremely tiny probability part
        break;
    case 2:
        F.function = &gsl_ncx2cdf_float_solver;   //single precision
        break;
    case 3:
        F.function = &gsl_ncx2cdf_solver;         //double precision
        break;
    case 4:
        F.function = &ncx2cdf_float_withouttinyprob_withmatlabchi2cdf_solver;   //single precision, w/ Matlab-based chi2cdf function
        break;
    case 5:
        F.function = &ncx2cdf_withouttinyprob_withmatlabchi2cdf_solver;         //double precision, w/ Matlab-based chi2cdf function
        break;
    default:
        F.function = &gsl_ncx2cdf_float_withouttinyprob_solver;     //single precision, without the extremely tiny probability part
        break;
    }
    struct ncx2cdf_solver_params pars;

    //loop over modulation depths
    for (INT4 ii=minrows; ii<=ihsmaxima->rows; ii++) {
        REAL8 loudestoutlier = 0.0, loudestoutlierminusnoise = 0.0, loudestoutliernoise = 0.0;
        INT4 jjbinofloudestoutlier = 0, locationofloudestoutlier = -1;
        INT4 startpositioninmaximavector = (ii-2)*ffdata->numfbins - ((ii-1)*(ii-1)-(ii-1))/2;
        REAL8 moddepth = 0.5*(ii-1.0)/params->Tsft;                             //"Signal" modulation depth

        //loop over frequency bins
        for (INT4 jj=0; jj<ffdata->numfbins-(ii-1); jj++) {
            INT4 locationinmaximavector = startpositioninmaximavector + jj;      //Current location in IHS maxima vector
            REAL8 noise = ihsfar->expectedIHSVector->data[ihsmaxima->locations->data[locationinmaximavector] - 5];  //Expected noise

            //Sum across multiple frequency bins scaling noise each time with average noise floor
            REAL8 totalnoise = 0.0;
            for (INT4 kk=0; kk<ii; kk++) totalnoise += fbinavgs->data[jj+kk];
            totalnoise = noise*totalnoise;

            REAL8 ihsminusnoise = ihsmaxima->maxima->data[locationinmaximavector] - totalnoise;    //IHS value minus noise

            REAL8 fsig = params->fmin - params->dfmax + (0.5*(ii-1.0) + jj - 6.0)/params->Tsft;        //"Signal" frequency

            if (ihsminusnoise>loudestoutlierminusnoise &&
                    (fsig>=params->ULfmin && fsig<params->ULfmin+params->ULfspan) &&
                    (moddepth>=params->ULminimumDeltaf && moddepth<=params->ULmaximumDeltaf)) {
                loudestoutlier = ihsmaxima->maxima->data[locationinmaximavector];
                loudestoutliernoise = totalnoise;
                loudestoutlierminusnoise = ihsminusnoise;
                locationofloudestoutlier = ihsmaxima->locations->data[locationinmaximavector];
                jjbinofloudestoutlier = jj;
            }
        } /* for jj < ffdata->numfbins-(ii-1) */

        if (locationofloudestoutlier!=-1) {
            //We do a root finding algorithm to find the delta value required so that only 5% of a non-central chi-square
            //distribution lies below the maximum value.
            REAL8 initialguess = ncx2inv_float(0.95, 2.0*loudestoutliernoise, 2.0*loudestoutlierminusnoise);
            XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );

            REAL8 lo = 0.001*initialguess, hi = 10.0*initialguess;
            pars.val = 2.0*loudestoutlier;
            pars.dof = 2.0*loudestoutliernoise;
            pars.ULpercent = 0.95;
            F.params = &pars;
            XLAL_CHECK( gsl_root_fsolver_set(s, &F, lo, hi) == GSL_SUCCESS, XLAL_EFUNC );

            INT4 status = GSL_CONTINUE;
            INT4 max_iter = 100;
            REAL8 root = 0.0;
            INT4 jj = 0;
            while (status==GSL_CONTINUE && jj<max_iter) {
                jj++;
                status = gsl_root_fsolver_iterate(s);
                XLAL_CHECK( status == GSL_CONTINUE || status == GSL_SUCCESS, XLAL_EFUNC, "gsl_root_fsolver_iterate() failed with code %d\n", status );
                root = gsl_root_fsolver_root(s);
                lo = gsl_root_fsolver_x_lower(s);
                hi = gsl_root_fsolver_x_upper(s);
                status = gsl_root_test_interval(lo, hi, 0.0, 0.001);
                XLAL_CHECK( status == GSL_CONTINUE || status == GSL_SUCCESS, XLAL_EFUNC, "gsl_root_test_interval() failed with code %d\n", status );
            } /* while status==GSL_CONTINUE and jj<max_iter */
            XLAL_CHECK( status == GSL_SUCCESS, XLAL_EFUNC, "Root finding iteration (%d/%d) failed with code %d\n", jj, max_iter, status );

            //Convert the root value to an h0 value
            REAL8 h0 = ihs2h0(root, params);

            //Store values in the upper limit struct
            ul->fsig->data[ii-minrows] = params->fmin - params->dfmax + (0.5*(ii-1.0) + jjbinofloudestoutlier - 6.0)/params->Tsft;
            ul->period->data[ii-minrows] = params->Tobs/locationofloudestoutlier;
            ul->moddepth->data[ii-minrows] = 0.5*(ii-1.0)/params->Tsft;
            ul->ULval->data[ii-minrows] = h0;
            ul->effSNRval->data[ii-minrows] = unitGaussianSNR(root, pars.dof);
            ULdetermined++;
        } // if locationofloudestoutlier != -1
    } // for ii=minrows --> maximum rows

    //Signal an error if we didn't find something above the noise level
    XLAL_CHECK( ULdetermined != 0, XLAL_EFUNC, "Failed to reach a louder outlier minus noise greater than 0\n" );

    gsl_root_fsolver_free(s);

    return XLAL_SUCCESS;

}
void
LALTaylorT4WaveformForInjection(
                             LALStatus        *status,
                             CoherentGW       *waveform,
                             InspiralTemplate *params,
                             PPNParamStruc  *ppnParams
                             )
{
  UINT4        count, i;
  REAL8       phiC;

  REAL4Vector *a   = NULL;      /* pointers to generated amplitude  data */
  REAL4Vector *ff  = NULL;      /* pointers to generated  frequency data */
  REAL8Vector *phi = NULL;      /* pointer to generated phase data */

  InspiralInit paramsInit;


  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* Make sure parameter and waveform structures exist. */
  ASSERT( params, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );
  ASSERT(waveform, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
  ASSERT( !( waveform->a ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );
  ASSERT( !( waveform->h ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );
  ASSERT( !( waveform->f ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );
  ASSERT( !( waveform->phi ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );

  params->ampOrder = (LALPNOrder) 0;
  XLALPrintInfo( "WARNING: Amp Order has been reset to %d", params->ampOrder);

  /* Compute some parameters*/
  LALInspiralInit(status->statusPtr, params, &paramsInit);
  CHECKSTATUSPTR(status);

  if (paramsInit.nbins == 0)
  {
      XLALPrintError( "Error: Estimated length of injection is zero.\n" );
      ABORT( status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE );
  }

  /* Now we can allocate memory and vector for coherentGW structure*/
  ff  = XLALCreateREAL4Vector( paramsInit.nbins );
  a   = XLALCreateREAL4Vector( 2*paramsInit.nbins );
  phi = XLALCreateREAL8Vector( paramsInit.nbins );
  if ( !ff || !a || !phi )
  {
    if ( ff )
      XLALDestroyREAL4Vector( ff );
    if ( a )
      XLALDestroyREAL4Vector( a );
    if ( phi )
      XLALDestroyREAL8Vector( phi );
    ABORTXLAL( status );
  }

  /* Call the engine function */
  LALTaylorT4WaveformEngine(status->statusPtr, NULL, NULL, a, ff,
                             phi, &count, params, &paramsInit);
  BEGINFAIL( status )
  {
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
  }
  ENDFAIL( status );

  /*wrap the phase vector*/
  phiC =  phi->data[count-1] ;
  for (i = 0; i < count; i++)
  {
    phi->data[i] =  phi->data[i] - phiC + ppnParams->phi;
  }

  /* Allocate the waveform structures. */
  if ( ( waveform->a = (REAL4TimeVectorSeries *)
         LALCalloc(1, sizeof(REAL4TimeVectorSeries) ) ) == NULL )
  {
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORT( status, LALINSPIRALH_EMEM,
           LALINSPIRALH_MSGEMEM );
  }
  if ( ( waveform->f = (REAL4TimeSeries *)
         LALCalloc(1, sizeof(REAL4TimeSeries) ) ) == NULL )
  {
    LALFree( waveform->a ); waveform->a = NULL;
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORT( status, LALINSPIRALH_EMEM,
           LALINSPIRALH_MSGEMEM );
  }
  if ( ( waveform->phi = (REAL8TimeSeries *)
         LALCalloc(1, sizeof(REAL8TimeSeries) ) ) == NULL )
  {
    LALFree( waveform->a ); waveform->a = NULL;
    LALFree( waveform->f ); waveform->f = NULL;
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORT( status, LALINSPIRALH_EMEM,
               LALINSPIRALH_MSGEMEM );
  }

  waveform->a->data = XLALCreateREAL4VectorSequence( (UINT4)count, 2 );
  waveform->f->data = XLALCreateREAL4Vector( count );
  waveform->phi->data = XLALCreateREAL8Vector( count );

  if ( !waveform->a->data || !waveform->f->data || !waveform->phi->data )
  {
    if ( waveform->a->data )
      XLALDestroyREAL4VectorSequence( waveform->a->data );
    if ( waveform->f->data )
      XLALDestroyREAL4Vector( waveform->f->data );
    if ( waveform->phi->data )
      XLALDestroyREAL8Vector( waveform->phi->data );
    LALFree( waveform->a ); waveform->a = NULL;
    LALFree( waveform->f ); waveform->f = NULL;
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORTXLAL( status );
  }

  memcpy(waveform->f->data->data , ff->data, count*(sizeof(REAL4)));
  memcpy(waveform->a->data->data , a->data, 2*count*(sizeof(REAL4)));
  memcpy(waveform->phi->data->data ,phi->data, count*(sizeof(REAL8)));

  waveform->a->deltaT = waveform->f->deltaT = waveform->phi->deltaT
    = ppnParams->deltaT;

  waveform->a->sampleUnits    = lalStrainUnit;
  waveform->f->sampleUnits    = lalHertzUnit;
  waveform->phi->sampleUnits  = lalDimensionlessUnit;
  waveform->position = ppnParams->position;
  waveform->psi = ppnParams->psi;

  snprintf( waveform->a->name, LALNameLength,   "T4 inspiral amplitude" );
  snprintf( waveform->f->name, LALNameLength,   "T4 inspiral frequency" );
  snprintf( waveform->phi->name, LALNameLength, "T4 inspiral phase" );

  /* --- fill some output ---*/
  ppnParams->tc     = (double)(count-1) / params->tSampling ;
  ppnParams->length = count;
  ppnParams->dfdt   = ((REAL4)(waveform->f->data->data[count-1]
                    - waveform->f->data->data[count-2])) * ppnParams->deltaT;
  ppnParams->fStop  = params->fFinal;
  ppnParams->termCode        = GENERATEPPNINSPIRALH_EFSTOP;
  ppnParams->termDescription = GENERATEPPNINSPIRALH_MSGEFSTOP;

  ppnParams->fStart   = ppnParams->fStartIn;


  /* --- free memory --- */
  XLALDestroyREAL4Vector( ff );
  XLALDestroyREAL4Vector( a );
  XLALDestroyREAL8Vector( phi );

  DETATCHSTATUSPTR(status);
  RETURN (status);
}
/**
 * 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() */
示例#23
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()
示例#24
0
/**
 * Multi-IFO version of LALGetBinarytimes().
 * Get all binary-timings for all input detector-series.
 *
 */
void
LALGetMultiBinarytimes (LALStatus *status,				/**< pointer to LALStatus structure */
			MultiSSBtimes **multiBinary,			/**< [out] SSB-timings for all input detector-state series */
			const MultiSSBtimes *multiSSB,			/**< [in] SSB-timings for all input detector-state series */
			const MultiDetectorStateSeries *multiDetStates, /**< [in] detector-states at timestamps t_i */
			const BinaryOrbitParams *binaryparams,		/**< [in] source binary orbit parameters */
			LIGOTimeGPS refTime				/**< SSB reference-time T_0 for SSB-timing */
			)
{
  UINT4 X, numDetectors;
  MultiSSBtimes *ret = NULL;

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  /* check input */
  ASSERT (multiDetStates, status,COMPUTEFSTATC_ENULL, COMPUTEFSTATC_MSGENULL);
  ASSERT (multiDetStates->length, status,COMPUTEFSTATC_ENULL, COMPUTEFSTATC_MSGENULL);
  ASSERT (multiSSB, status,COMPUTEFSTATC_ENULL, COMPUTEFSTATC_MSGENULL);
  ASSERT ( *multiBinary == NULL, status,COMPUTEFSTATC_ENONULL, COMPUTEFSTATC_MSGENONULL);
  ASSERT (multiSSB != NULL, status,COMPUTEFSTATC_ENULL, COMPUTEFSTATC_MSGENULL);

  numDetectors = multiDetStates->length;

  if ( ( ret = LALCalloc( 1, sizeof( *ret ) )) == NULL ) {
    ABORT (status, COMPUTEFSTATC_EMEM, COMPUTEFSTATC_MSGEMEM);
  }
  ret->length = numDetectors;
  if ( ( ret->data = LALCalloc ( numDetectors, sizeof ( *ret->data ) )) == NULL ) {
    LALFree ( ret );
    ABORT (status, COMPUTEFSTATC_EMEM, COMPUTEFSTATC_MSGEMEM);
  }

  for ( X=0; X < numDetectors; X ++ )
    {
      SSBtimes *BinarytimesX = NULL;
      UINT4 numStepsX = multiDetStates->data[X]->length;

      ret->data[X] = LALCalloc ( 1, sizeof ( *(ret->data[X]) ) );
      BinarytimesX = ret->data[X];
      BinarytimesX->DeltaT = XLALCreateREAL8Vector ( numStepsX );
      if ( (BinarytimesX->Tdot = XLALCreateREAL8Vector ( numStepsX )) == NULL ) {
	XLALPrintError ("\nOut of memory!\n\n");
	goto failed;
      }
      /* printf("calling  LALGetBinarytimes\n"); */
      LALGetBinarytimes (status->statusPtr, BinarytimesX, multiSSB->data[X], multiDetStates->data[X], binaryparams, refTime);
      /* printf("finished  LALGetBinarytimes\n"); */
      if ( status->statusPtr->statusCode )
	{
	  XLALPrintError ( "\nCall to LALGetBinarytimes() has failed ... \n\n");
	  goto failed;
	}

      // NOTE! It seems the old LAL-function *did not* set the reference time of the output binary-SSB vectors
      // so we 'fix' this here retro-actively, in order to facilitate comparison with the new XLAL function:
      BinarytimesX->refTime = multiSSB->data[X]->refTime;

    } /* for X < numDet */

  goto success;

 failed:
  /* free all memory allocated so far */
  XLALDestroyMultiSSBtimes ( ret );
  ABORT ( status, -1, "LALGetMultiBinarytimes failed" );

 success:
  (*multiBinary) = ret;

  DETATCHSTATUSPTR (status);
  RETURN(status);

} /* LALGetMultiBinarytimes() */
示例#25
0
/**
 * Test function to compute BSGL values from:
 * XLALComputeBSGL, from scratch
 * and from deprecated XLALComputeLineVeto and XLALComputeLineVetoArray
 * compare the results and exit if tolerance is violated.
 */
int
XLALCompareBSGLComputations ( const REAL4 TwoF,			/**< multi-detector  Fstat */
			     const UINT4 numDetectors,		/**< number of detectors */
			     const REAL4Vector *TwoFX,		/**< vector of single-detector Fstats */
			     const REAL4 Fstar0,		/**< amplitude prior normalization for lines */
			     const REAL4 *oLGX,			/**< array of single-detector prior line odds ratio, can be NULL */
			     const REAL4 tolerance		/**< tolerance for comparisons */
                          )
{

  /* conversions between old (rho) and new (F*) notation, REAL4 and REAL8 */
  REAL8 LVrho = exp( 0.25 * ( Fstar0 + log(70.0) ) );
  REAL4 oLG = 0.0;
  REAL8Vector *oLGXREAL8 = NULL;
  XLAL_CHECK ( (oLGXREAL8 = XLALCreateREAL8Vector ( numDetectors )) != NULL, XLAL_EFUNC );

  if ( oLGX ) {
    for ( UINT4 X = 0; X < numDetectors; X++ ) {
      oLGXREAL8->data[X] = (REAL8)oLGX[X];
      oLG += oLGX[X];
    }
  }
  else { /* if oLGX == NULL, assume oLGX=1/numDetectors for all X  ==> oLG = sumX oLGX = 1*/
    oLG = 1.0;
    for (UINT4 X = 0; X < numDetectors; X++) {
      oLGXREAL8->data[X] = 1.0/numDetectors; /* need to set this manually, as old functions still assume oLGX=1 instead */
    }
  } // if ( oLGX == NULL )

  /* further parameter pre-conversions for XLALComputeLineVetoArray() */
  REAL8 logRhoTerm = Fstar0;
  REAL8 logoLGX[numDetectors];
  for (UINT4 X = 0; X < numDetectors; X++) {
    logoLGX[X] = log(oLGXREAL8->data[X]);
  }

  /* compute BSGL "the pedestrian way", from Eq. (40) of Keitel, Prix, Papa, Leaci, Siddiqi, PR D 89, 064023 (2014),
   * explicit formula for numDet=2:
   * log10 BSGL = F - log ( e^F* + e^{F1}*oLG1/oLG + e^{F2}*oLG2/oLG )
   */
  REAL8 BSGL_extcomp_terms[3];
  BSGL_extcomp_terms[0] = exp(Fstar0)/oLG;
  REAL8 BSGL_extcomp_maxterm = BSGL_extcomp_terms[0];
  for (UINT4 X = 0; X < numDetectors; X++) {
    BSGL_extcomp_terms[1+X] = exp(0.5*TwoFX->data[X]);
    if ( oLGX ) {
      BSGL_extcomp_terms[1+X] *= oLGX[X]/oLG;
    }
    else {  /* oLGX=NULL is interpreted as oLGX[X]=1/numDetectors=0.5 for all X ==> oLG=1 */
      BSGL_extcomp_terms[1+X] *= 0.5/oLG;
    }
    if ( BSGL_extcomp_terms[1+X] > BSGL_extcomp_maxterm ) {
      BSGL_extcomp_maxterm = BSGL_extcomp_terms[1+X];
    }
  }
  REAL4 log10BSGL_extcomp_notallterms = 0.5*TwoF - log(BSGL_extcomp_maxterm);
  REAL8 BSGL_extcomp_denom = 0.0;
  for (UINT4 X = 0; X < 1+numDetectors; X++) {
    BSGL_extcomp_denom += BSGL_extcomp_terms[X];
  }
  REAL4 log10BSGL_extcomp_allterms = 0.5*TwoF - log( BSGL_extcomp_denom );

  /* these are not the log-Bayes-factor, as computed by XLALComputeBSGL(), so need to correct by log(1+1/oLG) */
  log10BSGL_extcomp_allterms    += log(1+1/oLG);
  log10BSGL_extcomp_notallterms += log(1+1/oLG);
  /* and actually switch to log10 */
  log10BSGL_extcomp_allterms    *= LAL_LOG10E;
  log10BSGL_extcomp_notallterms *= LAL_LOG10E;

  /* faster version: use only the leading term of the BSGL denominator sum */
  BSGLSetup *setup_noLogCorrection;
  XLAL_CHECK ( (setup_noLogCorrection = XLALCreateBSGLSetup ( numDetectors, Fstar0, oLGX, FALSE )) != NULL, XLAL_EFUNC );
  REAL4 log10BSGL_XLAL_notallterms = XLALComputeBSGL ( TwoF, TwoFX->data, setup_noLogCorrection );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeBSGL() failed with xlalErrno = %d\n", xlalErrno );
  XLALFree ( setup_noLogCorrection ); setup_noLogCorrection = NULL;

  /* more precise version: use all terms of the BSGL denominator sum */
  BSGLSetup *setup_withLogCorrection;
  XLAL_CHECK ( (setup_withLogCorrection = XLALCreateBSGLSetup ( numDetectors, Fstar0, oLGX, TRUE )) != NULL, XLAL_EFUNC );
  REAL4 log10BSGL_XLAL_allterms = XLALComputeBSGL ( TwoF, TwoFX->data, setup_withLogCorrection );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeBSGL() failed with xlalErrno = %d\n", xlalErrno );
  XLALFree ( setup_withLogCorrection ); setup_withLogCorrection = NULL;

  /* compute relative deviations */
  REAL4 diff_allterms    = fabs( log10BSGL_XLAL_allterms    - log10BSGL_extcomp_allterms    ) / ( 0.5 * ( log10BSGL_XLAL_allterms    + log10BSGL_extcomp_allterms    ));
  REAL4 diff_notallterms = fabs( log10BSGL_XLAL_notallterms - log10BSGL_extcomp_notallterms ) / ( 0.5 * ( log10BSGL_XLAL_notallterms + log10BSGL_extcomp_notallterms ));

  /* output results and deviations and return with error when tolerances are violated */
  printf ( "Externally recomputed     with  allterms: log10BSGL=%f\n",               log10BSGL_extcomp_allterms );
  printf ( "Externally recomputed     with !allterms: log10BSGL=%f\n",               log10BSGL_extcomp_notallterms );
  printf ( "XLALComputeBSGL()         with  allterms: log10BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_allterms,    diff_allterms );
  XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_allterms,    tolerance, "XLALComputeBSGL() with useAllTerms=TRUE" ) == XLAL_SUCCESS, XLAL_EFUNC );
  printf ( "XLALComputeBSGL()         with !allterms: log10BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_notallterms, diff_notallterms );
  XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_notallterms, tolerance, "XLALComputeBSGL() with useAllTerms=TRUE" ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* also test against deprecated rho-notation functions for consistency
   * need to correct for different prior parametrization,
   * log(BSGL_new)=LV_old+log(1+oLG)
   */
  REAL4 old_LV_corr = log(1+oLG);

  xlalErrno = 0;
  REAL4 log10BSGL_XLAL_rho_notallterms      = XLALComputeLineVeto      ( TwoF, TwoFX, LVrho, oLGXREAL8, FALSE );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVeto() failed with xlalErrno = %d\n", xlalErrno );
  log10BSGL_XLAL_rho_notallterms += old_LV_corr;
  log10BSGL_XLAL_rho_notallterms *= LAL_LOG10E;

  xlalErrno = 0;
  REAL4 log10BSGL_XLAL_rhoarray_notallterms = XLALComputeLineVetoArray ( TwoF, numDetectors, TwoFX->data, logRhoTerm, logoLGX, FALSE );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVetoArray() failed with xlalErrno = %d\n", xlalErrno );
  log10BSGL_XLAL_rhoarray_notallterms += old_LV_corr;
  log10BSGL_XLAL_rhoarray_notallterms *= LAL_LOG10E;

  xlalErrno = 0;
  REAL4 log10BSGL_XLAL_rho_allterms         = XLALComputeLineVeto      ( TwoF, TwoFX, LVrho, oLGXREAL8, TRUE );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVeto() failed with xlalErrno = %d\n", xlalErrno );
  log10BSGL_XLAL_rho_allterms += old_LV_corr;
  log10BSGL_XLAL_rho_allterms *= LAL_LOG10E;

  xlalErrno = 0;
  REAL4 log10BSGL_XLAL_rhoarray_allterms    = XLALComputeLineVetoArray ( TwoF, numDetectors, TwoFX->data, logRhoTerm, logoLGX, TRUE );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALComputeLineVetoArray() failed with xlalErrno = %d\n", xlalErrno );
  log10BSGL_XLAL_rhoarray_allterms += old_LV_corr;
  log10BSGL_XLAL_rhoarray_allterms *= LAL_LOG10E;

  REAL4 diff_rho_allterms         = fabs( log10BSGL_XLAL_rho_allterms         - log10BSGL_extcomp_allterms    ) / ( 0.5 * ( log10BSGL_XLAL_rho_allterms         + log10BSGL_extcomp_allterms ));
  REAL4 diff_rhoarray_allterms    = fabs( log10BSGL_XLAL_rhoarray_allterms    - log10BSGL_extcomp_allterms    ) / ( 0.5 * ( log10BSGL_XLAL_rhoarray_allterms    + log10BSGL_extcomp_allterms ));
  REAL4 diff_rho_notallterms      = fabs( log10BSGL_XLAL_rho_notallterms      - log10BSGL_extcomp_notallterms ) / ( 0.5 * ( log10BSGL_XLAL_rho_notallterms      + log10BSGL_extcomp_notallterms ));
  REAL4 diff_rhoarray_notallterms = fabs( log10BSGL_XLAL_rhoarray_notallterms - log10BSGL_extcomp_notallterms ) / ( 0.5 * ( log10BSGL_XLAL_rhoarray_notallterms + log10BSGL_extcomp_notallterms ));

  printf( "Legacy functions with rho-notation, corrected as BSGL_new=LV_old+log(1+oLG)=LV_old+%f:\n", old_LV_corr );
  printf ( "XLALComputeLineVeto()       with  allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rho_allterms,         diff_rho_allterms );
  XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rho_allterms,         tolerance, "XLALComputeLineVeto()       with useAllTerms=TRUE" )  == XLAL_SUCCESS, XLAL_EFUNC );
  printf ( "XLALComputeLineVetoArray()  with  allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rhoarray_allterms,    diff_rhoarray_allterms );
  XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rhoarray_allterms,    tolerance, "XLALComputeLineVetoArray()  with useAllTerms=TRUE" )  == XLAL_SUCCESS, XLAL_EFUNC );
  printf ( "XLALComputeLineVeto()       with !allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rho_notallterms,      diff_rho_notallterms );
  XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rho_notallterms,      tolerance, "XLALComputeLineVeto()       with useAllTerms=FALSE" ) == XLAL_SUCCESS, XLAL_EFUNC );
  printf ( "XLALComputeLineVetoArray()  with !allterms: BSGL=%f (rel. dev.: %f)", log10BSGL_XLAL_rhoarray_notallterms, diff_rhoarray_notallterms );
  XLAL_CHECK ( XLALCheckBSGLDifferences ( diff_rhoarray_notallterms, tolerance, "XLALComputeLineVetoArray()  with useAllTerms=FALSE" ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLALDestroyREAL8Vector(oLGXREAL8);

  return XLAL_SUCCESS;

} /* XLALCompareBSGLComputations() */
/**
 * Generates the ringdown wave associated with the given real
 * and imaginary parts of the inspiral waveform. The parameters of
 * the ringdown, such as amplitude and phase offsets, are determined
 * by solving the linear equations defined in the DCC document T1100433.
 * In the linear equations Ax=y,
 * A is a 16-by-16 matrix depending on QNM (complex) frequencies,
 * x is a 16-d vector of the 8 unknown complex QNM amplitudes,
 * y is a 16-d vector depending on inspiral-plunge waveforms and their derivatives near merger.
 */
static INT4 XLALSimIMREOBHybridRingdownWave(
  REAL8Vector          *rdwave1,   /**<< OUTPUT, Real part of ringdown waveform */
  REAL8Vector          *rdwave2,   /**<< OUTPUT, Imag part of ringdown waveform */
  const REAL8           dt,        /**<< Sampling interval */
  const REAL8           mass1,     /**<< First component mass (in Solar masses) */
  const REAL8           mass2,     /**<< Second component mass (in Solar masses) */
  REAL8VectorSequence  *inspwave1, /**<< Values and derivs of real part inspiral waveform */
  REAL8VectorSequence  *inspwave2, /**<< Values and derivs of imag part inspiral waveform */
  COMPLEX16Vector      *modefreqs, /**<< Complex freqs of ringdown (scaled by total mass) */
  REAL8Vector          *matchrange /**<< Times which determine the comb of ringdown attachment */
  )
{

  /* XLAL error handling */
  INT4 errcode = XLAL_SUCCESS;

  /* For checking GSL return codes */
  INT4 gslStatus;

  UINT4 i, j, k, nmodes = 8;

  /* Sampling rate from input */
  REAL8 t1, t2, t3, t4, t5, rt;
  gsl_matrix *coef;
  gsl_vector *hderivs;
  gsl_vector *x;
  gsl_permutation *p;
  REAL8Vector *modeamps;
  int s;
  REAL8 tj;
  REAL8 m;

  /* mass in geometric units */
  m  = (mass1 + mass2) * LAL_MTSUN_SI;
  t5 = (matchrange->data[0] - matchrange->data[1]) * m;
  rt = -t5 / 5.;

  t4 = t5 + rt;
  t3 = t4 + rt;
  t2 = t3 + rt;
  t1 = t2 + rt;
  
  if ( inspwave1->length != 3 || inspwave2->length != 3 ||
		modefreqs->length != nmodes )
  {
    XLAL_ERROR( XLAL_EBADLEN );
  }

  /* Solving the linear system for QNMs amplitude coefficients using gsl routine */
  /* Initiate matrices and supporting variables */
  XLAL_CALLGSL( coef = (gsl_matrix *) gsl_matrix_alloc(2 * nmodes, 2 * nmodes) );
  XLAL_CALLGSL( hderivs = (gsl_vector *) gsl_vector_alloc(2 * nmodes) );
  XLAL_CALLGSL( x = (gsl_vector *) gsl_vector_alloc(2 * nmodes) );
  XLAL_CALLGSL( p = (gsl_permutation *) gsl_permutation_alloc(2 * nmodes) );

  /* Check all matrices and variables were allocated */
  if ( !coef || !hderivs || !x || !p )
  {
    if (coef)    gsl_matrix_free(coef);
    if (hderivs) gsl_vector_free(hderivs);
    if (x)       gsl_vector_free(x);
    if (p)       gsl_permutation_free(p);

    XLAL_ERROR( XLAL_ENOMEM );
  }

  /* Define the linear system Ax=y */
  /* Matrix A (2*n by 2*n) has block symmetry. Define half of A here as "coef" */
  /* The half of A defined here corresponds to matrices M1 and -M2 in the DCC document T1100433 */ 
  /* Define y here as "hderivs" */
  for (i = 0; i < nmodes; ++i)
  {
	gsl_matrix_set(coef, 0, i, 1);
	gsl_matrix_set(coef, 1, i, - cimag(modefreqs->data[i]));
	gsl_matrix_set(coef, 2, i, exp(-cimag(modefreqs->data[i])*t1) * cos(creal(modefreqs->data[i])*t1));
	gsl_matrix_set(coef, 3, i, exp(-cimag(modefreqs->data[i])*t2) * cos(creal(modefreqs->data[i])*t2));
	gsl_matrix_set(coef, 4, i, exp(-cimag(modefreqs->data[i])*t3) * cos(creal(modefreqs->data[i])*t3));
	gsl_matrix_set(coef, 5, i, exp(-cimag(modefreqs->data[i])*t4) * cos(creal(modefreqs->data[i])*t4));
	gsl_matrix_set(coef, 6, i, exp(-cimag(modefreqs->data[i])*t5) * cos(creal(modefreqs->data[i])*t5));
	gsl_matrix_set(coef, 7, i, exp(-cimag(modefreqs->data[i])*t5) * 
				      (-cimag(modefreqs->data[i]) * cos(creal(modefreqs->data[i])*t5)
				       -creal(modefreqs->data[i]) * sin(creal(modefreqs->data[i])*t5)));
	gsl_matrix_set(coef, 8, i, 0);
	gsl_matrix_set(coef, 9, i, - creal(modefreqs->data[i]));
	gsl_matrix_set(coef, 10, i, -exp(-cimag(modefreqs->data[i])*t1) * sin(creal(modefreqs->data[i])*t1));
	gsl_matrix_set(coef, 11, i, -exp(-cimag(modefreqs->data[i])*t2) * sin(creal(modefreqs->data[i])*t2));
	gsl_matrix_set(coef, 12, i, -exp(-cimag(modefreqs->data[i])*t3) * sin(creal(modefreqs->data[i])*t3));
	gsl_matrix_set(coef, 13, i, -exp(-cimag(modefreqs->data[i])*t4) * sin(creal(modefreqs->data[i])*t4));
	gsl_matrix_set(coef, 14, i, -exp(-cimag(modefreqs->data[i])*t5) * sin(creal(modefreqs->data[i])*t5));
	gsl_matrix_set(coef, 15, i, exp(-cimag(modefreqs->data[i])*t5) * 
				      ( cimag(modefreqs->data[i]) * sin(creal(modefreqs->data[i])*t5)
				       -creal(modefreqs->data[i]) * cos(creal(modefreqs->data[i])*t5)));
  }
  for (i = 0; i < 2; ++i)
  {
	gsl_vector_set(hderivs, i, inspwave1->data[(i + 1) * inspwave1->vectorLength - 1]);
	gsl_vector_set(hderivs, i + nmodes, inspwave2->data[(i + 1) * inspwave2->vectorLength - 1]);
	gsl_vector_set(hderivs, i + 6, inspwave1->data[i * inspwave1->vectorLength]);
	gsl_vector_set(hderivs, i + 6 + nmodes, inspwave2->data[i * inspwave2->vectorLength]);
  }
  gsl_vector_set(hderivs, 2, inspwave1->data[4]);
  gsl_vector_set(hderivs, 2 + nmodes, inspwave2->data[4]);
  gsl_vector_set(hderivs, 3, inspwave1->data[3]);
  gsl_vector_set(hderivs, 3 + nmodes, inspwave2->data[3]);
  gsl_vector_set(hderivs, 4, inspwave1->data[2]);
  gsl_vector_set(hderivs, 4 + nmodes, inspwave2->data[2]);
  gsl_vector_set(hderivs, 5, inspwave1->data[1]);
  gsl_vector_set(hderivs, 5 + nmodes, inspwave2->data[1]);
  
  /* Complete the definition for the rest half of A */
  for (i = 0; i < nmodes; ++i)
  {
	for (k = 0; k < nmodes; ++k)
	{
	  gsl_matrix_set(coef, i, k + nmodes, - gsl_matrix_get(coef, i + nmodes, k));
	  gsl_matrix_set(coef, i + nmodes, k + nmodes, gsl_matrix_get(coef, i, k));
	}
  }

  #if 0
  /* print ringdown-matching linear system: coefficient matrix and RHS vector */
  printf("\nRingdown matching matrix:\n");
  for (i = 0; i < 16; ++i)
  {
    for (j = 0; j < 16; ++j)
    {
      printf("%.12e ",gsl_matrix_get(coef,i,j));
    }
    printf("\n");
  }
  printf("RHS:  ");
  for (i = 0; i < 16; ++i)
  {
    printf("%.12e   ",gsl_vector_get(hderivs,i));
  }
  printf("\n");
  #endif

  /* Call gsl LU decomposition to solve the linear system */
  XLAL_CALLGSL( gslStatus = gsl_linalg_LU_decomp(coef, p, &s) );
  if ( gslStatus == GSL_SUCCESS )
  {
    XLAL_CALLGSL( gslStatus = gsl_linalg_LU_solve(coef, p, hderivs, x) );
  }
  if ( gslStatus != GSL_SUCCESS )
  {
    gsl_matrix_free(coef);
    gsl_vector_free(hderivs);
    gsl_vector_free(x);
    gsl_permutation_free(p);
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* Putting solution to an XLAL vector */
  modeamps = XLALCreateREAL8Vector(2 * nmodes);

  if ( !modeamps )
  {
    gsl_matrix_free(coef);
    gsl_vector_free(hderivs);
    gsl_vector_free(x);
    gsl_permutation_free(p);
    XLAL_ERROR( XLAL_ENOMEM );
  }

  for (i = 0; i < nmodes; ++i)
  {
	modeamps->data[i] = gsl_vector_get(x, i);
	modeamps->data[i + nmodes] = gsl_vector_get(x, i + nmodes);
  }

  /* Free all gsl linear algebra objects */
  gsl_matrix_free(coef);
  gsl_vector_free(hderivs);
  gsl_vector_free(x);
  gsl_permutation_free(p);

  /* Build ring-down waveforms */

  REAL8 timeOffset = fmod( matchrange->data[1], dt/m) * dt;

  for (j = 0; j < rdwave1->length; ++j)
  {
	tj = j * dt - timeOffset;
	rdwave1->data[j] = 0;
	rdwave2->data[j] = 0;
	for (i = 0; i < nmodes; ++i)
	{
	  rdwave1->data[j] += exp(- tj * cimag(modefreqs->data[i]))
			* ( modeamps->data[i] * cos(tj * creal(modefreqs->data[i]))
			+   modeamps->data[i + nmodes] * sin(tj * creal(modefreqs->data[i])) );
	  rdwave2->data[j] += exp(- tj * cimag(modefreqs->data[i]))
			* (- modeamps->data[i] * sin(tj * creal(modefreqs->data[i]))
			+   modeamps->data[i + nmodes] * cos(tj * creal(modefreqs->data[i])) );
	}
  }

  XLALDestroyREAL8Vector(modeamps);
  return errcode;
}
示例#27
0
/*============================================================
 * FUNCTION definitions
 *============================================================*/
int
main(int argc, char *argv[])
{
  static LALStatus       status;  /* LALStatus pointer */
  UserVariables_t XLAL_INIT_DECL(uvar);
  ConfigVariables_t XLAL_INIT_DECL(cfg);

  UINT4 k, numBins, numIFOs, maxNumSFTs, X, alpha;
  REAL8 Freq0, dFreq, normPSD;
  UINT4 finalBinSize, finalBinStep, finalNumBins;

  REAL8Vector *overSFTs = NULL; /* one frequency bin over SFTs */
  REAL8Vector *overIFOs = NULL; /* one frequency bin over IFOs */
  REAL8Vector *finalPSD = NULL; /* math. operation PSD over SFTs and IFOs */
  REAL8Vector *finalNormSFT = NULL; /* normalised SFT power */

  vrbflg = 1;	/* verbose error-messages */

  /* set LAL error-handler */
  lal_errhandler = LAL_ERR_EXIT;

  /* register and read user variables */
  if (initUserVars(argc, argv, &uvar) != XLAL_SUCCESS)
    return EXIT_FAILURE;

  MultiSFTVector *inputSFTs = NULL;
  if ( ( inputSFTs = XLALReadSFTs ( &cfg, &uvar ) ) == NULL )
    {
      XLALPrintError ("Call to XLALReadSFTs() failed with xlalErrno = %d\n", xlalErrno );
      return EXIT_FAILURE;
    }

  /* clean sfts if required */
  if ( XLALUserVarWasSet( &uvar.linefiles ) )
    {
      RandomParams *randPar=NULL;
      FILE *fpRand=NULL;
      INT4 seed, ranCount;

      if ( (fpRand = fopen("/dev/urandom", "r")) == NULL ) {
	fprintf(stderr,"Error in opening /dev/urandom" );
	return EXIT_FAILURE;
      }

      if ( (ranCount = fread(&seed, sizeof(seed), 1, fpRand)) != 1 ) {
	fprintf(stderr,"Error in getting random seed" );
	return EXIT_FAILURE;
      }

      LAL_CALL ( LALCreateRandomParams (&status, &randPar, seed), &status );

      LAL_CALL( LALRemoveKnownLinesInMultiSFTVector ( &status, inputSFTs, uvar.maxBinsClean, uvar.blocksRngMed, uvar.linefiles, randPar), &status);
      LAL_CALL ( LALDestroyRandomParams (&status, &randPar), &status);
      fclose(fpRand);
    } /* end cleaning */

  LogPrintf (LOG_DEBUG, "Computing spectrogram and PSD ... ");

  /* get power running-median rngmed[ |data|^2 ] from SFTs */
  MultiPSDVector *multiPSD = NULL;
  XLAL_CHECK_MAIN( ( multiPSD = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.blocksRngMed, NULL ) ) != NULL, XLAL_EFUNC);
  /* restrict this PSD to just the "physical" band if requested using {--Freq, --FreqBand} */
  if ( ( XLALCropMultiPSDandSFTVectors ( multiPSD, inputSFTs, cfg.firstBin, cfg.lastBin )) != XLAL_SUCCESS ) {
    XLALPrintError ("%s: XLALCropMultiPSDandSFTVectors (inputPSD, inputSFTs, %d, %d) failed with xlalErrno = %d\n", __func__, cfg.firstBin, cfg.lastBin, xlalErrno );
    return EXIT_FAILURE;
  }

  /* start frequency and frequency spacing */
  Freq0 = multiPSD->data[0]->data[0].f0;
  dFreq = multiPSD->data[0]->data[0].deltaF;

  /* number of raw bins in final PSD */
  numBins = multiPSD->data[0]->data[0].data->length;
  if ( (finalPSD = XLALCreateREAL8Vector ( numBins )) == NULL ) {
    LogPrintf (LOG_CRITICAL, "Out of memory!\n");
    return EXIT_FAILURE;
  }

  /* number of IFOs */
  numIFOs = multiPSD->length;
  if ( (overIFOs = XLALCreateREAL8Vector ( numIFOs )) == NULL ) {
    LogPrintf (LOG_CRITICAL, "Out of memory!\n");
    return EXIT_FAILURE;
  }

  /* maximum number of SFTs */
  maxNumSFTs = 0;
  for (X = 0; X < numIFOs; ++X) {
    maxNumSFTs = GSL_MAX(maxNumSFTs, multiPSD->data[X]->length);
  }
  if ( (overSFTs = XLALCreateREAL8Vector ( maxNumSFTs )) == NULL ) {
    LogPrintf (LOG_CRITICAL, "Out of memory!\n");
    return EXIT_FAILURE;
  }

  /* normalize rngmd(power) to get proper *single-sided* PSD: Sn = (2/Tsft) rngmed[|data|^2]] */
  normPSD = 2.0 * dFreq;

  /* loop over frequency bins in final PSD */
  for (k = 0; k < numBins; ++k) {

    /* loop over IFOs */
    for (X = 0; X < numIFOs; ++X) {

      /* number of SFTs for this IFO */
      UINT4 numSFTs = multiPSD->data[X]->length;

      /* copy PSD frequency bins and normalise multiPSD for later use */
      for (alpha = 0; alpha < numSFTs; ++alpha) {
	multiPSD->data[X]->data[alpha].data->data[k] *= normPSD;
	overSFTs->data[alpha] = multiPSD->data[X]->data[alpha].data->data[k];
      }

      /* compute math. operation over SFTs for this IFO */
      overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.PSDmthopSFTs);
      if ( isnan( overIFOs->data[X] ) )
        XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X );

    } /* for IFOs X */

    /* compute math. operation over IFOs for this frequency */
    finalPSD->data[k] = math_op(overIFOs->data, numIFOs, uvar.PSDmthopIFOs);
    if ( isnan ( finalPSD->data[k] ) )
      XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in finalPSD->data[k=%d] = NAN ... exiting\n", k );

  } /* for freq bins k */
  LogPrintfVerbatim ( LOG_DEBUG, "done.\n");

  /* compute normalised SFT power */
  if (uvar.outputNormSFT) {
    LogPrintf (LOG_DEBUG, "Computing normalised SFT power ... ");

    if ( (finalNormSFT = XLALCreateREAL8Vector ( numBins )) == NULL ) {
      LogPrintf (LOG_CRITICAL, "Out of memory!\n");
      return EXIT_FAILURE;
    }

    /* loop over frequency bins in SFTs */
    for (k = 0; k < numBins; ++k) {

      /* loop over IFOs */
      for (X = 0; X < numIFOs; ++X) {

	/* number of SFTs for this IFO */
	UINT4 numSFTs = inputSFTs->data[X]->length;

	/* compute SFT power */
	for (alpha = 0; alpha < numSFTs; ++alpha) {
	  COMPLEX8 bin = inputSFTs->data[X]->data[alpha].data->data[k];
	  overSFTs->data[alpha] = crealf(bin)*crealf(bin) + cimagf(bin)*cimagf(bin);
	}

	/* compute math. operation over SFTs for this IFO */
	overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.nSFTmthopSFTs);
	if ( isnan ( overIFOs->data[X] ))
          XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X );

      } /* over IFOs */

      /* compute math. operation over IFOs for this frequency */
      finalNormSFT->data[k] = math_op(overIFOs->data, numIFOs, uvar.nSFTmthopIFOs);
      if ( isnan( finalNormSFT->data[k] ) )
        XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in bin finalNormSFT->data[k=%d] = NAN ... exiting\n", k );

    } /* over freq bins */
    LogPrintfVerbatim ( LOG_DEBUG, "done.\n");
  }

  /* output spectrograms */
  if ( uvar.outputSpectBname ) {
    LAL_CALL ( LALfwriteSpectrograms ( &status, uvar.outputSpectBname, multiPSD ), &status );
  }

  /* ---------- if user requested it, output complete MultiPSDVector over IFOs X, timestamps and freq-bins into ASCI file(s) */
  if ( uvar.dumpMultiPSDVector ) {
    if ( XLALDumpMultiPSDVector ( uvar.outputPSD, multiPSD ) != XLAL_SUCCESS ) {
      XLALPrintError ("%s: XLALDumpMultiPSDVector() failed, xlalErrnor = %d\n", __func__, xlalErrno );
      return EXIT_FAILURE;
    }
  } /* if uvar.dumpMultiPSDVector */

  /* ----- if requested, compute data-quality factor 'Q' -------------------- */
  if ( uvar.outputQ )
    {
      REAL8FrequencySeries *Q;
      if ( (Q = XLALComputeSegmentDataQ ( multiPSD, cfg.dataSegment )) == NULL ) {
        XLALPrintError ("%s: XLALComputeSegmentDataQ() failed with xlalErrno = %d\n", __func__, xlalErrno );
        return EXIT_FAILURE;
      }
      if ( XLAL_SUCCESS != XLALWriteREAL8FrequencySeries_to_file ( Q, uvar.outputQ ) ) {
        return EXIT_FAILURE;
      }
      XLALDestroyREAL8FrequencySeries ( Q );
    } /* if outputQ */

  /* ---------- BINNING if requested ---------- */
  /* work out bin size */
  if (XLALUserVarWasSet(&uvar.binSize)) {
    finalBinSize = uvar.binSize;
  }
  else if (XLALUserVarWasSet(&uvar.binSizeHz)) {
    finalBinSize = (UINT4)floor(uvar.binSizeHz / dFreq + 0.5); /* round to nearest bin */
  }
  else {
    finalBinSize = 1;
  }

  /* work out bin step */
  if (XLALUserVarWasSet(&uvar.binStep)) {
    finalBinStep = uvar.binStep;
  }
  else if (XLALUserVarWasSet(&uvar.binStepHz)) {
    finalBinStep = (UINT4)floor(uvar.binStepHz / dFreq + 0.5); /* round to nearest bin */
  }
  else {
    finalBinStep = finalBinSize;
  }

  /* work out total number of bins */
  finalNumBins = (UINT4)floor((numBins - finalBinSize) / finalBinStep) + 1;

  /* write final PSD to file */
  if (XLALUserVarWasSet(&uvar.outputPSD)) {

    FILE *fpOut = NULL;

    if ((fpOut = fopen(uvar.outputPSD, "wb")) == NULL) {
      LogPrintf ( LOG_CRITICAL, "Unable to open output file %s for writing...exiting \n", uvar.outputPSD );
      return EXIT_FAILURE;
    }

    /* write header info in comments */
    if ( XLAL_SUCCESS != XLALOutputVersionString ( fpOut, 0 ) )
      XLAL_ERROR ( XLAL_EFUNC );

    /* write the command-line */
    for (int a = 0; a < argc; a++)
      fprintf(fpOut,"%%%% argv[%d]: '%s'\n", a, argv[a]);

    /* write column headings */
    fprintf(fpOut,"%%%% columns:\n%%%% FreqBinStart");
    if (uvar.outFreqBinEnd)
      fprintf(fpOut," FreqBinEnd");
    fprintf(fpOut," PSD");
    if (uvar.outputNormSFT)
      fprintf(fpOut," normSFTpower");
    fprintf(fpOut,"\n");

    LogPrintf(LOG_DEBUG, "Printing PSD to file ... ");
    for (k = 0; k < finalNumBins; ++k) {
      UINT4 b = k * finalBinStep;

      REAL8 f0 = Freq0 + b * dFreq;
      REAL8 f1 = f0 + finalBinStep * dFreq;
      fprintf(fpOut, "%f", f0);
      if (uvar.outFreqBinEnd)
	fprintf(fpOut, "   %f", f1);

      REAL8 psd = math_op(&(finalPSD->data[b]), finalBinSize, uvar.PSDmthopBins);
      if ( isnan ( psd ))
        XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in psd[k=%d] = NAN ... exiting\n", k );

      fprintf(fpOut, "   %e", psd);

      if (uvar.outputNormSFT) {
	REAL8 nsft = math_op(&(finalNormSFT->data[b]), finalBinSize, uvar.nSFTmthopBins);
	if ( isnan ( nsft ))
          XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in nsft[k=%d] = NAN ... exiting\n", k );

	fprintf(fpOut, "   %f", nsft);
      }

      fprintf(fpOut, "\n");
    } // k < finalNumBins
    LogPrintfVerbatim ( LOG_DEBUG, "done.\n");

    fclose(fpOut);

  }

  /* we are now done with the psd */
  XLALDestroyMultiPSDVector  ( multiPSD);
  XLALDestroyMultiSFTVector  ( inputSFTs);

  XLALDestroyUserVars();

  XLALDestroyREAL8Vector ( overSFTs );
  XLALDestroyREAL8Vector ( overIFOs );
  XLALDestroyREAL8Vector ( finalPSD );
  XLALDestroyREAL8Vector ( finalNormSFT );

  LALCheckMemoryLeaks();

  return EXIT_SUCCESS;

} /* main() */
int main ( void )
{
  const char *fn = __func__;

  //LALStatus status = empty_status;

  SFTtype *mySFT;
  LIGOTimeGPS epoch = { 731210229, 0 };
  REAL8 dFreq = 1.0 / 1800.0;
  REAL8 f0 = 150.0 - 2.0 * dFreq;

  /* init data array */
  COMPLEX8 vals[] = {
    crectf( -1.249241e-21,   1.194085e-21 ),
    crectf(  2.207420e-21,   2.472366e-22 ),
    crectf(  1.497939e-21,   6.593609e-22 ),
    crectf(  3.544089e-20,  -9.365807e-21 ),
    crectf(  1.292773e-21,  -1.402466e-21 )
  };
  UINT4 numBins = sizeof ( vals ) / sizeof(vals[0] );

  if ( (mySFT = XLALCreateSFT ( numBins )) == NULL ) {
    XLALPrintError ("%s: Failed to create test-SFT using XLALCreateSFT(), xlalErrno = %d\n", fn, xlalErrno );
    return XLAL_EFAILED;
  }
  /* init header */
  strcpy ( mySFT->name, "H1;testSFTRngmed" );
  mySFT->epoch = epoch;
  mySFT->f0 = f0;
  mySFT->deltaF = dFreq;

  /* we simply copy over these data-values into the SFT */
  UINT4 iBin;
  for ( iBin = 0; iBin < numBins; iBin ++ )
    mySFT->data->data[iBin] = vals[iBin];

  /* get memory for running-median vector */
  REAL8FrequencySeries rngmed;
  INIT_MEM ( rngmed );
  XLAL_CHECK ( (rngmed.data = XLALCreateREAL8Vector ( numBins )) != NULL, XLAL_EFUNC, "Failed  XLALCreateREAL8Vector ( %d )", numBins );

  // ---------- Test running-median PSD estimation in simple blocksize cases
  // ------------------------------------------------------------
  // TEST 1: odd blocksize = 3
  // ------------------------------------------------------------
  UINT4 blockSize3 = 3;

  /* reference result for 3-bin block running-median computed in octave:
octave> sft = [ \
        -1.249241e-21 +  1.194085e-21i, \
         2.207420e-21 +  2.472366e-22i, \
         1.497939e-21 +  6.593609e-22i, \
         3.544089e-20 -  9.365807e-21i, \
         1.292773e-21 -  1.402466e-21i  \
         ];
octave> periodo = abs(sft).^2;
octave> m1 = median ( periodo(1:3) ); m2 = median ( periodo(2:4) ); m3 = median ( periodo (3:5 ) );
octave> rngmed = [ m1, m1, m2, m3, m3 ];
octave> printf ("rngmedREF3 = { %.16g, %.16g, %.16g, %.16g, %.16g };\n", rngmed );
        rngmedREF3[] = { 2.986442063306e-42, 2.986442063306e-42, 4.933828992779561e-42, 3.638172910684999e-42, 3.638172910684999e-42 };
  */
  REAL8 rngmedREF3[] = { 2.986442063306e-42, 2.986442063306e-42, 4.933828992779561e-42, 3.638172910684999e-42, 3.638172910684999e-42 };

  /* compute running median */
  XLAL_CHECK ( XLALSFTtoRngmed ( &rngmed, mySFT, blockSize3 ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALSFTtoRngmed() failed.");

  /* get median->mean bias correction, needed for octave-reference results, to make
   * them comparable to the bias-corrected results from LALSFTtoRngmed()
   */
  REAL8 medianBias3 = XLALRngMedBias ( blockSize3 );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALRngMedBias() failed.");

  BOOLEAN pass = 1;
  const CHAR *passStr;
  printf ("%4s %22s %22s %8s    <%g\n", "Bin", "rngmed(LAL)", "rngmed(Octave)", "relError", tol);
  for (iBin=0; iBin < numBins; iBin ++ )
    {
      REAL8 rngmedVAL = rngmed.data->data[iBin];
      REAL8 rngmedREF = rngmedREF3[iBin] / medianBias3;	// apply median-bias correction
      REAL8 relErr = REL_ERR ( rngmedREF, rngmedVAL );
      if ( relErr > tol ) {
        pass = 0;
        passStr = "fail";
      } else {
        passStr = "OK.";
      }

      printf ("%4d %22.16g %22.16g %8.1g    %s\n", iBin, rngmedVAL, rngmedREF, relErr, passStr );

    } /* for iBin < numBins */

  // ------------------------------------------------------------
  // TEST 2: even blocksize = 4
  // ------------------------------------------------------------
  UINT4 blockSize4 = 4;

  /* reference result for 4-bin block running-median computed in octave:
octave> m1 = median ( periodo(1:4) ); m2 = median ( periodo(2:5) );
octave> rngmed = [ m1, m1, m1, m2, m2 ];
octave> printf ("rngmedREF4[] = { %.16g, %.16g, %.16g, %.16g, %.16g };\n", rngmed );
rngmedREF4[] = { 3.96013552804278e-42, 3.96013552804278e-42, 3.96013552804278e-42, 4.28600095173228e-42, 4.28600095173228e-42 };
  */
  REAL8 rngmedREF4[] = { 3.96013552804278e-42, 3.96013552804278e-42, 3.96013552804278e-42, 4.28600095173228e-42, 4.28600095173228e-42 };

  /* compute running median */
  XLAL_CHECK ( XLALSFTtoRngmed ( &rngmed, mySFT, blockSize4 ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALSFTtoRngmed() failed.");

  /* get median->mean bias correction, needed for octave-reference results, to make
   * them comparable to the bias-corrected results from LALSFTtoRngmed()
   */
  REAL8 medianBias4 = XLALRngMedBias ( blockSize4 );
  XLAL_CHECK ( xlalErrno == 0, XLAL_EFUNC, "XLALRngMedBias() failed.");

  printf ("%4s %22s %22s %8s    <%g\n", "Bin", "rngmed(LAL)", "rngmed(Octave)", "relError", tol);
  for (iBin=0; iBin < numBins; iBin ++ )
    {
      REAL8 rngmedVAL = rngmed.data->data[iBin];
      REAL8 rngmedREF = rngmedREF4[iBin] / medianBias4;	// apply median-bias correction
      REAL8 relErr = REL_ERR ( rngmedREF, rngmedVAL );
      if ( relErr > tol ) {
        pass = 0;
        passStr = "fail";
      } else {
        passStr = "OK.";
      }

      printf ("%4d %22.16g %22.16g %8.1g    %s\n", iBin, rngmedVAL, rngmedREF, relErr, passStr );

    } /* for iBin < numBins */

  /* free memory */
  XLALDestroyREAL8Vector ( rngmed.data );
  XLALDestroySFT ( mySFT );

  LALCheckMemoryLeaks();

  if ( !pass )
    {
      printf ("Test failed! Difference exceeded tolerance.\n");
      return XLAL_EFAILED;
    }
  else
    {
      printf ("Test passed.\n");
      return XLAL_SUCCESS;
    }

} /* main() */
示例#29
0
int
test_XLALSincInterpolateCOMPLEX8TimeSeries ( void )
{

  COMPLEX8TimeSeries* tsIn;
  REAL8 f0 = 100;	// heterodyning frequency
  REAL8 dt = 0.1;	// sampling frequency = 10Hz
  LIGOTimeGPS epoch = { 100, 0 };
  REAL8 tStart = XLALGPSGetREAL8 ( &epoch );
  UINT4 numSamples = 1000;
  REAL8 Tspan = numSamples * dt;

  XLAL_CHECK ( (tsIn = XLALCreateCOMPLEX8TimeSeries ( "test TS_in", &epoch, f0, dt, &emptyLALUnit, numSamples )) != NULL, XLAL_EFUNC );
  for ( UINT4 j = 0; j < numSamples; j ++ ) {
    tsIn->data->data[j] = testSignal ( tStart + j * dt, 0 );
  } // for j < numSamples

  // ---------- interpolate this onto new time-samples
  UINT4 Dterms = 16;
  REAL8 safety = (Dterms+1.0) * dt;	// avoid truncated interpolation to minimize errors, set to 0 for seeing boundary-effects [they're not so bad...]
  LIGOTimeGPS epochOut = epoch;
  XLALGPSAdd ( &epochOut, safety );
  REAL8 TspanOut = Tspan - 2 * safety;

  REAL8 dtOut = dt / 10;
  UINT4 numSamplesOut = lround ( TspanOut / dtOut );
  COMPLEX8TimeSeries *tsOut;
  XLAL_CHECK ( (tsOut = XLALCreateCOMPLEX8TimeSeries ( "test TS_out", &epochOut, f0, dtOut, &emptyLALUnit, numSamplesOut )) != NULL, XLAL_EFUNC );


  REAL8 tStartOut = XLALGPSGetREAL8 ( &epochOut );
  REAL8Vector *times_out;
  XLAL_CHECK ( (times_out = XLALCreateREAL8Vector ( numSamplesOut )) != NULL, XLAL_EFUNC );
  for ( UINT4 j = 0; j < numSamplesOut; j ++ )
    {
      REAL8 t_j = tStartOut + j * dtOut;
      times_out->data[j] = t_j;
    } // for j < numSamplesOut

  XLAL_CHECK ( XLALSincInterpolateCOMPLEX8TimeSeries ( tsOut->data, times_out, tsIn, Dterms ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALDestroyREAL8Vector ( times_out );

  // ---------- check accuracy of interpolation
  COMPLEX8TimeSeries *tsFull;
  XLAL_CHECK ( (tsFull = XLALCreateCOMPLEX8TimeSeries ( "test TS_full", &epochOut, f0, dtOut, &emptyLALUnit, numSamplesOut )) != NULL, XLAL_EFUNC );
  for ( UINT4 j = 0; j < numSamplesOut; j ++ ) {
    tsFull->data->data[j] = testSignal ( tStartOut + j * dtOut, 0 );
  } // for j < numSamplesOut

  // ----- out debug info
  if ( lalDebugLevel & LALINFO )
    {
      XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_in.dat", tsIn ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_out.dat", tsOut ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_full.dat", tsFull ) == XLAL_SUCCESS, XLAL_EFUNC );
    } // if LALINFO

  VectorComparison XLAL_INIT_DECL(tol);
  tol.relErr_L1 	= 2e-2;
  tol.relErr_L2		= 2e-2;
  tol.angleV		= 2e-2;
  tol.relErr_atMaxAbsx	= 2e-2;
  tol.relErr_atMaxAbsy	= 2e-2;

  XLALPrintInfo ("Comparing sinc-interpolated timeseries to exact signal timeseries:\n");
  VectorComparison XLAL_INIT_DECL(cmp);
  XLAL_CHECK ( XLALCompareCOMPLEX8Vectors ( &cmp, tsOut->data, tsFull->data, &tol ) == XLAL_SUCCESS, XLAL_EFUNC );

  // ---------- free memory
  XLALDestroyCOMPLEX8TimeSeries ( tsIn );
  XLALDestroyCOMPLEX8TimeSeries ( tsOut );
  XLALDestroyCOMPLEX8TimeSeries ( tsFull );

  return XLAL_SUCCESS;

} // test_XLALSincInterpolateCOMPLEX8TimeSeries()
示例#30
0
/**
 * Generate a (heterodyned) REAL4 timeseries of a CW signal for given pulsarParams,
 * site, start-time, duration, and sampling-rate
 *
 * NOTE: this is mostly an API-wrapper to the more 'old-style' function
 * XLALGeneratePulsarSignal() [which will become deprecated in the future],
 * extended for the option to generate transient-CW signals
 */
REAL4TimeSeries *
XLALGenerateCWSignalTS ( const PulsarParams *pulsarParams,	///< input CW pulsar-signal parameters
                         const LALDetector *site,		///< detector
                         LIGOTimeGPS startTime,			///< time-series start-time GPS
                         REAL8 duration,			///< time-series duration to generate
                         REAL8 fSamp,				///< sampling frequency
                         REAL8 fHet,				///< heterodyning frequency
                         const EphemerisData *edat		///< ephemeris data
                         )
{
  XLAL_CHECK_NULL ( pulsarParams != NULL, XLAL_EINVAL );
  XLAL_CHECK_NULL ( site != NULL, XLAL_EINVAL );
  XLAL_CHECK_NULL ( duration > 0, XLAL_EDOM );
  XLAL_CHECK_NULL ( fSamp > 0, XLAL_EDOM );
  XLAL_CHECK_NULL ( fHet >= 0, XLAL_EDOM );

  // translate amplitude params
  REAL8 h0     = pulsarParams->Amp.h0;
  REAL8 cosi   = pulsarParams->Amp.cosi;
  REAL8 aPlus  = 0.5 * h0 * ( 1.0 + SQ(cosi) );
  REAL8 aCross = h0 * cosi;
  // translate 'modern' fkdot into 'old-style' spindown-vector
  UINT4 s_max;
  for ( s_max = PULSAR_MAX_SPINS-1; s_max > 0; s_max -- )
    {
      if ( pulsarParams->Doppler.fkdot[s_max] != 0 )
        break;
    } // for s_max = max ... 0
  REAL8Vector *spindown = NULL;
  if ( s_max > 0 )
    {
      XLAL_CHECK_NULL ( (spindown = XLALCreateREAL8Vector ( s_max )) != NULL, XLAL_EFUNC );
      for ( UINT4 s = 0; s < s_max; s ++ ) {
        spindown->data[s] = pulsarParams->Doppler.fkdot[s+1];
      }
    }

  /*----------------------------------------
   * fill old-style PulsarSignalParams struct
   *----------------------------------------*/
  PulsarSignalParams XLAL_INIT_DECL(params);
  params.pulsar.refTime            = pulsarParams->Doppler.refTime;
  params.pulsar.position.system    = COORDINATESYSTEM_EQUATORIAL;
  params.pulsar.position.longitude = pulsarParams->Doppler.Alpha;
  params.pulsar.position.latitude  = pulsarParams->Doppler.Delta;
  params.pulsar.aPlus              = aPlus;
  params.pulsar.aCross             = aCross;
  params.pulsar.phi0               = pulsarParams->Amp.phi0;
  params.pulsar.psi                = pulsarParams->Amp.psi;
  params.pulsar.f0                 = pulsarParams->Doppler.fkdot[0];
  params.pulsar.spindown           = spindown;
  params.orbit.tp                  = pulsarParams->Doppler.tp;
  params.orbit.argp                = pulsarParams->Doppler.argp;
  params.orbit.asini               = pulsarParams->Doppler.asini;
  params.orbit.ecc                 = pulsarParams->Doppler.ecc;
  params.orbit.period              = pulsarParams->Doppler.period;
  params.transfer                  = NULL;
  params.ephemerides               = edat;
  params.fHeterodyne               = fHet;

  // detector-specific settings
  params.startTimeGPS              = startTime;
  params.duration                  = ceil ( duration );
  params.samplingRate              = fSamp;
  params.site                      = site;

  /*----------------------------------------
   * generate the signal time-series
   *----------------------------------------*/
  REAL4TimeSeries *Tseries;
  XLAL_CHECK_NULL ( (Tseries = XLALGeneratePulsarSignal ( &params )) != NULL, XLAL_EFUNC );
  // ----- free internal memory
  XLALDestroyREAL8Vector ( spindown );

  // ----- apply transient-CW window
  XLAL_CHECK_NULL ( XLALApplyTransientWindow ( Tseries, pulsarParams->Transient ) == XLAL_SUCCESS, XLAL_EFUNC );

  return Tseries;

} // XLALGenerateCWSignalTS()