Esempio n. 1
0
/**
 * Computes REAL4TimeSeries containing time series of response amplitudes.
 * \see XLALComputeDetAMResponse() for more details.
 */
int XLALComputeDetAMResponseSeries(REAL4TimeSeries ** fplus, REAL4TimeSeries ** fcross, const REAL4 D[3][3], const double ra, const double dec, const double psi, const LIGOTimeGPS * start, const double deltaT, const int n)
{
	LIGOTimeGPS t;
	double gmst;
	int i;
	double p, c;

	*fplus = XLALCreateREAL4TimeSeries("plus", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	*fcross = XLALCreateREAL4TimeSeries("cross", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	if(!*fplus || !*fcross) {
		XLALDestroyREAL4TimeSeries(*fplus);
		XLALDestroyREAL4TimeSeries(*fcross);
		*fplus = *fcross = NULL;
		XLAL_ERROR(XLAL_EFUNC);
	}

	for(i = 0; i < n; i++) {
		t = *start;
		gmst = XLALGreenwichMeanSiderealTime(XLALGPSAdd(&t, i * deltaT));
		if(XLAL_IS_REAL8_FAIL_NAN(gmst)) {
			XLALDestroyREAL4TimeSeries(*fplus);
			XLALDestroyREAL4TimeSeries(*fcross);
			*fplus = *fcross = NULL;
			XLAL_ERROR(XLAL_EFUNC);
		}
		XLALComputeDetAMResponse(&p, &c, D, ra, dec, psi, gmst);
		(*fplus)->data->data[i] = p;
		(*fcross)->data->data[i] = c;
	}

	return 0;
}
Esempio n. 2
0
/**
 * Computes REAL4TimeSeries containing time series of the full general
 * metric theory of gravity response amplitudes.
 * \see XLALComputeDetAMResponseExtraModes() for more details.
 */
int XLALComputeDetAMResponseExtraModesSeries(REAL4TimeSeries ** fplus, REAL4TimeSeries ** fcross, REAL4TimeSeries ** fb, REAL4TimeSeries ** fl, REAL4TimeSeries ** fx, REAL4TimeSeries ** fy, const REAL4 D[3][3], const double ra, const double dec, const double psi, const LIGOTimeGPS * start, const double deltaT, const int n)
{
	LIGOTimeGPS t;
	double gmst;
	int i;
	double p, c, b, l, x, y;

	*fplus = XLALCreateREAL4TimeSeries("plus", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	*fcross = XLALCreateREAL4TimeSeries("cross", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	*fb = XLALCreateREAL4TimeSeries("b", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	*fl = XLALCreateREAL4TimeSeries("l", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	*fx = XLALCreateREAL4TimeSeries("x", start, 0.0, deltaT, &lalDimensionlessUnit, n);
	*fy = XLALCreateREAL4TimeSeries("y", start, 0.0, deltaT, &lalDimensionlessUnit, n);

	if(!*fplus || !*fcross || !*fb || !*fl || !*fx || !*fy) {
		XLALDestroyREAL4TimeSeries(*fplus);
		XLALDestroyREAL4TimeSeries(*fcross);
		XLALDestroyREAL4TimeSeries(*fb);
		XLALDestroyREAL4TimeSeries(*fl);
		XLALDestroyREAL4TimeSeries(*fx);
		XLALDestroyREAL4TimeSeries(*fy);

		*fplus = *fcross = *fb = *fl = *fx = *fy = NULL;
		XLAL_ERROR(XLAL_EFUNC);
	}

	for(i = 0; i < n; i++) {
		t = *start;
		gmst = XLALGreenwichMeanSiderealTime(XLALGPSAdd(&t, i * deltaT));
		if(XLAL_IS_REAL8_FAIL_NAN(gmst)) {
			XLALDestroyREAL4TimeSeries(*fplus);
			XLALDestroyREAL4TimeSeries(*fcross);
			XLALDestroyREAL4TimeSeries(*fb);
			XLALDestroyREAL4TimeSeries(*fl);
			XLALDestroyREAL4TimeSeries(*fx);
			XLALDestroyREAL4TimeSeries(*fy);

			*fplus = *fcross = *fb = *fl = *fx = *fy = NULL;
			XLAL_ERROR(XLAL_EFUNC);
		}
		XLALComputeDetAMResponseExtraModes(&p, &c, &b, &l, &x, &y, D, ra, dec, psi, gmst);
		(*fplus)->data->data[i] = p;
		(*fcross)->data->data[i] = c;
		(*fb)->data->data[i] = b;
		(*fl)->data->data[i] = l;
		(*fx)->data->data[i] = x;
		(*fy)->data->data[i] = y;
	}

	return 0;
}
Esempio n. 3
0
/* read a LIGO time series */
REAL4TimeSeries *get_ligo_data(LALFrStream *stream,
    CHAR *channel,
    LIGOTimeGPS start,
    LIGOTimeGPS end)
{
  /* variables */
  REAL4TimeSeries *series;
  size_t length;

  if (vrbflg)
    fprintf(stdout, "Allocating memory for \"%s\" series...\n", channel);

  /* create and initialise time series */
  series = XLALCreateREAL4TimeSeries(channel, &start, 0, 0, \
      &lalADCCountUnit, 0);

  if (vrbflg)
    fprintf(stdout, "Reading \"%s\" series metadata...\n", channel);

  /* get the series meta data */
  XLALFrStreamGetREAL4TimeSeriesMetadata(series, stream);

  if (vrbflg)
    fprintf(stdout, "Resizing \"%s\" series...\n", channel);

  /* resize series to the correct number of samples */
  length = floor((XLALGPSDiff(&end, &start) / series->deltaT) + 0.5);
  XLALResizeREAL4TimeSeries(series, 0, length);

  if (vrbflg)
    fprintf(stdout, "Reading channel \"%s\"...\n", channel);

  /* seek to and read data */
  XLALFrStreamSeek(stream, &start);
  XLALFrStreamGetREAL4TimeSeries(series, stream);

  return(series);
}
Esempio n. 4
0
/* cut a time series between given start and end times */
REAL4TimeSeries *cut_time_series(REAL4TimeSeries *input,
    LIGOTimeGPS start,
    UINT4 duration)
{
  /* variables */
  REAL4TimeSeries *series;
  INT4 length;
  INT4 first;

  /* calculate length of segment to cut */
  length = floor((duration / input->deltaT) + 0.5);

  /* get first bin */
  first = (INT4)((start.gpsSeconds - input->epoch.gpsSeconds) / input->deltaT);

  /* allocate memory */
  series = XLALCreateREAL4TimeSeries(input->name, &start, input->f0, \
      input->deltaT, &input->sampleUnits, length);

  /* cut time series */
  series = XLALCutREAL4TimeSeries(input, first, length);

  return(series);
}
/**
 * function to generate random time-series with gaps, and corresponding SFTs
 */
int
XLALgenerateRandomData ( REAL4TimeSeries **ts, SFTVector **sfts )
{
  /* input sanity checks */
  XLAL_CHECK ( (ts != NULL) && ( (*ts) == NULL ), XLAL_EINVAL );
  XLAL_CHECK ( (sfts != NULL) && ( (*sfts) == NULL ), XLAL_EINVAL );

  // test parameters
  LIGOTimeGPS epoch0 = { 714180733, 0 };
  UINT4 numSFTs = 20;
  REAL8 Tsft = 1000.0;

  // noise sigma
  REAL8 sigmaN = 0.1;

  /* prepare sampling constants */
  REAL8 numR4SamplesPerSFT = 2 * 5000;
  REAL8 dtR4 = (Tsft / numR4SamplesPerSFT);

  UINT4 numR4SamplesTS = numSFTs * numR4SamplesPerSFT;

  /* ----- allocate timeseries ----- */
  REAL4TimeSeries *outTS;	// input timeseries
  XLAL_CHECK ( (outTS = XLALCreateREAL4TimeSeries ("H1:test timeseries", &epoch0, 0, dtR4, &emptyLALUnit, numR4SamplesTS )) != NULL, XLAL_EFUNC );

  REAL4 *TSdata = outTS->data->data;
  /* initialize timeseries to zero (to allow for gaps) */
  memset ( TSdata, 0, outTS->data->length * sizeof (*TSdata) );

  /* also set up corresponding SFT timestamps vector */
  LIGOTimeGPSVector *timestampsSFT;
  XLAL_CHECK ( (timestampsSFT = XLALCalloc (1, sizeof(*timestampsSFT)) ) != NULL, XLAL_ENOMEM );
  XLAL_CHECK ( (timestampsSFT->data = XLALCalloc (numSFTs, sizeof (*timestampsSFT->data) )) != NULL, XLAL_ENOMEM );
  timestampsSFT->length = numSFTs;

  /* ----- set up random-noise timeseries with gaps ---------- */
  for ( UINT4 alpha=0; alpha < numSFTs; alpha ++ )
    {
      /* record this SFT's timestamp */
      timestampsSFT->data[alpha] = epoch0;
      timestampsSFT->data[alpha].gpsSeconds += lround( alpha * Tsft );

      /* generate all data-points of this SFT */
      for ( UINT4 j=0; j < numR4SamplesPerSFT; j++ )
        {
          UINT4 alpha_j = alpha * numR4SamplesPerSFT + j;
          REAL8 ti = alpha * Tsft + j * dtR4;
          /* unit-variance Gaussian noise + sinusoid */
          TSdata[alpha_j] = crealf ( testSignal ( ti, sigmaN ) );
        } // for js < numR4SamplesPerSFT

    } /* for alpha < numSFTs */

  /* ----- generate SFTs from this timeseries ---------- */
  SFTParams XLAL_INIT_DECL(sftParams);
  sftParams.Tsft = Tsft;
  sftParams.timestamps = timestampsSFT;
  sftParams.noiseSFTs = NULL;
  sftParams.window = NULL;

  SFTVector *outSFTs;
  XLAL_CHECK ( (outSFTs = XLALSignalToSFTs ( outTS, &sftParams )) != NULL, XLAL_EFUNC );

  /* free memory */
  XLALFree ( timestampsSFT->data );
  XLALFree ( timestampsSFT );

  /* return timeseries and SFTvector */
  (*ts)   = outTS;
  (*sfts) = outSFTs;

  return XLAL_SUCCESS;

} // XLALgenerateRandomData()
int
test_XLALSincInterpolateSFT ( void )
{
  REAL8 f0 = 0;		// heterodyning frequency
  REAL8 sigmaN = 0.001;
  REAL8 dt = 0.1;	// sampling frequency = 10Hz
  LIGOTimeGPS epoch = { 100, 0 };
  REAL8 tStart = XLALGPSGetREAL8 ( &epoch );
  UINT4 numSamples = 1000;
  REAL8 Tspan = numSamples * dt;
  REAL8 df = 1.0 / Tspan;

  UINT4 numSamples0padded = 3 * numSamples;
  REAL8 Tspan0padded = numSamples0padded * dt;
  REAL8 df0padded = 1.0 / Tspan0padded;

  UINT4 numBins = NhalfPosDC ( numSamples );
  UINT4 numBins0padded = NhalfPosDC ( numSamples0padded );
  // original timeseries
  REAL4TimeSeries* ts;
  XLAL_CHECK ( (ts = XLALCreateREAL4TimeSeries ( "test TS_in", &epoch, f0, dt, &emptyLALUnit, numSamples )) != NULL, XLAL_EFUNC );
  for ( UINT4 j = 0; j < numSamples; j ++ ) {
    ts->data->data[j] = crealf ( testSignal ( tStart + j * dt, sigmaN ) );
  } // for j < numSamples

  // zero-padded to double length
  REAL4TimeSeries* ts0padded;
  XLAL_CHECK ( (ts0padded = XLALCreateREAL4TimeSeries ( "test TS_padded", &epoch, f0, dt, &emptyLALUnit, numSamples0padded )) != NULL, XLAL_EFUNC );
  memcpy ( ts0padded->data->data, ts->data->data, numSamples * sizeof(ts0padded->data->data[0]) );
  memset ( ts0padded->data->data + numSamples, 0, (numSamples0padded - numSamples) * sizeof(ts0padded->data->data[0]) );

  // compute FFT on ts and ts0padded
  REAL4FFTPlan *plan, *plan0padded;
  XLAL_CHECK ( (plan        = XLALCreateForwardREAL4FFTPlan ( numSamples, 0 )) != NULL, XLAL_EFUNC );
  XLAL_CHECK ( (plan0padded = XLALCreateForwardREAL4FFTPlan ( numSamples0padded, 0 )) != NULL, XLAL_EFUNC );
  COMPLEX8Vector *fft, *fft0padded;
  XLAL_CHECK ( (fft        = XLALCreateCOMPLEX8Vector ( numBins )) != NULL, XLAL_ENOMEM );
  XLAL_CHECK ( (fft0padded = XLALCreateCOMPLEX8Vector ( numBins0padded )) != NULL, XLAL_ENOMEM );

  XLAL_CHECK ( XLALREAL4ForwardFFT ( fft, ts->data, plan ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALREAL4ForwardFFT ( fft0padded, ts0padded->data, plan0padded ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALDestroyREAL4TimeSeries ( ts );
  XLALDestroyREAL4TimeSeries ( ts0padded );
  XLALDestroyREAL4FFTPlan( plan );
  XLALDestroyREAL4FFTPlan( plan0padded );

  SFTtype XLAL_INIT_DECL(tmp);
  tmp.f0 = f0;
  tmp.deltaF = df;
  tmp.data = fft;

  REAL8 Band = 0.5/dt - f0;
  SFTtype *sft = NULL;
  XLAL_CHECK ( XLALExtractBandFromSFT ( &sft, &tmp, f0, Band ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALDestroyCOMPLEX8Vector ( fft );


  tmp.f0 = f0;
  tmp.deltaF = df0padded;
  tmp.data = fft0padded;
  SFTtype *sft0padded = NULL;
  XLAL_CHECK ( XLALExtractBandFromSFT ( &sft0padded, &tmp, f0, Band ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALDestroyCOMPLEX8Vector ( fft0padded );

  // ---------- interpolate input SFT onto frequency bins of padded-ts FFT for comparison
  UINT4 Dterms = 16;
  REAL8 safetyBins = (Dterms + 1.0);	// avoid truncated interpolation to minimize errors, set to 0 for seeing boundary-effects [they're not so bad...]

  REAL8 fMin = f0 + safetyBins * df;
  fMin = round(fMin / df0padded) * df0padded;
  UINT4 numBinsOut = numBins0padded - 3 * safetyBins;
  REAL8 BandOut = (numBinsOut-1) * df0padded;

  SFTtype *sftUpsampled = NULL;
  XLAL_CHECK ( XLALExtractBandFromSFT ( &sftUpsampled, sft0padded, fMin + 0.5*df0padded, BandOut - df0padded ) == XLAL_SUCCESS, XLAL_EFUNC );

  SFTtype *sftInterpolated;
  XLAL_CHECK ( (sftInterpolated = XLALSincInterpolateSFT ( sft, fMin, df0padded, numBinsOut, Dterms )) != NULL, XLAL_EFUNC );

  // ----- out debug info
  if ( lalDebugLevel & LALINFO )
    {
      XLAL_CHECK ( write_SFTdata ( "SFT_in.dat", sft ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( write_SFTdata ( "SFT_in0padded.dat", sft0padded ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( write_SFTdata ( "SFT_upsampled.dat", sftUpsampled ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( write_SFTdata ( "SFT_interpolated.dat", sftInterpolated ) == XLAL_SUCCESS, XLAL_EFUNC );
    } // if LALINFO

  // ---------- check accuracy of interpolation
  VectorComparison XLAL_INIT_DECL(tol);
  tol.relErr_L1 	= 8e-2;
  tol.relErr_L2		= 8e-2;
  tol.angleV		= 8e-2;
  tol.relErr_atMaxAbsx	= 4e-3;
  tol.relErr_atMaxAbsy	= 4e-3;

  XLALPrintInfo ("Comparing Dirichlet SFT interpolation with upsampled SFT:\n");
  XLAL_CHECK ( XLALCompareSFTs ( sftUpsampled, sftInterpolated, &tol ) == XLAL_SUCCESS, XLAL_EFUNC );

  // ---------- free memory
  XLALDestroySFT ( sft );
  XLALDestroySFT ( sft0padded );
  XLALDestroySFT ( sftUpsampled );
  XLALDestroySFT ( sftInterpolated );

  return XLAL_SUCCESS;

} // test_XLALSincInterpolateSFT()
int main(void) {
	static LALStatus    mystatus;

	/* variables for timing purposes */
	clock_t start, diff;
	int msec;

	REAL4TimeSeries *h_plus;
	REAL4TimeSeries *h_cross;
	REAL8TimeSeries *hplus;
	REAL8TimeSeries *hcross;
	InspiralTemplate params;

	FILE *outputfile;
	INT4 i,length;
	REAL8 dt, m, m1, m2, nu, lambda1, lambda2;
	LIGOTimeGPS tc = LIGOTIMEGPSZERO;

	memset( &mystatus, 0, sizeof(LALStatus) );
	memset( &params, 0, sizeof(InspiralTemplate) );

	m1 = 5.;
	m2 = 5.;
	m = m1 + m2;
	nu = m1 * m2 / m / m;

	lambda1 = 0.;
	lambda2 = 0.;
	LALSimInspiralWaveformFlags *waveFlags;
	waveFlags = XLALSimInspiralCreateWaveformFlags();

	params.approximant = TaylorT4;
	params.order = LAL_PNORDER_THREE_POINT_FIVE;
	params.ampOrder = LAL_PNORDER_NEWTONIAN;
	params.mass1 = m1;
	params.mass2 = m2;
	params.totalMass = m;
	params.eta = nu;
	params.tSampling = 4096;
	params.fCutoff = 2047.;
	params.fLower = 40.;
	params.distance = 1e6 * LAL_PC_SI;
	params.ieta = 1;

	dt = 1. / params.tSampling;

	start = clock();
	length = XLALSimInspiralTaylorT4PNRestricted(&hplus, &hcross, 0., dt, params.mass1*LAL_MSUN_SI, params.mass2*LAL_MSUN_SI, params.fLower, 0., params.distance, lambda1, lambda2, XLALSimInspiralGetTidalOrder(waveFlags), 0, 7);
	diff = clock() - start;
	msec = diff * 1000 / CLOCKS_PER_SEC;
	printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000);

	fprintf(stderr, "length = %i\n", length);
	fprintf(stderr, "T = %f\n", (float) length * dt);

	outputfile = fopen("T4wave1.dat","w");

	length = hplus->data->length;

	for(i = 0; i < length; i++) {
		fprintf(outputfile,"%e\t%e\t%e\n",
			i*dt,
			hplus->data->data[i],
			hcross->data->data[i]);
	}

	fclose(outputfile);
	fprintf(stdout,"waveform saved in T4wave1.dat\n" );

	start = clock();
	h_plus = XLALCreateREAL4TimeSeries("", &tc, 0.0, dt, &lalDimensionlessUnit, 4096*3);
	h_cross = XLALCreateREAL4TimeSeries("", &tc, 0.0, dt, &lalDimensionlessUnit, 4096*3);

	fprintf(stderr, "Lower cut-off frequency used will be %fHz\n", params.fLower);

	/* --- now we can call the injection function --- */
	LALTaylorT4WaveformTemplates(&mystatus, h_plus->data, h_cross->data, &params);
	diff = clock() - start;
	msec = diff * 1000 / CLOCKS_PER_SEC;
	printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000);

	if ( mystatus.statusCode )
	{
		fprintf( stderr, "LALInspiralTaylorT4Test: error generating waveform\n" );
		exit( 1 );
	}

	/* --- and finally save in a file --- */

	outputfile = fopen("T4wave2.dat","w");

	length = h_plus->data->length;

	for(i = 0; i < length; i++) {
		fprintf(outputfile,"%e\t%e\t%e\n",
			i*dt,
			h_plus->data->data[i],
			h_cross->data->data[i]);
	}

	fclose(outputfile);
	fprintf(stdout,"waveform saved in T4wave2.dat\n" );
	return 0;
}
Esempio n. 8
0
void AddNumRelStrainModes(  LALStatus              *status,     /**< pointer to LALStatus structure */
                            REAL4TimeVectorSeries  **outStrain, /**< [out]  h+, hx data    */
                            SimInspiralTable *thisinj           /**< [in]   injection data */)
{
  INT4 modeL, modeM, modeLlo, modeLhi;
  INT4 len, lenPlus, lenCross, k;
  CHAR *channel_name_plus;
  CHAR *channel_name_cross;
  LALFrStream  *frStream = NULL;
  LALCache frCache;
  LIGOTimeGPS epoch;
  REAL4TimeSeries  *seriesPlus=NULL;
  REAL4TimeSeries  *seriesCross=NULL;
  REAL8 massMpc;
  REAL4TimeVectorSeries *sumStrain=NULL;
  REAL4TimeVectorSeries *tempStrain=NULL;
  /*   NRWaveMetaData thisMetaData; */

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  modeLlo = thisinj->numrel_mode_min;
  modeLhi = thisinj->numrel_mode_max;

  /* create a frame cache and open the frame stream */
  frCache.length = 1;
  frCache.list = LALCalloc(1, sizeof(frCache.list[0]));
  frCache.list[0].url = thisinj->numrel_data;
  frStream = XLALFrStreamCacheOpen( &frCache );

  /* the total mass of the binary in Mpc */
  massMpc = (thisinj->mass1 + thisinj->mass2) * LAL_MRSUN_SI / ( LAL_PC_SI * 1.0e6);

  /* start time of waveform -- set it to something */
  epoch.gpsSeconds     = 0;
  epoch.gpsNanoSeconds = 0;

  /* loop over l values */
  for ( modeL = modeLlo; modeL <= modeLhi; modeL++ ) {

    /* loop over m values */
    for ( modeM = -modeL; modeM <= modeL; modeM++ ) {
      /* read numrel waveform */
      /* first the plus polarization */
      channel_name_plus = XLALGetNinjaChannelName("plus", modeL, modeM);
      /*get number of data points */
      lenPlus = XLALFrStreamGetVectorLength ( channel_name_plus, frStream );

      /* now the cross polarization */
      channel_name_cross = XLALGetNinjaChannelName("cross", modeL, modeM);
      /*get number of data points */
      lenCross = XLALFrStreamGetVectorLength ( channel_name_cross, frStream );

      /* skip on to next mode if mode doesn't exist */
      if ( (lenPlus <= 0) || (lenCross <= 0) || (lenPlus != lenCross) ) {
        XLALClearErrno();
        LALFree(channel_name_plus);
        LALFree(channel_name_cross);
        continue;
      }

      /* note: lenPlus and lenCross must be equal if we got this far*/
      /* len = lenPlus; */
      len = lenPlus;

      /* allocate and read the plus/cross time series */
      seriesPlus = XLALCreateREAL4TimeSeries ( channel_name_plus, &epoch, 0, 0, &lalDimensionlessUnit, len);
      memset(seriesPlus->data->data, 0, seriesPlus->data->length*sizeof(REAL4));
      XLALFrStreamGetREAL4TimeSeries ( seriesPlus, frStream );
      XLALFrStreamRewind( frStream );
      LALFree(channel_name_plus);

      seriesCross = XLALCreateREAL4TimeSeries ( channel_name_cross, &epoch, 0, 0, &lalDimensionlessUnit, len);
      memset(seriesCross->data->data, 0, seriesCross->data->length*sizeof(REAL4));
      XLALFrStreamGetREAL4TimeSeries ( seriesCross, frStream );
      XLALFrStreamRewind( frStream );
      LALFree(channel_name_cross);

      /* allocate memory for tempStrain */
      tempStrain = LALCalloc(1, sizeof(*tempStrain));
      tempStrain->data = XLALCreateREAL4VectorSequence(2, len);
      tempStrain->deltaT = LAL_MTSUN_SI * (thisinj->mass1 + thisinj->mass2) * seriesPlus->deltaT ;
      tempStrain->f0 = seriesPlus->f0;
      tempStrain->sampleUnits = seriesPlus->sampleUnits;
      memset(tempStrain->data->data, 0, tempStrain->data->length * tempStrain->data->vectorLength*sizeof(REAL4));

      /* now copy the data and scale amplitude corresponding to distance of 1Mpc*/
      for (k = 0; k < len; k++) {
        tempStrain->data->data[k] = massMpc * seriesPlus->data->data[k];
        tempStrain->data->data[len + k] = massMpc * seriesCross->data->data[k];            }

        /* we are done with seriesPlus and Cross for this iteration */
        XLALDestroyREAL4TimeSeries (seriesPlus);
        XLALDestroyREAL4TimeSeries (seriesCross);
        seriesPlus = NULL;
        seriesCross = NULL;

        /* compute the h+ and hx for given inclination and coalescence phase*/
        XLALOrientNRWave( tempStrain, modeL, modeM, thisinj->inclination, thisinj->coa_phase );
        if (sumStrain == NULL) {

          sumStrain = LALCalloc(1, sizeof(*sumStrain));
          sumStrain->data =  XLALCreateREAL4VectorSequence(2, tempStrain->data->vectorLength);
          sumStrain->deltaT = tempStrain->deltaT;
          sumStrain->f0 = tempStrain->f0;
          sumStrain->sampleUnits = tempStrain->sampleUnits;

          memset(sumStrain->data->data,0.0,2*tempStrain->data->vectorLength*sizeof(REAL4));

          sumStrain = XLALSumStrain( sumStrain, tempStrain );

        } else {
          sumStrain = XLALSumStrain( sumStrain, tempStrain );
        }

        /* clear memory for strain */
        if (tempStrain->data != NULL) {
          XLALDestroyREAL4VectorSequence ( tempStrain->data );
          LALFree( tempStrain );
          tempStrain = NULL;
      }
    } /* end loop over modeM values */
  } /* end loop over modeL values */

  XLALFrStreamClose( frStream );
  LALFree(frCache.list);
  *outStrain = sumStrain;
  DETATCHSTATUSPTR(status);
  RETURN(status);

}
int main( int argc, char *argv[] )
{
  LALStatus                     status = blank_status;

  UINT4                         k;
  UINT4                         kLow;
  UINT4                         kHi;
  INT4                          numPoints       = 524288;
  REAL4                         fSampling       = 2048.;
  REAL4                         fLow            = 70.;
  REAL4                         fLowInj         = 40.;
  REAL8                         deltaT          = 1./fSampling;
  REAL8                         deltaF          = fSampling / numPoints;

  REAL4                          statValue;
 
  /* vars required to make freq series */
  LIGOTimeGPS                   epoch = { 0, 0 };
  LIGOTimeGPS                   gpsStartTime = {0, 0}; 
  REAL8                         f0 = 0.;
  REAL8                         offset = 0.;
  INT8                          waveformStartTime = 0;

  /* files contain PSD info */
  CHAR                         *injectionFile = NULL;         
  CHAR                         *outputFile    = NULL;         
  CHAR                         *specFileH1    = NULL;         
  CHAR                         *specFileH2    = NULL;         
  CHAR                         *specFileL1    = NULL;         

  COMPLEX8Vector               *unity = NULL;
  const LALUnit strainPerCount = {0,{0,0,0,0,0,1,-1},{0,0,0,0,0,0,0}};

  int                           numInjections = 0;
  int                           numTriggers = 0;

  /* template bank simulation variables */
  INT4                         injSimCount = 0;
  SimInspiralTable            *injectionHead  = NULL;
  SimInspiralTable            *thisInjection  = NULL;
  SnglInspiralTable           *snglHead       = NULL;
  SearchSummaryTable          *searchSummHead = NULL;
  /*SummValueTable              *summValueHead  = NULL;    */

  /* raw input data storage */
  REAL8FrequencySeries          *specH1        = NULL;
  REAL8FrequencySeries          *specH2        = NULL;
  REAL8FrequencySeries          *specL1        = NULL;
  REAL8FrequencySeries          *thisSpec      = NULL;
  COMPLEX8FrequencySeries       *resp          = NULL;
  COMPLEX8FrequencySeries       *detTransDummy = NULL;
  REAL4TimeSeries               *chan          = NULL;
  RealFFTPlan                   *pfwd          = NULL;
  COMPLEX8FrequencySeries       *fftData       = NULL;
  REAL8                          thisSnrsq     = 0;
  REAL8                          thisSnr       = 0;
  REAL8                          thisCombSnr   = 0;
  REAL8                          snrVec[3];
  REAL8                          dynRange      = 1./(3.0e-23);

  /* needed for inj */
  CoherentGW                 waveform;
  PPNParamStruc              ppnParams;
  DetectorResponse           detector;
  InterferometerNumber       ifoNumber   = LAL_UNKNOWN_IFO;

  /* output data */
  LIGOLwXMLStream       xmlStream;
  MetadataTable         proctable;
  MetadataTable         outputTable;
  MetadataTable         procparams;
  CHAR                  fname[256];         
  CHAR                  comment[LIGOMETA_COMMENT_MAX];
  ProcessParamsTable   *this_proc_param = NULL;

  CHAR   chanfilename[FILENAME_MAX];

  REAL4 sum = 0;
  REAL4 bitten_H1 = 0;
  REAL4 bitten_H2 = 0;
  REAL4 thisCombSnr_H1H2 = 0;

  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME, lalAppsVCSIdentId,
      lalAppsVCSIdentStatus, lalAppsVCSIdentDate, 0);
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) 
                                      calloc( 1, sizeof(ProcessParamsTable) );
  memset( comment, 0, LIGOMETA_COMMENT_MAX * sizeof(CHAR) );

  /* look at input args, write process params where required */
  while ( 1 )
  {

  /* getopt arguments */
  static struct option long_options[] =
  {
    /* these options set a flag */
    /* these options do not set a flag */
    {"help",                    no_argument,       0,                'h'},
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"version",                 no_argument,       0,                'V'},
    {"spectrum-H1",             required_argument, 0,                'a'},
    {"spectrum-H2",             required_argument, 0,                'b'},
    {"spectrum-L1",             required_argument, 0,                'c'},
    {"inj-file",                required_argument, 0,                'd'},
    {"comment",                 required_argument, 0,                'e'},
    {"output-file",             required_argument, 0,                'f'},
    {"coire-flag",              no_argument,       &coireflg,         1 },
    {"ligo-srd",                no_argument,       &ligosrd,          1 },
    {"write-chan",              no_argument,       &writechan,        1 },
    {"inject-overhead",         no_argument,       &injoverhead,      1 },
    {"f-lower",                 required_argument, 0,                'g'},
    {0, 0, 0, 0}
  };
  int c;
  
  /*
   *
   * parse command line arguments
   *
   */

    /* getopt_long stores long option here */
    int option_index = 0;
    size_t optarg_len;

    c = getopt_long_only( argc, argv, "a:b:c:d:e:f:g:hV", long_options, &option_index );

    /* detect the end of the options */
    if ( c == - 1 )
    {
      break;
    }

    switch ( c )
    {
      case 0:
        /* if this option set a flag, do nothing else now */
        if ( long_options[option_index].flag != 0 )
        {
          break;
        }
        else
        {
          fprintf( stderr, "error parsing option %s with argument %s\n",
              long_options[option_index].name, optarg );
          exit( 1 );
        }
        break;

      case 'h':
        fprintf( stderr, USAGE );
        exit( 0 );
        break;

      case 'a':
        /* create storage for the spectrum file name */
        optarg_len = strlen( optarg ) + 1;
        specFileH1 = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( specFileH1, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'b':
        /* create storage for the spectrum file name */
        optarg_len = strlen( optarg ) + 1;
        specFileH2 = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( specFileH2, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'c':
        /* create storage for the spectrum file name */
        optarg_len = strlen( optarg ) + 1;
        specFileL1 = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( specFileL1, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'd':
        /* create storage for the injection file name */
        optarg_len = strlen( optarg ) + 1;
        injectionFile = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( injectionFile, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'f':
        /* create storage for the output file name */
        optarg_len = strlen( optarg ) + 1;
        outputFile = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( outputFile, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;
    
      case 'g':
        fLow = (INT4) atof( optarg );
        if ( fLow < 40 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "f-lower must be > 40Hz (%e specified)\n",
              long_options[option_index].name, fLow );
          exit( 1 );
        }
        ADD_PROCESS_PARAM( "float", "%e", fLow );
        break;


     case 'e':
        if ( strlen( optarg ) > LIGOMETA_COMMENT_MAX - 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "comment must be less than %d characters\n",
              long_options[option_index].name, LIGOMETA_COMMENT_MAX );
          exit( 1 );
        }
        else
        {
          snprintf( comment, LIGOMETA_COMMENT_MAX, "%s", optarg);
        }
        break;

      case 'V':
        /* print version information and exit */
        fprintf( stdout, "calculation of expected SNR of injections\n"
            "Gareth Jones\n");
        XLALOutputVersionString(stderr, 0);
        exit( 0 );
        break;

     default:
        fprintf( stderr, "unknown error while parsing options\n" );
        fprintf( stderr, USAGE );
        exit( 1 );
    }
  }  

  if ( optind < argc )
  {
    fprintf( stderr, "extraneous command line arguments:\n" );
    while ( optind < argc )
    {
      fprintf ( stderr, "%s\n", argv[optind++] );
    }
    exit( 1 );
  }

  /* check the input arguments */
  if ( injectionFile == NULL )
  {
    fprintf( stderr, "Must specify the --injection-file\n" );
    exit( 1 );
  }

  if ( outputFile == NULL )
  {
    fprintf( stderr, "Must specify the --output-file\n" );
    exit( 1 );
  }

  if ( !ligosrd && specFileH1 == NULL )
  {
    fprintf( stderr, "Must specify the --spectrum-H1\n" );
    exit( 1 );
  }

  if ( !ligosrd && specFileH2 == NULL )
  {
    fprintf( stderr, "Must specify the --spectrum-H2\n" );
    exit( 1 );
  }

  if ( !ligosrd && specFileL1 == NULL )
  {
    fprintf( stderr, "Must specify the --spectrum-L1\n" );
    exit( 1 );
  }

  if ( ligosrd && (specFileH1 || specFileH2 || specFileL1 ))
  {
    fprintf( stdout, "WARNING: using LIGOI SRD power spectral density \n" );
  } 
 
  if ( vrbflg ){
    fprintf( stdout, "injection file is %s\n", injectionFile );
    fprintf( stdout, "output file is %s\n", outputFile );
    fprintf( stdout, "H1 spec file is   %s\n", specFileH1 );
    fprintf( stdout, "H2 spec file is   %s\n", specFileH2 );
    fprintf( stdout, "L1 spec file is   %s\n", specFileL1 );
  }

  /* create vector for H1, H2 and L1 spectrums */
  specH1 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) );
  specH2 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) );
  specL1 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) );
  if (!specH1 || !specH2 || !specL1){
    XLALDestroyREAL8FrequencySeries ( specH1 );
    XLALDestroyREAL8FrequencySeries ( specH2 );
    XLALDestroyREAL8FrequencySeries ( specL1 );
    XLALPrintError("failure allocating H1, H2 and L1 spectra");
    exit(1);
  }

  if (!ligosrd){
    /* read in H1 spectrum */ 
    LAL_CALL( LALDReadFrequencySeries(&status, specH1, specFileH1), &status );
    if ( vrbflg ){
       fprintf( stdout, "read in H1 spec file\n" );
       fflush( stdout );
    } 

    /* read in H2 spectrum */ 
    LAL_CALL( LALDReadFrequencySeries(&status, specH2, specFileH2), &status );
    if ( vrbflg ){
       fprintf( stdout, "read in H2 spec file\n" );
       fflush( stdout );
    }

    /* read in L1 spectrum */ 
    LAL_CALL( LALDReadFrequencySeries(&status, specL1, specFileL1), &status );
    if ( vrbflg ){
       fprintf( stdout, "read in L1 spec file\n" );
       fflush( stdout );
     }
  }

  chan = XLALCreateREAL4TimeSeries( "", &epoch, f0, deltaT, 
                                     &lalADCCountUnit, numPoints );
  if ( !chan ){
    XLALPrintError("failure allocating chan");
    exit(1);
  }

  /*
   *
   * set up the response function
   *
   */
  resp = XLALCreateCOMPLEX8FrequencySeries( chan->name, 
     &chan->epoch, f0, deltaF, &strainPerCount, (numPoints / 2 + 1) );
  if ( !resp ){
    XLALPrintError("failure allocating response function");
    exit(1);
  }

  /* create vector that will contain detector.transfer info, since this 
   * is constant I calculate it once outside of all the loops and pass it 
   * in to detector.transfer when required 
   */
  detTransDummy = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch,
                  f0, deltaF, &strainPerCount, (numPoints / 2 + 1) );
  if ( !detTransDummy ){
    XLALPrintError("failure allocating detector.transfer info");
    exit(1);
  }

  /* invert the response function to get the transfer function */
  unity = XLALCreateCOMPLEX8Vector( resp->data->length );
  for ( k = 0; k < unity->length; ++k )
     {
        unity->data[k] = 1.0;
     }

  /* set response */
  for ( k = 0; k < resp->data->length; ++k )
  {
      resp->data->data[k] = 1.0;
  }

  XLALCCVectorDivide( detTransDummy->data, unity, resp->data );
  XLALDestroyCOMPLEX8Vector( unity );

  /* read in injections from injection file */
  /* set endtime to 0 so that we read in all events */
  if ( vrbflg ) fprintf( stdout, "Reading sim_inspiral table of %s\n", injectionFile );
  LAL_CALL(numInjections = SimInspiralTableFromLIGOLw( &injectionHead, injectionFile, 0, 0), &status);
  if ( vrbflg ) fprintf( stdout, "Read %d injections from sim_inspiral table of %s\n", 
                                    numInjections, injectionFile );

  if (coireflg){
     if ( vrbflg ) fprintf( stdout, "Reading sngl_inspiral table of %s\n", injectionFile );
     LAL_CALL(numTriggers = LALSnglInspiralTableFromLIGOLw(&snglHead, injectionFile, 0, -1), &status);
     if ( vrbflg ) fprintf( stdout, "Read %d triggers from sngl_inspiral table of %s\n", 
                                    numTriggers, injectionFile );
     if ( vrbflg ) {
           fprintf( stdout, "Reading search_summary table of %s ...", injectionFile );
           fflush( stdout );
           }
     searchSummHead = XLALSearchSummaryTableFromLIGOLw (injectionFile);
     if ( vrbflg ) fprintf( stdout, " done\n");
  }

 /* make sure we start at head of linked list */
 thisInjection = injectionHead;

  /* setting fixed waveform injection parameters */
  memset( &ppnParams, 0, sizeof(PPNParamStruc) );
  ppnParams.deltaT   = deltaT;
  ppnParams.lengthIn = 0;
  ppnParams.ppn      = NULL;

  /* loop over injections */
  injSimCount = 0;
    
        
  do
  {
     fprintf( stdout, "injection %d/%d\n", injSimCount+1, numInjections );

     /* reset waveform structure */
     memset( &waveform, 0, sizeof(CoherentGW) );

     /* reset chan structure */
     memset( chan->data->data, 0, chan->data->length * sizeof(REAL4) );

     if (thisInjection->f_lower == 0){
        fprintf( stdout, "WARNING: f_lower in sim_inpiral = 0, ");
        fprintf( stdout, "changing this to %e\n ", fLowInj);
        thisInjection->f_lower = fLowInj;
     }

     /* create the waveform, amp, freq phase etc */
     LAL_CALL( LALGenerateInspiral(&status, &waveform, thisInjection, &ppnParams), &status);
     if (vrbflg) fprintf( stdout, "ppnParams.tc %e\n ", ppnParams.tc);

    statValue = 0.;
  
    /* calc lower index for integration */
    kLow = ceil(fLow / deltaF);
    if ( vrbflg ) {
        fprintf( stdout, "starting integration to find SNR at frequency %e ", fLow);
        fprintf( stdout, "at index %d \n", kLow);
    }
    /* calc upper index for integration */
    kHi = floor(fSampling / (2. * deltaF));
    if ( vrbflg ) {
        fprintf( stdout, "ending integration to find SNR at frequency %e ", fSampling / 2.);
        fprintf( stdout, "at index %d \n", kHi);
    }

    /* loop over ifo */
    for ( ifoNumber = 1; ifoNumber < 4; ifoNumber++ )
    {
        /* allocate memory and copy the parameters describing the freq series */
        memset( &detector, 0, sizeof( DetectorResponse ) );
        detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) );

        if (injoverhead){ 
           if ( vrbflg ) fprintf( stdout, "WARNING: perform overhead injections\n");
           /* setting detector.site to NULL causes SimulateCoherentGW to
            * perform overhead injections */  
           detector.site = NULL; 
        }
        else {
           /* if not overhead, set detector.site using ifonumber */  
           XLALReturnDetector( detector.site, ifoNumber );
        } 

        switch ( ifoNumber )
        {
        case 1:
           if ( vrbflg ) fprintf( stdout, "looking at H1 \n");
           thisSpec = specH1;
           break;
        case 2:
           if ( vrbflg ) fprintf( stdout, "looking at H2 \n");
           thisSpec = specH2;
           break;
        case 3:
           if ( vrbflg ) fprintf( stdout, "looking at L1 \n");
           thisSpec = specL1;
           break;
        default:
           fprintf( stderr, "Error: ifoNumber %d does not correspond to H1, H2 or L1: \n", ifoNumber );
           exit( 1 );
        }

        /* get the gps start time of the signal to inject */
        waveformStartTime = XLALGPSToINT8NS( &(thisInjection->geocent_end_time) );
        waveformStartTime -= (INT8) ( 1000000000.0 * ppnParams.tc );

        offset = (chan->data->length / 2.0) * chan->deltaT;
        gpsStartTime.gpsSeconds     = thisInjection->geocent_end_time.gpsSeconds - offset;
        gpsStartTime.gpsNanoSeconds = thisInjection->geocent_end_time.gpsNanoSeconds;
        chan->epoch = gpsStartTime;


       if (vrbflg) fprintf(stdout, "offset start time of injection by %f seconds \n", offset ); 
       
       /* is this okay? copying in detector transfer which so far only contains response info  */
       detector.transfer = detTransDummy;

       XLALUnitInvert( &(detector.transfer->sampleUnits), &(resp->sampleUnits) );

       /* set the start times for injection */
       XLALINT8NSToGPS( &(waveform.a->epoch), waveformStartTime );
       memcpy(&(waveform.f->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) );
       memcpy(&(waveform.phi->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) );
 
       /* perform the injection */
       LAL_CALL( LALSimulateCoherentGW(&status, chan, &waveform, &detector ), &status); 

       if (writechan){ 
          /* write out channel data */
          if (vrbflg) fprintf(stdout, "writing channel data to file... \n" ); 
          switch ( ifoNumber )
          {
          case 1:
             snprintf( chanfilename, FILENAME_MAX, "chanTest_H1_inj%d.dat", injSimCount+1);
             if (vrbflg) fprintf( stdout, "writing H1 channel time series out to %s\n", chanfilename );
             LALSPrintTimeSeries(chan, chanfilename );
             break;
          case 2:
             snprintf( chanfilename, FILENAME_MAX, "chanTest_H2_inj%d.dat", injSimCount+1);
             if (vrbflg) fprintf( stdout, "writing H2 channel time series out to %s\n", chanfilename );
             LALSPrintTimeSeries(chan, chanfilename );
             break;
          case 3:
             snprintf( chanfilename, FILENAME_MAX, "chanTest_L1_inj%d.dat", injSimCount+1);
             if (vrbflg) fprintf( stdout, "writing L1 channel time series out to %s\n", chanfilename );
             LALSPrintTimeSeries(chan, chanfilename );
             break;
         default:
             fprintf( stderr, "Error: ifoNumber %d does not correspond to H1, H2 or L1: \n", ifoNumber );
             exit( 1 );
         }  
      } 

      LAL_CALL( LALCreateForwardRealFFTPlan( &status, &pfwd, chan->data->length, 0), &status);

      fftData = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch, f0, deltaF, 
                                                   &lalDimensionlessUnit, (numPoints / 2 + 1) );
      if ( !fftData ){
        XLALPrintError("failure allocating fftData");
        exit(1);
      }
   
      LAL_CALL( LALTimeFreqRealFFT( &status, fftData, chan, pfwd ), &status);
   
      LAL_CALL( LALDestroyRealFFTPlan( &status, &pfwd ), &status);
      pfwd = NULL;

       /* compute the SNR */
       thisSnrsq = 0;
       /* avoid f=0 part of psd */  

       if (ligosrd){
          if (vrbflg) fprintf( stdout, "using LIGOI PSD \n");
          for ( k = kLow; k < kHi; k++ )
          {
           REAL8 freq;
           REAL8 sim_psd_value;
           freq = fftData->deltaF * k;
           LALLIGOIPsd( NULL, &sim_psd_value, freq ); 

           thisSnrsq += ((crealf(fftData->data->data[k]) * dynRange) * 
                      (crealf(fftData->data->data[k]) * dynRange)) / sim_psd_value;
           thisSnrsq += ((cimagf(fftData->data->data[k]) * dynRange) * 
                      (cimagf(fftData->data->data[k]) * dynRange)) / sim_psd_value;
           }
       }
       else {
          if (vrbflg) fprintf( stdout, "using input spectra \n");
          for ( k = kLow; k < kHi; k++ )
          {
           thisSnrsq += ((crealf(fftData->data->data[k]) * dynRange) * 
              (crealf(fftData->data->data[k]) * dynRange))  /
              (thisSpec->data->data[k] * dynRange * dynRange);
           thisSnrsq += ((cimagf(fftData->data->data[k]) * dynRange) * 
              (cimagf(fftData->data->data[k]) * dynRange)) /
              (thisSpec->data->data[k] * dynRange * dynRange);
        } 
      }

       thisSnrsq *= 4*fftData->deltaF;
       thisSnr    = pow(thisSnrsq, 0.5);
       /* Note indexing on snrVec, ifoNumber runs from 1..3 to get source correct,
        * we must index snrVec 0..2 
        */ 
       snrVec[ifoNumber-1] = thisSnr; 
       XLALDestroyCOMPLEX8FrequencySeries(fftData);

       if ( vrbflg ){
          fprintf( stdout, "thisSnrsq %e\n", thisSnrsq );
          fprintf( stdout, "snrVec    %e\n", snrVec[ifoNumber-1] );
          fflush( stdout );
       }

       /* sum thisSnrsq to eventually get combined snr*/
       statValue += thisSnrsq; 

       /* free some memory */
       if (detector.transfer) detector.transfer = NULL;
       if ( detector.site ) {LALFree( detector.site); detector.site = NULL;}
     }
     /* end loop over ifo */
  
    destroyCoherentGW( &waveform );

    /* store inverse eff snrs in eff_dist columns */
    thisInjection->eff_dist_h = 1./snrVec[0];
    thisInjection->eff_dist_g = 1./snrVec[1];
    thisInjection->eff_dist_l = 1./snrVec[2];

    /* store inverse sum of squares snr in eff_dist_t */
    thisCombSnr = pow(statValue, 0.5);
    if ( vrbflg ) fprintf( stdout, "thisCombSnr %e\n", thisCombSnr);
    thisInjection->eff_dist_t = 1./thisCombSnr;

    /* calc inverse bittenL snr for H1H2 and store in eff_dist_v */
    thisCombSnr_H1H2 = 0.;
    sum = snrVec[0] * snrVec[0] + snrVec[1] * snrVec[1];
    bitten_H1 = 3 * snrVec[0] -3;
    bitten_H2 = 3 * snrVec[1] -3;

    if (sum < bitten_H1){
       thisCombSnr_H1H2 = sum;
    }
    else
    {
       thisCombSnr_H1H2 = bitten_H1;
    }

    if (bitten_H2 < thisCombSnr_H1H2){
       thisCombSnr_H1H2 = bitten_H2;
    }
    thisInjection->eff_dist_v = 1./thisCombSnr_H1H2;


    /* increment the bank sim sim_inspiral table if necessary */
    if ( injectionHead )
    {
      thisInjection = thisInjection->next;
    }

  } while ( ++injSimCount < numInjections ); 
  /* end loop over injections */

  /* try opening, writing and closing an xml file */

  /* open the output xml file */
  memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) );
  snprintf( fname, sizeof(fname), "%s", outputFile);
  LAL_CALL( LALOpenLIGOLwXMLFile  ( &status, &xmlStream, fname), &status);

  /* write out the process and process params tables */
  if ( vrbflg ) fprintf( stdout, "process... " );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_table ), &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, proctable, process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status );
  free( proctable.processTable );
  /* Just being pedantic here ... */
  proctable.processTable = NULL;
 
  /* free the unused process param entry */
  this_proc_param = procparams.processParamsTable;
  procparams.processParamsTable = procparams.processParamsTable->next;
  free( this_proc_param );
  this_proc_param = NULL;

  /* write the process params table */
  if ( vrbflg ) fprintf( stdout, "process_params... " );
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_params_table ), &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, procparams, process_params_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status );

  /* write the search summary table */
  if ( coireflg ){
     if ( vrbflg ) fprintf( stdout, "search_summary... " );
     outputTable.searchSummaryTable = searchSummHead;
     LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, search_summary_table), &status);
     LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, search_summary_table), &status);
     LAL_CALL( LALEndLIGOLwXMLTable  ( &status, &xmlStream), &status);
   }

  /* write the sim inspiral table */
  if ( vrbflg ) fprintf( stdout, "sim_inspiral... " );
  outputTable.simInspiralTable = injectionHead;
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sim_inspiral_table), &status);
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sim_inspiral_table), &status);
  LAL_CALL( LALEndLIGOLwXMLTable  ( &status, &xmlStream), &status);

  /* write the sngl inspiral table */
  if ( coireflg ){
     if ( vrbflg ) fprintf( stdout, "sngl_inspiral... " );
     outputTable.snglInspiralTable = snglHead;
     LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sngl_inspiral_table), &status);
     LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sngl_inspiral_table), &status);
     LAL_CALL( LALEndLIGOLwXMLTable  ( &status, &xmlStream), &status);
  } 

  /* close the xml file */ 
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlStream), &status);

  /* Freeing memory */
  XLALDestroyREAL4TimeSeries(chan);
  XLALDestroyCOMPLEX8FrequencySeries(resp);
  XLALDestroyCOMPLEX8FrequencySeries(detTransDummy);
  XLALDestroyREAL8FrequencySeries ( specH1 );
  XLALDestroyREAL8FrequencySeries ( specH2 );
  XLALDestroyREAL8FrequencySeries ( specL1 );


  free( specFileH1 );
  specFileH1 = NULL;
  free( specFileH2 );
  specFileH2 = NULL;
  free( specFileL1 );
  specFileL1 = NULL;
  free( injectionFile ); 
  injectionFile = NULL;

  /* free the process params */
  while( procparams.processParamsTable )
  {
    this_proc_param = procparams.processParamsTable;
    procparams.processParamsTable = this_proc_param->next;
    free( this_proc_param );
    this_proc_param = NULL;
  }

  /* free the sim inspiral tables */
  while ( injectionHead )
  {
    thisInjection = injectionHead;
    injectionHead = injectionHead->next;
    LALFree( thisInjection );
  }

  /*check for memory leaks */
  LALCheckMemoryLeaks(); 

  exit( 0 ); 
}
Esempio n. 10
0
int XLALASCIIFileReadCalFac( REAL4TimeSeries **alpha, REAL4TimeSeries **lal_gamma, const char *fname )
{
  const REAL8 fuzzfactor = 1e-3; /* fraction of a sample of fuzziness */
  REAL8 fuzz; /* possible discrepancies in times */
  char alphaName[] = "Xn:CAL-CAV_FAC";
  char gammaName[] = "Xn:CAL-OLOOP_FAC";
  LALDataFileNameFields              fileFields;
  LALCalFacFileNameDescriptionFields descFields;
  REAL8VectorSequence *data;
  LIGOTimeGPS epoch;
  REAL8 tstart;
  REAL8 tend;
  REAL4 deltaT;
  int ndat;
  int nrow;
  int row;
  int dat;

  if ( ! alpha || ! lal_gamma )
    XLAL_ERROR( XLAL_EFAULT );
  if ( *alpha || *lal_gamma )
    XLAL_ERROR( XLAL_EINVAL );

  if ( XLALDataFileNameParse( &fileFields, fname ) < 0 )
  {
    XLALPrintError( "XLAL Error - %s: invalid file name %s\n", __func__, fname );
    XLAL_ERROR( XLAL_EINVAL );
  }

  if ( XLALCalFacFileNameDescriptionParse( &descFields, fileFields.description ) < 0 )
  {
    XLALPrintError( "XLAL Error - %s: invalid description part of file name %s\n", __func__, fname );
    XLAL_ERROR( XLAL_EINVAL );
  }

  XLALPrintInfo( "XLAL Info - %s: Reading calibration factors from file %s\n", __func__, fname );

  /* setup channel names */
  memcpy( alphaName, descFields.ifo, 2 );
  memcpy( gammaName, descFields.ifo, 2 );

  deltaT = XLALASCIIFileReadCalFacHeader( fname );
  if ( XLAL_IS_REAL4_FAIL_NAN( deltaT ) )
    XLAL_ERROR( XLAL_EFUNC );

  if ( deltaT <= 0 ) /* bad time step */
    XLAL_ERROR( XLAL_EDATA );

  /* check consistency of time steps */
  if ( fabs( descFields.deltaT - deltaT ) > 1 ) /* step in file name might only be accurate to one second */
    XLAL_ERROR( XLAL_EDATA );

  /* read three columns */
  data = XLALASCIIFileReadColumns( 3, fname );
  if ( ! data )
    XLAL_ERROR( XLAL_EFUNC );
  if ( ! data->length )
  {
    XLALPrintError( "XLAL Error - %s: no rows of data\n", __func__ );
    XLAL_ERROR( XLAL_EFAILED );
  }
  nrow = data->length;

  /* sanity checks on time stamps */
  /* check for mismatch in start or end times compared to file name */
  tstart = ELEM(data,0,1);
  tend   = ELEM(data,nrow-1,1);
  ndat   = 1 + (int)floor( (tend - tstart)/deltaT + 0.5 );
  if ( ( fileFields.tstart != (int)floor( tstart ) )
    || ( fileFields.tstart + fileFields.duration != (int)ceil( tend + deltaT ) ) )
  {
    XLALPrintError( "XLAL Error - %s: filename start time and duration not consistent with contents\n", __func__ );
    XLALDestroyREAL8VectorSequence( data );
    XLAL_ERROR( XLAL_EDATA );
  }
  if ( nrow > ndat ) /* this should be impossible */
  {
    XLALDestroyREAL8VectorSequence( data );
    XLAL_ERROR( XLAL_EDATA );
  }

  XLALGPSSetREAL8( &epoch, tstart );

  *alpha = XLALCreateREAL4TimeSeries( alphaName, &epoch, 0.0, deltaT, &lalDimensionlessUnit, ndat );
  *lal_gamma = XLALCreateREAL4TimeSeries( gammaName, &epoch, 0.0, deltaT, &lalDimensionlessUnit, ndat );
  if ( ! *alpha || ! *lal_gamma )
  {
    XLALDestroyREAL4TimeSeries( *lal_gamma );
    XLALDestroyREAL4TimeSeries( *alpha );
    XLALDestroyREAL8VectorSequence( data );
    XLAL_ERROR( XLAL_EFUNC );
  }

  /* clear the data memory */
  memset( (*alpha)->data->data, 0, (*alpha)->data->length * sizeof( *(*alpha)->data->data ) );
  memset( (*lal_gamma)->data->data, 0, (*lal_gamma)->data->length * sizeof( *(*lal_gamma)->data->data ) );

  /* IMPORTANT: SPECIFICATION SAYS THAT ALPHA IS COL 2 AND GAMMA IS COL 3 */
  fuzz = fuzzfactor * deltaT;
  dat = -1;
  for ( row = 0; row < nrow; ++row )
  {
    int   line     = ELEM(data,row,0);
    REAL8 trow     = ELEM(data,row,1);
    REAL4 alphaval = ELEM(data,row,2);
    REAL4 gammaval = ELEM(data,row,3);
    int thisdat = (int)floor( (trow - tstart) / deltaT + 0.5 );
    if ( thisdat <= dat ) /* rows must be monotonically increasing in time */
    {
      XLALPrintError( "XLAL Error - %s: error on line %d of file %s\n\trows must be monotonically increasing in time\n", __func__, line, fname );
      XLALDestroyREAL4TimeSeries( *lal_gamma );
      XLALDestroyREAL4TimeSeries( *alpha );
      XLALDestroyREAL8VectorSequence( data );
      XLAL_ERROR( XLAL_EDATA );
    }
    dat = thisdat;
    if ( fabs( (tstart + dat * deltaT) - trow ) > fuzz ) /* time between rows must be an integral multiple of deltaT */
    {
      XLALPrintError( "XLAL Error - %s: error on line %d of file %s\n\ttimes must be integral multiples of deltaT\n", __func__, line, fname );
      XLALDestroyREAL4TimeSeries( *lal_gamma );
      XLALDestroyREAL4TimeSeries( *alpha );
      XLALDestroyREAL8VectorSequence( data );
      XLAL_ERROR( XLAL_EDATA );
    }
    if ( dat >= ndat ) /* beyond length of array */
    {
      printf( "%d\t%d\n", dat, ndat );
      XLALPrintError( "XLAL Error - %s: error on line %d of file %s\n\ttime beyond end time\n", __func__, line, fname );
      XLALDestroyREAL4TimeSeries( *lal_gamma );
      XLALDestroyREAL4TimeSeries( *alpha );
      XLALDestroyREAL8VectorSequence( data );
      XLAL_ERROR( XLAL_EDATA );
    }
    (*alpha)->data->data[dat] = alphaval;
    (*lal_gamma)->data->data[dat] = gammaval;
  }

  XLALDestroyREAL8VectorSequence( data );
  return 0;
}
Esempio n. 11
0
/**
 * Single-IFO version of XLALCWMakeFakeMultiData(), handling the actual
 * work, but same input API. The 'detectorIndex' has the index of the detector
 * to be used from the multi-IFO arrays.
 */
int
XLALCWMakeFakeData ( SFTVector **SFTvect,
                     REAL8TimeSeries **Tseries,
                     const PulsarParamsVector *injectionSources,
                     const CWMFDataParams *dataParams,
                     UINT4 detectorIndex,	/* index for current detector in dataParams */
                     const EphemerisData *edat
                     )
{
  XLAL_CHECK ( (SFTvect == NULL) || ((*SFTvect) == NULL ), XLAL_EINVAL );
  XLAL_CHECK ( (Tseries == NULL) || ((*Tseries) == NULL ), XLAL_EINVAL );
  XLAL_CHECK ( (SFTvect != NULL) || (Tseries != NULL), XLAL_EINVAL );
  XLAL_CHECK ( edat != NULL, XLAL_EINVAL );

  XLAL_CHECK ( dataParams != NULL, XLAL_EINVAL );
  XLAL_CHECK ( detectorIndex < dataParams->multiIFO.length, XLAL_EINVAL );
  XLAL_CHECK ( detectorIndex < dataParams->multiNoiseFloor.length, XLAL_EINVAL );
  XLAL_CHECK ( detectorIndex < dataParams->multiTimestamps.length, XLAL_EINVAL );
  XLAL_CHECK ( (dataParams->inputMultiTS == NULL) || (detectorIndex < dataParams->inputMultiTS->length), XLAL_EINVAL );
  XLAL_CHECK ( (dataParams->inputMultiTS == NULL) || (dataParams->fMin == 0 && dataParams->Band == 0), XLAL_EINVAL, "If given time-series, must have fMin=Band=0\n");

  // initial default values fMin, sampling rate from caller input or timeseries
  REAL8 fMin  = dataParams->fMin;
  REAL8 fBand = dataParams->Band;
  REAL8 fSamp = 2.0 * fBand;
  if ( dataParams->inputMultiTS != NULL )
    {
      XLAL_CHECK ( (fMin == 0) && (fBand == 0), XLAL_EINVAL, "fMin and fBand must be 0 if input timeseries is given\n");
      const REAL8TimeSeries *ts = dataParams->inputMultiTS->data[detectorIndex];
      XLAL_CHECK ( ts != NULL, XLAL_EINVAL );
      REAL8 dt = ts->deltaT;
      fMin = ts->f0;
      fSamp = 1.0 / dt;
      fBand = 0.5 * fSamp;
    }

  const LIGOTimeGPSVector *timestamps = dataParams->multiTimestamps.data[detectorIndex];
  const LALDetector *site = &dataParams->multiIFO.sites[detectorIndex];
  REAL8 Tsft = timestamps->deltaT;

  // if SFT output requested: need *effective* fMin and Band consistent with SFT bins
  if ( SFTvect )
    {
      UINT4 firstBinEff, numBinsEff;
      XLAL_CHECK ( XLALFindCoveringSFTBins ( &firstBinEff, &numBinsEff, fMin, fBand, Tsft ) == XLAL_SUCCESS, XLAL_EFUNC );

      REAL8 fBand_eff = (numBinsEff - 1.0) / Tsft;
      REAL8 fMin_eff  = firstBinEff / Tsft;
      REAL8 fMax = fMin + dataParams->Band;
      REAL8 fMax_eff = fMin_eff + fBand_eff;
      if ( (fMin_eff != fMin) || (fBand_eff != fBand ) ) {
        XLALPrintWarning("Caller asked for Band [%.16g, %.16g] Hz, effective SFT-Band produced is [%.16g, %.16g] Hz\n",
                         fMin, fMax, fMin_eff, fMax_eff );
        XLAL_CHECK ( dataParams->inputMultiTS == NULL, XLAL_EINVAL, "Cannot expand effective frequency band with input timeseries given. Timeseries seems inconsistent with SFTs\n");
        fMin = fMin_eff;		// (potentially) lower minimal frequency to fit SFT bins
        fBand = fBand_eff;
        fSamp = 2.0 * fBand_eff;	// (potentially) higher sampling rate required to fit SFT bins
      } // if (fMin_eff != fMin) || (fBand_eff != fBand)
    } // if SFT-output requested

  // characterize the output time-series
  UINT4 n0_fSamp = (UINT4) round ( Tsft * fSamp );

  // by construction, fSamp * Tsft = integer, but if there are gaps between SFTs,
  // then we might have to sample at higher rates in order for all SFT-boundaries to
  // fall on exact timesteps of the timeseries.
  // ie we start from fsamp0 = n0_fSamp/Tsft, and then try to find the smallest
  // n1_fSamp >= n0_fSamp, such that for fsamp1 = n1_fSamp/Tsft, for all gaps i: Dt_i * fsamp1 = int
  UINT4 n1_fSamp;
  XLAL_CHECK ( XLALFindSmallestValidSamplingRate ( &n1_fSamp, n0_fSamp, timestamps ) == XLAL_SUCCESS, XLAL_EFUNC );

  if ( n1_fSamp != n0_fSamp )
    {
      REAL8 fSamp1 = n1_fSamp / Tsft;	// increased sampling rate to fit all gaps
      XLALPrintWarning ( "GAPS: Initial SFT sampling frequency fSamp0= %d/%.0f = %g had to be increased to fSamp1 = %d/%.0f = %g\n",
                         n0_fSamp, Tsft, fSamp, n1_fSamp, Tsft, fSamp1 );
      XLAL_CHECK ( dataParams->inputMultiTS == NULL, XLAL_EINVAL, "Cannot expand effective frequency band with input timeseries given. Timeseries seems inconsistent with SFT timestamps\n");
      fSamp = fSamp1;
    } // if higher effective sampling rate required

  // ----- start-time and duration -----
  LIGOTimeGPS firstGPS = timestamps->data[0];
  REAL8 firstGPS_REAL8 = XLALGPSGetREAL8 ( &firstGPS );
  LIGOTimeGPS lastGPS  = timestamps->data [ timestamps->length - 1 ];
  REAL8 lastGPS_REAL8 = XLALGPSGetREAL8 ( &lastGPS );
  XLALGPSAdd( &lastGPS, Tsft );
  REAL8 duration = XLALGPSDiff ( &lastGPS, &firstGPS );

  // start with an empty output time-series
  REAL4TimeSeries *Tseries_sum;
  {
    REAL8 numSteps = ceil ( fSamp * duration );
    XLAL_CHECK ( numSteps < (REAL8)LAL_UINT4_MAX, XLAL_EDOM, "Sorry, time-series of %g samples too long to fit into REAL4TimeSeries (maxLen = %g)\n", numSteps, (REAL8)LAL_UINT4_MAX );
    REAL8 dt = 1.0 / fSamp;
    REAL8 fHeterodyne = fMin;	// heterodyne signals at lower end of frequency-band
    CHAR *detPrefix = XLALGetChannelPrefix ( site->frDetector.name );
    XLAL_CHECK ( (Tseries_sum = XLALCreateREAL4TimeSeries ( detPrefix, &firstGPS, fHeterodyne, dt, &lalStrainUnit, (UINT4)numSteps )) != NULL, XLAL_EFUNC );
    memset ( Tseries_sum->data->data, 0, Tseries_sum->data->length * sizeof(Tseries_sum->data->data[0]) );
    XLALFree ( detPrefix );
  } // generate empty timeseries

  // add CW signals, if any
  UINT4 numPulsars = injectionSources ? injectionSources->length : 0;
  for ( UINT4 iInj = 0; iInj < numPulsars; iInj ++ )
    {
      // truncate any transient-CW timeseries to the actual support of the transient signal,
      // in order to make the generation more efficient, these 'partial timeseries'
      // will then be added to the full timeseries
      const PulsarParams *pulsarParams = &( injectionSources->data[iInj] );
      UINT4 t0, t1;
      XLAL_CHECK ( XLALGetTransientWindowTimespan ( &t0, &t1, pulsarParams->Transient ) == XLAL_SUCCESS, XLAL_EFUNC );

      // use latest possible start-time: max(t0,firstGPS), but not later than than lastGPS
      LIGOTimeGPS XLAL_INIT_DECL(signalStartGPS);
      if ( t0 <= firstGPS_REAL8 ) {
        signalStartGPS = firstGPS;
      } else if ( t0 >= lastGPS_REAL8 ) {
        signalStartGPS = lastGPS;
      }
      else {
        signalStartGPS.gpsSeconds = t0;
      }

      // use earliest possible end-time: min(t1,lastGPS), but not earlier than firstGPS
      LIGOTimeGPS XLAL_INIT_DECL(signalEndGPS);
      if ( t1 >= lastGPS_REAL8 ) {
        signalEndGPS = lastGPS;
      } else if ( t1 <= firstGPS_REAL8 ) {
        signalEndGPS = firstGPS;
      } else {
        signalEndGPS.gpsSeconds = t1;
      }
      REAL8 signalDuration = XLALGPSDiff ( &signalEndGPS, &signalStartGPS );
      XLAL_CHECK ( signalDuration >= 0, XLAL_EFAILED, "Something went wrong, got negative signal duration = %g\n", signalDuration );
      if ( signalDuration > 0 )	// only need to do sth if transient-window had finite overlap with output TS
        {
          REAL4TimeSeries *Tseries_i = NULL;
          XLAL_CHECK ( (Tseries_i = XLALGenerateCWSignalTS ( pulsarParams, site, signalStartGPS, signalDuration, fSamp, fMin, edat )) != NULL, XLAL_EFUNC );

          XLAL_CHECK ( (Tseries_sum = XLALAddREAL4TimeSeries ( Tseries_sum, Tseries_i )) != NULL, XLAL_EFUNC );
          XLALDestroyREAL4TimeSeries ( Tseries_i );
        }
    } // for iInj < numSources

  /* add Gaussian noise if requested */
  REAL8 sqrtSn = dataParams->multiNoiseFloor.sqrtSn[detectorIndex];
  if ( sqrtSn > 0)
    {
      REAL8 noiseSigma = sqrtSn * sqrt ( 0.5 * fSamp );
      INT4 randSeed = (dataParams->randSeed == 0) ? 0 : (dataParams->randSeed + detectorIndex);	// seed=0 means to use /dev/urandom, so don't touch it
      XLAL_CHECK ( XLALAddGaussianNoise ( Tseries_sum, noiseSigma, randSeed ) == XLAL_SUCCESS, XLAL_EFUNC );
    }

  // convert final signal+Gaussian-noise timeseries into REAL8 precision:
  REAL8TimeSeries *outTS;
  XLAL_CHECK ( (outTS = XLALConvertREAL4TimeSeriesToREAL8 ( Tseries_sum )) != NULL, XLAL_EFUNC );
  XLALDestroyREAL4TimeSeries ( Tseries_sum );

  // add input noise time-series here if given
  if ( dataParams->inputMultiTS != NULL ) {
    XLAL_CHECK ( (outTS = XLALAddREAL8TimeSeries ( outTS, dataParams->inputMultiTS->data[detectorIndex] )) != NULL, XLAL_EFUNC );
  }

  // turn final timeseries into SFTs, if requested
  if ( SFTvect != NULL )
    {
      // compute SFTs from timeseries
      SFTVector *sftVect;
      XLAL_CHECK ( (sftVect = XLALMakeSFTsFromREAL8TimeSeries ( outTS, timestamps, dataParams->SFTWindowType, dataParams->SFTWindowBeta)) != NULL, XLAL_EFUNC );

      // extract effective band from this, if neccessary (ie if faster-sampled output SFTs)
      if ( n1_fSamp != n0_fSamp )
        {
          XLAL_CHECK ( ((*SFTvect) = XLALExtractBandFromSFTVector ( sftVect, fMin, fBand )) != NULL, XLAL_EFUNC );
          XLALDestroySFTVector ( sftVect );
        }
      else
        {
          (*SFTvect) = sftVect;
        }
    } // if SFTvect

  // return timeseries if requested
  if ( Tseries != NULL ) {
    (*Tseries) = outTS;
  } else {
    XLALDestroyREAL8TimeSeries ( outTS );
  }

  return XLAL_SUCCESS;

} // XLALCWMakeFakeData()
Esempio n. 12
0
/*
 * main program entry point
 */
INT4 main(INT4 argc, CHAR **argv)
{
  /* status */
  LALStatus status = blank_status;

  /* counters */
  int c;
  UINT4 i;

  /* mode counters */
  UINT4 l, m;

  /* metadata file/directory */
  CHAR *nrMetaFile = NULL;
  CHAR *nrDataDir = NULL;
  CHAR file_path[FILENAME_MAX];

  /* metadata format */
  CHAR *metadata_format = NULL;

  /* metadata parsing variables */
  LALParsedDataFile *meta_file = NULL;
  BOOLEAN wasRead = 0;
  CHAR field[HISTORY_COMMENT];
  CHAR *wf_name[MAX_L+1][(2*MAX_L) + 1];

  /* common metadata */
  CHAR *md_mass_ratio = NULL;
  CHAR *md_spin1x = NULL;
  CHAR *md_spin1y = NULL;
  CHAR *md_spin1z = NULL;
  CHAR *md_spin2x = NULL;
  CHAR *md_spin2y = NULL;
  CHAR *md_spin2z = NULL;
  CHAR *md_freq_start_22 = NULL;

  /* NINJA1 metadata */
  CHAR *md_simulation_details = NULL;
  CHAR *md_nr_group = NULL;
  CHAR *md_email = NULL;

  /* NINJA2 metadata */
  CHAR *md_waveform_name = NULL;
  CHAR *md_initial_separation = NULL;
  CHAR *md_eccentricity = NULL;
  CHAR *md_number_of_cycles_22 = NULL;
  CHAR *md_code = NULL;
  CHAR *md_submitter_email = NULL;
  CHAR *md_authors_emails = NULL;

  /* common metadata strings */
  CHAR str_mass_ratio[HISTORY_COMMENT];
  CHAR str_spin1x[HISTORY_COMMENT];
  CHAR str_spin1y[HISTORY_COMMENT];
  CHAR str_spin1z[HISTORY_COMMENT];
  CHAR str_spin2x[HISTORY_COMMENT];
  CHAR str_spin2y[HISTORY_COMMENT];
  CHAR str_spin2z[HISTORY_COMMENT];
  CHAR str_freq_start_22[HISTORY_COMMENT];
  CHAR str_creator[HISTORY_COMMENT];

  /* NINJA1 metadata strings */
  CHAR str_simulation_details[HISTORY_COMMENT];
  CHAR str_nr_group[HISTORY_COMMENT];
  CHAR str_email[HISTORY_COMMENT];

  /* NINJA2 metadata strings */
  CHAR str_waveform_name[HISTORY_COMMENT];
  CHAR str_initial_separation[HISTORY_COMMENT];
  CHAR str_eccentricity[HISTORY_COMMENT];
  CHAR str_number_of_cycles_22[HISTORY_COMMENT];
  CHAR str_code[HISTORY_COMMENT];
  CHAR str_submitter_email[HISTORY_COMMENT];
  CHAR str_authors_emails[HISTORY_COMMENT];

  /* channel names */
  CHAR *plus_channel[MAX_L+1][(2*MAX_L) + 1];
  CHAR *cross_channel[MAX_L+1][(2*MAX_L) + 1];

  /* waveforms */
  UINT4 wf_length;
  REAL4TimeVectorSeries *waveforms[MAX_L][(2*MAX_L) + 1];
  REAL4TimeSeries *hplus[MAX_L+1][(2*MAX_L) + 1];
  REAL4TimeSeries *hcross[MAX_L+1][(2*MAX_L) + 1];

  REAL8TimeVectorSeries *waveformsREAL8[MAX_L][(2*MAX_L) + 1];
  REAL8TimeSeries *hplusREAL8[MAX_L+1][(2*MAX_L) + 1];
  REAL8TimeSeries *hcrossREAL8[MAX_L+1][(2*MAX_L) + 1];

  /* frame variables */
  LALFrameH *frame;
  CHAR *frame_name = NULL;
  LIGOTimeGPS epoch;
  INT4 duration;
  INT4 detector_flags;

  INT4 generatingREAL8 = 0;

  /* LALgetopt arguments */
  struct LALoption long_options[] =
  {
    /* options that set a flag */
    {"verbose", no_argument, &vrbflg, 1},
    /* options that don't set a flag */
    {"format", required_argument, 0, 'f'},
    {"nr-meta-file", required_argument, 0, 'm'},
    {"nr-data-dir", required_argument, 0, 'd'},
    {"output", required_argument, 0, 'o'},
    {"double-precision", no_argument, 0, 'p'},
    {"help", no_argument, 0, 'h'},
    {"version", no_argument, 0, 'V'},
    {0, 0, 0, 0}
  };

  /* default debug level */
  lal_errhandler = LAL_ERR_EXIT;

  /* parse the arguments */
  while(1)
  {
    /* LALgetopt_long stores long option here */
    int option_index = 0;
    size_t LALoptarg_len;

    c = LALgetopt_long_only(argc, argv, "f:m:d:o:phV", long_options, &option_index);

    /* detect the end of the options */
    if (c == -1)
      break;

    switch(c)
    {
      case 0:
        /* if this option sets a flag, do nothing else for now */
        if (long_options[option_index].flag != 0)
          break;
        else
        {
          fprintf(stderr, "Error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg);
          exit(1);
        }
        break;

      case 'h':
        /* help message */
        print_usage(stdout, argv[0]);
        exit(0);
        break;

      case 'V':
        /* print version information and exit */
        fprintf(stdout, "Numerical Relativity Frame Generation\n");
        XLALOutputVersionString(stderr, 0);
        exit(0);
        break;

      case 'f':
        /* create storage for the metadata format */
        LALoptarg_len = strlen(LALoptarg) + 1;
        metadata_format = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR));
        memcpy(metadata_format, LALoptarg, LALoptarg_len);
        break;

      case 'm':
        /* create storage for the meta file name */
        LALoptarg_len = strlen(LALoptarg) + 1;
        nrMetaFile = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR));
        memcpy(nrMetaFile, LALoptarg, LALoptarg_len);
        break;

      case 'd':
        /* create storage for the meta data directory name */
        LALoptarg_len = strlen(LALoptarg) + 1;
        nrDataDir = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR));
        memcpy(nrDataDir, LALoptarg, LALoptarg_len);
        break;

      case 'o':
        /* create storage for the output frame file name */
        LALoptarg_len = strlen(LALoptarg) + 1;
        frame_name = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR));
        memcpy(frame_name, LALoptarg, LALoptarg_len);
        break;

      case 'p':
        /* We're generating a double-precision frame */
        generatingREAL8 = 1;
        break;

      case '?':
        print_usage(stderr, argv[0]);
        exit(1);
        break;

      default:
        fprintf(stderr, "Unknown error while parsing arguments\n");
        print_usage(stderr, argv[0]);
        exit(1);
        break;
    }
  }

  /* check for extraneous command line arguments */
  if (LALoptind < argc)
  {
    fprintf(stderr, "Extraneous command line arguments:\n");
    while(LALoptind < argc)
      fprintf(stderr, "%s\n", argv[LALoptind++]);
    exit(1);
  }

  /*
   * check validity of arguments
   */

  /* metadata format specified */
  if (metadata_format == NULL)
  {
    fprintf(stderr, "warning: --format not specified, assuming NINJA1\n");
    metadata_format = (CHAR *)calloc(7, sizeof(CHAR));
    memcpy(metadata_format, "NINJA1", 7);
  }

  /* check for supported metadata format */
  if (strcmp(metadata_format, "NINJA1") == 0);
  else if (strcmp(metadata_format, "NINJA2") == 0);
  else
  {
    fprintf(stderr, "Supported metadata formats are NINJA1 and NINJA2 (%s specified)\n", metadata_format);
    exit(1);
  }

  /* meta file specified */
  if (nrMetaFile == NULL)
  {
    fprintf(stderr, "--nr-meta-file must be specified\n");
    exit(1);
  }

  /* data directory specified */
  if (nrDataDir == NULL)
  {
    fprintf(stderr, "--nr-data-dir must be specified\n");
    exit(1);
  }

  /* output frame filename specified */
  if (frame_name == NULL)
  {
    fprintf(stderr, "--output must be specified\n");
    exit(1);
  }

  /*
   * main code
   */

  /* frame metadata */
  /* TODO: set these to something sensible */
  duration = 0;
  epoch.gpsSeconds = 0;
  epoch.gpsNanoSeconds = 0;
  detector_flags = 0;

  if (vrbflg)
    fprintf(stdout, "reading metadata: %s\n", nrMetaFile);

  /* open metadata file */
  XLAL_CHECK ( XLALParseDataFile(&meta_file, nrMetaFile) == XLAL_SUCCESS, XLAL_EFUNC );

  /*
   * get metadata
   */

  /* common metadata */
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_mass_ratio, meta_file, NULL, "mass-ratio", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin1x, meta_file, NULL, "spin1x", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin1y, meta_file, NULL, "spin1y", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin1z, meta_file, NULL, "spin1z", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin2x, meta_file, NULL, "spin2x", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin2y, meta_file, NULL, "spin2y", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin2z, meta_file, NULL, "spin2z", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );

  /* format specific metadata */
  if (strcmp(metadata_format, "NINJA1") == 0)
  {
    /* NINJA1 */
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_simulation_details, meta_file, NULL, "simulation-details", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_nr_group, meta_file, NULL, "nr-group", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_email, meta_file, NULL, "email", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_freq_start_22, meta_file, NULL, "freqStart22", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  }
  else if (strcmp(metadata_format, "NINJA2") == 0)
  {
    /* NINJA2 */
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_waveform_name, meta_file, NULL, "waveform-name", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_initial_separation, meta_file, NULL, "initial-separation", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_eccentricity, meta_file, NULL, "eccentricity", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_number_of_cycles_22, meta_file, NULL, "number-of-cycles-22", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_code, meta_file, NULL, "code", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_submitter_email, meta_file, NULL, "submitter-email", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_authors_emails, meta_file, NULL, "authors-emails", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_freq_start_22, meta_file, NULL, "freq-start-22", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );
  }
  else
  {
    /* unknown metadata format - should not be executed */
    fprintf(stderr, "error: unsupported metadata format: %s\n", metadata_format);
    exit(1);
  }

  /*
   * set metadata strings
   */

  /* common waveform */
  snprintf(str_mass_ratio, HISTORY_COMMENT, "mass-ratio:%s", md_mass_ratio);
  snprintf(str_spin1x, HISTORY_COMMENT, "spin1x:%s", md_spin1x);
  snprintf(str_spin1y, HISTORY_COMMENT, "spin1y:%s", md_spin1y);
  snprintf(str_spin1z, HISTORY_COMMENT, "spin1z:%s", md_spin1z);
  snprintf(str_spin2x, HISTORY_COMMENT, "spin2x:%s", md_spin2x);
  snprintf(str_spin2y, HISTORY_COMMENT, "spin2y:%s", md_spin2y);
  snprintf(str_spin2z, HISTORY_COMMENT, "spin2z:%s", md_spin2z);
  snprintf(str_creator, HISTORY_COMMENT, "creator:%s(git:%s)", PROGRAM_NAME, lalAppsVCSId);

  /* format specific metadata */
  if (strcmp(metadata_format, "NINJA1") == 0)
  {
    /* NINJA1 */
    snprintf(str_freq_start_22, HISTORY_COMMENT, "freqStart22:%s", md_freq_start_22);
    snprintf(str_simulation_details, HISTORY_COMMENT, "simulation-details:%s", md_simulation_details);
    snprintf(str_nr_group, HISTORY_COMMENT, "nr-group:%s", md_nr_group);
    snprintf(str_email, HISTORY_COMMENT, "email:%s", md_email);
  }
  else if (strcmp(metadata_format, "NINJA2") == 0)
  {
    /* NINJA2 */
    snprintf(str_waveform_name, HISTORY_COMMENT, "waveform-name:%s", md_waveform_name);
    snprintf(str_initial_separation, HISTORY_COMMENT, "inital-separation:%s", md_initial_separation);
    snprintf(str_eccentricity, HISTORY_COMMENT, "eccentricity:%s", md_eccentricity);
    snprintf(str_freq_start_22, HISTORY_COMMENT, "freq_start_22:%s", md_freq_start_22);
    snprintf(str_number_of_cycles_22, HISTORY_COMMENT, "number-of-cycles-22:%s", md_number_of_cycles_22);
    snprintf(str_code, HISTORY_COMMENT, "code:%s", md_code);
    snprintf(str_submitter_email, HISTORY_COMMENT, "submitter-email:%s", md_submitter_email);
    snprintf(str_authors_emails, HISTORY_COMMENT, "authors-emails:%s", md_authors_emails);
  }
  else
  {
    /* unknown metadata format - should not be executed */
    fprintf(stderr, "error: unsupported metadata format: %s\n", metadata_format);
    exit(1);
  }

  /* define frame */
  frame = XLALFrameNew(&epoch, duration, "NR", 0, 1, detector_flags);

  /*
   * add metadata as FrHistory structures
   */

  /* common metadata */
  XLALFrameAddFrHistory(frame, "creator", str_creator);
  XLALFrameAddFrHistory(frame, "mass-ratio", str_mass_ratio);
  XLALFrameAddFrHistory(frame, "spin1x", str_spin1x);
  XLALFrameAddFrHistory(frame, "spin1y", str_spin1y);
  XLALFrameAddFrHistory(frame, "spin1z", str_spin1z);
  XLALFrameAddFrHistory(frame, "spin2x", str_spin2x);
  XLALFrameAddFrHistory(frame, "spin2y", str_spin2y);
  XLALFrameAddFrHistory(frame, "spin2z", str_spin2z);

  /* format specific metadata */
  if (strcmp(metadata_format, "NINJA1") == 0)
  {
    /* NINJA1 */
    XLALFrameAddFrHistory(frame, "simulation-details", str_simulation_details);
    XLALFrameAddFrHistory(frame, "nr-group", str_nr_group);
    XLALFrameAddFrHistory(frame, "email", str_email);
    XLALFrameAddFrHistory(frame, "freqStart22", str_freq_start_22);
  }
  else if (strcmp(metadata_format, "NINJA2") == 0)
  {
    /* NINJA2 */
    XLALFrameAddFrHistory(frame, "waveform-name", str_waveform_name);
    XLALFrameAddFrHistory(frame, "initial-separation", str_initial_separation);
    XLALFrameAddFrHistory(frame, "eccentricity", str_eccentricity);
    XLALFrameAddFrHistory(frame, "freq_start_22", str_freq_start_22);
    XLALFrameAddFrHistory(frame, "number-of-cycles-22", str_number_of_cycles_22);
    XLALFrameAddFrHistory(frame, "code", str_code);
    XLALFrameAddFrHistory(frame, "submitter-email", str_code);
    XLALFrameAddFrHistory(frame, "authors-emails", str_authors_emails);
  }
  else
  {
    /* unknown metadata format - should not be executed */
    fprintf(stderr, "error: unsupported metadata format: %s\n", metadata_format);
    exit(1);
  }

  /* loop over l & m values */
  for (l = MIN_L; l <= MAX_L; l++)
  {
    for (m = (MAX_L - l); m <= MAX_L + l; m++)
    {
      /* ensure pointers are NULL */
      wf_name[l][m] = NULL;
      plus_channel[l][m] = NULL;
      cross_channel[l][m] = NULL;

      /* generate channel names */
      plus_channel[l][m] = XLALGetNinjaChannelName("plus", l, m - MAX_L);
      cross_channel[l][m] = XLALGetNinjaChannelName("cross", l, m - MAX_L);

      if (generatingREAL8)
      {
        hplusREAL8[l][m] = NULL;
        hcrossREAL8[l][m] = NULL;
        waveformsREAL8[l][m] = NULL;
        
        /* initilise waveform time series */
        hplusREAL8[l][m] = XLALCreateREAL8TimeSeries(plus_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0);
        hcrossREAL8[l][m] = XLALCreateREAL8TimeSeries(cross_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0);
      }
      else
      {
        hplus[l][m] = NULL;
        hcross[l][m] = NULL;
        waveforms[l][m] = NULL;
      
        /* initilise waveform time series */
        hplus[l][m] = XLALCreateREAL4TimeSeries(plus_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0);
        hcross[l][m] = XLALCreateREAL4TimeSeries(cross_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0);
      }

      /* read ht-data section of metadata file */
      snprintf(field, HISTORY_COMMENT, "%d,%d", l, m - MAX_L);
      XLAL_CHECK ( XLALReadConfigSTRINGVariable( &wf_name[l][m], meta_file, NULL, field, &wasRead) == XLAL_SUCCESS, XLAL_EFUNC );

      /* read waveform */
      if (wf_name[l][m] != NULL)
      {
        /* get full path to waveform data file */
        snprintf(file_path, FILENAME_MAX, "%s/%s", nrDataDir, wf_name[l][m]);

        if (vrbflg)
          fprintf(stdout, "reading waveform: %s\n", file_path);

        /* read waveforms */
        if (generatingREAL8)
        {
          LAL_CALL(LALReadNRWave_raw_real8(&status, &waveformsREAL8[l][m], file_path), &status);
        }
        else
        {
          LAL_CALL(LALReadNRWave_raw(&status, &waveforms[l][m], file_path), &status);
        }
      }

      /* generate waveform time series from vector series */
      /* TODO: should use pointer arithmetic here and update the data
       * pointer in the REAL4TimeSeries to point to the appropriate
       * location within the REAL4TimeVector Series */
      if (generatingREAL8) {
        if (waveformsREAL8[l][m])
        {
          /* get length of waveform */
          wf_length = waveformsREAL8[l][m]->data->vectorLength;

          /* allocate memory for waveform */
          XLALResizeREAL8TimeSeries(hplusREAL8[l][m], 0, wf_length);
          XLALResizeREAL8TimeSeries(hcrossREAL8[l][m], 0, wf_length);

          /* set time spacing */
          hplusREAL8[l][m]->deltaT = waveformsREAL8[l][m]->deltaT;
          hcrossREAL8[l][m]->deltaT = waveformsREAL8[l][m]->deltaT;

          /* copy waveforms into appropriate series */
          for (i = 0; i < wf_length; i ++) {
            hplusREAL8[l][m]->data->data[i] = waveformsREAL8[l][m]->data->data[i];
            hcrossREAL8[l][m]->data->data[i] = waveformsREAL8[l][m]->data->data[wf_length + i];
          }

          /* Done with waveformsREAL8, clean up here to limit memory usage */
          LALFree(waveformsREAL8[l][m]->data->data);
          LALFree(waveformsREAL8[l][m]->data);
          LALFree(waveformsREAL8[l][m]);
        }
      }
      else /* REAL4 */
      {
        if (waveforms[l][m])
        {
          /* get length of waveform */
          wf_length = waveforms[l][m]->data->vectorLength;

          /* allocate memory for waveform */
          XLALResizeREAL4TimeSeries(hplus[l][m], 0, wf_length);
          XLALResizeREAL4TimeSeries(hcross[l][m], 0, wf_length);

          /* set time spacing */
          hplus[l][m]->deltaT = waveforms[l][m]->deltaT;
          hcross[l][m]->deltaT = waveforms[l][m]->deltaT;

          /* copy waveforms into appropriate series */
          for (i = 0; i < wf_length; i ++) {
            hplus[l][m]->data->data[i] = waveforms[l][m]->data->data[i];
            hcross[l][m]->data->data[i] = waveforms[l][m]->data->data[wf_length + i];
          }
        }
      }

      /* add channels to frame */
      if (generatingREAL8)
      {
        if ((hplusREAL8[l][m]->data->length) && (hcrossREAL8[l][m]->data->length))
        {
          XLALFrameAddREAL8TimeSeriesSimData(frame, hplusREAL8[l][m]);
          XLALFrameAddREAL8TimeSeriesSimData(frame, hcrossREAL8[l][m]);
        }
      }
      else
      {
        if ((hplus[l][m]->data->length) && (hcross[l][m]->data->length))
        {
          XLALFrameAddREAL4TimeSeriesSimData(frame, hplus[l][m]);
          XLALFrameAddREAL4TimeSeriesSimData(frame, hcross[l][m]);
        }
      }
    }
  }

  if (vrbflg)
    fprintf(stdout, "writing frame: %s\n", frame_name);

  /* write frame */
  if (XLALFrameWrite(frame, frame_name) != 0 )
  {
    fprintf(stderr, "Error: Cannot save frame file '%s'\n", frame_name);
    exit(1);
  }

  /*
   * clear memory
   */

  /* strings */
  if(nrMetaFile) free(nrMetaFile);
  if(nrDataDir)  free(nrDataDir);
  if(frame_name) free(frame_name);
  if(metadata_format) free(metadata_format);

  /* common metadata */
  if(md_mass_ratio) LALFree(md_mass_ratio);
  if(md_spin1x) LALFree(md_spin1x);
  if(md_spin1y) LALFree(md_spin1y);
  if(md_spin1z) LALFree(md_spin1z);
  if(md_spin2x) LALFree(md_spin2x);
  if(md_spin2y) LALFree(md_spin2y);
  if(md_spin2z) LALFree(md_spin2z);
  if(md_freq_start_22) LALFree(md_freq_start_22);

  /* NINJA1 metadata */
  if(md_simulation_details) LALFree(md_simulation_details);
  if(md_nr_group)           LALFree(md_nr_group);
  if(md_email)              LALFree(md_email);

  /* NINJA2 metadata */
  if(md_waveform_name)       LALFree(md_waveform_name);
  if(md_initial_separation)  LALFree(md_initial_separation);
  if(md_eccentricity)        LALFree(md_eccentricity);
  if(md_number_of_cycles_22) LALFree(md_number_of_cycles_22);
  if(md_code)                LALFree(md_code);
  if(md_submitter_email)     LALFree(md_submitter_email);
  if(md_authors_emails)      LALFree(md_authors_emails);

  /* config file */
  if(meta_file->lines->list->data) LALFree(meta_file->lines->list->data);
  if(meta_file->lines->list)   LALFree(meta_file->lines->list);
  if(meta_file->lines->tokens) LALFree(meta_file->lines->tokens);
  if(meta_file->lines)   LALFree(meta_file->lines);
  if(meta_file->wasRead) LALFree(meta_file->wasRead);
  if(meta_file)          LALFree(meta_file);

  /* waveforms */
  if (generatingREAL8)
  {
    for (l = MIN_L; l <= MAX_L; l++)
    {
      for (m = (MAX_L - l); m <= MAX_L + l; m++)
      {
        /* channel names */
        if (plus_channel[l][m])
          LALFree(plus_channel[l][m]);

        if (cross_channel[l][m])
          LALFree(cross_channel[l][m]);

        if (wf_name[l][m])
          LALFree(wf_name[l][m]);

        /* hplus */
        if (hplusREAL8[l][m])
          XLALDestroyREAL8TimeSeries(hplusREAL8[l][m]);

        /* hcross */
        if (hcrossREAL8[l][m])
          XLALDestroyREAL8TimeSeries(hcrossREAL8[l][m]);
      }
    }
  }
  else
  {
    for (l = MIN_L; l <= MAX_L; l++)
    {
      for (m = (MAX_L - l); m <= MAX_L + l; m++)
      {
        /* channel names */
        if (plus_channel[l][m])
          LALFree(plus_channel[l][m]);

        if (cross_channel[l][m])
          LALFree(cross_channel[l][m]);

        if (wf_name[l][m])
          LALFree(wf_name[l][m]);

        /* raw waveforms */
        if (waveforms[l][m]) {
          LALFree(waveforms[l][m]->data->data);
          LALFree(waveforms[l][m]->data);
          LALFree(waveforms[l][m]);
        }

        /* hplus */
        if (hplus[l][m])
          XLALDestroyREAL4TimeSeries(hplus[l][m]);

        /* hcross */
        if (hcross[l][m])
          XLALDestroyREAL4TimeSeries(hcross[l][m]);
      }
    }
  }

  /* clear frame */
  XLALFrameFree(frame);

  /* check for memory leaks */
  LALCheckMemoryLeaks();

  exit(0);
}
Esempio n. 13
0
/* read and high pass filter a GEO time series */
REAL4TimeSeries *get_geo_data(LALFrStream *stream,
    CHAR *channel,
    LIGOTimeGPS start,
    LIGOTimeGPS end,
    INT4 hpf_order,
    REAL8 hpf_frequency,
    REAL8 hpf_attenuation)
{
  /* variables */
  PassBandParamStruc high_pass_params;
  REAL4TimeSeries *series;
  REAL8TimeSeries *geo;
  size_t length;
  size_t i;

  if (vrbflg)
    fprintf(stdout, "Allocating memory for \"%s\" series...\n", channel);

  /* create and initialise time series */
  geo = XLALCreateREAL8TimeSeries(channel, &start, 0, 0, \
        &lalADCCountUnit, 0);

  if (vrbflg)
    fprintf(stdout, "Reading \"%s\" series metadata...\n", channel);

  /* get the series meta data */
  XLALFrStreamGetREAL8TimeSeriesMetadata(geo, stream);

  if (vrbflg)
    fprintf(stdout, "Resizing \"%s\" series...\n", channel);

  /* resize series to the correct number of samples */
  length = floor((XLALGPSDiff(&end, &start) / geo->deltaT) + 0.5);
  XLALResizeREAL8TimeSeries(geo, 0, length);

  if (vrbflg)
    fprintf(stdout, "Reading channel \"%s\"...\n", channel);

  /* seek to and read data */
  XLALFrStreamSeek(stream, &start);
  XLALFrStreamGetREAL8TimeSeries(geo, stream);

  if (vrbflg)
    fprintf(stdout, "High pass filtering \"%s\"...\n", channel);

  /* high pass filter before casting to a REAL4 */
  high_pass_params.nMax = hpf_order;
  high_pass_params.f1 = -1;
  high_pass_params.f2 = hpf_frequency;
  high_pass_params.a1 = -1;
  high_pass_params.a2 = hpf_attenuation;
  XLALButterworthREAL8TimeSeries(geo, &high_pass_params);

  if (vrbflg)
    fprintf(stdout, "Casting \"%s\" as a REAL4...\n", channel);

  /* cast as a REAL4 */
  series = XLALCreateREAL4TimeSeries(geo->name, &geo->epoch, geo->f0, \
      geo->deltaT, &geo->sampleUnits, geo->data->length);
  for (i = 0; i < series->data->length; i++)
    series->data->data[i] = (REAL4)geo->data->data[i];

  /* destroy geo series */
  XLALDestroyREAL8TimeSeries(geo);

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

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

  UINT4 numSpins = 3;

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

  UINT4 numSteps = timestamps->length;

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

  XLALDestroyTimestampVector ( timestamps );
  timestamps = NULL;

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

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

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

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

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

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

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

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

      XLALGPSSetREAL8( &newEpoch, startTimeSSB );

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

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

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

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

      refTime = startTimeSSB;

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

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

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

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

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

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

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

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

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

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

    } /* for i < numSteps */

  XLALDestroyDetectorStateSeries( detStates );
  XLALDestroyAMCoeffs ( amcoe );

  return ts;

} /* XLALSimulateExactPulsarSignal() */
Esempio n. 15
0
REAL4TimeSeries *
XLALCutAtFreq(
	      REAL4TimeSeries *h,
	      REAL4Vector     *freq,
	      REAL8           cutFreq)
{
  REAL8 dt;
  UINT4 k, k0, kMid, len;
  REAL4 currentFreq;
  UINT4 newLen;

  REAL4TimeSeries *newH = NULL;

  LIGOTimeGPS epoch;

  len = freq->length;
  dt = h->deltaT;

  /* Since the boundaries of this freq vector are likely to have   */
  /* FFT crap, let's scan the freq values starting from the middle */
  kMid = len/2;
  currentFreq = freq->data[kMid];
  k = kMid;

  /* freq is an increasing function of time */
  /* If we are above the cutFreq we move to the left; else to the right */
  if (currentFreq > cutFreq && k > 0)
    {
      while(currentFreq > cutFreq)
	{
	  currentFreq = freq->data[k];
	  k--;
	}
      k0 = k;
    }
  else
    {
      while(currentFreq < cutFreq && k < len)
	{
	  currentFreq = freq->data[k];
	  k++;
	}
      k0 = k;
    }

  newLen = len - k0;

  /* Allocate memory for the frequency series */
  epoch.gpsSeconds = 0;
  epoch.gpsNanoSeconds = 0;
  newH =
    XLALCreateREAL4TimeSeries("", &epoch, 0, dt, &lalDimensionlessUnit, newLen);

  for(k = 0; k < newLen; k++)
    {
      newH->data->data[k] = h->data->data[k0 + k];
    }

  return newH;

}
Esempio n. 16
0
/* Main Program */
INT4 main ( INT4 argc, CHAR *argv[] ) {

  static LALStatus status;
  INT4 c;
  UINT4 i;
  REAL8 dt, totTime;
  REAL8 sampleRate = -1;
  REAL8 totalMass = -1, massRatio = -1;
  REAL8 lowFreq = -1, df, fLow;
  CHAR  *outFile = NULL, *outFileLong = NULL, tail[50];
  size_t optarg_len;
  REAL8 eta;
  REAL8 newtonianChirpTime, PN1ChirpTime, mergTime;
  UINT4 numPts;
  LIGOTimeGPS epoch;
  REAL8 offset;

  PhenomCoeffs coeffs;
  PhenomParams params;

  REAL4FrequencySeries     *Aeff   = NULL, *Phieff  = NULL;
  COMPLEX8Vector           *uFPlus = NULL, *uFCross = NULL;

  COMPLEX8 num;

  REAL4Vector      *hPlus = NULL, *hCross = NULL;
  REAL4TimeSeries  *hP = NULL, *hC = NULL;
  /*  REAL4TimeSeries  *hP = NULL, *hC = NULL;*/
  REAL4FFTPlan     *prevPlus = NULL, *prevCross = NULL;

  /*REAL4Vector      *Freq = NULL;*/

  UINT4 windowLength;
  INT4 hPLength;
  REAL8 linearWindow;

  /* getopt arguments */
  struct option long_options[] =
  {
    {"mass-ratio",              required_argument, 0,                'q'},
    {"low-freq (Hz)",           required_argument, 0,                'f'},
    {"total-mass (M_sun)",      required_argument, 0,                'm'},
    {"sample-rate",             required_argument, 0,                's'},
    {"output-file",             required_argument, 0,                'o'},
    {"help",                    no_argument,       0,                'h'},
    {"version",                 no_argument,       0,                'V'},
    {0, 0, 0, 0}
  };

  /* parse the arguments */
  while ( 1 )
  {
    /* getopt_long stores long option here */
    int option_index = 0;

    /* parse command line arguments */
    c = getopt_long_only( argc, argv, "q:t:d:hV",
        long_options, &option_index );

    /* detect the end of the options */
    if ( c == -1 )
      {
	break;
      }

    switch ( c )
    {
      case 0:
        fprintf( stderr, "Error parsing option '%s' with argument '%s'\n",
            long_options[option_index].name, optarg );
        exit( 1 );
        break;

      case 'h':
        /* help message */
        print_usage( argv[0] );
        exit( 0 );
        break;

      case 'V':
        /* print version information and exit */
        fprintf( stdout, "%s - Compute Ajith's Phenomenological Waveforms " \
		 "(arXiv:0710.2335) and output them to a plain text file\n" \
            "CVS Version: %s\nCVS Tag: %s\n", PROGRAM_NAME, CVS_ID_STRING, \
            CVS_NAME_STRING );
        exit( 0 );
        break;

      case 'q':
        /* set mass ratio */
        massRatio = atof( optarg );
        break;

      case 'f':
        /* set low freq */
        lowFreq = atof( optarg );
        break;

      case 'm':
        /* set total mass */
        totalMass = atof( optarg );
        break;

      case 's':
        /* set sample rate */
        sampleRate = atof( optarg );
        break;

      case 'o':
	/* set name of output file */
        optarg_len = strlen(optarg) + 1;
        outFile = (CHAR *)calloc(optarg_len, sizeof(CHAR));
        memcpy(outFile, optarg, optarg_len);
	break;

      case '?':
        print_usage( argv[0] );
        exit( 1 );
        break;

      default:
        fprintf( stderr, "ERROR: Unknown error while parsing options\n" );
        print_usage( argv[0] );
        exit( 1 );
    }
  }

  if ( optind < argc )
  {
    fprintf( stderr, "ERROR: Extraneous command line arguments:\n" );
    while ( optind < argc )
      {
	fprintf ( stderr, "%s\n", argv[optind++] );
      }
    exit( 1 );
  }


  /* * * * * * * * */
  /* Main Program  */
  /* * * * * * * * */

  eta = massRatio / pow(1. + massRatio, 2.);

  /* This freq low is the one used for the FFT */
  /* fLow = 2.E-3/(totalMass*LAL_MTSUN_SI); */
  fLow = lowFreq;       /* Changed by Ajith. 5 May 2008 */

  /* Phenomenological coefficients as in Ajith et. al */
  GetPhenomCoeffsLongJena( &coeffs );

  /* Compute phenomenologial parameters */
  ComputeParamsFromCoeffs( &params, &coeffs, eta, totalMass );


  /* Check validity of arguments */

  /* check we have freqs */
  if ( totalMass < 0 )
    {
      fprintf( stderr, "ERROR: --total-mass must be specified\n" );
      exit( 1 );
    }

  /* check we have mass ratio and delta t*/
  if ( massRatio < 0 )
    {
      fprintf( stderr, "ERROR: --mass-ratio must be specified\n" );
      exit( 1 );
    }
  if ( lowFreq < 0 )
    {
      fprintf( stderr, "ERROR: --low-freq must be specified\n" );
      exit( 1 );
    }
  if ( sampleRate < 0 )
    {
      fprintf( stderr, "ERROR: --sample-rate must be specified\n" );
      exit( 1 );
    }
  if ( lowFreq > params.fCut )
    {
      fprintf( stderr, "\nERROR in --low-freq\n"\
	       "The value chosen for the low frequency is larger "\
	       "than the frequency at the merger.\n"
	       "Frequency at the merger: %4.2f Hz\nPick either a lower value"\
	       " for --low-freq or a lower total mass\n\n", params.fCut);
      exit(1);
    }
  if ( lowFreq < fLow )
    {
      fprintf( stderr, "\nERROR in --low-freq\n"\
	       "The value chosen for the low frequency is lower "\
	       "than the lowest frequency computed\nby the implemented FFT.\n"
	       "Lowest frequency allowed: %4.2f Hz\nPick either a higher value"\
	       " for --low-freq or a higher total mass\n\n", fLow);
      exit(1);
    }
  if ( outFile == NULL )
    {
      fprintf( stderr, "ERROR: --output-file must be specified\n" );
      exit( 1 );
    }

  /* Complete file name with details of the input variables */
  sprintf(tail, "%s-Phenom_M%3.1f_R%2.1f.dat", outFile, totalMass, massRatio);
  optarg_len = strlen(tail) + strlen(outFile) + 1;
  outFileLong = (CHAR *)calloc(optarg_len, sizeof(CHAR));
  strcpy(outFileLong, tail);

  /* check sample rate is enough */
  if (sampleRate > 4.*params.fCut)   /* Changed by Ajith. 5 May 2008 */
    {
      dt = 1./sampleRate;
    }
  else
    {
      sampleRate = 4.*params.fCut;
      dt = 1./sampleRate;
    }

  /* Estimation of the time duration of the binary           */
  /* See Sathya (1994) for the Newtonian and PN1 chirp times */
  /* The merger time is overestimated                        */
  newtonianChirpTime =
    (5./(256.*eta))*pow(totalMass*LAL_MTSUN_SI,-5./3.)*pow(LAL_PI*fLow,-8./3.);
  PN1ChirpTime =
    5.*(743.+924.*eta)/(64512.*eta*totalMass*LAL_MTSUN_SI*pow(LAL_PI*fLow,2.));
  mergTime = 2000.*totalMass*LAL_MTSUN_SI;
  totTime = 1.2 * (newtonianChirpTime + PN1ChirpTime + mergTime);

  numPts = (UINT4) ceil(totTime/dt);
  df = 1/(numPts * dt);

  /* Compute Amplitude and Phase from the paper (Eq. 4.19) */
  Aeff = XLALHybridP1Amplitude(&params, fLow, df, eta, totalMass, numPts/2+1);
  Phieff = XLALHybridP1Phase(&params, fLow, df, eta, totalMass, numPts/2 +1);

  /* Construct u(f) = Aeff*e^(i*Phieff) */
  XLALComputeComplexVector(&uFPlus, &uFCross, Aeff, Phieff);

  /* Scale this to units of M */
  for (i = 0; i < numPts/2 + 1; i++) {
    num = uFPlus->data[i];
    num.re *= 1./(dt*totalMass*LAL_MTSUN_SI);
    num.im *= 1./(dt*totalMass*LAL_MTSUN_SI);
    uFPlus->data[i] = num;
    num = uFCross->data[i];
    num.re *= 1./(dt*totalMass*LAL_MTSUN_SI);
    num.im *= 1./(dt*totalMass*LAL_MTSUN_SI);
    uFCross->data[i] = num;
  }

  /* Inverse Fourier transform */
  LALCreateReverseREAL4FFTPlan( &status, &prevPlus, numPts, 0 );
  LALCreateReverseREAL4FFTPlan( &status, &prevCross, numPts, 0 );
  hPlus = XLALCreateREAL4Vector(numPts);
  hCross = XLALCreateREAL4Vector(numPts);

  LALReverseREAL4FFT( &status, hPlus, uFPlus, prevPlus );
  LALReverseREAL4FFT( &status, hCross, uFCross, prevCross );

  /* The LAL implementation of the FFT omits the factor 1/n */
  for (i = 0; i < numPts; i++) {
    hPlus->data[i] /= numPts;
    hCross->data[i] /= numPts;
  }

  /* Create TimeSeries to store more info about the waveforms */
  /* Note: it could be done easier using LALFreqTimeFFT instead of ReverseFFT */
  epoch.gpsSeconds = 0;
  epoch.gpsNanoSeconds = 0;

  hP =
    XLALCreateREAL4TimeSeries("", &epoch, 0, dt, &lalDimensionlessUnit, numPts);
  hP->data = hPlus;
  hC =
    XLALCreateREAL4TimeSeries("", &epoch, 0, dt, &lalDimensionlessUnit, numPts);
  hC->data = hCross;

  /* Cutting off the part of the waveform with f < fLow */
  /*  Freq = XLALComputeFreq( hP, hC);
      hP = XLALCutAtFreq( hP, Freq, lowFreq);
      hC = XLALCutAtFreq( hC, Freq, lowFreq); */

  /* multiply the last few samples of the time-series by a linearly
   * dropping window function in order to avid edges in the data
   * Added by Ajith 6 May 2008 */

  hPLength = hP->data->length;
  windowLength = (UINT4) (20.*totalMass * LAL_MTSUN_SI/dt);
  for (i=1; i<= windowLength; i++){
    linearWindow =  (i-1.)/windowLength;
    hP->data->data[hPLength-i] *= linearWindow;
    hC->data->data[hPLength-i] *= linearWindow;
  }

  /* Convert t column to units of (1/M) */
  /*  offset *= (1./(totalMass * LAL_MTSUN_SI));
      hP->deltaT *= (1./(totalMass * LAL_MTSUN_SI)); */

  /* Set t = 0 at the merger (defined as the max of the NR wave) */
  XLALFindNRCoalescenceTimeFromhoft( &offset, hP);
  XLALGPSAdd( &(hP->epoch), -offset);
  XLALGPSAdd( &(hC->epoch), -offset);

  /* Print waveforms to file */
  LALPrintHPlusCross( hP, hC, outFileLong );

  /* Free Memory */

  XLALDestroyREAL4FrequencySeries(Aeff);
  XLALDestroyREAL4FrequencySeries(Phieff);

  XLALDestroyREAL4FFTPlan(prevPlus);
  XLALDestroyREAL4FFTPlan(prevCross);

  XLALDestroyCOMPLEX8Vector(uFPlus);
  XLALDestroyCOMPLEX8Vector(uFCross);
  XLALDestroyREAL4TimeSeries(hP);
  XLALDestroyREAL4TimeSeries(hC);
  /*  XLALDestroyREAL4TimeSeries(hP); */
  /*  XLALDestroyREAL4TimeSeries(hC); */

  return(0);

}