예제 #1
0
/**
 * Evolves a post-Newtonian orbit using the Taylor T4 method.
 *
 * See:
 * Michael Boyle, Duncan A. Brown, Lawrence E. Kidder, Abdul H. Mroue,
 * Harald P. Pfeiffer, Mark A. Scheel, Gregory B. Cook, and Saul A. Teukolsky
 * "High-accuracy comparison of numerical relativity simulations with
 * post-Newtonian expansions"
 * <a href="http://arxiv.org/abs/0710.0158v2">arXiv:0710.0158v2</a>.
 */
int XLALSimInspiralTaylorT4PNEvolveOrbit(
		REAL8TimeSeries **v,            /**< post-Newtonian parameter [returned] */
		REAL8TimeSeries **phi,          /**< orbital phase [returned] */
		REAL8 phiRef,                   /**< reference orbital phase (rad) */
		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 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 O                           /**< twice post-Newtonian order */
		)
{
	const UINT4 blocklen = 1024;
	const REAL8 visco = 1./sqrt(6.);
	REAL8 VRef = 0.;
	XLALSimInspiralTaylorT4PNEvolveOrbitParams params;
	expnFuncTaylorT4 expnfunc;
	expnCoeffsTaylorT4 ak;
	expnCoeffsdEnergyFlux akdEF;

	if(XLALSimInspiralTaylorT4Setup(&ak,&expnfunc,&akdEF,m1,m2,lambda1,lambda2,
			tideO,O))
		XLAL_ERROR(XLAL_EFUNC);

	params.func=expnfunc.angacc4;
	params.ak=ak;

	REAL8 E;
	UINT4 j, len, idxRef = 0;
	LIGOTimeGPS tc = LIGOTIMEGPSZERO;
	double y[2];
	double yerr[2];
	const gsl_odeiv_step_type *T = gsl_odeiv_step_rk4;
	gsl_odeiv_step *s;
	gsl_odeiv_system sys;

	/* setup ode system */
	sys.function = XLALSimInspiralTaylorT4PNEvolveOrbitIntegrand;
	sys.jacobian = NULL;
	sys.dimension = 2;
	sys.params = &params;

	/* allocate memory */
	*v = XLALCreateREAL8TimeSeries( "ORBITAL_VELOCITY_PARAMETER", &tc, 0., deltaT, &lalDimensionlessUnit, blocklen );
	*phi = XLALCreateREAL8TimeSeries( "ORBITAL_PHASE", &tc, 0., deltaT, &lalDimensionlessUnit, blocklen );
	if ( !v || !phi )
		XLAL_ERROR(XLAL_EFUNC);

	y[0] = (*v)->data->data[0] = cbrt(LAL_PI*LAL_G_SI*ak.m*f_min)/LAL_C_SI;
	y[1] = (*phi)->data->data[0] = 0.;
	E = expnfunc.energy4(y[0],&akdEF);
	if (XLALIsREAL8FailNaN(E))
		XLAL_ERROR(XLAL_EFUNC);
	j = 0;

	s = gsl_odeiv_step_alloc(T, 2);
	while (1) {
		++j;
		gsl_odeiv_step_apply(s, j*deltaT, deltaT, y, yerr, NULL, NULL, &sys);
		/* ISCO termination condition for quadrupole, 1pN, 2.5pN */
		if ( y[0] > visco ) {
			XLALPrintInfo("XLAL Info - %s: PN inspiral terminated at ISCO\n", __func__);
			break;
		}
		if ( j >= (*v)->data->length ) {
			if ( ! XLALResizeREAL8TimeSeries(*v, 0, (*v)->data->length + blocklen) )
				XLAL_ERROR(XLAL_EFUNC);
			if ( ! XLALResizeREAL8TimeSeries(*phi, 0, (*phi)->data->length + blocklen) )
				XLAL_ERROR(XLAL_EFUNC);
		}
		(*v)->data->data[j] = y[0];
		(*phi)->data->data[j] = y[1];
	}
	gsl_odeiv_step_free(s);

	/* make the correct length */
	if ( ! XLALResizeREAL8TimeSeries(*v, 0, j) )
		XLAL_ERROR(XLAL_EFUNC);
	if ( ! XLALResizeREAL8TimeSeries(*phi, 0, j) )
		XLAL_ERROR(XLAL_EFUNC);

	/* adjust to correct time */
	XLALGPSAdd(&(*v)->epoch, -1.0*j*deltaT);
	XLALGPSAdd(&(*phi)->epoch, -1.0*j*deltaT);

	/* Do a constant phase shift to get desired value of phiRef */
	len = (*phi)->data->length;
	/* For fRef==0, phiRef is phase of last sample */
	if( fRef == 0. )
		phiRef -= (*phi)->data->data[len-1];
	/* For fRef==fmin, phiRef is phase of first sample */
	else if( fRef == f_min )
		phiRef -= (*phi)->data->data[0];
	/* phiRef is phase when f==fRef */
	else
	{
		VRef = pow(LAL_PI * LAL_G_SI*(m1+m2) * fRef, 1./3.) / LAL_C_SI;
		j = 0;
		do {
			idxRef = j;
			j++;
		} while ((*v)->data->data[j] <= VRef);
		phiRef -= (*phi)->data->data[idxRef];
	}
	for (j = 0; j < len; ++j)
		(*phi)->data->data[j] += phiRef;

	return (int)(*v)->data->length;
}
/**
 * \brief Deserializes a \c PulsarSpins array from a VOTable XML document
 *
 * This function takes a VOTable XML document and deserializes (extracts) the \c PulsarSpins array
 * (found as a \c PARAM element with the specified \c RESOURCE parent-path) identified by the given name.
 *
 * \return \c XLAL_SUCCESS if the specified \c PulsarSpins array could be found and
 * deserialized successfully.
 *
 * \sa XLALVOTXML2PulsarDopplerParamsByName
 * \sa XLALGetSingleVOTResourceParamAttribute
 *
 * \author Oliver Bock, Reinhard Prix\n
 * Albert-Einstein-Institute Hannover, Germany
 */
INT4
XLALVOTDoc2PulsarSpinsByName ( const xmlDocPtr xmlDocument,	/**< [in] Pointer to the VOTable XML document containing the array */
                               const char *resourcePath,	/**< [in] (optional) parent RESOURCE path */
                               const char *paramName,		/**< [in] Name of the PulsarSpins PARAM element */
                               PulsarSpins spins		/**< [out] Pointer to an empty \c PulsarSpins array to store the deserialized instance */
                               )
{
    /* set up local variables */
    CHAR *nodeContent = NULL;
    CHAR *nodeContentWorker = NULL;
    int arraySize = 0;
    int i;

    /* sanity check */
    if(!xmlDocument) {
        XLALPrintError("Invalid input parameters: xmlDocument\n");
        XLAL_ERROR(XLAL_EINVAL);
    }
    if(!paramName) {
        XLALPrintError("Invalid input parameters: paramName\n");
        XLAL_ERROR(XLAL_EINVAL);
    }
    if(!spins) {
        XLALPrintError("Invalid input parameters: spins\n");
        XLAL_ERROR(XLAL_EINVAL);
    }

    /* retrieve arraysize (number of pulsar spins) */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, resourcePath, paramName, VOT_PARAM, VOT_ARRAYSIZE );
    if(!nodeContent || sscanf( nodeContent, "%i", &arraySize) == EOF || arraySize == 0) {
      if(nodeContent) XLALFree(nodeContent);
      XLALPrintError("Invalid node content encountered: %s.%s.arraysize\n", resourcePath, paramName);
      XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree(nodeContent);

    /* retrieve pulsar spin array (string) */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, resourcePath, paramName, VOT_PARAM, VOT_VALUE );
    if(!nodeContent) {
      XLALPrintError("Invalid node content encountered: %s.%s\n", resourcePath, paramName);
      XLAL_ERROR(XLAL_EDATA);
    }

    /* finally, parse and store individual spin values */
    nodeContentWorker = strtok(nodeContent, " ");
    for(i = 0; i < arraySize; i++ )
      {
        /* scan current item */
        if(sscanf((char*)nodeContentWorker, "%lf", &spins[i]) == EOF) {
          XLALFree(nodeContent);
          XLALPrintError("Invalid node content encountered: %s.%s[%i]\n", resourcePath, paramName, i);
          XLAL_ERROR(XLAL_EDATA);
        }

        /* advance to next item */
        nodeContentWorker = strtok(NULL, " ");
      } /* for i < arraySize */

    /* sanity check */
    if(i != arraySize) {
      XLALFree(nodeContent);
      XLALPrintError("Invalid node content encountered: %s.%s (found %i of %i items)\n", resourcePath, paramName, i, arraySize);
      XLAL_ERROR(XLAL_EDATA);
    }

    /* clean up*/
    XLALFree(nodeContent);

    return XLAL_SUCCESS;

} /* XLALVOTDoc2PulsarSpinsByName() */
예제 #3
0
/* helper function to allocate vector in channel */
int XLALFrameUFrChanVectorAlloc_FrameL_(LALFrameUFrChan * channel, int dtype, size_t ndata)
{
    switch (channel->type) {
    case XLAL_FRAMEU_FR_CHAN_TYPE_ADC:
        /* determine bits */
        switch (dtype) {
        case FR_VECT_4S:
            channel->handle.adc->nBits = 32;
            break;
        case FR_VECT_2S:
            channel->handle.adc->nBits = 16;
            break;
        case FR_VECT_C:
            channel->handle.adc->nBits = 8;
            break;
        case FR_VECT_4R:
            channel->handle.adc->nBits = 32;
            break;
        case FR_VECT_8R:
            channel->handle.adc->nBits = 64;
            break;
        default:       /* invalid vector type for adc data */
            XLAL_ERROR(XLAL_ETYPE);
        }
        /* discard old vector (if present) */
        FrVectFree(channel->handle.adc->data);
        /* create new vector; note negative type means use malloc, not calloc */
        channel->handle.adc->data = FrVectNew1D(channel->handle.adc->name, -dtype, ndata, 0.0, NULL, NULL);
        if (!channel->handle.adc->data)
            XLAL_ERROR(XLAL_EIO, "FrVectNew1D failed");
        break;
    case XLAL_FRAMEU_FR_CHAN_TYPE_SIM:
        /* make sure type is allowed */
        switch (dtype) {
        case FR_VECT_4S:
        case FR_VECT_2S:
        case FR_VECT_C:
        case FR_VECT_4R:
        case FR_VECT_8R:
            break;
        default:       /* invalid vector type for sim data */
            XLAL_ERROR(XLAL_ETYPE);
        }
        /* discard old vector (if present) */
        FrVectFree(channel->handle.sim->data);
        /* create new vector; note negative type means use malloc, not calloc */
        channel->handle.sim->data = FrVectNew1D(channel->handle.sim->name, -dtype, ndata, 0.0, NULL, NULL);
        if (!channel->handle.sim->data)
            XLAL_ERROR(XLAL_EIO, "FrVectNew1D failed");
        break;
    case XLAL_FRAMEU_FR_CHAN_TYPE_PROC:
        /* discard old vector (if present) */
        FrVectFree(channel->handle.proc->data);
        /* create new vector; note negative type means use malloc, not calloc */
        channel->handle.proc->data = FrVectNew1D(channel->handle.proc->name, -dtype, ndata, 0.0, NULL, NULL);
        if (!channel->handle.proc->data)
            XLAL_ERROR(XLAL_EIO, "FrVectNew1D failed");
        break;
    default:   /* invalid channel type */
        XLAL_ERROR(XLAL_ETYPE);
    }
    return 0;
}
/**
 * Root function for gsl root finders.
 * The gsl root finder will look for gsl_vector *x position in parameter space
 * where the returned values in gsl_vector *f are zero.
 * The functions on which we search for roots are:
 * dH/dr, dH/dptheta and dH/dpphi-omega,
 * namely, Eqs. 4.8 and 4.9 of Buonanno et al. PRD 74, 104005 (2006).
 */
static int
XLALFindSphericalOrbitPrec(
          const gsl_vector * x,	/**<< Parameters requested by gsl root finder */
		      void *params,	        /**<< Spin EOB parameters */
		      gsl_vector * f	      /**<< Function values for the given parameters*/
)
{
	int		debugPK = 0;
	SEOBRootParams *rootParams = (SEOBRootParams *) params;
	REAL8		mTotal = rootParams->params->eobParams->m1 + rootParams->params->eobParams->m2;
	if (debugPK)
		XLAL_PRINT_INFO("\n\nmtotal in XLALFindSphericalOrbitPrec = %f\n", (float)mTotal);

	REAL8		py      , pz, r, ptheta, pphi;

	/* Numerical derivative of Hamiltonian wrt given value */
	REAL8		dHdx    , dHdpy, dHdpz;
	REAL8		dHdr    , dHdptheta, dHdpphi;

	/* Populate the appropriate values */
	/* In the special theta=pi/2 phi=0 case, r is x */
	rootParams->values[0] = r =  gsl_vector_get(x, 0)/scale1;
	rootParams->values[4] = py = gsl_vector_get(x, 1)/scale2;
	rootParams->values[5] = pz = gsl_vector_get(x, 2)/scale3;

    if(isnan(rootParams->values[0])) {
        rootParams->values[0] = 100.;
    }
    if(isnan(rootParams->values[4])) {
        rootParams->values[4] = 0.1;
    }
    if(isnan(rootParams->values[5])) {
        rootParams->values[5] = 0.01;
    }
	if (debugPK) {
    XLAL_PRINT_INFO("%3.10f %3.10f %3.10f %3.10f %3.10f %3.10f\n",
      rootParams->values[0], rootParams->values[1], rootParams->values[2],
      rootParams->values[3], rootParams->values[4], rootParams->values[5]);
    XLAL_PRINT_INFO("Values r = %.16e, py = %.16e, pz = %.16e\n", r, py, pz);
    fflush(NULL);
  }

	ptheta = -r * pz;
	pphi = r * py;

	if (debugPK)
		XLAL_PRINT_INFO("Input Values r = %.16e, py = %.16e, pz = %.16e\n pthetha = %.16e pphi = %.16e\n", r, py, pz, ptheta, pphi);

	/* dH by dR and dP */
	REAL8		tmpDValues[14];
	int UNUSED	status;
	for (int i = 0; i < 3; i++) {
		rootParams->values[i + 6] /= mTotal * mTotal;
		rootParams->values[i + 9] /= mTotal * mTotal;
	}
    UINT4 oldignoreflux = rootParams->params->ignoreflux;
    rootParams->params->ignoreflux = 1;
	status = XLALSpinPrecHcapNumericalDerivative(0, rootParams->values, tmpDValues, rootParams->params);
    rootParams->params->ignoreflux = oldignoreflux;
	for (int i = 0; i < 3; i++) {
		rootParams->values[i + 6] *= mTotal * mTotal;
		rootParams->values[i + 9] *= mTotal * mTotal;
	}
	REAL8	rvec[3] =
        {rootParams->values[0], rootParams->values[1], rootParams->values[2]};
	REAL8	pvec[3] =
        {rootParams->values[3], rootParams->values[4], rootParams->values[5]};
	REAL8	chi1vec[3] =
        {rootParams->values[6], rootParams->values[7], rootParams->values[8]};
	REAL8	chi2vec[3] =
        {rootParams->values[9], rootParams->values[10], rootParams->values[11]};
	REAL8	Lvec[3] = {CalculateCrossProductPrec(0, rvec, pvec),
    CalculateCrossProductPrec(1, rvec, pvec), CalculateCrossProductPrec(2, rvec, pvec)};
	REAL8	theta1 = acos(CalculateDotProductPrec(chi1vec, Lvec)
                / sqrt(CalculateDotProductPrec(chi1vec, chi1vec))
                / sqrt(CalculateDotProductPrec(Lvec, Lvec)));
	REAL8	theta2 = acos(CalculateDotProductPrec(chi2vec, Lvec)
                / sqrt(CalculateDotProductPrec(chi2vec, chi2vec))
                / sqrt(CalculateDotProductPrec(Lvec, Lvec)));

  if (debugPK) {
		XLAL_PRINT_INFO("rvec = %.16e %.16e %.16e\n", rvec[0], rvec[1], rvec[2]);
		XLAL_PRINT_INFO("pvec = %.16e %.16e %.16e\n", pvec[0], pvec[1], pvec[2]);
		XLAL_PRINT_INFO("theta1 = %.16e\n", theta1);
		XLAL_PRINT_INFO("theta2 = %.16e\n", theta2);
	}

  if (theta1 > 1.0e-6 && theta2 >= 1.0e-6) {
		dHdx = -tmpDValues[3];
		dHdpy = tmpDValues[1];
		dHdpz = tmpDValues[2];
	} else {
		//rootParams->values[5] = 0.;
		//rootParams->values[6] = 0.;
		//rootParams->values[7] = 0.;
		//rootParams->values[8] = sqrt(CalculateDotProductPrec(chi1vec, chi1vec));
    //rootParams->values[9] = 0.;
		//rootParams->values[10]= 0.;
		//rootParams->values[11]= sqrt(CalculateDotProductPrec(chi2vec, chi2vec));

		dHdx = XLALSpinPrecHcapNumDerivWRTParam(0,
                  rootParams->values, rootParams->params);
		dHdpy = XLALSpinPrecHcapNumDerivWRTParam(4,
                  rootParams->values, rootParams->params);
		dHdpz = XLALSpinPrecHcapNumDerivWRTParam(5,
                  rootParams->values, rootParams->params);
	}

	if (XLAL_IS_REAL8_FAIL_NAN(dHdx)) { XLAL_ERROR(XLAL_EDOM); }
	if (XLAL_IS_REAL8_FAIL_NAN(dHdpy)) { XLAL_ERROR(XLAL_EDOM); }
	if (XLAL_IS_REAL8_FAIL_NAN(dHdpz)) { XLAL_ERROR(XLAL_EDOM); }
	if (debugPK)
		XLAL_PRINT_INFO("dHdx = %.16e, dHdpy = %.16e, dHdpz = %.16e\n", dHdx, dHdpy, dHdpz);

	/* Now convert to spherical polars */
	dHdr      = dHdx - dHdpy * pphi / (r * r) + dHdpz * ptheta / (r * r);
	dHdptheta = -dHdpz / r;
	dHdpphi   = dHdpy / r;

	if (debugPK)
		XLAL_PRINT_INFO("dHdr = %.16e dHdptheta = %.16e dHdpphi = %.16e\n",
            dHdr, dHdptheta, dHdpphi);
	/* populate the function vector */
	gsl_vector_set(f, 0, dHdr);
	gsl_vector_set(f, 1, dHdptheta);
	gsl_vector_set(f, 2, dHdpphi - rootParams->omega);

	if (debugPK)
		XLAL_PRINT_INFO("Current funcvals = %.16e %.16e %.16e\n",
        gsl_vector_get(f, 0), gsl_vector_get(f, 1), gsl_vector_get(f, 2) );

  /* Rescale back */
  rootParams->values[0] *= scale1;
  rootParams->values[4] *= scale2;
  rootParams->values[5] *= scale3;

	return XLAL_SUCCESS;
}
/**
 * This function is largely based on/copied from
 * XLALAdaptiveRungeKutta4(), which exists inside the
 * lal/src/utilities/LALAdaptiveRungeKutta4.c file
 * subroutine. It reads in an array of timeseries that
 * contain data *not* evenly spaced in time
 * and performs cubic spline interpolations to resample
 * the data to uniform time sampling. Interpolations use
 * GSL's built-in routines, which recompute interpolation
 * coefficients each time the itnerpolator is called.
 * This can be extremely inefficient; in case of SEOBNRv4,
 * first data points exist at very large dt, and
 * interp. coefficients might be needlessly recomputed
 * 10,000+ times or more. We also made the optimization
 * that assumes the data are sampled at points monotone
 * in time.
 * tinit and deltat specify the desired initial time and
 *   time spacing for the output interpolated data,
 * num_input_times denotes the number of points yin arrays
 *   are sampled in time.
 * yout is the output array.
 */
UNUSED static int
SEOBNRv2OptimizedInterpolatorNoAmpPhase (REAL8Array * yin, REAL8 tinit,
					 REAL8 deltat, UINT4 num_input_times,
					 REAL8Array ** yout)
{
  int errnum = 0;

  /* needed for the final interpolation */
  gsl_spline *interp = NULL;
  gsl_interp_accel *accel = NULL;
  int outputlen = 0;
  REAL8Array *output = NULL;
  REAL8 *times, *vector;	/* aliases */

  /* needed for the integration */
  size_t dim = 4;
  
  interp = gsl_spline_alloc (gsl_interp_cspline, num_input_times);
  accel = gsl_interp_accel_alloc ();

  outputlen = (int) (yin->data[num_input_times - 1] / deltat) + 1;
  output = XLALCreateREAL8ArrayL (2, dim + 1, outputlen);	/* Only dim + 1 rather than dim + 3 since we're not adding amp & phase */

  if (!interp || !accel || !output)
    {
      errnum = XLAL_ENOMEM;	/* ouch again, ran out of memory */
      if (output)
	XLALDestroyREAL8Array (output);
      outputlen = 0;
      goto bail_out;
    }

  /* make an array of times */
  times = output->data;
  for (int j = 0; j < outputlen; j++)
    times[j] = tinit + deltat * j;

  /* interpolate! */
  for (unsigned int i = 1; i <= dim; i++)
    {				/* only up to dim (4) because we are not interpolating amplitude and phase */
      //gsl_spline_init(interp, &yin->data[0], &yin->data[num_input_times * i], num_input_times + 1);
      gsl_spline_init (interp, &yin->data[0], &yin->data[num_input_times * i],
		       num_input_times);

      vector = output->data + outputlen * i;
      unsigned int index_old = 0;
      double x_lo_old = 0, y_lo_old = 0, b_i_old = 0, c_i_old = 0, d_i_old =
	0;
      for (int j = 0; j < outputlen; j++)
	{
	  optimized_gsl_spline_eval_e (interp, times[j], accel, &(vector[j]),
				       &index_old, &x_lo_old, &y_lo_old,
				       &b_i_old, &c_i_old, &d_i_old);
	}
    }

  /* deallocate stuff and return */
bail_out:

  if (interp)
    XLAL_CALLGSL (gsl_spline_free (interp));
  if (accel)
    XLAL_CALLGSL (gsl_interp_accel_free (accel));

  if (errnum)
    XLAL_ERROR (errnum);

  *yout = output;
  return outputlen;
}
예제 #6
0
static int IMRPhenomCGenerateFDForTD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 t0,					   /**< time of coalescence */
    const REAL8 phi0,                  /**< phase at peak */
    const REAL8 deltaF,                /**< frequency resolution */
    const REAL8 m1,                    /**< mass of companion 1 [solar masses] */
    const REAL8 m2,                    /**< mass of companion 2 [solar masses] */
    //const REAL8 chi,                   /**< mass-weighted aligned-spin parameter */
    const REAL8 f_min,                 /**< start frequency */
    const REAL8 f_max,                 /**< end frequency */
    const REAL8 distance,              /**< distance to source (m) */
    const BBHPhenomCParams *params,    /**< from ComputeIMRPhenomCParams */
    const size_t nf                    /**< Length of frequency vector required */
) {
  static LIGOTimeGPS ligotimegps_zero = {0, 0};
  size_t i;
  INT4 errcode;

  const REAL8 M = m1 + m2;
  const REAL8 eta = m1 * m2 / (M * M);

  /* Memory to temporarily store components of amplitude and phase */
  /*
  REAL8 phSPA, phPM, phRD, aPM, aRD;
  REAL8 wPlusf1, wPlusf2, wMinusf1, wMinusf2, wPlusf0, wMinusf0;
  */
  REAL8 phPhenomC = 0.0;
  REAL8 aPhenomC = 0.0;

  /* compute the amplitude pre-factor */
  REAL8 amp0 = 2. * sqrt(5. / (64.*LAL_PI)) * M * LAL_MRSUN_SI * M * LAL_MTSUN_SI / distance;

  /* allocate htilde */
  size_t n = NextPow2_PC(f_max / deltaF) + 1;
  if ( n > nf )
    XLAL_ERROR(XLAL_EDOM, "The required length passed as input wont fit the FD waveform\n");
  else
    n = nf;
  *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &ligotimegps_zero, 0.0,
      deltaF, &lalStrainUnit, n);
  memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16));
  XLALUnitMultiply(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit);
  if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC);

  /* now generate the waveform */
  size_t ind_max = (size_t) (f_max / deltaF);
  for (i = (size_t) (f_min / deltaF); i < ind_max; i++)
  {
    REAL8 f = i * deltaF;

    errcode = IMRPhenomCGenerateAmpPhase( &aPhenomC, &phPhenomC, f, eta, params );
    if( errcode != XLAL_SUCCESS )
      XLAL_ERROR(XLAL_EFUNC);
    phPhenomC -= 2.*phi0; // factor of 2 b/c phi0 is orbital phase
    phPhenomC += 2.*LAL_PI*f*t0; //shifting the coalescence to t=t0

    /* generate the waveform */
    ((*htilde)->data->data)[i] = amp0 * aPhenomC * cos(phPhenomC);
    ((*htilde)->data->data)[i] += -I * amp0 * aPhenomC * sin(phPhenomC);
  }

  return XLAL_SUCCESS;
}
예제 #7
0
REAL8 MatchSI(COMPLEX16FrequencySeries **htilde1, COMPLEX16FrequencySeries **htilde2, REAL8 fMin, REAL8 fMax, REAL8 df) {
  // Frequencies are in Hz!

  // Assume that waveforms use same frequency points
  int len1 = (*htilde1)->data->length;
  int len2 = (*htilde1)->data->length;
  if (len1 != len2) {
    XLALPrintError("Length of waveforms differs!\n");
    XLAL_ERROR(XLAL_EDOM); // FIXME
  }
  int n = len1;

  fftw_complex *integrand;
  integrand = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);
  REAL8 PSDfact = XLALSimNoisePSDaLIGOZeroDetHighPower((fMax-fMin)/4.);
  REAL8 tableS;
  COMPLEX16 h1,h2;

  REAL8 norm1 = 0.0;
  REAL8 norm2 = 0.0;
  int iStart = (int)(fMin / df);
  int iStop = (int)(fMax / df);
  iStart = (iStart < 1) ? 1 : iStart;
  iStop = (iStop > n) ? n : iStop;
  for (int i=iStart; i<iStop; i++) {
    REAL8 f = i*df;
    tableS = PSDfact / XLALSimNoisePSDaLIGOZeroDetHighPower(f);
    h1 = ((*htilde1)->data->data)[i];
    h2 = ((*htilde2)->data->data)[i];
    integrand[i] = h1 * conj(h2) * tableS;
    norm1 += sqr(cabs(h1)) * tableS;
    norm2 += sqr(cabs(h2)) * tableS;
    // printf("f = %g\tnoise(f) = %g\ttableS[i] = %g\tintegrand[i] = %g\n", f, XLALSimNoisePSDaLIGOZeroDetHighPower(f), tableS, creal(integrand[i]));
    // printf("{norm1, norm2} = {%g,%g}\t{%g,%g}\n", norm1,norm2, cabs(h1)*tableS, cabs(h2)*tableS);
  }

  n = iStop-iStart;
  int zpf = 10;
  int m = n + 2*zpf*n; // zero-pad on both sides
  //printf("Total length %d\n", m);
  fftw_complex *array;
  fftw_plan p;
  array = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * m);
  p = fftw_plan_dft_1d(m, array, array, FFTW_FORWARD, FFTW_ESTIMATE); // prepare in-place FFT

  // fill input array
  for (int i=0; i<zpf*n; i++)
    array[i] = 0.0;
  for (int i=zpf*n; i<(zpf*n + n); i++)
    array[i] = integrand[iStart + i-zpf*n];
  for (int i=zpf*n + n; i<m; i++)
    array[i] = 0.0;

  fftw_execute(p);

  REAL8 match=0; REAL8 val;
  for (int i=0; i<m; i++) {
    val = cabs(array[i]);
    if (val > match)
      match = val;
  }

  fftw_destroy_plan(p);
  fftw_free(array);
  fftw_free(integrand);

  return match / sqrt(norm1*norm2);
}
예제 #8
0
int XLALNormalDeviates( REAL4Vector *deviates, RandomParams *params )
{
  REAL4 *data;
  INT4   half;

  if ( ! deviates || ! deviates->data || ! params )
    XLAL_ERROR( XLAL_EFAULT );
  if ( ! deviates->length )
    XLAL_ERROR( XLAL_EBADLEN );

  data = deviates->data;
  half = deviates->length/2;

  while (half-- > 0)
  {
    REAL4 u;
    REAL4 v;
    REAL4 x;
    REAL4 y;
    REAL4 rsq;
    REAL4 fac;

    do {
      u = XLALUniformDeviate( params );
      v = XLALUniformDeviate( params );
      x   = 2*u - 1;
      y   = 2*v - 1;
      rsq = x*x + y*y;
    }
    while (rsq >= 1 || rsq == 0);

    fac     = sqrt(-2*log(rsq)/rsq);
    *data++ = fac*x;
    *data++ = fac*y;
  }

  /* do it again if there is an odd amount of data */
  if (deviates->length % 2)
  {
    REAL4 u;
    REAL4 v;
    REAL4 x;
    REAL4 y;
    REAL4 rsq;
    REAL4 fac;

    do {
      u = XLALUniformDeviate( params );
      v = XLALUniformDeviate( params );
      x   = 2*u - 1;
      y   = 2*v - 1;
      rsq = x*x + y*y;
    }
    while (rsq >= 1 || rsq == 0);

    fac   = sqrt(-2*log(rsq)/rsq);
    *data = fac*x;
    /* throw away y */
  }

  return XLAL_SUCCESS;
}
/**
 * Computes the stationary phase approximation to the Fourier transform of
 * a chirp waveform with phase given by \eqref{eq_InspiralFourierPhase_f2}
 * and amplitude given by expanding \f$1/\sqrt{\dot{F}}\f$. If the PN order is
 * set to -1, then the highest implemented order is used.
 *
 * See arXiv:0810.5336 and arXiv:astro-ph/0504538 for spin corrections
 * to the phasing.
 * See arXiv:1303.7412 for spin-orbit phasing corrections at 3 and 3.5PN order
 */
int XLALSimInspiralSpinTaylorF2(
        COMPLEX16FrequencySeries **hplus_out,  /**< FD hplus waveform */
        COMPLEX16FrequencySeries **hcross_out, /**< FD hcross waveform */
        const REAL8 phi_ref,                   /**< reference orbital phase (rad) */
        const REAL8 deltaF,                    /**< frequency resolution */
        const REAL8 m1_SI,                     /**< mass of companion 1 (kg) */
        const REAL8 m2_SI,                     /**< mass of companion 2 (kg) */
        const REAL8 s1x,                             /**< initial value of S1x */
        const REAL8 s1y,                             /**< initial value of S1y */
        const REAL8 s1z,                             /**< initial value of S1z */
        const REAL8 lnhatx,                          /**< initial value of LNhatx */
        const REAL8 lnhaty,                          /**< initial value of LNhaty */
        const REAL8 lnhatz,                          /**< initial value of LNhatz */
        const REAL8 fStart,                    /**< start GW frequency (Hz) */
        const REAL8 fEnd,                      /**< highest GW frequency (Hz) of waveform generation - if 0, end at Schwarzschild ISCO */
        const REAL8 f_ref,                     /**< Reference GW frequency (Hz) - if 0 reference point is coalescence */
        const REAL8 r,                         /**< distance of source (m) */
	LALDict *moreParams, /**< Linked list of extra. Pass in NULL (or None in python) for standard waveform. Set "sideband",m to get a single sideband (m=-2..2) */
        const INT4 phaseO,                     /**< twice PN phase order */
        const INT4 amplitudeO                  /**< twice PN amplitude order */
        )
{
    /* external: SI; internal: solar masses */
    const REAL8 m1 = m1_SI / LAL_MSUN_SI;
    const REAL8 m2 = m2_SI / LAL_MSUN_SI;
    const REAL8 m = m1 + m2;
    const REAL8 m_sec = m * LAL_MTSUN_SI;  /* total mass in seconds */
    const REAL8 eta = m1 * m2 / (m * m);
    const REAL8 piM = LAL_PI * m_sec;
    const REAL8 vISCO = 1. / sqrt(6.);
    const REAL8 fISCO = vISCO * vISCO * vISCO / piM;
    REAL8 shft, amp0, f_max;
    size_t i, n, iStart;
    COMPLEX16 *data_plus = NULL;
    COMPLEX16 *data_cross = NULL;
    LIGOTimeGPS tC = {0, 0};

    /* If f_ref = 0, use f_ref = f_low for everything except the phase offset */
    const REAL8 v_ref = f_ref > 0. ? cbrt(piM*f_ref) : cbrt(piM*fStart);

    REAL8 alpha, alpha_ref;
    COMPLEX16 prec_plus, prec_cross, phasing_fac;
    bool enable_precession = true; /* Handle the non-spinning case separately */
    int mm;

    LALSimInspiralSF2Orientation orientation;
    XLALSimInspiralSF2CalculateOrientation(&orientation, m1, m2, v_ref, lnhatx, lnhaty, lnhatz, s1x, s1y, s1z);

    LALSimInspiralSF2Coeffs coeffs;
    XLALSimInspiralSF2CalculateCoeffs(&coeffs, m1, m2, orientation.chi, orientation.kappa);
    enable_precession = orientation.chi != 0. && orientation.kappa != 1. && orientation.kappa != -1.;

    alpha_ref = enable_precession ? XLALSimInspiralSF2Alpha(v_ref, coeffs) - orientation.alpha0 : 0.;

    COMPLEX16 SBplus[5]; /* complex sideband factors for plus pol, mm=2 is first entry */
    COMPLEX16 SBcross[5]; /* complex sideband factors for cross pol, mm=2 is first entry */
    REAL8 emission[5]; /* emission factor for each sideband */
    if ( !XLALSimInspiralWaveformParamsSidebandIsDefault(moreParams))
    {
        for(mm = -2; mm <= 2; mm++)
        {
            SBplus[2-mm] = XLALSimInspiralSF2Polarization(orientation.thetaJ, orientation.psiJ, mm);
            SBcross[2-mm] = XLALSimInspiralSF2Polarization(orientation.thetaJ, orientation.psiJ+LAL_PI/4., mm);
        }
    }
    else
    {
        memset(SBplus, 0, 5 * sizeof(COMPLEX16));
        memset(SBcross, 0, 5 * sizeof(COMPLEX16));
        mm = (int) XLALSimInspiralWaveformParamsLookupSideband(moreParams);
        SBplus[2-mm] = XLALSimInspiralSF2Polarization(orientation.thetaJ, orientation.psiJ, mm);
        SBcross[2-mm] = XLALSimInspiralSF2Polarization(orientation.thetaJ, orientation.psiJ+LAL_PI/4., mm);
    }

    const REAL8 chi1L = orientation.chi*orientation.kappa;
    const REAL8 chi1sq = orientation.chi*orientation.chi;
    /* FIXME: Cannot yet set QM constant in ChooseFDWaveform interface */
    /* phasing coefficients */
    PNPhasingSeries pfa;
    XLALSimInspiralPNPhasing_F2(&pfa, m1, m2, chi1L, 0., chi1sq, 0., 0., moreParams);

    REAL8 pfaN = 0.; REAL8 pfa1 = 0.;
    REAL8 pfa2 = 0.; REAL8 pfa3 = 0.; REAL8 pfa4 = 0.;
    REAL8 pfa5 = 0.; REAL8 pfl5 = 0.;
    REAL8 pfa6 = 0.; REAL8 pfl6 = 0.;
    REAL8 pfa7 = 0.; REAL8 pfa8 = 0.;

    switch (phaseO)
    {
        case -1:
        case 7:
            pfa7 = pfa.v[7];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 6:
            pfa6 = pfa.v[6];
            pfl6 = pfa.vlogv[6];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 5:
            pfa5 = pfa.v[5];
            pfl5 = pfa.vlogv[5];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 4:
            pfa4 = pfa.v[4];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 3:
            pfa3 = pfa.v[3];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 2:
            pfa2 = pfa.v[2];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 1:
            pfa1 = pfa.v[1];
#if __GNUC__ >= 7
            __attribute__ ((fallthrough));
#endif
        case 0:
            pfaN = pfa.v[0];
            break;
        default:
            XLAL_ERROR(XLAL_ETYPE, "Invalid phase PN order %d", phaseO);
    }

    /* Add the zeta factor to the phasing, since it looks like a pN series.
     * This is the third Euler angle after alpha and beta.
     */
    if (enable_precession)
    {
        pfa2 += 2.*coeffs.prec_fac*coeffs.zc[0];
        pfa3 += 2.*coeffs.prec_fac*coeffs.zc[1];
        pfa4 += 2.*coeffs.prec_fac*coeffs.zc[2];
        pfl5 += 2.*coeffs.prec_fac*coeffs.zc[3];
        pfa6 += 2.*coeffs.prec_fac*coeffs.zc[4];
        pfa7 += 2.*coeffs.prec_fac*coeffs.zc[5];
        pfa8 += 2.*coeffs.prec_fac*coeffs.zc[6];
    }

    /* Validate expansion order arguments.
     * This must be done here instead of in the OpenMP parallel loop
     * because when OpenMP parallelization is turned on, early exits
     * from loops (via return or break statements) are not permitted.
     */

    /* Validate amplitude PN order. */
    if (amplitudeO != 0) { XLAL_ERROR(XLAL_ETYPE, "Invalid amplitude PN order %d", amplitudeO); }

    /* energy coefficients - not currently used, but could for MECO
    const REAL8 dETaN = 2. * XLALSimInspiralPNEnergy_0PNCoeff(eta);
    const REAL8 dETa1 = 2. * XLALSimInspiralPNEnergy_2PNCoeff(eta);
    const REAL8 dETa2 = 3. * XLALSimInspiralPNEnergy_4PNCoeff(eta);
    const REAL8 dETa3 = 4. * XLALSimInspiralPNEnergy_6PNCoeff(eta);
    */

    COMPLEX16FrequencySeries *hplus;
    COMPLEX16FrequencySeries *hcross;

    /* Perform some initial checks */
    if (!hplus_out) XLAL_ERROR(XLAL_EFAULT);
    if (!hcross_out) XLAL_ERROR(XLAL_EFAULT);
    if (*hplus_out) XLAL_ERROR(XLAL_EFAULT);
    if (*hcross_out) XLAL_ERROR(XLAL_EFAULT);
    if (m1_SI <= 0) XLAL_ERROR(XLAL_EDOM);
    if (m2_SI <= 0) XLAL_ERROR(XLAL_EDOM);
    if (fStart <= 0) XLAL_ERROR(XLAL_EDOM);
    if (f_ref < 0) XLAL_ERROR(XLAL_EDOM);
    if (r <= 0) XLAL_ERROR(XLAL_EDOM);

    /* allocate htilde */
    if ( fEnd == 0. ) // End at ISCO
        f_max = fISCO;
    else // End at user-specified freq.
        f_max = fEnd;
    n = (size_t) (f_max / deltaF + 1);
    XLALGPSAdd(&tC, -1 / deltaF);  /* coalesce at t=0 */
    /* Allocate hplus and hcross */
    hplus = XLALCreateCOMPLEX16FrequencySeries("hplus: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, n);
    if (!hplus) XLAL_ERROR(XLAL_EFUNC);
    memset(hplus->data->data, 0, n * sizeof(COMPLEX16));
    XLALUnitMultiply(&hplus->sampleUnits, &hplus->sampleUnits, &lalSecondUnit);
    hcross = XLALCreateCOMPLEX16FrequencySeries("hcross: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, n);
    if (!hcross) XLAL_ERROR(XLAL_EFUNC);
    memset(hcross->data->data, 0, n * sizeof(COMPLEX16));
    XLALUnitMultiply(&hcross->sampleUnits, &hcross->sampleUnits, &lalSecondUnit);

    /* extrinsic parameters */
    amp0 = -4. * m1 * m2 / r * LAL_MRSUN_SI * LAL_MTSUN_SI * sqrt(LAL_PI/12.L);
    amp0 *= sqrt(-2. * XLALSimInspiralPNEnergy_0PNCoeff(eta)/XLALSimInspiralPNFlux_0PNCoeff(eta));
    shft = LAL_TWOPI * (tC.gpsSeconds + 1e-9 * tC.gpsNanoSeconds);

    /* Fill with non-zero vals from fStart to f_max */
    iStart = (size_t) ceil(fStart / deltaF);
    data_plus = hplus->data->data;
    data_cross = hcross->data->data;

    /* Compute the SPA phase at the reference point */
    REAL8 ref_phasing = 0.;
    if (f_ref > 0.)
    {
        const REAL8 logvref = log(v_ref);
        const REAL8 v2ref = v_ref * v_ref;
        const REAL8 v3ref = v_ref * v2ref;
        const REAL8 v4ref = v_ref * v3ref;
        const REAL8 v5ref = v_ref * v4ref;
        ref_phasing = (pfaN + pfa1 * v_ref +pfa2 * v2ref + pfa3 * v3ref + pfa4 * v4ref) / v5ref + (pfa5 + pfl5 * logvref) + (pfa6 + pfl6 * logvref) * v_ref + pfa7 * v2ref + pfa8 * v3ref;
    } /* end of if (f_ref > 0.) */

    #pragma omp parallel for
    for (i = iStart; i < n; i++) {
        const REAL8 f = i * deltaF;
        const REAL8 v = cbrt(piM*f);
        const REAL8 logv = log(v);
        const REAL8 v2 = v * v;
        const REAL8 v3 = v * v2;
        const REAL8 v4 = v * v3;
        const REAL8 v5 = v * v4;
        REAL8 phasing = (pfaN + pfa1*v + pfa2 * v2 + pfa3 * v3 + pfa4 * v4) / v5 + (pfa5 + pfl5 * logv) + (pfa6 + pfl6 * logv) * v + pfa7 * v2 + pfa8 * v3;
        COMPLEX16 amp = amp0 / (v3 * sqrt(v));

        alpha = enable_precession ? XLALSimInspiralSF2Alpha(v, coeffs) - alpha_ref : 0.;

        COMPLEX16 u = cos(alpha) + 1.0j*sin(alpha);
        XLALSimInspiralSF2Emission(emission, v, coeffs);
        prec_plus = SBplus[0]*emission[0]*u*u
                    + SBplus[1]*emission[1]*u
                    + SBplus[2]*emission[2]
                    + SBplus[3]*emission[3]/u
                    + SBplus[4]*emission[4]/u/u;
        prec_cross= SBcross[0]*emission[0]*u*u
                    + SBcross[1]*emission[1]*u
                    + SBcross[2]*emission[2]
                    + SBcross[3]*emission[3]/u
                    + SBcross[4]*emission[4]/u/u;
        // Note the factor of 2 b/c phi_ref is orbital phase
        phasing += shft * f - 2.*phi_ref - ref_phasing - LAL_PI_4;
        phasing_fac = cos(phasing) - 1.0j*sin(phasing);
        data_plus[i] = amp * prec_plus * phasing_fac;
        data_cross[i] = amp * prec_cross * phasing_fac;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

         REAL4 detPhaseArg = 0.0, detPhaseMag = 0.0;
         BOOLEAN loopbroken = 0;
         for (INT4 jj=0; jj<16 && !loopbroken; jj++) {
            REAL4 psi = 0.0625*jj*LAL_PI;
            Fplus0 = multiAMcoefficients->data[0]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[0]->b->data[ii]*sin(2.0*psi);
            Fcross0 = multiAMcoefficients->data[0]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[0]->a->data[ii]*sin(2.0*psi);
            Fplus1 = multiAMcoefficients->data[1]->a->data[ii]*cos(2.0*psi) + multiAMcoefficients->data[1]->b->data[ii]*sin(2.0*psi);
            Fcross1 = multiAMcoefficients->data[1]->b->data[ii]*cos(2.0*psi) - multiAMcoefficients->data[1]->a->data[ii]*sin(2.0*psi);
            for (INT4 kk=0; kk<21 && !loopbroken; kk++) {
               REAL4 cosi = 1.0 - 2.0*0.05*kk;
               if (!uvar.unrestrictedCosi) {
                  if (cosi0<0.0) cosi = -0.05*kk;
                  else cosi = 0.05*kk;
               }
               COMPLEX16 complexnumerator = crect(0.5*Fplus1*(1.0+cosi*cosi), Fcross1*cosi);
               COMPLEX16 complexdenominator = crect(0.5*Fplus0*(1.0+cosi*cosi) , Fcross0*cosi);
               if (cabs(complexdenominator)>1.0e-6) {
                  COMPLEX16 complexval = complexnumerator/complexdenominator;
                  detPhaseMag += fmin(cabs(complexval), 10.0);
                  detPhaseArg += gsl_sf_angle_restrict_pos(carg(complexval));
               } else {
                  loopbroken = 1;
                  detPhaseMag = 0.0;
                  detPhaseArg = 0.0;
               }
            }
         }
         detPhaseMag /= 336.0;
         detPhaseArg /= 336.0;
         COMPLEX16 RatioTerm = cpolar(detPhaseMag, detPhaseArg);

         //Bin of interest
         REAL8 signalFrequencyBin = round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft) - frequency*uvar.Tsft;  //estimated nearest freq in ref IFO

         REAL8 timediff0 = multissb->data[0]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[0]->Tdot->data[ii];
         REAL8 timediff1 = multissb->data[1]->DeltaT->data[ii] - 0.5*uvar.Tsft*multissb->data[1]->Tdot->data[ii];
         REAL8 tau = timediff1 - timediff0;
         REAL8 freqshift0 = -LAL_TWOPI*tau*frequency0;  //real freq shift
         REAL8 freqshift = -LAL_TWOPI*tau*(round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft)/uvar.Tsft);    //estimated freq shift
         COMPLEX16 phaseshift0 = cpolar(1.0, freqshift0);
         COMPLEX16 phaseshift = cpolar(1.0, freqshift);

         REAL8 delta0_0 = (multissb->data[0]->Tdot->data[ii]*frequency0-frequency)*uvar.Tsft - signalFrequencyBin;
         REAL8 delta1_0 = (multissb->data[1]->Tdot->data[ii]*frequency0-frequency)*uvar.Tsft - signalFrequencyBin;
         REAL8 realSigBinDiff = round(delta0_0) - round(delta1_0);
         delta1_0 += realSigBinDiff;
         REAL8 delta0 = round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft)*(multissb->data[0]->Tdot->data[ii] - 1.0);
         REAL8 delta1 = round(multissb->data[0]->Tdot->data[ii]*frequency0*uvar.Tsft)*(multissb->data[1]->Tdot->data[ii] - 1.0);
         REAL8 estSigBinDiff = round(delta0) - round(delta1);
         delta1 += estSigBinDiff;
         COMPLEX16 dirichlet0;
         if (!uvar.rectWindow) {
            if (fabsf((REAL4)delta1_0)<(REAL4)1.0e-6) {
               if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = crect(1.0, 0.0);
               else if (fabsf((REAL4)(delta0_0*delta0_0-1.0))<(REAL4)1.0e-6) dirichlet0 = crect(-2.0, 0.0);
               else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) {
                  dirichlet0 = crect(0.0, 0.0);
                  continue;
               }
	       else dirichlet0 = -LAL_PI*crectf(cos(LAL_PI*delta0_0), -sin(LAL_PI*delta0_0))*delta0_0*(delta0_0*delta0_0 - 1.0)/sin(LAL_PI*delta0_0);
            }
            else if (fabsf((REAL4)(delta1_0*delta1_0-1.0))<(REAL4)1.0e-6) {
               if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = crect(-0.5, 0.0);
               else if (fabsf((REAL4)(delta0_0*delta0_0-1.0))<(REAL4)1.0e-6) dirichlet0 = crect(1.0, 0.0);
               else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) {
                  dirichlet0 = crect(0.0, 0.0);
                  continue;
               }
	       else dirichlet0 = -LAL_PI_2*crectf(-cos(LAL_PI*delta0_0), sin(LAL_PI*delta0_0))*delta0_0*(delta0_0*delta0_0 - 1.0)/sin(LAL_PI*delta0_0);
            }
            else if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = -LAL_1_PI*crectf(cos(LAL_PI*delta1_0), sin(LAL_PI*delta1_0))*sin(LAL_PI*delta1_0)/(delta1_0*(delta1_0*delta1_0-1.0));
            else if (fabsf((REAL4)(delta0_0*delta0_0-1.0))<(REAL4)1.0e-6) dirichlet0 = LAL_2_PI*crectf(cos(LAL_PI*delta1_0), sin(LAL_PI*delta1_0))*sin(LAL_PI*delta1_0)/(delta1_0*(delta1_0*delta1_0-1.0));
            else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) {
               dirichlet0 = crect(0.0, 0.0);
               continue;
            }
            else dirichlet0 = sin(LAL_PI*delta1_0)/sin(LAL_PI*delta0_0)*(delta0_0*(delta0_0*delta0_0-1.0))/(delta1_0*(delta1_0*delta1_0-1.0))*cpolarf(1.0,LAL_PI*(delta1_0-delta0_0));
         } else {
            if (fabsf((REAL4)delta1_0)<(REAL4)1.0e-6) {
               if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = crect(1.0, 0.0);
               else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) {
                  dirichlet0 = crect(0.0, 0.0);
                  continue;
               }
               else dirichlet0 = conj(1.0/((cpolar(1.0,LAL_TWOPI*delta0_0)-1.0)/crect(0.0,LAL_TWOPI*delta0_0)));
            }
            else if (fabsf((REAL4)delta0_0)<(REAL4)1.0e-6) dirichlet0 = conj((cpolar(1.0,LAL_TWOPI*delta1_0)-1.0)/crect(0.0,LAL_TWOPI*delta1_0));
            else if (fabsf((REAL4)(delta0_0-roundf(delta0_0)))<(REAL4)1.0e-6) {
               dirichlet0 = crect(0.0, 0.0);
               continue;
            }
            else dirichlet0 = conj(((cpolar(1.0,LAL_TWOPI*delta1_0)-1.0)/crect(0.0,LAL_TWOPI*delta1_0))/((cpolar(1.0,LAL_TWOPI*delta0_0)-1.0)/crect(0.0,LAL_TWOPI*delta0_0)));
         }

         COMPLEX16 dirichlet;
         if (!uvar.rectWindow) {
            if (fabsf((REAL4)delta1)<(REAL4)1.0e-6) {
               if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = crect(1.0, 0.0);
               else if (fabsf((REAL4)(delta0*delta0-1.0))<(REAL4)1.0e-6) dirichlet = crect(-2.0, 0.0);
               else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0);
               else dirichlet = -LAL_PI*crectf(cos(LAL_PI*delta0), -sin(LAL_PI*delta0))*delta0*(delta0*delta0 - 1.0)/sin(LAL_PI*delta0);
            }
            else if (fabsf((REAL4)(delta1*delta1-1.0))<(REAL4)1.0e-6) {
               if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = crect(-0.5, 0.0);
               else if (fabsf((REAL4)(delta0*delta0-1.0))<(REAL4)1.0e-6) dirichlet = crect(1.0, 0.0);
               else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0);
               else dirichlet = -LAL_PI_2*crectf(-cos(LAL_PI*delta0), sin(LAL_PI*delta0))*delta0*(delta0*delta0 - 1.0)/sin(LAL_PI*delta0);
            }
            else if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = -LAL_1_PI*crectf(cos(LAL_PI*delta1), sin(LAL_PI*delta1))*sin(LAL_PI*delta1)/(delta1*(delta1*delta1-1.0));
            else if (fabsf((REAL4)(delta0*delta0-1.0))<(REAL4)1.0e-6) dirichlet = LAL_2_PI*crectf(cos(LAL_PI*delta1), sin(LAL_PI*delta1))*sin(LAL_PI*delta1)/(delta1*(delta1*delta1-1.0));
            else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0);
            else dirichlet = sin(LAL_PI*delta1)/sin(LAL_PI*delta0)*(delta0*(delta0*delta0-1.0))/(delta1*(delta1*delta1-1.0))*cpolarf(1.0,LAL_PI*(delta1-delta0));
         } else {
            if (fabsf((REAL4)delta1)<(REAL4)1.0e-6) {
               if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = crect(1.0, 0.0);
               else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0);
               else dirichlet = conj(1.0/((cpolar(1.0,LAL_TWOPI*delta0)-1.0)/crect(0.0,LAL_TWOPI*delta0)));
            }
            else if (fabsf((REAL4)delta0)<(REAL4)1.0e-6) dirichlet = conj((cpolar(1.0,LAL_TWOPI*delta1)-1.0)/crect(0.0,LAL_TWOPI*delta1));
            else if (fabsf((REAL4)(delta0-roundf(delta0)))<(REAL4)1.0e-6) dirichlet = crect(0.0, 0.0);
            else dirichlet = conj(((cpolar(1.0,LAL_TWOPI*delta1)-1.0)/crect(0.0,LAL_TWOPI*delta1))/((cpolar(1.0,LAL_TWOPI*delta0)-1.0)/crect(0.0,LAL_TWOPI*delta0)));
         }
         dirichlet = cpolar(1.0, carg(dirichlet));
         if (fabs(floor(delta0)-floor(delta1))>=1.0) dirichlet *= -1.0;

         COMPLEX16 realRatio = RatioTerm0*phaseshift0*conj(dirichlet0);
         COMPLEX16 estRatio = RatioTerm*phaseshift*conj(dirichlet);

         fprintf(OUTPUT, "%g %g %g %g\n", cabs(realRatio), gsl_sf_angle_restrict_pos(carg(realRatio)), cabs(estRatio), gsl_sf_angle_restrict_pos(carg(estRatio)));
      }

      XLALDestroyMultiAMCoeffs(multiAMcoefficients);
      XLALDestroyMultiSSBtimes(multissb);
   }

   fclose(OUTPUT);
   gsl_rng_free(rng);
   XLALDestroyMultiDetectorStateSeries(multiStateSeries);
   XLALDestroyMultiTimestamps(multiTimestamps);
   XLALDestroyEphemerisData(edat);
   XLALFree(detectors);
   XLALDestroyUserVars();
}
예제 #11
0
//Main program
int main(int argc, char *argv[])
{
   
   FILE *OUTPUT;
   LALDetector det;
   LALStatus XLAL_INIT_DECL(status);

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

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

   //Destroy
   XLALDestroyUserVars();
   XLALDestroyEphemerisData(edat);
   fclose(OUTPUT);
   
   return 0;
   
}
예제 #12
0
/** \see See \ref BilinearTransform_c for documentation */
int XLALWToZCOMPLEX16ZPGFilter( COMPLEX16ZPGFilter *filter )
{
  INT4 i;        /* A counter. */
  INT4 j;        /* Another counter. */
  INT4 num;      /* The total number of zeros or poles. */
  INT4 numZeros; /* The number of finite zeros. */
  INT4 numPoles; /* The number of finite poles. */
  COMPLEX16 *a;   /* A zero or pole in the w plane. */
  COMPLEX16 *b;   /* A zero or pole in the z plane. */
  COMPLEX16 *g;   /* A gain correction factor. */
  COMPLEX16Vector *z=NULL;   /* Vector of zeros or poles in z plane. */
  COMPLEX16Vector *gain=NULL; /* Vector of gain correction factors. */
  COMPLEX16Vector null;       /* A vector of zero length. */
  INT4Vector *idx=NULL;    /* Index array for sorting absGain. */

  /* Make sure the filter pointer is non-null. */
  if ( ! filter )
    XLAL_ERROR( XLAL_EFAULT );

  /* If the filter->zeros or filter->poles pointers is null, this
     means that there are no zeros or no poles.  For simplicity, we
     set the pointer to point to a vector of zero length. */
  null.length=0;
  null.data=NULL;
  if(!filter->zeros)
    filter->zeros=&null;
  if(!filter->poles)
    filter->poles=&null;

  /* Check that the vector lengths are non-negative, and, if positive,
     that the vector data pointer is non-null. */
  numZeros=filter->zeros->length;
  if (numZeros<0)
    XLAL_ERROR(XLAL_EINVAL);
  if(numZeros>0)
    if (!filter->zeros->data)
      XLAL_ERROR(XLAL_EFAULT);
  numPoles=filter->poles->length;
  if (numPoles<0)
    XLAL_ERROR(XLAL_EINVAL);
  if(numPoles>0)
    if (!filter->poles->data)
      XLAL_ERROR(XLAL_EFAULT);

  /* Compute the total number of zeros and poles in the w-plane,
     including those at w=infinity. */
  num = (numZeros>numPoles) ? numZeros : numPoles;
  numZeros=numPoles=num;

  /* If there are neither zeros nor poles, then there is nothing to
     transform.  (The <0 case should never occur if the ASSERT()
     macros have done their job, but is included for extra safety.) */
  if(num<=0){
    filter->zeros=NULL;
    filter->poles=NULL;
    return 0;
  }

  /* Compute the revised number of zeros and poles in the z-plane,
     excluding those at z=infinity (w=-i). */
  for(i=0,a=filter->zeros->data;i<(INT4)filter->zeros->length;i++,a++)
    if((creal(*a)==0.0)&&(cimag(*a)==-1.0))
      numZeros--;
  for(i=0,a=filter->poles->data;i<(INT4)filter->poles->length;i++,a++)
    if((creal(*a)==0.0)&&(cimag(*a)==-1.0))
      numPoles--;

  /* Create the vector of gain correction factors. */
  /* Create the new vector of zeros. */
  gain=XLALCreateCOMPLEX16Vector(filter->zeros->length+filter->poles->length);
  z=XLALCreateCOMPLEX16Vector(numZeros);
  if (!gain||!z)
  {
    XLALDestroyCOMPLEX16Vector(gain);
    XLALDestroyCOMPLEX16Vector(z);
    XLAL_ERROR(XLAL_EFUNC);
  }
  g=gain->data;
  b=z->data;

  /* Transform existing zeros from w to z, except for those at w=-i,
     which are mapped to z=infinity.  At the same time, compute the
     gain correction factors. */
  for(i=0,j=0,a=filter->zeros->data;i<(INT4)filter->zeros->length;
      i++,a++,g++){
    REAL8 ar=creal(*a);
    REAL8 ai=cimag(*a);
    if(ar==0.0){
      if(ai==-1.0){
	/* w=-i is mapped to z=infinity. */
	*g=2.0*I;
      }else{
	/* w=i*y is mapped to z=(1-y)/(1+y). */
	*b=(1.0-ai)/(1.0+ai);
	*g=-(1.0+ai)*I;
	b++;
	j++;
      }
    }else if(fabs(1.0+ai)>fabs(ar)){
      REAL8 ratio = -ar/(1.0+ai);
      REAL8 denom = 1.0+ai - ratio*ar;

      *b = (1.0-ai + ratio*ar)/denom;
      *b += I*(ar - ratio*(1.0-ai))/denom;
      *g = -ar;
      *g += -(1.0+ai)*I;
      b++;
      j++;
    }else{
      REAL8 ratio = -(1.0+ai)/ar;
      REAL8 denom = -ar + ratio*(1.0+ai);

      *b = ((1.0-ai)*ratio + ar)/denom;
      *b += I*(ar*ratio - 1.0+ai)/denom;
      *g = -ar;
      *g += -(1.0+ai)*I;
      b++;
      j++;
    }
  }
  /* Transform any remaining zeros at w=infinity to z=-1. */
  for(;j<numZeros;b++,j++){
    *b = -1.0;
  }
  /* Replace the old filter zeros with the new ones. */
  if(filter->zeros->length>0)
    XLALDestroyCOMPLEX16Vector(filter->zeros);
  filter->zeros=z;
  z=NULL;

  /* Create the new vector of poles. */
  z=XLALCreateCOMPLEX16Vector(numPoles);
  if (!gain||!z)
  {
    XLALDestroyCOMPLEX16Vector(gain);
    XLAL_ERROR(XLAL_EFUNC);
  }
  b=z->data;
  /* Transform existing poles from w to z, except for those at w=-i,
     which are mapped to z=infinity.  At the same time, compute the
     gain correction factors. */
  for(i=0,j=0,a=filter->poles->data;i<(INT4)filter->poles->length;
      i++,a++,g++){
    REAL8 ar=creal(*a);
    REAL8 ai=cimag(*a);
    if(ar==0.0){
      if(ai==-1.0){
	/* w=-i is mapped to z=infinity. */
	*g=-0.5*I;
      }else{
	/* w=i*y is mapped to z=(1-y)/(1+y). */
	*b=(1.0-ai)/(1.0+ai);
	*g=I*1.0/(1.0+ai);
	b++;
	j++;
      }
    }else if(fabs(1.0+ai)>fabs(ar)){
      REAL8 ratio = -ar/(1.0+ai);
      REAL8 denom = 1.0+ai - ratio*ar;

      *b = (1.0-ai + ratio*ar)/denom;
      *b += I*(ar - ratio*(1.0-ai))/denom;
      *g = ratio/denom;
      *g += I*1.0/denom;
      b++;
      j++;
    }else{
      REAL8 ratio = -(1.0+ai)/ar;
      REAL8 denom = -ar + ratio*(1.0+ai);

      *b = ((1.0-ai)*ratio + ar)/denom;
      *b += I*(ar*ratio - 1.0+ai)/denom;
      *g = ratio/denom;
      *g += I*1.0/denom;
      b++;
      j++;
    }
  }
  /* Transform any remaining poles at w=infinity to z=-1. */
  for(;j<numPoles;b++,j++){
    *b = -1.0;
  }
  /* Replace the old filter poles with the new ones. */
  if(filter->poles->length>0)
    XLALDestroyCOMPLEX16Vector(filter->poles);
  filter->poles=z;
  z=NULL;

  /* To avoid numerical overflow when applying the gain correction
     factors, we should multiply alternately by large and small
     factors.  Create an idx vector that indexes the magnitudes
     from small to large. */
  idx=XLALCreateINT4Vector(gain->length);
  if(!idx||XLALHeapIndex(idx->data,gain->data,gain->length,sizeof(*gain->data),NULL,CompareCOMPLEX16Abs)<0)
  {
    XLALDestroyCOMPLEX16Vector(gain);
    XLALDestroyINT4Vector(idx);
    XLAL_ERROR(XLAL_EFUNC);
  }

  /* Now multiply the gain alternately by small and large correction
     factors. */
  for(i=0,j=gain->length-1;i<j;i++,j--){
    /* Multiply the small and largest factors together. */
    /* Multiply the gain by the combined factor. */
    filter->gain *= gain->data[idx->data[i]] * gain->data[idx->data[j]];
  }
  if(i==j){
    /* Multiply by the remaining odd factor. */
    filter->gain *= gain->data[idx->data[i]];
  }

  /* Free remaining temporary vectors, and exit. */
  XLALDestroyCOMPLEX16Vector(gain);
  XLALDestroyINT4Vector(idx);
  return 0;
}
예제 #13
0
int XLALSQTPNGenerator(LALSQTPNWave *waveform, LALSQTPNWaveformParams *params) {

	if( !params || !waveform )
		XLAL_ERROR(XLAL_EFAULT);

	// variable declaration and initialization
	UINT4 i = 0; // index
	REAL8 time = 0.;
	REAL8 LNhztol = 1.0e-8;
	REAL8 alpha, amp, temp1, temp2;
	const REAL8 geometrized_m_total = params->totalMass * LAL_MTSUN_SI;
	const REAL8 freq_Step = geometrized_m_total * LAL_PI;
	const REAL8 step = params->samplingTime / geometrized_m_total;
	REAL8 values[LALSQTPN_NUM_OF_VAR], dvalues[LALSQTPN_NUM_OF_VAR];
	LALSQTPNIntegratorSystem integrator;
	xlalErrno = 0;
	if( XLALSQTPNIntegratorInit(&integrator, LALSQTPN_NUM_OF_VAR, 
			params, XLALSQTPNDerivator) )
		XLAL_ERROR(XLAL_EFUNC);

	// initializing the dynamic variables
	values[LALSQTPN_PHASE] = params->phi;
	values[LALSQTPN_OMEGA] = params->lowerFreq * freq_Step;
	values[LALSQTPN_LNH_1] = sin(params->inclination); ///< \f$\hat{L_N}=\sin\iota\f$
	values[LALSQTPN_LNH_2] = 0.; ///< \f$\hat{L_N}=0\f$
	values[LALSQTPN_LNH_3] = cos(params->inclination); ///< \f$\hat{L_N}=\cos\iota\f$
	values[LALSQTPN_MECO] = 0.;
	for (i = 0; i < 3; i++) {
		values[LALSQTPN_CHIH1_1 + i] = params->chih[0][i];
		values[LALSQTPN_CHIH2_1 + i] = params->chih[1][i];
	}

	// filling the LALSQTPNCoefficients
	xlalErrno = 0;
	if( XLALSQTPNFillCoefficients(params) )
		XLAL_ERROR(XLAL_EFUNC);
	if( XLALSQTPNDerivator(time, values, dvalues, params) )
		XLAL_ERROR(XLAL_EFUNC);
	dvalues[LALSQTPN_MECO] = -1.; // to be able to start the loop
	i = 0;
	do {
		alpha = atan2(values[LALSQTPN_LNH_2], values[LALSQTPN_LNH_1]);
		amp = params->signalAmp * pow(values[LALSQTPN_OMEGA], 2. / 3.);

		// calculating the waveform components
		if (waveform->hp || waveform->hc || waveform->h) {
			temp1 = -0.5*amp*cos(2.*values[LALSQTPN_PHASE])
				* (values[LALSQTPN_LNH_3] 
				* values[LALSQTPN_LNH_3] + 1.);
			temp2 = amp * sin(2.*values[LALSQTPN_PHASE]) 
				* values[LALSQTPN_LNH_3];
			if (waveform->h) {
				waveform->hp->data[2*i] = temp1 * cos(2.*alpha)
					+ temp2 * sin(2.*alpha);
				waveform->hc->data[2*i+1] = temp1 
					* sin(2.*alpha) - temp2 * cos(2.*alpha);
			}
			if (waveform->hp) {
				waveform->hp->data[i] = temp1 * cos(2.*alpha) 
					+ temp2 * sin(2.*alpha);
			}
			if (waveform->hc) {
				waveform->hc->data[i] = temp1 * sin(2.*alpha) 
					- temp2 * cos(2.*alpha);
			}
		}
		if (waveform->waveform) {
			waveform->waveform->a->data->data[2*i] = -amp*0.5 
				* (1. + values[LALSQTPN_LNH_3] 
				* values[LALSQTPN_LNH_3]);
			waveform->waveform->a->data->data[2*i + 1] = -amp 
				* values[LALSQTPN_LNH_3];
			waveform->waveform->phi->data->data[i] = 2. 
				* (values[LALSQTPN_PHASE] - params->phi);
			waveform->waveform->shift->data->data[i] = 2. * alpha;
			waveform->waveform->f->data->data[i] 
				= values[LALSQTPN_OMEGA] / freq_Step;
		}

		// evolving
		time = i++ * params->samplingTime;
		xlalErrno = 0;
		if(XLALSQTPNIntegratorFunc(values, &integrator, step)) {
			XLAL_ERROR(XLAL_EFUNC);
		}
		// if one of the variables is nan, the PN approximation broke down
		if (isnan(values[LALSQTPN_PHASE]) 
				|| isnan(values[LALSQTPN_OMEGA]) 
				|| isnan(values[LALSQTPN_LNH_1]) 
				|| isnan(values[LALSQTPN_LNH_2])
				|| isnan(values[LALSQTPN_LNH_3]) 
				|| isnan(values[LALSQTPN_CHIH1_1])
				|| isnan(values[LALSQTPN_CHIH1_2]) 
				|| isnan(values[LALSQTPN_CHIH1_3])
				|| isnan(values[LALSQTPN_CHIH2_1]) 
				|| isnan(values[LALSQTPN_CHIH2_2])
				|| isnan(values[LALSQTPN_CHIH2_3])) {
			break;
		}
		if( XLALSQTPNDerivator(time, values, dvalues, params) )
			XLAL_ERROR(XLAL_EFUNC);
		if ((waveform->waveform && 
				i == waveform->waveform->f->data->length) ||
				(waveform->hp && i == waveform->hp->length) ||
				(waveform->hc && i == waveform->hc->length)) {
			XLALSQTPNIntegratorFree(&integrator);
			XLAL_ERROR(XLAL_EBADLEN);
		}
	} while (dvalues[LALSQTPN_MECO] < 0. && dvalues[LALSQTPN_OMEGA] > 0.0 
			&& SQT_SQR(values[LALSQTPN_LNH_3]) < 1. - LNhztol 
			&& values[LALSQTPN_OMEGA] / freq_Step 
			< params->samplingFreq / 2.
			/* && values[LALSQTPN_OMEGA] / freq_Step 
			< params->finalFreq*/);
	if (waveform->hp || waveform->hc){
		params->finalFreq = values[LALSQTPN_OMEGA] 
			/ (LAL_PI * geometrized_m_total);
		params->coalescenceTime = time;
	}
   	if (waveform->waveform->a){
		params->finalFreq = waveform->waveform->f->data->data[i-1];
	}

	waveform->length = i;
	XLALSQTPNIntegratorFree(&integrator);

	return XLAL_SUCCESS;
}
예제 #14
0
int XLALSQTPNFillCoefficients(LALSQTPNWaveformParams * const params) {

	// variable declaration and initialization
	REAL8 thetahat = 1039. / 4620.;
	REAL8 spin_MPow2[2];
	REAL8 m_m[2] = { params->mass[1] / params->mass[0], params->mass[0]
		/ params->mass[1] };
	REAL8 piPow2 = SQT_SQR(LAL_PI);
	REAL8 etaPow2 = SQT_SQR(params->eta);
	REAL8 etaPow3 = etaPow2 * params->eta;
	INT2 i;
	for (i = 0; i < 2; i++) {
		spin_MPow2[i] = params->chiAmp[i] * SQT_SQR(params->mass[i])
			/SQT_SQR(params->totalMass);
	}

	// calculating the coefficients
	params->coeff.domegaGlobal = params->eta * 96. / 5.;
	for (i = LAL_PNORDER_NEWTONIAN; i < LAL_PNORDER_PSEUDO_FOUR; i += 2) {
		params->coeff.meco[i] = -0.5 * params->eta 
			* (REAL8) (i + 2) / 3.;
	}
	switch (params->order) {
		case LAL_PNORDER_THREE_POINT_FIVE:
			params->coeff.domega[LAL_PNORDER_THREE_POINT_FIVE] 
				= (-4415./ 4032. + params->eta * 358675. 
				/ 6048. + etaPow2 * 91495. / 1512.) * LAL_PI;
		case LAL_PNORDER_THREE:
			params->coeff.domega[LAL_PNORDER_THREE]
				= (16447322263. / 139708800. - LAL_GAMMA 
				* 1712. / 105. + piPow2 * 16. / 3.) 
				+ (-273811877. / 1088640.+ piPow2 * 451. / 48. 
				- thetahat * 88. / 3.) * params->eta + etaPow2 
				* 541. / 896. - etaPow3 * 5605. / 2592.;
			params->coeff.domegaLN = -856. / 105.;
			params->coeff.meco[LAL_PNORDER_THREE] *= -675. / 64. 
				+ (209323. / 4032. - 205. * piPow2 / 96. 
				+ (110. / 9.) * (1987. / 3080.)) * params->eta 
				- 155. * etaPow2 / 96. - 35. * etaPow3 / 5184.;
		case LAL_PNORDER_TWO_POINT_FIVE:
			params->coeff.domega[LAL_PNORDER_TWO_POINT_FIVE] 
				= -(4159. + 15876. * params->eta) 
				* LAL_PI / 672.;
		case LAL_PNORDER_TWO:
			params->coeff.domega[LAL_PNORDER_TWO] = 34103. / 18144.
				+ params->eta * 13661. / 2016. 
				+ etaPow2 * 59. / 18.;
			params->coeff.domegaSSselfConst = 0.;
			params->coeff.domegaQMConst = 0.;
			if ((params->interaction & LAL_INSPIRAL_INTERACTION_SPIN_SPIN_2PN) == LAL_INSPIRAL_INTERACTION_SPIN_SPIN_2PN) {
				params->coeff.dchihSS[0] = spin_MPow2[1] / 2.;
				params->coeff.dchihSS[1] = spin_MPow2[0] / 2.;
				params->coeff.domegaSS[0] = 721. * params->eta
					* params->chiAmp[0] * params->chiAmp[1]
					/ 48.;
				params->coeff.domegaSS[1] = -247. 
					* params->coeff.domegaSS[0] / 721.;
				params->coeff.mecoSS = -spin_MPow2[0] 
					* spin_MPow2[1];
			}
			if ((params->interaction & LAL_INSPIRAL_INTERACTION_SPIN_SPIN_SELF_2PN) == LAL_INSPIRAL_INTERACTION_SPIN_SPIN_SELF_2PN) {
				for (i = 0; i < 2; i++) {
					params->coeff.domegaSSself[i] 
						= -spin_MPow2[i] 
						* params->chiAmp[i] / 96.;
					params->coeff.domegaSSselfConst -= 7. 
						* params->coeff.domegaSSself[i];
				}
			}
			if ((params->interaction & LAL_INSPIRAL_INTERACTION_QUAD_MONO_2PN) == LAL_INSPIRAL_INTERACTION_QUAD_MONO_2PN) {
				for (i = 0; i < 2; i++) {
					params->coeff.domegaQM[i] 
						= spin_MPow2[i] 
						* params->chiAmp[i] 
						* params->qmParameter[i] * 7.5;
					params->coeff.domegaQMConst 
						-= params->coeff.domegaQM[i] 
						/ 3.;
					params->coeff.dchihQM[i] 
						= -params->qmParameter[i] 
						* params->eta 
						* params->chiAmp[i] * 3. / 2.;
				}
				params->coeff.mecoQM = 2. * params->eta;
			}
			params->coeff.meco[LAL_PNORDER_TWO] *= (-81. + 57. 
				* params->eta - etaPow2) / 24.;
		case LAL_PNORDER_ONE_POINT_FIVE:
			params->coeff.domega[LAL_PNORDER_ONE_POINT_FIVE] 
				= 4. * LAL_PI;
			if (params->interaction != 0) {
				for (i = 0; i < 2; i++) {
					params->coeff.dchihSO[i] = (4. + 3. 
						* m_m[i]) * params->eta / 2.;
					params->coeff.dLNh[i] = -spin_MPow2[i] 
						/ params->eta;
					params->coeff.domegaSO[i] 
						= -spin_MPow2[i] * (113. + 75. 
						* m_m[i]) / 12.;
					params->coeff.mecoSO[i] 
						= -spin_MPow2[i] * 5. 
						* params->eta * (4. + 3. 
						* m_m[i]) / 9.;
				}
			}
		case LAL_PNORDER_ONE:
			params->coeff.domega[LAL_PNORDER_ONE]
				= -(743. + 924. * params->eta) / 336.;
			params->coeff.meco[LAL_PNORDER_ONE] *= -(9. 
				+ params->eta) / 12.;
		case LAL_PNORDER_HALF:
			params->coeff.domega[LAL_PNORDER_HALF] = 0.;
		case LAL_PNORDER_NEWTONIAN:
			params->coeff.domega[LAL_PNORDER_NEWTONIAN] = 1.;
			break;
		default:
			XLAL_ERROR(XLAL_EINVAL);
			break;
	}

	return XLAL_SUCCESS;
}
예제 #15
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);
}
/*
 * Core function for computing the ROM waveform.
 * Evaluates projection coefficients and shifts in time and phase at desired q.
 * Construct 1D splines for amplitude and phase.
 * Compute strain waveform from amplitude and phase.
*/
static INT4 EOBNRv2HMROMCore(
  COMPLEX16FrequencySeries **hptilde,
  COMPLEX16FrequencySeries **hctilde,
  REAL8 phiRef,
  REAL8 deltaF,
  REAL8 fLow,
  REAL8 fHigh,
  REAL8 fRef,
  REAL8 distance,
  REAL8 inclination,
  REAL8 Mtot_sec,
  REAL8 q)
{
  INT4 ret = XLAL_SUCCESS;
  INT4 i;
  INT4 j;
  double tpeak22estimate = 0.;
  /* Check output arrays */
  if(!hptilde || !hctilde) XLAL_ERROR(XLAL_EFAULT);
  if(*hptilde || *hctilde)
  {
    XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p\n",(*hptilde),(*hctilde));
    XLAL_ERROR(XLAL_EFAULT);
  }

  /* Check if the data has been set up */
  if(__lalsim_EOBNRv2HMROM_setup) {
    XLALPrintError("Error: the ROM data has not been set up\n");
    XLAL_ERROR(XLAL_EFAULT);
  }
  /* Set the global pointers to data */
  ListmodesEOBNRHMROMdata* listdata = *__lalsim_EOBNRv2HMROM_data;
  ListmodesEOBNRHMROMdata_interp* listdata_interp = *__lalsim_EOBNRv2HMROM_interp;

  /* Global amplitude prefactor - includes total mass scaling, Fourier scaling, distance scaling, and undoing an additional arbitrary scaling */
  REAL8 Mtot_msol = Mtot_sec / LAL_MTSUN_SI; /* Mtot_msol and M_ROM in units of solar mass */
  REAL8 amp0 = (Mtot_msol/M_ROM) * Mtot_sec * 1.E-16 * 1.E6 * LAL_PC_SI / distance;

  /* Highest allowed geometric frequency for the first mode of listmode in the ROM - used for fRef
   * by convention, we use the first mode of listmode (presumably the 22) for phiref */
  ListmodesEOBNRHMROMdata* listdata_ref = ListmodesEOBNRHMROMdata_GetMode(listdata, listmode[0][0], listmode[0][1]);
  EOBNRHMROMdata* data_ref = listdata_ref->data;
  REAL8 Mf_ROM_max_ref = gsl_vector_get(data_ref->freq, nbfreq-1);
  /* Convert to geometric units for frequency */
  REAL8 fLow_geom = fLow * Mtot_sec;
  REAL8 fHigh_geom = fHigh * Mtot_sec;
  REAL8 fRef_geom = fRef * Mtot_sec;
  REAL8 deltaF_geom = deltaF * Mtot_sec;

  /* Enforce allowed geometric frequency range */
  if (fLow_geom < Mf_ROM_min) { /* Enforce minimal frequency */
    XLALPrintWarning("Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min);
    fLow_geom = Mf_ROM_min;
  }
  /* Default highest frequency */
  if (fHigh == 0)
    fHigh_geom = Mf_ROM_max;
  /* In case the user asks for a frequency higher than covered by the ROM, we keep it that way as we will just 0-pad the waveform (and do it anyway for some modes) */
  if (fRef_geom > Mf_ROM_max_ref || fRef_geom == 0)
    fRef_geom = Mf_ROM_max_ref; /* If fRef > fhigh or 0 we reset fRef to default value of cutoff frequency for the first mode of the list (presumably the 22 mode) */
  if (0 < fRef_geom && fRef_geom < Mf_ROM_min) {
    XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Setting it to the lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min);
    fRef_geom = Mf_ROM_min;
  }
  /* Set up output array with size closest power of 2 - fHigh is the upper frequency specified by the user */
  size_t nbpt = NextPow2(fHigh_geom / deltaF_geom) + 1;

  /* Internal storage for the projection coefficients and shifts in time and phase */
  /* Initialized only once, and reused for the different modes */
  EOBNRHMROMdata_coeff *data_coeff = NULL;
  EOBNRHMROMdata_coeff_Init(&data_coeff);
  /* Create spherical harmonic frequency series that will contain the hlm's */
  SphHarmFrequencySeries** hlmsphharmfreqseries = XLALMalloc(sizeof(SphHarmFrequencySeries));
  *hlmsphharmfreqseries = NULL;

  /* GPS time definition - common to all modes */
  LIGOTimeGPS tC;
  XLALGPSAdd(&tC, -1. / deltaF);  /* coalesce at t=0 */

  /* The phase change imposed by phiref, from the phase of the first mode in the list - to be set in the first step of the loop on the modes */
  REAL8 phase_change_ref = 0;

  /* Main loop over the modes */
  for( i=0; i<nbmode; i++ ){
    UINT4 l = listmode[i][0];
    INT4 m = listmode[i][1];

    /* Getting the relevant modes in the lists of data */
    ListmodesEOBNRHMROMdata* listdata_mode = ListmodesEOBNRHMROMdata_GetMode(listdata, l, m);
    ListmodesEOBNRHMROMdata_interp* listdata_interp_mode = ListmodesEOBNRHMROMdata_interp_GetMode(listdata_interp, l, m);

    /* Evaluating the projection coefficients and shift in time and phase */
    ret |= Evaluate_Spline_Data(q, listdata_interp_mode->data_interp, data_coeff);

    /* Evaluating the unnormalized amplitude and unshifted phase vectors for the mode */
    /* Notice a change in convention: B matrices are transposed with respect to the B matrices in SEOBNRROM */
    /* amp_pts = Bamp . Camp_coeff */
    /* phi_pts = Bphi . Cphi_coeff */
    gsl_vector* amp_f = gsl_vector_alloc(nbfreq);
    gsl_vector* phi_f = gsl_vector_alloc(nbfreq);
    gsl_blas_dgemv(CblasNoTrans, 1.0, listdata_mode->data->Bamp, data_coeff->Camp_coeff, 0.0, amp_f);
    gsl_blas_dgemv(CblasNoTrans, 1.0, listdata_mode->data->Bphi, data_coeff->Cphi_coeff, 0.0, phi_f);

    /* The downsampled frequencies for the mode - we undo the rescaling of the frequency for the 44 and 55 modes */
    gsl_vector* freq_ds = gsl_vector_alloc(nbfreq);
    gsl_vector_memcpy(freq_ds, listdata_mode->data->freq);
    if ( l==4 && m==4) gsl_vector_scale( freq_ds, 1./Scaling44(q));
    if ( l==5 && m==5) gsl_vector_scale( freq_ds, 1./Scaling55(q));

    /* Evaluating the shifts in time and phase - conditional scaling for the 44 and 55 modes */
    /* Note: the stored values of 'shifttime' correspond actually to 2pi*Deltat */
    SplineList* shifttime_splinelist = listdata_interp_mode->data_interp->shifttime_interp;
    SplineList* shiftphase_splinelist = listdata_interp_mode->data_interp->shiftphase_interp;
    REAL8 twopishifttime;
    if( l==4 && m==4) {
      twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel) * Scaling44(q);
    }
    else if( l==5 && m==5) {
      twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel) * Scaling55(q);
    }
    else {
      twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel);
    }
    REAL8 shiftphase = gsl_spline_eval(shiftphase_splinelist->spline, q, shiftphase_splinelist->accel);

    /* If first mode in the list, assumed to be the 22 mode, set totalshifttime and phase_change_ref */
    if( i==0 ) {
      if(l==2 && m==2) {
      /* Setup 1d cubic spline for the phase of the 22 mode */
      gsl_interp_accel* accel_phi22 = gsl_interp_accel_alloc();
      gsl_spline* spline_phi22 = gsl_spline_alloc(gsl_interp_cspline, nbfreq);
      gsl_spline_init(spline_phi22, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(phi_f,0), nbfreq);
      /* Compute the shift in time needed to set the peak of the 22 mode roughly at t=0 */
      /* We use the SPA formula tf = -(1/2pi)*dPsi/df to estimate the correspondence between frequency and time */
      /* The frequency corresponding to the 22 peak is omega22peak/2pi, with omega22peak taken from the fit to NR in Pan&al 1106 EOBNRv2HM paper */
      double f22peak = fmin(omega22peakOfq(q)/(2*LAL_PI), Mf_ROM_max_ref); /* We ensure we evaluate the spline within its range */
      tpeak22estimate = -1./(2*LAL_PI) * gsl_spline_eval_deriv(spline_phi22, f22peak, accel_phi22);
      /* Determine the change in phase (to be propagated to all modes) required to have phi22(fRef) = 2*phiRef */
      phase_change_ref = 2*phiRef + (gsl_spline_eval(spline_phi22, fRef_geom, accel_phi22) - (twopishifttime - 2*LAL_PI*tpeak22estimate) * fRef_geom - shiftphase);

      gsl_spline_free(spline_phi22);
      gsl_interp_accel_free(accel_phi22);
      }
      else {
	XLALPrintError("Error: the first mode in listmode must be the 22 mode to set the changes in phase and time \n");
	XLAL_ERROR(XLAL_EFAILED);
      }
    }
    /* Total shift in time, and total change in phase for this mode */
    double totaltwopishifttime = twopishifttime - 2*LAL_PI*tpeak22estimate;
    double constphaseshift = (double) m/listmode[0][1] * phase_change_ref + shiftphase;

    /* Initialize the complex series for the mode - notice that metadata used here is useless, only the one for the final output will matter */
    COMPLEX16FrequencySeries* mode = XLALCreateCOMPLEX16FrequencySeries("mode hlm", &tC, 0.0, deltaF, &lalStrainUnit, nbpt);
    memset(mode->data->data, 0, nbpt * sizeof(COMPLEX16));
    /* Setup 1d cubic spline for the phase and amplitude of the mode */
    gsl_interp_accel* accel_phi = gsl_interp_accel_alloc();
    gsl_interp_accel* accel_amp = gsl_interp_accel_alloc();
    gsl_spline* spline_phi = gsl_spline_alloc(gsl_interp_cspline, nbfreq);
    gsl_spline* spline_amp = gsl_spline_alloc(gsl_interp_cspline, nbfreq);
    gsl_spline_init(spline_phi, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(phi_f,0), nbfreq);
    gsl_spline_init(spline_amp, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(amp_f,0), nbfreq);
    /* Interval in frequency covered by the ROM */
    REAL8 fLow_geom_mode = gsl_vector_get(freq_ds, 0);
    REAL8 fHigh_geom_mode = fmin(gsl_vector_get(freq_ds, nbfreq-1), fHigh_geom);
    /* Initialize the loop - values outside this range in j are 0 by default */
    INT4 jStart = (UINT4) ceil(fLow_geom_mode / deltaF_geom);
    INT4 jStop = (UINT4) ceil(fHigh_geom_mode / deltaF_geom);
    COMPLEX16 *modedata = mode->data->data;
    /* Mode-dependent complete amplitude prefactor */
    REAL8 amp_pre = amp0 * ModeAmpFactor( l, m, q);
    /* Loop on the frequency samples chosen to evaluate the waveform */
    /* We set apart the first and last step to avoid falling outside of the range of the splines by numerical errors */
    REAL8 f, A, phase;

    f = fmax(fLow_geom_mode, jStart*deltaF_geom);
    A = gsl_spline_eval(spline_amp, f, accel_amp);
    phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */
    modedata[jStart] = amp_pre * A * cexp(I*phase);

    for (j=jStart+1; j<jStop-1; j++) {
      f = j*deltaF_geom;
      A = gsl_spline_eval(spline_amp, f, accel_amp);
      phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */
      modedata[j] = amp_pre * A * cexp(I*phase);
    }

    f = fmin(fHigh_geom_mode, (jStop-1)*deltaF_geom);
    A = gsl_spline_eval(spline_amp, f, accel_amp);
    phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */
    modedata[jStop-1] = amp_pre * A * cexp(I*phase);

    /* Add the computed mode to the SphHarmFrequencySeries structure */
    *hlmsphharmfreqseries = XLALSphHarmFrequencySeriesAddMode(*hlmsphharmfreqseries, mode, l, m);

    /* Cleanup for the mode */
    gsl_spline_free(spline_amp);
    gsl_spline_free(spline_phi);
    gsl_interp_accel_free(accel_amp);
    gsl_interp_accel_free(accel_phi);
    gsl_vector_free(amp_f);
    gsl_vector_free(phi_f);
    gsl_vector_free(freq_ds);
    XLALDestroyCOMPLEX16FrequencySeries(mode);

  }
  /* Cleanup of the coefficients data structure */
  EOBNRHMROMdata_coeff_Cleanup(data_coeff);

  /* Combining the modes for a hplus, hcross output */
  /* Initialize the complex series hplus, hcross */
  *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, nbpt);
  *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, nbpt);

  if (!(hptilde) || !(*hctilde)) XLAL_ERROR(XLAL_EFUNC);
  memset((*hptilde)->data->data, 0, nbpt * sizeof(COMPLEX16));
  memset((*hctilde)->data->data, 0, nbpt * sizeof(COMPLEX16));

  XLALUnitDivide(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit);
  XLALUnitDivide(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit);

  /* Adding the modes to form hplus, hcross
   * - use of a function that copies XLALSimAddMode but for Fourier domain structures */
  INT4 sym; /* sym will decide whether to add the -m mode (when equatorial symmetry is present) */
  for( i=0; i<nbmode; i++){
    INT4 l = listmode[i][0];
    INT4 m = listmode[i][1];
    COMPLEX16FrequencySeries* mode = XLALSphHarmFrequencySeriesGetMode(*hlmsphharmfreqseries, l, m);
    if ( m==0 ) sym = 0; /* We test for hypothetical m=0 modes */
    else sym = 1;
    FDAddMode( *hptilde, *hctilde, mode, inclination, 0., l, m, sym); /* The phase \Phi is set to 0 - assumes phiRef is defined as half the phase of the 22 mode h22 (or the first mode in the list), not for h = hplus-I hcross */
  }

  /* Destroying the list of frequency series for the modes, including the COMPLEX16FrequencySeries that it contains */
  XLALDestroySphHarmFrequencySeries(*hlmsphharmfreqseries);
  XLALFree(hlmsphharmfreqseries);

  /* Additional complex conjugation of hptilde, hctilde - due to the difference in convention for the Fourier transform between LAL and the ROM internals */
  COMPLEX16* datap = (*hptilde)->data->data;
  COMPLEX16* datac = (*hctilde)->data->data;
  for ( j = 0; j < (INT4) (*hptilde)->data->length; ++j ) {
    datap[j] = conj(datap[j]);
  }
  for ( j = 0; j < (INT4) (*hctilde)->data->length; ++j ) {
    datac[j] = conj(datac[j]);
  }

  return(XLAL_SUCCESS);
}
예제 #17
0
static int IMRPhenomCGenerateFD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 phi0,                  /**< phase at peak */
    const REAL8 deltaF,                /**< frequency resolution */
    const REAL8 m1,                    /**< mass of companion 1 [solar masses] */
    const REAL8 m2,                    /**< mass of companion 2 [solar masses] */
    //const REAL8 chi,                   /**< mass-weighted aligned-spin parameter */
    const REAL8 f_min,                 /**< start frequency */
    const REAL8 f_max,                 /**< end frequency */
    const REAL8 distance,              /**< distance to source (m) */
    const BBHPhenomCParams *params      /**< from ComputeIMRPhenomCParams */
) {
  LIGOTimeGPS ligotimegps_zero = LIGOTIMEGPSZERO; // = {0, 0}

  int errcode = XLAL_SUCCESS;
  /*
   We can't call XLAL_ERROR() directly with OpenMP on.
   Keep track of return codes for each thread and in addition use flush to get out of
   the parallel for loop as soon as possible if something went wrong in any thread.
  */

  const REAL8 M = m1 + m2;
  const REAL8 eta = m1 * m2 / (M * M);

  /* Memory to temporarily store components of amplitude and phase */
  /*
  REAL8 phSPA, phPM, phRD, aPM, aRD;
  REAL8 wPlusf1, wPlusf2, wMinusf1, wMinusf2, wPlusf0, wMinusf0;
  */

  /* compute the amplitude pre-factor */
  REAL8 amp0 = 2. * sqrt(5. / (64.*LAL_PI)) * M * LAL_MRSUN_SI * M * LAL_MTSUN_SI / distance;

  /* allocate htilde */
  size_t n = NextPow2_PC(f_max / deltaF) + 1;
  /* coalesce at t=0 */
  XLALGPSAdd(&ligotimegps_zero, -1. / deltaF); // shift by overall length in time
  *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &ligotimegps_zero, 0.0,
      deltaF, &lalStrainUnit, n);
  memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16));
  XLALUnitMultiply(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit);
  if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC);

  size_t ind_min = (size_t) (f_min / deltaF);
  size_t ind_max = (size_t) (f_max / deltaF);

  /* Set up spline for phase */
  gsl_interp_accel *acc = gsl_interp_accel_alloc();
  size_t L =  ind_max - ind_min;
  gsl_spline *phiI = gsl_spline_alloc(gsl_interp_cspline, L);
  REAL8 *freqs = XLALMalloc(L*sizeof(REAL8));
  REAL8 *phis = XLALMalloc(L*sizeof(REAL8));

  /* now generate the waveform */
  #pragma omp parallel for
  for (size_t i = ind_min; i < ind_max; i++)
  {

    REAL8 phPhenomC = 0.0;
    REAL8 aPhenomC = 0.0;
    REAL8 f = i * deltaF;

    int per_thread_errcode;
    #pragma omp flush(errcode)
    if (errcode != XLAL_SUCCESS)
      goto skip;

    per_thread_errcode = IMRPhenomCGenerateAmpPhase( &aPhenomC, &phPhenomC, f, eta, params );
    if (per_thread_errcode != XLAL_SUCCESS) {
      errcode = per_thread_errcode;
      #pragma omp flush(errcode)
    }

    phPhenomC -= 2.*phi0; // factor of 2 b/c phi0 is orbital phase

    freqs[i-ind_min] = f;
    phis[i-ind_min] = -phPhenomC; // PhenomP uses cexp(-I*phPhenomC); want to use same phase adjustment code, so we will flip the sign of the phase

    /* generate the waveform */
    ((*htilde)->data->data)[i] = amp0 * aPhenomC * cos(phPhenomC);
    ((*htilde)->data->data)[i] += -I * amp0 * aPhenomC * sin(phPhenomC);

  skip: /* this statement intentionally left blank */;

  }

  if( errcode != XLAL_SUCCESS )
    XLAL_ERROR(errcode);

  /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */
  gsl_spline_init(phiI, freqs, phis, L);

  REAL8 f_final = params->fRingDown;
  XLAL_PRINT_INFO("f_ringdown = %g\n", f_final);

  // Prevent gsl interpolation errors
  if (f_final > freqs[L-1])
    f_final = freqs[L-1];
  if (f_final < freqs[0])
    XLAL_ERROR(XLAL_EDOM, "f_ringdown <= f_min\n");

  /* Time correction is t(f_final) = 1/(2pi) dphi/df (f_final) */
  REAL8 t_corr = gsl_spline_eval_deriv(phiI, f_final, acc) / (2*LAL_PI);
  XLAL_PRINT_INFO("t_corr = %g\n", t_corr);
  /* Now correct phase */
  for (size_t i = ind_min; i < ind_max; i++) {
    REAL8 f = i * deltaF;
    ((*htilde)->data->data)[i] *= cexp(-2*LAL_PI * I * f * t_corr);
  }

  gsl_spline_free(phiI);
  gsl_interp_accel_free(acc);
  XLALFree(freqs);
  XLALFree(phis);

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

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

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

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

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

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

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

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

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

  }

  else {

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

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

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

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

    } // if ( haveTimeGPS )

    else { // haveTimeStampsFiles || haveTimeStampsFile

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

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

    } // else: haveTimeStampsFiles || haveTimeStampsFile

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

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

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

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

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

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

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

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

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

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

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

    REAL8 psd_normalization = 0;

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

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

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

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

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

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

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

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

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

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

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

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

    XLALDestroyREAL8Vector ( noiseSqrtShX );

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

  else {
    cfg->multiNoiseWeights =  NULL;
  }

  return XLAL_SUCCESS;

} /* XLALInitCode() */
예제 #19
0
/**
 * Driver routine to compute the spin-aligned, inspiral-merger-ringdown
 * phenomenological waveform IMRPhenomC in the frequency domain.
 *
 * 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 XLALSimIMRPhenomCGenerateFD(
    COMPLEX16FrequencySeries **htilde, /**< FD waveform */
    const REAL8 phi0,                  /**< orbital phase at peak (rad) */
    const REAL8 deltaF,                /**< sampling interval (Hz) */
    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 frequency; 0 defaults to ringdown cutoff freq */
    const REAL8 distance               /**< distance of source (m) */
) {
  BBHPhenomCParams *params;
  int status;
  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;

  /* check inputs for sanity */
  if (*htilde) XLAL_ERROR(XLAL_EFAULT);
  if (deltaF <= 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");

  status = IMRPhenomCGenerateFD(htilde, phi0, deltaF, m1, m2, f_min, f_max_prime, distance, params);

  if (f_max_prime < f_max) {
    // The user has requested a higher f_max than Mf=params->fCut.
    // Resize the frequency series to fill with zeros to fill with zeros beyond the cutoff frequency.
        size_t n_full = NextPow2_PC(f_max / deltaF) + 1; // we actually want to have the length be a power of 2 + 1 power of 2 + 1
    *htilde = XLALResizeCOMPLEX16FrequencySeries(*htilde, 0, n_full);
  }

  LALFree(params);
  return status;
}
/**
 * Generate the "reduced-spin templates" proposed in http://arxiv.org/abs/1107.1267
 * Add the tidal phase terms from http://arxiv.org/abs/1101.1673 (Eqs. 3.9, 3.10)
 * The chi parameter should be determined from XLALSimInspiralTaylorF2ReducedSpinComputeChi.
 */
int XLALSimInspiralTaylorF2ReducedSpinTidal(
    COMPLEX16FrequencySeries **htilde,   /**< FD waveform */
    const REAL8 phic,                /**< orbital coalescence phase (rad) */
    const REAL8 deltaF,              /**< frequency resolution (Hz) */
    const REAL8 m1_SI,               /**< mass of companion 1 (kg) */
    const REAL8 m2_SI,               /**< mass of companion 2 (kg) */
    const REAL8 chi,                 /**< dimensionless aligned-spin param */
    const REAL8 lam1,                /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
    const REAL8 lam2,                /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
    const REAL8 fStart,              /**< start GW frequency (Hz) */
    const REAL8 fEnd,                /**< highest GW frequency (Hz) of waveform generation - if 0, end at Schwarzschild ISCO */
    const REAL8 r,                   /**< distance of source (m) */
    const INT4 phaseO,               /**< twice PN phase order */
    const INT4 ampO                  /**< twice PN amplitude order */
    ) {
    /* external: SI; internal: solar masses */
    const REAL8 m1 = m1_SI / LAL_MSUN_SI;
    const REAL8 m2 = m2_SI / LAL_MSUN_SI;
    const REAL8 m = m1 + m2;
    const REAL8 m_sec = m * LAL_MTSUN_SI;  /* total mass in seconds */
    const REAL8 eta = m1 * m2 / (m * m);
    const REAL8 xi1 = m1 / m;
    const REAL8 xi2 = m2 / m;
    const REAL8 piM = LAL_PI * m_sec;
    const REAL8 mSevenBySix = -7./6.;
    const REAL8 vISCO = 1. / sqrt(6.);
    const REAL8 fISCO = vISCO * vISCO * vISCO / piM;
    REAL8 v0 = 1.0; /* v0=c */
    REAL8 shft, amp0, f_max;
    REAL8 psiNewt, psi2, psi3, psi4, psi5, psi6, psi6L, psi7, psi3S, psi4S, psi5S, psi10T1, psi10T2, psi10, psi12T1, psi12T2, psi12;
    REAL8 alpha2, alpha3, alpha4, alpha5, alpha6, alpha6L, alpha7, alpha3S, alpha4S, alpha5S;
    size_t i, n, iStart;
    COMPLEX16 *data = NULL;
    LIGOTimeGPS tStart = {0, 0};

    /* check inputs for sanity */
    if (*htilde) XLAL_ERROR(XLAL_EFAULT);
    if (m1_SI <= 0) XLAL_ERROR(XLAL_EDOM);
    if (m2_SI <= 0) XLAL_ERROR(XLAL_EDOM);
    if (fabs(chi) > 1) XLAL_ERROR(XLAL_EDOM);
    if (fStart <= 0) XLAL_ERROR(XLAL_EDOM);
    if (r <= 0) XLAL_ERROR(XLAL_EDOM);
    if (ampO > 7) XLAL_ERROR(XLAL_EDOM); /* only implemented to pN 3.5 */
    if (phaseO > 7) XLAL_ERROR(XLAL_EDOM); /* only implemented to pN 3.5 */

    /* allocate htilde */
    if ( fEnd == 0. ) // End at ISCO
        f_max = fISCO;
    else // End at user-specified freq.
        f_max = fEnd;
    n = (size_t) (f_max / deltaF + 1);
    XLALGPSAdd(&tStart, -1 / deltaF);  /* coalesce at t=0 */
    *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &tStart, 0.0, deltaF, &lalStrainUnit, n);
    if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC);
    memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16));
    XLALUnitDivide(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit);

    /* extrinsic parameters */
    amp0 = -pow(m_sec, 5./6.) * sqrt(5. * eta / 24.) / (cbrt(LAL_PI * LAL_PI) * r / LAL_C_SI);
    shft = LAL_TWOPI * (tStart.gpsSeconds + 1e-9 * tStart.gpsNanoSeconds);

    /* spin terms in the amplitude and phase (in terms of the reduced
     * spin parameter */
    psi3S = 113.*chi/3.;
    psi4S = 63845.*(-81. + 4.*eta)*chi*chi/(8.*pow(-113. + 76.*eta, 2.));
    psi5S = -565.*(-146597. + 135856.*eta + 17136.*eta*eta)*chi/(2268.*(-113. + 76.*eta));

    alpha3S = (113.*chi)/24.;
    alpha4S = (12769.*chi*chi*(-81. + 4.*eta))/(32.*pow(-113. + 76.*eta,2));
    alpha5S = (-113.*chi*(502429. - 591368.*eta + 1680*eta*eta))/(16128.*(-113 + 76*eta));

    /* tidal terms in the phase */
    psi10T2 = -24./xi2 * (1. + 11. * xi1) * lam2 * xi2*xi2*xi2*xi2*xi2;
    psi10T1 = -24./xi1 * (1. + 11. * xi2) * lam1 * xi1*xi1*xi1*xi1*xi1;
    psi12T2 = -5./28./xi2 * (3179. - 919.* xi2 - 2286.* xi2*xi2 + 260.* xi2*xi2*xi2)* lam2 * xi2*xi2*xi2*xi2*xi2;
    psi12T1 = -5./28./xi1 * (3179. - 919.* xi1 - 2286.* xi1*xi1 + 260.* xi1*xi1*xi1)* lam1 * xi1*xi1*xi1*xi1*xi1;

    /* coefficients of the phase at PN orders from 0 to 3.5PN */
    psiNewt = 3./(128.*eta);
    psi2 = 3715./756. + 55.*eta/9.;
    psi3 = psi3S - 16.*LAL_PI;
    psi4 = 15293365./508032. + 27145.*eta/504. + 3085.*eta*eta/72. + psi4S;
    psi5 = (38645.*LAL_PI/756. - 65.*LAL_PI*eta/9. + psi5S);
    psi6 = 11583231236531./4694215680. - (640.*LAL_PI*LAL_PI)/3. - (6848.*LAL_GAMMA)/21.
             + (-5162.983708047263 + 2255.*LAL_PI*LAL_PI/12.)*eta
             + (76055.*eta*eta)/1728. - (127825.*eta*eta*eta)/1296.;
    psi6L = -6848./21.;
    psi7 = (77096675.*LAL_PI)/254016. + (378515.*LAL_PI*eta)/1512.
             - (74045.*LAL_PI*eta*eta)/756.;
    psi10 = psi10T1+psi10T2;
    psi12 = psi12T1+psi12T2;

    /* amplitude coefficients */
    alpha2 = 1.1056547619047619 + (11*eta)/8.;
    alpha3 = -LAL_TWOPI + alpha3S;
    alpha4 = 0.8939214212884228 + (18913*eta)/16128. + (1379*eta*eta)/1152. + alpha4S;
    alpha5 = (-4757*LAL_PI)/1344. + (57*eta*LAL_PI)/16. + alpha5S;
    alpha6 = -58.601030974347324 + (3526813753*eta)/2.7869184e7 -
                (1041557*eta*eta)/258048. + (67999*eta*eta*eta)/82944. +
                (10*LAL_PI*LAL_PI)/3. - (451*eta*LAL_PI*LAL_PI)/96.;
    alpha6L = 856/105.;
    alpha7 = (-5111593*LAL_PI)/2.709504e6 - (72221*eta*LAL_PI)/24192. -
                (1349*eta*eta*LAL_PI)/24192.;

    /* select the terms according to the PN order chosen */
    switch (ampO) {
        case 0:
        case 1:
            alpha2 = 0.;
        case 2:
            alpha3 = 0.;
        case 3:
            alpha4 = 0.;
        case 4:
            alpha5 = 0.;
        case 5:
            alpha6 = 0.;
            alpha6L = 0.;
        case 6:
            alpha7 = 0.;
        default:
            break;
    }

    switch (phaseO) {
        case 0:
        case 1:
            psi2 = 0.;
        case 2:
            psi3 = 0.;
        case 3:
            psi4 = 0.;
        case 4:
            psi5 = 0.;
        case 5:
            psi6 = 0.;
            psi6L = 0.;
        case 6:
            psi7 = 0.;
        default:
            break;
    }

    /* Fill with non-zero vals from fStart to lesser of fEnd, fISCO */
    iStart = (size_t) ceil(fStart / deltaF);
    data = (*htilde)->data->data;
    const REAL8 logv0=log(v0);
    const REAL8 log4=log(4.0);
    
    for (i = iStart; i < n; i++) {
        /* fourier frequency corresponding to this bin */
        const REAL8 f = i * deltaF;
        const REAL8 v3 = piM*f;

        /* PN expansion parameter */
        REAL8 Psi, amp;
        const REAL8 v = cbrt(v3);
	const REAL8 logv=log(v);
        const REAL8 v2 = v*v;
	const REAL8 v4 = v3*v;
	const REAL8 v5 = v4*v;
	const REAL8 v6 = v3*v3;
	const REAL8 v7 = v6*v;
        const REAL8 v10 = v5*v5;
	const REAL8 v12 = v6*v6;

        /* compute the phase and amplitude */
        Psi = psiNewt / v5 * (1.
            + psi2 * v2 + psi3 * v3 + psi4 * v4
            + psi5 * v5 * (1. + 3. * (logv - logv0))
            + (psi6 + psi6L * (log4 + logv)) * v6 + psi7 * v7)
            + psi10 * v10 + psi12 * v12;

        amp = amp0 * pow(f, mSevenBySix) * (1.
            + alpha2 * v2 + alpha3 * v3 + alpha4 * v4 + alpha5 * v5
            + (alpha6 + alpha6L * (LAL_GAMMA + (log4 + logv))) * v6
            + alpha7 * v7);

        data[i] = amp * cos(Psi + shft * f - 2.*phic - LAL_PI_4) - I * (amp * sin(Psi + shft * f - 2.*phic - LAL_PI_4));
    }

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

  ConfigVariables XLAL_INIT_DECL(config);
  UserVariables_t XLAL_INIT_DECL(uvar);

  /* register user-variables */

  XLAL_CHECK ( XLALInitUserVars ( &uvar ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* read cmdline & cfgfile  */
  BOOLEAN should_exit = 0;
  XLAL_CHECK( XLALUserVarReadAllInput( &should_exit, argc, argv ) == XLAL_SUCCESS, XLAL_EFUNC );
  if ( should_exit ) {
    exit(1);
  }

  if ( uvar.version )
    {
      XLALOutputVersionString ( stdout, lalDebugLevel );
      exit(0);
    }

  /* basic setup and initializations */
  XLAL_CHECK ( XLALInitCode( &config, &uvar, argv[0] ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* ----- allocate memory for AM-coeffs ----- */
  AMCoeffs AMold, AMnew1, AMnew2;	/**< containers holding AM-coefs computed by 3 different AM functions */
  AMold.a = XLALCreateREAL4Vector ( 1 );
  AMold.b = XLALCreateREAL4Vector ( 1 );
  AMnew1.a = XLALCreateREAL4Vector ( 1 );
  AMnew1.b = XLALCreateREAL4Vector ( 1 );
  AMnew2.a = XLALCreateREAL4Vector ( 1 );
  AMnew2.b = XLALCreateREAL4Vector ( 1 );

  XLAL_CHECK ( AMold.a && AMold.b && AMnew1.a && AMnew1.b && AMnew2.a && AMnew2.a, XLAL_ENOMEM, "Failed to XLALCreateREAL4Vector ( 1 )\n" );

  /* ----- get detector-state series ----- */
  DetectorStateSeries *detStates = NULL;
  XLAL_CHECK ( (detStates = XLALGetDetectorStates ( config.timestamps, config.det, config.edat, 0 )) != NULL, XLAL_EFUNC );

  /* ----- compute associated SSB timing info ----- */
  SSBtimes *tSSB = XLALGetSSBtimes ( detStates, config.skypos, config.timeGPS, SSBPREC_RELATIVISTIC );
  XLAL_CHECK ( tSSB != NULL, XLAL_EFUNC, "XLALGetSSBtimes() failed with xlalErrno = %d\n", xlalErrno );

  /* ===== 1) compute AM-coeffs the 'old way': [used in CFSv1] ===== */
  BarycenterInput XLAL_INIT_DECL(baryinput);
  AMCoeffsParams XLAL_INIT_DECL(amParams);
  EarthState earth;

  baryinput.site.location[0] = config.det->location[0]/LAL_C_SI;
  baryinput.site.location[1] = config.det->location[1]/LAL_C_SI;
  baryinput.site.location[2] = config.det->location[2]/LAL_C_SI;
  baryinput.alpha = config.skypos.longitude;
  baryinput.delta = config.skypos.latitude;
  baryinput.dInv = 0.e0;

  /* amParams structure to compute a(t) and b(t) */
  amParams.das = XLALMalloc(sizeof(*amParams.das));
  amParams.das->pSource = XLALMalloc(sizeof(*amParams.das->pSource));
  amParams.baryinput = &baryinput;
  amParams.earth = &earth;
  amParams.edat = config.edat;
  amParams.das->pDetector = config.det;
  amParams.das->pSource->equatorialCoords.longitude = config.skypos.longitude;
  amParams.das->pSource->equatorialCoords.latitude = config.skypos.latitude;
  amParams.das->pSource->orientation = 0.0;
  amParams.das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
  amParams.polAngle = 0;

  LAL_CALL ( LALComputeAM ( &status, &AMold, config.timestamps->data, &amParams), &status);

  XLALFree ( amParams.das->pSource );
  XLALFree ( amParams.das );


  /* ===== 2) compute AM-coeffs the 'new way' using LALNewGetAMCoeffs() */
  LALGetAMCoeffs ( &status, &AMnew1, detStates, config.skypos );
  if ( status.statusCode ) {
    XLALPrintError ("%s: call to LALGetAMCoeffs() failed, status = %d\n\n", __func__, status.statusCode );
    XLAL_ERROR (  status.statusCode & XLAL_EFUNC );
  }

  /* ===== 3) compute AM-coeffs the 'newer way' using LALNewGetAMCoeffs() [used in CFSv2] */
  LALNewGetAMCoeffs ( &status, &AMnew2, detStates, config.skypos );
  if ( status.statusCode ) {
    XLALPrintError ("%s: call to LALNewGetAMCoeffs() failed, status = %d\n\n", __func__, status.statusCode );
    XLAL_ERROR (  status.statusCode & XLAL_EFUNC );
  }

  /* ===== 4) use standalone version of the above [used in FstatMetric_v2] */
  REAL8 a0,b0;
  if ( XLALComputeAntennaPatternCoeffs ( &a0, &b0, &config.skypos, &config.timeGPS, config.det, config.edat ) != XLAL_SUCCESS ) {
    XLALPrintError ("%s: XLALComputeAntennaPatternCoeffs() failed.\n", __func__ );
    XLAL_ERROR ( XLAL_EFUNC );
  }


  /* ==================== output the results ==================== */
  printf ("\n");
  printf ("----- Input parameters:\n");
  printf ("tGPS = { %d, %d }\n", config.timeGPS.gpsSeconds, config.timeGPS.gpsNanoSeconds );
  printf ("Detector = %s\n", config.det->frDetector.name );
  printf ("Sky position: longitude = %g rad, latitude = %g rad [equatorial coordinates]\n", config.skypos.longitude, config.skypos.latitude );
  printf ("\n");

  printf ("----- Antenna pattern functions (a,b):\n");
  printf ("LALComputeAM:                    ( %-12.8g, %-12.8g)  [REAL4]\n", AMold.a->data[0], AMold.b->data[0] );
  printf ("LALGetAMCoeffs:                  ( %-12.8g, %-12.8g)  [REAL4]\n", AMnew1.a->data[0], AMnew1.b->data[0] );
  printf ("LALNewGetAMCoeffs:               ( %-12.8g, %-12.8g)  [REAL4]\n", AMnew2.a->data[0]/config.sinzeta, AMnew2.b->data[0]/config.sinzeta );
  printf ("XLALComputeAntennaPatternCoeffs: ( %-12.8g, %-12.8g)  [REAL8]\n", a0/config.sinzeta, b0/config.sinzeta );
  printf ("\n");

  printf ("----- Detector & Earth state:\n");
  REAL8 *pos = detStates->data[0].rDetector;
  printf ("Detector position [ICRS J2000. Units=sec]: rDet = {%g, %g, %g}\n", pos[0], pos[1], pos[2] );
  REAL8 *vel = detStates->data[0].vDetector;
  printf ("Detector velocity [ICRS J2000. Units=c]:   vDet = {%g, %g, %g}\n", vel[0], vel[1], vel[2] );
  printf ("Local mean sideral time: LMST = %g rad\n", detStates->data[0].LMST);
  printf ("\n");
  printf ("----- SSB timing data:\n");
  printf ("TOA difference tSSB - tDet = %g s\n", tSSB->DeltaT->data[0] );
  printf ("TOA rate of change dtSSB/dtDet - 1 = %g\n", tSSB->Tdot->data[0] - 1.0 );
  printf ("\n\n");


  /* ----- done: free all memory */
  XLAL_CHECK ( XLALDestroyConfig( &config ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLALDestroyDetectorStateSeries ( detStates );

  XLALDestroyREAL4Vector ( AMold.a );
  XLALDestroyREAL4Vector ( AMold.b );
  XLALDestroyREAL4Vector ( AMnew1.a );
  XLALDestroyREAL4Vector ( AMnew1.b );
  XLALDestroyREAL4Vector ( AMnew2.a );
  XLALDestroyREAL4Vector ( AMnew2.b );

  XLALDestroyREAL8Vector ( tSSB->DeltaT );
  XLALDestroyREAL8Vector ( tSSB->Tdot );
  XLALFree (tSSB);

  LALCheckMemoryLeaks();

  return 0;
} /* main */
예제 #22
0
// ---------- main ----------
int
main ( int argc, char *argv[] )
{
  XLAL_CHECK ( argc == 1, XLAL_EINVAL, "No input arguments allowed.\n" );
  XLAL_CHECK ( argv != NULL, XLAL_EINVAL );

  // ----- load ephemeris
  EphemerisData *ephem;
  XLAL_CHECK ( (ephem = XLALInitBarycenter ( TEST_DATA_DIR "earth00-19-DE405.dat.gz", TEST_DATA_DIR "sun00-19-DE405.dat.gz" )) != NULL, XLAL_EFUNC );

  // ----- setup injection and data parameters
  LALStringVector *detNames = NULL;
  XLAL_CHECK ( (detNames = XLALCreateStringVector ( "H1", "L1", NULL )) != NULL, XLAL_EFUNC );
  UINT4 numDetectors = detNames->length;

  // generate and assume some gaussian noise floors
  MultiNoiseFloor XLAL_INIT_DECL(injectSqrtSX);
  MultiNoiseFloor XLAL_INIT_DECL(assumeSqrtSX);
  injectSqrtSX.length = numDetectors;
  assumeSqrtSX.length = numDetectors;
  for ( UINT4 X = 0; X < numDetectors; X ++ )
    {
      injectSqrtSX.sqrtSn[X] = 0; // don't inject random noise to keep errors deterministic and informative (resampling differs much more on noise)
      assumeSqrtSX.sqrtSn[X] = 1.0 + 2.0*X;
    }

  LIGOTimeGPS startTime = {711595934, 0};
  REAL8 Tspan = 20 * 3600;
  LIGOTimeGPS endTime = startTime;
  XLALGPSAdd( &endTime, Tspan );
  REAL8 Tsft = 1800;

  LIGOTimeGPS refTime = { startTime.gpsSeconds - 2.3 * Tspan, 0 };

  MultiLIGOTimeGPSVector *multiTimestamps;
  XLAL_CHECK ( ( multiTimestamps = XLALCalloc ( 1, sizeof(*multiTimestamps))) != NULL, XLAL_ENOMEM );
  XLAL_CHECK ( ( multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(multiTimestamps->data[0]) )) != NULL, XLAL_ENOMEM );
  multiTimestamps->length = numDetectors;
  LIGOTimeGPS startTimeX = startTime;
  for ( UINT4 X=0; X < numDetectors; X ++ )
    {
      XLAL_CHECK ( (multiTimestamps->data[X] = XLALMakeTimestamps ( startTimeX, Tspan, Tsft, 0 ) ) != NULL, XLAL_EFUNC );
      XLALGPSAdd ( &startTimeX, 0.5 * Tspan );	// shift start-times by 1/2 Tspan for each detector
      Tspan *= 2.0;
    } // for X < numDetectors

  // shift a few timestamps around to create gaps
  UINT4 numSFTsPerDet = multiTimestamps->data[0]->length;
  multiTimestamps->data[0]->data[numSFTsPerDet-1].gpsSeconds += 10000;
  multiTimestamps->data[0]->data[numSFTsPerDet-2].gpsSeconds += 5000;
  multiTimestamps->data[1]->data[0].gpsSeconds -= 10000;
  multiTimestamps->data[1]->data[1].gpsSeconds -=  5000;

  SFTCatalog *catalog;
  XLAL_CHECK ( (catalog = XLALMultiAddToFakeSFTCatalog ( NULL, detNames, multiTimestamps )) != NULL, XLAL_EFUNC );

  // ----- CW sources to injet ----------
  REAL8 Freq = 100.0;

  PulsarParamsVector *injectSources;
  XLAL_CHECK ( (injectSources = XLALCreatePulsarParamsVector(1)) != NULL, XLAL_EFUNC );

  injectSources->data[0].Amp.h0   = 1;
  injectSources->data[0].Amp.cosi = 0.5;
  injectSources->data[0].Amp.psi  = 0.1;
  injectSources->data[0].Amp.phi0 = 1.2;

  REAL8 asini = 0; // 1.4;	// sco-X1 like
  REAL8 Period = 0; // 19 * 3600;// sco-X1 like
  REAL8 ecc = 0; // 0.1;	// much larger than ScoX1
  PulsarDopplerParams XLAL_INIT_DECL(Doppler);
  Doppler.Alpha = 0.5;
  Doppler.Delta = -0.5;
  Doppler.fkdot[0] = Freq;
  Doppler.fkdot[1] = -1e-9;
  Doppler.refTime = refTime;

  Doppler.asini = asini;
  Doppler.ecc = ecc;
  Doppler.tp = startTime;
  Doppler.period = Period;
  Doppler.argp = 0.5;

  injectSources->data[0].Doppler = Doppler;

  REAL8 dFreq = 0.1 / Tspan;		// 10x finer than native FFT resolution
  REAL8 mis = 0.5;
  REAL8 df1dot = sqrt( 720.0 * mis ) / (LAL_PI * Tspan * Tspan);	// metric (f-projected) stepsize for given mismatch mis
  REAL8 dSky = 1e4 / (Freq * Tspan);	// rough estimate of a 'metric' sky step, eg. Eq.(118) in \cite Prix07

  REAL8 dPeriod = 3600;
  UINT4 numFreqBins = 1000;

  UINT4 numf1dotPoints  = 2;
  UINT4 numSkyPoints    = 2;
  UINT4 numPeriodPoints = 2;

  PulsarSpinRange XLAL_INIT_DECL(spinRange);
  spinRange.refTime = refTime;
  memcpy ( &spinRange.fkdot, &injectSources->data[0].Doppler.fkdot, sizeof(spinRange.fkdot) );
  spinRange.fkdotBand[0] = (numFreqBins - 1)*dFreq - 10*LAL_REAL8_EPS;
  spinRange.fkdotBand[1] = (numf1dotPoints - 1)*df1dot - 10*LAL_REAL8_EPS;

  Doppler.fkdot[0] -= 0.4 * spinRange.fkdotBand[0];

  REAL8 minCoverFreq, maxCoverFreq;
  XLAL_CHECK ( XLALCWSignalCoveringBand ( &minCoverFreq, &maxCoverFreq, &startTime, &endTime, &spinRange, asini, Period, ecc ) == XLAL_SUCCESS, XLAL_EFUNC );

  // ----- setup optional Fstat arguments
  FstatOptionalArgs optionalArgs = FstatOptionalArgsDefaults;
  optionalArgs.injectSources = injectSources;
  optionalArgs.injectSqrtSX = &injectSqrtSX;
  optionalArgs.assumeSqrtSX = &assumeSqrtSX;

  // ----- prepare input data with injection for all available methods
  FstatInput *input[FMETHOD_END];
  FstatResults *results[FMETHOD_END];
  for ( UINT4 iMethod = FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ )
    {
      results[iMethod] = NULL;
      if ( !XLALFstatMethodIsAvailable(iMethod) ) {
        continue;
      }
      optionalArgs.FstatMethod = iMethod;
      XLAL_CHECK ( (input[iMethod] = XLALCreateFstatInput ( catalog, minCoverFreq, maxCoverFreq, dFreq, ephem, &optionalArgs )) != NULL, XLAL_EFUNC );
    }

  FstatQuantities whatToCompute = (FSTATQ_2F | FSTATQ_FAFB);
  // ----- loop over all templates {sky, f1dot, period}
  for ( UINT4 iSky = 0; iSky < numSkyPoints; iSky ++ )
    {
      for ( UINT4 if1dot = 0; if1dot < numf1dotPoints; if1dot ++ )
        {
          for ( UINT4 iPeriod = 0; iPeriod < numPeriodPoints; iPeriod ++ )
            {
              // ----- loop over all available methods and compare Fstat results
              FstatMethodType firstMethod = FMETHOD_START;
              for ( UINT4 iMethod = FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ )
                {
                  if ( !XLALFstatMethodIsAvailable(iMethod) ) {
                    continue;
                  }
                  if ( firstMethod == FMETHOD_START ) {	// keep track of first available method found
                    firstMethod = iMethod;
                  }

                  XLAL_CHECK ( XLALComputeFstat ( &results[iMethod], input[iMethod], &Doppler, numFreqBins, whatToCompute ) == XLAL_SUCCESS, XLAL_EFUNC );

                  if ( lalDebugLevel & LALINFOBIT )
                    {
                      FILE *fp;
                      char fname[1024]; XLAL_INIT_MEM ( fname );
                      snprintf ( fname, sizeof(fname)-1, "twoF%s-iSky%02d-if1dot%02d-iPeriod%02d.dat", XLALGetFstatMethodName(iMethod), iSky, if1dot, iPeriod );
                      XLAL_CHECK ( (fp = fopen ( fname, "wb" )) != NULL, XLAL_EFUNC );
                      for ( UINT4 k = 0; k < results[iMethod]->numFreqBins; k ++ )
                        {
                          REAL8 Freq0 = results[iMethod]->doppler.fkdot[0];
                          REAL8 Freq_k = Freq0 + k * results[iMethod]->dFreq;
                          if ( whatToCompute & FSTATQ_FAFB ) {
                            fprintf ( fp, "%20.16g %10.4g   %10.4g %10.4g   %10.4g %10.4g\n",
                                      Freq_k, results[iMethod]->twoF[k],
                                      crealf(results[iMethod]->Fa[k]), cimagf(results[iMethod]->Fa[k]),
                                      crealf(results[iMethod]->Fb[k]), cimagf(results[iMethod]->Fb[k])
                                      );
                          } else {
                            fprintf ( fp, "%20.16g %10.4g\n",
                                      Freq_k, results[iMethod]->twoF[k] );
                          }
                        } // for k < numFreqBins
                      fclose(fp);
                    } // if info

                  // compare to first result
                  if ( iMethod != firstMethod )
                    {
                      XLALPrintInfo ("Comparing results between method '%s' and '%s'\n", XLALGetFstatMethodName(firstMethod), XLALGetFstatMethodName(iMethod) );
                      if ( compareFstatResults ( results[firstMethod], results[iMethod] ) != XLAL_SUCCESS )
                        {
                          XLALPrintError ("Comparison between method '%s' and '%s' failed\n", XLALGetFstatMethodName(firstMethod), XLALGetFstatMethodName(iMethod) );
                          XLAL_ERROR ( XLAL_EFUNC );
                        }
                    }

                }  // for i < FMETHOD_END

              Doppler.period += dPeriod;

            } // for iPeriod < numPeriodPoints

          Doppler.fkdot[1] += df1dot;

        } // for if1dot < numf1dotPoints

      Doppler.Alpha += dSky;

    } // for iSky < numSkyPoints

  // free remaining memory
  for ( UINT4 iMethod=FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ )
    {
      if ( !XLALFstatMethodIsAvailable(iMethod) ) {
        continue;
      }
      XLALDestroyFstatInput ( input[iMethod] );
      XLALDestroyFstatResults ( results[iMethod] );
    } // for i < FMETHOD_END

  XLALDestroyPulsarParamsVector ( injectSources );
  XLALDestroySFTCatalog ( catalog );
  XLALDestroyMultiTimestamps ( multiTimestamps );
  XLALDestroyStringVector ( detNames );
  XLALDestroyEphemerisData ( ephem );

  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} // main()
static int
XLALSimIMRSpinEOBInitialConditionsPrec(
				   REAL8Vector * initConds,	/**<< OUTPUT, Initial dynamical variables */
				   const REAL8 mass1,	/**<< mass 1 */
				   const REAL8 mass2,	/**<< mass 2 */
				   const REAL8 fMin,	/**<< Initial frequency (given) */
				   const REAL8 inc,	/**<< Inclination */
				   const REAL8 spin1[],	/**<< Initial spin vector 1 */
				   const REAL8 spin2[],	/**<< Initial spin vector 2 */
				   SpinEOBParams * params	/**<< Spin EOB parameters */
)
{

#ifndef LAL_NDEBUG
	if (!initConds) {
		XLAL_ERROR(XLAL_EINVAL);
	}
#endif

	int	debugPK = 0; int printPK = 0;
  FILE* UNUSED out = NULL;

	if (printPK) {
		XLAL_PRINT_INFO("Inside the XLALSimIMRSpinEOBInitialConditionsPrec function!\n");
		XLAL_PRINT_INFO(
    "Inputs: m1 = %.16e, m2 = %.16e, fMin = %.16e, inclination = %.16e\n",
      mass1, mass2, (double)fMin, (double)inc);
		XLAL_PRINT_INFO("Inputs: mSpin1 = {%.16e, %.16e, %.16e}\n",
      spin1[0], spin1[1], spin1[2]);
		XLAL_PRINT_INFO("Inputs: mSpin2 = {%.16e, %.16e, %.16e}\n",
      spin2[0], spin2[1], spin2[2]);
		fflush(NULL);
	}
	static const int UNUSED lMax = 8;

	int		i;

	/* Variable to keep track of whether the user requested the tortoise */
	int		tmpTortoise;

	UINT4		SpinAlignedEOBversion;

	REAL8		mTotal;
	REAL8		eta;
	REAL8		omega   , v0;	/* Initial velocity and angular
					 * frequency */

	REAL8		ham;	/* Hamiltonian */

	REAL8		LnHat    [3];	/* Initial orientation of angular
					 * momentum */
	REAL8		rHat     [3];	/* Initial orientation of radial
					 * vector */
	REAL8		vHat     [3];	/* Initial orientation of velocity
					 * vector */
	REAL8		Lhat     [3];	/* Direction of relativistic ang mom */
	REAL8		qHat     [3];
	REAL8		pHat     [3];

	/* q and p vectors in Cartesian and spherical coords */
	REAL8		qCart    [3], pCart[3];
	REAL8		qSph     [3], pSph[3];

	/* We will need to manipulate the spin vectors */
	/* We will use temporary vectors to do this */
	REAL8		tmpS1    [3];
	REAL8		tmpS2    [3];
	REAL8		tmpS1Norm[3];
	REAL8		tmpS2Norm[3];

	REAL8Vector	qCartVec, pCartVec;
	REAL8Vector	s1Vec, s2Vec, s1VecNorm, s2VecNorm;
	REAL8Vector	sKerr, sStar;
	REAL8		sKerrData[3], sStarData[3];
	REAL8		a = 0.;
	//, chiS, chiA;
	//REAL8 chi1, chi2;

	/*
	 * We will need a full values vector for calculating derivs of
	 * Hamiltonian
	 */
	REAL8		sphValues[12];
	REAL8		cartValues[12];

	/* Matrices for rotating to the new basis set. */
	/* It is more convenient to calculate the ICs in a simpler basis */
	gsl_matrix     *rotMatrix = NULL;
	gsl_matrix     *invMatrix = NULL;
	gsl_matrix     *rotMatrix2 = NULL;
	gsl_matrix     *invMatrix2 = NULL;

	/* Root finding stuff for finding the spherical orbit */
	SEOBRootParams	rootParams;
	const gsl_multiroot_fsolver_type *T = gsl_multiroot_fsolver_hybrid;
	gsl_multiroot_fsolver *rootSolver = NULL;

	gsl_multiroot_function rootFunction;
	gsl_vector     *initValues = NULL;
	gsl_vector     *finalValues = NULL;
	INT4 gslStatus;
        INT4 cntGslNoProgress = 0, MAXcntGslNoProgress = 5;
        //INT4 cntGslNoProgress = 0, MAXcntGslNoProgress = 50;
        REAL8 multFacGslNoProgress = 3./5.;
	//const int	maxIter = 2000;
	const int	maxIter = 10000;

	memset(&rootParams, 0, sizeof(rootParams));

	mTotal = mass1 + mass2;
	eta = mass1 * mass2 / (mTotal * mTotal);
	memcpy(tmpS1, spin1, sizeof(tmpS1));
	memcpy(tmpS2, spin2, sizeof(tmpS2));
	memcpy(tmpS1Norm, spin1, sizeof(tmpS1Norm));
	memcpy(tmpS2Norm, spin2, sizeof(tmpS2Norm));
	for (i = 0; i < 3; i++) {
		tmpS1Norm[i] /= mTotal * mTotal;
		tmpS2Norm[i] /= mTotal * mTotal;
	}
	SpinAlignedEOBversion = params->seobCoeffs->SpinAlignedEOBversion;
	/* We compute the ICs for the non-tortoise p, and convert at the end */
	tmpTortoise = params->tortoise;
	params->tortoise = 0;

	EOBNonQCCoeffs *nqcCoeffs = NULL;
	nqcCoeffs = params->nqcCoeffs;

	/*
	 * STEP 1) Rotate to LNhat0 along z-axis and N0 along x-axis frame,
	 * where LNhat0 and N0 are initial normal to orbital plane and
	 * initial orbital separation;
	 */

	/* Set the initial orbital ang mom direction. Taken from STPN code */
	LnHat[0] = sin(inc);
	LnHat[1] = 0.;
	LnHat[2] = cos(inc);

	/*
	 * Set the radial direction - need to take care to avoid singularity
	 * if L is along z axis
	 */
	if (LnHat[2] > 0.9999) {
		rHat[0] = 1.;
		rHat[1] = rHat[2] = 0.;
	} else {
		REAL8		theta0 = atan(-LnHat[2] / LnHat[0]);	/* theta0 is between 0
									 * and Pi */
		rHat[0] = sin(theta0);
		rHat[1] = 0;
		rHat[2] = cos(theta0);
	}

	/* Now we can complete the triad */
	vHat[0] = CalculateCrossProductPrec(0, LnHat, rHat);
	vHat[1] = CalculateCrossProductPrec(1, LnHat, rHat);
	vHat[2] = CalculateCrossProductPrec(2, LnHat, rHat);

	NormalizeVectorPrec(vHat);

	/* Vectors BEFORE rotation */
	if (printPK) {
		for (i = 0; i < 3; i++)
			XLAL_PRINT_INFO(" LnHat[%d] = %.16e, rHat[%d] = %.16e, vHat[%d] = %.16e\n",
        i, LnHat[i], i, rHat[i], i, vHat[i]);

		XLAL_PRINT_INFO("\n\n");
		for (i = 0; i < 3; i++)
			XLAL_PRINT_INFO(" s1[%d] = %.16e, s2[%d] = %.16e\n", i, tmpS1[i], i, tmpS2[i]);
    fflush(NULL);
	}

	/* Allocate and compute the rotation matrices */
	XLAL_CALLGSL(rotMatrix = gsl_matrix_alloc(3, 3));
	XLAL_CALLGSL(invMatrix = gsl_matrix_alloc(3, 3));
	if (!rotMatrix || !invMatrix) {
		if (rotMatrix)
			gsl_matrix_free(rotMatrix);
		if (invMatrix)
			gsl_matrix_free(invMatrix);
		XLAL_ERROR(XLAL_ENOMEM);
	}
	if (CalculateRotationMatrixPrec(rotMatrix, invMatrix, rHat, vHat, LnHat) == XLAL_FAILURE) {
		gsl_matrix_free(rotMatrix);
		gsl_matrix_free(invMatrix);
		XLAL_ERROR(XLAL_ENOMEM);
	}
	/* Rotate the orbital vectors and spins */
	ApplyRotationMatrixPrec(rotMatrix, rHat);
	ApplyRotationMatrixPrec(rotMatrix, vHat);
	ApplyRotationMatrixPrec(rotMatrix, LnHat);
	ApplyRotationMatrixPrec(rotMatrix, tmpS1);
	ApplyRotationMatrixPrec(rotMatrix, tmpS2);
	ApplyRotationMatrixPrec(rotMatrix, tmpS1Norm);
	ApplyRotationMatrixPrec(rotMatrix, tmpS2Norm);

	/* See if Vectors have been rotated fine */
	if (printPK) {
		XLAL_PRINT_INFO("\nAfter applying rotation matrix:\n\n");
		for (i = 0; i < 3; i++)
			XLAL_PRINT_INFO(" LnHat[%d] = %.16e, rHat[%d] = %.16e, vHat[%d] = %.16e\n",
                i, LnHat[i], i, rHat[i], i, vHat[i]);

		XLAL_PRINT_INFO("\n");
		for (i = 0; i < 3; i++)
			XLAL_PRINT_INFO(" s1[%d] = %.16e, s2[%d] = %.16e\n", i, tmpS1[i], i, tmpS2[i]);

    fflush(NULL);
	}
	/*
	 * STEP 2) After rotation in STEP 1, in spherical coordinates, phi0
	 * and theta0 are given directly in Eq. (4.7), r0, pr0, ptheta0 and
	 * pphi0 are obtained by solving Eqs. (4.8) and (4.9) (using
	 * gsl_multiroot_fsolver). At this step, we find initial conditions
	 * for a spherical orbit without radiation reaction.
	 */

  /* Initialise the gsl stuff */
	XLAL_CALLGSL(rootSolver = gsl_multiroot_fsolver_alloc(T, 3));
	if (!rootSolver) {
		gsl_matrix_free(rotMatrix);
		gsl_matrix_free(invMatrix);
		XLAL_ERROR(XLAL_ENOMEM);
	}
	XLAL_CALLGSL(initValues = gsl_vector_calloc(3));
	if (!initValues) {
		gsl_multiroot_fsolver_free(rootSolver);
		gsl_matrix_free(rotMatrix);
		gsl_matrix_free(invMatrix);
		XLAL_ERROR(XLAL_ENOMEM);
	}

	rootFunction.f = XLALFindSphericalOrbitPrec;
	rootFunction.n = 3;
	rootFunction.params = &rootParams;

	/* Calculate the initial velocity from the given initial frequency */
	omega = LAL_PI * mTotal * LAL_MTSUN_SI * fMin;
	v0 = cbrt(omega);

	/* Given this, we can start to calculate the initial conditions */
	/* for spherical coords in the new basis */
	rootParams.omega = omega;
	rootParams.params = params;

	/* To start with, we will just assign Newtonian-ish ICs to the system */
	rootParams.values[0] = scale1 * 1. / (v0 * v0);	/* Initial r */
	rootParams.values[4] = scale2 * v0;	            /* Initial p */
	rootParams.values[5] = scale3 * 1e-3;
	//PK
  memcpy(rootParams.values + 6, tmpS1, sizeof(tmpS1));
	memcpy(rootParams.values + 9, tmpS2, sizeof(tmpS2));

	if (printPK) {
    XLAL_PRINT_INFO("ICs guess: x = %.16e, py = %.16e, pz = %.16e\n",
      rootParams.values[0]/scale1, rootParams.values[4]/scale2,
      rootParams.values[5]/scale3);
    fflush(NULL);
  }

	gsl_vector_set(initValues, 0, rootParams.values[0]);
	gsl_vector_set(initValues, 1, rootParams.values[4]);
  gsl_vector_set(initValues, 2, rootParams.values[5]);

	gsl_multiroot_fsolver_set(rootSolver, &rootFunction, initValues);

	/* We are now ready to iterate to find the solution */
	i = 0;

  if(debugPK){ out = fopen("ICIterations.dat", "w"); }
	do {
		XLAL_CALLGSL(gslStatus = gsl_multiroot_fsolver_iterate(rootSolver));
		if (debugPK) {
      fprintf( out, "%d\t", i );

      /* Write to file */
      fprintf( out, "%.16e\t%.16e\t%.16e\t",
        rootParams.values[0]/scale1, rootParams.values[4]/scale2,
        rootParams.values[5]/scale3 );

      /* Residual Function values whose roots we are trying to find */
      finalValues = gsl_multiroot_fsolver_f(rootSolver);

      /* Write to file */
      fprintf( out, "%.16e\t%.16e\t%.16e\t",
        gsl_vector_get(finalValues, 0),
        gsl_vector_get(finalValues, 1),
        gsl_vector_get(finalValues, 2) );

      /* Step sizes in each of function variables */
      finalValues = gsl_multiroot_fsolver_dx(rootSolver);

      /* Write to file */
      fprintf( out, "%.16e\t%.16e\t%.16e\t%d\n",
        gsl_vector_get(finalValues, 0)/scale1,
        gsl_vector_get(finalValues, 1)/scale2,
        gsl_vector_get(finalValues, 2)/scale3,
        gslStatus );
		}

    if (gslStatus == GSL_ENOPROG || gslStatus == GSL_ENOPROGJ) {
      XLAL_PRINT_INFO(
        "\n NO PROGRESS being made by Spherical orbit root solver\n");

      /* Print Residual Function values whose roots we are trying to find */
      finalValues = gsl_multiroot_fsolver_f(rootSolver);
      XLAL_PRINT_INFO("Function value here given by the following:\n");
      XLAL_PRINT_INFO(" F1 = %.16e, F2 = %.16e, F3 = %.16e\n",
          gsl_vector_get(finalValues, 0),
		       gsl_vector_get(finalValues, 1), gsl_vector_get(finalValues, 2));

      /* Print Step sizes in each of function variables */
      finalValues = gsl_multiroot_fsolver_dx(rootSolver);
//      XLAL_PRINT_INFO("Stepsizes in each dimension:\n");
//      XLAL_PRINT_INFO(" x = %.16e, py = %.16e, pz = %.16e\n",
//          gsl_vector_get(finalValues, 0)/scale1,
//	       gsl_vector_get(finalValues, 1)/scale2,
//          gsl_vector_get(finalValues, 2)/scale3);

      /* Only allow this flag to be caught MAXcntGslNoProgress no. of times */
      cntGslNoProgress += 1;
      if (cntGslNoProgress >= MAXcntGslNoProgress) {
        cntGslNoProgress = 0;

        if(multFacGslNoProgress < 1.){ multFacGslNoProgress *= 1.02; }
        else{ multFacGslNoProgress /= 1.01; }

      } 
      /* Now that no progress is being made, we need to reset the initial guess
       * for the (r,pPhi, pTheta) and reset the integrator */
      rootParams.values[0] = scale1 * 1. / (v0 * v0);	/* Initial r */
      rootParams.values[4] = scale2 * v0;	            /* Initial p */
      if( cntGslNoProgress % 2 )
        rootParams.values[5] = scale3 * 1e-3 / multFacGslNoProgress;
      else
        rootParams.values[5] = scale3 * 1e-3 * multFacGslNoProgress;
      //PK
      memcpy(rootParams.values + 6, tmpS1, sizeof(tmpS1));
      memcpy(rootParams.values + 9, tmpS2, sizeof(tmpS2));

      if (printPK) {
        XLAL_PRINT_INFO("New ICs guess: x = %.16e, py = %.16e, pz = %.16e\n",
                rootParams.values[0]/scale1, rootParams.values[4]/scale2,
                rootParams.values[5]/scale3);
        fflush(NULL);
      }

      gsl_vector_set(initValues, 0, rootParams.values[0]);
      gsl_vector_set(initValues, 1, rootParams.values[4]);
      gsl_vector_set(initValues, 2, rootParams.values[5]);
      gsl_multiroot_fsolver_set(rootSolver, &rootFunction, initValues);
    }
    else if (gslStatus == GSL_EBADFUNC) {
      XLALPrintError(
      "Inf or Nan encountered in evaluluation of spherical orbit Eqn\n");
			gsl_multiroot_fsolver_free(rootSolver);
			gsl_vector_free(initValues);
			gsl_matrix_free(rotMatrix);
			gsl_matrix_free(invMatrix);
			XLAL_ERROR(XLAL_EDOM);
    }
		else if (gslStatus != GSL_SUCCESS) {
			XLALPrintError("Error in GSL iteration function!\n");
			gsl_multiroot_fsolver_free(rootSolver);
			gsl_vector_free(initValues);
			gsl_matrix_free(rotMatrix);
			gsl_matrix_free(invMatrix);
			XLAL_ERROR(XLAL_EDOM);
		}

    /* different ways to test convergence of the method */
		XLAL_CALLGSL(gslStatus = gsl_multiroot_test_residual(rootSolver->f, 1.0e-8));
    /*XLAL_CALLGSL(gslStatus= gsl_multiroot_test_delta(
          gsl_multiroot_fsolver_dx(rootSolver),
          gsl_multiroot_fsolver_root(rootSolver),
          1.e-8, 1.e-5));*/
		i++;
	}
	while (gslStatus == GSL_CONTINUE && i <= maxIter);

  if(debugPK) { fflush(NULL); fclose(out); }

	if (i > maxIter && gslStatus != GSL_SUCCESS) {
		gsl_multiroot_fsolver_free(rootSolver);
		gsl_vector_free(initValues);
		gsl_matrix_free(rotMatrix);
		gsl_matrix_free(invMatrix);
		//XLAL_ERROR(XLAL_EMAXITER);
		XLAL_ERROR(XLAL_EDOM);
	}
	finalValues = gsl_multiroot_fsolver_root(rootSolver);

	if (printPK) {
		XLAL_PRINT_INFO("Spherical orbit conditions here given by the following:\n");
		XLAL_PRINT_INFO(" x = %.16e, py = %.16e, pz = %.16e\n",
           gsl_vector_get(finalValues, 0)/scale1,
		       gsl_vector_get(finalValues, 1)/scale2,
           gsl_vector_get(finalValues, 2)/scale3);
	}
	memset(qCart, 0, sizeof(qCart));
	memset(pCart, 0, sizeof(pCart));

	qCart[0] = gsl_vector_get(finalValues, 0)/scale1;
	pCart[1] = gsl_vector_get(finalValues, 1)/scale2;
	pCart[2] = gsl_vector_get(finalValues, 2)/scale3;


	/* Free the GSL root finder, since we're done with it */
	gsl_multiroot_fsolver_free(rootSolver);
	gsl_vector_free(initValues);


	/*
	 * STEP 3) Rotate to L0 along z-axis and N0 along x-axis frame, where
	 * L0 is the initial orbital angular momentum and L0 is calculated
	 * using initial position and linear momentum obtained in STEP 2.
	 */

	/* Now we can calculate the relativistic L and rotate to a new basis */
	memcpy(qHat, qCart, sizeof(qCart));
	memcpy(pHat, pCart, sizeof(pCart));

	NormalizeVectorPrec(qHat);
	NormalizeVectorPrec(pHat);

	Lhat[0] = CalculateCrossProductPrec(0, qHat, pHat);
	Lhat[1] = CalculateCrossProductPrec(1, qHat, pHat);
	Lhat[2] = CalculateCrossProductPrec(2, qHat, pHat);

	NormalizeVectorPrec(Lhat);

	XLAL_CALLGSL(rotMatrix2 = gsl_matrix_alloc(3, 3));
	XLAL_CALLGSL(invMatrix2 = gsl_matrix_alloc(3, 3));

	if (CalculateRotationMatrixPrec(rotMatrix2, invMatrix2, qHat, pHat, Lhat) == XLAL_FAILURE) {
		gsl_matrix_free(rotMatrix);
		gsl_matrix_free(invMatrix);
		XLAL_ERROR(XLAL_ENOMEM);
	}
	ApplyRotationMatrixPrec(rotMatrix2, rHat);
	ApplyRotationMatrixPrec(rotMatrix2, vHat);
	ApplyRotationMatrixPrec(rotMatrix2, LnHat);
	ApplyRotationMatrixPrec(rotMatrix2, tmpS1);
	ApplyRotationMatrixPrec(rotMatrix2, tmpS2);
	ApplyRotationMatrixPrec(rotMatrix2, tmpS1Norm);
	ApplyRotationMatrixPrec(rotMatrix2, tmpS2Norm);
	ApplyRotationMatrixPrec(rotMatrix2, qCart);
	ApplyRotationMatrixPrec(rotMatrix2, pCart);

        gsl_matrix_free(rotMatrix);
        gsl_matrix_free(rotMatrix2);

        if (printPK) {
		XLAL_PRINT_INFO("qCart after rotation2 %3.10f %3.10f %3.10f\n", qCart[0], qCart[1], qCart[2]);
		XLAL_PRINT_INFO("pCart after rotation2 %3.10f %3.10f %3.10f\n", pCart[0], pCart[1], pCart[2]);
		XLAL_PRINT_INFO("S1 after rotation2 %3.10f %3.10f %3.10f\n", tmpS1Norm[0], tmpS1Norm[1], tmpS1Norm[2]);
		XLAL_PRINT_INFO("S2 after rotation2 %3.10f %3.10f %3.10f\n", tmpS2Norm[0], tmpS2Norm[1], tmpS2Norm[2]);
	}
	/*
	 * STEP 4) In the L0-N0 frame, we calculate (dE/dr)|sph using Eq.
	 * (4.14), then initial dr/dt using Eq. (4.10), and finally pr0 using
	 * Eq. (4.15).
	 */

	/* Now we can calculate the flux. Change to spherical co-ords */
	CartesianToSphericalPrec(qSph, pSph, qCart, pCart);
	memcpy(sphValues, qSph, sizeof(qSph));
	memcpy(sphValues + 3, pSph, sizeof(pSph));
	memcpy(sphValues + 6, tmpS1, sizeof(tmpS1));
	memcpy(sphValues + 9, tmpS2, sizeof(tmpS2));

	memcpy(cartValues, qCart, sizeof(qCart));
	memcpy(cartValues + 3, pCart, sizeof(pCart));
	memcpy(cartValues + 6, tmpS1, sizeof(tmpS1));
	memcpy(cartValues + 9, tmpS2, sizeof(tmpS2));

	REAL8		dHdpphi , d2Hdr2, d2Hdrdpphi;
	REAL8		rDot    , dHdpr, flux, dEdr;

	d2Hdr2 = XLALCalculateSphHamiltonianDeriv2Prec(0, 0, sphValues, params);
	d2Hdrdpphi = XLALCalculateSphHamiltonianDeriv2Prec(0, 5, sphValues, params);

	if (printPK)
		XLAL_PRINT_INFO("d2Hdr2 = %.16e, d2Hdrdpphi = %.16e\n", d2Hdr2, d2Hdrdpphi);

	/* New code to compute derivatives w.r.t. cartesian variables */

	REAL8		tmpDValues[14];
	int UNUSED	status;
	for (i = 0; i < 3; i++) {
		cartValues[i + 6] /= mTotal * mTotal;
		cartValues[i + 9] /= mTotal * mTotal;
	}
    UINT4 oldignoreflux = params->ignoreflux;
    params->ignoreflux = 1;
	status = XLALSpinPrecHcapNumericalDerivative(0, cartValues, tmpDValues, params);
    params->ignoreflux = oldignoreflux;
	for (i = 0; i < 3; i++) {
		cartValues[i + 6] *= mTotal * mTotal;
		cartValues[i + 9] *= mTotal * mTotal;
	}

	dHdpphi = tmpDValues[1] / sqrt(cartValues[0] * cartValues[0] + cartValues[1] * cartValues[1] + cartValues[2] * cartValues[2]);
	//XLALSpinPrecHcapNumDerivWRTParam(4, cartValues, params) / sphValues[0];

	dEdr = -dHdpphi * d2Hdr2 / d2Hdrdpphi;

	if (printPK)
		XLAL_PRINT_INFO("d2Hdr2 = %.16e d2Hdrdpphi = %.16e dHdpphi = %.16e\n",
            d2Hdr2, d2Hdrdpphi, dHdpphi);

	if (d2Hdr2 != 0.0) {
		/* We will need to calculate the Hamiltonian to get the flux */
		s1Vec.length = s2Vec.length = s1VecNorm.length = s2VecNorm.length = sKerr.length = sStar.length = 3;
		s1Vec.data = tmpS1;
		s2Vec.data = tmpS2;
		s1VecNorm.data = tmpS1Norm;
		s2VecNorm.data = tmpS2Norm;
		sKerr.data = sKerrData;
		sStar.data = sStarData;

		qCartVec.length = pCartVec.length = 3;
		qCartVec.data = qCart;
		pCartVec.data = pCart;

		//chi1 = tmpS1[0] * LnHat[0] + tmpS1[1] * LnHat[1] + tmpS1[2] * LnHat[2];
		//chi2 = tmpS2[0] * LnHat[0] + tmpS2[1] * LnHat[1] + tmpS2[2] * LnHat[2];

		//if (debugPK)
			//XLAL_PRINT_INFO("magS1 = %.16e, magS2 = %.16e\n", chi1, chi2);

		//chiS = 0.5 * (chi1 / (mass1 * mass1) + chi2 / (mass2 * mass2));
		//chiA = 0.5 * (chi1 / (mass1 * mass1) - chi2 / (mass2 * mass2));

		XLALSimIMRSpinEOBCalculateSigmaKerr(&sKerr, mass1, mass2, &s1Vec, &s2Vec);
		XLALSimIMRSpinEOBCalculateSigmaStar(&sStar, mass1, mass2, &s1Vec, &s2Vec);

		/*
		 * The a in the flux has been set to zero, but not in the
		 * Hamiltonian
		 */
		a = sqrt(sKerr.data[0] * sKerr.data[0] + sKerr.data[1] * sKerr.data[1] + sKerr.data[2] * sKerr.data[2]);
		//XLALSimIMREOBCalcSpinPrecFacWaveformCoefficients(params->eobParams->hCoeffs, mass1, mass2, eta, /* a */ 0.0, chiS, chiA);
		//XLALSimIMRCalculateSpinPrecEOBHCoeffs(params->seobCoeffs, eta, a);
		ham = XLALSimIMRSpinPrecEOBHamiltonian(eta, &qCartVec, &pCartVec, &s1VecNorm, &s2VecNorm, &sKerr, &sStar, params->tortoise, params->seobCoeffs);

		if (printPK)
			XLAL_PRINT_INFO("Stas: hamiltonian in ICs at this point is %.16e\n", ham);

		/* And now, finally, the flux */
		REAL8Vector	polarDynamics, cartDynamics;
		REAL8		polarData[4], cartData[12];

		polarDynamics.length = 4;
		polarDynamics.data = polarData;

		polarData[0] = qSph[0];
		polarData[1] = 0.;
		polarData[2] = pSph[0];
		polarData[3] = pSph[2];

		cartDynamics.length = 12;
		cartDynamics.data = cartData;

		memcpy(cartData, qCart, 3 * sizeof(REAL8));
		memcpy(cartData + 3, pCart, 3 * sizeof(REAL8));
		memcpy(cartData + 6, tmpS1Norm, 3 * sizeof(REAL8));
		memcpy(cartData + 9, tmpS2Norm, 3 * sizeof(REAL8));

		//XLAL_PRINT_INFO("Stas: starting FLux calculations\n");

		flux = XLALInspiralPrecSpinFactorizedFlux(&polarDynamics, &cartDynamics, nqcCoeffs, omega, params, ham, lMax, SpinAlignedEOBversion);
		/*
		 * flux  = XLALInspiralSpinFactorizedFlux( &polarDynamics,
		 * nqcCoeffs, omega, params, ham, lMax, SpinAlignedEOBversion
		 * );
		 */
		//XLAL_PRINT_INFO("Stas flux = %.16e \n", flux);
		//exit(0);
		flux = flux / eta;

		rDot = -flux / dEdr;
		if (debugPK) {
			XLAL_PRINT_INFO("Stas here I am 2  \n");
		}
		/*
		 * We now need dHdpr - we take it that it is safely linear up
		 * to a pr of 1.0e-3 PK: Ideally, the pr should be of the
		 * order of other momenta, in order for its contribution to
		 * the Hamiltonian to not get buried in the numerical noise
		 * in the numerically larger momenta components
		 */
		cartValues[3] = 1.0e-3;
		for (i = 0; i < 3; i++) {
			cartValues[i + 6] /= mTotal * mTotal;
			cartValues[i + 9] /= mTotal * mTotal;
		}
        oldignoreflux = params->ignoreflux;
        params->ignoreflux = 1;
        params->seobCoeffs->updateHCoeffs = 1;
		status = XLALSpinPrecHcapNumericalDerivative(0, cartValues, tmpDValues, params);
        params->ignoreflux = oldignoreflux;
		for (i = 0; i < 3; i++) {
			cartValues[i + 6] *= mTotal * mTotal;
			cartValues[i + 9] *= mTotal * mTotal;
		}
        REAL8		csi = sqrt(XLALSimIMRSpinPrecEOBHamiltonianDeltaT(params->seobCoeffs, qSph[0], eta, a)*XLALSimIMRSpinPrecEOBHamiltonianDeltaR(params->seobCoeffs, qSph[0], eta, a)) / (qSph[0] * qSph[0] + a * a);

		dHdpr = csi*tmpDValues[0];
		//XLALSpinPrecHcapNumDerivWRTParam(3, cartValues, params);

		if (debugPK) {
			XLAL_PRINT_INFO("Ingredients going into prDot:\n");
			XLAL_PRINT_INFO("flux = %.16e, dEdr = %.16e, dHdpr = %.16e, dHdpr/pr = %.16e\n", flux, dEdr, dHdpr, dHdpr / cartValues[3]);
		}
		/*
		 * We can now calculate what pr should be taking into account
		 * the flux
		 */
		pSph[0] = rDot / (dHdpr / cartValues[3]);
	} else {
		/*
		 * Since d2Hdr2 has evaluated to zero, we cannot do the
		 * above. Just set pr to zero
		 */
		//XLAL_PRINT_INFO("d2Hdr2 is zero!\n");
		pSph[0] = 0;
	}

	/* Now we are done - convert back to cartesian coordinates ) */
	SphericalToCartesianPrec(qCart, pCart, qSph, pSph);

	/*
	 * STEP 5) Rotate back to the original inertial frame by inverting
	 * the rotation of STEP 3 and then  inverting the rotation of STEP 1.
	 */

	/* Undo rotations to get back to the original basis */
	/* Second rotation */
	ApplyRotationMatrixPrec(invMatrix2, rHat);
	ApplyRotationMatrixPrec(invMatrix2, vHat);
	ApplyRotationMatrixPrec(invMatrix2, LnHat);
	ApplyRotationMatrixPrec(invMatrix2, tmpS1);
	ApplyRotationMatrixPrec(invMatrix2, tmpS2);
	ApplyRotationMatrixPrec(invMatrix2, tmpS1Norm);
	ApplyRotationMatrixPrec(invMatrix2, tmpS2Norm);
	ApplyRotationMatrixPrec(invMatrix2, qCart);
	ApplyRotationMatrixPrec(invMatrix2, pCart);

	/* First rotation */
	ApplyRotationMatrixPrec(invMatrix, rHat);
	ApplyRotationMatrixPrec(invMatrix, vHat);
	ApplyRotationMatrixPrec(invMatrix, LnHat);
	ApplyRotationMatrixPrec(invMatrix, tmpS1);
	ApplyRotationMatrixPrec(invMatrix, tmpS2);
	ApplyRotationMatrixPrec(invMatrix, tmpS1Norm);
	ApplyRotationMatrixPrec(invMatrix, tmpS2Norm);
	ApplyRotationMatrixPrec(invMatrix, qCart);
	ApplyRotationMatrixPrec(invMatrix, pCart);

        gsl_matrix_free(invMatrix);
        gsl_matrix_free(invMatrix2);

        /* If required, apply the tortoise transform */
	if (tmpTortoise) {
		REAL8		r = sqrt(qCart[0] * qCart[0] + qCart[1] * qCart[1] + qCart[2] * qCart[2]);
		REAL8		deltaR = XLALSimIMRSpinPrecEOBHamiltonianDeltaR(params->seobCoeffs, r, eta, a);
		REAL8		deltaT = XLALSimIMRSpinPrecEOBHamiltonianDeltaT(params->seobCoeffs, r, eta, a);
		REAL8		csi = sqrt(deltaT * deltaR) / (r * r + a * a);

		REAL8		pr = (qCart[0] * pCart[0] + qCart[1] * pCart[1] + qCart[2] * pCart[2]) / r;

		params->tortoise = tmpTortoise;

		if (debugPK) {
			XLAL_PRINT_INFO("Applying the tortoise to p (csi = %.26e)\n", csi);
			XLAL_PRINT_INFO("pCart = %3.10f %3.10f %3.10f\n", pCart[0], pCart[1], pCart[2]);
		}
		for (i = 0; i < 3; i++) {
			pCart[i] = pCart[i] + qCart[i] * pr * (csi - 1.) / r;
		}
	}


    /* Now copy the initial conditions back to the return vector */
	memcpy(initConds->data, qCart, sizeof(qCart));
	memcpy(initConds->data + 3, pCart, sizeof(pCart));
	memcpy(initConds->data + 6, tmpS1Norm, sizeof(tmpS1Norm));
	memcpy(initConds->data + 9, tmpS2Norm, sizeof(tmpS2Norm));

    for (i=0; i<12; i++) {
        if (fabs(initConds->data[i]) <=1.0e-15) {
            initConds->data[i] = 0.;
        }
    }

	if (debugPK) {
		XLAL_PRINT_INFO("THE FINAL INITIAL CONDITIONS:\n");
		XLAL_PRINT_INFO(" %.16e %.16e %.16e\n%.16e %.16e %.16e\n%.16e %.16e %.16e\n%.16e %.16e %.16e\n", initConds->data[0], initConds->data[1], initConds->data[2],
		       initConds->data[3], initConds->data[4], initConds->data[5], initConds->data[6], initConds->data[7], initConds->data[8],
		       initConds->data[9], initConds->data[10], initConds->data[11]);
	}
	return XLAL_SUCCESS;
}
int
XLALInspiralChooseModel(
   expnFunc         *f,
   expnCoeffs       *ak,
   InspiralTemplate *params
   )
{
   REAL8 vn, vlso;
   TofVIn in1;
   REAL8 tofv;
   void *in2;

   if (f == NULL)
      XLAL_ERROR(XLAL_EFAULT);
   if (ak == NULL)
      XLAL_ERROR(XLAL_EFAULT);
   if (params == NULL)
      XLAL_ERROR(XLAL_EFAULT);
   if (params->order == LAL_PNORDER_HALF || (INT4)params->order < 0
      || (INT4)params->order > 8)
   {
      XLALPrintError("XLAL Error - %s: PN order %d%s not supported\n", __func__,
         ((INT4)params->order)/2, ((INT4)params->order)%2?".5":"");
      XLAL_ERROR(XLAL_EINVAL);
   }

   vlso = 0;

   switch (params->order)
   {
      case LAL_PNORDER_NEWTONIAN:
      switch (params->approximant)
      {
         case AmpCorPPN:
         case Eccentricity:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
		 case SpinQuadTaylor:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
            ak->vn = ak->vlso = vlso = ak->vlsoT0;
            f->dEnergy = dEt0;
            f->flux = Ft0;
            f->phasing2 = &XLALInspiralPhasing2_0PN;
            f->timing2 = &XLALInspiralTiming2_0PN;
            f->phasing3 = &XLALInspiralPhasing3_0PN;
            f->frequency3 = &XLALInspiralFrequency3_0PN;
            break;
         case PadeT1:
         case PadeF1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
      }
      break;
      case LAL_PNORDER_HALF:
        XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
        XLAL_ERROR(XLAL_EINVAL);
        break;
      case LAL_PNORDER_ONE:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
		 case SpinQuadTaylor:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:

            ak->vn = ak->vlso = vlso = ak->vlsoT2;
            f->dEnergy = dEt2;
            f->flux = Ft2;
            f->phasing2 = &XLALInspiralPhasing2_2PN;
            f->timing2 = &XLALInspiralTiming2_2PN;
            f->phasing3 = &XLALInspiralPhasing3_2PN;
            f->frequency3 = &XLALInspiralFrequency3_2PN;
            break;
         case PadeT1:
         case PadeF1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
      }
      break;
      case LAL_PNORDER_ONE_POINT_FIVE:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
		 case SpinQuadTaylor:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
            ak->vn = ak->vlso = vlso = ak->vlsoT2;
            f->dEnergy = dEt2;
            f->flux = Ft3;
            f->phasing3 = &XLALInspiralPhasing3_3PN;
            f->frequency3 = &XLALInspiralFrequency3_3PN;
            f->phasing2 = &XLALInspiralPhasing2_3PN;
            f->timing2 = &XLALInspiralTiming2_3PN;
            break;
         case PadeT1:
            ak->vn = ak->vlso = vlso = ak->vlsoP0;
            f->dEnergy = dEp2;
            f->flux = Fp3;
            break;
         case PadeF1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
      }
      break;
      case LAL_PNORDER_TWO:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
		 case SpinQuadTaylor:
/*
   The value vlsoT4 is too large and doesn't work sometimes;
   so we use vlsoT2.
*/
            ak->vn = ak->vlso = vlso = ak->vlsoT2;
            f->dEnergy = dEt4;
            f->flux = Ft4;
            f->phasing2 = &XLALInspiralPhasing2_4PN;
            f->timing2 = &XLALInspiralTiming2_4PN;
            f->phasing3 = &XLALInspiralPhasing3_4PN;
            f->frequency3 = &XLALInspiralFrequency3_4PN;
            break;
         case PadeT1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            ak->vn = ak->vlso = vlso = ak->vlsoP4;
            f->dEnergy = dEp4;
            f->flux = Fp4;
            break;
         case PadeF1:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
      }
      break;
      case LAL_PNORDER_TWO_POINT_FIVE:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
		 case SpinQuadTaylor:
/*
   The value vlsoT4 is too large and doesn't work with 2.5 PN
   Taylor approximant; so we use vlsoT2.
*/
            ak->vn = ak->vlso = vlso = ak->vlsoT2;
            f->dEnergy = dEt4;
            f->flux = Ft5;
            f->phasing2 = &XLALInspiralPhasing2_5PN;
            f->timing2 = &XLALInspiralTiming2_5PN;
            f->phasing3 = &XLALInspiralPhasing3_5PN;
            f->frequency3 = &XLALInspiralFrequency3_5PN;
            break;
         case PadeT1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            ak->vn = ak->vlso = vlso = ak->vlsoP4;
            f->dEnergy = dEp4;
            f->flux = Fp5;
            break;
         case PadeF1:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
      }
      break;
      case LAL_PNORDER_THREE:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylorT4:
         case SpinTaylor:
         case PhenSpinTaylorRD:
	     case SpinQuadTaylor:
/*
   vlsoT6 is as yet undetermined and vlsoT4 is too large in
   certain cases (TaylorT2 crashes for (1.4,10)); using vlsoT2;
*/
            ak->vn = ak->vlso = vlso = ak->vlsoT2;
            f->dEnergy = dEt6;
            f->flux = Ft6;
            f->phasing2 = &XLALInspiralPhasing2_6PN;
            f->timing2 = &XLALInspiralTiming2_6PN;
            f->phasing3 = &XLALInspiralPhasing3_6PN;
            f->frequency3 = &XLALInspiralFrequency3_6PN;
            break;
         case PadeT1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            ak->vn = ak->vlso = vlso = ak->vlsoP6;
            f->dEnergy = dEp6;
            f->flux = Fp6;
            break;
         case PadeF1:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
      }
      break;
      case LAL_PNORDER_THREE_POINT_FIVE:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
		 case SpinQuadTaylor:
            ak->vn = ak->vlso = vlso = ak->vlsoT2;
            f->dEnergy = dEt6;
            f->flux = Ft7;
            f->phasing2 = &XLALInspiralPhasing2_7PN;
            f->timing2 = &XLALInspiralTiming2_7PN;
            f->phasing3 = &XLALInspiralPhasing3_7PN;
            f->frequency3 = &XLALInspiralFrequency3_7PN;
            break;
         case PadeT1:
         case EOB:
         case EOBNR:
         case EOBNRv2:
         case EOBNRv2HM:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            ak->vn = ak->vlso = vlso = ak->vlsoP6;
            f->dEnergy = dEp6;
            f->flux = Fp7;
            break;
         case PadeF1:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
      }
      break;
      case LAL_PNORDER_PSEUDO_FOUR:
      switch (params->approximant)
      {
         case Eccentricity:
            XLALPrintError("XLAL Error - %s: The PN order requested is not implemented for this approximant\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         case EOBNRv2:
         case EOBNRv2HM:
            ak->vn = ak->vlso = vlso = ak->vlsoPP;
            f->dEnergy = dEp6;
            f->flux = Fp8PP;
            break;
         case EOB:
         case EOBNR:
         case IMRPhenomA:
         case IMRPhenomB:
         case IMRPhenomFA:
         case IMRPhenomFB:
            ak->vn = ak->vlso = vlso = ak->vlsoP6;
            f->dEnergy = dEp6;
            f->flux = Fp7;
            break;
         case AmpCorPPN:
         case TaylorT1:
         case TaylorT2:
         case TaylorT3:
         case TaylorF1:
         case TaylorF2:
         case TaylorF2RedSpin:
         case SpinTaylorFrameless:
         case SpinTaylorT3:
         case SpinTaylor:
         case SpinTaylorT4:
         case PhenSpinTaylorRD:
         case SpinQuadTaylor:
         case PadeT1:
         case PadeF1:
         case TaylorEt:
         case TaylorT4:
         case TaylorN:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for requested PN order\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
         default:
            XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
            break;
      }
      break;
      default:
         XLALPrintError("XLAL Error - %s: Unknown PN order in switch\n", __func__);
         XLAL_ERROR(XLAL_EINVAL);
   }

   switch (params->approximant)
   {
      case AmpCorPPN:
      case TaylorT1:
      case TaylorT2:
      case TaylorT3:
      case TaylorF1:
      case EOB:
      case EOBNR:
      case PadeT1:
      case PadeF1:
      case TaylorF2:
      case TaylorF2RedSpin:
      case SpinTaylorFrameless:
      case SpinTaylorT3:
      case SpinTaylor:
      case SpinTaylorT4:
      case PhenSpinTaylorRD:
      case SpinQuadTaylor:
      case TaylorEt:
      case TaylorT4:
      case TaylorN:
         ak->flso = vlso * vlso * vlso /(LAL_PI * ak->totalmass);

         if (ak->fn)
         {
            vn = cbrt(LAL_PI * ak->totalmass * ak->fn);
            ak->vn = (vn < vlso) ? vn :  vlso;
         }

         in1.t=0.0;
         in1.v0=ak->v0;
         in1.t0=ak->t0;
         in1.vlso=ak->vlso;
         in1.totalmass = ak->totalmass;
         in1.dEnergy = f->dEnergy;
         in1.flux = f->flux;
         in1.coeffs = ak;

         in2 = (void *) &in1;

         tofv = XLALInspiralTofV(ak->vn, in2);
         if (XLAL_IS_REAL8_FAIL_NAN(tofv))
            XLAL_ERROR(XLAL_EFUNC);

         ak->tn = -tofv - ak->samplinginterval;
         params->fCutoff = ak->fn = pow(ak->vn, 3.)/(LAL_PI * ak->totalmass);
         /*
         for (v=0; v<ak->vn; v+=0.001)
         {
            FtN = Ft0(v,ak);
            printf("%e %e %e %e %e %e %e\n", v,
            Ft2(v,ak)/FtN, Ft3(v,ak)/FtN, Ft4(v,ak)/FtN, Ft5(v,ak)/FtN,
            Ft6(v,ak)/FtN, Ft7(v,ak)/FtN);
         }
         exit(0);
         */
         break;
      case BCV:
      case BCVSpin:
         ak->tn = 100.;
         break;
      case IMRPhenomA:
      case IMRPhenomB:
      case IMRPhenomFA:
      case IMRPhenomFB:
      case EOBNRv2:
      case EOBNRv2HM:
         ak->tn = 5.*ak->totalmass/(256.*ak->eta*pow(ak->v0,8.)) + 1000.*ak->totalmass;
         break;
      case Eccentricity:
         /* The eccentric waveforms contain harmonic, so similarly to amplitude corrected waveforms
          * the duration are longer than non eccentric waveform and starts at 2fl/3*/
         ak->tn = 5.*ak->totalmass/256./ak->eta/pow(LAL_PI*ak->totalmass*params->fLower/3.*2.,8./3.);
         ak->flso = vlso * vlso * vlso /(LAL_PI * ak->totalmass);
         break;
      default:
         XLALPrintError("XLAL Error - %s: Unknown case in PN approximant switch\n", __func__);
         XLAL_ERROR(XLAL_EINVAL);
   }

  return 0;
}
예제 #25
0
파일: ppe_utils.c 프로젝트: ahnitz/lalsuite
/**
 * \brief Automatically set the solar system ephemeris file based on environment variables and data time span
 *
 * This function will attempt to find Earth and Sun ephemeris files based on LAL environment variables (as set up by
 * <code> lalpulsar-user-env.(c)sh </code>) and a given start and end GPS time (presumably taken from the data that is
 * to be analysed). It requires \c LALPULSAR is installed and the \c LALPULSAR_PREFIX variable is set, which should mean
 * that ephemeris files are installed in the directory \c ${LALPULSAR_PREFIX}/share/lalpulsar/.
 *
 * \param efile [in] a string that will return the Earth ephemeris file
 * \param sfile [in] a string that will return the Sun ephemeris file
 * \param tfile [in] a string that will return the time correction file
 * \param pulsar [in] the pulsar parameters read from a .par file
 * \param gpsstart [in] the GPS time of the start of the data
 * \param gpsend [in] the GPS time of the end of the data
 *
 * \return The TimeCorrectionType e.g. TDB or TCB
 */
TimeCorrectionType XLALAutoSetEphemerisFiles( CHAR *efile, CHAR *sfile, CHAR *tfile, BinaryPulsarParams  pulsar,
                                              INT4 gpsstart, INT4 gpsend ){
  /* set the times that the ephemeris files span */
  INT4 ephemstart = 630720013; /* GPS time of Jan 1, 2000, 00:00:00 UTC */
  INT4 ephemend = 1261872015; /* GPS time of Jan 1, 2020, 00:00:00 UTC */
  CHAR *eftmp = NULL, *sftmp = NULL, *tftmp = NULL;
  TimeCorrectionType ttype = TIMECORRECTION_NONE;

  CHAR *lalpath = NULL, *lalpulsarpath = NULL;

  if( gpsstart < ephemstart || gpsend < ephemstart || gpsstart > ephemend || gpsend > ephemend ){
    XLALPrintError("Start and end times are outside the ephemeris file ranges!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  /* first check that the path to the Ephemeris files is available in the
     environment variables */
  if((lalpath = getenv("LALPULSAR_PREFIX")) == NULL){
    XLALPrintError("LALPULSAR_PREFIX environment variable not set. Cannot automatically generate ephemeris files!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  lalpulsarpath = XLALStringDuplicate( lalpath );

  if ( (lalpulsarpath = XLALStringAppend(lalpulsarpath, "/share/lalpulsar/")) == NULL ) { XLAL_ERROR(XLAL_EFUNC); }

  eftmp = XLALStringDuplicate(lalpulsarpath);
  sftmp = XLALStringDuplicate(lalpulsarpath);
  tftmp = XLALStringDuplicate(lalpulsarpath);

  eftmp = XLALStringAppend(eftmp, "earth00-19-");
  sftmp = XLALStringAppend(sftmp, "sun00-19-");

  if( pulsar.ephem == NULL ){
    /* default to use DE405 */
    eftmp = XLALStringAppend(eftmp, "DE405");
    sftmp = XLALStringAppend(sftmp, "DE405");
  }
  else{
    if( !strcmp(pulsar.ephem, "DE405") || !strcmp(pulsar.ephem, "DE200") ||
        !strcmp(pulsar.ephem, "DE414") ){
      eftmp = XLALStringAppend(eftmp, pulsar.ephem);
      sftmp = XLALStringAppend(sftmp, pulsar.ephem);
    }
    else{
      XLALPrintError("Unknown ephemeris %s in par file\n", pulsar.ephem);
      XLAL_ERROR(XLAL_EFUNC);
    }
  }

  /* add .dat extension */
  eftmp = XLALStringAppend(eftmp, ".dat.gz");
  sftmp = XLALStringAppend(sftmp, ".dat.gz");

  if ( eftmp == NULL || sftmp == NULL ) { XLAL_ERROR(XLAL_EFUNC); }

  XLALStringCopy( efile, eftmp, strlen(eftmp)+1 );
  XLALStringCopy( sfile, sftmp, strlen(sftmp)+1 );

  /* double check that the files exist */
  if( fopen(sfile, "r") == NULL || fopen(efile, "r") == NULL ){
    XLALPrintError("Error... ephemeris files not, or incorrectly, defined!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  if( pulsar.units == NULL ){
    /* default to using TCB units */
    tftmp = XLALStringAppend(tftmp, "te405_2000-2019.dat.gz");
    ttype = TIMECORRECTION_TCB;
  }
  else{
    if ( !strcmp( pulsar.units, "TDB" ) ){
      tftmp = XLALStringAppend(tftmp, "tdb_2000-2019.dat.gz");
      ttype = TIMECORRECTION_TDB;
    }
    else{
      XLALPrintError("Error... unknown units %s in par file!\n", pulsar.units);
      XLAL_ERROR(XLAL_EFUNC);
    }
  }

  if ( tftmp == NULL ) { XLAL_ERROR(XLAL_EFUNC); }

  XLALStringCopy( tfile, tftmp, strlen(tftmp)+1 );

  if( fopen(tfile, "r") == NULL ){
    XLALPrintError("Error... time ephemeris files not, or incorrectly, defined!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  return ttype;
}
예제 #26
0
///
/// Read results from a FITS file and append to new/existing output results
///
int XLALWeaveOutputResultsReadAppend(
  FITSFile *file,
  WeaveOutputResults **out,
  UINT4 toplist_limit
  )
{

  // Check input
  XLAL_CHECK( file != NULL, XLAL_EFAULT );
  XLAL_CHECK( out != NULL, XLAL_EFAULT );

  // Read reference time
  LIGOTimeGPS ref_time;
  XLAL_CHECK( XLALFITSHeaderReadGPSTime( file, "date-obs", &ref_time ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Read number of spindowns
  UINT4 nspins = 0;
  XLAL_CHECK( XLALFITSHeaderReadUINT4( file, "nspins", &nspins ) == XLAL_SUCCESS, XLAL_EFUNC );

  // ----- read elements for 'statistics_params' struct ----------
  WeaveStatisticsParams *statistics_params = XLALCalloc( 1, sizeof( *statistics_params ) );
  XLAL_CHECK( statistics_params != NULL, XLAL_ENOMEM );

  // Read list of detectors
  XLAL_CHECK( XLALFITSHeaderReadStringVector( file, "detect", &( statistics_params->detectors ) ) == XLAL_SUCCESS, XLAL_EFUNC );

  /// Number of segments
  XLAL_CHECK( XLALFITSHeaderReadUINT4( file, "segments", &( statistics_params->nsegments ) ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Read names of selected toplist statistics
  char *toplist_stats_names = NULL;
  int toplist_stats = 0;
  XLAL_CHECK( XLALFITSHeaderReadString( file, "toplists", &toplist_stats_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALParseStringValueAsUserFlag( &toplist_stats, &WeaveToplistChoices, toplist_stats_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALFree( toplist_stats_names );

  // Read names of selected extra output stats
  char *extras_names = NULL;
  int extra_stats = 0;
  XLAL_CHECK( XLALFITSHeaderReadString( file, "extras", &extras_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALParseStringValueAsUserFlag( &extra_stats, &WeaveStatisticChoices, extras_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALFree( extras_names );

  // Read names of selected recalc stats
  int recalc_stats = 0;
  BOOLEAN exists = 0;
  XLAL_CHECK( XLALFITSHeaderQueryKeyExists( file, "recalc" , &exists ) == XLAL_SUCCESS, XLAL_EFUNC );
  if ( exists ) {
    char *recalc_names = NULL;
    XLAL_CHECK( XLALFITSHeaderReadString( file, "recalc", &recalc_names ) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK( XLALParseStringValueAsUserFlag( &recalc_stats, &WeaveStatisticChoices, recalc_names ) == XLAL_SUCCESS, XLAL_EFUNC );
    XLALFree( recalc_names );
  }

  // Compute and fill the full stats-dependency map
  XLAL_CHECK( XLALWeaveStatisticsParamsSetDependencyMap( statistics_params, toplist_stats, extra_stats, recalc_stats ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Read maximum size of toplists, if not supplied
  if ( toplist_limit == 0 ) {
    XLAL_CHECK( XLALFITSHeaderReadUINT4( file, "toplimit", &toplist_limit ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Read whether to output semicoherent/coherent template indexes
  BOOLEAN toplist_tmpl_idx = 0;
  {
    exists = 0;
    XLAL_CHECK( XLALFITSHeaderQueryKeyExists( file, "toptmpli", &exists ) == XLAL_SUCCESS, XLAL_EFUNC );
    if ( exists ) {
      XLAL_CHECK( XLALFITSHeaderReadBOOLEAN( file, "toptmpli", &toplist_tmpl_idx ) == XLAL_SUCCESS, XLAL_EFUNC );
    }
  }

  if ( *out == NULL ) {

    // Create new output results
    *out = XLALWeaveOutputResultsCreate( &ref_time, nspins, statistics_params, toplist_limit, toplist_tmpl_idx );
    XLAL_CHECK( *out != NULL, XLAL_EFUNC );

  } else {

    // Check reference time
    XLAL_CHECK( XLALGPSCmp( &ref_time, &( *out )->ref_time ) == 0, XLAL_EIO, "Inconsistent reference time: %" LAL_GPS_FORMAT " != %" LAL_GPS_FORMAT, LAL_GPS_PRINT( ref_time ), LAL_GPS_PRINT( ( *out )->ref_time ) );

    // Check number of spindowns
    XLAL_CHECK( ( size_t ) nspins == ( *out )->nspins, XLAL_EIO, "Inconsistent number of spindowns: %i != %zu", nspins, ( *out )->nspins );

    // Check if list of detectors agrees
    if ( statistics_params->detectors != NULL ) {
      XLAL_CHECK( statistics_params->detectors->length == ( *out )->statistics_params->detectors->length, XLAL_EIO, "Inconsistent number of detectors: %u != %u", statistics_params->detectors->length, ( *out )->statistics_params->detectors->length );
      for ( size_t i = 0; i < statistics_params->detectors->length; ++i ) {
        XLAL_CHECK( strcmp( statistics_params->detectors->data[i], ( *out )->statistics_params->detectors->data[i] ) == 0, XLAL_EIO, "Inconsistent detectors: %s != %s", statistics_params->detectors->data[i], ( *out )->statistics_params->detectors->data[i] );
      }
    }

    // Check if number of segments agrees
    XLAL_CHECK( statistics_params->nsegments == ( *out )->statistics_params->nsegments, XLAL_EIO, "Inconsistent output per segment?: %i != %u", statistics_params->nsegments, ( *out )->statistics_params->nsegments );

    // Check list of selected toplist statistics
    if ( statistics_params->toplist_statistics != ( *out )->statistics_params->toplist_statistics ) {
      char *toplists1, *toplists2;
      toplists1 = XLALPrintStringValueOfUserFlag( ( const int * )&( statistics_params->toplist_statistics ), &WeaveToplistChoices );
      XLAL_CHECK( toplists1 != NULL, XLAL_EFUNC );
      toplists2 = XLALPrintStringValueOfUserFlag( ( const int * )&( ( *out )->statistics_params->toplist_statistics ), &WeaveToplistChoices );
      XLAL_CHECK( toplists2 != NULL, XLAL_EFUNC );
      XLALPrintError( "Inconsistent set of toplist statistics: %s != %s\n", toplists1, toplists2 );
      XLALFree( toplists1 );
      XLALFree( toplists2 );
      XLAL_ERROR( XLAL_EIO );
    }
    // Check list of selected output statistics
    for ( UINT4 istage = 0; istage < 2; ++ istage ) {
      if ( statistics_params->statistics_to_output[istage] != ( *out )->statistics_params->statistics_to_output[istage] ) {
        char *output1, *output2;
        output1 = XLALPrintStringValueOfUserFlag( ( const int * )&( statistics_params->statistics_to_output[istage] ), &WeaveStatisticChoices );
        XLAL_CHECK( output1 != NULL, XLAL_EFUNC );
        output2 = XLALPrintStringValueOfUserFlag( ( const int * )&( ( *out )->statistics_params->statistics_to_output[istage] ), &WeaveStatisticChoices );
        XLAL_CHECK( output2 != NULL, XLAL_EFUNC );
        XLALPrintError( "Inconsistent set of stage-%d output statistics: {%s} != {%s}\n", istage, output1, output2 );
        XLALFree( output1 );
        XLALFree( output2 );
        XLAL_ERROR( XLAL_EIO );
      }
    }

    XLALWeaveStatisticsParamsDestroy( statistics_params );  // Not creating a new output, so we need to free this

    // Check whether to output semicoherent/coherent template indexes
    XLAL_CHECK( !toplist_tmpl_idx == !( *out )->toplist_tmpl_idx, XLAL_EIO, "Inconsistent output template indexes? %i != %i", toplist_tmpl_idx, ( *out )->toplist_tmpl_idx );

  }

  // Read and append to toplists
  for ( size_t i = 0; i < ( *out )->ntoplists; ++i ) {
    XLAL_CHECK( XLALWeaveResultsToplistReadAppend( file, ( *out )->toplists[i] ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  return XLAL_SUCCESS;

}
/**
 * \brief Deserializes a \c PulsarDopplerParams structure from a VOTable XML document
 *
 * This function takes a VOTable XML document and deserializes (extracts)
 * the \c PulsarDopplerParams structure identified by the given name.
 *
 * \param xmlDocument [in] Pointer to the VOTable XML document containing the structure
 * \param name [in] Unique identifier of the particular \c PulsarDopplerParams structure to be deserialized
 * \param pdp [out] Pointer to an empty \c PulsarDopplerParams structure to store the deserialized instance
 *
 * \return \c XLAL_SUCCESS if the specified \c PulsarDopplerParams structure could be found and
 * deserialized successfully.
 *
 * \sa XLALVOTXML2PulsarDopplerParamsByName
 * \sa XLALGetSingleNodeContentByXPath
 *
 * \author Oliver Bock\n
 * Albert-Einstein-Institute Hannover, Germany
 */
INT4
XLALVOTDoc2PulsarDopplerParamsByName ( const xmlDocPtr xmlDocument,
                                       const char *name,
                                       PulsarDopplerParams *pdp
                                       )
{
    /* set up local variables */
    CHAR childNameRefTime[NAMESTR_MAXLEN] = {0};
    CHAR *nodeContent = NULL;

    /* sanity checks */
    if(!xmlDocument) {
        XLALPrintError("Invalid input parameter: xmlDocument\n");
        XLAL_ERROR(XLAL_EINVAL);
    }
    if(!name || strlen(name) <= 0) {
        XLALPrintError("Invalid input parameter: name\n");
        XLAL_ERROR(XLAL_EINVAL);
    }
    if(!pdp) {
        XLALPrintError("Invalid input parameter: pdp\n");
        XLAL_ERROR(XLAL_EINVAL);
    }

    /* compile child name attribute (refTime) */
    if(!strncpy(childNameRefTime, name, NAMESTR_MAXLEN) || !strncat(childNameRefTime, ".refTime", NAMESTR_MAXLEN)) {
        XLALPrintError("Child attribute preparation failed: PulsarDopplerParams.refTime\n");
        XLAL_ERROR(XLAL_EFAILED);
    }

    /* retrieve PulsarDopplerParams.refTime */
    if(XLALVOTDoc2LIGOTimeGPSByName(xmlDocument, childNameRefTime, &pdp->refTime)) {
        XLALPrintError("Error parsing XML document content: %s.refTime\n", childNameRefTime);
        XLAL_ERROR(XLAL_EFAILED);
    }

    /* retrieve PulsarDopplerParams.Alpha */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "Alpha", VOT_PARAM, VOT_VALUE );
    if(!nodeContent || sscanf( nodeContent, "%lf", &pdp->Alpha) == EOF) {
      if(nodeContent) XLALFree(nodeContent);
      XLALPrintError("Invalid node content encountered: %s.Alpha\n", name);
      XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree ( nodeContent );

    /* retrieve PulsarDopplerParams.Delta */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "Delta", VOT_PARAM, VOT_VALUE );
    if(!nodeContent || sscanf( nodeContent, "%lf", &pdp->Delta) == EOF) {
        if(nodeContent) XLALFree(nodeContent);
        XLALPrintError("Invalid node content encountered: %s.Delta\n", name);
        XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree ( nodeContent );

    /* retrieve PulsarDopplerParams.fkdot */
    if ( XLALVOTDoc2PulsarSpinsByName(xmlDocument, name, "fkdot", pdp->fkdot)) {
      XLALPrintError("Error parsing XML document content: %s.fkdot\n", name);
      XLAL_ERROR(XLAL_EFAILED);
    }


    /* compile child name attribute (tp) */
    CHAR childName[NAMESTR_MAXLEN];
    if ( snprintf ( childName, NAMESTR_MAXLEN, "%s.%s", name, "tp") >= NAMESTR_MAXLEN ) {
      XLALPrintError("Child attribute preparation failed: PulsarDopplerParams.tp\n");
      XLAL_ERROR(XLAL_EFAILED);
    }

    /* retrieve PulsarDopplerParams.tp */
    if ( XLALVOTDoc2LIGOTimeGPSByName(xmlDocument, childName, &pdp->tp)) {
      XLALPrintError("Error parsing XML document content: %s.tp\n", childName);
      XLAL_ERROR(XLAL_EFAILED);
    }

    /* retrieve PulsarDopplerParams.argp content */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "argp", VOT_PARAM, VOT_VALUE );
    if( !nodeContent || sscanf( nodeContent, "%lf", &pdp->argp) == EOF) {
      if ( nodeContent ) XLALFree (nodeContent);
      XLALPrintError("Invalid node content encountered: %s.argp\n", name);
      XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree (nodeContent);

    /* retrieve PulsarDopplerParams.asini content */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "asini", VOT_PARAM, VOT_VALUE );
    if( !nodeContent || sscanf( nodeContent, "%lf", &pdp->asini) == EOF) {
      if ( nodeContent ) XLALFree (nodeContent);
      XLALPrintError("Invalid node content encountered: %s.asini\n", name);
      XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree (nodeContent);

    /* retrieve PulsarDopplerParams.ecc content */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "ecc", VOT_PARAM, VOT_VALUE );
    if( !nodeContent || sscanf( nodeContent, "%lf", &pdp->ecc) == EOF) {
      if ( nodeContent ) XLALFree (nodeContent);
      XLALPrintError("Invalid node content encountered: %s.ecc\n", name);
      XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree (nodeContent);

    /* retrieve PulsarDopplerParams.period content */
    nodeContent = XLALReadVOTAttributeFromNamedElement ( xmlDocument, name, "period", VOT_PARAM, VOT_VALUE );
    if(!nodeContent || sscanf( nodeContent, "%lf", &pdp->period) == EOF ) {
      if(nodeContent) XLALFree (nodeContent);
      XLALPrintError("Invalid node content encountered: %s.period\n", name);
      XLAL_ERROR(XLAL_EDATA);
    }
    XLALFree(nodeContent);

    return XLAL_SUCCESS;

} /* XLALVOTDoc2PulsarDopplerParamsByName() */
예제 #28
0
int main(int argc,char *argv[])
{
  LALFrameH *frame;                /* output frame        */
  char filename[256];           /* output file name    */

  REAL8TimeSeries *ht_1;        /* H1 strain data      */
  REAL8TimeSeries *ht_2;        /* H2 strain data      */
  REAL8TimeSeries *ht_m;        /* H- strain data      */
  
  char cache_name_1[256];       /* H1 frame cache name */
  char cache_name_2[256];       /* H2 frame cache name */
  LALCache *cache_1;            /* H1 frame cache      */
  LALCache *cache_2;            /* H2 frame cache      */
  LALFrStream *stream_1;           /* H1 stream           */
  LALFrStream *stream_2;           /* H2 stream           */

  int i, p, gps_start_i, gps_end_i, start, end;
  LIGOTimeGPS gps_start, gps_end;

  cache_name_1[0]='\0';
  cache_name_2[0]='\0';
  filename[0]='\0';
  ht_1=NULL;
  ht_2=NULL;
  
  /* read arguments */
  if(argc!=4){
    printf("%s(): usage: lalapps_StringAddFrame [gps_start] [gps_end] [outdir]\n",__func__);
    printf("    There should be the H1 and H2 cache files ready in [outdir] named H1.cache and H2.cache\n");
    return 1;
  }
  gps_start_i=atoi(argv[1]);
  gps_end_i=atoi(argv[2]);
  sprintf(cache_name_1,"%s/H1.cache", argv[3]);
  sprintf(cache_name_2,"%s/H2.cache", argv[3]);
  
  /* create Frame cache, open frame stream and delete frame cache */
  cache_1 = XLALCacheImport(cache_name_1);
  if(!cache_1){
    printf("%s(): no cache named %s\n",__func__,cache_name_1);
    return 2;
  }
  stream_1 = XLALFrStreamCacheOpen(cache_1);
  XLALDestroyCache(cache_1);
  if(!stream_1){
    printf("%s(): no stream for H1\n",__func__);
    return 2;
  }
  if(!stream_1) XLAL_ERROR(XLAL_EFUNC);
 
  cache_2 = XLALCacheImport(cache_name_2);
  if(!cache_2){
    printf("%s(): no cache named %s\n",__func__,cache_name_2);
    return 3;
  }
  stream_2 = XLALFrStreamCacheOpen(cache_2);
  XLALDestroyCache(cache_2);
  if(!stream_2){
    printf("%s(): no stream for H2\n",__func__);
    return 3;
  }
 
  /* turn on checking for missing data */
  XLALFrStreamSetMode(stream_1, LAL_FR_STREAM_VERBOSE_MODE);
  XLALFrStreamSetMode(stream_2, LAL_FR_STREAM_VERBOSE_MODE);

  /* divide the time period into 128s segments */
  for(i=gps_start_i; i<gps_end_i; i+=128){
   
    start=i;
    end=Min(i+128,gps_end_i);
    printf("Building frame %d-%d...\n",start,end);
    
    /* define time segment */
    gps_start.gpsSeconds     = start;
    gps_start.gpsNanoSeconds = 0;
    gps_end.gpsSeconds     = end;
    gps_end.gpsNanoSeconds = 0;
  
    /* read H1 and H2 data */
    ht_1 = XLALFrStreamReadREAL8TimeSeries(stream_1, "H1:LSC-STRAIN", &gps_start, XLALGPSDiff(&gps_end, &gps_start), 0);
    if(!ht_1) {
      XLALFrStreamClose(stream_1);
      printf("%s(): cannot read data for H1:LSC-STRAIN\n",__func__);
    }
    ht_2 = XLALFrStreamReadREAL8TimeSeries(stream_2, "H2:LSC-STRAIN", &gps_start, XLALGPSDiff(&gps_end, &gps_start), 0);
    if(!ht_2) {
      XLALFrStreamClose(stream_2);
      printf("%s(): cannot read data for H2:LSC-STRAIN\n",__func__);
    }

    /* units */
    ht_1->sampleUnits = lalStrainUnit;
    ht_2->sampleUnits = lalStrainUnit;

    /* create H- time series */
    ht_m = XLALCreateREAL8TimeSeries("H2:LSC-STRAIN_HNULL", &gps_start, ht_1->f0, ht_1->deltaT, &ht_1->sampleUnits, ht_1->data->length);
        
    /* fill H- data vector */
    for ( p = 0 ; p < (int)ht_1->data->length; p++ )
      ht_m->data->data[p]=ht_1->data->data[p]-ht_2->data->data[p];
    
    /* save time series into a frame */
    frame = XLALFrameNew(&gps_start, XLALGPSDiff(&gps_end, &gps_start), "LIGO", 0, 1,LAL_LHO_4K_DETECTOR_BIT);
    /*XLALFrameAddREAL8TimeSeriesProcData( frame, ht_1 );*/
    /*XLALFrameAddREAL8TimeSeriesProcData( frame, ht_2 );*/
    XLALFrameAddREAL8TimeSeriesProcData( frame, ht_m );
    sprintf(filename,"%s/H-H1H2_COHERENT-%d-%d.gwf", argv[3],start,end-start);
    XLALFrameWrite(frame, filename);
    
    /* cleaning */
    XLALDestroyREAL8TimeSeries(ht_1);
    XLALDestroyREAL8TimeSeries(ht_2);
    XLALDestroyREAL8TimeSeries(ht_m);
    XLALFrameFree(frame);
  }
  
  /* close streams */
  XLALFrStreamClose(stream_1);
  XLALFrStreamClose(stream_2);
  
  return 0;
}
예제 #29
0
int XLALFrameUFrameHWrite_FrameL_(LALFrameUFrFile * stream, LALFrameUFrameH * frame)
{
    if (FrameWrite(frame, stream->handle) != FR_OK)
        XLAL_ERROR(XLAL_EIO, "FrameWrite failed with error code %s.", XLALFrameLErrorMessage(stream->handle->error));
    return 0;
}
예제 #30
0
/**
 * Set up the expnCoeffsTaylorT4 and expnFuncTaylorT4 structures for
 * generating a TaylorT4 waveform and select the post-newtonian
 * functions corresponding to the desired order.
 *
 * Inputs given in SI units.
 */
static int 
XLALSimInspiralTaylorT4Setup(
    expnCoeffsTaylorT4 *ak,         /**< coefficients for TaylorT4 evolution [modified] */
    expnFuncTaylorT4 *f,            /**< functions for TaylorT4 evolution [modified] */
    expnCoeffsdEnergyFlux *akdEF,   /**< coefficients for Energy calculation [modified] */
    REAL8 m1,                       /**< mass of companion 1 */
    REAL8 m2,                       /**< mass of companion 2 */
    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,	/**< twice PN order of tidal effects */
    int O                           /**< twice post-Newtonian order */
)
{
    ak->m1 = m1;
    ak->m2 = m2;
    ak->m = ak->m1 + ak->m2;
    ak->mu = m1 * m2 / ak->m;
    ak->nu = ak->mu/ak->m;
    ak->chi1 = ak->m1/ak->m;
    ak->chi2 = ak->m2/ak->m;

    /* Angular velocity co-efficient */
    ak->av = pow(LAL_C_SI, 3.0)/(LAL_G_SI*ak->m);

    /* PN co-efficients for energy */
    akdEF->ETaN = XLALSimInspiralPNEnergy_0PNCoeff(ak->nu);
    akdEF->ETa1 = XLALSimInspiralPNEnergy_2PNCoeff(ak->nu);
    akdEF->ETa2 = XLALSimInspiralPNEnergy_4PNCoeff(ak->nu);
    akdEF->ETa3 = XLALSimInspiralPNEnergy_6PNCoeff(ak->nu);

    /* PN co-efficients for angular acceleration */
    ak->aatN = XLALSimInspiralTaylorT4wdot_0PNCoeff(ak->nu)/(ak->m/LAL_MSUN_SI*LAL_MTSUN_SI)/3.;
    ak->aat2 = XLALSimInspiralTaylorT4wdot_2PNCoeff(ak->nu);
    ak->aat3 = XLALSimInspiralTaylorT4wdot_3PNCoeff(ak->nu);
    ak->aat4 = XLALSimInspiralTaylorT4wdot_4PNCoeff(ak->nu);
    ak->aat5 = XLALSimInspiralTaylorT4wdot_5PNCoeff(ak->nu);
    ak->aat6 = XLALSimInspiralTaylorT4wdot_6PNCoeff(ak->nu);
    ak->aat7 = XLALSimInspiralTaylorT4wdot_7PNCoeff(ak->nu);
    ak->aat6l = XLALSimInspiralTaylorT4wdot_6PNLogCoeff(ak->nu);

    /* Tidal coefficients for energy and angular acceleration */
    akdEF->ETa5 = 0.;
    akdEF->ETa6 = 0.;
    ak->aat10   = 0.;
    ak->aat12   = 0.;
    switch( tideO )
    {
        case LAL_SIM_INSPIRAL_TIDAL_ORDER_ALL:
        case LAL_SIM_INSPIRAL_TIDAL_ORDER_6PN:
            akdEF->ETa6 = lambda1 * XLALSimInspiralPNEnergy_12PNTidalCoeff(ak->chi1) + lambda2 * XLALSimInspiralPNEnergy_12PNTidalCoeff(ak->chi2);
            ak->aat12   = lambda1 * XLALSimInspiralTaylorT4wdot_12PNTidalCoeff(ak->chi1) + lambda2 * XLALSimInspiralTaylorT4wdot_12PNTidalCoeff(ak->chi2);
        case LAL_SIM_INSPIRAL_TIDAL_ORDER_5PN:
            akdEF->ETa5 = lambda1 * XLALSimInspiralPNEnergy_10PNTidalCoeff(ak->chi1) + lambda2 * XLALSimInspiralPNEnergy_10PNTidalCoeff(ak->chi2);
            ak->aat10   = lambda1 * XLALSimInspiralTaylorT4wdot_10PNTidalCoeff(ak->chi1) + lambda2 * XLALSimInspiralTaylorT4wdot_10PNTidalCoeff(ak->chi2);
        case LAL_SIM_INSPIRAL_TIDAL_ORDER_0PN:
            break;
        default:
            XLALPrintError("XLAL Error - %s: Invalid tidal PN order %d\nSee LALSimInspiralTidalOrder enum in LALSimInspiralWaveformFlags.h for valid tidal orders.\n",
                    __func__, tideO );
            XLAL_ERROR(XLAL_EINVAL);
            break;
    }

    switch (O)
    {
        case 0:
            f->energy4 = &XLALSimInspiralEt0;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_0PN;
            break;
        case 1:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for PN order %d\n", __func__,O);
            XLAL_ERROR(XLAL_EINVAL);
            break;
        case 2:
            f->energy4 = &XLALSimInspiralEt2;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_2PN;
            break;
        case 3:
            f->energy4 = &XLALSimInspiralEt2;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_3PN;
            break;
        case 4:
            f->energy4 = &XLALSimInspiralEt4;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_4PN;
            break;
        case 5:
            f->energy4 = &XLALSimInspiralEt4;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_5PN;
            break;
        case 6:
            f->energy4 = &XLALSimInspiralEt6;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_6PN;
            break;
        case 7:
        case -1:
            f->energy4 = &XLALSimInspiralEt6;
            f->angacc4 = &XLALSimInspiralAngularAcceleration4_7PN;
            break;
        case 8:
            XLALPrintError("XLAL Error - %s: PN approximant not supported for PN order %d\n", __func__,O);
            XLAL_ERROR(XLAL_EINVAL);
            break;
        default:
            XLALPrintError("XLAL Error - %s: Unknown PN order in switch\n", __func__);
            XLAL_ERROR(XLAL_EINVAL);
    }
  
  return 0;
}