Exemplo n.º 1
0
REAL8TimeSeries *
XLALNRInjectionStrain(const char *ifo, SimInspiralTable *inj)
{
  REAL8TimeSeries *hplus = NULL;
  REAL8TimeSeries *hcross = NULL;
  REAL8TimeSeries *strain = NULL;

  REAL8 deltaT = 1./16384.;
  InterferometerNumber ifoNumber = LAL_UNKNOWN_IFO;
  LALDetector det;

  /* look up detector */
  memset( &det, 0, sizeof(LALDetector) );
  ifoNumber = XLALIFONumber( ifo );
  XLALReturnDetector( &det, ifoNumber );

  /* generate plus and cross polarizations */
  XLALNRInjectionFromSimInspiral(&hplus, &hcross, inj, deltaT);

  /* Use Jolien's method to place on the sky */
  strain = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross,
           inj->longitude, inj->latitude, inj->polarization, &det);

  XLALDestroyREAL8TimeSeries (hplus);
  XLALDestroyREAL8TimeSeries (hcross);

  return strain;
}
Exemplo n.º 2
0
/**
 * Driver routine to compute the post-Newtonian inspiral waveform.
 *
 * This routine allows the user to specify different pN orders
 * for phasing calcuation vs. amplitude calculations.
 */
int XLALSimInspiralTaylorT4PNGenerator(
		REAL8TimeSeries **hplus,        /**< +-polarization waveform */
		REAL8TimeSeries **hcross,       /**< x-polarization waveform */
		REAL8 phiRef,                   /**< reference orbital phase (rad) */
		REAL8 v0,                       /**< tail-term gauge choice (default = 1) */
		REAL8 deltaT,                   /**< sampling interval (s) */
		REAL8 m1,                       /**< mass of companion 1 (kg) */
		REAL8 m2,                       /**< mass of companion 2 (kg) */
		REAL8 f_min,                    /**< start frequency (Hz) */
		REAL8 fRef,                     /**< reference frequency (Hz) */
		REAL8 r,                        /**< distance of source (m) */
		REAL8 i,                        /**< inclination of source (rad) */
		REAL8 lambda1,                  /**< (tidal deformability of body 1)/(mass of body 1)^5 */
		REAL8 lambda2,                  /**< (tidal deformability of body 2)/(mass of body 2)^5 */
		LALSimInspiralTidalOrder tideO, /**< flag to control spin and tidal effects */
		int amplitudeO,                 /**< twice post-Newtonian amplitude order */
		int phaseO                      /**< twice post-Newtonian phase order */
		)
{

	/* The Schwarzschild ISCO frequency - for sanity checking fRef */
	REAL8 fISCO = pow(LAL_C_SI,3) / (pow(6.,3./2.)*LAL_PI*(m1+m2)*LAL_G_SI);

	/* Sanity check fRef value */
	if( fRef < 0. )
	{
		XLALPrintError("XLAL Error - %s: fRef = %f must be >= 0\n",
				__func__, fRef);
		XLAL_ERROR(XLAL_EINVAL);
	}
	if( fRef != 0. && fRef < f_min )
	{
		XLALPrintError("XLAL Error - %s: fRef = %f must be > fStart = %f\n", 
				__func__, fRef, f_min);
		XLAL_ERROR(XLAL_EINVAL);
	}
	if( fRef >= fISCO )
	{
		XLALPrintError("XLAL Error - %s: fRef = %f must be < Schwar. ISCO=%f\n",
				__func__, fRef, fISCO);
		XLAL_ERROR(XLAL_EINVAL);
	}


	REAL8TimeSeries *v;
	REAL8TimeSeries *phi;
	int status;
	int n;
	n = XLALSimInspiralTaylorT4PNEvolveOrbit(&v, &phi, phiRef, deltaT,
			m1, m2, f_min, fRef, lambda1, lambda2, tideO, phaseO);
	if ( n < 0 )
		XLAL_ERROR(XLAL_EFUNC);
	status = XLALSimInspiralPNPolarizationWaveforms(hplus, hcross, v, phi,
			v0, m1, m2, r, i, amplitudeO);
	XLALDestroyREAL8TimeSeries(phi);
	XLALDestroyREAL8TimeSeries(v);
	if ( status < 0 )
		XLAL_ERROR(XLAL_EFUNC);
	return n;
}
Exemplo n.º 3
0
int main(void) {
  REAL8TimeSeries *conv, *data, *response, *exactConv;
  const UINT4 N = 101;
  const LIGOTimeGPS zero = {0, 0};
  UINT4 i;

  conv = XLALCreateREAL8TimeSeries("FFT Convolution", &zero, 0.0, 0.01, &lalDimensionlessUnit, N);
  data = XLALCreateREAL8TimeSeries("data", &zero, 0.0, 0.01, &lalDimensionlessUnit, N);
  response = XLALCreateREAL8TimeSeries("response function", &zero, 0.0, 0.01, &lalDimensionlessUnit, N);
  exactConv = XLALCreateREAL8TimeSeries("exact convolution", &zero, 0.0, 0.01, &lalDimensionlessUnit, N);

  data->data->data[0] = 1.0;
  for (i = 1; i < N; i++) {
    /* Data is 1/i */
    data->data->data[i] = 1.0 / i;
  }

  response->data->data[0] = 1.0;
  for (i = 1; i <= (N-1)/2; i++) {
    response->data->data[i] = exp(-(i/10.0)); /* Decaying exponential with time constant 10. */
    response->data->data[N-i] = exp(-(i/10.0)); /* Same in the negative, wrapped dimension. */
  }
  if (N % 2 == 0) {
    response->data->data[N/2] = exp(-(N/20.0));
  }

  /* Exact, O(N^2) convolution */
  for (i = 0; i < N; i++) {
    REAL8 sum = 0.0;
    UINT4 j;

    for (j = MAX_INT(0, ((int)i)-((int) N/2)); j <= MIN_INT(i+N/2, N-1); j++) {
      UINT4 rIndex = (j > i ? i + (N - j) : i - j);

      sum += data->data->data[j]*response->data->data[rIndex];
    }

    exactConv->data->data[i] = sum;
  }

  convolveTimeSeries(conv, data, response);

  for (i = 0; i < N; i++) {
    if (fabs(exactConv->data->data[i] - conv->data->data[i]) > 1e-8) {
      fprintf(stderr, "Index %d differs (exact = %g, FFT = %g)\n", 
              i, exactConv->data->data[i], conv->data->data[i]);
    }
  }

  XLALDestroyREAL8TimeSeries(conv);
  XLALDestroyREAL8TimeSeries(data);
  XLALDestroyREAL8TimeSeries(response);
  XLALDestroyREAL8TimeSeries(exactConv);

  return 0;
}
Exemplo n.º 4
0
/**
 * Driver routine to compute the -2 spin-weighted spherical harmonic mode
 * using TaylorT4 phasing.
 */
COMPLEX16TimeSeries *XLALSimInspiralTaylorT4PNMode(
		REAL8 phiRef,                   /**< reference orbital phase (rad) */
		REAL8 v0,                       /**< tail-term gauge choice (default = 1) */
		REAL8 deltaT,                   /**< sampling interval (s) */
		REAL8 m1,                       /**< mass of companion 1 (kg) */
		REAL8 m2,                       /**< mass of companion 2 (kg) */
		REAL8 f_min,                    /**< starting GW frequency (Hz) */
		REAL8 fRef,                     /**< reference GW frequency (Hz) */
		REAL8 r,                        /**< distance of source (m) */
		REAL8 lambda1,                  /**< (tidal deformability of body 1)/(mass of body 1)^5 */
		REAL8 lambda2,                  /**< (tidal deformability of body 2)/(mass of body 2)^5 */
		LALSimInspiralTidalOrder tideO, /**< flag to control spin and tidal effects */
		int amplitudeO,                 /**< twice post-Newtonian amplitude order */
		int phaseO,                     /**< twice post-Newtonian phase order */
		int l,                          /**< l index of mode */
		int m                           /**< m index of mode */
		)
{
	COMPLEX16TimeSeries *hlm;
	/* The Schwarzschild ISCO frequency - for sanity checking fRef */
	REAL8 fISCO = pow(LAL_C_SI,3) / (pow(6.,3./2.)*LAL_PI*(m1+m2)*LAL_G_SI);

	/* Sanity check fRef value */
	if( fRef < 0. )
	{
		XLALPrintError("XLAL Error - %s: fRef = %f must be >= 0\n", 
				__func__, fRef);
		XLAL_ERROR_NULL(XLAL_EINVAL);
	}
	if( fRef != 0. && fRef < f_min )
	{
		XLALPrintError("XLAL Error - %s: fRef = %f must be > fStart = %f\n", 
				__func__, fRef, f_min);
		XLAL_ERROR_NULL(XLAL_EINVAL);
	}
	if( fRef >= fISCO )
	{
		XLALPrintError("XLAL Error - %s: fRef = %f must be < Schwar. ISCO=%f\n",
				__func__, fRef, fISCO);
		XLAL_ERROR_NULL(XLAL_EINVAL);
	}

	REAL8TimeSeries *V;
	REAL8TimeSeries *phi;
	int n;
	n = XLALSimInspiralTaylorT4PNEvolveOrbit(&V, &phi, phiRef, deltaT,
			m1, m2, f_min, fRef, lambda1, lambda2, tideO, phaseO);
	if ( n < 0 )
		XLAL_ERROR_NULL(XLAL_EFUNC);
	hlm = XLALCreateSimInspiralPNModeCOMPLEX16TimeSeries(V, phi,
			v0, m1, m2, r, amplitudeO, l, m);
	XLALDestroyREAL8TimeSeries(phi);
	XLALDestroyREAL8TimeSeries(V);
	return hlm;
}
/**
 * Destroy a waveform cache.
 */
void XLALDestroySimInspiralWaveformCache(LALSimInspiralWaveformCache *cache)
{
    if (cache != NULL) {
        XLALDestroyREAL8TimeSeries(cache->hplus);
        XLALDestroyREAL8TimeSeries(cache->hcross);
        XLALDestroyCOMPLEX16FrequencySeries(cache->hptilde);
        XLALDestroyCOMPLEX16FrequencySeries(cache->hctilde);

        XLALFree(cache);
    }
}
Exemplo n.º 6
0
void XLALSimInjectNinjaSignals(
  REAL4TimeSeries* chan,
  const char *ifo,
  REAL8 dynRange,
  SimInspiralTable* events
)
{
  /* New REAL8, NINJA-2 code */
  UINT4 j;
  SimInspiralTable *thisInj = NULL;
  
  REAL8TimeSeries *tempStrain = NULL;
  REAL8TimeSeries *tempChan   = NULL;

  /* Make a REAL8 version of the channel data    */
  /* so we can call Jolien's new inject function */
  tempChan = XLALCreateREAL8TimeSeries(
             chan->name,
             &(chan->epoch),
             chan->f0,
             chan->deltaT,
             &(chan->sampleUnits),
             chan->data->length);
  for ( j = 0 ; j < tempChan->data->length ; ++j )
  {
    tempChan->data->data[j] = (REAL8) ( chan->data->data[j] );
  }

  /* loop over injections */
  for ( thisInj = events; thisInj; thisInj = thisInj->next )
  {
    tempStrain = XLALNRInjectionStrain(ifo, thisInj);
    for ( j = 0 ; j < tempStrain->data->length ; ++j )
    {
      tempStrain->data->data[j] *= dynRange;
    }

    XLALSimAddInjectionREAL8TimeSeries( tempChan, tempStrain, NULL);
    XLALDestroyREAL8TimeSeries(tempStrain);
  } /* loop over injections */

  /* Back to REAL4 */
  for ( j = 0 ; j < tempChan->data->length ; ++j )
  {
    chan->data->data[j] = (REAL4) ( tempChan->data->data[j] );
  }

  XLALDestroyREAL8TimeSeries(tempChan);
}
Exemplo n.º 7
0
int main(int argc, char *argv[])
{
    LALFrStream *stream;
    REAL8TimeSeries *series;
    LIGOTimeGPS start;

    XLALSetErrorHandler(XLALAbortErrorHandler);

    parseargs(argc, argv);

    /* get the data */
    stream = XLALFrStreamCacheOpen(cache);
    XLALGPSSetREAL8(&start, t0 - pad);
    series = XLALFrStreamInputREAL8TimeSeries(stream, channel, &start, dt + 2.0 * pad, 0);
    XLALFrStreamClose(stream);

    /* manipulate the data */
    if (srate > 0)
        XLALResampleREAL8TimeSeries(series, 1.0 / srate);
    if (minfreq > 0)
        XLALHighPassREAL8TimeSeries(series, minfreq, 0.9, 8);
    if (maxfreq > 0)
        XLALLowPassREAL8TimeSeries(series, maxfreq, 0.9, 8);
    if (pad > 0)
        series = XLALResizeREAL8TimeSeries(series, pad / series->deltaT, dt / series->deltaT);

    if (df > 0) { /* we are computing a spectrum */
        REAL8FrequencySeries *spectrum;
        REAL8FFTPlan *plan;
        REAL8Window *window;
        size_t seglen = 1.0 / (df * series->deltaT);

        /* make sure that the time series length is commensurate with seglen */
        if (((2 * series->data->length) % seglen) != 0) {
            size_t newlen = ((2 * series->data->length) / seglen) * seglen;
            series = XLALResizeREAL8TimeSeries(series, 0, newlen);
        }

        spectrum = XLALCreateREAL8FrequencySeries(series->name, &series->epoch, 0.0, df, &lalDimensionlessUnit, seglen/2 + 1);
        plan = XLALCreateForwardREAL8FFTPlan(seglen, 0);
        window = XLALCreateHannREAL8Window(seglen);
        XLALREAL8AverageSpectrumWelch(spectrum, series, seglen, seglen/2, window, plan);
        if (minfreq > 0 || maxfreq > 0) {
            size_t first = minfreq / spectrum->deltaF;
            size_t last = maxfreq > 0 ? maxfreq / spectrum->deltaF : spectrum->data->length;
            spectrum = XLALResizeREAL8FrequencySeries(spectrum, first, last - first);
        }
        output_fs(outfile, spectrum);
        XLALDestroyREAL8Window(window);
        XLALDestroyREAL8FFTPlan(plan);
        XLALDestroyREAL8FrequencySeries(spectrum);
    } else { /* we are outputting a time series */
        output_ts(outfile, series);
    }

    XLALDestroyREAL8TimeSeries(series);
    return 0;
}
Exemplo n.º 8
0
/**
 * Window and IFFT a FD waveform to TD, then window in TD.
 * Requires that the FD waveform be generated outside of f_min and f_max.
 * FD waveform is modified.
 */
static int FDToTD(REAL8TimeSeries **signalTD, const COMPLEX16FrequencySeries *signalFD, const REAL8 totalMass, const REAL8 deltaT, const REAL8 f_min, const REAL8 f_max, const REAL8 f_min_wide, const REAL8 f_max_wide) {
	const LIGOTimeGPS gpstime_zero = {0, 0};
	const size_t nf = signalFD->data->length;
	const size_t nt = 2 * (nf - 1);

        /* Calculate the expected lengths of the FD and TD vectors from the
         * deltaF and deltaT passed in to this function */
        //const size_t exp_nt = (size_t) 1. / (signalFD->deltaF * deltaT);
        //const size_t exp_nf = (exp_nt / 2) + 1;

	const REAL8 windowLength = 20. * totalMass * LAL_MTSUN_SI / deltaT;
	const REAL8 winFLo = 0.2*f_min_wide + 0.8*f_min;
	/* frequency used for tapering, slightly less than f_min to minimize FFT artifacts
	 * equivalent to winFLo = f_min_wide + 0.8*(f_min - f_min_wide) */
	REAL8 winFHi = f_max_wide;
	COMPLEX16 *FDdata = signalFD->data->data;
	REAL8FFTPlan *revPlan;
	REAL8 *TDdata;
	size_t k;

	/* check inputs */
	if (f_min_wide >= f_min) XLAL_ERROR(XLAL_EDOM);

	/* apply the softening window function */
	if (winFHi > 0.5 / deltaT) winFHi = 0.5 / deltaT;
	for (k = nf;k--;) {
		const REAL8 f = k / (deltaT * nt);
		REAL8 softWin = PlanckTaper(f, f_min_wide, winFLo) * (1.0 - PlanckTaper(f, f_max, winFHi));
		FDdata[k] *= softWin;
	}


	/* allocate output */
	*signalTD = XLALCreateREAL8TimeSeries("h", &gpstime_zero, 0.0, deltaT, &lalStrainUnit, nt);


	/* Inverse Fourier transform */
	revPlan = XLALCreateReverseREAL8FFTPlan(nt, 1);
	if (!revPlan) {
		XLALDestroyREAL8TimeSeries(*signalTD);
		*signalTD = NULL;
		XLAL_ERROR(XLAL_EFUNC);
	}
	XLALREAL8FreqTimeFFT(*signalTD, signalFD, revPlan);
	XLALDestroyREAL8FFTPlan(revPlan);
	if (!(*signalTD)) XLAL_ERROR(XLAL_EFUNC);


	/* apply a linearly decreasing window at the end
	 * of the waveform in order to avoid edge effects. */
	if (windowLength > (*signalTD)->data->length) XLAL_ERROR(XLAL_ERANGE);
	TDdata = (*signalTD)->data->data;
	for (k = windowLength; k--;)
		TDdata[nt-k-1] *= k / windowLength;

	return XLAL_SUCCESS;
}
Exemplo n.º 9
0
int main(int argc, char *argv[])
{
	char tstr[32]; // string to hold GPS time -- 31 characters is enough
	const double H0 = 0.72 * LAL_H0FAC_SI; // Hubble's constant in seconds
	const size_t length = 65536; // number of points in a segment
	const size_t stride = length / 2; // number of points in a stride
	size_t i, n;
	REAL8FrequencySeries *OmegaGW = NULL;
	REAL8TimeSeries **seg = NULL;
	LIGOTimeGPS epoch;
	gsl_rng *rng;

	XLALSetErrorHandler(XLALAbortErrorHandler);

	parseargs(argc, argv);

	XLALGPSSetREAL8(&epoch, tstart);
	gsl_rng_env_setup();
	rng = gsl_rng_alloc(gsl_rng_default);
	OmegaGW = XLALSimSGWBOmegaGWFlatSpectrum(Omega0, flow, srate/length, length/2 + 1);

	n = duration * srate;
	seg = LALCalloc(numDetectors, sizeof(*seg));
	printf("# time (s)");
	for (i = 0; i < numDetectors; ++i) {
		char name[LALNameLength];
		snprintf(name, sizeof(name), "%s:STRAIN", detectors[i].frDetector.prefix);
		seg[i] = XLALCreateREAL8TimeSeries(name, &epoch, 0.0, 1.0/srate, &lalStrainUnit, length);
		printf("\t%s (strain)", name);
	}
	printf("\n");

	XLALSimSGWB(seg, detectors, numDetectors, 0, OmegaGW, H0, rng); // first time to initilize

	while (1) { // infinite loop
		size_t j;
		for (j = 0; j < stride; ++j, --n) { // output first stride points
			LIGOTimeGPS t = seg[0]->epoch;
			if (n == 0) // check if we're done
				goto end;
			printf("%s", XLALGPSToStr(tstr, XLALGPSAdd(&t, j * seg[0]->deltaT)));
			for (i = 0; i < numDetectors; ++i)
				printf("\t%e", seg[i]->data->data[j]);
			printf("\n");
		}
		XLALSimSGWB(seg, detectors, numDetectors, stride, OmegaGW, H0, rng); // make more data
	}

end:
	for (i = 0; i < numDetectors; ++i)
		XLALDestroyREAL8TimeSeries(seg[i]);
	XLALFree(seg);
	XLALDestroyREAL8FrequencySeries(OmegaGW);
	LALCheckMemoryLeaks();

	return 0;
}
Exemplo n.º 10
0
int
XLALNRInjectionFromSimInspiral(
    REAL8TimeSeries **hplus,	/**< +-polarization waveform */
    REAL8TimeSeries **hcross,	/**< x-polarization waveform */
    SimInspiralTable *thisRow,	/**< row from the sim_inspiral table containing waveform parameters */
    REAL8 deltaT		/**< time step */
    )
{
  REAL8TimeSeries *plus      = NULL;
  REAL8TimeSeries *cross     = NULL;
  INT4 sampleRate            = (INT4) 1./deltaT;

  /* Add the modes together */
  XLALAddNumRelStrainModesREAL8(&plus, &cross, thisRow);
  /* Place at distance */
  for (uint j = 0; j < plus->data->length; j++)
  {
    plus->data->data[j]  /= thisRow->distance;
    cross->data->data[j] /= thisRow->distance;
  }

  plus->sampleUnits  = lalADCCountUnit;
  cross->sampleUnits = lalADCCountUnit;

  /* Interpolate to desired sample rate */
  *hplus  = XLALInterpolateNRWaveREAL8(plus, sampleRate);
  *hcross = XLALInterpolateNRWaveREAL8(cross, sampleRate);
  if (*hplus == NULL || *hcross == NULL)
    XLAL_ERROR(XLAL_EFUNC);

  /* We want the end time to be the time of largest amplitude */
  REAL8 offset = 0;
  XLALFindNRCoalescencePlusCrossREAL8(&offset, *hplus, *hcross);
  XLALGPSAdd( &((*hplus)->epoch), -offset);
  XLALGPSAdd( &((*hcross)->epoch), -offset);

  XLALDestroyREAL8TimeSeries (plus);
  XLALDestroyREAL8TimeSeries (cross);

  return XLAL_SUCCESS;
}
Exemplo n.º 11
0
int main(void)
{
	LIGOTimeGPS tc = { 888888888, 222222222 };
	REAL8 phic = 1.0;
	REAL8 deltaT = 1.0/16384.0;
	REAL8 m1 = 1.4*LAL_MSUN_SI;
	REAL8 m2 = 1.4*LAL_MSUN_SI;
	REAL8 r = 1e6*LAL_PC_SI;
	REAL8 i = 0.5*LAL_PI;
	REAL8 f_min = 100.0;
	REAL8 fRef = 0.;
	int O = -1;
	REAL8TimeSeries *hplus;
	REAL8TimeSeries *hcross;
	XLALSimInspiralTaylorT4PN(&hplus, &hcross, &tc, phic, deltaT, m1, m2, f_min, fRef, r, i, lambda1, lambda2, tideO, O);
	LALDPrintTimeSeries(hplus, "hp.dat");
	LALDPrintTimeSeries(hcross, "hc.dat");
	XLALDestroyREAL8TimeSeries(hplus);
	XLALDestroyREAL8TimeSeries(hcross);
	LALCheckMemoryLeaks();
	return 0;
}
Exemplo n.º 12
0
int main(int argc, char *argv[])
{
  	LIGOTimeGPS epoch = {0, 0};
	REAL8TimeSeries *hplus;
	REAL8TimeSeries *hcross;
	size_t j;

	XLALSetErrorHandler(XLALBacktraceErrorHandler);

	parseargs(argc, argv);

	XLALSimBlackHoleRingdown(&hplus, &hcross, &epoch, q, dt, M, a, e, r, i, l, m);

	fprintf(stdout, "# time (s)\th_plus      \th_cross\n");
	for (j = 0; j < hplus->data->length; ++j)
		fprintf(stdout, "%.9f\t%e\t%e\n", j*dt, hplus->data->data[j], hcross->data->data[j]);

	XLALDestroyREAL8TimeSeries(hcross);
	XLALDestroyREAL8TimeSeries(hplus);
	LALCheckMemoryLeaks();

	return 0;
}
Exemplo n.º 13
0
int main(int argc, char *argv[])
{
	const double H0 = 0.72 * LAL_H0FAC_SI; // Hubble's constant in seconds
	const double srate = 16384.0; // sampling rate in Hertz
	const size_t length = 65536; // number of points in a segment
	const size_t stride = length / 2; // number of points in a stride
	size_t i, n;
	REAL8FrequencySeries *OmegaGW = NULL;
	REAL8TimeSeries **seg = NULL;
	LIGOTimeGPS epoch;
	gsl_rng *rng;

	XLALSetErrorHandler(XLALAbortErrorHandler);

	parseargs(argc, argv);

	XLALGPSSetREAL8(&epoch, tstart);
	gsl_rng_env_setup();
	rng = gsl_rng_alloc(gsl_rng_default);
	OmegaGW = XLALSimSGWBOmegaGWFlatSpectrum(Omega0, flow, srate/length, length/2 + 1);

	n = duration * srate;
	seg = LALCalloc(numDetectors, sizeof(*seg));
	for (i = 0; i < numDetectors; ++i)
		seg[i] = XLALCreateREAL8TimeSeries("STRAIN", &epoch, 0.0, 1.0/srate, &lalStrainUnit, length);

	XLALSimSGWB(seg, detectors, numDetectors, 0, OmegaGW, H0, rng); // first time to initilize
	while (1) { // infinite loop
		double t0 = XLALGPSGetREAL8(&seg[0]->epoch);
		size_t j;
		for (j = 0; j < stride; ++j, --n) { // output first stride points
			if (n == 0) // check if we're done
				goto end;
			printf("%.9f", t0 + j * seg[0]->deltaT);
			for (i = 0; i < numDetectors; ++i)
				printf("\t%e", seg[i]->data->data[j]);
			printf("\n");
		}
		XLALSimSGWB(seg, detectors, numDetectors, stride, OmegaGW, H0, rng); // make more data
	}

end:
	for (i = 0; i < numDetectors; ++i)
		XLALDestroyREAL8TimeSeries(seg[i]);
	XLALFree(seg);
	XLALDestroyREAL8FrequencySeries(OmegaGW);
	LALCheckMemoryLeaks();

	return 0;
}
Exemplo n.º 14
0
int
XLALAddNumRelStrainModesREAL8(
    REAL8TimeSeries   **seriesPlus, /**< [out]  h+, hx data    */
    REAL8TimeSeries   **seriesCross, /**< [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;
  REAL8TimeSeries  *modePlus=NULL;
  REAL8TimeSeries  *modeCross=NULL;
  REAL8 massMpc, timeStep;

  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);

  /* Time step in dimensionful units */
  timeStep = (thisinj->mass1 + thisinj->mass2) * LAL_MTSUN_SI;

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

  /* 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 */
      if (XLALCheckFrameHasChannel(channel_name_plus, frStream ) )
      {
        lenPlus = XLALFrStreamGetVectorLength ( channel_name_plus, frStream );
      }
      else
      {
        lenPlus = -1;
      }

      /* now the cross polarization */
      channel_name_cross = XLALGetNinjaChannelName("cross", modeL, modeM);
      /*get number of data points */
      if (XLALCheckFrameHasChannel(channel_name_cross, frStream ) )
      {
        lenCross = XLALFrStreamGetVectorLength ( channel_name_cross, frStream );
      }
      else
      {
        lenCross = -1;
      }

      /* 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;

      /* allocate and read the plus/cross time series */
      modePlus = XLALCreateREAL8TimeSeries ( channel_name_plus, &epoch, 0, 0, &lalDimensionlessUnit, len);
      memset(modePlus->data->data, 0, modePlus->data->length*sizeof(REAL8));
      XLALFrStreamGetREAL8TimeSeries ( modePlus, frStream );
      XLALFrStreamRewind( frStream );
      LALFree(channel_name_plus);

      modeCross = XLALCreateREAL8TimeSeries ( channel_name_cross, &epoch, 0, 0, &lalDimensionlessUnit, len);
      memset(modeCross->data->data, 0, modeCross->data->length*sizeof(REAL8));
      XLALFrStreamGetREAL8TimeSeries ( modeCross, frStream );
      XLALFrStreamRewind( frStream );
      LALFree(channel_name_cross);

      /* scale and add */
      if (*seriesPlus == NULL) {
          *seriesPlus = XLALCreateREAL8TimeSeries ( "hplus", &epoch, 0, 0, &lalDimensionlessUnit, len);
          memset((*seriesPlus)->data->data, 0, (*seriesPlus)->data->length*sizeof(REAL8));
          (*seriesPlus)->deltaT = modePlus->deltaT;
      }

      if (*seriesCross == NULL) {
          *seriesCross = XLALCreateREAL8TimeSeries ( "hcross", &epoch, 0, 0, &lalDimensionlessUnit, len);
          memset((*seriesCross)->data->data, 0, (*seriesCross)->data->length*sizeof(REAL8));
          (*seriesCross)->deltaT = modeCross->deltaT;
      }

      XLALOrientNRWaveTimeSeriesREAL8( modePlus, modeCross, modeL, modeM, thisinj->inclination, thisinj->coa_phase );

      for (k = 0; k < len; k++) {
        (*seriesPlus)->data->data[k]  += massMpc * modePlus->data->data[k];
        (*seriesCross)->data->data[k] += massMpc * modeCross->data->data[k];
      }

      /* we are done with seriesPlus and Cross for this iteration */
      XLALDestroyREAL8TimeSeries (modePlus);
      XLALDestroyREAL8TimeSeries (modeCross);
    } /* end loop over modeM values */
  } /* end loop over modeL values */
  (*seriesPlus)->deltaT  *= timeStep;
  (*seriesCross)->deltaT *= timeStep;
  XLALFrStreamClose( frStream );
  LALFree(frCache.list);

  return XLAL_SUCCESS;
}
Exemplo n.º 15
0
/* Everything needs to be declared as unused in case HDF is not enabled. */
int XLALSimInspiralNRWaveformGetHplusHcross(
        UNUSED REAL8TimeSeries **hplus,        /**< Output h_+ vector */
        UNUSED REAL8TimeSeries **hcross,       /**< Output h_x vector */
        UNUSED REAL8 phiRef,                   /**< orbital phase at reference pt. */
        UNUSED REAL8 inclination,              /**< inclination angle */
        UNUSED REAL8 deltaT,                   /**< sampling interval (s) */
        UNUSED REAL8 m1,                       /**< mass of companion 1 (kg) */
        UNUSED REAL8 m2,                       /**< mass of companion 2 (kg) */
        UNUSED REAL8 r,                        /**< distance of source (m) */
        UNUSED REAL8 fStart,                   /**< start GW frequency (Hz) */
        UNUSED REAL8 fRef,                     /**< reference GW frequency (Hz) */
        UNUSED REAL8 s1x,                      /**< initial value of S1x */
        UNUSED REAL8 s1y,                      /**< initial value of S1y */
        UNUSED REAL8 s1z,                      /**< initial value of S1z */
        UNUSED REAL8 s2x,                      /**< initial value of S2x */
        UNUSED REAL8 s2y,                      /**< initial value of S2y */
        UNUSED REAL8 s2z,                      /**< initial value of S2z */
        UNUSED const char *NRDataFile          /**< Location of NR HDF file */
        )
{
  #ifndef LAL_HDF5_ENABLED
  XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled");
  #else
  /* Declarations */
  UINT4 curr_idx;
  INT4 model, modem;
  size_t array_length;
  REAL8 nrEta;
  REAL8 S1x, S1y, S1z, S2x, S2y, S2z;
  REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s;
  REAL8 chi, est_start_time, curr_h_real, curr_h_imag;
  REAL8 theta, psi, calpha, salpha;
  REAL8 distance_scale_fac;
  COMPLEX16 curr_ylm;
  REAL8TimeSeries *hplus_corr;
  REAL8TimeSeries *hcross_corr;

  /* These keys follow a strict formulation and cannot be longer than 11
   * characters */
  char amp_key[20];
  char phase_key[20];
  gsl_vector *tmpVector=NULL;
  LALH5File *file, *group;
  LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO;
  REAL8Vector *curr_amp, *curr_phase;

  /* Use solar masses for units. NR files will use
   * solar masses as well, so easier for that conversion
   */
  m1 = m1 / LAL_MSUN_SI;
  m2 = m2 / LAL_MSUN_SI;

  file = XLALH5FileOpen(NRDataFile, "r");

  /* Sanity checks on physical parameters passed to waveform
   * generator to guarantee consistency with NR data file.
   */
  XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta");
  if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "MASSES ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION.\n");
  }

  /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure
   * the ChooseTDWaveform() input values are consistent with the data
   * recorded in the metadata of the HDF5 file.
   * PS: This assumes that the input spins are in the LAL frame!
   */
  XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z,
                                                       &S2x, &S2y, &S2z, file);

  if (fabs(S1x - s1x) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S1y - s1y) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S1z - s1z) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S2x - s2x) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S2y - s2y) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S2z - s2z) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }


  /* First estimate the length of time series that is needed.
   * Demand that 22 mode that is present and use that to figure this out
   */

  XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN");
  /* Figure out start time of data */
  group = XLALH5GroupOpen(file, "amp_l2_m2");
  ReadHDF5RealVectorDataset(group, "knots", &tmpVector);
  time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0));
  time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1));
  gsl_vector_free(tmpVector);
  time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI;
  time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI;

  /* We don't want to return the *entire* waveform if it will be much longer
   * than the specified f_lower. Therefore guess waveform length using
   * the SEOBNR_ROM function and add 10% for safety.
   * FIXME: Is this correct for precessing waveforms?
   */

  chi = XLALSimIMRPhenomBComputeChi(m1, m2, s1z, s2z);
  est_start_time = XLALSimIMRSEOBNRv2ChirpTimeSingleSpin(m1 * LAL_MSUN_SI,
                                                m2 * LAL_MSUN_SI, chi, fStart);
  est_start_time = (-est_start_time) * 1.1;
  if (est_start_time > time_start_s)
  {
    /* Restrict start time of waveform */
    time_start_s = est_start_time;
    time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI);
  }
  else if (fStart < Mflower / (m1 + m2) )
  {
     XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e",
                fStart, Mflower, Mflower / (m1 + m2));
  }

  array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT));

  /* Compute correct angles for hplus and hcross following LAL convention. */

  theta = psi = calpha = salpha = 0.;
  XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha,
                       &salpha, file, inclination, phiRef);

  /* Create the return time series, use arbitrary epoch here. We set this
   * properly later. */
  XLALGPSAdd(&tmpEpoch, time_start_s);

  *hplus  = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );
  *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );

  hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );
  hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );
  for (curr_idx = 0; curr_idx < array_length; curr_idx++)
  {
    hplus_corr->data->data[curr_idx] = 0.0;
    hcross_corr->data->data[curr_idx] = 0.0;
  }

  /* Create the distance scale factor */
  distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r;

  /* Generate the waveform */
  for (model=2; model < 9 ; model++)
  {
    for (modem=-model; modem < (model+1); modem++)
    {
      snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem);
      snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem);

      /* Check that both groups exist */
      if (XLALH5CheckGroupExists(file, amp_key) == 0)
      {
        continue;
      }
      if (XLALH5CheckGroupExists(file, phase_key) == 0)
      {
        continue;
      }

      /* Get amplitude and phase from file */
      XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2),
                                  time_start_s, array_length, deltaT, amp_key);
      XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2),
                                time_start_s, array_length, deltaT, phase_key);

      curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2,
                                                   model, modem);

      for (curr_idx = 0; curr_idx < array_length; curr_idx++)
      {
        curr_h_real = curr_amp->data[curr_idx]
                    * cos(curr_phase->data[curr_idx]) * distance_scale_fac;
        curr_h_imag = curr_amp->data[curr_idx]
                    * sin(curr_phase->data[curr_idx]) * distance_scale_fac;

        hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx]
               + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm);

        hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx]
               - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm);

      }

      XLALDestroyREAL8Vector(curr_amp);
      XLALDestroyREAL8Vector(curr_phase);

    }

  }

 /* Correct for the "alpha" angle as given in T1600045 to translate
  * from the NR wave frame to LAL wave-frame
  * Helper time series needed.
  */

  for (curr_idx = 0; curr_idx < array_length; curr_idx++)
  {
    (*hplus)->data->data[curr_idx] =
          (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx]
          - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx];

    (*hcross)->data->data[curr_idx] =
          + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx]
        + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx];
  }

  XLALDestroyREAL8TimeSeries(hplus_corr);
  XLALDestroyREAL8TimeSeries(hcross_corr);
  XLALH5FileClose(file);

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

  InputParams XLAL_INIT_DECL(inputs);

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

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

  LALStatus XLAL_INIT_DECL(status);

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

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

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

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

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

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

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

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

      pulparams[h] = XLALReadTEMPOParFile( parname );

      fclose( inject );
    }
  }
  LIGOTimeGPS epoch;

  UINT4 ndata;

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

  ndata = inputs.frDur;

  REAL8TimeSeries *series=NULL;

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

  LALFrameH *outFrame = NULL;

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

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

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

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

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

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

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

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

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

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

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

      /*Add binary later if needed!*/

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

      REAL4TimeSeries *TSeries = NULL;

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

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

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

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

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

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

  XLALFrameFree(outFrame);
  XLALDestroyREAL8TimeSeries( series );

  return 0;
}
Exemplo n.º 17
0
/**
 * Generate the + and x time series for a single sim_burst table row.
 * Note:  only the row pointed to by sim_burst is processed, the linked
 * list is not iterated over.  The hplus and hcross time series objects
 * will be allocated by this function.  The time-at-geocentre is applied,
 * but the time shift offset must be applied separately.  delta_t is the
 * sample interval for the time series.  The return value is 0 in success,
 * non-0 on failure.
 */
int XLALGenerateSimBurst(
	REAL8TimeSeries **hplus,
	REAL8TimeSeries **hcross,
	const SimBurst *sim_burst,
	double delta_t
)
{
	if(!strcmp(sim_burst->waveform, "BTLWNB")) {
		/* E_{GW}/r^{2} is in M_{sun} / pc^{2}, so we multiply by
		 * (M_{sun} c^2) to convert to energy/pc^{2}, and divide by
		 * (distance/pc)^{2} to convert to energy/distance^{2},
		 * which is then multiplied by (4 G / c^3) to convert to a
		 * value of \int \dot{h}^{2} \diff t.  From the values of
		 * the LAL constants, the total factor multiplying
		 * egw_over_rsquared is 1.8597e-21. */

		double int_hdot_squared_dt = sim_burst->egw_over_rsquared * LAL_GMSUN_SI * 4 / LAL_C_SI / LAL_PC_SI / LAL_PC_SI;

		/* the waveform number is interpreted as the seed for GSL's
		 * Mersenne twister random number generator */
		gsl_rng *rng = gsl_rng_alloc(gsl_rng_mt19937);
		if(!rng) {
			XLALPrintError("%s(): failure creating random number generator\n", __func__);
			XLAL_ERROR(XLAL_ENOMEM);
		}
		gsl_rng_set(rng, sim_burst->waveform_number);

		XLALPrintInfo("%s(): BTLWNB @ %9d.%09u s (GPS): f = %.16g Hz, df = %.16g Hz, dt = %.16g s, hdot^2 = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->frequency, sim_burst->bandwidth, sim_burst->duration, int_hdot_squared_dt);
		if(XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(hplus, hcross, sim_burst->duration, sim_burst->frequency, sim_burst->bandwidth, sim_burst->pol_ellipse_e, int_hdot_squared_dt, delta_t, rng)) {
			gsl_rng_free(rng);
			XLAL_ERROR(XLAL_EFUNC);
		}
		gsl_rng_free(rng);
	} else if(!strcmp(sim_burst->waveform, "StringCusp")) {
		XLALPrintInfo("%s(): string cusp @ %9d.%09u s (GPS): A = %.16g, fhigh = %.16g Hz\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->amplitude, sim_burst->frequency);
		if(XLALGenerateStringCusp(hplus, hcross, sim_burst->amplitude, sim_burst->frequency, delta_t))
			XLAL_ERROR(XLAL_EFUNC);
	} else if(!strcmp(sim_burst->waveform, "SineGaussian")) {
		XLALPrintInfo("%s(): sine-Gaussian @ %9d.%09u s (GPS): f = %.16g Hz, Q = %.16g, hrss = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->frequency, sim_burst->q, sim_burst->hrss);
		if(XLALSimBurstSineGaussian(hplus, hcross, sim_burst->q, sim_burst->frequency, sim_burst->hrss, sim_burst->pol_ellipse_e, sim_burst->pol_ellipse_angle, delta_t))
			XLAL_ERROR(XLAL_EFUNC);
	} else if(!strcmp(sim_burst->waveform, "Gaussian")) {
		XLALPrintInfo("%s(): Gaussian @ %9d.%09u s (GPS): duration = %.16g, hrss = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->duration, sim_burst->hrss);
		if(XLALSimBurstGaussian(hplus, hcross, sim_burst->duration, sim_burst->hrss, delta_t))
			XLAL_ERROR(XLAL_EFUNC);
	} else if(!strcmp(sim_burst->waveform, "Impulse")) {
		XLALPrintInfo("%s(): impulse @ %9d.%09u s (GPS): hpeak = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->amplitude);
		if(XLALGenerateImpulseBurst(hplus, hcross, sim_burst->amplitude, delta_t))
			XLAL_ERROR(XLAL_EFUNC);
	} else {
		/* unrecognized waveform */
		XLALPrintError("%s(): error: unrecognized waveform\n", __func__);
		XLAL_ERROR(XLAL_EINVAL);
	}

	/* add the time of the injection at the geocentre to the start
	 * times of the h+ and hx time series.  after this, their epochs
	 * mark the start of those time series at the geocentre. */

	if(!XLALGPSAddGPS(&(*hcross)->epoch, &sim_burst->time_geocent_gps) ||
	   !XLALGPSAddGPS(&(*hplus)->epoch, &sim_burst->time_geocent_gps)) {
		XLALPrintError("%s(): bad geocentre time or waveform too long\n", __func__);
		XLALDestroyREAL8TimeSeries(*hcross);
		XLALDestroyREAL8TimeSeries(*hplus);
		*hplus = *hcross = NULL;
		XLAL_ERROR(XLAL_EFUNC);
	}

	/* done */

	return 0;
}
Exemplo n.º 18
0
void LALInferenceTemplateXLALSimInspiralChooseWaveform(LALInferenceModel *model)
/*************************************************************************************************************************/
/* Wrapper for LALSimulation waveforms:						                                                             */
/* XLALSimInspiralChooseFDWaveform() and XLALSimInspiralChooseTDWaveform().                                              */
/*                                                                                                                       */
/*  model->params parameters are:										                                                 */
/*  - "name" description; type OPTIONAL (default value)										                             */
/*										                                                                                 */
/*   MODEL PARAMETERS										                                                             */
/*   - "LAL_APPROXIMANT     Approximant;        Approximant                                                              */
/*   - "LAL_PNORDER"        Phase PN order;     INT4                                                                     */
/*   - "LAL_AMPORDER"       Amplitude PN order; INT4 OPTIONAL (-1)                                                       */
/*   - "spinO"              Spin order;         LALSimInspiralSpinOrder OPTIONAL (LAL_SIM_INSPIRAL_SPIN_ORDER_DEFAULT)   */
/*   - "tideO"              Tidal order;        LALSimInspiralTidalOrder OPTIONAL (LAL_SIM_INSPIRAL_TIDAL_ORDER_DEFAULT) */
/*   - "f_ref"               frequency at which the (frequency dependent) parameters are defined; REAL8 OPTIONAL (0.0)    */
/*   - "fLow"               lower frequency bound; REAL8 OPTIONAL (model->fLow)                                          */
/*                                                                                                                       */
/*   MASS PARAMETERS; either:                                                                                            */
/*      - "mass1"           mass of object 1 in solar mass; REAL8								                         */
/*      - "mass2"		        mass of object 1 in solar mass; REAL8								                     */
/*      OR                                                                                                               */
/*      - "chirpmass"       chirpmass in solar mass; REAL8                                                               */
/*      - "q"  asymmetric mass ratio m2/m1, 0<q<1; REAL8                                      */
/*      OR                                                                                                               */
/*      - "chirpmass"       chirpmass in solar mass; REAL8                                                               */
/*      - "eta"             symmetric mass ratio (m1*m2)/(m1+m2)^2; REAL8                                                */
/*                                                                                                                       */
/*   ORIENTATION AND SPIN PARAMETERS                                                                                     */
/*   - "phi0"               reference phase as per LALSimulation convention; REAL8                                       */
/*   - "distance"           distance in Mpc                                                                              */
/*   - "costheta_jn");      cos of zenith angle between J and N in radians;            REAL8                                    */
/*   - "phi_jl");        azimuthal angle of L_N on its cone about J radians; REAL8                                    */
/*   - "tilt_spin1");    zenith angle between S1 and LNhat in radians;       REAL8                                    */
/*   - "tilt_spin2");    zenith angle between S2 and LNhat in radians;       REAL8                                    */
/*   - "phi12");         difference in azimuthal angle between S1, S2 in radians;   REAL8                             */
/*   - "a_spin1"            magnitude of spin 1 in general configuration, -1<a_spin1<1; REAL8 OPTIONAL (0.0)              */
/*   - "a_spin2"            magnitude of spin 2 in general configuration, -1<a_spin1<1; REAL8 OPTIONAL (0.0)              */
/*                                                                                                                       */
/*   OTHER PARAMETERS                                                                                                    */
/*   - "lambda1"            tidal parameter of object 1; REAL8  OPTIONAL (0.0)                                           */
/*   - "lambda2"            tidal parameter of object 1; REAL8  OPTIONAL (0.0)                                           */
/*                                                                                                                       */
/*   - "time"               used as an OUTPUT only; REAL8								                                 */
/*                                                                                                                       */
/*                                                                                                                       */
/*   model needs to also contain:                                                                                        */
/*   - model->fLow Unless  - "fLow" OPTIONAL                                                                             */
/*   - model->deltaT                                                                                                     */
/*   - if model->domain == LAL_SIM_DOMAIN_FREQUENCY                                                                      */
/*      - model->deltaF                                                                                                  */
/*      - model->freqhCross                                                                                              */
/*      - model->freqhPlus                                                                                               */
/*   - else                                                                                                              */
/*      - model->timehPlus                                                                                               */
/*      - model->timehCross                                                                                              */
/*************************************************************************************************************************/
{

  Approximant approximant = (Approximant) 0;
  INT4 order=-1;
  INT4 amporder;

  static int sizeWarning = 0;
  int ret=0;
  INT4 errnum=0;
  
  REAL8TimeSeries *hplus=NULL;  /**< +-polarization waveform [returned] */
  REAL8TimeSeries *hcross=NULL; /**< x-polarization waveform [returned] */
  COMPLEX16FrequencySeries *hptilde=NULL, *hctilde=NULL;
  REAL8 mc;
  REAL8 phi0, deltaT, m1, m2, f_low, f_start, distance, inclination;
  
  REAL8 *m1_p,*m2_p;
  REAL8 deltaF, f_max;
  
  /* Sampling rate for time domain models */
  deltaT = model->deltaT;
  
  if (LALInferenceCheckVariable(model->params, "LAL_APPROXIMANT"))
    approximant = *(Approximant*) LALInferenceGetVariable(model->params, "LAL_APPROXIMANT");
  else {
    XLALPrintError(" ERROR in templateLALGenerateInspiral(): (INT4) \"LAL_APPROXIMANT\" parameter not provided!\n");
    XLAL_ERROR_VOID(XLAL_EDATA);
  }
	
  if (LALInferenceCheckVariable(model->params, "LAL_PNORDER"))
    order = *(INT4*) LALInferenceGetVariable(model->params, "LAL_PNORDER");
  else {
    XLALPrintError(" ERROR in templateLALGenerateInspiral(): (INT4) \"LAL_PNORDER\" parameter not provided!\n");
    XLAL_ERROR_VOID(XLAL_EDATA);
  }

  /* Explicitly set the default amplitude order if one is not specified.
   *   This serves two purposes:
   *     1) The default behavior of the code won't change unexpectedly due to changes in LALSimulation.
   *     2) We need to know the amplitude order in order to set the starting frequency of the waveform properly. */
  if (LALInferenceCheckVariable(model->params, "LAL_AMPORDER"))
    amporder = *(INT4*) LALInferenceGetVariable(model->params, "LAL_AMPORDER");
  else
    amporder = -1;
    
  REAL8 f_ref = 100.0;
  if (LALInferenceCheckVariable(model->params, "f_ref")) f_ref = *(REAL8 *)LALInferenceGetVariable(model->params, "f_ref");

  REAL8 fTemp = f_ref;

  if(LALInferenceCheckVariable(model->params,"chirpmass"))
    {
      mc  = *(REAL8*) LALInferenceGetVariable(model->params, "chirpmass");
      if (LALInferenceCheckVariable(model->params,"q")) {
	REAL8 q = *(REAL8 *)LALInferenceGetVariable(model->params,"q");
	q2masses(mc, q, &m1, &m2);
      } else {
	REAL8 eta = *(REAL8*) LALInferenceGetVariable(model->params, "eta");
	mc2masses(mc, eta, &m1, &m2);
      }
    }
  else if((m1_p=(REAL8 *)LALInferenceGetVariable(model->params, "mass1")) && (m2_p=(REAL8 *)LALInferenceGetVariable(model->params, "mass2")))
    {
      m1=*m1_p;
      m2=*m2_p;
    }
  else
    {
      fprintf(stderr,"No mass parameters found!");
      exit(0);
    }

  distance	= LALInferenceGetREAL8Variable(model->params,"distance")* LAL_PC_SI * 1.0e6;        /* distance (1 Mpc) in units of metres */
  
  phi0		= LALInferenceGetREAL8Variable(model->params, "phase"); /* START phase as per lalsimulation convention, radians*/
  
  /* Zenith angle between J and N in radians. Also known as inclination angle when spins are aligned */
  REAL8 thetaJN = acos(LALInferenceGetREAL8Variable(model->params, "costheta_jn"));     /* zenith angle between J and N in radians */

  /* Check if fLow is a model parameter, otherwise use data structure definition */
  if(LALInferenceCheckVariable(model->params, "flow"))
    f_low = *(REAL8*) LALInferenceGetVariable(model->params, "flow");
  else
    f_low = model->fLow;

  f_start = fLow2fStart(f_low, amporder, approximant);
  f_max = 0.0; /* for freq domain waveforms this will stop at ISCO. Previously found using model->fHigh causes NaNs in waveform (see redmine issue #750)*/

  /* ==== SPINS ==== */
  /* We will default to spinless signal and then add in the spin components if required */
  /* If there are non-aligned spins, we must convert between the System Frame coordinates
   * and the cartestian coordinates */

  /* The cartesian spin coordinates (default 0), as passed to LALSimulation */
  REAL8 spin1x = 0.0;
  REAL8 spin1y = 0.0;
  REAL8 spin1z = 0.0;
  REAL8 spin2x = 0.0;
  REAL8 spin2y = 0.0;
  REAL8 spin2z = 0.0;
  
  /* System frame coordinates as used for jump proposals */
  REAL8 a_spin1 = 0.0;  /* Magnitude of spin1 */
  REAL8 a_spin2 = 0.0;  /* Magnitude of spin2 */
  REAL8 phiJL  = 0.0;  /* azimuthal angle of L_N on its cone about J radians */ 
  REAL8 tilt1   = 0.0;  /* zenith angle between S1 and LNhat in radians */
  REAL8 tilt2   = 0.0;  /* zenith angle between S2 and LNhat in radians */
  REAL8 phi12   = 0.0;  /* difference in azimuthal angle btwn S1, S2 in radians */

  /* Now check if we have spin amplitudes */
  if(LALInferenceCheckVariable(model->params, "a_spin1"))    a_spin1   = *(REAL8*) LALInferenceGetVariable(model->params, "a_spin1");
  if(LALInferenceCheckVariable(model->params, "a_spin2"))    a_spin2   = *(REAL8*) LALInferenceGetVariable(model->params, "a_spin2");

  /* Check if we have spin angles too */
  if(LALInferenceCheckVariable(model->params, "phi_jl"))
      phiJL = LALInferenceGetREAL8Variable(model->params, "phi_jl");
  if(LALInferenceCheckVariable(model->params, "tilt_spin1"))
      tilt1 = LALInferenceGetREAL8Variable(model->params, "tilt_spin1");
  if(LALInferenceCheckVariable(model->params, "tilt_spin2"))
      tilt2 = LALInferenceGetREAL8Variable(model->params, "tilt_spin2");
  if(LALInferenceCheckVariable(model->params, "phi12"))
      phi12 = LALInferenceGetREAL8Variable(model->params, "phi12");

  /* If we have tilt angles zero, then the spins are aligned and we just set the z component */
  /* However, if the waveform supports precession then we still need to get the right coordinate components */
  SpinSupport spin_support=XLALSimInspiralGetSpinSupportFromApproximant(approximant);
  if(tilt1==0.0 && tilt2==0.0 && (spin_support==LAL_SIM_INSPIRAL_SPINLESS || spin_support==LAL_SIM_INSPIRAL_ALIGNEDSPIN))
  {
      spin1z=a_spin1;
      spin2z=a_spin2;
      inclination = thetaJN; /* Inclination angle is just thetaJN */
  }
  else
  {   /* Template is not aligned-spin only. */
      /* Set all the other spin components according to the angles we received above */
      /* The transformation function doesn't know fLow, so f_ref==0 isn't interpretted as a request to use the starting frequency for reference. */
      if(fTemp==0.0)
        fTemp = f_start;

      XLAL_TRY(ret=XLALSimInspiralTransformPrecessingNewInitialConditions(
                    &inclination, &spin1x, &spin1y, &spin1z, &spin2x, &spin2y, &spin2z,
                    thetaJN, phiJL, tilt1, tilt2, phi12, a_spin1, a_spin2, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, fTemp), errnum);
      if (ret == XLAL_FAILURE)
      {
        XLALPrintError(" ERROR in XLALSimInspiralTransformPrecessingNewInitialConditions(): error converting angles. errnum=%d\n",errnum );
        return;
      }
  }

  
  /* ==== TIDAL PARAMETERS ==== */  
  REAL8 lambda1 = 0.;
  if(LALInferenceCheckVariable(model->params, "lambda1")) lambda1 = *(REAL8*) LALInferenceGetVariable(model->params, "lambda1");
  REAL8 lambda2 = 0.;
  if(LALInferenceCheckVariable(model->params, "lambda2")) lambda2 = *(REAL8*) LALInferenceGetVariable(model->params, "lambda2");
  REAL8 lambdaT = 0.;
  REAL8 dLambdaT = 0.;
  REAL8 sym_mass_ratio_eta = 0.;
  if(LALInferenceCheckVariable(model->params, "lambdaT")&&LALInferenceCheckVariable(model->params, "dLambdaT")){
    lambdaT = *(REAL8*) LALInferenceGetVariable(model->params, "lambdaT");
    dLambdaT = *(REAL8*) LALInferenceGetVariable(model->params, "dLambdaT");
    sym_mass_ratio_eta = m1*m2/((m1+m2)*(m1+m2));
    LALInferenceLambdaTsEta2Lambdas(lambdaT,dLambdaT,sym_mass_ratio_eta,&lambda1,&lambda2);
  }


  /* Only use GR templates */
  LALSimInspiralTestGRParam *nonGRparams = NULL;
  
  

  /* ==== Call the waveform generator ==== */
  if(model->domain == LAL_SIM_DOMAIN_FREQUENCY) {
    deltaF = model->deltaF;
    
	XLAL_TRY(ret=XLALSimInspiralChooseFDWaveformFromCache(&hptilde, &hctilde, phi0,
            deltaF, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, spin1x, spin1y, spin1z,
            spin2x, spin2y, spin2z, f_start, f_max, f_ref, distance, inclination,lambda1, lambda2, model->waveFlags, nonGRparams, amporder, order,
            approximant,model->waveformCache, NULL), errnum);

     
    /* if the waveform failed to generate, fill the buffer with zeros
     * so that the previous waveform is not left there
     */
    if (ret != XLAL_SUCCESS || hptilde == NULL || hctilde == NULL)
    {
	    XLALPrintError(" ERROR in XLALSimInspiralChooseWaveformFromCache(): error generating waveform. errnum=%d\n",errnum );
	    memset(model->freqhPlus->data->data,0,sizeof(model->freqhPlus->data->data[0])*model->freqhPlus->data->length);
	    memset(model->freqhCross->data->data,0,sizeof(model->freqhCross->data->data[0])*model->freqhCross->data->length);
        if ( hptilde ) XLALDestroyCOMPLEX16FrequencySeries(hptilde);
        if ( hctilde ) XLALDestroyCOMPLEX16FrequencySeries(hctilde);
        XLALSimInspiralDestroyTestGRParam(nonGRparams);
	    XLAL_ERROR_VOID(XLAL_FAILURE);
    }
	if (hptilde==NULL || hptilde->data==NULL || hptilde->data->data==NULL ) {
	  XLALPrintError(" ERROR in LALInferenceTemplateXLALSimInspiralChooseWaveform(): encountered unallocated 'hptilde'.\n");
	  XLAL_ERROR_VOID(XLAL_EFAULT);
	}
	if (hctilde==NULL || hctilde->data==NULL || hctilde->data->data==NULL ) {
	  XLALPrintError(" ERROR in LALInferenceTemplateXLALSimInspiralChooseWaveform(): encountered unallocated 'hctilde'.\n");
	  XLAL_ERROR_VOID(XLAL_EFAULT);
	}

    INT4 rem=0;
    UINT4 size=hptilde->data->length;
    if(size>model->freqhPlus->data->length) size=model->freqhPlus->data->length;
    memcpy(model->freqhPlus->data->data,hptilde->data->data,sizeof(hptilde->data->data[0])*size);
    if( (rem=(model->freqhPlus->data->length - size)) > 0)
        memset(&(model->freqhPlus->data->data[size]),0, rem*sizeof(hptilde->data->data[0]) );

    size=hctilde->data->length;
    if(size>model->freqhCross->data->length) size=model->freqhCross->data->length;
    memcpy(model->freqhCross->data->data,hctilde->data->data,sizeof(hctilde->data->data[0])*size);
    if( (rem=(model->freqhCross->data->length - size)) > 0)
        memset(&(model->freqhCross->data->data[size]),0, rem*sizeof(hctilde->data->data[0]) );
    
    
    /* Destroy the nonGr params */
    XLALSimInspiralDestroyTestGRParam(nonGRparams);
    
    REAL8 instant = model->freqhPlus->epoch.gpsSeconds + 1e-9*model->freqhPlus->epoch.gpsNanoSeconds;
    LALInferenceSetVariable(model->params, "time", &instant);
    
  } else {

    XLAL_TRY(ret=XLALSimInspiralChooseTDWaveformFromCache(&hplus, &hcross, phi0, deltaT,
            m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, spin1x, spin1y, spin1z,
            spin2x, spin2y, spin2z, f_start, f_ref, distance,
            inclination, lambda1, lambda2, model->waveFlags, nonGRparams,
            amporder, order, approximant,model->waveformCache), errnum);
    XLALSimInspiralDestroyTestGRParam(nonGRparams);
    if (ret == XLAL_FAILURE || hplus == NULL || hcross == NULL)
    {
            XLALPrintError(" ERROR in XLALSimInspiralChooseWaveformFromCache(): error generating waveform. errnum=%d\n",errnum );
            memset(model->timehPlus->data->data,0,sizeof(model->timehPlus->data->data[0]) * model->timehPlus->data->length);
            memset(model->timehCross->data->data,0,sizeof(model->timehCross->data->data[0]) * model->timehCross->data->length);
            if ( hplus ) XLALDestroyREAL8TimeSeries(hplus);
            if ( hcross ) XLALDestroyREAL8TimeSeries(hcross);
            XLALSimInspiralDestroyTestGRParam(nonGRparams);
            XLAL_ERROR_VOID(XLAL_FAILURE);
    }

    /* The following complicated mess is a result of the following considerations:
       
       1) The discrete time samples of the template and the timeModel
       buffers will not, in general line up.

       2) The likelihood function will timeshift the template in the
       frequency domain to align it properly with the desired tc in
       each detector (these are different because the detectors
       receive the signal at different times).  Because this
       timeshifting is done in the frequency domain, the effective
       time-domain template is periodic.  We want to avoid the
       possibility of non-zero template samples wrapping around from
       the start/end of the buffer, since real templates are not
       periodic!

       3) If the template apporaches the ends of the timeModel buffer,
       then it should be tapered in the same way as the timeData
       (currently 0.4 seconds, hard-coded! Tukey window; see
       LALInferenceReadData.c, near line 233) so that template and
       signal in the data match.  However, as an optimization, we
       perform only one tapering and FFT-ing in the likelihood
       function; subsequent timeshifts for the different detectors
       will cause the tapered regions of the template and data to
       become mis-aligned.

       The algorthim we use is the following:

       1) Inject the template to align with the nearest sample in the
       timeModel buffer to the desired geocent_end time.

       2) Check whether either the start or the end of the template
       overlaps the tapered region, plus a safety buffer corresponding
       to a conservative estimate of the largest geocenter <-->
       detector timeshift.
       
         a) If there is no overlap at the start or end of the buffer,
         we're done.

	 b) If there is an overlap, issue one warning per process
	 (which can be disabled by setting the LAL debug level) about
	 a too-short segment length, and return.
*/

    size_t waveLength = hplus->data->length;
    size_t bufLength = model->timehPlus->data->length;

    /* 2*Rearth/(c*deltaT)---2 is safety factor---is the maximum time
       shift for any earth-based detector. */
    size_t maxShift = (size_t)lround(4.255e-2/deltaT); 

    /* Taper 0.4 seconds at start and end (hard-coded! in
       LALInferenceReadData.c, around line 233). */
    size_t taperLength = (size_t)lround(0.4/deltaT); 

    /* Within unsafeLength of ends of buffer, possible danger of
       wrapping and/or tapering interactions. */
    size_t unsafeLength = taperLength + maxShift;

    REAL8 desiredTc = *(REAL8 *)LALInferenceGetVariable(model->params, "time");
    REAL8 tStart = XLALGPSGetREAL8(&(model->timehPlus->epoch));
    REAL8 tEnd = tStart + deltaT * model->timehPlus->data->length;

    if (desiredTc < tStart || desiredTc > tEnd) {
      XLALDestroyREAL8TimeSeries(hplus);
      XLALDestroyREAL8TimeSeries(hcross);

      XLAL_PRINT_ERROR("desired tc (%.4f) outside data buffer\n", desiredTc);
      XLAL_ERROR_VOID(XLAL_EDOM);
    }

    /* The nearest sample in model buffer to the desired tc. */
    size_t tcSample = (size_t)lround((desiredTc - XLALGPSGetREAL8(&(model->timehPlus->epoch)))/deltaT);

    /* The acutal coalescence time that corresponds to the buffer
       sample on which the waveform's tC lands. */
    REAL8 injTc = XLALGPSGetREAL8(&(model->timehPlus->epoch)) + tcSample*deltaT;

    /* The sample at which the waveform reaches tc. */
    size_t waveTcSample = (size_t)lround(-XLALGPSGetREAL8(&(hplus->epoch))/deltaT);

    /* 1 + (number of samples post-tc in waveform) */
    size_t wavePostTc = waveLength - waveTcSample;

    size_t bufStartIndex = (tcSample >= waveTcSample ? tcSample - waveTcSample : 0);
    size_t bufEndIndex = (wavePostTc + tcSample <= bufLength ? wavePostTc + tcSample : bufLength);
    size_t bufWaveLength = bufEndIndex - bufStartIndex;
    size_t waveStartIndex = (tcSample >= waveTcSample ? 0 : waveTcSample - tcSample);    

    if (bufStartIndex < unsafeLength || (bufLength - bufEndIndex) <= unsafeLength) {
      /* The waveform could be timeshifted into a region where it will
	 be tapered improperly, or even wrap around from the periodic
	 timeshift.  Issue warning. */
      if (!sizeWarning) {
	fprintf(stderr, "WARNING: Generated template is too long to guarantee that it will not\n");
	fprintf(stderr, "WARNING:  (a) lie in a tapered region of the time-domain buffer\n");
	fprintf(stderr, "WARNING:  (b) wrap periodically when timeshifted in likelihood computation\n");
	fprintf(stderr, "WARNING: Either of these may cause differences between the template and the\n");
	fprintf(stderr, "WARNING: correct GW waveform in each detector.\n");
	fprintf(stderr, "WARNING: Parameter estimation will continue, but you should consider\n");
	fprintf(stderr, "WARNING: increasing the data segment length (using the --seglen) option.\n");
	sizeWarning = 1;
      }
    }

    /* Clear model buffers */
    memset(model->timehPlus->data->data, 0, sizeof(REAL8)*model->timehPlus->data->length);
    memset(model->timehCross->data->data, 0, sizeof(REAL8)*model->timehCross->data->length);
    
    /* Inject */
    memcpy(model->timehPlus->data->data + bufStartIndex,
	   hplus->data->data + waveStartIndex,
	   bufWaveLength*sizeof(REAL8));
    memcpy(model->timehCross->data->data + bufStartIndex,
	   hcross->data->data + waveStartIndex,
	   bufWaveLength*sizeof(REAL8));

    LALInferenceSetVariable(model->params, "time", &injTc);
  }

  if ( hplus ) XLALDestroyREAL8TimeSeries(hplus);
  if ( hcross ) XLALDestroyREAL8TimeSeries(hcross);
  if ( hptilde ) XLALDestroyCOMPLEX16FrequencySeries(hptilde);
  if ( hctilde ) XLALDestroyCOMPLEX16FrequencySeries(hctilde);
  
  return;
}
Exemplo n.º 19
0
int main(int argc, char *argv[])
{
    struct params p;
    int istd, isfd;

    XLALSetErrorHandler(XLALBacktraceErrorHandler);

    p = parseargs(argc, argv);
    print_params(p);

    /* sanity check on domain; set to natural value if unspecified */
    istd = XLALSimInspiralImplementedTDApproximants(p.approx);
    isfd = XLALSimInspiralImplementedFDApproximants(p.approx);
    if (!istd && !isfd) {
        fprintf(stderr, "error: approximant not supported\n");
        exit(1);
    }
    switch (p.domain) {
    case LAL_SIM_DOMAIN_TIME:
        if (!istd) {
            fprintf(stderr, "error: approximant not supported in time domain\n");
            exit(1);
        }
        break;
    case LAL_SIM_DOMAIN_FREQUENCY:
        if (!isfd) {
            fprintf(stderr, "error: approximant not supported in frequency domain\n");
            exit(1);
        }
        break;
    default:
        switch (p.freq_dom) {
        case 0:
            p.domain = istd ? LAL_SIM_DOMAIN_TIME : LAL_SIM_DOMAIN_FREQUENCY;
            break;
        case 1:
            p.domain = isfd ? LAL_SIM_DOMAIN_FREQUENCY : LAL_SIM_DOMAIN_TIME;
            break;
        }
        break;
    }

    /* generate and output the waveform in appropriate domain */
    if (p.freq_dom) {
        COMPLEX16FrequencySeries *htilde_plus = NULL;
        COMPLEX16FrequencySeries *htilde_cross = NULL;
        create_fd_waveform(&htilde_plus, &htilde_cross, p);
        output_fd_waveform(htilde_plus, htilde_cross, p);
        XLALDestroyCOMPLEX16FrequencySeries(htilde_cross);
        XLALDestroyCOMPLEX16FrequencySeries(htilde_plus);
    } else {
        REAL8TimeSeries *h_plus = NULL;
        REAL8TimeSeries *h_cross = NULL;
        create_td_waveform(&h_plus, &h_cross, p);
        output_td_waveform(h_plus, h_cross, p);
        XLALDestroyREAL8TimeSeries(h_cross);
        XLALDestroyREAL8TimeSeries(h_plus);
    }

    /* cleanup */
    XLALDestroyDict(p.params);
    LALCheckMemoryLeaks();
    return 0;
}
Exemplo n.º 20
0
INT4 main (INT4 argc, char* argv[])
{
    UINT4 startAtZero = 1;
    // RNG seed
    UINT8 seed;

    REAL8 desiredDeltaF;

    // if passed parameters, assume first parameter is the seed
    if(argc > 1)
    {
        seed = atoi(argv[1]);
        if(seed == 0)
        {
            seed = time(0);
        }

        if(argc > 2)
        {
            desiredDeltaF = atof(argv[2]);
        }
        else
        {
            desiredDeltaF = 0.1;
        }
    }
    else
    {
        seed = time(0);
    }

    // seed the RNG
    srand(seed);
    printf("Starting TestTaylorTFourier with seed %" LAL_UINT8_FORMAT "\n" , seed);

    // define different orders
    LALSimInspiralSpinOrder spinO = 7;
    LALSimInspiralTidalOrder tideO = 0;
    INT4 phaseO = 7;
    INT4 amplitudeO = 3;

    // define parameters
    REAL8 phiRef, v0, m1, m2, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2;

    v0 = 1.;

    // deformability parameters turned off
    lambda1 = 0.;
    lambda2 = 0.;
    quadparam1 = 0.;
    quadparam2 = 0.;

    // define instrument projection parameters
    REAL8 Fplus, Fcross;

    // define range for the parameters
    REAL8 m1Min, m1Max, m2Min, m2Max, chi1Min, chi1Max, chi2Min, chi2Max, rMin, rMax;

    m1Min = 1.; // in solar masses
    m1Max = 2.5; // in solar masses
    m2Min = 1.; // in solar masses
    m2Max = 2.5; // in solar masses
    chi1Min = 0.;
    chi1Max = 1.;
    chi2Min = 0.;
    chi2Max = 1.;
    rMin = 3.e24;
    rMax = 3.e24;

    // randomize parameters
    randomize(&phiRef, &m1, &m2, &r, &s1x, &s1y, &s1z, &s2x, &s2y, &s2z, &lnhatx, &lnhaty, &lnhatz, &e1x, &e1y, &e1z, &Fplus, &Fcross, m1Min, m1Max, m2Min, m2Max,  chi1Min, chi1Max, chi2Min, chi2Max, rMin, rMax);

    // misc parameters
    REAL8 tTot;
    REAL8 deltaF;
    INT4 nSamples;
    REAL8 fMin;
    REAL8 fMax;
    REAL8 tInit;
    REAL8 desiredFMin;
    UINT4 i;

    fMax = 2000.;
    desiredFMin = 10.;

    REAL8 M = m1 + m2;
    REAL8 eta = (m1*m2)/(M*M);
    // define time series for time domain waveform
    REAL8TimeSeries* hPlus = 0;
    REAL8TimeSeries* hCross = 0;

    // define extra parameters for TD WF
    REAL8 deltaT;

    REAL8 fStart = 9.;
    REAL8 fRef = 70.;
    INT4 phiRefAtEnd = 0;

    // more misc variables
    COMPLEX16* hPlusTildeTD;
    COMPLEX16* hCrossTildeTD;

    REAL8 factTukey, t1, t2, t3, t4;
    REAL8 sinfact, t;

    fftw_complex* ftilde_data;
    fftw_plan plan;

    INT4 iStart, jStart, nSkip;
    REAL8 rStop;

    INT4 nMax;


    // define frequency series for FD WFs
    COMPLEX16FrequencySeries* hPlusTildeFD = 0;
    COMPLEX16FrequencySeries* hCrossTildeFD = 0;

    INT4 kMax;
    REAL8 normalizationTD;
    REAL8 meanDeltaT;
    REAL8 match;


    printf("TaylorT4:\nStarting time domain...\n");

    // compute TD WF with deltaT=1 to get signal time duration
    deltaT = 1.;
    XLALSimInspiralSpinTaylorT4(&hPlus, &hCross, phiRef, v0, deltaT, m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, amplitudeO);

    // compute deltaT necessary for Nyquist frequency at fMax
    tTot = -(hPlus->epoch.gpsSeconds + 1.e-9*hPlus->epoch.gpsNanoSeconds);
    deltaF = 1./tTot;
    nSamples = 2.*fMax/deltaF;
    deltaT = tTot/nSamples;

    // compute TD WF with good deltaT
    XLALDestroyREAL8TimeSeries(hPlus);
    XLALDestroyREAL8TimeSeries(hCross);
    XLALSimInspiralSpinTaylorT4(&hPlus, &hCross, phiRef, v0, deltaT, m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, amplitudeO);

    // define and allocate DFT of TD WF
    hPlusTildeTD = (COMPLEX16*)malloc(sizeof(COMPLEX16)*(hPlus->data->length));
    hCrossTildeTD = (COMPLEX16*)malloc(sizeof(COMPLEX16)*(hCross->data->length));

    tInit = hPlus->epoch.gpsSeconds + 1.e-9*hPlus->epoch.gpsNanoSeconds;
    deltaF = 1./(deltaT*(hPlus->data->length));

    // define Tukey window parameters
    factTukey = (-5.*LAL_G_SI*M)/(((256.*eta*LAL_C_SI)*LAL_C_SI)*LAL_C_SI);
    t1 = tInit;
    t2 = factTukey*pow((LAL_PI*LAL_G_SI)*M*9.5/(((((REAL8)LAL_C_SI)*LAL_C_SI)*LAL_C_SI)), -8./3.); // 9.5 Hertz Newtonian
    t3 = factTukey*50625.; // 15M separation Newtonian
    t4 = 0.;

    // apply Tukey window
    i = 0;
    t = tInit;
    while(t < t2)
    {
        sinfact = sin(LAL_PI_2*(t - t1)/(t2 - t1));
        hPlus->data->data[i] *= sinfact*sinfact;
        hCross->data->data[i] *= sinfact*sinfact;
        i++;
        t = tInit + i*deltaT;
    }

    i = hPlus->data->length-1;
    t = tInit + i*deltaT;
    while(t > t3)
    {
        sinfact = sin(LAL_PI_2*(t - t4)/(t3 - t4));
        hPlus->data->data[i] *= sinfact*sinfact;
        hCross->data->data[i] *= sinfact*sinfact;
        i--;
        t = tInit + i*deltaT;
    }

    // compute the DFTs, applying the necessary time shift
    ftilde_data = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*(hPlus->data->length));
    plan = fftw_plan_dft_r2c_1d(hPlus->data->length, hPlus->data->data, ftilde_data, FFTW_ESTIMATE);
    fftw_execute(plan);
    fftw_destroy_plan(plan);

    for(i = 0; i <= hPlus->data->length >> 1; i++)
    {
        hPlusTildeTD[i] = deltaT*cexp(-I*LAL_TWOPI*i*deltaF*tInit)*ftilde_data[i];
    }

    plan = fftw_plan_dft_r2c_1d(hCross->data->length, hCross->data->data, ftilde_data, FFTW_ESTIMATE);
    fftw_execute(plan);
    fftw_destroy_plan(plan);

    for(i = 0; i <= hCross->data->length >> 1; i++)
    {
        hCrossTildeTD[i] = deltaT*cexp(-I*LAL_TWOPI*i*deltaF*tInit)*ftilde_data[i];
    }

    fftw_free(ftilde_data);


    // compute fMin and deltaF for the frequency domain WFs, close to desiredFMin and desiredDeltaF but a multiple of deltaF for the TD WF
    iStart = (INT4)ceil(desiredFMin/deltaF);
    nSkip = (INT4)ceil(desiredDeltaF/deltaF);
    iStart -= iStart % nSkip;
    fMin = iStart*deltaF;
    deltaF *= nSkip;
    if(startAtZero)
    {
        jStart = iStart/nSkip;
    }
    else
    {
        jStart = 0;
    }

    // set maximum frequency for the comparison
    rStop = 20.; // frequency of r = 20M
    fMax = LAL_C_SI*(LAL_C_SI*(LAL_C_SI/(LAL_PI*LAL_G_SI*M*rStop*sqrt(rStop))));

    nMax = (INT4)floor((fMax - fMin)/deltaF) + jStart;


    // normalize TD WF
    normalizationTD = normalizeTD(hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax);

    printf("Matches:\n");

    for(kMax = 0; kMax <= 10; kMax++) // loop over kMax
    {
        //compute FD WF
        XLALSimInspiralSpinTaylorT4Fourier(&hPlusTildeFD, &hCrossTildeFD, fMin, fMax, deltaF, kMax, phiRef, v0, m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, amplitudeO, phiRefAtEnd);

        // XLALSimInspiralSpinTaylorT4 and XLALSimInspiralSpinTaylorT4Fourier return with a slight time offset between the two. We get rid of that.
        if(startAtZero)
        {
            meanDeltaT = meanTimeOffset(hPlusTildeFD, hCrossTildeFD, hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax, 0., deltaF);
            for(i = 0; i < hPlusTildeFD->data->length; i++)
            {
                hPlusTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(i*deltaF)*meanDeltaT);
                hCrossTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(i*deltaF)*meanDeltaT);
            }
        }
        else
        {
            meanDeltaT = meanTimeOffset(hPlusTildeFD, hCrossTildeFD, hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax, fMin, deltaF);
            for(i = 0; i < hPlusTildeFD->data->length; i++)
            {
                hPlusTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(fMin + i*deltaF)*meanDeltaT);
                hCrossTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(fMin + i*deltaF)*meanDeltaT);
            }
        }

        // compute match
        match = normalizationTD*computeMatch(hPlusTildeFD, hCrossTildeFD, hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax);
        printf("kMax = %2d: %.15f\n", kMax, match);

        XLALDestroyCOMPLEX16FrequencySeries(hPlusTildeFD);
        XLALDestroyCOMPLEX16FrequencySeries(hCrossTildeFD);
    }

    XLALDestroyREAL8TimeSeries(hPlus);
    XLALDestroyREAL8TimeSeries(hCross);
    free(hPlusTildeTD);
    free(hCrossTildeTD);








    printf("\nTaylorT2:\nStarting time domain...\n");

    // compute TD WF with deltaT=1 to get signal time duration
    deltaT = 1.;
    XLALSimInspiralSpinTaylorT2(&hPlus, &hCross, phiRef, v0, deltaT, m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, amplitudeO);

    // compute deltaT necessary for Nyquist frequency at fMax
    tTot = -(hPlus->epoch.gpsSeconds + 1.e-9*hPlus->epoch.gpsNanoSeconds);
    deltaF = 1./tTot;
    nSamples = 2.*fMax/deltaF;
    deltaT = tTot/nSamples;

    // compute TD WF with good deltaT
    XLALDestroyREAL8TimeSeries(hPlus);
    XLALDestroyREAL8TimeSeries(hCross);
    XLALSimInspiralSpinTaylorT2(&hPlus, &hCross, phiRef, v0, deltaT, m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, amplitudeO);

    // define and allocate DFT of TD WF
    hPlusTildeTD = (COMPLEX16*)malloc(sizeof(COMPLEX16)*(hPlus->data->length));
    hCrossTildeTD = (COMPLEX16*)malloc(sizeof(COMPLEX16)*(hCross->data->length));

    tInit = hPlus->epoch.gpsSeconds + 1.e-9*hPlus->epoch.gpsNanoSeconds;
    deltaF = 1./(deltaT*(hPlus->data->length));

    // define Tukey window parameters
    factTukey = (-5.*LAL_G_SI*M)/(((256.*eta*LAL_C_SI)*LAL_C_SI)*LAL_C_SI);
    t1 = tInit;
    t2 = factTukey*pow((LAL_PI*LAL_G_SI)*M*9.5/(((((REAL8)LAL_C_SI)*LAL_C_SI)*LAL_C_SI)), -8./3.); // 9.5 Hertz Newtonian
    t3 = factTukey*25.*25.*25.*25.; // 25M separation Newtonian. For TaylorT2 we need a huge half-Hann window at the end for some reason.
    t4 = 0.;

    // apply Tukey window
    i = 0;
    t = tInit;
    while(t < t2)
    {
        sinfact = sin(LAL_PI_2*(t - t1)/(t2 - t1));
        hPlus->data->data[i] *= sinfact*sinfact;
        hCross->data->data[i] *= sinfact*sinfact;
        i++;
        t = tInit + i*deltaT;
    }

    i = hPlus->data->length-1;
    t = tInit + i*deltaT;
    while(t > t3)
    {
        sinfact = sin(LAL_PI_2*(t - t4)/(t3 - t4));
        hPlus->data->data[i] *= sinfact*sinfact;
        hCross->data->data[i] *= sinfact*sinfact;
        i--;
        t = tInit + i*deltaT;
    }

    // compute the DFTs, applying the necessary time shift
    ftilde_data = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*(hPlus->data->length));
    plan = fftw_plan_dft_r2c_1d(hPlus->data->length, hPlus->data->data, ftilde_data, FFTW_ESTIMATE);
    fftw_execute(plan);
    fftw_destroy_plan(plan);

    for(i = 0; i <= hPlus->data->length >> 1; i++)
    {
        hPlusTildeTD[i] = deltaT*cexp(-I*LAL_TWOPI*i*deltaF*tInit)*ftilde_data[i];
    }

    plan = fftw_plan_dft_r2c_1d(hCross->data->length, hCross->data->data, ftilde_data, FFTW_ESTIMATE);
    fftw_execute(plan);
    fftw_destroy_plan(plan);

    for(i = 0; i <= hCross->data->length >> 1; i++)
    {
        hCrossTildeTD[i] = deltaT*cexp(-I*LAL_TWOPI*i*deltaF*tInit)*ftilde_data[i];
    }

    fftw_free(ftilde_data);


    // compute fMin and deltaF for the frequency domain WFs, close to desiredFMin and desiredDeltaF but a multiple of deltaF for the TD WF
    iStart = (INT4)ceil(desiredFMin/deltaF);
    nSkip = (INT4)ceil(desiredDeltaF/deltaF);
    iStart -= iStart % nSkip;
    fMin = iStart*deltaF;
    deltaF *= nSkip;
    if(startAtZero)
    {
        jStart = iStart/nSkip;
    }
    else
    {
        jStart = 0;
    }

    // set maximum frequency for the comparison
    rStop = 25.; // frequency of r = 20M
    fMax = LAL_C_SI*(LAL_C_SI*(LAL_C_SI/(LAL_PI*LAL_G_SI*M*rStop*sqrt(rStop))));

    nMax = (INT4)floor((fMax - fMin)/deltaF) + jStart;


    // define frequency series for FD WFs
    hPlusTildeFD = 0;
    hCrossTildeFD = 0;

    // normalize TD WF
    normalizationTD = normalizeTD(hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax);

    printf("Matches:\n");

    for(kMax = 0; kMax <= 10; kMax++) // loop over kMax
    {
        //compute FD WF
        XLALSimInspiralSpinTaylorT2Fourier(&hPlusTildeFD, &hCrossTildeFD, fMin, fMax, deltaF, kMax, phiRef, v0, m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, amplitudeO, phiRefAtEnd);

        // XLALSimInspiralSpinTaylorT2 and XLALSimInspiralSpinTaylorT2Fourier return with a slight time offset between the two. We get rid of that.
        if(startAtZero)
        {
            meanDeltaT = meanTimeOffset(hPlusTildeFD, hCrossTildeFD, hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax, 0., deltaF);
            for(i = 0; i < hPlusTildeFD->data->length; i++)
            {
                hPlusTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(i*deltaF)*meanDeltaT);
                hCrossTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(i*deltaF)*meanDeltaT);
            }
        }
        else
        {
            meanDeltaT = meanTimeOffset(hPlusTildeFD, hCrossTildeFD, hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax, fMin, deltaF);
            for(i = 0; i < hPlusTildeFD->data->length; i++)
            {
                hPlusTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(fMin + i*deltaF)*meanDeltaT);
                hCrossTildeFD->data->data[i] *= cexp(I*LAL_TWOPI*(fMin + i*deltaF)*meanDeltaT);
            }
        }

        // compute match
        match = normalizationTD*computeMatch(hPlusTildeFD, hCrossTildeFD, hPlusTildeTD, hCrossTildeTD, Fplus, Fcross, iStart, jStart, nSkip, nMax);
        printf("kMax = %2d: %.15f\n", kMax, match);

        XLALDestroyCOMPLEX16FrequencySeries(hPlusTildeFD);
        XLALDestroyCOMPLEX16FrequencySeries(hCrossTildeFD);
    }

    XLALDestroyREAL8TimeSeries(hPlus);
    XLALDestroyREAL8TimeSeries(hCross);
    free(hPlusTildeTD);
    free(hCrossTildeTD);

    fftw_cleanup();


    return XLAL_SUCCESS;
}
/** Store the output FD hptilde and hctilde in cache. */
static int StoreFDHCache(LALSimInspiralWaveformCache *cache,
        COMPLEX16FrequencySeries *hptilde,
        COMPLEX16FrequencySeries *hctilde,
        REAL8 phiRef,
        REAL8 deltaT,
        REAL8 m1, REAL8 m2,
        REAL8 S1x, REAL8 S1y, REAL8 S1z,
        REAL8 S2x, REAL8 S2y, REAL8 S2z,
        REAL8 f_min, REAL8 f_ref, REAL8 f_max,
        REAL8 r,
        REAL8 i,
	LALDict *LALpars,
        Approximant approximant,
        REAL8Sequence *frequencies
        )
{
    /* Clear any time-domain data. */
    if (cache->hplus != NULL) {
        XLALDestroyREAL8TimeSeries(cache->hplus);
        cache->hplus = NULL;
    }

    if (cache->hcross != NULL) {
        XLALDestroyREAL8TimeSeries(cache->hcross);
        cache->hcross = NULL;
    }

    /* Store params in cache */
    cache->phiRef = phiRef;
    cache->deltaTF = deltaT;
    cache->m1 = m1;
    cache->m2 = m2;
    cache->S1x = S1x;
    cache->S1y = S1y;
    cache->S1z = S1z;
    cache->S2x = S2x;
    cache->S2y = S2y;
    cache->S2z = S2z;
    cache->f_min = f_min;
    cache->f_ref = f_ref;
    cache->f_max = f_max;
    cache->r = r;
    cache->i = i;
    cache->LALpars = LALpars;
    cache->approximant = approximant;

    XLALDestroyREAL8Sequence(cache->frequencies);
    cache->frequencies = NULL;
    if (frequencies != NULL){
        cache->frequencies = XLALCopyREAL8Sequence(frequencies);
    }

    // Copy over the waveforms
    // NB: XLALCut... creates a new Series object and copies data and metadata
    XLALDestroyCOMPLEX16FrequencySeries(cache->hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(cache->hctilde);
    cache->hptilde = XLALCutCOMPLEX16FrequencySeries(hptilde, 0,
            hptilde->data->length);
    if (cache->hptilde == NULL) return XLAL_ENOMEM;
    cache->hctilde = XLALCutCOMPLEX16FrequencySeries(hctilde, 0,
            hctilde->data->length);
    if (cache->hctilde == NULL) {
        XLALDestroyCOMPLEX16FrequencySeries(cache->hptilde);
        cache->hptilde = NULL;
        return XLAL_ENOMEM;
    }

    return XLAL_SUCCESS;
}
Exemplo n.º 22
0
/**
 * Driver routine to compute the spin-aligned, inspiral-merger-ringdown
 * phenomenological waveform IMRPhenomC in the time domain.
 * (Note that this approximant was constructed as a smooth function in
 * the frequency domain, so there might be spurious effects after
 * transforming into the time domain. One example are small amplitude
 * oscillations just before merger.)
 *
 * Reference: http://arxiv.org/pdf/1005.3306v3.pdf
 *   - Waveform: Eq.(5.3)-(5.13)
 *   - Coefficients: Eq.(5.14) and Table II
 *
 * All input parameters should be in SI units. Angles should be in radians.
 */
int XLALSimIMRPhenomCGenerateTD(
    REAL8TimeSeries **hplus,  /**< +-polarization waveform */
    REAL8TimeSeries **hcross, /**< x-polarization waveform */
    const REAL8 phiPeak,      /**< orbital phase at peak (rad) */
    const REAL8 deltaT,       /**< sampling interval (s) */
    const REAL8 m1_SI,        /**< mass of companion 1 (kg) */
    const REAL8 m2_SI,        /**< mass of companion 2 (kg) */
    const REAL8 chi,          /**< mass-weighted aligned-spin parameter */
    const REAL8 f_min,        /**< starting GW frequency (Hz) */
    const REAL8 f_max,        /**< end GW frequency; 0 defaults to ringdown cutoff freq */
    const REAL8 distance,     /**< distance of source (m) */
    const REAL8 inclination   /**< inclination of source (rad) */
) {
	BBHPhenomCParams *params;
	size_t cut_ind, peak_ind, ind_t0;
	REAL8 peak_phase;  /* measured, not intended */
	REAL8 f_max_prime;

	/* external: SI; internal: solar masses */
	const REAL8 m1 = m1_SI / LAL_MSUN_SI;
	const REAL8 m2 = m2_SI / LAL_MSUN_SI;
	const REAL8 fISCO = 0.022 / ((m1 + m2) * LAL_MTSUN_SI);

	/* check inputs for sanity */
	if (*hplus) XLAL_ERROR(XLAL_EFAULT);
	if (*hcross) XLAL_ERROR(XLAL_EFAULT);
	if (deltaT <= 0) XLAL_ERROR(XLAL_EDOM);
	if (m1 < 0) XLAL_ERROR(XLAL_EDOM);
	if (m2 < 0) XLAL_ERROR(XLAL_EDOM);
	if (fabs(chi) > 1) XLAL_ERROR(XLAL_EDOM);
	if (f_min <= 0) XLAL_ERROR(XLAL_EDOM);
	if (f_max < 0) XLAL_ERROR(XLAL_EDOM);
	if (distance <= 0) XLAL_ERROR(XLAL_EDOM);

	/* If spins are above 0.9 or below -0.9, throw an error */
	if (chi > 0.9 || chi < -0.9)
		XLAL_ERROR(XLAL_EDOM, "Spins outside the range [-0.9,0.9] are not supported\n");

	/* If mass ratio is above 4 and below 20, give a warning, and if it is above
	 * 20, throw an error */
	REAL8 q = (m1 > m2) ? (m1 / m2) : (m2 / m1);

	if (q > 20.0)
		XLAL_ERROR(XLAL_EDOM, "Mass ratio is way outside the calibration range. m1/m2 should be <= 20.\n");
	else if (q > 4.0)
		XLAL_PRINT_WARNING("Warning: The model is only calibrated for m1/m2 <= 4.\n");

	/* phenomenological parameters*/
	params = ComputeIMRPhenomCParams(m1, m2, chi);
	if (!params) XLAL_ERROR(XLAL_EFUNC);
	if (params->fCut <= f_min)
		XLAL_ERROR(XLAL_EDOM, "(fCut = 0.15M) <= f_min\n");

	/* default f_max to params->fCut */
	f_max_prime = f_max ? f_max : params->fCut;
	f_max_prime = (f_max_prime > params->fCut) ? params->fCut : f_max_prime;
	if (f_max_prime <= f_min)
		XLAL_ERROR(XLAL_EDOM, "f_max <= f_min\n");

	/* generate plus */

	IMRPhenomCGenerateTD(hplus, 0., &ind_t0, deltaT, m1, m2, f_min, f_max_prime, distance, params);
	if (!(*hplus)) {
		XLALFree(params);
		XLAL_ERROR(XLAL_EFUNC);
	}

	/* generate hcross, which is hplus w/ GW phase shifted by -pi/2
	 * <==> orb. phase shifted by -pi/4 */
	IMRPhenomCGenerateTD(hcross, -LAL_PI_4, &ind_t0, deltaT, m1, m2, f_min, f_max_prime, distance, params);
	if (!(*hcross)) {
		XLALDestroyREAL8TimeSeries(*hplus);
		*hplus = NULL;
		XLAL_ERROR(XLAL_EFUNC);
	}

	/* clip the parts below f_min */
	//const size_t start_ind = ((*hplus)->data->length + EstimateIMRLength(m1, m2, f_max_prime, deltaT)) > EstimateIMRLength(m1, m2, f_min, deltaT) ? ((*hplus)->data->length + EstimateIMRLength(m1, m2, f_max_prime, deltaT) - EstimateIMRLength(m1, m2, f_min, deltaT)) : 0;

	//const size_t start_ind = ((*hplus)->data->length
	//	      - EstimateIMRLength(m1, m2, 0.95 * f_min + 0.05 * f_max_prime, deltaT));


	peak_ind = find_peak_amp(*hplus, *hcross);

	cut_ind =find_instant_freq(*hplus, *hcross, f_min < fISCO/2. ? f_min : fISCO/2., peak_ind);
	*hplus = XLALResizeREAL8TimeSeries(*hplus, cut_ind, (*hplus)->data->length - cut_ind);
	*hcross = XLALResizeREAL8TimeSeries(*hcross, cut_ind, (*hcross)->data->length - cut_ind);

	if (!(*hplus) || !(*hcross))
		XLAL_ERROR(XLAL_EFUNC);

	/* set phase and time at peak */
	peak_ind = find_peak_amp(*hplus, *hcross);
	peak_phase = atan2((*hcross)->data->data[peak_ind], (*hplus)->data->data[peak_ind]);
	// NB: factor of 2 b/c phiPeak is *orbital* phase, and we're shifting GW phase
	apply_phase_shift(*hplus, *hcross, 2.*phiPeak - peak_phase);
	XLALGPSSetREAL8(&((*hplus)->epoch), -(peak_ind * deltaT));
	XLALGPSSetREAL8(&((*hcross)->epoch), -(peak_ind * deltaT));

	/* apply inclination */
	XLALFree(params);
	return apply_inclination(*hplus, *hcross, inclination);
}
Exemplo n.º 23
0
int main(void) {
    clock_t s1, e1, s2, e2;
    double diff1, diff2;
    unsigned int i;
    REAL8 plusdiff, crossdiff, temp;
    REAL8TimeSeries *hplus = NULL;
    REAL8TimeSeries *hcross = NULL;
    REAL8TimeSeries *hplusC = NULL;
    REAL8TimeSeries *hcrossC = NULL;
    COMPLEX16FrequencySeries *hptilde = NULL;
    COMPLEX16FrequencySeries *hctilde = NULL;
    COMPLEX16FrequencySeries *hptildeC = NULL;
    COMPLEX16FrequencySeries *hctildeC = NULL;
    REAL8 m1 = 10. * LAL_MSUN_SI, m2 = 10 * LAL_MSUN_SI;
    REAL8 s1x = 0., s1y = 0., s1z = 0., s2x = 0., s2y = 0., s2z = 0.;
    REAL8 f_min = 40., f_ref = 0., lambda1 = 0., lambda2 = 0.i, f_max = 0.;
    REAL8 dt = 1./16384., df = 1./16.;
    int ret, phaseO = 7, ampO = 0;
    Approximant approx = SEOBNRv1;
    Approximant approxFD = TaylorF2;
    REAL8 phiref1 = 0., phiref2 = 0.3;
    REAL8 inc1 = 0.2, inc2 = 1.3;
    REAL8 dist1 = 1.e6 * LAL_PC_SI, dist2 = 2.e6 * LAL_PC_SI;
    LALSimInspiralWaveformCache *cache = XLALCreateSimInspiralWaveformCache();

    //
    // Test TD path with SEOBNRv1
    //

    // Generate waveform via usual ChooseTDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseTDWaveform(&hplus, &hcross, phiref1, dt, m1, m2,
        s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist1, inc1,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will call ChooseWaveform this 1st time
    s2 = clock();
    ret = XLALSimInspiralChooseTDWaveformFromCache(&hplusC, &hcrossC, phiref1,
        dt, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist1, inc1,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx, cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hplus->data->length; i++)
    {
        temp = abs(hplus->data->data[i] - hplusC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hcross->data->data[i] - hcrossC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseTDWaveform and ChooseTDWaveformFromCache\n");
    printf("when both must be generated from scratch...\n");
    printf("ChooseTDWaveform took %f seconds\n", diff1);
    printf("ChooseTDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    // Generate another waveform via ChooseTDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseTDWaveform(&hplus, &hcross, phiref2, dt, m1, m2,
        s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist2, inc2,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will transform previous waveform
    s2 = clock();
    ret = XLALSimInspiralChooseTDWaveformFromCache(&hplusC, &hcrossC, phiref2,
        dt, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist2, inc2,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx, cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hplus->data->length; i++)
    {
        temp = abs(hplus->data->data[i] - hplusC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hcross->data->data[i] - hcrossC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseTDWaveform and ChooseTDWaveformFromCache\n");
    printf("when the latter is cached and transformed...\n");
    printf("ChooseTDWaveform took %f seconds\n", diff1);
    printf("ChooseTDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    XLALDestroyREAL8TimeSeries(hplus);
    XLALDestroyREAL8TimeSeries(hcross);
    XLALDestroyREAL8TimeSeries(hplusC);
    XLALDestroyREAL8TimeSeries(hcrossC);


    //
    // Test FD path with TaylorF2
    //

    // Generate waveform via usual ChooseFDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde, phiref1, df,
            m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max, dist1, inc1,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will call ChooseWaveform this 1st time
    s2 = clock();
    ret = XLALSimInspiralChooseFDWaveformFromCache(&hptildeC, &hctildeC,
            phiref1, df, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max,
            dist1, inc1, lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD,
            cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hptilde->data->length; i++)
    {
        temp = abs(hptilde->data->data[i] - hptildeC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hctilde->data->data[i] - hctildeC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseFDWaveform and ChooseFDWaveformFromCache\n");
    printf("when both must be generated from scratch...\n");
    printf("ChooseFDWaveform took %f seconds\n", diff1);
    printf("ChooseFDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(hctilde);
    XLALDestroyCOMPLEX16FrequencySeries(hptildeC);
    XLALDestroyCOMPLEX16FrequencySeries(hctildeC);
    hptilde = hctilde = hptildeC = hctildeC = NULL;

    // Generate another waveform via ChooseFDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde, phiref2, df,
            m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max, dist2, inc2,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will transform previous waveform
    s2 = clock();
    ret = XLALSimInspiralChooseFDWaveformFromCache(&hptildeC, &hctildeC,
            phiref2, df, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max,
            dist2, inc2, lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD,
            cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hptilde->data->length; i++)
    {
        temp = abs(hptilde->data->data[i] - hptildeC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hctilde->data->data[i] - hctildeC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseFDWaveform and ChooseFDWaveformFromCache\n");
    printf("when the latter is cached and transformed...\n");
    printf("ChooseFDWaveform took %f seconds\n", diff1);
    printf("ChooseFDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    XLALDestroySimInspiralWaveformCache(cache);
    XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(hctilde);
    XLALDestroyCOMPLEX16FrequencySeries(hptildeC);
    XLALDestroyCOMPLEX16FrequencySeries(hctildeC);

    LALCheckMemoryLeaks();

    return 0;
}
/** Store the output TD hplus and hcross in the cache. */
static int StoreTDHCache(LALSimInspiralWaveformCache *cache,
        REAL8TimeSeries *hplus,
        REAL8TimeSeries *hcross,
        REAL8 phiRef,
        REAL8 deltaT,
        REAL8 m1, REAL8 m2,
        REAL8 S1x, REAL8 S1y, REAL8 S1z,
        REAL8 S2x, REAL8 S2y, REAL8 S2z,
        REAL8 f_min, REAL8 f_ref,
        REAL8 r,
        REAL8 i,
        LALDict *LALpars,
        Approximant approximant
        )
{
    /* Clear any frequency-domain data. */
    if (cache->hptilde != NULL) {
        XLALDestroyCOMPLEX16FrequencySeries(cache->hptilde);
        cache->hptilde = NULL;
    }

    if (cache->hctilde != NULL) {
        XLALDestroyCOMPLEX16FrequencySeries(cache->hctilde);
        cache->hctilde = NULL;
    }

    /* Store params in cache */
    cache->phiRef = phiRef;
    cache->deltaTF = deltaT;
    cache->m1 = m1;
    cache->m2 = m2;
    cache->S1x = S1x;
    cache->S1y = S1y;
    cache->S1z = S1z;
    cache->S2x = S2x;
    cache->S2y = S2y;
    cache->S2z = S2z;
    cache->f_min = f_min;
    cache->f_ref = f_ref;
    cache->r = r;
    cache->i = i;
    cache->LALpars = LALpars;
    cache->approximant = approximant;
    cache->frequencies = NULL;

    // Copy over the waveforms
    // NB: XLALCut... creates a new Series object and copies data and metadata
    XLALDestroyREAL8TimeSeries(cache->hplus);
    XLALDestroyREAL8TimeSeries(cache->hcross);
    if (hplus == NULL || hcross == NULL || hplus->data == NULL || hcross->data == NULL){
        XLALPrintError("We have null pointers for h+, hx in StoreTDHCache \n");
        XLALPrintError("Houston-S, we've got a problem SOS, SOS, SOS, the waveform generator returns NULL!!!... m1 = %.18e, m2 = %.18e, fMin = %.18e, spin1 = {%.18e, %.18e, %.18e},   spin2 = {%.18e, %.18e, %.18e} \n", 
                   m1, m2, (double)f_min, S1x, S1y, S1z, S2x, S2y, S2z);
        return XLAL_ENOMEM;
    }
    cache->hplus = XLALCutREAL8TimeSeries(hplus, 0, hplus->data->length);
    if (cache->hplus == NULL) return XLAL_ENOMEM;
    cache->hcross = XLALCutREAL8TimeSeries(hcross, 0, hcross->data->length);
    if (cache->hcross == NULL) {
        XLALDestroyREAL8TimeSeries(cache->hplus);
        cache->hplus = NULL;
        return XLAL_ENOMEM;
    }

    return XLAL_SUCCESS;
}
Exemplo n.º 25
0
REAL8 calculate_lalsim_snr(SimInspiralTable *inj, char *IFOname, REAL8FrequencySeries *psd, REAL8 start_freq)
{
  /* Calculate and return the single IFO SNR
   *
   * Required options:
   *
   * inj:     SimInspiralTable entry for which the SNR has to be calculated
   * IFOname: The canonical name (e.g. H1, L1, V1) name of the IFO for which the SNR must be calculated
   * PSD:     PSD curve to be used for the overlap integrap
   * start_freq: lower cutoff of the overlap integral
   *
   * */

  int ret=0;
  INT4 errnum=0;
  UINT4 j=0;
  /* Fill detector site info */
  LALDetector*  detector=NULL;
  detector=calloc(1,sizeof(LALDetector));
  if(!strcmp(IFOname,"H1"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLHODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"H2"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLHODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"LLO")||!strcmp(IFOname,"L1"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLLODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"V1")||!strcmp(IFOname,"VIRGO"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexVIRGODIFF],sizeof(LALDetector));

  Approximant approx=TaylorF2;
  approx=XLALGetApproximantFromString(inj->waveform);
  LALSimulationDomain modelDomain;

  if(XLALSimInspiralImplementedFDApproximants(approx)) modelDomain = LAL_SIM_DOMAIN_FREQUENCY;
  else if(XLALSimInspiralImplementedTDApproximants(approx)) modelDomain = LAL_SIM_DOMAIN_TIME;
  else
  {
      fprintf(stderr,"ERROR. Unknown approximant number %i. Unable to choose time or frequency domain model.",approx);
      exit(1);
  }

  REAL8 m1,m2, s1x,s1y,s1z,s2x,s2y,s2z,phi0,f_min,f_max,iota,polarization;

  /* No tidal PN terms until injtable is able to get them */

  LALDict *LALpars= XLALCreateDict();

  /* Spin and tidal interactions at the highest level (default) until injtable stores them.
   * When spinO and tideO are added to injtable we can un-comment those lines and should be ok
   *
  int spinO = inj->spinO;
  int tideO = inj->tideO;
  XLALSimInspiralSetSpinOrder(waveFlags, *(LALSimInspiralSpinOrder*) spinO);
  XLALSimInspiralSetTidalOrder(waveFlags, *(LALSimInspiralTidalOrder*) tideO);
  */

  XLALSimInspiralWaveformParamsInsertPNPhaseOrder(LALpars,XLALGetOrderFromString(inj->waveform));
  XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALpars,inj->amp_order);
  /* Read parameters */
  m1=inj->mass1*LAL_MSUN_SI;
  m2=inj->mass2*LAL_MSUN_SI;
  s1x=inj->spin1x;
  s1y=inj->spin1y;
  s1z=inj->spin1z;
  s2x=inj->spin2x;
  s2y=inj->spin2y;
  s2z=inj->spin2z;
  iota=inj->inclination;
  f_min=XLALSimInspiralfLow2fStart(inj->f_lower,XLALSimInspiralWaveformParamsLookupPNAmplitudeOrder(LALpars),XLALGetApproximantFromString(inj->waveform));
  phi0=inj->coa_phase;
  polarization=inj->polarization;
  REAL8 latitude=inj->latitude;
  REAL8 longitude=inj->longitude;

  LIGOTimeGPS epoch;
  memcpy(&epoch,&(inj->geocent_end_time),sizeof(LIGOTimeGPS));

  /* Hardcoded values of srate and segment length. If changed here they must also be changed in inspinj.c */
  REAL8 srate=4096.0;
  const CHAR *WF=inj->waveform;
  /* Increase srate for EOB WFs */
  if (strstr(WF,"EOB"))
    srate=8192.0;
  REAL8 segment=64.0;

  f_max=(srate/2.0-(1.0/segment));
  size_t seglen=(size_t) segment*srate;
  REAL8 deltaF=1.0/segment;
  REAL8 deltaT=1.0/srate;

  /* Frequency domain h+ and hx. They are going to be filled either by a FD WF or by the FFT of a TD WF*/
  COMPLEX16FrequencySeries *freqHplus;
  COMPLEX16FrequencySeries *freqHcross;
  freqHplus=  XLALCreateCOMPLEX16FrequencySeries("fhplus",
    &epoch,
    0.0,
    deltaF,
    &lalDimensionlessUnit,
    seglen/2+1
  );

  freqHcross=XLALCreateCOMPLEX16FrequencySeries("fhcross",
    &epoch,
    0.0,
    deltaF,
    &lalDimensionlessUnit,
    seglen/2+1
  );

  /* If the approximant is on the FD call XLALSimInspiralChooseFDWaveform */
  if (modelDomain == LAL_SIM_DOMAIN_FREQUENCY)
  {

    COMPLEX16FrequencySeries *hptilde=NULL;
    COMPLEX16FrequencySeries *hctilde=NULL;
    //We do not pass the polarization here, we assume it is taken into account when projecting h+,x onto the detector.
    XLAL_TRY(ret=XLALSimInspiralChooseFDWaveform(&hptilde,&hctilde, m1, m2,
						 s1x, s1y, s1z, s2x, s2y, s2z,
						 LAL_PC_SI * 1.0e6, iota, phi0, 0., 0., 0.,
						 deltaF, f_min, 0.0, 0.0,
						 LALpars,approx),errnum);
    XLALDestroyDict(LALpars);

    if(!hptilde|| hptilde->data==NULL || hptilde->data->data==NULL ||!hctilde|| hctilde->data==NULL || hctilde->data->data==NULL)
    {
      XLALPrintError(" ERROR in XLALSimInspiralChooseFDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum );
      exit(1);
    }

    COMPLEX16 *dataPtr = hptilde->data->data;
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      if(j < hptilde->data->length)
      {
        freqHplus->data->data[j] = dataPtr[j];
      }
      else
      {
        freqHplus->data->data[j]=0.0 + I*0.0;
      }
    }
    dataPtr = hctilde->data->data;
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      if(j < hctilde->data->length)
      {
        freqHcross->data->data[j] = dataPtr[j];
      }
      else
      {
        freqHcross->data->data[j]=0.0+0.0*I;
      }
    }
    /* Clean */
    if(hptilde) XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    if(hctilde) XLALDestroyCOMPLEX16FrequencySeries(hctilde);

  }
  else
  {

    /* Otherwise use XLALSimInspiralChooseTDWaveform */
    REAL8FFTPlan *timeToFreqFFTPlan = XLALCreateForwardREAL8FFTPlan((UINT4) seglen, 0 );
    REAL8TimeSeries *hplus=NULL;
    REAL8TimeSeries *hcross=NULL;
    REAL8TimeSeries *timeHplus=NULL;
    REAL8TimeSeries *timeHcross=NULL;
    REAL8 padding =0.4;//seconds
    REAL8Window *window=XLALCreateTukeyREAL8Window(seglen,(REAL8)2.0*padding*srate/(REAL8)seglen);
    REAL4 WinNorm = sqrt(window->sumofsquares/window->data->length);
    timeHcross=XLALCreateREAL8TimeSeries("timeModelhCross",
      &epoch,
      0.0,
      deltaT,
      &lalStrainUnit,
      seglen
    );
    timeHplus=XLALCreateREAL8TimeSeries("timeModelhplus",
      &epoch,
      0.0,
      deltaT,
      &lalStrainUnit,
      seglen
    );
    for (j=0;j<(UINT4) timeHcross->data->length;++j)
      timeHcross->data->data[j]=0.0;
    for (j=0;j<(UINT4) timeHplus->data->length;++j)
      timeHplus->data->data[j]=0.0;
    XLAL_TRY(ret=XLALSimInspiralChooseTDWaveform(&hplus, &hcross, m1, m2,
						 s1x, s1y, s1z, s2x, s2y, s2z,
						 LAL_PC_SI*1.0e6, iota,
						 phi0, 0., 0., 0., deltaT, f_min, 0.,
						 LALpars, approx),
        errnum);

    if (ret == XLAL_FAILURE || hplus == NULL || hcross == NULL)
    {
      XLALPrintError(" ERROR in XLALSimInspiralChooseTDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum );
      exit(1);
    }

    hplus->epoch  = timeHplus->epoch;
    hcross->epoch = timeHcross->epoch;

    XLALSimAddInjectionREAL8TimeSeries(timeHplus, hplus, NULL);
    XLALSimAddInjectionREAL8TimeSeries(timeHcross, hcross, NULL);
    for (j=0; j<(UINT4) timeHplus->data->length; ++j)
      timeHplus->data->data[j]*=window->data->data[j];
    for (j=0; j<(UINT4) timeHcross->data->length; ++j)
      timeHcross->data->data[j]*=window->data->data[j];
      
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      freqHplus->data->data[j]=0.0+I*0.0;
      freqHcross->data->data[j]=0.0+I*0.0;
    }

    /* FFT into freqHplus and freqHcross */
    XLALREAL8TimeFreqFFT(freqHplus,timeHplus,timeToFreqFFTPlan);
    XLALREAL8TimeFreqFFT(freqHcross,timeHcross,timeToFreqFFTPlan);
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      freqHplus->data->data[j]/=WinNorm;
      freqHcross->data->data[j]/=WinNorm;
    }
    /* Clean... */
    if ( hplus ) XLALDestroyREAL8TimeSeries(hplus);
    if ( hcross ) XLALDestroyREAL8TimeSeries(hcross);
    if ( timeHplus ) XLALDestroyREAL8TimeSeries(timeHplus);
    if ( timeHcross ) XLALDestroyREAL8TimeSeries(timeHcross);
    if (timeToFreqFFTPlan) LALFree(timeToFreqFFTPlan);
    if (window) XLALDestroyREAL8Window(window);
  }

  /* The WF has been generated and is in freqHplus/cross. Now project into the IFO frame */
  double Fplus, Fcross;
  double FplusScaled, FcrossScaled;
  double HSquared;
  double GPSdouble=(REAL8) inj->geocent_end_time.gpsSeconds+ (REAL8) inj->geocent_end_time.gpsNanoSeconds*1.0e-9;
  double gmst;
  LIGOTimeGPS GPSlal;
  XLALGPSSetREAL8(&GPSlal, GPSdouble);
  gmst=XLALGreenwichMeanSiderealTime(&GPSlal);

  /* Fill Fplus and Fcross*/
  XLALComputeDetAMResponse(&Fplus, &Fcross, (const REAL4 (*)[3])detector->response,longitude, latitude, polarization, gmst);
  /* And take the distance into account */
  FplusScaled  = Fplus  / (inj->distance);
  FcrossScaled = Fcross / (inj->distance);

  REAL8 timedelay = XLALTimeDelayFromEarthCenter(detector->location,longitude, latitude, &GPSlal);
  REAL8 timeshift =  timedelay;
  REAL8 twopit    = LAL_TWOPI * timeshift;

  UINT4 lower = (UINT4)ceil(start_freq / deltaF);
  UINT4 upper = (UINT4)floor(f_max / deltaF);
  REAL8 re = cos(twopit*deltaF*lower);
  REAL8 im = -sin(twopit*deltaF*lower);

  /* Incremental values, using cos(theta) - 1 = -2*sin(theta/2)^2 */
  REAL8 dim = -sin(twopit*deltaF);
  REAL8 dre = -2.0*sin(0.5*twopit*deltaF)*sin(0.5*twopit*deltaF);
  REAL8 TwoDeltaToverN = 2.0 *deltaT / ((double) seglen);

  REAL8 plainTemplateReal,  plainTemplateImag,templateReal,templateImag;
  REAL8 newRe, newIm,temp;
  REAL8 this_snr=0.0;
  if ( psd )
  {
    psd = XLALInterpolatePSD(psd,  deltaF);
  } 
  for (j=lower; j<=(UINT4) upper; ++j)
  {
    /* derive template (involving location/orientation parameters) from given plus/cross waveforms: */
    plainTemplateReal = FplusScaled * creal(freqHplus->data->data[j])
                        +  FcrossScaled *creal(freqHcross->data->data[j]);
    plainTemplateImag = FplusScaled * cimag(freqHplus->data->data[j])
                        +  FcrossScaled * cimag(freqHcross->data->data[j]);

    /* do time-shifting...             */
    /* (also un-do 1/deltaT scaling): */
    templateReal = (plainTemplateReal*re - plainTemplateImag*im) / deltaT;
    templateImag = (plainTemplateReal*im + plainTemplateImag*re) / deltaT;
    HSquared  = templateReal*templateReal + templateImag*templateImag ;
    temp = ((TwoDeltaToverN * HSquared) / psd->data->data[j]);
    this_snr  += temp;
    /* Now update re and im for the next iteration. */
    newRe = re + re*dre - im*dim;
    newIm = im + re*dim + im*dre;

    re = newRe;
    im = newIm;
  }

  /* Clean */
  if (freqHcross) XLALDestroyCOMPLEX16FrequencySeries(freqHcross);
  if (freqHplus) XLALDestroyCOMPLEX16FrequencySeries(freqHplus);
  if (detector) free(detector);

  return sqrt(this_snr*2.0);

}
Exemplo n.º 26
0
/* Everything needs to be declared as unused in case HDF is not enabled. */
int XLALSimInspiralNRWaveformGetHplusHcross(
        UNUSED REAL8TimeSeries **hplus,        /**< Output h_+ vector */
        UNUSED REAL8TimeSeries **hcross,       /**< Output h_x vector */
        UNUSED REAL8 phiRef,                   /**< orbital phase at reference pt. */
        UNUSED REAL8 inclination,              /**< inclination angle */
        UNUSED REAL8 deltaT,                   /**< sampling interval (s) */
        UNUSED REAL8 m1,                       /**< mass of companion 1 (kg) */
        UNUSED REAL8 m2,                       /**< mass of companion 2 (kg) */
        UNUSED REAL8 r,                        /**< distance of source (m) */
        UNUSED REAL8 fStart,                   /**< start GW frequency (Hz) */
        UNUSED REAL8 fRef,                     /**< reference GW frequency (Hz) */
        UNUSED REAL8 s1x,                      /**< initial value of S1x */
        UNUSED REAL8 s1y,                      /**< initial value of S1y */
        UNUSED REAL8 s1z,                      /**< initial value of S1z */
        UNUSED REAL8 s2x,                      /**< initial value of S2x */
        UNUSED REAL8 s2y,                      /**< initial value of S2y */
        UNUSED REAL8 s2z,                      /**< initial value of S2z */
        UNUSED const char *NRDataFile,         /**< Location of NR HDF file */
        UNUSED LALValue* ModeArray             /**< Container for the ell and m modes to generate. To generate all available modes pass NULL */
        )
{
  #ifndef LAL_HDF5_ENABLED
  XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled");
  #else
  /* Declarations */
  UINT4 curr_idx, nr_file_format;
  INT4 model, modem;
  size_t array_length;
  REAL8 nrEta;
  REAL8 S1x, S1y, S1z, S2x, S2y, S2z;
  REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s;
  REAL8 est_start_time, curr_h_real, curr_h_imag;
  REAL8 theta, psi, calpha, salpha;
  REAL8 distance_scale_fac;
  COMPLEX16 curr_ylm;
  REAL8TimeSeries *hplus_corr;
  REAL8TimeSeries *hcross_corr;

  /* These keys follow a strict formulation and cannot be longer than 11
   * characters */
  char amp_key[20];
  char phase_key[20];
  gsl_vector *tmpVector=NULL;
  LALH5File *file, *group;
  LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO;
  REAL8Vector *curr_amp, *curr_phase;

  /* Use solar masses for units. NR files will use
   * solar masses as well, so easier for that conversion
   */
  m1 = m1 / LAL_MSUN_SI;
  m2 = m2 / LAL_MSUN_SI;

  file = XLALH5FileOpen(NRDataFile, "r");
  if (file == NULL)
  {
     XLAL_ERROR(XLAL_EIO, "NR SIMULATION DATA FILE %s NOT FOUND.\n", NRDataFile);
  }

  /* Sanity checks on physical parameters passed to waveform
   * generator to guarantee consistency with NR data file.
   */
  XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta");
  if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "MASSES (%e and %e) ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION (eta=%e).\n", m1, m2, nrEta);
  }

  /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure
   * the ChooseTDWaveform() input values are consistent with the data
   * recorded in the metadata of the HDF5 file.
   * PS: This assumes that the input spins are in the LAL frame!
   */
  XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format");
  if (nr_file_format < 2)
  {
    XLALPrintInfo("This NR file is format %d. Only formats 2 and above support the use of reference frequency. For formats < 2 the reference frequency always corresponds to the start of the waveform.", nr_file_format);
    fRef = -1;
  }
  XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z,
                                                       &S2x, &S2y, &S2z,
                                                       fRef, m1+m2, file);

  if (fabs(S1x - s1x) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S1y - s1y) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S1z - s1z) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S2x - s2x) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S2y - s2y) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }

  if (fabs(S2z - s2z) > 1E-3)
  {
     XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n");
  }


  /* First estimate the length of time series that is needed.
   * Demand that 22 mode that is present and use that to figure this out
   */

  XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN");
  /* Figure out start time of data */
  group = XLALH5GroupOpen(file, "amp_l2_m2");
  ReadHDF5RealVectorDataset(group, "X", &tmpVector);
  time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0));
  time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1));
  gsl_vector_free(tmpVector);
  time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI;
  time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI;

  /* We don't want to return the *entire* waveform if it will be much longer
   * than the specified f_lower. Therefore guess waveform length using
   * the SEOBNR_ROM function and add 10% for safety.
   * FIXME: Is this correct for precessing waveforms?
   */

  if (fStart < Mflower / (m1 + m2) )
  {
    XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e",
                fStart, Mflower, Mflower / (m1 + m2));
  }

  XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format");
  if (nr_file_format > 1)
  {
    if (XLALSimInspiralNRWaveformCheckFRef(file, fStart * (m1+m2)) > 0)
    {
      /* Can use Omega array to get start time */
      est_start_time = XLALSimInspiralNRWaveformGetRefTimeFromRefFreq(file, fStart * (m1+m2)) * (m1 + m2) * LAL_MTSUN_SI;
    }
    else
    {
      /* This is the potential weird case where Omega-vs-time does not start
       * at precisely the same time as flower_at_1MSUN. This gap should be
       * small, so just use the full waveform here.
       */
      est_start_time = time_start_s;
    }
  }
  else
  {
    /* Fall back on SEOBNR chirp time estimate */
    XLALSimIMRSEOBNRv4ROMTimeOfFrequency(&est_start_time, fStart, m1 * LAL_MSUN_SI, m2 * LAL_MSUN_SI, s1z, s2z);
    est_start_time = (-est_start_time) * 1.1;
  }

  if (est_start_time > time_start_s)
  {
    /* Restrict start time of waveform */
    time_start_s = est_start_time;
    time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI);
  }

  array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT));

  /* Compute correct angles for hplus and hcross following LAL convention. */

  theta = psi = calpha = salpha = 0.;
  XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha,
                       &salpha, file, inclination, phiRef, fRef*(m1+m2));

  /* Create the return time series, use arbitrary epoch here. We set this
   * properly later. */
  XLALGPSAdd(&tmpEpoch, time_start_s);

  *hplus  = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );
  *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );

  hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );
  hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT,
                                      &lalStrainUnit, array_length );
  for (curr_idx = 0; curr_idx < array_length; curr_idx++)
  {
    hplus_corr->data->data[curr_idx] = 0.0;
    hcross_corr->data->data[curr_idx] = 0.0;
  }

  /* Create the distance scale factor */
  distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r;

  /* Generate the waveform */
  /* NOTE: We assume that for a given ell mode, all m modes are present */
  INT4 NRLmax;
  XLALH5FileQueryScalarAttributeValue(&NRLmax, file, "Lmax");

  if ( ModeArray == NULL )
  {/* Default behaviour: Generate all modes upto NRLmax */
    ModeArray = XLALSimInspiralCreateModeArray();
    for (int ell=2; ell<=NRLmax; ell++)
    {
        XLALSimInspiralModeArrayActivateAllModesAtL(ModeArray, ell);
    }
  }
  /* else Use the ModeArray given */

  for (model=2; model < (NRLmax + 1) ; model++)
  {
    for (modem=-model; modem < (model+1); modem++)
    {

      /* first check if (l,m) mode is 'activated' in the ModeArray */
      /* if activated then generate the mode, else skip this mode. */
      if (XLALSimInspiralModeArrayIsModeActive(ModeArray, model, modem) != 1)
      {
          XLAL_PRINT_INFO("SKIPPING model = %i modem = %i\n", model, modem);
          continue;
      }
      XLAL_PRINT_INFO("generateing model = %i modem = %i\n", model, modem);


      snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem);
      snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem);

      /* Check that both groups exist */
      if (XLALH5FileCheckGroupExists(file, amp_key) == 0)
      {
        continue;
      }
      if (XLALH5FileCheckGroupExists(file, phase_key) == 0)
      {
        continue;
      }

      /* Get amplitude and phase from file */
      XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2),
                                  time_start_s, array_length, deltaT, amp_key);
      XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2),
                                time_start_s, array_length, deltaT, phase_key);

      curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2,
                                                   model, modem);

      for (curr_idx = 0; curr_idx < array_length; curr_idx++)
      {
        curr_h_real = curr_amp->data[curr_idx]
                    * cos(curr_phase->data[curr_idx]) * distance_scale_fac;
        curr_h_imag = curr_amp->data[curr_idx]
                    * sin(curr_phase->data[curr_idx]) * distance_scale_fac;

        hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx]
               + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm);

        hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx]
               - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm);

      }

      XLALDestroyREAL8Vector(curr_amp);
      XLALDestroyREAL8Vector(curr_phase);

    }

  }

 /* Correct for the "alpha" angle as given in T1600045 to translate
  * from the NR wave frame to LAL wave-frame
  * Helper time series needed.
  */

  for (curr_idx = 0; curr_idx < array_length; curr_idx++)
  {
    (*hplus)->data->data[curr_idx] =
          (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx]
          - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx];

    (*hcross)->data->data[curr_idx] =
          + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx]
        + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx];
  }

  XLALDestroyREAL8TimeSeries(hplus_corr);
  XLALDestroyREAL8TimeSeries(hcross_corr);
  XLALH5FileClose(file);
  XLALDestroyValue(ModeArray);

  return XLAL_SUCCESS;
  #endif
}
Exemplo n.º 27
0
/* creates a waveform in the frequency domain; the waveform might be generated
 * in the time-domain and transformed */
int create_fd_waveform(COMPLEX16FrequencySeries ** htilde_plus, COMPLEX16FrequencySeries ** htilde_cross, struct params p)
{
    clock_t timer_start = 0;
    double chirplen, deltaF;
    int chirplen_exp;

    /* length of the chirp in samples */
    chirplen = imr_time_bound(p.f_min, p.m1, p.m2, p.s1z, p.s2z) * p.srate;
    /* make chirplen next power of two */
    frexp(chirplen, &chirplen_exp);
    chirplen = ldexp(1.0, chirplen_exp);
    deltaF = p.srate / chirplen;
    if (p.verbose)
        fprintf(stderr, "using frequency resolution deltaF = %g Hz\n", deltaF);

    if (p.condition) {
        if (p.verbose) {
            fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralFD...\n");
            timer_start = clock();
        }
        XLALSimInspiralFD(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
    } else if (p.domain == LAL_SIM_DOMAIN_FREQUENCY) {
        if (p.verbose) {
            fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralChooseFDWaveform...\n");
            timer_start = clock();
        }
        XLALSimInspiralChooseFDWaveform(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
    } else {
        REAL8TimeSeries *h_plus = NULL;
        REAL8TimeSeries *h_cross = NULL;
        REAL8FFTPlan *plan;

        /* generate time domain waveform */
        if (p.verbose) {
            fprintf(stderr, "generating waveform in time domain using XLALSimInspiralChooseTDWaveform...\n");
            timer_start = clock();
        }
        XLALSimInspiralChooseTDWaveform(&h_plus, &h_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, 1.0 / p.srate, p.f_min, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);

        /* resize the waveforms to the required length */
        XLALResizeREAL8TimeSeries(h_plus, h_plus->data->length - (size_t) chirplen, (size_t) chirplen);
        XLALResizeREAL8TimeSeries(h_cross, h_cross->data->length - (size_t) chirplen, (size_t) chirplen);

        /* put the waveform in the frequency domain */
        /* (the units will correct themselves) */
        if (p.verbose) {
            fprintf(stderr, "transforming waveform to frequency domain...\n");
            timer_start = clock();
        }
        *htilde_plus = XLALCreateCOMPLEX16FrequencySeries("htilde_plus", &h_plus->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
        *htilde_cross = XLALCreateCOMPLEX16FrequencySeries("htilde_cross", &h_cross->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
        plan = XLALCreateForwardREAL8FFTPlan((size_t) chirplen, 0);
        XLALREAL8TimeFreqFFT(*htilde_cross, h_cross, plan);
        XLALREAL8TimeFreqFFT(*htilde_plus, h_plus, plan);
        if (p.verbose)
            fprintf(stderr, "transformation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);

        /* clean up */
        XLALDestroyREAL8FFTPlan(plan);
        XLALDestroyREAL8TimeSeries(h_cross);
        XLALDestroyREAL8TimeSeries(h_plus);
    }
    return 0;
}
Exemplo n.º 28
0
/**
 * Main function for injecting numetrical relativity waveforms.
 * Takes as input a list of injections, and adds h(t) to a given
 * timeseries for a specified ifo and a dynamic range factor.
 */
void InjectNumRelWaveformsREAL8 (LALStatus      *status,       /**< pointer to LALStatus structure */
                            REAL8TimeSeries     *chan,         /**< [out] the output time series */
                            SimInspiralTable    *injections,   /**< [in] list of injections */
                            CHAR                ifo[3],        /**< [in] 2 char code for interferometer */
                            REAL8               freqLowCutoff, /**< [in] Lower cutoff frequency */
                            REAL8               snrLow,        /**< [in] lower cutoff value of snr */
                            REAL8               snrHigh,       /**< TO BE DOCUMENTED */
                            CHAR                *fname)       /**< [in] higher cutoff value of snr */
{
  SimInspiralTable *thisInj = NULL;
  REAL8 startFreq, startFreqHz, massTotal;
  REAL8 thisSNR;
  SimInspiralTable *simTableOut=NULL;
  SimInspiralTable *thisInjOut=NULL;

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);
  ASSERT( chan, status, INSPIRALH_ENULL, INSPIRALH_MSGENULL );
  ASSERT( ifo, status, INSPIRALH_ENULL, INSPIRALH_MSGENULL );


  /* loop over injections */
  for ( thisInj = injections; thisInj; thisInj = thisInj->next )
    {

      startFreq = start_freq_from_frame_url(thisInj->numrel_data);
      massTotal = (thisInj->mass1 + thisInj->mass2) * LAL_MTSUN_SI;
      startFreqHz = startFreq / ( LAL_TWOPI * massTotal);

      if (startFreqHz < freqLowCutoff)
        {
          REAL8TimeSeries *strain = NULL;
          strain  = XLALNRInjectionStrain(ifo, thisInj);
          thisSNR = calculate_ligo_snr_from_strain_real8(strain, ifo);

           /* set channel name */
           snprintf( chan->name, LALNameLength * sizeof( CHAR ),
                    "%s:STRAIN", ifo );

          if ((thisSNR < snrHigh) && (thisSNR > snrLow))
            {
              /* simTableOut will be null only the first time */
              if ( simTableOut == NULL) {
                simTableOut = (SimInspiralTable *)LALCalloc( 1, sizeof(SimInspiralTable) );
                memcpy(simTableOut, thisInj, sizeof(*thisInj));
                simTableOut->next = NULL;
                thisInjOut = simTableOut;
              }
              else {
                thisInjOut->next = (SimInspiralTable *)LALCalloc( 1, sizeof(SimInspiralTable) );
                memcpy(thisInjOut->next, thisInj, sizeof(*thisInj));
                thisInjOut->next->next = NULL;
                thisInjOut = thisInjOut->next;
              }

              XLALSimAddInjectionREAL8TimeSeries( chan, strain, NULL);
            }

          XLALDestroyREAL8TimeSeries (strain);
        }
    } /* loop over injectionsj */


  /* write and free the output simInspiral table */
  if ( simTableOut ) {

    LIGOLwXMLStream xmlfp;
    MetadataTable dummyTable;
    dummyTable.simInspiralTable = simTableOut;

    /* write the xml table of actual injections */
    memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
    TRY( LALOpenLIGOLwXMLFile( status->statusPtr, &xmlfp, fname ), status );
    TRY( LALBeginLIGOLwXMLTable( status->statusPtr, &xmlfp, sim_inspiral_table ),
              status );

    TRY( LALWriteLIGOLwXMLTable( status->statusPtr, &xmlfp, dummyTable,
                                      sim_inspiral_table ), status );

    TRY( LALEndLIGOLwXMLTable ( status->statusPtr, &xmlfp ), status );
    TRY( LALCloseLIGOLwXMLFile ( status->statusPtr, &xmlfp ), status );

  }

  while (simTableOut) {
    thisInjOut = simTableOut;
    simTableOut = simTableOut->next;
    LALFree(thisInjOut);
  }

  DETATCHSTATUSPTR(status);
  RETURN(status);

}
Exemplo n.º 29
0
/**
 * Main function for injecting numetrical relativity waveforms.
 * Takes as input a list of injections, and adds h(t) to a given
 * timeseries for a specified ifo and a dynamic range factor.
 * Updated/generalized version of InjectNumRelWaveforms that allows
 * arbitrary LIGO and Virgo PSDs and integration starting frequencies
 */
void InjectNumRelWaveformsUsingPSDREAL8(LALStatus *status,         /**< pointer to LALStatus structure */
                            REAL8TimeSeries      *chan,         /**< [out] the output time series */
                            SimInspiralTable     *injections,   /**< [in] list of injections */
                            CHAR                 ifo[3],        /**< [in] 2 char code for interferometer */
                            REAL8                freqLowCutoff, /**< [in] Lower cutoff frequency */
                            REAL8                snrLow,        /**< [in] lower cutoff value of snr */
                            REAL8                snrHigh,       /**< TO BE DOCUMENTED */
                            REAL8FrequencySeries *ligoPSD,        /**< [in] PSD to use for LIGO SNRs.  If NULL, use initial PSD */
                            REAL8                ligoSnrLowFreq,  /**< [in] Frequency at which to start integration for LIGO SNRs */
                            REAL8FrequencySeries *virgoPSD,       /**< [in] PSD to use for Virgo SNRs.  If NULL, use initial PSD */
                            REAL8                virgoSnrLowFreq, /**< [in] Frequency at which to start integration for Virgo SNRs */
                            CHAR                 *fname)       /**< [in] higher cutoff value of snr */
{
  SimInspiralTable *thisInj = NULL;
  REAL8 startFreq, startFreqHz, massTotal;
  REAL8 thisSNR;
  SimInspiralTable *simTableOut=NULL;
  SimInspiralTable *thisInjOut=NULL;

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);
  ASSERT( chan, status, INSPIRALH_ENULL, INSPIRALH_MSGENULL );
  ASSERT( ifo, status, INSPIRALH_ENULL, INSPIRALH_MSGENULL );


  /* loop over injections */
  for ( thisInj = injections; thisInj; thisInj = thisInj->next )
    {

      startFreq = start_freq_from_frame_url(thisInj->numrel_data);
      massTotal = (thisInj->mass1 + thisInj->mass2) * LAL_MTSUN_SI;
      startFreqHz = startFreq / ( LAL_TWOPI * massTotal);

      if (startFreqHz < freqLowCutoff)
        {
          REAL8TimeSeries *strain = NULL;
          strain  = XLALNRInjectionStrain(ifo, thisInj);

          if (ifo[0] == 'V')
            thisSNR = calculate_snr_from_strain_and_psd_real8( strain, virgoPSD, virgoSnrLowFreq, ifo );
          else
            thisSNR = calculate_snr_from_strain_and_psd_real8( strain, ligoPSD, ligoSnrLowFreq, ifo );

           /* set channel name */
           snprintf( chan->name, LALNameLength * sizeof( CHAR ),
                    "%s:STRAIN", ifo );

          printf("Injection at %d.%d in ifo %s has SNR %f\n",
                   thisInj->geocent_end_time.gpsSeconds,
                   thisInj->geocent_end_time.gpsNanoSeconds,
                   ifo,
                   thisSNR);

          if ((thisSNR < snrHigh) && (thisSNR > snrLow))
            {
              /* simTableOut will be null only the first time */
              if ( simTableOut == NULL) {
                simTableOut = (SimInspiralTable *)LALCalloc( 1, sizeof(SimInspiralTable) );
                memcpy(simTableOut, thisInj, sizeof(*thisInj));
                simTableOut->next = NULL;
                thisInjOut = simTableOut;
              }
              else {
                thisInjOut->next = (SimInspiralTable *)LALCalloc( 1, sizeof(SimInspiralTable) );
                memcpy(thisInjOut->next, thisInj, sizeof(*thisInj));
                thisInjOut->next->next = NULL;
                thisInjOut = thisInjOut->next;
              }

              XLALSimAddInjectionREAL8TimeSeries( chan, strain, NULL);
            }

          XLALDestroyREAL8TimeSeries (strain);
        }
      else
        {
           fprintf( stderr, "Skipping injection at %d because it turns on at %f Hz, "
                            "but the low frequency cutoff is %f\n",
                            thisInj->geocent_end_time.gpsSeconds, startFreqHz, freqLowCutoff);
        }
    } /* loop over injectionsj */


  /* write and free the output simInspiral table */
  if ( simTableOut ) {

    LIGOLwXMLStream xmlfp;
    MetadataTable dummyTable;
    dummyTable.simInspiralTable = simTableOut;

    /* write the xml table of actual injections */
    if (fname) {
      memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
      TRY( LALOpenLIGOLwXMLFile( status->statusPtr, &xmlfp, fname ), status );
      TRY( LALBeginLIGOLwXMLTable( status->statusPtr, &xmlfp, sim_inspiral_table ),
                status );

      TRY( LALWriteLIGOLwXMLTable( status->statusPtr, &xmlfp, dummyTable,
                                        sim_inspiral_table ), status );

      TRY( LALEndLIGOLwXMLTable ( status->statusPtr, &xmlfp ), status );
      TRY( LALCloseLIGOLwXMLFile ( status->statusPtr, &xmlfp ), status );
    }
  }

  while (simTableOut) {
    thisInjOut = simTableOut;
    simTableOut = simTableOut->next;
    LALFree(thisInjOut);
  }

  DETATCHSTATUSPTR(status);
  RETURN(status);

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

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

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

	/* iterate over injections */

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

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

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

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

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

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

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

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

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

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

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

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

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

	/* done */

	return 0;
}