Пример #1
0
/** \see See \ref Eigen_c for documentation */
void
LALDSymmetricEigenValues( LALStatus *stat, REAL8Vector *values, REAL8Array *matrix )
{
  REAL8Vector *offDiag = NULL; /* off-diagonal line of
                                  tri-diagonalized matrix */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Check dimension length.  All other argument testing is done by
     the subroutines. */
  ASSERT( values, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL );
  ASSERT( values->length, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL );

  /* Allocate an off-diagonal vector for the tri-diagonal matrix. */
  TRY( LALDCreateVector( stat->statusPtr, &offDiag, values->length ),
       stat );

  /* Call the subroutines. */
  LALDSymmetricToTriDiagonal2( stat->statusPtr, values, matrix,
			       offDiag );
  BEGINFAIL( stat ) {
    TRY( LALDDestroyVector( stat->statusPtr, &offDiag ), stat );
  } ENDFAIL( stat );
  LALDTriDiagonalToDiagonal2( stat->statusPtr, values, matrix,
			      offDiag );
  BEGINFAIL( stat ) {
    TRY( LALDDestroyVector( stat->statusPtr, &offDiag ), stat );
  } ENDFAIL( stat );

  /* Clean up. */
  TRY( LALDDestroyVector( stat->statusPtr, &offDiag ), stat );
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
Пример #2
0
void getMetric( LALStatus *stat,
                REAL4 g[3],
                REAL4 x[2],
                void *params )
{
  PtoleMetricIn *patch = params; /* avoid pesky gcc warnings */
  REAL8Vector   *metric = NULL;  /* for output of metric */

  /* Set up shop. */
  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );
  TRY( LALDCreateVector( stat->statusPtr, &metric, 6 ), stat );

  /* Translate input. */
  patch->position.longitude = x[1];
  patch->position.latitude =  x[0];


  /* Call the real metric function. */
  LALPtoleMetric( stat->statusPtr, metric, patch );
  BEGINFAIL( stat )
    TRY( LALDDestroyVector( stat->statusPtr, &metric ), stat );
  ENDFAIL( stat );
  LALProjectMetric( stat->statusPtr, metric, 0 );
  BEGINFAIL( stat )
    TRY( LALDDestroyVector( stat->statusPtr, &metric ), stat );
  ENDFAIL( stat );

  /* Translate output. */
      g[1] = metric->data[2];
      g[0] = metric->data[5];
      g[2] = metric->data[4];

  /* Clean up and leave. */
  TRY( LALDDestroyVector( stat->statusPtr, &metric ), stat );
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
} /* getMetric() */
/**
 * \author Creighton, T. D.
 *
 * \brief Computes a continuous waveform with frequency drift and Doppler
 * modulation from a hyperbolic orbital trajectory.
 *
 * This function computes a quaiperiodic waveform using the spindown and
 * orbital parameters in <tt>*params</tt>, storing the result in
 * <tt>*output</tt>.
 *
 * In the <tt>*params</tt> structure, the routine uses all the "input"
 * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the
 * "output" fields.  If <tt>params-\>f</tt>=\c NULL, no spindown
 * modulation is performed.  If <tt>params-\>oneMinusEcc</tt>\f$\not<0\f$ (a
 * non-hyperbolic orbit), or if
 * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$
 * (faster-than-light speed at periapsis), an error is returned.
 *
 * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is
 * ignored, but all other pointer fields must be set to \c NULL.  The
 * function will create and allocate space for <tt>output-\>a</tt>,
 * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary.  The
 * <tt>output-\>shift</tt> field will remain set to \c NULL.
 *
 * ### Algorithm ###
 *
 * For hyperbolic orbits, we combine \eqref{eq_spinorbit-tr},
 * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$
 * directly as a function of \f$E\f$:
 * \f{eqnarray}{
 * \label{eq_tr-e3}
 * t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega\\
 * & + & \frac{1}{n} \left( -E +
 * \left[v_p(e-1)\cos\omega + e\right]\sinh E
 * - \left[v_p\sqrt{\frac{e-1}{e+1}}\sin\omega\right]
 * [\cosh E - 1]\right) \;,
 * \f}
 * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at
 * periapsis and \f$n=\dot{\upsilon}_p\sqrt{(1-e)^3/(1+e)}\f$ is a normalized
 * angular speed for the orbit (the hyperbolic analogue of the mean
 * angular speed for closed orbits).  For simplicity we write this as:
 * \f{equation}{
 * \label{eq_tr-e4}
 * t_r = T_p + \frac{1}{n}\left( E + A\sinh E + B[\cosh E - 1] \right) \;,
 * \f}
 *
 * \figure{inject_hanomaly,eps,0.23,Function to be inverted to find eccentric anomaly}
 *
 * where \f$T_p\f$ is the \e observed time of periapsis passage.  Thus
 * the key numerical procedure in this routine is to invert the
 * expression \f$x=E+A\sinh E+B(\cosh E - 1)\f$ to get \f$E(x)\f$.  This function
 * is sketched to the right (solid line), along with an approximation
 * used for making an initial guess (dotted line), as described later.
 *
 * We note that \f$A^2-B^2<1\f$, although it approaches 1 when
 * \f$e\rightarrow1\f$, or when \f$v_p\rightarrow1\f$ and either \f$e=0\f$ or
 * \f$\omega=\pi\f$.  Except in this limit, Newton-Raphson methods will
 * converge rapidly for any initial guess.  In this limit, though, the
 * slope \f$dx/dE\f$ approaches zero at \f$E=0\f$, and an initial guess or
 * iteration landing near this point will send the next iteration off to
 * unacceptably large or small values.  A hybrid root-finding strategy is
 * used to deal with this, and with the exponential behaviour of \f$x\f$ at
 * large \f$E\f$.
 *
 * First, we compute \f$x=x_{\pm1}\f$ at \f$E=\pm1\f$.  If the desired \f$x\f$ lies
 * in this range, we use a straightforward Newton-Raphson root finder,
 * with the constraint that all guesses of \f$E\f$ are restricted to the
 * domain \f$[-1,1]\f$.  This guarantees that the scheme will eventually find
 * itself on a uniformly-convergent trajectory.
 *
 * Second, for \f$E\f$ outside of this range, \f$x\f$ is dominated by the
 * exponential terms: \f$x\approx\frac{1}{2}(A+B)\exp(E)\f$ for \f$E\gg1\f$, and
 * \f$x\approx-\frac{1}{2}(A-B)\exp(-E)\f$ for \f$E\ll-1\f$.  We therefore do an
 * \e approximate Newton-Raphson iteration on the function \f$\ln|x|\f$,
 * where the approximation is that we take \f$d\ln|x|/d|E|\approx1\f$.  This
 * involves computing an extra logarithm inside the loop, but gives very
 * rapid convergence to high precision, since \f$\ln|x|\f$ is very nearly
 * linear in these regions.
 *
 * At the start of the algorithm, we use an initial guess of
 * \f$E=-\ln[-2(x-x_{-1})/(A-B)-\exp(1)]\f$ for \f$x<x_{-1}\f$, \f$E=x/x_{-1}\f$ for
 * \f$x_{-1}\leq x\leq0\f$, \f$E=x/x_{+1}\f$ for \f$0\leq x\leq x_{+1}\f$, or
 * \f$E=\ln[2(x-x_{+1})/(A+B)-\exp(1)]\f$ for \f$x>x_{+1}\f$.  We refine this
 * guess until we get agreement to within 0.01 parts in part in
 * \f$N_\mathrm{cyc}\f$ (where \f$N_\mathrm{cyc}\f$ is the larger of the number
 * of wave cycles in a time \f$2\pi/n\f$, or the number of wave cycles in the
 * entire waveform being generated), or one part in \f$10^{15}\f$ (an order
 * of magnitude off the best precision possible with \c REAL8
 * numbers).  The latter case indicates that \c REAL8 precision may
 * fail to give accurate phasing, and one should consider modeling the
 * orbit as a set of Taylor frequency coefficients \'{a} la
 * <tt>LALGenerateTaylorCW()</tt>.  On subsequent timesteps, we use the
 * previous timestep as an initial guess, which is good so long as the
 * timesteps are much smaller than \f$1/n\f$.
 *
 * Once a value of \f$E\f$ is found for a given timestep in the output
 * series, we compute the system time \f$t\f$ via \eqref{eq_spinorbit-t},
 * and use it to determine the wave phase and (non-Doppler-shifted)
 * frequency via \eqref{eq_taylorcw-freq}
 * and \eqref{eq_taylorcw-phi}.  The Doppler shift on the frequency is
 * then computed using \eqref{eq_spinorbit-upsilon}
 * and \eqref{eq_orbit-rdot}.  We use \f$\upsilon\f$ as an intermediate in
 * the Doppler shift calculations, since expressing \f$\dot{R}\f$ directly in
 * terms of \f$E\f$ results in expression of the form \f$(e-1)/(e\cosh E-1)\f$,
 * which are difficult to simplify and face precision losses when
 * \f$E\sim0\f$ and \f$e\rightarrow1\f$.  By contrast, solving for \f$\upsilon\f$ is
 * numerically stable provided that the system <tt>atan2()</tt> function is
 * well-designed.
 *
 * This routine does not account for relativistic timing variations, and
 * issues warnings or errors based on the criterea of
 * \eqref{eq_relativistic-orbit} in \ref LALGenerateEllipticSpinOrbitCW().
 */
void
LALGenerateHyperbolicSpinOrbitCW( LALStatus             *stat,
				  PulsarCoherentGW            *output,
				  SpinOrbitCWParamStruc *params )
{
  UINT4 n, i;              /* number of and index over samples */
  UINT4 nSpin = 0, j;      /* number of and index over spindown terms */
  REAL8 t, dt, tPow;       /* time, interval, and t raised to a power */
  REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */
  REAL8 f, fPrev;          /* current and previous values of frequency */
  REAL4 df = 0.0;          /* maximum difference between f and fPrev */
  REAL8 phi;               /* current value of phase */
  REAL8 vDotAvg;           /* nomalized orbital angular speed */
  REAL8 vp;                /* projected speed at periapsis */
  REAL8 upsilon, argument; /* true anomaly, and argument of periapsis */
  REAL8 eCosOmega;         /* eccentricity * cosine of argument */
  REAL8 tPeriObs;          /* time of observed periapsis */
  REAL8 spinOff;           /* spin epoch - orbit epoch */
  REAL8 x;                 /* observed ``mean anomaly'' */
  REAL8 xPlus, xMinus;     /* limits where exponentials dominate */
  REAL8 dx, dxMax;         /* current and target errors in x */
  REAL8 a, b;              /* constants in equation for x */
  REAL8 ecc;               /* orbital eccentricity */
  REAL8 eccMinusOne, eccPlusOne; /* ecc - 1 and ecc + 1 */
  REAL8 e;                       /* hyperbolic anomaly */
  REAL8 sinhe, coshe;            /* sinh of e, and cosh of e minus 1 */
  REAL8 *fSpin = NULL;           /* pointer to Taylor coefficients */
  REAL4 *fData;                  /* pointer to frequency data */
  REAL8 *phiData;                /* pointer to phase data */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Make sure parameter and output structures exist. */
  ASSERT( params, stat, GENERATESPINORBITCWH_ENUL,
	  GENERATESPINORBITCWH_MSGENUL );
  ASSERT( output, stat, GENERATESPINORBITCWH_ENUL,
	  GENERATESPINORBITCWH_MSGENUL );

  /* Make sure output fields don't exist. */
  ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );

  /* If Taylor coeficients are specified, make sure they exist. */
  if ( params->f ) {
    ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL,
	    GENERATESPINORBITCWH_MSGENUL );
    nSpin = params->f->length;
    fSpin = params->f->data;
  }

  /* Set up some constants (to avoid repeated calculation or
     dereferencing), and make sure they have acceptable values. */
  eccMinusOne = -params->oneMinusEcc;
  ecc = 1.0 + eccMinusOne;
  eccPlusOne = 2.0 + eccMinusOne;
  if ( eccMinusOne <= 0.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EECC,
	   GENERATESPINORBITCWH_MSGEECC );
  }
  vp = params->rPeriNorm*params->angularSpeed;
  vDotAvg = params->angularSpeed
    *sqrt( eccMinusOne*eccMinusOne*eccMinusOne/eccPlusOne );
  n = params->length;
  dt = params->deltaT;
  f0 = fPrev = params->f0;
  if ( vp >= 1.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EFTL,
	   GENERATESPINORBITCWH_MSGEFTL );
  }
  if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDotAvg <= 0.0 ||
       n == 0 ) {
    ABORT( stat, GENERATESPINORBITCWH_ESGN,
	   GENERATESPINORBITCWH_MSGESGN );
  }

  /* Set up some other constants. */
  twopif0 = f0*LAL_TWOPI;
  phi0 = params->phi0;
  argument = params->omega;
  a = vp*eccMinusOne*cos( argument ) + ecc;
  b = -vp*sqrt( eccMinusOne/eccPlusOne )*sin( argument );
  eCosOmega = ecc*cos( argument );
  if ( n*dt*vDotAvg > LAL_TWOPI )
    dxMax = 0.01/( f0*n*dt );
  else
    dxMax = 0.01/( f0*LAL_TWOPI/vDotAvg );
  if ( dxMax < 1.0e-15 ) {
    dxMax = 1.0e-15;
#ifndef NDEBUG
    LALWarning( stat, "REAL8 arithmetic may not have sufficient"
		" precision for this orbit" );
#endif
  }
#ifndef NDEBUG
  if ( lalDebugLevel & LALWARNING ) {
    REAL8 tau = n*dt;
    if ( tau > LAL_TWOPI/vDotAvg )
      tau = LAL_TWOPI/vDotAvg;
    if ( f0*tau*vp*vp*ecc/eccPlusOne > 0.25 )
      LALWarning( stat, "Orbit may have significant relativistic"
		  " effects that are not included" );
  }
#endif

  /* Compute offset between time series epoch and observed periapsis,
     and betweem true periapsis and spindown reference epoch. */
  tPeriObs = (REAL8)( params->orbitEpoch.gpsSeconds -
		      params->epoch.gpsSeconds );
  tPeriObs += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
				params->epoch.gpsNanoSeconds );
  tPeriObs += params->rPeriNorm*sin( params->omega );
  spinOff = (REAL8)( params->orbitEpoch.gpsSeconds -
		     params->spinEpoch.gpsSeconds );
  spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
			       params->spinEpoch.gpsNanoSeconds );

  /* Determine bounds of hybrid root-finding algorithm, and initial
     guess for e. */
  xMinus = 1.0 + a*sinh( -1.0 ) + b*cosh( -1.0 ) - b;
  xPlus = -1.0 + a*sinh( 1.0 ) + b*cosh( 1.0 ) - b;
  x = -vDotAvg*tPeriObs;
  if ( x < xMinus )
    e = -log( -2.0*( x - xMinus )/( a - b ) - exp( 1.0 ) );
  else if ( x <= 0 )
    e = x/xMinus;
  else if ( x <= xPlus )
    e = x/xPlus;
  else
    e = log( 2.0*( x - xPlus )/( a + b ) - exp( 1.0 ) );
  sinhe = sinh( e );
  coshe = cosh( e ) - 1.0;

  /* Allocate output structures. */
  if ( ( output->a = (REAL4TimeVectorSeries *)
	 LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
  if ( ( output->f = (REAL4TimeSeries *)
	 LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->f, 0, sizeof(REAL4TimeSeries) );
  if ( ( output->phi = (REAL8TimeSeries *)
	 LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    LALFree( output->f ); output->f = NULL;
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->phi, 0, sizeof(REAL8TimeSeries) );

  /* Set output structure metadata fields. */
  output->position = params->position;
  output->psi = params->psi;
  output->a->epoch = output->f->epoch = output->phi->epoch
    = params->epoch;
  output->a->deltaT = n*params->deltaT;
  output->f->deltaT = output->phi->deltaT = params->deltaT;
  output->a->sampleUnits = lalStrainUnit;
  output->f->sampleUnits = lalHertzUnit;
  output->phi->sampleUnits = lalDimensionlessUnit;
  snprintf( output->a->name, LALNameLength, "CW amplitudes" );
  snprintf( output->f->name, LALNameLength, "CW frequency" );
  snprintf( output->phi->name, LALNameLength, "CW phase" );

  /* Allocate phase and frequency arrays. */
  LALSCreateVector( stat->statusPtr, &( output->f->data ), n );
  BEGINFAIL( stat ) {
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );
  LALDCreateVector( stat->statusPtr, &( output->phi->data ), n );
  BEGINFAIL( stat ) {
    TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	 stat );
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );

  /* Allocate and fill amplitude array. */
  {
    CreateVectorSequenceIn in; /* input to create output->a */
    in.length = 2;
    in.vectorLength = 2;
    LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
    BEGINFAIL( stat ) {
      TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	   stat );
      TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
	   stat );
      LALFree( output->a );   output->a = NULL;
      LALFree( output->f );   output->f = NULL;
      LALFree( output->phi ); output->phi = NULL;
    } ENDFAIL( stat );
    output->a->data->data[0] = output->a->data->data[2] = params->aPlus;
    output->a->data->data[1] = output->a->data->data[3] = params->aCross;
  }

  /* Fill frequency and phase arrays. */
  fData = output->f->data->data;
  phiData = output->phi->data->data;
  for ( i = 0; i < n; i++ ) {

    x = vDotAvg*( i*dt - tPeriObs );

    /* Use approximate Newton-Raphson method on ln|x| if |x| > 1. */
    if ( x < xMinus ) {
      x = log( -x );
      while ( fabs( dx = log( e - a*sinhe - b*coshe ) - x ) > dxMax ) {
	e += dx;
	sinhe = sinh( e );
	coshe = cosh( e ) - 1.0;
      }
    }
    else if ( x > xPlus ) {
      x = log( x );
      while ( fabs( dx = log( -e + a*sinhe + b*coshe ) - x ) > dxMax ) {
	e -= dx;
	sinhe = sinh( e );
	coshe = cosh( e ) - 1.0;
      }
    }

    /* Use ordinary Newton-Raphson method on x if |x| <= 1. */
    else {
      while ( fabs( dx = -e + a*sinhe + b*coshe - x ) > dxMax ) {
	e -= dx/( -1.0 + a*coshe + a + b*sinhe );
	if ( e < -1.0 )
	  e = -1.0;
	else if ( e > 1.0 )
	  e = 1.0;
	sinhe = sinh( e );
	coshe = cosh( e ) - 1.0;
      }
    }

    /* Compute source emission time, phase, and frequency. */
    phi = t = tPow =
      ( ecc*sinhe - e )/vDotAvg + spinOff;
    f = 1.0;
    for ( j = 0; j < nSpin; j++ ) {
      f += fSpin[j]*tPow;
      phi += fSpin[j]*( tPow*=t )/( j + 2.0 );
    }

    /* Appy frequency Doppler shift. */
    upsilon = 2.0*atan2( sqrt( eccPlusOne*coshe ),
			 sqrt( eccMinusOne*( coshe + 2.0 ) ) );
    f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega )
		/eccPlusOne );
    phi *= twopif0;
    if ( fabs( f - fPrev ) > df )
      df = fabs( f - fPrev );
    *(fData++) = fPrev = f;
    *(phiData++) = phi + phi0;
  }

  /* Set output field and return. */
  params->dfdt = df*dt;
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
Пример #4
0
/**
 * \author Jones D. I., Owen, B. J., and Whitbeck, D. M.
 * \date 2001-2005
 * \brief Computes metric components for a pulsar search in the ``Ptolemaic''
 * approximation; both the Earth's spin and orbit are included.
 *
 * ### Description ###
 *
 * This function computes metric components in a way that yields results
 * very similar to those of LALCoherentMetric() called with the
 * output of LALTBaryPtolemaic(). The CPU demand, however, is less,
 * and the metric components can be expressed analytically, lending
 * themselves to better understanding of the behavior of the parameter
 * space.  For short durations (less than about 70000 seconds or 20 hours) a
 * Taylor series expansion is used to improve the accuracy with which several
 * terms are computed.
 *
 * ### Algorithm ###
 *
 * For speed and checking reasons, a minimum of numerical computation is
 * involved. The metric components can be expressed analytically (though not
 * tidily) in terms of trig functions and are much too large to be worth
 * writing down here.  More comprehensive documentation on the derivation of
 * the metric components can be found in the pulgroup CVS archive as
 * docs/S2/FDS/Isolated/ptolemetric.tex.  Jones, Owen, and Whitbeck will write
 * up the calculation and some tests as a journal article.
 *
 * The function LALGetEarthTimes() is used to calculate the spin and
 * rotational phase of the Earth at the beginning of the observation.
 *
 * On output, the \a metric->data is arranged with the same indexing
 * scheme as in LALCoherentMetric(). The order of the parameters is
 * \f$(f_0, \alpha, \delta)\f$.
 *
 * ### Notes ###
 *
 * The analytic metric components were derived separately by Jones and
 * Whitbeck (and partly by Owen) and found to agree.  Also, the output of this
 * function has been compared against that of the function combination
 * (CoherentMetric + TDBaryPtolemaic), which is a numerical implementation of
 * the Ptolemaic approximation, and found to agree up to the fourth
 * significant figure or better.  Even using DTEphemeris.c for the true
 * Earth's orbit only causes errors in the metric components of order 10\%,
 * with (so far) no noticeable effect on the sky coverage.
 *
 * At present, only one spindown parameter can be included with the sky
 * location.  The code contains (commented out) expressions for
 * spindown-spindown metric components for an arbitrary number of spindowns,
 * but the (commented out) spindown-sky components neglect orbital motion.
 *
 * A separate routine, XLALSpindownMetric(), has been added to compute the
 * metric for multiple spindowns but for fixed sky position, suitable for
 * e.g. directed searches.
 */
void LALPtoleMetric( LALStatus *status,
                     REAL8Vector *metric,
                     PtoleMetricIn *input )
{
  INT2 j;              /* Loop counters */
  /*REAL8 temp1, temp2, temp3, temp4; dummy variables */
  REAL8 R_o, R_s;         /* Amplitude of daily/yearly modulation, s */
  REAL8 lat, lon;         /* latitude and longitude of detector site */
  REAL8 omega_s, omega_o; /* Ang freq of daily/yearly modulation, rad/s */
  REAL8 phi_o_i;          /* Phase of Earth's orbit at begining (epoch) */
  REAL8 phi_o_f;          /* Phase of Earth's orbit at end (epoch+duration) */
  REAL8 phi_s_i;          /* Phase of Earth's spin at beginning (epoch) */
  REAL8 phi_s_f;          /* Phase of Earth's spin at end (epoch+duration) */
  REAL8 cos_l, sin_l, sin_2l;  /* Trig fns for detector lattitude */
  REAL8 cos_i, sin_i;     /* Trig fns for inclination of Earth's spin */
  REAL8 cos_a, sin_a, sin_2a;  /* Trig fns for source RA */
  REAL8 cos_d, sin_d, sin_2d;  /* Trig fns for source declination */
  REAL8 A[22];     /* Array of intermediate quantities */
  REAL8 B[10];     /* Array of intermediate quantities */
  REAL8 Is[5];      /* Array of integrals needed for spindown.*/
  UINT2 dim;         /* Dimension of parameter space */
  PulsarTimesParamStruc zero_phases; /* Needed to calculate phases of spin*/
  /* and orbit at t_gps =0             */
  REAL8Vector *big_metric; /* 10-dim metric in (phi,f,a,d,f1) for internal use */
  REAL8 T;  /* Duration of observation */
  REAL8 f; /* Frequency */
  /* Some useful short-hand notations involving the orbital phase: */
  REAL8 D_p_o;
  REAL8 sin_p_o;
  REAL8 cos_p_o;
  REAL8 D_sin_p_o;
  REAL8 D_cos_p_o;
  REAL8 D_sin_2p_o;
  REAL8 D_cos_2p_o;
  /* Some useful short-hand notations involving the spin phase: */
  REAL8 D_p_s;
  REAL8 sin_p_s;
  REAL8 cos_p_s;
  REAL8 D_sin_p_s;
  REAL8 D_cos_p_s;
  REAL8 D_sin_2p_s;
  REAL8 D_cos_2p_s;
  /* Some useful short-hand notations involving spin and orbital phases: */
  REAL8 D_sin_p_o_plus_s;
  REAL8 D_sin_p_o_minus_s;
  REAL8 D_cos_p_o_plus_s;
  REAL8 D_cos_p_o_minus_s;
  /* Quantities related to the short-time Tatlor expansions : */
  REAL8 D_p_o_crit;       /* The orbital phase BELOW which series used.  */
  REAL8 sum1, sum2, sum3;
  REAL8 next1, next2, next3;
  INT2 j_max;  /* Number of terms in series */


  INITSTATUS(status);

  /* Check for valid input structure. */
  ASSERT( input != NULL, status, PTOLEMETRICH_ENULL,
	  PTOLEMETRICH_MSGENULL );

  /* Check for valid sky position. */
  ASSERT( input->position.system == COORDINATESYSTEM_EQUATORIAL, status,
	  PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM );
  ASSERT( input->position.longitude >= 0, status, PTOLEMETRICH_EPARM,
	  PTOLEMETRICH_MSGEPARM );
  ASSERT( input->position.longitude <= LAL_TWOPI, status,
          PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM );
  ASSERT( abs(input->position.latitude) <= LAL_PI_2, status,
	  PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM );

  /* Check for valid maximum frequency. */
  ASSERT( input->maxFreq > MIN_MAXFREQ, status, PTOLEMETRICH_EPARM,
          PTOLEMETRICH_MSGEPARM );

  /* Check for valid detector location. */
  ASSERT( abs(input->site->frDetector.vertexLatitudeRadians) <= LAL_PI_2, status,
	  PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM );
  ASSERT( abs(input->site->frDetector.vertexLongitudeRadians) <= LAL_PI, status,
	  PTOLEMETRICH_EPARM, PTOLEMETRICH_MSGEPARM );

  if( input->spindown )
    dim = 2+input->spindown->length;
  else
    dim = 2;
  ASSERT( metric != NULL, status, PTOLEMETRICH_ENULL,
	  PTOLEMETRICH_MSGENULL );
  ASSERT( metric->data != NULL, status, PTOLEMETRICH_ENULL,
          PTOLEMETRICH_MSGENULL );
  ASSERT( metric->length == (UINT4)(dim+1)*(dim+2)/2, status, PTOLEMETRICH_EDIM,
          PTOLEMETRICH_MSGEDIM );

  /* A bigger metric that includes phase for internal use only:  */
  /* Apart from normalization, this is just the information matrix. */
  big_metric = NULL;
  LALDCreateVector( status, &big_metric, (dim+2)*(dim+3)/2);

  /* Detector location: */
  lat = input->site->frDetector.vertexLatitudeRadians;
  lon = input->site->frDetector.vertexLongitudeRadians;
  cos_l = cos(lat);
  sin_l = sin(lat);
  sin_2l = sin(2*lat);

  /* Inclination of Earth's spin-axis to ecliptic */
  sin_i = sin(LAL_IEARTH);
  cos_i = cos(LAL_IEARTH);

  /* Radii of circular motions in seconds:  */
  R_s = LAL_REARTH_SI / LAL_C_SI;
  R_o = LAL_AU_SI / LAL_C_SI;

  /* To switch off orbital motion uncomment this: */
  /* R_o = 0.0; */

  /* To switch off spin motion uncomment this: */
  /* R_s = 0.0; */

  /* Angular velocities: */
  omega_s = LAL_TWOPI / LAL_DAYSID_SI;
  omega_o = LAL_TWOPI / LAL_YRSID_SI;

  /* Duration of observation */
  T = input->duration;

  /* Frequency: */
  f = input->maxFreq;

  /* Source RA: */
  sin_a  = sin(input->position.longitude);
  cos_a  = cos(input->position.longitude);
  sin_2a = sin(2*(input->position.longitude));

  /* Source declination: */
  sin_d  = sin(input->position.latitude);
  cos_d  = cos(input->position.latitude);
  sin_2d = sin(2*(input->position.latitude));

  /* Calculation of phases of spin and orbit at start: */
  zero_phases.epoch.gpsSeconds = input->epoch.gpsSeconds;
  zero_phases.epoch.gpsNanoSeconds = input->epoch.gpsNanoSeconds;
  LALGetEarthTimes( status, &zero_phases);
  phi_o_i = -zero_phases.tAutumn/LAL_YRSID_SI*LAL_TWOPI;
  phi_s_i = -zero_phases.tMidnight/LAL_DAYSID_SI*LAL_TWOPI + lon;


  /* Quantities involving the orbital phase: */
  phi_o_f   = phi_o_i + omega_o*T;
  D_p_o     = omega_o*T;
  sin_p_o   = sin(phi_o_f);
  cos_p_o   = cos(phi_o_f);
  D_sin_p_o = (sin(phi_o_f) - sin(phi_o_i))/D_p_o;
  D_cos_p_o = (cos(phi_o_f) - cos(phi_o_i))/D_p_o;
  D_sin_2p_o = (sin(2*phi_o_f) - sin(2*phi_o_i))/2.0/D_p_o;
  D_cos_2p_o = (cos(2*phi_o_f) - cos(2*phi_o_i))/2.0/D_p_o;

  /* Quantities involving the spin phase: */
  phi_s_f    = phi_s_i + omega_s*T;
  D_p_s      = omega_s*T;
  sin_p_s    = sin(phi_s_f);
  cos_p_s    = cos(phi_s_f);
  D_sin_p_s  = (sin(phi_s_f) - sin(phi_s_i))/D_p_s;
  D_cos_p_s  = (cos(phi_s_f) - cos(phi_s_i))/D_p_s;
  D_sin_2p_s = (sin(2*phi_s_f) - sin(2*phi_s_i))/2.0/D_p_s;
  D_cos_2p_s = (cos(2*phi_s_f) - cos(2*phi_s_i))/2.0/D_p_s;

  /* Some mixed quantities: */
  D_sin_p_o_plus_s
    = (sin(phi_o_f+phi_s_f) - sin(phi_o_i+phi_s_i))/(D_p_o + D_p_s);
  D_sin_p_o_minus_s
    = (sin(phi_o_f-phi_s_f) - sin(phi_o_i-phi_s_i))/(D_p_o - D_p_s);
  D_cos_p_o_plus_s
    = (cos(phi_o_f+phi_s_f) - cos(phi_o_i+phi_s_i))/(D_p_o + D_p_s);
  D_cos_p_o_minus_s
    = (cos(phi_o_f-phi_s_f) - cos(phi_o_i-phi_s_i))/(D_p_o - D_p_s);



  /***************************************************************/
  /* Small D_p_o overwrite:                                      */
  /***************************************************************/
  j_max = 7;
  D_p_o_crit = 1.4e-2; /* This corresponds to about 70000 seconds */

  sum1  = next1 = D_p_o/2.0;
  sum2  = next2 = D_p_o/3.0/2.0;
  sum3  = next3 = D_p_o;

  for(j=1; j<=j_max; j++)
    {
      next1 *= -pow(D_p_o,2.0)/(2.0*j+1.0)/(2.0*j+2.0);
      sum1  += next1;
      next2 *= -pow(D_p_o,2.0)/(2.0*j+2.0)/(2.0*j+3.0);
      sum2  += next2;
      next3 *= -pow(2.0*D_p_o,2.0)/(2.0*j+1.0)/(2.0*j+2.0);
      sum3  += next3;
    }

  if(D_p_o < D_p_o_crit)
    {
      D_sin_p_o = sin(phi_o_f)*sum1 + cos(phi_o_f)*sin(D_p_o)/D_p_o;
      D_cos_p_o = cos(phi_o_f)*sum1 - sin(phi_o_f)*sin(D_p_o)/D_p_o;
      D_sin_2p_o
	= sin(2.0*phi_o_f)*sum3 + cos(2.0*phi_o_f)*sin(2.0*D_p_o)/2.0/D_p_o;
      D_cos_2p_o
	= cos(2.0*phi_o_f)*sum3 - sin(2.0*phi_o_f)*sin(2.0*D_p_o)/2.0/D_p_o;
   }
  /****************************************************************/


  /* The A[i] quantities: */
  A[1] =
    R_o*D_sin_p_o + R_s*cos_l*D_sin_p_s;

  A[2] =
    R_o*cos_i*D_cos_p_o + R_s*cos_l*D_cos_p_s;

  A[3] =
    -R_o*sin_i*D_cos_p_o + R_s*sin_l;

  A[4] =
    R_o*(sin_p_o/D_p_o + D_cos_p_o/D_p_o);

  A[5] =
    R_s*(sin_p_s/D_p_s + D_cos_p_s/D_p_s);

  A[6] =
    R_o*(-cos_p_o/D_p_o + D_sin_p_o/D_p_o);

  /* Special overwrite for A4 and A6: *********************/
  if(D_p_o < D_p_o_crit)
    {
      A[4] = R_o*(cos(phi_o_f)*sum1/D_p_o + sin(phi_o_f)*sum2);
      A[6] = R_o*(sin(phi_o_f)*sum1/D_p_o - cos(phi_o_f)*sum2);
    }
  /***********************************************************/

  A[7] =
    R_s*(-cos_p_s/D_p_s + D_sin_p_s/D_p_s);

  A[8] =
    R_o*R_o*(1 + D_sin_2p_o);

  A[9] =
    R_o*R_s*(D_sin_p_o_minus_s + D_sin_p_o_plus_s);

  A[10] =
    R_s*R_s*(1 + D_sin_2p_s);

  A[11] =
    R_o*R_o*D_cos_2p_o;

  A[12] =
    R_o*R_s*(-D_cos_p_o_minus_s + D_cos_p_o_plus_s);

  A[13] =
    R_o*R_s*(D_cos_p_o_minus_s + D_cos_p_o_plus_s);

  A[14] =
    R_s*R_s*D_cos_2p_s;

  A[15] =
    R_o*R_o*(1 - D_sin_2p_o);

  A[16] =
    R_o*R_s*(D_sin_p_o_minus_s - D_sin_p_o_plus_s);

  A[17] =
    R_s*R_s*(1 - D_sin_2p_s);

  A[18] =
    R_o*R_s*D_sin_p_o;

  A[19] =
    R_s*R_s*D_sin_p_s;

  A[20] =
    R_o*R_s*D_cos_p_o;

  A[21] =
    R_s*R_s*D_cos_p_s;


  /* The B[i] quantities: */
  B[1] =
    A[4] + A[5]*cos_l;

  B[2] =
    A[6]*cos_i + A[7]*cos_l;

  B[3] =
    A[6]*sin_i + R_s*sin_l/2;

  B[4] =
    A[8] + 2*A[9]*cos_l + A[10]*cos_l*cos_l;

  B[5] =
    A[11]*cos_i + A[12]*cos_l + A[13]*cos_i*cos_l + A[14]*cos_l*cos_l;

  B[6] =
    A[15]*cos_i*cos_i +2*A[16]*cos_i*cos_l + A[17]*cos_l*cos_l;

  B[7] =
    -A[11]*sin_i + 2*A[18]*sin_l - A[13]*sin_i*cos_l + A[19]*sin_2l;

  B[8] =
    A[15]*sin_i*cos_i - 2*A[20]*cos_i*sin_l + A[16]*sin_i*cos_l - A[21]*sin_2l;

  B[9] =
    A[15]*sin_i*sin_i - 4*A[20]*sin_i*sin_l + 2*R_s*R_s*sin_l*sin_l;

 /* The spindown integrals. */

  /* orbital t^2 cos */

  Is[1] = (2*sin(phi_o_i) + 2*omega_o*T*cos_p_o + (-2 + pow(omega_o*T,2))*sin_p_o)/pow(omega_o*T,3);

  /* spin t^2 cos */
  Is[2] = (2*sin(phi_s_i) + 2*omega_s*T*cos_p_s + (-2 + pow(omega_s*T,2))*sin_p_s)/pow(omega_s*T,3);

  /* orbital t^2 sin */
  Is[3] = (-2*cos(phi_o_i) + 2*omega_o*T*sin_p_o - (-2 + pow(omega_o*T,2))*cos_p_o)/pow(omega_o*T,3);

  /*spin t^2 sin */

  Is[4] = (-2*cos(phi_s_i) + 2*omega_s*T*sin_p_s - (-2 + pow(omega_s*T,2))*cos_p_s)/pow(omega_s*T,3);



  /* The 4-dim metric components: */
  /* g_pp = */
  big_metric->data[0] =
    1;

  /* g_pf = */
  big_metric->data[1] =
    LAL_PI*T;

  /* g_pa = */
  big_metric->data[3] =
    -LAL_TWOPI*f*cos_d*(A[1]*sin_a + A[2]*cos_a);

  /* g_pd = */
  big_metric->data[6] =
    LAL_TWOPI*f*(-A[1]*sin_d*cos_a + A[2]*sin_d*sin_a + A[3]*cos_d);

  /* g_ff = */
  big_metric->data[2] =
    pow(LAL_TWOPI*T, 2)/3;

  /* g_fa = */
  big_metric->data[4] =
    pow(LAL_TWOPI,2)*f*cos_d*T*(-B[1]*sin_a + B[2]*cos_a);

  /* g_fd = */
  big_metric->data[7] =
    pow(LAL_TWOPI,2)*f*T*(-B[1]*sin_d*cos_a - B[2]*sin_d*sin_a + B[3]*cos_d);

  /* g_aa = */
  big_metric->data[5] =
    2*pow(LAL_PI*f*cos_d,2) * (B[4]*sin_a*sin_a + B[5]*sin_2a + B[6]*cos_a*cos_a);

  /* g_ad =  */
  big_metric->data[8] =
    2*pow(LAL_PI*f,2)*cos_d*(B[4]*sin_a*cos_a*sin_d - B[5]*sin_a*sin_a*sin_d
			     -B[7]*sin_a*cos_d + B[5]*cos_a*cos_a*sin_d - B[6]*sin_a*cos_a*sin_d
			     +B[8]*cos_a*cos_d);

  /* g_dd = */
  big_metric->data[9] =
    2*pow(LAL_PI*f,2)*(B[4]*pow(cos_a*sin_d,2) + B[6]*pow(sin_a*sin_d,2)
		       +B[9]*pow(cos_d,2) - B[5]*sin_2a*pow(sin_d,2) - B[8]*sin_a*sin_2d
		       -B[7]*cos_a*sin_2d);

  /*The spindown components*/
  if(dim==3) {
    /* g_p1 = */
    big_metric->data[10] =
      T*LAL_PI*f*T/3;

    /* g_f1= */
    big_metric->data[11]=
      T*pow(LAL_PI*T,2)*f/2;

    /* g_a1 = */
    big_metric->data[12] = T*2*pow(LAL_PI*f,2)*T*(-cos_d*sin_a*(R_o*Is[1] + R_s*cos_l*Is[2])+ cos_d*cos_a*(R_o*cos_i*Is[3] + R_s*cos_l*Is[4]));

    /* g_d1 = */
    big_metric->data[13] = T*2*pow(LAL_PI*f,2)*T*(-sin_d*cos_a*(R_o*Is[1] + R_s*cos_l*Is[2])- sin_d*sin_a*(R_o*cos_i*Is[3] + R_s*cos_l*Is[4]) + cos_d*(R_o*sin_i*Is[3] + R_s*sin_l/3));

    /* g_11 = */
    big_metric->data[14] = T*T*pow(LAL_PI*f*T,2)/5;
  }


  /**********************************************************/
  /* Spin-down stuff not consistent with rest of code - don't uncomment! */
  /* Spindown-spindown metric components, before projection
     if( input->spindown )
     for (j=1; j<=dim-2; j++)
     for (k=1; k<=j; k++)
     metric->data[(k+2)+(j+2)*(j+3)/2] = pow(LAL_TWOPI*input->maxFreq
     *input->duration,2)/(j+2)/(k+2)/(j+k+3);

     Spindown-angle metric components, before projection
     if( input->spindown )
     for (j=1; j<=(INT4)input->spindown->length; j++) {

     Spindown-RA: 1+(j+2)*(j+3)/2
     metric->data[1+(j+2)*(j+3)/2] = 0;
     temp1=0;
     temp2=0;
     for (k=j+1; k>=0; k--) {
     metric->data[1+(j+2)*(j+3)/2] += pow(-1,(k+1)/2)*factrl(j+1)
     /factrl(j+1-k)/pow(D_p_s,k)*((k%2)?sin_p_s:cos_p_s);
     metric->data[1+(j+2)*(j+3)/2] += pow(-1,j/2)/pow(D_p_s,j+1)*factrl(j+1)
     *((j%2)?cos(phi_s_i):sin(phi_s_i));
     metric->data[1+(j+2)*(j+3)/2] -= (cos_p_s-cos(phi_s_i))/(j+2);
     metric->data[1+(j+2)*(j+3)/2] *= -pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l
     *cos_d/omega_s/(j+1);
     temp1+=pow(-1,(k+1)/2)*factrl(j+1)
     /factrl(j+1-k)/pow(D_p_s,k)*((k%2)?sin_p_s:cos_p_s);
     temp2+=pow(-1,(k+1)/2)*factrl(j+1)
     /factrl(j+1-k)/pow(D_p_o,k)*((k%2)?sin_p_o:cos_p_o);
     }
     temp1+=pow(-1,j/2)/pow(D_p_s,j+1)*factrl(j+1)
     *((j%2)?cos(phi_s_i):sin(phi_s_i));
     temp2+=pow(-1,j/2)/pow(D_p_o,j+1)*factrl(j+1)
     *((j%2)?cos(phi_o_i):sin(phi_o_i));
     temp1-=(cos_p_s-cos(phi_s_i))/(j+2);
     temp2-=(cos_p_o-cos(phi_o_i))/(j+2);
     temp1*=-pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l
     *cos_d/omega_s/(j+1);
     temp2*=-pow(LAL_TWOPI*input->maxFreq,2)*R_o*cos_i
     *cos_d/omega_o/(j+1);
     metric->data[1+(j+2)*(j+3)/2]+=temp1+temp2;
     Spindown-dec: 2+(j+2)*(j+3)/2
     metric->data[2+(j+2)*(j+3)/2] = 0;
     temp3=0;
     temp4=0;
     for (k=j+1; k>=0; k--) {
     metric->data[2+(j+2)*(j+3)/2] -= pow(-1,k/2)*factrl(j+1)/factrl(j+1-k)
     /pow(D_p_s,k)*((k%2)?cos_p_s:sin_p_s);
     metric->data[2+(j+2)*(j+3)/2] += pow(-1,(j+1)/2)/pow(D_p_s,j+1)
     *factrl(j+1)*((j%2)?sin(phi_s_i):cos(phi_s_i));
     metric->data[2+(j+2)*(j+3)/2] += (sin_p_s-sin(phi_s_i))/(j+2);
     metric->data[2+(j+2)*(j+3)/2] *= pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l
     *sin_d/omega_s/(j+1);
     }    for( j... )
     temp3-=pow(-1,k/2)*factrl(j+1)/factrl(j+1-k)
     /pow(D_p_s,k)*((k%2)?cos_p_s:sin_p_s);
     temp4-=pow(-1,k/2)*factrl(j+1)/factrl(j+1-k)
     /pow(D_p_o,k)*((k%2)?cos_p_o:sin_p_o);
     }
     temp3+=pow(-1,(j+1)/2)/pow(D_p_s,j+1)
     *factrl(j+1)*((j%2)?sin(phi_s_i):cos(phi_s_i));
     temp4+=pow(-1,(j+1)/2)/pow(D_p_o,j+1)
     *factrl(j+1)*((j%2)?sin(phi_o_i):cos(phi_o_i));
     temp3+=(sin_p_s-sin(phi_s_i))/(j+2);
     temp4+=(sin_p_o-sin(phi_o_i))/(j+2);
     temp3*=pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_l
     *sin_d/omega_s/(j+1);
     temp4*=pow(LAL_TWOPI*input->maxFreq,2)*R_s*cos_i
     *sin_d/omega_o/(j+1);
     metric->data[2+(j+2)*(j+3)/2]=temp3+temp4;
     }
     f0-spindown : 0+(j+2)*(j+3)/2
     if( input->spindown )
     for (j=1; j<=dim-2; j++)
     metric->data[(j+2)*(j+3)/2] = 2*pow(LAL_PI,2)*input->maxFreq
     *pow(input->duration,2)/(j+2)/(j+3);*/
/*************************************************************/


/* Project down to 4-dim metric: */

/*f-f component */
  metric->data[0] =  big_metric->data[2]
    - big_metric->data[1]*big_metric->data[1]/big_metric->data[0];
  /*f-a component */
  metric->data[1] =  big_metric->data[4]
    - big_metric->data[1]*big_metric->data[3]/big_metric->data[0];
  /*a-a component */
  metric->data[2] =  big_metric->data[5]
    - big_metric->data[3]*big_metric->data[3]/big_metric->data[0];
  /*f-d component */
  metric->data[3] =  big_metric->data[7]
    - big_metric->data[6]*big_metric->data[1]/big_metric->data[0];
  /*a-d component */
  metric->data[4] =  big_metric->data[8]
    - big_metric->data[6]*big_metric->data[3]/big_metric->data[0];
  /*d-d component */
  metric->data[5] =  big_metric->data[9]
    - big_metric->data[6]*big_metric->data[6]/big_metric->data[0];
  if(dim==3) {

    /*f-f1 component */
    metric->data[6] = big_metric->data[11]
      - big_metric->data[1]*big_metric->data[10]/big_metric->data[0];

    /*a-f1 component */
    metric->data[7] = big_metric->data[12]
      - big_metric->data[3]*big_metric->data[10]/big_metric->data[0];

    /*d-f1 component */
    metric->data[8] = big_metric->data[13]
      - big_metric->data[6]*big_metric->data[10]/big_metric->data[0];

    /* f1-f1 component */
    metric->data[9] = big_metric->data[14]
      - big_metric->data[10]*big_metric->data[10]/big_metric->data[0];
  }

  LALDDestroyVector( status, &big_metric );
  /* All done */
  RETURN( status );
} /* LALPtoleMetric() */
Пример #5
0
int main (int argc, char *argv[])
{
    enum {ArraySize = 10};

    static LALStatus       status;
    static REAL4Vector *x;
    static REAL4Vector *y;
    static REAL8Vector *xx;
    static REAL8Vector *yy;

    SInterpolateOut sintout;
    SInterpolatePar sintpar;
    DInterpolateOut dintout;
    DInterpolatePar dintpar;

    int i;

    ParseOptions (argc, argv);

    LALSCreateVector (&status, &x, ArraySize);
    TestStatus (&status, CODES(0), 1);
    LALSCreateVector (&status, &y, ArraySize);
    TestStatus (&status, CODES(0), 1);
    LALDCreateVector (&status, &xx, ArraySize);
    TestStatus (&status, CODES(0), 1);
    LALDCreateVector (&status, &yy, ArraySize);
    TestStatus (&status, CODES(0), 1);

    if ( verbose )
        printf ("Initial data:\n");
    if ( verbose )
        printf ("y = P(x) = 7 - 8x + 2x^2 + 2x^3 - x^4\n");
    if ( verbose )
        printf ("-----------------\n");
    if ( verbose )
        printf ("x\ty\n");
    if ( verbose )
        printf ("=================\n");
    for (i = 0; i < ArraySize; ++i)
    {
        REAL4 xi = x->data[i] = xx->data[i] = i*i;
        y->data[i] = yy->data[i] = 7 + xi*(-8 + xi*(2 + xi*(2 - xi)));
        if ( verbose )
            printf ("%.0f\t%.0f\n", x->data[i], y->data[i]);
    }
    if ( verbose )
        printf ("-----------------\n");

    if ( verbose )
        printf ("\nInterpolate to x = 0.3:\n");
    if ( verbose )
        printf ("---------------------------------\n");
    if ( verbose )
        printf ("order\ty\t\tdy\n");
    if ( verbose )
        printf ("=================================\n");
    sintpar.x = x->data;
    sintpar.y = y->data;
    dintpar.x = xx->data;
    dintpar.y = yy->data;
    for (i = 2; i < ArraySize; ++i)
    {
        sintpar.n = i;
        dintpar.n = i;
        LALSPolynomialInterpolation (&status, &sintout, 0.3, &sintpar);
        TestStatus (&status, CODES(0), 1);
        LALDPolynomialInterpolation (&status, &dintout, 0.3, &dintpar);
        TestStatus (&status, CODES(0), 1);
        if ( verbose )
            printf ("%d\t%f\t%f\t%f\t%f\n", i - 1,
                    sintout.y, sintout.dy, dintout.y, dintout.dy);
    }
    if ( verbose )
        printf ("---------------------------------\n");

    if ( verbose )
        printf ("\nExtrapolate to x = -0.3:\n");
    if ( verbose )
        printf ("---------------------------------\n");
    if ( verbose )
        printf ("order\ty\t\tdy\n");
    if ( verbose )
        printf ("=================================\n");
    sintpar.x = x->data;
    sintpar.y = y->data;
    dintpar.x = xx->data;
    dintpar.y = yy->data;
    for (i = 2; i < ArraySize; ++i)
    {
        sintpar.n = i;
        dintpar.n = i;
        LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar);
        TestStatus (&status, CODES(0), 1);
        LALDPolynomialInterpolation (&status, &dintout, -0.3, &dintpar);
        TestStatus (&status, CODES(0), 1);
        if ( verbose )
            printf ("%d\t%f\t%f\t%f\t%f\n", i - 1,
                    sintout.y, sintout.dy, dintout.y, dintout.dy);
    }
    if ( verbose )
        printf ("---------------------------------\n");


    LALSDestroyVector (&status, &x);
    TestStatus (&status, CODES(0), 1);
    LALSDestroyVector (&status, &y);
    TestStatus (&status, CODES(0), 1);
    LALDDestroyVector (&status, &xx);
    TestStatus (&status, CODES(0), 1);
    LALDDestroyVector (&status, &yy);
    TestStatus (&status, CODES(0), 1);

    LALCheckMemoryLeaks ();

    LALSCreateVector (&status, &x, ArraySize);
    TestStatus (&status, CODES(0), 1);
    LALSCreateVector (&status, &y, ArraySize);
    TestStatus (&status, CODES(0), 1);
    LALDCreateVector (&status, &xx, ArraySize);
    TestStatus (&status, CODES(0), 1);
    LALDCreateVector (&status, &yy, ArraySize);
    TestStatus (&status, CODES(0), 1);


#ifndef LAL_NDEBUG

    if ( ! lalNoDebug )
    {
        if ( verbose )
            printf ("\nCheck error conditions:\n");

        if ( verbose )
            printf ("\nNull pointer:\r");
        LALSPolynomialInterpolation (&status, NULL, -0.3, &sintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        LALDPolynomialInterpolation (&status, NULL, -0.3, &dintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        if ( verbose )
            printf ("Null pointer check passed.\n");

        if ( verbose )
            printf ("\nNull pointer:\r");
        LALSPolynomialInterpolation (&status, &sintout, -0.3, NULL);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        LALDPolynomialInterpolation (&status, &dintout, -0.3, NULL);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        if ( verbose )
            printf ("Null pointer check passed.\n");

        sintpar.x = NULL;
        dintpar.x = NULL;
        if ( verbose )
            printf ("\nNull pointer:\r");
        LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        LALDPolynomialInterpolation (&status, &dintout, -0.3, &dintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        if ( verbose )
            printf ("Null pointer check passed.\n");

        sintpar.x = x->data;
        sintpar.y = NULL;
        dintpar.x = xx->data;
        dintpar.y = NULL;
        if ( verbose )
            printf ("\nNull pointer:\r");
        LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        LALDPolynomialInterpolation (&status, &dintout, -0.3, &dintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ENULL), 1);
        if ( verbose )
            printf ("Null pointer check passed.\n");

        sintpar.y = y->data;
        sintpar.n = 1;
        dintpar.y = yy->data;
        dintpar.n = 1;
        if ( verbose )
            printf ("\nInvalid size:\r");
        LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar);
        TestStatus (&status, CODES(INTERPOLATEH_ESIZE), 1);
        dintout.dy = XLALREAL8PolynomialInterpolation (&(dintout.y), -0.3, dintpar.y, dintpar.x, dintpar.n);
        if (xlalErrno == XLAL_ESIZE)
            xlalErrno = 0;
        else
            abort();
        if ( verbose )
            printf ("Invalid size check passed.\n");

        x->data[1]  = x->data[0]  = 2;
        xx->data[1] = xx->data[0] = 2;
        sintpar.n = 3;
        dintpar.n = 3;
        if ( verbose )
            printf ("\nZero divide:\r");
        LALSPolynomialInterpolation (&status, &sintout, -0.3, &sintpar);
        TestStatus (&status, CODES(INTERPOLATEH_EZERO), 1);
        dintout.dy = XLALREAL8PolynomialInterpolation (&(dintout.y), -0.3, dintpar.y, dintpar.x, dintpar.n);
        if (xlalErrno == XLAL_EFPDIV0)
            xlalErrno = 0;
        else
            abort();
        if ( verbose )
            printf ("Zero divide check passed.\n");
    }
#endif


    LALSDestroyVector (&status, &x);
    TestStatus (&status, CODES(0), 1);
    LALSDestroyVector (&status, &y);
    TestStatus (&status, CODES(0), 1);
    LALDDestroyVector (&status, &xx);
    TestStatus (&status, CODES(0), 1);
    LALDDestroyVector (&status, &yy);
    TestStatus (&status, CODES(0), 1);

    return 0;
}
Пример #6
0
/**
 * \brief Provides an interface between code build from \ref lalinspiral_findchirp and
 * various simulation packages for injecting chirps into data.
 * \author Brown, D. A. and Creighton, T. D
 *
 * Injects the signals described
 * in the linked list of \c SimInspiralTable structures \c events
 * into the data \c chan. The response function \c resp should
 * contain the response function to use when injecting the signals into the data.
 */
void
LALFindChirpInjectIMR (
    LALStatus                  *status,
    REAL4TimeSeries            *chan,
    SimInspiralTable           *events,
    SimRingdownTable           *ringdownevents,
    COMPLEX8FrequencySeries    *resp,
    INT4                        injectSignalType
    )

{
  UINT4                 k;
  DetectorResponse      detector;
  SimInspiralTable     *thisEvent = NULL;
  SimRingdownTable     *thisRingdownEvent = NULL;
  PPNParamStruc         ppnParams;
  CoherentGW            waveform, *wfm;
  INT8                  waveformStartTime;
  REAL4TimeSeries       signalvec;
  COMPLEX8Vector       *unity = NULL;
  CHAR                  warnMsg[512];
#if 0
  UINT4 n;
  UINT4 i;
#endif

  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  ASSERT( chan, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );
  ASSERT( chan->data, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );
  ASSERT( chan->data->data, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );

  ASSERT( events, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );

  ASSERT( resp, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );
  ASSERT( resp->data, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );
  ASSERT( resp->data->data, status,
      FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );


  /*
   *
   * set up structures and parameters needed
   *
   */

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


  /*
   *
   * compute the transfer function from the given response function
   *
   */


  /* allocate memory and copy the parameters describing the freq series */
  memset( &detector, 0, sizeof( DetectorResponse ) );
  detector.transfer = (COMPLEX8FrequencySeries *)
    LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) );
  if ( ! detector.transfer )
  {
    ABORT( status, FINDCHIRPH_EALOC, FINDCHIRPH_MSGEALOC );
  }
  memcpy( &(detector.transfer->epoch), &(resp->epoch),
      sizeof(LIGOTimeGPS) );
  detector.transfer->f0 = resp->f0;
  detector.transfer->deltaF = resp->deltaF;

  detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) );
  /* set the detector site */
  switch ( chan->name[0] )
  {
    case 'H':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF];
      LALWarning( status, "computing waveform for Hanford." );
      break;
    case 'L':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF];
      LALWarning( status, "computing waveform for Livingston." );
      break;
    case 'G':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexGEO600DIFF];
      LALWarning( status, "computing waveform for GEO600." );
      break;
    case 'T':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexTAMA300DIFF];
      LALWarning( status, "computing waveform for TAMA300." );
      break;
    case 'V':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexVIRGODIFF];
      LALWarning( status, "computing waveform for Virgo." );
      break;
    default:
      LALFree( detector.site );
      detector.site = NULL;
      LALWarning( status, "Unknown detector site, computing plus mode "
          "waveform with no time delay" );
      break;
  }

  /* set up units for the transfer function */
  if (XLALUnitDivide( &(detector.transfer->sampleUnits),
                      &lalADCCountUnit, &lalStrainUnit ) == NULL) {
    ABORTXLAL(status);
  }

  /* invert the response function to get the transfer function */
  LALCCreateVector( status->statusPtr, &( detector.transfer->data ),
      resp->data->length );
  CHECKSTATUSPTR( status );

  LALCCreateVector( status->statusPtr, &unity, resp->data->length );
  CHECKSTATUSPTR( status );
  for ( k = 0; k < resp->data->length; ++k )
  {
    unity->data[k] = 1.0;
  }

  LALCCVectorDivide( status->statusPtr, detector.transfer->data, unity,
      resp->data );
  CHECKSTATUSPTR( status );

  LALCDestroyVector( status->statusPtr, &unity );
  CHECKSTATUSPTR( status );

  thisRingdownEvent = ringdownevents;

  /*
   *
   * loop over the signals and inject them into the time series
   *
   */


  for ( thisEvent = events; thisEvent; thisEvent = thisEvent->next)
  {
    /*
     *
     * generate waveform and inject it into the data
     *
     */


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

    LALGenerateInspiral(status->statusPtr, &waveform, thisEvent, &ppnParams);
    CHECKSTATUSPTR( status );

    /* add the ringdown */
    wfm = XLALGenerateInspRing( &waveform, thisEvent, thisRingdownEvent,
       injectSignalType );

    if ( !wfm )
    {
      fprintf( stderr, "Failed to generate the waveform \n" );
      if (xlalErrno == XLAL_EFAILED)
      {
        fprintf( stderr, "Too much merger\n");
        XLALDestroyREAL4TimeSeries( chan );
        xlalErrno = XLAL_SUCCESS;
        return;
      }
      else exit ( 1 );
    }


    waveform = *wfm;

    LALInfo( status, ppnParams.termDescription );

    if ( thisEvent->geocent_end_time.gpsSeconds )
    {
      /* get the gps start time of the signal to inject */
      waveformStartTime = XLALGPSToINT8NS( &(thisEvent->geocent_end_time) );
      waveformStartTime -= (INT8) ( 1000000000.0 * ppnParams.tc );
    }
    else
    {
      LALInfo( status, "Waveform start time is zero: injecting waveform "
          "into center of data segment" );

      /* center the waveform in the data segment */
      waveformStartTime = XLALGPSToINT8NS( &(chan->epoch) );

      waveformStartTime += (INT8) ( 1000000000.0 *
          ((REAL8) (chan->data->length - ppnParams.length) / 2.0) * chan->deltaT
          );
    }

    snprintf( warnMsg, sizeof(warnMsg)/sizeof(*warnMsg),
        "Injected waveform timing:\n"
        "thisEvent->geocent_end_time.gpsSeconds = %d\n"
        "thisEvent->geocent_end_time.gpsNanoSeconds = %d\n"
        "ppnParams.tc = %e\n"
        "waveformStartTime = %" LAL_INT8_FORMAT "\n",
        thisEvent->geocent_end_time.gpsSeconds,
        thisEvent->geocent_end_time.gpsNanoSeconds,
        ppnParams.tc,
        waveformStartTime );
    LALInfo( status, warnMsg );

    /* clear the signal structure */
    memset( &signalvec, 0, sizeof(REAL4TimeSeries) );

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

    /* set the start time of the signal vector to the start time of the chan */
    signalvec.epoch = chan->epoch;

    /* set the parameters for the signal time series */
    signalvec.deltaT = chan->deltaT;
    if ( ( signalvec.f0 = chan->f0 ) != 0 )
    {
      ABORT( status, FINDCHIRPH_EHETR, FINDCHIRPH_MSGEHETR );
    }
    signalvec.sampleUnits = lalADCCountUnit;

    /* simulate the detectors response to the inspiral */
    LALSCreateVector( status->statusPtr, &(signalvec.data), chan->data->length );
    CHECKSTATUSPTR( status );

    LALSimulateCoherentGW( status->statusPtr,
        &signalvec, &waveform, &detector );
    CHECKSTATUSPTR( status );

/* *****************************************************************************/
#if 0
    FILE *fp;
    char fname[512];
    UINT4 jj, kplus, kcross;
    snprintf( fname, sizeof(fname) / sizeof(*fname),
        "waveform-%d-%d-%s.txt",
        thisEvent->geocent_end_time.gpsSeconds,
        thisEvent->geocent_end_time.gpsNanoSeconds,
        thisEvent->waveform );
    fp = fopen( fname, "w" );
    for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length;
        ++jj, kplus += 2, kcross +=2 )
    {
      fprintf(fp, "%d %e %e %le %e\n", jj,
          waveform.a->data->data[kplus],
          waveform.a->data->data[kcross],
          waveform.phi->data->data[jj],
          waveform.f->data->data[jj]);
    }
    fclose( fp );
#endif

/* ********************************************************************************/
#if 0
    FILE *fp;
    char fname[512];
    UINT4 jj;
    snprintf( fname, sizeof(fname) / sizeof(*fname),
        "waveform-%d-%d-%s.txt",
        thisEvent->geocent_end_time.gpsSeconds,
        thisEvent->geocent_end_time.gpsNanoSeconds,
        thisEvent->waveform );
    fp = fopen( fname, "w" );
    for( jj = 0; jj < signalvec.data->length; ++jj )
    {
      fprintf(fp, "%d %e %e \n", jj, signalvec.data->data[jj]);
    }
    fclose( fp );
#endif

/* ********************************************************************************/


    /* inject the signal into the data channel */
    LALSSInjectTimeSeries( status->statusPtr, chan, &signalvec );
    CHECKSTATUSPTR( status );

    /* allocate and go to next SimRingdownTable */
    if( thisEvent->next )
      thisRingdownEvent = thisRingdownEvent->next = (SimRingdownTable *)
      calloc( 1, sizeof(SimRingdownTable) );
    else
      thisRingdownEvent->next = NULL;

    /* destroy the signal */
    LALSDestroyVector( status->statusPtr, &(signalvec.data) );
    CHECKSTATUSPTR( status );

    LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) );
    CHECKSTATUSPTR( status );

    LALSDestroyVector( status->statusPtr, &(waveform.f->data) );
    CHECKSTATUSPTR( status );

    LALDDestroyVector( status->statusPtr, &(waveform.phi->data) );
    CHECKSTATUSPTR( status );

    if ( waveform.shift )
    {
      LALSDestroyVector( status->statusPtr, &(waveform.shift->data) );
      CHECKSTATUSPTR( status );
    }

    LALFree( waveform.a );
    LALFree( waveform.f );
    LALFree( waveform.phi );
    if ( waveform.shift )
    {
      LALFree( waveform.shift );
    }

  }

  LALCDestroyVector( status->statusPtr, &( detector.transfer->data ) );
  CHECKSTATUSPTR( status );

  if ( detector.site ) LALFree( detector.site );
  LALFree( detector.transfer );

  DETATCHSTATUSPTR( status );
  RETURN( status );
}
/**
 * \author Creighton, T. D.
 *
 * \brief Computes a continuous waveform with frequency drift and Doppler
 * modulation from a parabolic orbital trajectory.
 *
 * This function computes a quaiperiodic waveform using the spindown and
 * orbital parameters in <tt>*params</tt>, storing the result in
 * <tt>*output</tt>.
 *
 * In the <tt>*params</tt> structure, the routine uses all the "input"
 * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the
 * "output" fields.  If <tt>params-\>f</tt>=\c NULL, no spindown
 * modulation is performed.  If <tt>params-\>oneMinusEcc</tt>\f$\neq0\f$, or if
 * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$
 * (faster-than-light speed at periapsis), an error is returned.
 *
 * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is
 * ignored, but all other pointer fields must be set to \c NULL.  The
 * function will create and allocate space for <tt>output-\>a</tt>,
 * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary.  The
 * <tt>output-\>shift</tt> field will remain set to \c NULL.
 *
 * ### Algorithm ###
 *
 * For parabolic orbits, we combine \eqref{eq_spinorbit-tr},
 * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$
 * directly as a function of \f$E\f$:
 * \f{equation}{
 * \label{eq_cubic-e}
 * t_r = t_p + \frac{r_p\sin i}{c} \left[ \cos\omega +
 * \left(\frac{1}{v_p} + \cos\omega\right)E -
 * \frac{\sin\omega}{4}E^2 + \frac{1}{12v_p}E^3\right] \;,
 * \f}
 * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at
 * periapsis.  Following the prescription for the general analytic
 * solution to the real cubic equation, we substitute
 * \f$E=x+3v_p\sin\omega\f$ to obtain:
 * \f{equation}{
 * \label{eq_cubic-x}
 * x^3 + px = q \;,
 * \f}
 * where:
 * \f{eqnarray}{
 * \label{eq_cubic-p}
 * p & = & 12 + 12v_p\cos\omega - 3v_p^2\sin^2\omega \;, \\
 * \label{eq_cubic-q}
 * q & = & 12v_p^2\sin\omega\cos\omega - 24v_p\sin\omega +
 * 2v_p^3\sin^3\omega + 12\dot{\upsilon}_p(t_r-t_p) \;.
 * \f}
 * We note that \f$p>0\f$ is guaranteed as long as \f$v_p<1\f$, so the right-hand
 * side of \eqref{eq_cubic-x} is monotonic in \f$x\f$ and has exactly one
 * root.  However, \f$p\rightarrow0\f$ in the limit \f$v_p\rightarrow1\f$ and
 * \f$\omega=\pi\f$.  This may cause some loss of precision in subsequent
 * calculations.  But \f$v_p\sim1\f$ means that our solution will be
 * inaccurate anyway because we ignore significant relativistic effects.
 *
 * Since \f$p>0\f$, we can substitute \f$x=y\sqrt{3/4p}\f$ to obtain:
 * \f{equation}{
 * 4y^3 + 3y = \frac{q}{2}\left(\frac{3}{p}\right)^{3/2} \equiv C \;.
 * \f}
 * Using the triple-angle hyperbolic identity
 * \f$\sinh(3\theta)=4\sinh^3\theta+3\sinh\theta\f$, we have
 * \f$y=\sinh\left(\frac{1}{3}\sinh^{-1}C\right)\f$.  The solution to the
 * original cubic equation is then:
 * \f{equation}{
 * E = 3v_p\sin\omega + 2\sqrt{\frac{p}{3}}
 * \sinh\left(\frac{1}{3}\sinh^{-1}C\right) \;.
 * \f}
 * To ease the calculation of \f$E\f$, we precompute the constant part
 * \f$E_0=3v_p\sin\omega\f$ and the coefficient \f$\Delta E=2\sqrt{p/3}\f$.
 * Similarly for \f$C\f$, we precompute a constant piece \f$C_0\f$ evaluated at
 * the epoch of the output time series, and a stepsize coefficient
 * \f$\Delta C=6(p/3)^{3/2}\dot{\upsilon}_p\Delta t\f$, where \f$\Delta t\f$ is
 * the step size in the (output) time series in \f$t_r\f$.  Thus at any
 * timestep \f$i\f$, we obtain \f$C\f$ and hence \f$E\f$ via:
 * \f{eqnarray}{
 * C & = & C_0 + i\Delta C \;,\\
 * E & = & E_0 + \Delta E\times\left\{\begin{array}{l@{\qquad}c}
 * \sinh\left[\frac{1}{3}\ln\left(
 * C + \sqrt{C^2+1} \right) \right]\;, & C\geq0 \;,\\ \\
 * \sinh\left[-\frac{1}{3}\ln\left(
 * -C + \sqrt{C^2+1} \right) \right]\;, & C\leq0 \;,\\
 * \end{array}\right.
 * \f}
 * where we have explicitly written \f$\sinh^{-1}\f$ in terms of functions in
 * \c math.h.  Once \f$E\f$ is found, we can compute
 * \f$t=E(12+E^2)/(12\dot{\upsilon}_p)\f$ (where again \f$1/12\dot{\upsilon}_p\f$
 * can be precomputed), and hence \f$f\f$ and \f$\phi\f$ via
 * \eqref{eq_taylorcw-freq} and \eqref{eq_taylorcw-phi}.  The
 * frequency \f$f\f$ must then be divided by the Doppler factor:
 * \f[
 * 1 + \frac{\dot{R}}{c} = 1 + \frac{v_p}{4+E^2}\left(
 * 4\cos\omega - 2E\sin\omega \right)
 * \f]
 * (where once again \f$4\cos\omega\f$ and \f$2\sin\omega\f$ can be precomputed).
 *
 * This routine does not account for relativistic timing variations, and
 * issues warnings or errors based on the criterea of
 * \eqref{eq_relativistic-orbit} in GenerateEllipticSpinOrbitCW().
 * The routine will also warn if
 * it seems likely that \c REAL8 precision may not be sufficient to
 * track the orbit accurately.  We estimate that numerical errors could
 * cause the number of computed wave cycles to vary by
 * \f[
 * \Delta N \lesssim f_0 T\epsilon\left[
 * \sim6+\ln\left(|C|+\sqrt{|C|^2+1}\right)\right] \;,
 * \f]
 * where \f$|C|\f$ is the maximum magnitude of the variable \f$C\f$ over the
 * course of the computation, \f$f_0T\f$ is the approximate total number of
 * wave cycles over the computation, and \f$\epsilon\approx2\times10^{-16}\f$
 * is the fractional precision of \c REAL8 arithmetic.  If this
 * estimate exceeds 0.01 cycles, a warning is issued.
 */
void
LALGenerateParabolicSpinOrbitCW( LALStatus             *stat,
				 PulsarCoherentGW            *output,
				 SpinOrbitCWParamStruc *params )
{
  UINT4 n, i;              /* number of and index over samples */
  UINT4 nSpin = 0, j;      /* number of and index over spindown terms */
  REAL8 t, dt, tPow;       /* time, interval, and t raised to a power */
  REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */
  REAL8 f, fPrev;      /* current and previous values of frequency */
  REAL4 df = 0.0;      /* maximum difference between f and fPrev */
  REAL8 phi;           /* current value of phase */
  REAL8 vp;            /* projected speed at periapsis */
  REAL8 argument;      /* argument of periapsis */
  REAL8 fourCosOmega;  /* four times the cosine of argument */
  REAL8 twoSinOmega;   /* two times the sine of argument */
  REAL8 vpCosOmega;    /* vp times cosine of argument */
  REAL8 vpSinOmega;    /* vp times sine of argument */
  REAL8 vpSinOmega2;   /* vpSinOmega squared */
  REAL8 vDot6;         /* 6 times angular speed at periapsis */
  REAL8 oneBy12vDot;   /* one over (12 times angular speed) */
  REAL8 pBy3;          /* constant sqrt(p/3) in cubic equation */
  REAL8 p32;           /* constant (p/3)^1.5 in cubic equation */
  REAL8 c, c0, dc;     /* C variable, offset, and step increment */
  REAL8 e, e2, e0;     /* E variable, E^2, and constant piece of E */
  REAL8 de;            /* coefficient of sinh() piece of E */
  REAL8 tpOff;         /* orbit epoch - time series epoch (s) */
  REAL8 spinOff;       /* spin epoch - orbit epoch (s) */
  REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */
  REAL4 *fData;        /* pointer to frequency data */
  REAL8 *phiData;      /* pointer to phase data */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Make sure parameter and output structures exist. */
  ASSERT( params, stat, GENERATESPINORBITCWH_ENUL,
	  GENERATESPINORBITCWH_MSGENUL );
  ASSERT( output, stat, GENERATESPINORBITCWH_ENUL,
	  GENERATESPINORBITCWH_MSGENUL );

  /* Make sure output fields don't exist. */
  ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );

  /* If Taylor coeficients are specified, make sure they exist. */
  if ( params->f ) {
    ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL,
	    GENERATESPINORBITCWH_MSGENUL );
    nSpin = params->f->length;
    fSpin = params->f->data;
  }

  /* Set up some constants (to avoid repeated calculation or
     dereferencing), and make sure they have acceptable values. */
  vp = params->rPeriNorm*params->angularSpeed;
  vDot6 = 6.0*params->angularSpeed;
  n = params->length;
  dt = params->deltaT;
  f0 = fPrev = params->f0;
  if ( params->oneMinusEcc != 0.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EECC,
	   GENERATESPINORBITCWH_MSGEECC );
  }
  if ( vp >= 1.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EFTL,
	   GENERATESPINORBITCWH_MSGEFTL );
  }
  if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDot6 <= 0.0 ||
       n == 0 ) {
    ABORT( stat, GENERATESPINORBITCWH_ESGN,
	   GENERATESPINORBITCWH_MSGESGN );
  }
#ifndef NDEBUG
  if ( lalDebugLevel & LALWARNING ) {
    if ( f0*n*dt*vp*vp > 0.5 )
      LALWarning( stat, "Orbit may have significant relativistic"
		  " effects that are not included" );
  }
#endif

  /* Compute offset between time series epoch and periapsis, and
     betweem periapsis and spindown reference epoch. */
  tpOff = (REAL8)( params->orbitEpoch.gpsSeconds -
		   params->epoch.gpsSeconds );
  tpOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
			     params->epoch.gpsNanoSeconds );
  spinOff = (REAL8)( params->orbitEpoch.gpsSeconds -
		     params->spinEpoch.gpsSeconds );
  spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
			       params->spinEpoch.gpsNanoSeconds );

  /* Set up some other constants. */
  twopif0 = f0*LAL_TWOPI;
  phi0 = params->phi0;
  argument = params->omega;
  oneBy12vDot = 0.5/vDot6;
  fourCosOmega = 4.0*cos( argument );
  twoSinOmega = 2.0*sin( argument );
  vpCosOmega = 0.25*vp*fourCosOmega;
  vpSinOmega = 0.5*vp*twoSinOmega;
  vpSinOmega2 = vpSinOmega*vpSinOmega;
  pBy3 = sqrt( 4.0*( 1.0 + vpCosOmega ) - vpSinOmega2 );
  p32 = 1.0/( pBy3*pBy3*pBy3 );
  c0 = p32*( vpSinOmega*( 6.0*vpCosOmega - 12.0 + vpSinOmega2 ) -
	     tpOff*vDot6 );
  dc = p32*vDot6*dt;
  e0 = 3.0*vpSinOmega;
  de = 2.0*pBy3;

  /* Check whether REAL8 precision is good enough. */
#ifndef NDEBUG
  if ( lalDebugLevel & LALWARNING ) {
    REAL8 x = fabs( c0 + n*dc ); /* a temporary computation variable */
    if ( x < fabs( c0 ) )
      x = fabs( c0 );
    x = 6.0 + log( x + sqrt( x*x + 1.0 ) );
    if ( LAL_REAL8_EPS*f0*dt*n*x > 0.01 )
      LALWarning( stat, "REAL8 arithmetic may not have sufficient"
		  " precision for this orbit" );
  }
#endif

  /* Allocate output structures. */
  if ( ( output->a = (REAL4TimeVectorSeries *)
	 LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
  if ( ( output->f = (REAL4TimeSeries *)
	 LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->f, 0, sizeof(REAL4TimeSeries) );
  if ( ( output->phi = (REAL8TimeSeries *)
	 LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    LALFree( output->f ); output->f = NULL;
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->phi, 0, sizeof(REAL8TimeSeries) );

  /* Set output structure metadata fields. */
  output->position = params->position;
  output->psi = params->psi;
  output->a->epoch = output->f->epoch = output->phi->epoch
    = params->epoch;
  output->a->deltaT = n*params->deltaT;
  output->f->deltaT = output->phi->deltaT = params->deltaT;
  output->a->sampleUnits = lalStrainUnit;
  output->f->sampleUnits = lalHertzUnit;
  output->phi->sampleUnits = lalDimensionlessUnit;
  snprintf( output->a->name, LALNameLength, "CW amplitudes" );
  snprintf( output->f->name, LALNameLength, "CW frequency" );
  snprintf( output->phi->name, LALNameLength, "CW phase" );

  /* Allocate phase and frequency arrays. */
  LALSCreateVector( stat->statusPtr, &( output->f->data ), n );
  BEGINFAIL( stat ) {
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );
  LALDCreateVector( stat->statusPtr, &( output->phi->data ), n );
  BEGINFAIL( stat ) {
    TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	 stat );
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );

  /* Allocate and fill amplitude array. */
  {
    CreateVectorSequenceIn in; /* input to create output->a */
    in.length = 2;
    in.vectorLength = 2;
    LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
    BEGINFAIL( stat ) {
      TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	   stat );
      TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
	   stat );
      LALFree( output->a );   output->a = NULL;
      LALFree( output->f );   output->f = NULL;
      LALFree( output->phi ); output->phi = NULL;
    } ENDFAIL( stat );
    output->a->data->data[0] = output->a->data->data[2] = params->aPlus;
    output->a->data->data[1] = output->a->data->data[3] = params->aCross;
  }

  /* Fill frequency and phase arrays. */
  fData = output->f->data->data;
  phiData = output->phi->data->data;
  for ( i = 0; i < n; i++ ) {

    /* Compute emission time. */
    c = c0 + dc*i;
    if ( c > 0 )
      e = e0 + de*sinh( log( c + sqrt( c*c + 1.0 ) )/3.0 );
    else
      e = e0 + de*sinh( -log( -c + sqrt( c*c + 1.0 ) )/3.0 );
    e2 = e*e;
    phi = t = tPow = oneBy12vDot*e*( 12.0 + e2 );

    /* Compute source emission phase and frequency. */
    f = 1.0;
    for ( j = 0; j < nSpin; j++ ) {
      f += fSpin[j]*tPow;
      phi += fSpin[j]*( tPow*=t )/( j + 2.0 );
    }

    /* Appy frequency Doppler shift. */
    f *= f0 / ( 1.0 + vp*( fourCosOmega - e*twoSinOmega )
		/( 4.0 + e2 ) );
    phi *= twopif0;
    if ( fabs( f - fPrev ) > df )
      df = fabs( f - fPrev );
    *(fData++) = fPrev = f;
    *(phiData++) = phi + phi0;
  }

  /* Set output field and return. */
  params->dfdt = df*dt;
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
Пример #8
0
void
LALCoarseFitToPulsar	( 	LALStatus            *status,
		    		CoarseFitOutput      *output,
		    		CoarseFitInput       *input,
		    		CoarseFitParams      *params )


{
  /******* DECLARE VARIABLES ************/

	UINT4 			n,i;		/* integer indices */
	REAL8 			psi;
	REAL8 			h0/*,h*/;
	REAL8 			cosIota;
	REAL8			phase;
	REAL8   		chiSquare;
	LALDetector 		detector;
	LALSource 		pulsar;
	LALDetAndSource 	detAndSource;
 	LALDetAMResponse 	computedResponse;
	REAL4Vector 		*Fp, *Fc;	/* pointers to amplitude responses of the detector */
	REAL8Vector		*var;
	REAL8 			cos2phase,sin2phase;
 	COMPLEX16		Xp, Xc;
	REAL8 			Y, cosIota2;
	COMPLEX16		A,B;
  	REAL8			sumAA, sumBB, sumAB;
	REAL8			h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0;
  	REAL8			minChiSquare;
	COMPLEX16		eh0;
	REAL8 oldMinEh0, oldMaxEh0, weh0;
	UINT4			iH0, iCosIota, iPhase, iPsi, arg;

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /******* CHECK VALIDITY OF ARGUMENTS  ************/
  ASSERT(output != (CoarseFitOutput *)NULL, status,
         FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT);

  ASSERT(params != (CoarseFitParams *)NULL, status,
         FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS);

  ASSERT(input != (CoarseFitInput *)NULL, status,
         FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT);

  ASSERT(input->B->length == input->var->length, status,
  FITTOPULSARH_EVECSIZE , FITTOPULSARH_MSGEVECSIZE );

  /******* EXTRACT INPUTS AND PARAMETERS ************/

  n = input->B->length;

  for (i = 0; i < n; i++)
     ASSERT(creal(input->var->data[i]) > 0.0 && cimag(input->var->data[i]) > 0.0, status,
         FITTOPULSARH_EVAR, FITTOPULSARH_MSGEVAR);

  detector = params->detector;
  detAndSource.pDetector = &detector;

  pulsar = params->pulsarSrc;

  /******* ALLOCATE MEMORY TO VECTORS **************/

  Fp = NULL;
  LALSCreateVector(status->statusPtr, &Fp, n);
  Fp->length = n;

  Fc = NULL;
  LALSCreateVector(status->statusPtr, &Fc, n);
  Fc->length = n;

  var = NULL;
  LALDCreateVector(status->statusPtr, &var, n);
  var->length = n;
  /******* INITIALIZE VARIABLES *******************/

  minChiSquare = INICHISQU;
  oldMaxEh0 = INIMAXEH;
  oldMinEh0 = INIMINEH;


  for (i=0;i<n;i++)
  {
    var->data[i] = creal(input->var->data[i]) + cimag(input->var->data[i]);
  }
  /******* DO ANALYSIS ************/

  for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++)
  {
    psi = params->meshPsi[0] + iPsi*params->meshPsi[1];
    pulsar.orientation = psi;
    detAndSource.pSource = &pulsar;

   /* create vectors containing amplitude response of detector for specified times */
   for (i=0;i<n;i++)
   {
     LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &input->t[i]);
     Fp->data[i] = (REAL8)computedResponse.plus;
     Fc->data[i] = (REAL8)computedResponse.cross;
   }

   for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++)
   {
     phase = params->meshPhase[0] + iPhase*params->meshPhase[1];
     cos2phase = cos(2.0*phase);
     sin2phase = sin(2.0*phase);
     for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++)
     {
       cosIota = params->meshCosIota[0] + iCosIota*params->meshCosIota[1];
       cosIota2 = 1.0 + cosIota*cosIota;
       Xp = crect( cosIota2 * cos2phase, cosIota2 * sin2phase );

       Y = 2.0*cosIota;

       Xc = crect( Y*sin2phase, -Y*cos2phase );

       sumAB = 0.0;
       sumAA = 0.0;
       sumBB = 0.0;
       eh0 = 0.0;

       for (i = 0; i < n; i++)
       {
	 B = input->B->data[i];

	 A = crect( Fp->data[i]*creal(Xp) + Fc->data[i]*creal(Xc), Fp->data[i]*cimag(Xp) + Fc->data[i]*cimag(Xc) );

	 sumBB += (creal(B)*creal(B) + cimag(B)*cimag(B)) / var->data[i];
	 sumAA += (creal(A)*creal(A) + cimag(A)*cimag(A)) / var->data[i];
	 sumAB += (creal(B)*creal(A) + cimag(B)*cimag(A)) / var->data[i];

         /**** calculate error on h0 **********/
	 eh0 += crect( (Fp->data[i]*cosIota2*cos2phase + 2.0*Fc->data[i]*cosIota*sin2phase) * (Fp->data[i]*cosIota2*cos2phase + 2.0*Fc->data[i]*cosIota*sin2phase) / creal(input->var->data[i]), (Fp->data[i]*cosIota2*sin2phase - 2.0*Fc->data[i]*cosIota*cos2phase) * (Fp->data[i]*cosIota2*sin2phase - 2.0*Fc->data[i]*cosIota*cos2phase) / cimag(input->var->data[i]) );
        }

	for (iH0 = 0; iH0 < params->meshH0[2]; iH0++)
        {
	  h0 = params->meshH0[0] + iH0*params->meshH0[1];
	  chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA;

	  if (chiSquare<minChiSquare)
	  {
	    minChiSquare = chiSquare;
	    h0BestFit = h0;
	    cosIotaBestFit = cosIota;
	    psiBestFit = psi;
	    phaseBestFit = phase;
	    output->eh0[0] = 1.0 /sqrt(sqrt(creal(eh0)*creal(eh0) + cimag(eh0)*cimag(eh0)));
	  }

	  weh0 = 1.0 /sqrt(sqrt(creal(eh0)*creal(eh0) + cimag(eh0)*cimag(eh0)));

	  if (weh0>oldMaxEh0)
	  {
	    output->eh0[2] = weh0;
	    oldMaxEh0 = weh0;
	  }

	  if (weh0<oldMinEh0)
	  {
	    output->eh0[1] = weh0;
	    oldMinEh0 = weh0;
          }
	  arg = iH0 + params->meshH0[2]*(iCosIota +  params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi));
	  output->mChiSquare->data[arg] = chiSquare;
        }
      }
    }
  }

  /******* CONSTRUCT OUTPUT ************/

  output->h0 = h0BestFit;
  output->cosIota = cosIotaBestFit;
  output->phase = phaseBestFit;
  output->psi = psiBestFit;
  output->chiSquare = minChiSquare;


  ASSERT(minChiSquare < INICHISQU,  status,
  FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI);

  LALSDestroyVector(status->statusPtr, &Fp);
  LALSDestroyVector(status->statusPtr, &Fc);
  LALDDestroyVector(status->statusPtr, &var);
  DETATCHSTATUSPTR(status);
  RETURN(status);


}
void FUNC ( LALStatus* status, 
                              STYPE *series,
	                      const CHAR *filename )
 
{
  REAL8Vector		*f=NULL;
  REAL8			*fPtr;
  REAL8			*fStopPtr;
  union { TYPE value; BASETYPE array[sizeof(TYPE)/sizeof(BASETYPE)]; } data;
  TYPE			*outputPtr;
  FILE			*fp;
  CHAR			line[MaxLineLength];  /*holds data from each line*/
  LALUnit		tempUnit;
  CHARVector            *string=NULL;
  
  /* need to declare error section here */
  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  ASSERT( filename != NULL, status, READFTSERIESH_EFILENOTFOUND,
	  READFTSERIESH_MSGEFILENOTFOUND );
  
  /* if (filename == NULL) return; */

  fp = LALFopen( filename, "r" );
  if (fp == NULL) 
  {
    ABORT( status, READFTSERIESH_EFILENOTFOUND,
	   READFTSERIESH_MSGEFILENOTFOUND );
  }

  /* limited to line of data not exceeding MaxLineLength chars*/

  if (fgets(line,sizeof(line),fp) == NULL)
  { 
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }

  if (line[0] != '#' || line[1] != ' ')
  {
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }

  if (snprintf( series->name, sizeof( series->name ), "%s", line + 2) < 0)
  {
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }
  /* Change trailing linefeed to '\0' */
  if ( changeCharToNull(series->name, '\n', series->name + LALNameLength) )
  {	
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }

  if (fgets(line,sizeof(line),fp) == NULL)
  { 
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }

  if (line[0] != '#' || line[1] != ' ')
  {
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }
  if (line[2] == '\n') 
  {
    series->epoch.gpsSeconds = 0;
    series->epoch.gpsNanoSeconds = 0;
  }
  else if ( sscanf( line, "# Epoch is %d seconds, %d nanoseconds\n",
	            &(series->epoch.gpsSeconds), 
                    &(series->epoch.gpsNanoSeconds) )
	    != 2 )
  {
    ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE );
  }

  TRY( LALCHARCreateVector(status->statusPtr, &string, MaxLineLength), status );
  
  if (fgets(line,sizeof(line),fp) == NULL) 
  {
    TRY( LALCHARDestroyVector( status->statusPtr, &string ), status );
    ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE );
  }

  if (!strcmp(line,"# Units are ()\n"))
  {
    series->sampleUnits = lalDimensionlessUnit; 
  }
  else {
    if ( sscanf( line, "# Units are (%[^)]", string->data ) != 1 )
    {
      TRY( LALCHARDestroyVector( status->statusPtr, &string ), status );
      ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE );
    }
    if ( XLALParseUnitString(&tempUnit, string->data) == NULL )
    {
      TRY( LALCHARDestroyVector( status->statusPtr, &string ), status );
      ABORT( status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE );
    }
    series->sampleUnits = tempUnit;
  }

  TRY( LALCHARDestroyVector( status->statusPtr, &string ), status );

  TRY( LALDCreateVector(status->statusPtr, &f, series->data->length),
       status );
  
  fPtr = &(f->data[0]);
  fStopPtr = fPtr + f->length;
  outputPtr = &(series->data->data[0]);
  
  if(fgets(line,sizeof(line),fp) == NULL) 
  {
    TRY( LALDDestroyVector( status->statusPtr, &f ), status );
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }
  
  while(fgets(line,sizeof(line),fp)!=NULL)
  {
    /*change arg so we dereference pointer */
    if ( sscanf(line, FMT, fPtr, ARG) != 1 + NARGS ) 
    {
      TRY( LALDDestroyVector( status->statusPtr, &f ), status );
      ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
    }
    *(outputPtr) = data.value;
    fPtr++;
    outputPtr++;	
    
    if (fPtr > fStopPtr) {
      TRY( LALDDestroyVector( status->statusPtr, &f ), status );
      ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
    }
  }
  if (fPtr != fStopPtr) 
  {
    TRY( LALDDestroyVector( status->statusPtr, &f ), status );
    ABORT(status, READFTSERIESH_EPARSE, READFTSERIESH_MSGEPARSE);
  }
  
  (series->deltaF) = ( f->data[1] - f->data[0] );
  (series->f0) = f->data[0];
  
  TRY( LALDDestroyVector( status->statusPtr, &f ), status );
  
  DETATCHSTATUSPTR(status);
  RETURN(status);
}
Пример #10
0
int
main(int argc, char **argv)
{
  /* top-level status structure */
  static LALStatus status;
  /* Structure specifying the nature of the bank needed */
  static InspiralCoarseBankIn coarseIn;
  /* Template bank lists */
  static InspiralTemplateList *list1, *list2;
  /* Number of templates in list1 and list2 */
  INT4 nlist1=0;

  void (*noisemodel)(LALStatus*,REAL8*,REAL8) = LALLIGOIPsd;
  INT4   j, numPSDpts=16384/2;
  FILE *fpr;
  UserParams userParams;
  INT4 i=1;
  double scaling = sqrt(2.);

  /* initiliase userParams.calque */
  userParams.calque = TaylorT1;

  while(i < argc)
    {
      if (strcmp(argv[i], "--help") == 0) {
        fprintf(stderr, "--template [TaylorT1, TaylorT3, EOB, ...]\n--grid-spacing [Hexagonal, SquareNotOriented, ...]\n`--noise-model [LIGO, VIRGO...]\n");
        exit(0);
      }
      else if ( strcmp(argv[i],	"--noise-model") 	== 0 ) {
	if ( strcmp(argv[++i],	"VIRGO")	==0)	{
          (noisemodel) = &LALVIRGOPsd;
        }
        else if ( strcmp(argv[i],	"LIGOI")	==0){
          (noisemodel) = &LALLIGOIPsd;
        }
        else if ( strcmp(argv[i],	"LIGOA")	==0){
          (noisemodel) = &LALAdvLIGOPsd;
        }
        else if ( strcmp(argv[i],	"EGO")	==0){
          (noisemodel) = &LALEGOPsd;
        }
      }
      else if ( strcmp(argv[i],	"--template") 	== 0 ) {
	if ( strcmp(argv[++i],	"TaylorT1")	==0)	{
          userParams.calque = TaylorT1;
        }
	else if ( strcmp(argv[i],	"TaylorT2")	==0)	{
          userParams.calque = TaylorT2;
        }
	else if ( strcmp(argv[i],	"TaylorT3")	==0)	{
          userParams.calque = TaylorT3;
        }
	else if ( strcmp(argv[i],	"TaylorF1")	==0)	{
          userParams.calque = TaylorF1;
        }
	else if ( strcmp(argv[i],	"TaylorF2")	==0)	{
          userParams.calque = TaylorF2;
        }
	else if ( strcmp(argv[i],	"PadeT1")	==0)	{
          userParams.calque = PadeT1;
        }
	else if ( strcmp(argv[i],	"PadeF1")	==0)	{
          userParams.calque = PadeF1;
        }
	else if ( strcmp(argv[i],	"EOB")		==0)	{
          userParams.calque = EOB;
        }
	else if ( strcmp(argv[i],	"BCV")		==0)    {
          userParams.calque = BCV;
        }
	else if ( strcmp(argv[i],	"SpinTaylorT3")	==0)	{
          userParams.calque = SpinTaylorT3;
        }
      } /*end of --template if*/
      else if  ( strcmp(argv[i],	"--grid-spacing") 	== 0 ) {
	i++;
	if (strcmp(argv[i], "Square") == 0)
          coarseIn.gridSpacing = Square;
	else if (strcmp(argv[i], "Hexagonal")         == 0)
          coarseIn.gridSpacing = Hexagonal;
	else if (strcmp(argv[i], "HybridHexagonal")         == 0)
          coarseIn.gridSpacing = HybridHexagonal;
	else if (strcmp(argv[i], "SquareNotOriented")         == 0)
          coarseIn.gridSpacing = SquareNotOriented;
	else if (strcmp(argv[i], "HexagonalNotOriented")         == 0)
          coarseIn.gridSpacing = HexagonalNotOriented;
	else {fprintf(stderr, "grid-spacing is either square or hexagonal\n"); exit(0);}
      }
      i++;
    }

  coarseIn.LowGM        = -2;
  coarseIn.HighGM       = 6;
  coarseIn.fLower       = 40.L;
  coarseIn.fUpper       = 2047L;
  coarseIn.tSampling    = 4096.L;
  coarseIn.order        = LAL_PNORDER_TWO;
  coarseIn.space        = Tau0Tau3;
  coarseIn.mmCoarse     = 0.98;
  coarseIn.mmFine       = 0.98;
  coarseIn.iflso        = 0.0L;
  coarseIn.mMin         = 3;
  coarseIn.mMax         = 30.0;
  coarseIn.MMax         = coarseIn.mMax * 2.;
  coarseIn.massRange    = MinMaxComponentMass;
  /* coarseIn.massRange = MinComponentMassMaxTotalMass;*/
  /* minimum value of eta */
  coarseIn.etamin       = coarseIn.mMin * ( coarseIn.MMax - coarseIn.mMin) / pow(coarseIn.MMax,2.);
  coarseIn.psi0Min      = 1.e0;
  coarseIn.psi0Max      = 2.5e4;
  coarseIn.psi3Min      = -1e4;
  coarseIn.psi3Max      = -10;
  coarseIn.alpha        = 0.L;
  coarseIn.numFcutTemplates = 4;

  memset( &(coarseIn.shf), 0, sizeof(REAL8FrequencySeries) );
  coarseIn.shf.f0 = 0;
  LALDCreateVector( &status, &(coarseIn.shf.data), numPSDpts );
  coarseIn.shf.deltaF = coarseIn.tSampling / (2.*(REAL8) coarseIn.shf.data->length + 1.L);
  LALNoiseSpectralDensity (&status,
			   coarseIn.shf.data,
			   noisemodel, coarseIn.shf.deltaF );


  if (userParams.calque == BCV)
  {
	coarseIn.approximant = BCV;
	coarseIn.space 	= Psi0Psi3;
  }
  else
  {
	coarseIn.approximant = TaylorT3;
	coarseIn.space 	= Tau0Tau3;
  }

  LALInspiralCreateCoarseBank(&status, &list1, &nlist1, coarseIn);


  fprintf(stderr, "save %d template in results in SpaceCovering.out\n", nlist1);
  fflush(stdout);
  fflush(stderr);

  fpr = fopen("SpaceCovering.out", "w");
  for (j=0; j<nlist1; j++)
  {
	  switch(userParams.calque){
	  case TaylorT1:
	  case TaylorT2:
	  case TaylorT3:
	  case EOB:

 	  fprintf(fpr, "%e %e %e %e %e %e %e\n",
	  		  list1[j].params.t0,
			  list1[j].params.t3,
			  list1[j].metric.g00,
			  list1[j].metric.g11,
                          2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g00),
                          2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g11),
			  list1[j].metric.theta*180/LAL_PI);
		  break;
	  case BCV:
	  fprintf(fpr, "%e %e %e %e %e %e %e\n",
	  		  list1[j].params.psi0,
			  list1[j].params.psi3,
			  list1[j].metric.g00,
			  list1[j].metric.g11,
                          2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g00),
                          2*sqrt((1-coarseIn.mmCoarse)/list1[j].metric.g11),
			  list1[j].metric.theta);
	  break;
	  }
  }



  fprintf(fpr, "&\n");

  {
    INT4 k;
    UINT4 valid;
    static RectangleIn RectIn;
    static RectangleOut RectOut;
    static HexagonOut HexaOut;

    /* Print out the template parameters */
    for (k=0; k<nlist1; j=k++)
    {
      RectIn.dx = sqrt(2.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g00 );
      RectIn.dy = sqrt(2.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g11 );
      RectIn.theta = list1[j].metric.theta  ;

      if (userParams.calque == BCV)
      {
        RectIn.x0 = (REAL8) list1[k].params.psi0;
        RectIn.y0 = (REAL8) list1[k].params.psi3;
      }
      else
      {
        RectIn.x0 = (REAL8) list1[k].params.t0;
        RectIn.y0 = (REAL8) list1[k].params.t3;
      }
      /*
       * LALInspiralValidParams(&status, &valid, bankParams, coarseIn);
       * */
      valid = 1;
      if (valid)
      {
        if (coarseIn.gridSpacing == SquareNotOriented)
        {
          LALRectangleVertices(&status, &RectOut, &RectIn);
          fprintf(fpr, "%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n",
              RectOut.x1, RectOut.y1,
              RectOut.x2, RectOut.y2,
              RectOut.x3, RectOut.y3,
              RectOut.x4, RectOut.y4,
              RectOut.x5, RectOut.y5);
          fprintf(fpr, "&\n");
        }
        else if (coarseIn.gridSpacing == Hexagonal || coarseIn.gridSpacing == HybridHexagonal)
        {
          RectIn.dx = sqrt(3.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g00 );
          RectIn.dy = sqrt(3.0 * (1. - coarseIn.mmCoarse)/list1[k].metric.g11 );
          /*RectIn.theta = list1[j].metric.theta + LAL_PI/6;*/
          LALHexagonVertices(&status, &HexaOut, &RectIn);
          fprintf(fpr, "%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n%e %e\n",
              HexaOut.x1, HexaOut.y1,
              HexaOut.x2, HexaOut.y2,
              HexaOut.x3, HexaOut.y3,
              HexaOut.x4, HexaOut.y4,
              HexaOut.x5, HexaOut.y5,
              HexaOut.x6, HexaOut.y6,
              HexaOut.x7, HexaOut.y7);
          fprintf(fpr, "&\n");

        }
      }

      /*plots the ellipses*/
      {
        int Nth =100;
        double th;
        double x,y,phi,a,b, theta;
        for (theta=0; theta<2*3.14; theta+=2*3.14/(double)Nth)
        {
          a = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g00 );
          b = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g11 );
          x = a * cos(theta)/scaling;
          y = b * sin(theta)/scaling;
          phi=list1[j].metric.theta ;
          /*              phi *=1.1;*/
          if (userParams.calque == BCV)
          {
            th = x*cos(phi)-y*sin(phi)+list1[j].params.psi0;
            y  = x*sin(phi)+y*cos(phi)+list1[j].params.psi3;
          }
          else
          {
            th = x*cos(phi)-y*sin(phi)+list1[j].params.t0;
            y  = x*sin(phi)+y*cos(phi)+list1[j].params.t3;
          }
          x  = th;
          fprintf(fpr, "%f %f\n", x, y);
        }
        theta = 0;
        a = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g00 );
        b = sqrt( 2.L * (1.L-coarseIn.mmCoarse)/list1[j].metric.g11 );
        x = a * cos(theta) /scaling;
        y = b * sin(theta)/scaling;
        phi=list1[j].metric.theta ;

        if (userParams.calque == BCV)
        {
          th = x*cos(phi)-y*sin(phi)+list1[j].params.psi0;
          y  = x*sin(phi)+y*cos(phi)+list1[j].params.psi3;
        }
        else
        {
          th = x*cos(phi)-y*sin(phi)+list1[j].params.t0;
          y  = x*sin(phi)+y*cos(phi)+list1[j].params.t3;
        }
        x  = th;
        fprintf(fpr, "%f %f\n", x, y);

        fprintf(fpr, "&\n");
      }
    }
  }




  LALInspiralCreateBoundarySpace(coarseIn);


  fclose(fpr);
  /* Free the list, and exit. */
  if (list1 != NULL) LALFree (list1);
  if (list2 != NULL) LALFree (list2);
  LALDDestroyVector( &status, &(coarseIn.shf.data) );
  LALCheckMemoryLeaks();
  return(0);
}
void
LALCoarseFitToPulsar	( 	LALStatus            *status,
		    		CoarseFitOutput      *output,
		    		CoarseFitInput       *input,
		    		CoarseFitParams      *params )
		

{
  /******* DECLARE VARIABLES ************/

  UINT4 			n,i,j;		/* integer indices */
  REAL8 			psi;
  REAL8 			h0;
  REAL8 			cosIota;
  REAL8			phase;
  REAL8   		chiSquare;
  LALDetector 		detector;
  LALSource 		pulsar;
  LALDetAndSource 	detAndSource;
  LALDetAMResponse 	computedResponse;
  REAL4Vector 		*Fp, *Fc;	/* pointers to amplitude responses of the detector */
  REAL8Vector		*var;
  REAL8 			cos2phase,sin2phase;
  COMPLEX16		Xp, Xc;
  REAL8 			Y, cosIota2;
  COMPLEX16		A,B;
  REAL8			sumAA, sumBB, sumAB;	
  REAL8			h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0;
  REAL8			minChiSquare;
  UINT4			iH0, iCosIota, iPhase, iPsi, arg;
  LALGPSandAcc		pGPSandAcc;
	
  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /******* CHECK VALIDITY OF ARGUMENTS  ************/	 
  ASSERT(output != (CoarseFitOutput *)NULL, status,
         FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT);	 
  
  ASSERT(params != (CoarseFitParams *)NULL, status,
         FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS);
	 
  ASSERT(input != (CoarseFitInput *)NULL, status,
         FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT);

  ASSERT(input->B->length == input->var->length, status, 
  FITTOPULSARH_EVECSIZE , FITTOPULSARH_MSGEVECSIZE );

  /******* EXTRACT INPUTS AND PARAMETERS ************/
  
  n = input->B->length;

  for (i = 0; i < n; i++)
     ASSERT(input->var->data[i].re > 0.0 && input->var->data[i].im > 0.0, status,
         FITTOPULSARH_EVAR, FITTOPULSARH_MSGEVAR);
  
  detector = params->detector;
  detAndSource.pDetector = &detector;
  
  pulsar = params->pulsarSrc;

  /******* ALLOCATE MEMORY TO VECTORS **************/
  
  Fp = NULL;
  LALSCreateVector(status->statusPtr, &Fp, n);
  Fp->length = n;
 
  Fc = NULL;
  LALSCreateVector(status->statusPtr, &Fc, n);
  Fc->length = n;
  
  var = NULL;
  LALDCreateVector(status->statusPtr, &var, n);
  var->length = n; 
  /******* INITIALIZE VARIABLES *******************/
  
  minChiSquare = INICHISQU;
  
  /******* DO ANALYSIS ************/
  for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++)
  {
    fprintf(stderr,"%d out of %f iPsi\n", iPsi+1, params->meshPsi[2]);
    fflush(stderr);
    psi = params->meshPsi[0] + (REAL8)iPsi*params->meshPsi[1];
    pulsar.orientation = psi;
    detAndSource.pSource = &pulsar;
   
   for (i=0;i<n;i++)
   {    
      Fp->data[i] = 0.0;
      Fc->data[i] = 0.0;
      for(j=0;j<input->N;j++)
      {
        pGPSandAcc.gps.gpsNanoSeconds =  input->t[i].gpsNanoSeconds;
        pGPSandAcc.gps.gpsSeconds =  input->t[i].gpsSeconds + (double)j*60.0; 
        pGPSandAcc.accuracy = 1.0; 
        LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &pGPSandAcc);        
	Fp->data[i] += (REAL8)computedResponse.plus;
        Fc->data[i] += (REAL8)computedResponse.cross;	  
      }	  
      Fp->data[i] /= (double)input->N;
      Fc->data[i] /= (double)input->N;
   }
   for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++)
   {   
     phase = params->meshPhase[0] + (REAL8)iPhase*params->meshPhase[1];
     cos2phase = cos(2.0*phase);
     sin2phase = sin(2.0*phase);
     for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++)
     {
       cosIota = params->meshCosIota[0] + (REAL8)iCosIota*params->meshCosIota[1];
       cosIota2 = 1.0 + cosIota*cosIota; 
       Xp.re = 0.25*cosIota2 * cos2phase;
       Xp.im = 0.25*cosIota2 * sin2phase;

       Y = 0.5*cosIota;
		
       Xc.re = Y*sin2phase;
       Xc.im = -Y*cos2phase; 
	  
       sumAB = 0.0;
       sumAA = 0.0;
       sumBB = 0.0;
       
       for (i = 0; i < n; i++)
       {
	 B.re = input->B->data[i].re;
	 B.im = input->B->data[i].im;
	    
	 A.re = Fp->data[i]*Xp.re + Fc->data[i]*Xc.re;
	 A.im = Fp->data[i]*Xp.im + Fc->data[i]*Xc.im;	
	
	 sumBB += B.re*B.re/input->var->data[i].re +
	 B.im*B.im/input->var->data[i].im;
	 sumAA += A.re*A.re/input->var->data[i].re +
	 A.im*A.im/input->var->data[i].im;
	 sumAB += B.re*A.re/input->var->data[i].re +
	 B.im*A.im/input->var->data[i].im;
       }

	for (iH0 = 0; iH0 < params->meshH0[2]; iH0++)
        {
	  h0 = params->meshH0[0] + (float)iH0*params->meshH0[1];
	  chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA;
	
	  if (chiSquare<minChiSquare)
	  {
	    minChiSquare = chiSquare;
	    h0BestFit = h0;
	    cosIotaBestFit = cosIota;
	    psiBestFit = psi;
	    phaseBestFit = phase;
	  }
	  
	  arg = iH0 + params->meshH0[2]*(iCosIota +  params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi));
	  output->mChiSquare->data[arg] = chiSquare;
        }
      }  
    }
  }

  /******* CONSTRUCT OUTPUT ************/

  output->h0 = h0BestFit;
  output->cosIota = cosIotaBestFit;
  output->phase = phaseBestFit;
  output->psi = psiBestFit;
  output->chiSquare = minChiSquare;

  ASSERT(minChiSquare < INICHISQU,  status,
  FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI); 
  
  LALSDestroyVector(status->statusPtr, &Fp);
  LALSDestroyVector(status->statusPtr, &Fc);
  LALDDestroyVector(status->statusPtr, &var);
  DETATCHSTATUSPTR(status);
  RETURN(status);  
}
Пример #12
0
int main(int argc, char **argv)
{
  /***** declare variables *****/
  static LALStatus      status;
  FILE *fp1, *fp2, *fp3, *fp4;
  FILE *fp_pdf1, *fp_pdf2, *fp_pdf3, *fp_pdf4;
  FILE *fp_pdf1Phase, *fp_pdf2Phase, *fp_pdf3Phase, *fp_pdf4Phase;
  FILE *fp_pdf1Psi, *fp_pdf2Psi, *fp_pdf3Psi, *fp_pdf4Psi;
  FILE *fp_pdf1CosIota, *fp_pdf2CosIota, *fp_pdf3CosIota, *fp_pdf4CosIota;  
  FILE *fp_joint, *fp_jointPhase, *fp_jointPsi, *fp_jointCosIota;
  FILE *fpmesh, *psrfp;
  char infile1[256], infile2[256], infile3[256], infile4[256];  
  char outfile1[256], outfile2[256], outfile3[256], outfile4[256];
  char outfile1Phase[256], outfile2Phase[256], outfile3Phase[256], outfile4Phase[256];
  char outfile1Psi[256], outfile2Psi[256], outfile3Psi[256], outfile4Psi[256];
  char outfile1CosIota[256], outfile2CosIota[256], outfile3CosIota[256], outfile4CosIota[256];   
  char outfile[256], outfilePhase[256],outfilePsi[256],outfileCosIota[256];   
  char psrinput[256], inmesh[256], txt[32], pulsar_name[64];
  UINT4 iPsi, iPhase, iCosIota, iH0, arg, i;
  INT4 iRA=0, iDEC=0, if0=0, if1=0, if2=0,ifepoch=0, flag =0, irun;
  INT4 num_dect, iGEO = 0, iL1 = 0, iH1 = 0, iH2 = 0;
  REAL4 psr_ra, psr_dec; 
  REAL8 RA, DEC, f0, f1, f2, val, t;
  REAL8 minChi, area, outL1, outH1, outH2, outGEO;
  COMPLEX16 B, var;    
  LIGOTimeGPS fepoch, tgps1[MAXLENGTH],tgps2[MAXLENGTH],tgps3[MAXLENGTH], tgps4[MAXLENGTH];    
  FitInputStudentT  input1, input2, input3, input4;
  CoarseFitInput input1_chi, input2_chi, input3_chi, input4_chi;
  CoarseFitParams params1, params2, params3, params4;
  CoarseFitOutput output1, output2, output3, output4;
  LALDetector 	detectorLHO,detectorLLO, detectorGEO;
  LALSource pulsar;
  PulsarPdfs prob1, prob2, prob3, prob4, prob;


/* get command line arguments and print error if there is wrong number of arguments.  if 
the variable condor is defined, then read in the first argument pulsar_name from stdin */

#ifndef CONDOR 
  if (argc < 8 || argc > 11){
   fprintf(stderr, "1. Name of pulsar (when not using condor)\n"); 
   fprintf(stderr,"2. working directory\n");
   fprintf(stderr, "3. flag=1 for Gaussian with explicit noise estimate provided\n flag=2 for noise analytically marginalised out of Gaussian\n");
   fprintf(stderr, "4. name of mesh file in inputs directory\n");
   fprintf(stderr, "5. irun - 2 for S2, 3 for S3\n");
   fprintf(stderr, "6. num detectors (max 4)\n");
   fprintf(stderr, "7-10. H1, H2, L1, and/or GEO\n");
   fprintf(stderr,"There were argc= %d arguments:\n",argc -1);
   fflush(stderr);
   return 2;
  }
  sprintf(pulsar_name, "%s", argv[1]);
#else
  // read pulsar name from stdin for condor
   scanf("%s", &pulsar_name[0]);
   fprintf(stderr, "pulsar name: %s\n",pulsar_name);
#endif  

  fprintf(stderr, "pulsarname=%s\n", pulsar_name);
   
  flag = atoi(argv[3]);
  irun = atoi(argv[5]);
  num_dect = atoi(argv[6]);
  
  if (num_dect >4)
  {
    fprintf(stderr, "Number of IFOs must be less than 5 (H1, H2, L1, and/or GEO)!\n");
    return(1);
  }
  
  /* check which detectors we are being used for analysis*/
  for (i=0;i<num_dect;i++)
  {
    if (!strcmp(argv[i+7],"GEO")) iGEO = 1;
    else if (!strcmp(argv[i+7],"L1")) iL1 = 1;
    else if (!strcmp(argv[i+7],"H1")) iH1 = 1;
    else if (!strcmp(argv[i+7],"H2")) iH2 = 1;
    else 
    {
      fprintf(stderr, "what is %s? not GEO, L1, H1, or H2!\n",argv[i+7]);
      return(2); 
    }
  }
/************** BEGIN READING PULSAR PARAMETERS ******************/     
/* read input file with pulsar information */
  
  sprintf(psrinput,"%s/inputs/%s", argv[2],pulsar_name);
  psrfp=fopen(psrinput,"r");
  
  while (2==fscanf(psrfp,"%s %lf", &txt[0], &val))
  {
    if( !strcmp(txt,"ra") || !strcmp(txt,"RA")) {
      psr_ra = RA = val;
      iRA = 1;
    }  
    
    else if( !strcmp(txt,"dec") || !strcmp(txt,"DEC")) {
      psr_dec = DEC = val;
      iDEC = 1;
    }
    else if( !strcmp(txt,"f0") || !strcmp(txt,"F0")) {
      f0 = val;
      if0 = 1;
    }
    else if( !strcmp(txt,"f1") || !strcmp(txt,"F1")) {
      f1 = val;
      if1 = 1;
    }
    else if( !strcmp(txt,"f2") || !strcmp(txt,"F2")) {
      f2 = val;
      if2 = 1;
    }
    else if( !strcmp(txt,"fepoch") || !strcmp(txt,"fepoch")) {
      fepoch.gpsSeconds = floor(val*1e-9);
      fepoch.gpsNanoSeconds = (INT8) val - fepoch.gpsSeconds*1e9;
      ifepoch = 1;
    }
  }
  
  if ((iRA+iDEC+ifepoch+if0+if1+if2) != 6) {
    fprintf(stderr, "pulsar input file missing info \nra\txxx\ndec\txxx\nf0\txxx\nf1\txxx\nf2\txxx\nfepoch\txxx\n");
    return(3);
  }

  fclose(psrfp);
  
  /************** END READING PULSAR PARAMETERS ******************/   

  detectorLHO = lalCachedDetectors[LALDetectorIndexLHODIFF];
  detectorLLO = lalCachedDetectors[LALDetectorIndexLLODIFF];
  detectorGEO = lalCachedDetectors[LALDetectorIndexGEO600DIFF];

  /* currently this code assumes that we are using 30 minute stretches of data
     this could be relaxed in the future */
  input1.N = input2.N = input3.N = input4.N = 30;  
  input1_chi.N = input2_chi.N = input3_chi.N = input4_chi.N = 30;
  
  /* set up strings pointing to the file that we want to read as input
     for the gaussian likelihood (flag=1) there is two extra columns in the 
     input files corresponding to the variance of the real and imaginary Bk's. 
     the Bk's used in the gausian likelihood (flag=1) are calculated every 30 minutes
     (average of 30 1-minute Bk).
     for the student-t likelihood (flag=2), the Bk's are from every 60 seconds */
     
  if (flag == 1)
  {
   if (iL1) sprintf(infile1,"%s/dataL1/outfine.%s_L1.S%d_chi_30", argv[2],pulsar_name, irun);   
   if (iH1) sprintf(infile2,"%s/dataH1/outfine.%s_H1.S%d_chi_30", argv[2], pulsar_name, irun);   
   if (iH2) sprintf(infile3,"%s/dataH2/outfine.%s_H2.S%d_chi_30", argv[2], pulsar_name, irun);         
   if (iGEO) sprintf(infile4, "%s/dataGEO/outfine.%s_GEO.S%d_chi_30", argv[2], pulsar_name, irun);
  }
  else if (flag == 2)
  {
    if (iL1) sprintf(infile1,"%s/dataL1/finehet_%s_L1", argv[2], pulsar_name);
    if (iH1) sprintf(infile2,"%s/dataH1/finehet_%s_H1", argv[2], pulsar_name);
    if (iH2) sprintf(infile3,"%s/dataH2/finehet_%s_H2", argv[2], pulsar_name); 
    if (iGEO) sprintf(infile4,"%s/dataG1/finehet_%s_GEO", argv[2],
pulsar_name);  
  }
  else
  {
    fprintf(stderr, "flag should be 1 or 2\n");
    return(2);    
  }
  
  /* open output files */
  if (iL1) fp1 = fopen(infile1, "r"); 
  if (iH1) fp2 = fopen(infile2, "r"); 
  if (iH2) fp3 = fopen(infile3, "r");
  if (iGEO) fp4 = fopen(infile4, "r");

  /* allocate memory for B_k and var */
  if (flag ==1 && iL1 == 1) 
  {
    input1_chi.B = NULL;
    LALZCreateVector( &status, &input1_chi.B, MAXLENGTH);
    TESTSTATUS(&status);

    input1_chi.var = NULL; 
    LALZCreateVector( &status, &input1_chi.var, MAXLENGTH);   
    TESTSTATUS(&status);
  }
  else if (flag == 2 && iL1 == 1)
  {
    input1.B = NULL;
    LALZCreateVector( &status, &input1.B, MAXLENGTH);
    TESTSTATUS(&status); 
  }
  
  if (flag ==1 && iH1 == 1) 
  {
    input2_chi.B = NULL;
    LALZCreateVector( &status, &input2_chi.B, MAXLENGTH);
    TESTSTATUS(&status);
    
    input2_chi.var = NULL; 
    LALZCreateVector( &status, &input2_chi.var, MAXLENGTH); 
    TESTSTATUS(&status);   
  }
  else if (flag == 2 && iH1 == 1)
  {
    input2.B = NULL;
    LALZCreateVector( &status, &input2.B, MAXLENGTH); 
    TESTSTATUS(&status);
  }
  
  if (flag ==1 && iH2 == 1) 
  {
    input3_chi.B = NULL;
    LALZCreateVector( &status, &input3_chi.B, MAXLENGTH);
    TESTSTATUS(&status);
    
    input3_chi.var = NULL; 
    LALZCreateVector( &status, &input3_chi.var, MAXLENGTH);  
    TESTSTATUS(&status);  
  }
  else if (flag == 2 && iH2 == 1)
  {
    input3.B = NULL;
    LALZCreateVector( &status, &input3.B, MAXLENGTH); 
    TESTSTATUS(&status);
  }
  if (flag ==1 && iGEO == 1) 
  {
    input4_chi.B = NULL;
    LALZCreateVector( &status, &input4_chi.B, MAXLENGTH);
    TESTSTATUS(&status);
    
    input4_chi.var = NULL; 
    LALZCreateVector( &status, &input4_chi.var, MAXLENGTH);   
    TESTSTATUS(&status); 
  }
  else if (flag == 2 && iGEO == 1)
  {
    input4.B = NULL;
    LALZCreateVector( &status, &input4.B, MAXLENGTH); 
    TESTSTATUS(&status);
  }
  
       
  params1.detector = detectorLLO;
  params2.detector = detectorLHO;
  params3.detector = detectorLHO;
  params4.detector = detectorGEO;
  
  /* set up RA, DEC, and coordinate system */
  pulsar.equatorialCoords.longitude = psr_ra;	      
  pulsar.equatorialCoords.latitude = psr_dec;	      
  pulsar.equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
  
  /* polarization angle will be redefined inside the fitting routine */
  pulsar.orientation = 0.0; 	      
 		      
  params1.pulsarSrc = params2.pulsarSrc = params3.pulsarSrc = params4.pulsarSrc= pulsar;  
 
  /****************** BEGIN READ INPUT DATA (Bk's) ***************************/
 
  /* read data from L1 */
  if (iL1)
  {
    if (flag == 2) /* student-t */
    {
      fscanf(fp1,"%lf\t%lf\t%lf",&t,&B.re, &B.im);  
      i=0;  
      while (!feof(fp1))
      {
        if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){
          tgps1[i].gpsSeconds = (INT4)floor(t);
          tgps1[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
          input1.B->data[i].re = B.re;
          input1.B->data[i].im = B.im;   
          i++;
        }
        fscanf(fp1,"%lf\t%lf\t%lf",&t,&B.re, &B.im);
      } 
      input1.t = tgps1;
      input1.B->length = i;
    }
    else if (flag == 1) /* chisquare */
    {
      fscanf(fp1,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);  
      i=0;  
      while (!feof(fp1))
      {
        tgps1[i].gpsSeconds = (INT4)floor(t);
        tgps1[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
        input1_chi.B->data[i].re = B.re;
        input1_chi.B->data[i].im = B.im; 
        input1_chi.var->data[i].re = var.re;
        input1_chi.var->data[i].im = var.im;   
        fscanf(fp1,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);          
        i++;  
      } 
      input1_chi.t = tgps1;
      input1_chi.B->length = i;
      input1_chi.var->length = i;
    }
    fclose(fp1);
  }
 
  fprintf(stderr, "I've read in the L1 data.\n");
 /* read data from H1 */
  if (iH1)
  {
    if (flag == 2) /* student-t */
    {
      fscanf(fp2,"%lf\t%lf\t%lf",&t,&B.re, &B.im);  
      i=0;  
      while (!feof(fp2))
      {
        if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){
          tgps2[i].gpsSeconds = (INT4)floor(t);
          tgps2[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
          input2.B->data[i].re = B.re;
          input2.B->data[i].im = B.im;   
          i++;
        }
        fscanf(fp2,"%lf\t%lf\t%lf",&t,&B.re, &B.im);
      } 
      input2.t = tgps2;
      input2.B->length = i;
    }
    else if (flag == 1) /* chisquare */
    {
      fscanf(fp2,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);  
      i=0;  
      while (!feof(fp2))
      {
        tgps2[i].gpsSeconds = (INT4)floor(t);
        tgps2[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
        input2_chi.B->data[i].re = B.re;
        input2_chi.B->data[i].im = B.im; 
        input2_chi.var->data[i].re = var.re;
        input2_chi.var->data[i].im = var.im;   
        fscanf(fp2,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);    
        i++;  
      } 
      input2_chi.t = tgps2;
      input2_chi.B->length = i;
      input2_chi.var->length = i;
    }
    fclose(fp2);
  }
  
  fprintf(stderr, "I've read in the H1 data.\n");
 /* read data from H2 */
  if (iH2)
  {
    if (flag == 2) /* student-t */
    {
      fscanf(fp3,"%lf\t%lf\t%lf",&t,&B.re, &B.im);  
      i=0;  
      while (!feof(fp3))
      {
        if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){
          tgps3[i].gpsSeconds = (INT4)floor(t);
          tgps3[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
          input3.B->data[i].re = B.re;
          input3.B->data[i].im = B.im;
          i++;
        }
        fscanf(fp3,"%lf\t%lf\t%lf",&t,&B.re, &B.im);
      }  
    input3.t = tgps3;
    input3.B->length = i;
  }
    else if (flag == 1) /* chisquare */
    {
      fscanf(fp3,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);  
      i=0;  
      while (!feof(fp3))
      {
        tgps3[i].gpsSeconds = (INT4)floor(t);
        tgps3[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
        input3_chi.B->data[i].re = B.re;
        input3_chi.B->data[i].im = B.im; 
        input3_chi.var->data[i].re = var.re;
        input3_chi.var->data[i].im = var.im;   
        fscanf(fp3,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);    
        i++;  
      } 
      input3_chi.t = tgps3;
      input3_chi.B->length = i;
      input3_chi.var->length = i;
    }
    fclose(fp3);
  }
  
  fprintf(stderr, "I've read in the H2 data.\n");
  /* read data from GEO */
  if (iGEO)
  {
    if (flag == 2) /* student-t */
    {
      fscanf(fp4,"%lf\t%lf\t%lf",&t,&B.re, &B.im);  
      i=0;  
      while (!feof(fp4))
      {
        if(fabs(B.re) > 1e-28 && fabs(B.im) > 1e-28){
          tgps4[i].gpsSeconds = (INT4)floor(t);
          tgps4[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
          input4.B->data[i].re = B.re;
          input4.B->data[i].im = B.im; 
          i++;
        }
        fscanf(fp4,"%lf\t%lf\t%lf",&t,&B.re, &B.im);
      } 
      input4.t = tgps4;
      input4.B->length = i;
    }
    else if (flag == 1) /* chisquare */
    {
      fscanf(fp4,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);  
      i=0;  
      while (!feof(fp4))
      {
        tgps4[i].gpsSeconds = (INT4)floor(t);
        tgps4[i].gpsNanoSeconds = (INT4)floor((fmod(t,1.0)*1.e9));       
        input4_chi.B->data[i].re = B.re;
        input4_chi.B->data[i].im = B.im; 
        input4_chi.var->data[i].re = var.re;
        input4_chi.var->data[i].im = var.im;   
        fscanf(fp4,"%lf\t%lf\t%lf\t%lf\t%lf",&t,&B.re, &B.im, &var.re, &var.im);    
        i++;  
      } 
      input4_chi.t = tgps4;
      input4_chi.B->length = i;
      input4_chi.var->length = i;
    }
    fclose(fp4);
  }  
  /****************** END READ INPUT DATA (Bk's) ***************************/
  /******** read mesh input file *****************/
 
  /* construct name of mesh file and open file */
  sprintf(inmesh,"%s/inputs/%s", argv[2],argv[4]);
  fpmesh = fopen(inmesh,"r");
 
  fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],&params1.meshH0[0], &params1.meshH0[1], &params1.meshH0[2]); 
  fprintf(stderr, "%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshH0[0], params1.meshH0[1],
  params1.meshH0[2],params1.meshH0[0]+params1.meshH0[1]*(params1.meshH0[2]-1.0));
  params2.meshH0[0] = params3.meshH0[0] = params4.meshH0[0] = params1.meshH0[0];
  params2.meshH0[1] = params3.meshH0[1] = params4.meshH0[1] = params1.meshH0[1];
  params2.meshH0[2] = params3.meshH0[2] = params4.meshH0[2] = params1.meshH0[2];

  fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],&params1.meshCosIota[0], &params1.meshCosIota[1], &params1.meshCosIota[2]); 
  fprintf(stderr, "%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshCosIota[0], params1.meshCosIota[1],
  params1.meshCosIota[2], params1.meshCosIota[0]+ params1.meshCosIota[1]*(params1.meshCosIota[2]-1.0));
  params2.meshCosIota[0] = params3.meshCosIota[0] =  params4.meshCosIota[0] =  params1.meshCosIota[0];
  params2.meshCosIota[1] = params3.meshCosIota[1]  = params4.meshCosIota[1] =  params1.meshCosIota[1];
  params2.meshCosIota[2] = params3.meshCosIota[2] = params4.meshCosIota[2] =   params1.meshCosIota[2];

  fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],&params1.meshPhase[0], &params1.meshPhase[1], &params1.meshPhase[2]);   
  fprintf(stderr,"%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshPhase[0], params1.meshPhase[1],
  params1.meshPhase[2], params1.meshPhase[0]+params1.meshPhase[1]*(params1.meshPhase[2]-1.0));
  params2.meshPhase[0] = params3.meshPhase[0] = params4.meshPhase[0] = params1.meshPhase[0]; 
  params2.meshPhase[1] = params3.meshPhase[1] = params4.meshPhase[1] = params1.meshPhase[1]; 
  params2.meshPhase[2] = params3.meshPhase[2] = params4.meshPhase[2] = params1.meshPhase[2]; 
 
  fscanf(fpmesh,"%s\t%lf\t%lf\t%lf",&txt[0],&params1.meshPsi[0], &params1.meshPsi[1], &params1.meshPsi[2]); 
  fprintf(stderr,"%s\t%e\t%e\t%f\t-> %e\n", txt, params1.meshPsi[0], params1.meshPsi[1],
  params1.meshPsi[2],params1.meshPsi[0]+params1.meshPsi[1]*(params1.meshPsi[2]-1.0)); 
  params2.meshPsi[0] = params3.meshPsi[0] =  params4.meshPsi[0] =  params1.meshPsi[0];
  params2.meshPsi[1] = params3.meshPsi[1] =  params4.meshPsi[1] =  params1.meshPsi[1];
  params2.meshPsi[2] = params3.meshPsi[2] =  params4.meshPsi[2] =  params1.meshPsi[2];
 
  fclose(fpmesh);

  /* allocate memory for 'chi square' matrix */
  
  if (iL1)
  { 
   output1.mChiSquare = NULL;
   LALDCreateVector( &status, &output1.mChiSquare,params1.meshH0[2]*params1.meshCosIota[2]*params1.meshPhase[2]*params1.meshPsi[2]);
  }
  
  if (iH1)
  {
    output2.mChiSquare = NULL;
    LALDCreateVector( &status, &output2.mChiSquare,params2.meshH0[2]*params2.meshCosIota[2]*params2.meshPhase[2]*params2.meshPsi[2]);
  }
  
  if (iH2)
  {
    output3.mChiSquare = NULL;
    LALDCreateVector( &status, &output3.mChiSquare,params3.meshH0[2]*params3.meshCosIota[2]*params3.meshPhase[2]*params3.meshPsi[2]);
  }
  if (iGEO)
  {    
    output4.mChiSquare = NULL;
    LALDCreateVector( &status, &output4.mChiSquare,params4.meshH0[2]*params4.meshCosIota[2]*params4.meshPhase[2]*params4.meshPsi[2]);
  }
  
  /* allocate memory for pdfs */
  if (iL1)
  {
   prob1.pdf = NULL; LALCreateVector(&status, &prob1.pdf, params1.meshH0[2]);
   prob1.cdf = NULL; LALCreateVector(&status, &prob1.cdf, params1.meshH0[2]);
   prob1.pdfPhase = NULL; LALCreateVector(&status, &prob1.pdfPhase, params1.meshPhase[2]);
   prob1.cdfPhase = NULL; LALCreateVector(&status, &prob1.cdfPhase, params1.meshPhase[2]);
   prob1.pdfPsi = NULL; LALCreateVector(&status, &prob1.pdfPsi, params1.meshPsi[2]);
   prob1.cdfPsi = NULL; LALCreateVector(&status, &prob1.cdfPsi, params1.meshPsi[2]);
   prob1.pdfCosIota = NULL; LALCreateVector(&status, &prob1.pdfCosIota, params1.meshCosIota[2]);
   prob1.cdfCosIota = NULL; LALCreateVector(&status, &prob1.cdfCosIota, params1.meshCosIota[2]);  
  }  
  if (iH1)
  {
   prob2.pdf = NULL; LALCreateVector(&status, &prob2.pdf, params2.meshH0[2]);
   prob2.cdf = NULL; LALCreateVector(&status, &prob2.cdf, params2.meshH0[2]);
   prob2.pdfPhase = NULL; LALCreateVector(&status, &prob2.pdfPhase, params2.meshPhase[2]);
   prob2.cdfPhase = NULL; LALCreateVector(&status, &prob2.cdfPhase, params2.meshPhase[2]);
   prob2.pdfPsi = NULL; LALCreateVector(&status, &prob2.pdfPsi, params2.meshPsi[2]);
   prob2.cdfPsi = NULL; LALCreateVector(&status, &prob2.cdfPsi, params2.meshPsi[2]);
   prob2.pdfCosIota = NULL; LALCreateVector(&status, &prob2.pdfCosIota, params2.meshCosIota[2]);
   prob2.cdfCosIota = NULL; LALCreateVector(&status, &prob2.cdfCosIota, params2.meshCosIota[2]);
  }
  if (iH2)
  { 
   prob3.pdf = NULL; LALCreateVector(&status, &prob3.pdf, params3.meshH0[2]);
   prob3.cdf = NULL; LALCreateVector(&status, &prob3.cdf, params3.meshH0[2]);
   prob3.pdfPhase = NULL; LALCreateVector(&status, &prob3.pdfPhase, params3.meshPhase[2]);
   prob3.cdfPhase = NULL; LALCreateVector(&status, &prob3.cdfPhase, params3.meshPhase[2]);
   prob3.pdfPsi = NULL; LALCreateVector(&status, &prob3.pdfPsi, params3.meshPsi[2]);
   prob3.cdfPsi = NULL; LALCreateVector(&status, &prob3.cdfPsi, params3.meshPsi[2]);
   prob3.pdfCosIota = NULL; LALCreateVector(&status, &prob3.pdfCosIota, params3.meshCosIota[2]);
   prob3.cdfCosIota = NULL; LALCreateVector(&status, &prob3.cdfCosIota, params3.meshCosIota[2]);
  } 
  if (iGEO)
  {
   prob4.pdf = NULL; LALCreateVector(&status, &prob4.pdf, params4.meshH0[2]);
   prob4.cdf = NULL; LALCreateVector(&status, &prob4.cdf, params4.meshH0[2]);
   prob4.pdfPhase = NULL; LALCreateVector(&status, &prob4.pdfPhase, params4.meshPhase[2]);
   prob4.cdfPhase = NULL; LALCreateVector(&status, &prob4.cdfPhase, params4.meshPhase[2]);
   prob4.pdfPsi = NULL; LALCreateVector(&status, &prob4.pdfPsi, params4.meshPsi[2]);
   prob4.cdfPsi = NULL; LALCreateVector(&status, &prob4.cdfPsi, params4.meshPsi[2]);
   prob4.pdfCosIota = NULL; LALCreateVector(&status, &prob4.pdfCosIota, params4.meshCosIota[2]);
   prob4.cdfCosIota = NULL; LALCreateVector(&status, &prob4.cdfCosIota, params4.meshCosIota[2]);
  }  
  
  /* allocate memory for pdfs for joint analysis if there is data from more than one detector */
  if (iH1 + iH2 + iL1 +iGEO > 1) 
  {
   prob.pdf = NULL; LALCreateVector(&status, &prob.pdf, params1.meshH0[2]);
   prob.cdf = NULL; LALCreateVector(&status, &prob.cdf, params1.meshH0[2]);  
   prob.pdfPhase = NULL; LALCreateVector(&status, &prob.pdfPhase, params1.meshPhase[2]);
   prob.cdfPhase = NULL; LALCreateVector(&status, &prob.cdfPhase, params1.meshPhase[2]);  
   prob.pdfPsi = NULL; LALCreateVector(&status, &prob.pdfPsi, params1.meshPsi[2]);
   prob.cdfPsi = NULL; LALCreateVector(&status, &prob.cdfPsi, params1.meshPsi[2]);  
   prob.pdfCosIota = NULL; LALCreateVector(&status, &prob.pdfCosIota, params1.meshCosIota[2]);
   prob.cdfCosIota = NULL; LALCreateVector(&status, &prob.cdfCosIota, params1.meshCosIota[2]);  
  }
        
  minChi = 0.0;
  
  /* calculate chisquare for each IFO and then marginalize over nuissance parameters */
  if (flag == 1)
  {
    if (iL1) {
      fprintf(stderr, "Entering LALCoarseFitToPulsar for L1\n");
      LALCoarseFitToPulsar(&status,&output1, &input1_chi, &params1);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}    
      minChi += output1.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for L1\n");
      LALPulsarMarginalize(&status, &prob1, &output1, &params1);}
    if (iH1){
      fprintf(stderr, "Entering LALCoarseFitToPulsar for H1\n");
      LALCoarseFitToPulsar(&status,&output2, &input2_chi, &params2);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}   
      minChi += output2.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for H1\n");
      LALPulsarMarginalize(&status, &prob2, &output2, &params2);}
   
    if (iH2){ 
      fprintf(stderr, "Entering LALCoarseFitToPulsar for H2\n");
      LALCoarseFitToPulsar(&status,&output3, &input3_chi, &params3);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}         
      minChi += output3.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for H2\n");
      LALPulsarMarginalize(&status, &prob3, &output3, &params3);}
    
    if (iGEO){
      fprintf(stderr, "Entering LALCoarseFitToPulsar for GEO\n");
      LALCoarseFitToPulsar(&status,&output4, &input4_chi, &params4);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}   
      minChi += output4.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for GEO\n");
      LALPulsarMarginalize(&status, &prob4, &output4, &params4); }  
  }
  else if (flag == 2)
  {
    if (iL1){
      fprintf(stderr, "Entering FitToPulsarStudentT for L1\n");
      LALFitToPulsarStudentT(&status,&output1, &input1, &params1);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}   
      minChi += output1.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for L1\n");
      LALPulsarMarginalize(&status, &prob1, &output1, &params1);}
    if (iH1){
      fprintf(stderr, "Entering FitToPulsarStudentT for H1\n");
      LALFitToPulsarStudentT(&status,&output2, &input2, &params2);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}   
      minChi += output2.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for H1\n");
      LALPulsarMarginalize(&status, &prob2, &output2, &params2);}
    if (iH2){
      fprintf(stderr, "Entering FitToPulsarStudentT for H2\n");
      LALFitToPulsarStudentT(&status,&output3, &input3, &params3);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}   
      minChi += output3.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for H2\n");
      LALPulsarMarginalize(&status, &prob3, &output3, &params3);}
    if (iGEO){
      fprintf(stderr, "Entering FitToPulsarStudentT for GEO\n");
      LALFitToPulsarStudentT(&status,&output4, &input4, &params4);
      if(status.statusCode){
        fprintf(stderr,"Unexpectedly got error code %d and message %s\n",
	 status.statusCode, status.statusDescription);
         return 0;}   
      minChi += output4.chiSquare;
      fprintf(stderr, "Entering  LALPulsarMarginalize for GEO\n");
      LALPulsarMarginalize(&status, &prob4, &output4, &params4);}  
  }
  
  
/************ BEGIN MARGINALIZE FOR JOINT PDF *******************************/  
  /* if there is data from more that one IFO then calculate joint pdfs */
  if (iL1+iH1+iH2+iGEO>1) 
  {
    /* initialize to zero */
    for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++) 
    {
      prob.pdf->data[iH0] = 0.0;
      prob.cdf->data[iH0] = 0.0;
    }
    for (iPhase=0; iPhase < params1.meshPhase[2]; iPhase++)
    {
      prob.pdfPhase->data[iPhase] = 0.0;
      prob.cdfPhase->data[iPhase] = 0.0;
    } 
    for (iPsi=0;iPsi< params1.meshPsi[2]; iPsi++)
    {
      prob.pdfPsi->data[iPsi] = 0.0;
      prob.cdfPsi->data[iPsi] = 0.0;
    }
    for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++)
    {
      prob.pdfCosIota->data[iCosIota] = 0.0;
      prob.cdfCosIota->data[iCosIota] = 0.0;
    }
       
     /* marginalize over angles to get p(h0|Bk) */
   for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++)
     for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++)
       for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++)
         for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++){
           arg = iH0 + params1.meshH0[2]*(iCosIota +  params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); 
	   
	   if (iL1) outL1 = output1.mChiSquare->data[arg];
	   else outL1 = 0.0;
	   
	   if (iH1) outH1 = output2.mChiSquare->data[arg];
	   else outH1 = 0.0;
	   
	   if (iH2) outH2 = output3.mChiSquare->data[arg];
	   else outH2 = 0.0;
	   
	   if (iGEO) outGEO = output4.mChiSquare->data[arg];
	   else outGEO = 0.0;
	   
	   prob.pdf->data[iH0] +=  exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0);    
         }
 
   area = 0.0;
   for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++)
     area += prob.pdf->data[iH0]*params1.meshH0[1];
   
   for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++)
      prob.pdf->data[iH0] = prob.pdf->data[iH0]/area;
  
  prob.cdf->data[0] = prob.pdf->data[0]*params1.meshH0[1];
  for (iH0 = 1; iH0 < params1.meshH0[2]; iH0++)  
    prob.cdf->data[iH0] = prob.pdf->data[iH0]*params1.meshH0[1] + prob.cdf->data[iH0-1];
   
   /* marginalize over h0, psi, cosIota to get p(phase|Bk) */
   for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++)
     for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++)
       for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++)
         for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++){
           arg = iH0 + params1.meshH0[2]*(iCosIota +  params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); 
	   
	   if (iL1) outL1 = output1.mChiSquare->data[arg];
	   else outL1 = 0.0;
	   
	   if (iH1) outH1 = output2.mChiSquare->data[arg];
	   else outH1 = 0.0;
	   
	   if (iH2) outH2 = output3.mChiSquare->data[arg];
	   else outH2 = 0.0;
	   
	   if (iGEO) outGEO = output4.mChiSquare->data[arg];
	   else outGEO = 0.0;
	   
	   prob.pdfPhase->data[iPhase] +=  exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0);    
         }
 
   area = 0.0;
   for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++)
     area += prob.pdfPhase->data[iPhase]*params1.meshPhase[1];
   
   for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++)
      prob.pdfPhase->data[iPhase] = prob.pdfPhase->data[iPhase]/area;
  
  prob.cdfPhase->data[0] = prob.pdfPhase->data[0]*params1.meshPhase[1];
  for (iPhase = 1; iPhase < params1.meshPhase[2]; iPhase++)  
    prob.cdfPhase->data[iPhase] = prob.pdf->data[iPhase]*params1.meshPhase[1] + prob.cdf->data[iPhase-1];
  
  /* marginalize over phase, h0, and cosIota to get p(Psi|Bk) */
   for (iH0 = 0; iH0 < params1.meshH0[2]; iH0++)
     for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++)
       for (iCosIota = 0; iCosIota < params1.meshCosIota[2];iCosIota++)
         for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++){
           arg = iH0 + params1.meshH0[2]*(iCosIota +  params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); 
	   
	   if (iL1) outL1 = output1.mChiSquare->data[arg];
	   else outL1 = 0.0;
	   
	   if (iH1) outH1 = output2.mChiSquare->data[arg];
	   else outH1 = 0.0;
	   
	   if (iH2) outH2 = output3.mChiSquare->data[arg];
	   else outH2 = 0.0;
	   
	   if (iGEO) outGEO = output4.mChiSquare->data[arg];
	   else outGEO = 0.0;
	   
	   prob.pdfPsi->data[iPsi] +=  exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0);    
         }
 
   area = 0.0;
   for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++)
     area += prob.pdfPsi->data[iPsi]*params1.meshPsi[1];
   
   for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++)
      prob.pdfPsi->data[iPsi] = prob.pdfPsi->data[iPsi]/area;
  
  prob.cdfPsi->data[0] = prob.pdfPsi->data[0]*params1.meshPsi[1];
  for (iPsi = 1; iPsi < params1.meshPsi[2]; iPsi++)  
    prob.cdfPsi->data[iPsi] = prob.pdfPsi->data[iPsi]*params1.meshPsi[1] + prob.cdfPsi->data[iPsi-1];
  
    /* marginalize over phase, psi, and h0 to get p(Cosiota|Bk) */
   for (iPsi = 0; iPsi < params1.meshPsi[2]; iPsi++)
     for (iPhase = 0; iPhase < params1.meshPhase[2]; iPhase++)
       for (iH0 = 0; iH0 < params1.meshH0[2];iH0++)
         for (iCosIota = 0; iCosIota < params1.meshCosIota[2]; iCosIota++){
           arg = iH0 + params1.meshH0[2]*(iCosIota +  params1.meshCosIota[2]*(iPhase + params1.meshPhase[2]*iPsi)); 
	   
	   if (iL1) outL1 = output1.mChiSquare->data[arg];
	   else outL1 = 0.0;
	   
	   if (iH1) outH1 = output2.mChiSquare->data[arg];
	   else outH1 = 0.0;
	   
	   if (iH2) outH2 = output3.mChiSquare->data[arg];
	   else outH2 = 0.0;
	   
	   if (iGEO) outGEO = output4.mChiSquare->data[arg];
	   else outGEO = 0.0;
	   
	   prob.pdfCosIota->data[iCosIota] +=  exp((minChi - (outL1 + outH1 + outH2 + outGEO))/2.0);    
         }
 
   area = 0.0;
   for (iCosIota = 0; iCosIota < params1.meshCosIota[2]; iCosIota++)
     area += prob.pdfCosIota->data[iCosIota]*params1.meshCosIota[1];
   
   for (iCosIota = 0; iCosIota < params1.meshCosIota[2]; iCosIota++)
      prob.pdfCosIota->data[iCosIota] = prob.pdfCosIota->data[iCosIota]/area;
  
  prob.cdfCosIota->data[0] = prob.pdfCosIota->data[0]*params1.meshCosIota[1];
  for (iCosIota = 1; iCosIota < params1.meshCosIota[2]; iCosIota++)  
    prob.cdfCosIota->data[iCosIota] = prob.pdfCosIota->data[iCosIota]*params1.meshCosIota[1] + prob.cdfCosIota->data[iCosIota-1];
  
  } 
/************ END MARGINALIZE FOR JOINT PDF *******************************/  
       
/********************* BEGIN WRITING OUTPUT FILES *********************************/
  if (iL1)
  {
    if (flag == 1)
    {
      sprintf(outfile1,"%s/%s/pdf.%s_L1", argv[2], pulsar_name, pulsar_name); 
      sprintf(outfile1Phase,"%s/%s/pdfPhase.%s_L1", argv[2], pulsar_name, pulsar_name); 
      sprintf(outfile1Psi,"%s/%s/pdfPsi.%s_L1", argv[2], pulsar_name, pulsar_name); 
      sprintf(outfile1CosIota,"%s/%s/pdfCosIota.%s_L1", argv[2], pulsar_name, pulsar_name); 
    }
    else if (flag == 2)
    {
       sprintf(outfile1,"%s/pdfoutputs/pdf_st.%s_L1", argv[2], pulsar_name); 
       sprintf(outfile1Phase,"%s/pdfoutputs/pdfPhase_st.%s_L1", argv[2], pulsar_name); 
       sprintf(outfile1Psi,"%s/pdfoutputs/pdfPsi_st.%s_L1", argv[2], pulsar_name); 
       sprintf(outfile1CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_L1", argv[2], pulsar_name); 
    }
   
    fp_pdf1 = fopen(outfile1, "w"); 
    fp_pdf1Phase = fopen(outfile1Phase, "w"); 
    fp_pdf1Psi = fopen(outfile1Psi, "w"); 
    fp_pdf1CosIota = fopen(outfile1CosIota, "w"); 
     
    for (i=0;i<params1.meshH0[2];i++)
      fprintf(fp_pdf1,"%e\t%e\t%e\n", params1.meshH0[0]+(float)i*params1.meshH0[1],prob1.pdf->data[i], prob1.cdf->data[i]);
    for (i=0;i<params1.meshPhase[2];i++)
      fprintf(fp_pdf1Phase,"%e\t%e\t%e\n", params1.meshPhase[0]+(float)i*params1.meshPhase[1],prob1.pdfPhase->data[i], prob1.cdfPhase->data[i]);    
    for (i=0;i<params1.meshPsi[2];i++)
      fprintf(fp_pdf1Psi,"%e\t%e\t%e\n", params1.meshPsi[0]+(float)i*params1.meshPsi[1],prob1.pdfPsi->data[i], prob1.cdfPsi->data[i]);
    for (i=0;i<params1.meshCosIota[2];i++)
      fprintf(fp_pdf1CosIota,"%e\t%e\t%e\n", params1.meshCosIota[0]+(float)i*params1.meshCosIota[1],prob1.pdfCosIota->data[i], prob1.cdfCosIota->data[i]);	   	   	       
  
    fclose(fp_pdf1); fclose(fp_pdf1Phase); fclose(fp_pdf1Psi); fclose(fp_pdf1CosIota);
  }
  
  if (iH1)
  {
     if (flag ==1)
     {  
       sprintf(outfile2,"%s/%s/pdf.%s_H1", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile2Phase,"%s/%s/pdfPhase.%s_H1", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile2Psi,"%s/%s/pdfPsi.%s_H1", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile2CosIota,"%s/%s/pdfCosIota.%s_H1", argv[2], pulsar_name, pulsar_name);
     }
     else if (flag == 2)
     {
       sprintf(outfile2,"%s/pdfoutputs/pdf_st.%s_H1", argv[2], pulsar_name);
       sprintf(outfile2Phase,"%s/pdfoutputs/pdfPhase_st.%s_H1", argv[2], pulsar_name);
       sprintf(outfile2Psi,"%s/pdfoutputs/pdfPsi_st.%s_H1", argv[2], pulsar_name);
       sprintf(outfile2CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_H1", argv[2], pulsar_name);
     }    
     fp_pdf2 = fopen(outfile2, "w"); 
     fp_pdf2Phase = fopen(outfile2Phase, "w"); 
     fp_pdf2Psi = fopen(outfile2Psi, "w"); 
     fp_pdf2CosIota = fopen(outfile2CosIota, "w"); 
  
    for (i=0;i<params1.meshH0[2];i++)
      fprintf(fp_pdf2,"%e\t%e\t%e\n", params2.meshH0[0]+(float)i*params2.meshH0[1], prob2.pdf->data[i], prob2.cdf->data[i]);
    for (i=0;i<params1.meshPhase[2];i++)
      fprintf(fp_pdf2Phase,"%e\t%e\t%e\n", params2.meshPhase[0]+(float)i*params2.meshPhase[1], prob2.pdfPhase->data[i], prob2.cdfPhase->data[i]);
    for (i=0;i<params1.meshPsi[2];i++)
      fprintf(fp_pdf2Psi,"%e\t%e\t%e\n", params2.meshPsi[0]+(float)i*params2.meshPsi[1], prob2.pdfPsi->data[i], prob2.cdfPsi->data[i]);
    for (i=0;i<params1.meshCosIota[2];i++)
      fprintf(fp_pdf2CosIota,"%e\t%e\t%e\n", params2.meshCosIota[0]+(float)i*params2.meshCosIota[1], prob2.pdfCosIota->data[i], prob2.cdfCosIota->data[i]);

    fclose(fp_pdf2); fclose(fp_pdf2Phase); fclose(fp_pdf2Psi); fclose(fp_pdf2CosIota); 
  }

  if (iH2)
  { 
     if (flag ==1)
     {  
       sprintf(outfile3,"%s/%s/pdf.%s_H2", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile3Phase,"%s/%s/pdfPhase.%s_H2", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile3Psi,"%s/%s/pdfPsi.%s_H2", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile3CosIota,"%s/%s/pdfCosIota.%s_H2", argv[2], pulsar_name, pulsar_name);
     }
     else if (flag == 2)
     {
       sprintf(outfile3,"%s/pdfoutputs/pdf_st.%s_H2", argv[2], pulsar_name);
       sprintf(outfile3Phase,"%s/pdfoutputs/pdfPhase_st.%s_H2", argv[2], pulsar_name);
       sprintf(outfile3Psi,"%s/pdfoutputs/pdfPsi_st.%s_H2", argv[2], pulsar_name);
       sprintf(outfile3CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_H2", argv[2], pulsar_name);
     }
     
    fp_pdf3 = fopen(outfile3, "w"); 
    fp_pdf3Phase = fopen(outfile3Phase, "w"); 
    fp_pdf3Psi = fopen(outfile3Psi, "w"); 
    fp_pdf3CosIota = fopen(outfile3CosIota, "w"); 
  
    for (i=0;i<params1.meshH0[2];i++)
      fprintf(fp_pdf3,"%e\t%e\t%e\n", params3.meshH0[0]+(float)i*params3.meshH0[1], prob3.pdf->data[i], prob3.cdf->data[i]);
    for (i=0;i<params1.meshPhase[2];i++)
      fprintf(fp_pdf3Phase,"%e\t%e\t%e\n", params3.meshPhase[0]+(float)i*params3.meshPhase[1], prob3.pdfPhase->data[i], prob3.cdfPhase->data[i]);	    
    for (i=0;i<params1.meshPsi[2];i++)
      fprintf(fp_pdf3Psi,"%e\t%e\t%e\n", params3.meshPsi[0]+(float)i*params3.meshPsi[1], prob3.pdfPsi->data[i], prob3.cdfPsi->data[i]);  
    for (i=0;i<params1.meshCosIota[2];i++)
      fprintf(fp_pdf3CosIota,"%e\t%e\t%e\n", params3.meshCosIota[0]+(float)i*params3.meshCosIota[1], prob3.pdfCosIota->data[i], prob3.cdfCosIota->data[i]);  
   
    fclose(fp_pdf3); fclose(fp_pdf3Phase); fclose(fp_pdf3Psi); fclose(fp_pdf3CosIota); 
  }
       
  if (iGEO){ 
       if (flag ==1)
     {  
       sprintf(outfile4,"%s/%s/pdf.%s_GEO", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile4Phase,"%s/%s/pdfPhase.%s_GEO", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile4Psi,"%s/%s/pdfPsi.%s_GEO", argv[2], pulsar_name, pulsar_name);
       sprintf(outfile4CosIota,"%s/%s/pdfCosIota.%s_GEO", argv[2], pulsar_name, pulsar_name);
     }
     else if (flag == 2)
     {
       sprintf(outfile4,"%s/pdfoutputs/pdf_st.%s_GEO", argv[2], pulsar_name);
       sprintf(outfile4Phase,"%s/pdfoutputs/pdfPhase_st.%s_GEO", argv[2], pulsar_name);
       sprintf(outfile4Psi,"%s/pdfoutputs/pdfPsi_st.%s_GEO", argv[2], pulsar_name);
       sprintf(outfile4CosIota,"%s/pdfoutputs/pdfCosIota_st.%s_GEO", argv[2], pulsar_name);
     }
     
    fp_pdf4 = fopen(outfile4, "w"); 
    fp_pdf4Phase = fopen(outfile4Phase, "w"); 
    fp_pdf4Psi = fopen(outfile4Psi, "w"); 
    fp_pdf4CosIota = fopen(outfile4CosIota, "w"); 
  
    for (i=0;i<params1.meshH0[2];i++)
      fprintf(fp_pdf4,"%e\t%e\t%e\n", params4.meshH0[0]+(float)i*params4.meshH0[1], prob4.pdf->data[i], prob4.cdf->data[i]);
    for (i=0;i<params1.meshPhase[2];i++)
      fprintf(fp_pdf4Phase,"%e\t%e\t%e\n", params4.meshPhase[0]+(float)i*params4.meshPhase[1], prob4.pdfPhase->data[i], prob4.cdfPhase->data[i]); 
    for (i=0;i<params1.meshPsi[2];i++)
      fprintf(fp_pdf4Psi,"%e\t%e\t%e\n", params4.meshPsi[0]+(float)i*params4.meshPsi[1], prob4.pdfPsi->data[i], prob4.cdfPsi->data[i]); 
    for (i=0;i<params1.meshCosIota[2];i++)
      fprintf(fp_pdf4CosIota,"%e\t%e\t%e\n", params4.meshCosIota[0]+(float)i*params4.meshCosIota[1], prob4.pdfCosIota->data[i], prob4.cdfCosIota->data[i]);
  
    fclose(fp_pdf4); fclose(fp_pdf4Phase); fclose(fp_pdf4Psi); fclose(fp_pdf4CosIota);  
  }
  
  if (iL1+iH1+iH2+iGEO>1)
  {
       if (flag ==1)
     {  
       sprintf(outfile,"%s/%s/pdf.%s_Joint", argv[2], pulsar_name, pulsar_name);
       sprintf(outfilePhase,"%s/%s/pdfPhase.%s_Joint", argv[2], pulsar_name, pulsar_name);
       sprintf(outfilePsi,"%s/%s/pdfPsi.%s_Joint", argv[2], pulsar_name, pulsar_name);
       sprintf(outfileCosIota,"%s/%s/pdfCosIota.%s_Joint", argv[2], pulsar_name, pulsar_name);
     }
     else if (flag == 2)
     {
       sprintf(outfile,"%s/pdfoutputs/pdf_st.%s_Joint", argv[2], pulsar_name);
       sprintf(outfilePhase,"%s/pdfoutputs/pdfPhase_st.%s_Joint", argv[2], pulsar_name);
       sprintf(outfilePsi,"%s/pdfoutputs/pdfPsi_st.%s_Joint", argv[2], pulsar_name);
       sprintf(outfileCosIota,"%s/pdfoutputs/pdfCosIota_st.%s_Joint", argv[2], pulsar_name);
     }
     
    fp_joint = fopen(outfile, "w"); 
    fp_jointPhase = fopen(outfilePhase, "w"); 
    fp_jointPsi = fopen(outfilePsi, "w"); 
    fp_jointCosIota = fopen(outfileCosIota, "w"); 
  
    for (i=0;i<params1.meshH0[2];i++)
      fprintf(fp_joint,"%e\t%e\t%e\n", params1.meshH0[0]+(float)i*params1.meshH0[1], prob.pdf->data[i], prob.cdf->data[i]);        
    for (i=0;i<params1.meshPhase[2];i++)
      fprintf(fp_jointPhase,"%e\t%e\t%e\n", params1.meshPhase[0]+(float)i*params1.meshPhase[1], prob.pdfPhase->data[i], prob.cdfPhase->data[i]);      
    for (i=0;i<params1.meshPsi[2];i++)
      fprintf(fp_jointPsi,"%e\t%e\t%e\n", params1.meshPsi[0]+(float)i*params1.meshPsi[1], prob.pdfPsi->data[i], prob.cdfPsi->data[i]);      
    for (i=0;i<params1.meshCosIota[2];i++)
      fprintf(fp_jointCosIota,"%e\t%e\t%e\n", params1.meshCosIota[0]+(float)i*params1.meshCosIota[1], prob.pdfCosIota->data[i], prob.cdfCosIota->data[i]);      
  
    fclose(fp_joint);fclose(fp_jointPhase);fclose(fp_jointPsi);fclose(fp_jointCosIota);
  } 
 /********************* END WRITING OUTPUT FILES*********************************/

/* print out best fit information for each IFO */  
  if (iL1){fprintf(stderr, "BEST FIT FOR L1:\n");
 fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n",
  output1.h0, output1.cosIota, output1.psi, output1.phase, output1.chiSquare);}

  if (iH1){fprintf(stderr, "\nBEST FIT FOR H1:\n");
 fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n",
  output2.h0, output2.cosIota, output2.psi, output2.phase, output2.chiSquare);}

  if (iH2){fprintf(stderr, "\nBEST FIT FOR H2:\n");
 fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n",
  output3.h0, output3.cosIota, output3.psi, output3.phase, output3.chiSquare);} 
  
  if (iGEO){fprintf(stderr, "\nBEST FIT FOR GEO:\n");
 fprintf(stderr,"h0 = %e\tcosIota = %f\tpsi = %f\tphase = %f\nchisquare = %f\n",
  output4.h0, output4.cosIota, output4.psi, output4.phase, output4.chiSquare);}      
 fprintf(stderr,"iL1 = %d\tiH1=%d\tiH2=%d\tiGEO=%d\n", iL1, iH1, iH2, iGEO);
  
/* free allocated memory */  
  if (iL1) {
    if (flag == 1) LALZDestroyVector(&status, &input1_chi.B);
    else if (flag ==2)  LALZDestroyVector(&status, &input1.B);
    
    LALDDestroyVector(&status, &output1.mChiSquare); 
    LALDestroyVector(&status, &prob1.pdf); LALDestroyVector(&status, &prob1.cdf);
    LALDestroyVector(&status, &prob1.pdfPhase); LALDestroyVector(&status, &prob1.cdfPhase);
    LALDestroyVector(&status, &prob1.pdfPsi); LALDestroyVector(&status, &prob1.cdfPsi);
    LALDestroyVector(&status, &prob1.pdfCosIota); LALDestroyVector(&status, &prob1.cdfCosIota);  
  }

  if (iH1){
    if (flag == 1) LALZDestroyVector(&status, &input2_chi.B);
    else if (flag == 2) LALZDestroyVector(&status, &input2.B); 
    LALDDestroyVector(&status, &output2.mChiSquare); 
    LALDestroyVector(&status, &prob2.pdf); LALDestroyVector(&status, &prob2.cdf);
    LALDestroyVector(&status, &prob2.pdfPhase); LALDestroyVector(&status, &prob2.cdfPhase);
    LALDestroyVector(&status, &prob2.pdfPsi); LALDestroyVector(&status, &prob2.cdfPsi);
    LALDestroyVector(&status, &prob2.pdfCosIota); LALDestroyVector(&status, &prob2.cdfCosIota);   
  }

  if (iH2){
    if (flag == 1) LALZDestroyVector(&status, &input3_chi.B); 
    else if (flag == 2) LALZDestroyVector(&status, &input3.B); 
    LALDDestroyVector(&status, &output3.mChiSquare); 
    LALDestroyVector(&status, &prob3.pdf); LALDestroyVector(&status, &prob3.cdf);
    LALDestroyVector(&status, &prob3.pdfPhase); LALDestroyVector(&status, &prob3.cdfPhase);
    LALDestroyVector(&status, &prob3.pdfPsi); LALDestroyVector(&status, &prob3.cdfPsi);
    LALDestroyVector(&status, &prob3.pdfCosIota); LALDestroyVector(&status, &prob3.cdfCosIota); 
  }
 
  if (iGEO){
    if (flag == 1) LALZDestroyVector(&status, &input4_chi.B); 
    else if (flag == 2) LALZDestroyVector(&status, &input4.B); 
    LALDDestroyVector(&status, &output4.mChiSquare); 
    LALDestroyVector(&status, &prob4.pdf); LALDestroyVector(&status, &prob4.cdf);
    LALDestroyVector(&status, &prob4.pdfPhase); LALDestroyVector(&status, &prob4.cdfPhase);
    LALDestroyVector(&status, &prob4.pdfPsi); LALDestroyVector(&status, &prob4.cdfPsi);
    LALDestroyVector(&status, &prob4.pdfCosIota); LALDestroyVector(&status, &prob4.cdfCosIota);    
  }
  
  if (iL1+iH1+iH2+iGEO>1)
  {  
    LALDestroyVector(&status, &prob.pdf); LALDestroyVector(&status, &prob.cdf);
    LALDestroyVector(&status, &prob.pdfPhase); LALDestroyVector(&status, &prob.cdfPhase);
    LALDestroyVector(&status, &prob.pdfPsi); LALDestroyVector(&status, &prob.cdfPsi);
    LALDestroyVector(&status, &prob.pdfCosIota); LALDestroyVector(&status, &prob.cdfCosIota); 
  }
    LALCheckMemoryLeaks();
    return(0);
}  /* main */
Пример #13
0
int main(void)
{
  static LALStatus      status;
  LALDetector           detector;
  LALSource             pulsar;
  CoarseFitOutput       output;
  CoarseFitInput        input;
  CoarseFitParams       params;
  LIGOTimeGPS           tgps[FITTOPULSARTEST_LENGTH];
  REAL4                 cosIota;
  REAL4                 phase;
  REAL4                 psi;
  REAL4                 h0;
  REAL4                 cos2phase, sin2phase;
  static RandomParams   *randomParams;
  static REAL4Vector    *noise;
  INT4                  seed = 0;
  LALDetAndSource       detAndSource;
  LALDetAMResponseSeries        pResponseSeries = {NULL,NULL,NULL};
  REAL4TimeSeries               Fp, Fc, Fs;
  LALTimeIntervalAndNSample     time_info;
  UINT4                         i;


  /* Allocate memory */
  input.B = NULL;
  input.var = NULL;

  LALZCreateVector( &status, &input.B, FITTOPULSARTEST_LENGTH);
  LALZCreateVector( &status, &input.var, FITTOPULSARTEST_LENGTH);

  noise = NULL;
  LALCreateVector( &status, &noise, FITTOPULSARTEST_LENGTH);
  LALCreateRandomParams( &status, &randomParams, seed);

  Fp.data = NULL;
  Fc.data = NULL;
  Fs.data = NULL;

  pResponseSeries.pPlus   = &(Fp);
  pResponseSeries.pCross  = &(Fc);
  pResponseSeries.pScalar = &(Fs);

  LALSCreateVector(&status, &(pResponseSeries.pPlus->data), 1);
  LALSCreateVector(&status, &(pResponseSeries.pCross->data), 1);
  LALSCreateVector(&status, &(pResponseSeries.pScalar->data), 1);

  input.t = tgps;
  /******** GENERATE FAKE INPUT **********/

  time_info.epoch.gpsSeconds     = FITTOPULSARTEST_T0;
  time_info.epoch.gpsNanoSeconds = 0;
  time_info.deltaT               = 60;
  time_info.nSample              = FITTOPULSARTEST_LENGTH;

  cosIota = 0.5;
  psi = 0.1;
  phase = 0.4;
  h0 = 5.0;

  cos2phase = cos(2.0*phase);
  sin2phase = sin(2.0*phase);

  detector = lalCachedDetectors[LALDetectorIndexGEO600DIFF];     /* use GEO 600 detector for tests */
  pulsar.equatorialCoords.longitude = 1.4653;                   /* right ascention of pulsar */
  pulsar.equatorialCoords.latitude = -1.2095;                   /* declination of pulsar */
  pulsar.equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; /* coordinate system */
  pulsar.orientation = psi;                                     /* polarization angle */
  strcpy(pulsar.name, "fakepulsar");                            /* name of pulsar */

  detAndSource.pDetector = &detector;
  detAndSource.pSource = &pulsar;

  LALNormalDeviates( &status, noise, randomParams );

  LALComputeDetAMResponseSeries(&status, &pResponseSeries, &detAndSource, &time_info);

  for (i = 0;i < FITTOPULSARTEST_LENGTH; i++)
  {
    input.t[i].gpsSeconds = FITTOPULSARTEST_T0 + 60*i;
    input.t[i].gpsNanoSeconds = 0;

    input.B->data[i] = crect( pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*cos2phase + 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*sin2phase, pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*sin2phase - 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*cos2phase );
    input.var->data[i] = crect( noise->data[FITTOPULSARTEST_LENGTH-i-1]*noise->data[FITTOPULSARTEST_LENGTH-i-1], noise->data[i]*noise->data[i] );
  }

  input.B->length = FITTOPULSARTEST_LENGTH;
  input.var->length = FITTOPULSARTEST_LENGTH;

  /*******  TEST RESPONSE TO VALID DATA  ************/
/* Test that valid data generate the correct answers */
  params.detector = detector;
  params.pulsarSrc = pulsar;

  params.meshH0[0] = 4.0;
  params.meshH0[1] = 0.2;
  params.meshH0[2] = 10;

  params.meshCosIota[0] = 0.0;
  params.meshCosIota[1] =  0.1;
  params.meshCosIota[2] =  10;

  params.meshPhase[0] = 0.0;
  params.meshPhase[1] = 0.1;
  params.meshPhase[2] = 10;

  params.meshPsi[0] =  0.0;
  params.meshPsi[1] =  0.1;
  params.meshPsi[2] =  10;

  output.mChiSquare = NULL;
  LALDCreateVector( &status, &output.mChiSquare,params.meshH0[2]*params.meshCosIota[2]*params.meshPhase[2]*params.meshPsi[2]);


  LALCoarseFitToPulsar(&status,&output, &input, &params);

  if(status.statusCode)
  {
    printf("Unexpectedly got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    return FITTOPULSARTESTC_EFLS;
  }


  if(output.phase > phase + params.meshPhase[2] || output.phase < phase - params.meshPhase[2])
  {
    printf("Got incorrect phase %f when expecting %f \n",
            output.phase, phase);
    return FITTOPULSARTESTC_EFLS;
  }

  if(output.cosIota > cosIota + params.meshCosIota[2] || output.cosIota < cosIota - params.meshCosIota[2])
  {
    printf("Got incorrect cosIota %f when expecting %f \n",
            output.cosIota, cosIota);
    return FITTOPULSARTESTC_EFLS;
  }

    if(output.psi > psi + params.meshPsi[2] || output.psi < psi - params.meshPsi[2])
  {
    printf("Got incorrect psi %f when expecting %f \n",
            output.psi, psi);
    return FITTOPULSARTESTC_EFLS;
  }

  /*******  TEST RESPONSE OF LALCoarseFitToPulsar TO INVALID DATA  ************/

#ifndef LAL_NDEBUG
if ( ! lalNoDebug ) {

 /* Test that all the error conditions are correctly detected by the function */

 LALCoarseFitToPulsar(&status, NULL, &input, &params);

  if (status.statusCode != FITTOPULSARH_ENULLOUTPUT
       || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLOUTPUT))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT);
    return FITTOPULSARTESTC_ECHK;
  }

 LALCoarseFitToPulsar(&status, &output, NULL, &params);

  if (status.statusCode != FITTOPULSARH_ENULLINPUT
       || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLINPUT))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT);
    return FITTOPULSARTESTC_ECHK;
  }

 LALCoarseFitToPulsar(&status, &output, &input, NULL);

  if (status.statusCode != FITTOPULSARH_ENULLPARAMS
       || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLPARAMS))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS);
    return FITTOPULSARTESTC_ECHK;
  }

  /* try having two input vectors of different length */
  input.var->length = 1;
  LALCoarseFitToPulsar(&status, &output, &input, &params);

  if (status.statusCode != FITTOPULSARH_EVECSIZE
       || strcmp(status.statusDescription, FITTOPULSARH_MSGEVECSIZE))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_EVECSIZE, FITTOPULSARH_MSGEVECSIZE);
    return FITTOPULSARTESTC_ECHK;
  }

  input.var->length = FITTOPULSARTEST_LENGTH;

} /* if ( ! lalNoDebug ) */
#endif /* LAL_NDEBUG */

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

  LALZDestroyVector(&status, &input.B);
  LALZDestroyVector(&status, &input.var);
  LALDestroyVector(&status, &noise);
  LALDDestroyVector(&status, &output.mChiSquare);
  LALDestroyRandomParams(&status, &randomParams);
  LALSDestroyVector(&status, &(pResponseSeries.pPlus->data));
  LALSDestroyVector(&status, &(pResponseSeries.pCross->data));
  LALSDestroyVector(&status, &(pResponseSeries.pScalar->data));

  LALCheckMemoryLeaks();

  return FITTOPULSARTESTC_ENOM;
}
Пример #14
0
/* void RunGeneratePulsarSignalTest(LALStatus *status, int argc, char **argv) */ /* 02/02/05 gam */
void RunGeneratePulsarSignalTest(LALStatus *status)
{
  INT4    i, j, k;         /* all purpose indices */
  INT4    iSky = 0;        /* for loop over sky positions */
  INT4    jDeriv = 0;      /* for loop over spindowns */
  INT4    testNumber = 0;  /* which test is being run */

  /* The input and output structs used by the functions being tested */
  PulsarSignalParams *pPulsarSignalParams = NULL;
  REAL4TimeSeries *signalvec = NULL;
  SFTParams *pSFTParams = NULL;
  SkyConstAndZeroPsiAMResponse *pSkyConstAndZeroPsiAMResponse;
  SFTandSignalParams *pSFTandSignalParams;
  SFTVector *outputSFTs = NULL;
  SFTVector *fastOutputSFTs = NULL;
  REAL4 renorm; /* to renormalize SFTs to account for different effective sample rates */

  /* containers for detector and ephemeris data */
  LALDetector cachedDetector;
  CHAR IFO[6] = "LHO";
  EphemerisData *edat = NULL;

  char earthFile[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz";
  char sunFile[]   = TEST_DATA_DIR "sun00-19-DE405.dat.gz";

  /* containers for sky position and spindown data */
  REAL8 **skyPosData;
  REAL8 **freqDerivData;
  INT4 numSkyPosTotal = 8;
  INT4 numSpinDown = 1;
  INT4 numFreqDerivTotal = 2;
  INT4 numFreqDerivIncludingNoSpinDown; /* set below */
  INT4 iFreq = 0;
  REAL8 cosTmpDEC;
  REAL8 tmpDeltaRA;
  REAL8 DeltaRA = 0.01;
  REAL8 DeltaDec = 0.01;
  REAL8 DeltaFDeriv1 = -1.0e-10;
  REAL8 DeltaFDeriv2 = 0.0;
  REAL8 DeltaFDeriv3 = 0.0;
  REAL8 DeltaFDeriv4 = 0.0;
  REAL8 DeltaFDeriv5 = 0.0;

  /* containers for number of SFTs, times to generate SFTs, reference time, and gap */
  INT4 numSFTs = 4;
  REAL8 f0SFT = 943.12;
  REAL8 bandSFT = 0.5;
  UINT4 gpsStartTimeSec = 765432109; /* GPS start time of data requested seconds; example = Apr 08 2004 04:01:36 UTC */
  UINT4 gpsStartTimeNan = 0;          /* GPS start time of data requested nanoseconds */
  LIGOTimeGPSVector *timeStamps;
  LIGOTimeGPS GPSin;   /* holder for reference-time for pulsar parameters at the detector; will convert to SSB! */
  REAL8 sftGap = 73.0; /* extra artificial gap between SFTs */
  REAL8 tSFT   = 1800.0;
  REAL8 duration = tSFT + (numSFTs - 1)*(tSFT + sftGap);
  INT4 nBinsSFT = (INT4)(bandSFT*tSFT + 0.5);

  /* additional parameters that determine what signals to test; note f0SGNL and bandSGNL must be compatible with f0SFT and bandSFT */
  REAL8 f0SGNL = f0SFT + bandSFT/2.0;
  REAL8 dfSGNL = 1.0/tSFT;
  REAL8 bandSGNL = 0.005;
  INT4  nBinsSGNL = (INT4)(bandSGNL*tSFT + 0.5);
  INT4  nsamples = 18000; /* nsamples from SFT header; 2 x this would be the effective number of time samples used to create an SFT from raw data */
  INT4  Dterms = 3;       /* 09/07/05 gam; use Dterms to fill in SFT bins with fake data as per LALDemod else fill in bin with zero */
  REAL8 h_0 = 7.0e-22;    /* Source amplitude; use arbitrary small number for default */
  REAL8 cosIota;        /* cosine of inclination angle iota of the source */

  /* variables for comparing differences */
  REAL4 maxDiffSFTMod, diffAtMaxPower;
  REAL4 overallMaxDiffSFTMod;
  REAL4 maxMod, fastMaxMod;
  INT4  jMaxMod, jFastMaxMod;
  REAL4 tmpDiffSFTMod, sftMod, fastSFTMod;
  REAL4 smallMod = 1.e-30;
  REAL4 epsDiffMod;
  REAL4 epsBinErrorRate;   /* 10/12/04 gam; Allowed bin error rate */
  INT4  binErrorCount = 0; /* 10/12/04 gam; Count number of bin errors  */

  /* randval is always set to a default value or given a random value to generate certain signal parameters or mismatch */
  REAL4 randval;
  #ifdef INCLUDE_RANDVAL_MISMATCH
   INT4 seed=0;
   INT4 rndCount;
   RandomParams *randPar=NULL;
   FILE *fpRandom;
  #endif

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* generate timeStamps */
  timeStamps = (LIGOTimeGPSVector *)LALMalloc(sizeof(LIGOTimeGPSVector));
  timeStamps->data =(LIGOTimeGPS *)LALMalloc (numSFTs*sizeof(LIGOTimeGPS));
  timeStamps->length = numSFTs;
  for (i = 0; i < numSFTs; i++) {
      timeStamps->data[i].gpsSeconds = gpsStartTimeSec + (UINT4)(i*(tSFT + sftGap));
      timeStamps->data[i].gpsNanoSeconds = 0;
  } /* for i < numSFTs */

  /* generate skyPosData */
  skyPosData=(REAL8 **)LALMalloc(numSkyPosTotal*sizeof(REAL8 *));
  for(iSky=0;iSky<numSkyPosTotal;iSky++)
  {
        skyPosData[iSky] = (REAL8 *)LALMalloc(2*sizeof(REAL8));
        /* Try fairly random sky positions skyPosData[iSky][0] = RA, skyPosData[iSky][1] = DEC */
        if (iSky == 0) {
          skyPosData[iSky][0] = 0.02*LAL_TWOPI;
          skyPosData[iSky][1] = 0.03*LAL_PI/2.0;
        } else if (iSky == 1) {
          skyPosData[iSky][0] = 0.23*LAL_TWOPI;
          skyPosData[iSky][1] = -0.57*LAL_PI/2.0;
        } else if (iSky == 2) {
          skyPosData[iSky][0] = 0.47*LAL_TWOPI;
          skyPosData[iSky][1] = 0.86*LAL_PI/2.0;
        } else if (iSky == 3) {
          skyPosData[iSky][0] = 0.38*LAL_TWOPI;
          skyPosData[iSky][1] = -0.07*LAL_PI/2.0;
        } else if (iSky == 4) {
          skyPosData[iSky][0] = 0.65*LAL_TWOPI;
          skyPosData[iSky][1] = 0.99*LAL_PI/2.0;
        } else if (iSky == 5) {
          skyPosData[iSky][0] = 0.72*LAL_TWOPI;
          skyPosData[iSky][1] = -0.99*LAL_PI/2.0;
        } else if (iSky == 6) {
          skyPosData[iSky][0] = 0.81*LAL_TWOPI;
          skyPosData[iSky][1] = 0.19*LAL_PI/2.0;
        } else if (iSky == 7) {
          skyPosData[iSky][0] = 0.99*LAL_TWOPI;
          skyPosData[iSky][1] = 0.01*LAL_PI/2.0;
        } else {
          skyPosData[iSky][0] = 0.0;
          skyPosData[iSky][1] = 0.0;
        } /* END if (k == 0) ELSE ... */
  } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */

  freqDerivData = NULL; /* 02/02/05 gam */
  if (numSpinDown > 0) {
    freqDerivData=(REAL8 **)LALMalloc(numFreqDerivTotal*sizeof(REAL8 *));
    for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) {
        freqDerivData[jDeriv] = (REAL8 *)LALMalloc(numSpinDown*sizeof(REAL8));
        if (jDeriv == 0) {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 0.0;
          }
        } else if (jDeriv == 1) {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 1.e-9; /* REALLY THIS IS ONLY GOOD FOR numSpinDown = 1; */
          }
        } else {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 0.0;
          }
        } /* END if (k == 0) ELSE ... */
    } /* END for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) */
    numFreqDerivIncludingNoSpinDown = numFreqDerivTotal;
  } else {
    numFreqDerivIncludingNoSpinDown = 1;  /* Even if numSpinDown = 0 still need to count case of zero spindown. */
  }  /* END if (numSpinDown > 0) ELSE ... */

  /* Initialize ephemeris data */
  XLAL_CHECK_LAL (status, ( edat = XLALInitBarycenter( earthFile, sunFile ) ) != NULL, XLAL_EFUNC);

  /* Allocate memory for PulsarSignalParams and initialize */
  pPulsarSignalParams = (PulsarSignalParams *)LALMalloc(sizeof(PulsarSignalParams));
  pPulsarSignalParams->pulsar.position.system = COORDINATESYSTEM_EQUATORIAL;
  pPulsarSignalParams->pulsar.spindown = NULL;
  if (numSpinDown > 0) {
    LALDCreateVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown),((UINT4)numSpinDown));
    CHECKSTATUSPTR (status);
  }
  pPulsarSignalParams->orbit.asini = 0 /* isolated pulsar */;
  pPulsarSignalParams->transfer = NULL;
  pPulsarSignalParams->dtDelayBy2 = 0;
  pPulsarSignalParams->dtPolBy2 = 0;
  /* Set up pulsar site */
  if (strstr(IFO, "LHO")) {
       cachedDetector = lalCachedDetectors[LALDetectorIndexLHODIFF];
  } else if (strstr(IFO, "LLO")) {
       cachedDetector = lalCachedDetectors[LALDetectorIndexLLODIFF];
  } else if (strstr(IFO, "GEO")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexGEO600DIFF];
  } else if (strstr(IFO, "VIRGO")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexVIRGODIFF];
  } else if (strstr(IFO, "TAMA")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexTAMA300DIFF];
  } else {
      /* "Invalid or null IFO" */
      ABORT( status, GENERATEPULSARSIGNALTESTC_EIFO, GENERATEPULSARSIGNALTESTC_MSGEIFO);
  }
  pPulsarSignalParams->site = &cachedDetector;
  pPulsarSignalParams->ephemerides = edat;
  pPulsarSignalParams->startTimeGPS.gpsSeconds = (INT4)gpsStartTimeSec;
  pPulsarSignalParams->startTimeGPS.gpsNanoSeconds = (INT4)gpsStartTimeNan;
  pPulsarSignalParams->duration = (UINT4)duration;
  pPulsarSignalParams->samplingRate = (REAL8)ceil(2.0*bandSFT); /* Make sampleRate an integer so that T*samplingRate = integer for integer T */
  pPulsarSignalParams->fHeterodyne = f0SFT;

  GPSin.gpsSeconds = timeStamps->data[0].gpsSeconds;
  GPSin.gpsNanoSeconds = timeStamps->data[0].gpsNanoSeconds;

  /* Allocate memory for SFTParams and initialize */
  pSFTParams = (SFTParams *)LALCalloc(1, sizeof(SFTParams));
  pSFTParams->Tsft = tSFT;
  pSFTParams->timestamps = timeStamps;
  pSFTParams->noiseSFTs = NULL;

  #ifdef INCLUDE_RANDVAL_MISMATCH
    /* Initial seed and randPar to use LALUniformDeviate to generate random mismatch during Monte Carlo. */
    fpRandom = fopen("/dev/urandom","r");
    rndCount = fread(&seed, sizeof(INT4),1, fpRandom);
    fclose(fpRandom);
    /* seed = 1234; */ /* Test value */
    LALCreateRandomParams(status->statusPtr, &randPar, seed);
    CHECKSTATUSPTR (status);
  #endif

  /* allocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */
  pSkyConstAndZeroPsiAMResponse = (SkyConstAndZeroPsiAMResponse *)LALMalloc(sizeof(SkyConstAndZeroPsiAMResponse));
  pSkyConstAndZeroPsiAMResponse->skyConst = (REAL8 *)LALMalloc((2*numSpinDown*(numSFTs+1)+2*numSFTs+3)*sizeof(REAL8));
  pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4));
  pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4));
  pSFTandSignalParams = (SFTandSignalParams *)LALMalloc(sizeof(SFTandSignalParams));
  /* create lookup table (LUT) values for doing trig */
  /* pSFTandSignalParams->resTrig = 64; */ /* length sinVal and cosVal; resolution of trig functions = 2pi/resTrig */
  /* pSFTandSignalParams->resTrig = 128; */ /* 10/08/04 gam; length sinVal and cosVal; domain = -2pi to 2pi inclusive; resolution = 4pi/resTrig */
  pSFTandSignalParams->resTrig = 0; /* 10/12/04 gam; turn off using LUTs since this is more typical. */
  /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */
  if (pSFTandSignalParams->resTrig > 0) {
    pSFTandSignalParams->trigArg = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    pSFTandSignalParams->sinVal  = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    pSFTandSignalParams->cosVal  = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    for (k=0; k<=pSFTandSignalParams->resTrig; k++) {
       /* pSFTandSignalParams->trigArg[k]= ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig); */ /* 10/08/04 gam */
       pSFTandSignalParams->trigArg[k]= -1.0*((REAL8)LAL_TWOPI) + 2.0 * ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig);
       pSFTandSignalParams->sinVal[k]=sin( pSFTandSignalParams->trigArg[k] );
       pSFTandSignalParams->cosVal[k]=cos( pSFTandSignalParams->trigArg[k] );
    }
  }
  pSFTandSignalParams->pSigParams = pPulsarSignalParams;
  pSFTandSignalParams->pSFTParams = pSFTParams;
  pSFTandSignalParams->nSamples = nsamples;
  pSFTandSignalParams->Dterms = Dterms;  /* 09/07/05 gam */

  /* ********************************************************/
  /*                                                       */
  /* START SECTION: LOOP OVER SKY POSITIONS                */
  /*                                                       */
  /* ********************************************************/
  for(iSky=0;iSky<numSkyPosTotal;iSky++) {

    /* set source sky position declination (DEC) */
    randval = 0.5; /* Gives default value */
    #ifdef INCLUDE_SEQUENTIAL_MISMATCH
      randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
    #endif
    #ifdef INCLUDE_RANDVAL_MISMATCH
       LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
    #endif
    pPulsarSignalParams->pulsar.position.latitude = skyPosData[iSky][1] + (((REAL8)randval) - 0.5)*DeltaDec;
    cosTmpDEC = cos(skyPosData[iSky][1]);
    if (cosTmpDEC != 0.0) {
          tmpDeltaRA = DeltaRA/cosTmpDEC;
    } else {
          tmpDeltaRA = 0.0; /* We are at a celestial pole */
    }

    /* set source sky position right ascension (RA) */
    randval = 0.5; /* Gives default value */
    #ifdef INCLUDE_SEQUENTIAL_MISMATCH
      randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
    #endif
    #ifdef INCLUDE_RANDVAL_MISMATCH
      LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
    #endif
    pPulsarSignalParams->pulsar.position.longitude = skyPosData[iSky][0] + (((REAL8)randval) - 0.5)*tmpDeltaRA;

    /* Find reference time in SSB for this sky positions */
    int ret = XLALConvertGPS2SSB ( &(pPulsarSignalParams->pulsar.refTime), GPSin, pPulsarSignalParams );
    if ( ret != XLAL_SUCCESS ) {
      XLALPrintError ("XLALConvertGPS2SSB() failed with xlalErrno = %d\n", xlalErrno );
      ABORTXLAL (status);
    }

    /* one per sky position fill in SkyConstAndZeroPsiAMResponse for use with LALFastGeneratePulsarSFTs */
    LALComputeSkyAndZeroPsiAMResponse (status->statusPtr, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams);
    CHECKSTATUSPTR (status);

    /* ********************************************************/
    /*                                                       */
    /* START SECTION: LOOP OVER SPINDOWN                     */
    /*                                                       */
    /* ********************************************************/
    for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) {
     /* source spindown parameters */
     if (numSpinDown > 0) {
       for(k=0;k<numSpinDown;k++) {
         randval = 0.5; /* Gives default value */
         #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            if (freqDerivData[jDeriv][k] < 0.0) {
               randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
            } else {
               randval = 0.5; /* If derivative is not negative (i.e., it is zero) then do not add in mismatch; keep it zero. */
            }
         #endif
         #ifdef INCLUDE_RANDVAL_MISMATCH
           LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
         #endif
         if (k == 0) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv1;
         } else if (k == 1) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv2;
         } else if (k == 2) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv3;
         } else if (k == 3) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv4;
         } else if (k == 4) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv5;
         } /* END if (k == 0) ELSE ... */
       }
     }

     /* ***************************************************/
     /*                                                  */
     /* START SECTION: LOOP OVER FREQUENCIES             */
     /*                                                  */
     /* ***************************************************/
     for(iFreq=0;iFreq<nBinsSGNL;iFreq++) {

       /* set source orientation psi */
       randval = 0.5; /* Gives default value */
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.psi = (randval - 0.5) * ((REAL4)LAL_PI_2);

       /* set angle between source spin axis and direction from source to SSB, cosIota */
       randval = 1.0; /* Gives default value */
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       cosIota = 2.0*((REAL8)randval) - 1.0;

       /* h_0 is fixed above; get A_+ and A_x from h_0 and cosIota */
       pPulsarSignalParams->pulsar.aPlus = (REAL4)(0.5*h_0*(1.0 + cosIota*cosIota));
       pPulsarSignalParams->pulsar.aCross = (REAL4)(h_0*cosIota);

       /* get random value for phi0 */
       randval = 0.125; /* Gives default value pi/4*/
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.phi0 = ((REAL8)randval) * ((REAL8)LAL_TWOPI);

       /* randval steps through various mismatches to frequencies centered on a bin */
       /* Note that iFreq = nBinsSGNL/2 gives randval = 0.5 gives no mismatch from frequency centered on a bin */
       randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.f0 = f0SGNL + iFreq*dfSGNL + (((REAL8)randval) - 0.5)*dfSGNL;

       testNumber++; /* Update count of which test we about to do. */

       /* FIRST: Use LALGeneratePulsarSignal and LALSignalToSFTs to generate outputSFTs */
       signalvec = NULL;
       LALGeneratePulsarSignal(status->statusPtr, &signalvec, pPulsarSignalParams);
       CHECKSTATUSPTR (status);
       outputSFTs = NULL;
       LALSignalToSFTs(status->statusPtr, &outputSFTs, signalvec, pSFTParams);
       CHECKSTATUSPTR (status);

       #ifdef PRINT_OUTPUTSFT
           if (testNumber == TESTNUMBER_TO_PRINT) {
              i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */
              fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0);
              fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross);
              fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi);
              fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0);
              fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0);
              fprintf(stdout,"outputSFTs->data[%i].data->length = %i \n",i,outputSFTs->data[i].data->length);
              renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1));
              for(j=0;j<nBinsSFT;j++) {
                /* fprintf(stdout,"%i %g %g \n", j, renorm*outputSFTs->data[i].data->data[j].re, renorm*outputSFTs->data[i].data->data[j].im); */
                fprintf(stdout,"%i %g \n",j,renorm*renorm*outputSFTs->data[i].data->data[j].re*outputSFTs->data[i].data->data[j].re + renorm*renorm*outputSFTs->data[i].data->data[j].im*outputSFTs->data[i].data->data[j].im);
                fflush(stdout);
              }
           }
       #endif

       /* SECOND: Use LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs to generate outputSFTs */
       LALFastGeneratePulsarSFTs (status->statusPtr, &fastOutputSFTs, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams);
       CHECKSTATUSPTR (status);

       #ifdef PRINT_FASTOUTPUTSFT
          if (testNumber == TESTNUMBER_TO_PRINT) {
            REAL4  fPlus;
            REAL4  fCross;
            i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */
            fPlus = pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) + pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi);
            fCross = pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) - pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi);
            fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0);
            fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross);
            fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi);
            fprintf(stdout,"iFreq = %i, fPlus, fCross = %23.10e,  %23.10e \n",iFreq,fPlus,fCross);
            fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0);
            fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0);
            fprintf(stdout,"fastOutputSFTs->data[%i].data->length = %i \n",i,fastOutputSFTs->data[i].data->length);
            fflush(stdout);
            for(j=0;j<nBinsSFT;j++) {
               /* fprintf(stdout,"%i %g %g \n",j,fastOutputSFTs->data[i].data->data[j].re,fastOutputSFTs->data[i].data->data[j].im); */
               fprintf(stdout,"%i %g \n",j,fastOutputSFTs->data[i].data->data[j].re*fastOutputSFTs->data[i].data->data[j].re + fastOutputSFTs->data[i].data->data[j].im*fastOutputSFTs->data[i].data->data[j].im);
               fflush(stdout);
            }
          }
       #endif

       /* find maximum difference in power */
       epsDiffMod = 0.20; /* maximum allowed percent difference */ /* 10/12/04 gam */
       overallMaxDiffSFTMod = 0.0;
       for (i = 0; i < numSFTs; i++) {
          renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1));
          maxDiffSFTMod = 0.0;
          diffAtMaxPower = 0.0;
          maxMod = 0.0;
          fastMaxMod = 0.0;
          jMaxMod = -1;
          jFastMaxMod = -1;
          /* Since doppler shifts can move the signal by an unknown number of bins search the whole band for max modulus: */
          for(j=0;j<nBinsSFT;j++) {
               sftMod = renorm*renorm*crealf(outputSFTs->data[i].data->data[j])*crealf(outputSFTs->data[i].data->data[j]) + renorm*renorm*cimagf(outputSFTs->data[i].data->data[j])*cimagf(outputSFTs->data[i].data->data[j]);
               sftMod = sqrt(sftMod);
               fastSFTMod = crealf(fastOutputSFTs->data[i].data->data[j])*crealf(fastOutputSFTs->data[i].data->data[j]) + cimagf(fastOutputSFTs->data[i].data->data[j])*cimagf(fastOutputSFTs->data[i].data->data[j]);
               fastSFTMod = sqrt(fastSFTMod);
               if (fabs(sftMod) > smallMod) {
                   tmpDiffSFTMod = fabs((sftMod - fastSFTMod)/sftMod);
                   if (tmpDiffSFTMod > maxDiffSFTMod) {
                       maxDiffSFTMod = tmpDiffSFTMod;
                   }
                   if (tmpDiffSFTMod > overallMaxDiffSFTMod) {
                       overallMaxDiffSFTMod = tmpDiffSFTMod;
                   }
                   if (sftMod > maxMod) {
                       maxMod = sftMod;
                       jMaxMod = j;
                   }
                   if (fastSFTMod > fastMaxMod) {
                       fastMaxMod = fastSFTMod;
                       jFastMaxMod = j;
                   }
               }
          }
          if (fabs(maxMod) > smallMod) {
             diffAtMaxPower = fabs((maxMod - fastMaxMod)/maxMod);
          }
          #ifdef PRINT_MAXSFTPOWER
            fprintf(stdout,"maxSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxMod,maxMod);
            fprintf(stdout,"maxFastSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jFastMaxMod,fastMaxMod);
            fflush(stdout);
          #endif
          #ifdef PRINT_MAXDIFFSFTPOWER
            fprintf(stdout,"maxDiffSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxDiff,maxDiffSFTMod);
            fflush(stdout);
          #endif
          #ifdef PRINT_DIFFATMAXPOWER
            fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower);
            fflush(stdout);
          #endif
          #ifdef PRINT_ERRORATMAXPOWER
            if (diffAtMaxPower > epsDiffMod) {
              fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g exceeded epsDiffMod = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower,epsDiffMod);
              fflush(stdout);
              /* break; */ /* only report 1 error per test */
            }
            if (jMaxMod != jFastMaxMod) {
              fprintf(stdout,"MaxPower occurred in different bins: testNumber %i, SFT %i, bins %i and %i\n",testNumber,i,jMaxMod,jFastMaxMod);
              fflush(stdout);
              /* break; */ /* only report 1 error per test */
            }
          #endif
          if (jMaxMod != jFastMaxMod) {
              binErrorCount++; /* 10/12/04 gam; count up bin errors; if too ABORT at bottom of code */
          }
          if ( diffAtMaxPower > epsDiffMod ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EMOD, GENERATEPULSARSIGNALTESTC_MSGEMOD);
          }
          /* 10/12/04 gam; turn on test above and add test below */
          if ( fabs(((REAL8)(jMaxMod - jFastMaxMod))) >  1.1 ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EBIN,   GENERATEPULSARSIGNALTESTC_MSGEBIN);
          }
       } /* END for(i = 0; i < numSFTs; i++) */
       #ifdef PRINT_OVERALLMAXDIFFSFTPOWER
         fprintf(stdout,"overallMaxDiffSFTMod, testNumber = %i, SFT %i, bin %i = %g \n",testNumber,iOverallMaxDiffSFTMod,jOverallMaxDiff,overallMaxDiffSFTMod);
         fflush(stdout);
       #endif

       /* 09/07/05 gam; Initialize fastOutputSFTs since only 2*Dterms bins are changed by LALFastGeneratePulsarSFTs */
       for (i = 0; i < numSFTs; i++) {
          for(j=0;j<nBinsSFT;j++) {
             fastOutputSFTs->data[i].data->data[j] = 0.0;
          }
       }

       XLALDestroySFTVector( outputSFTs);

       LALFree(signalvec->data->data);
       LALFree(signalvec->data);
       LALFree(signalvec);

     } /* END for(iFreq=0;iFreq<nBinsSGNL;iFreq++) */
     /* ***************************************************/
     /*                                                  */
     /* END SECTION: LOOP OVER FREQUENCIES               */
     /*                                                  */
     /* ***************************************************/
   } /* END for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) */
  /* ********************************************************/
  /*                                                       */
  /* END SECTION: LOOP OVER SPINDOWN                       */
  /*                                                       */
  /* ********************************************************/

  } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */
  /* ********************************************************/
  /*                                                       */
  /* END SECTION: LOOP OVER SKY POSITIONS                  */
  /*                                                       */
  /* ********************************************************/

  /* 10/12/04 gam; check if too many bin errors */
  epsBinErrorRate = 0.20;  /* 10/12/04 gam; maximum allowed bin errors */
  if ( (((REAL4)binErrorCount)/((REAL4)testNumber)) > epsBinErrorRate ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EBINS, GENERATEPULSARSIGNALTESTC_MSGEBINS);
  }

  #ifdef INCLUDE_RANDVAL_MISMATCH
    LALDestroyRandomParams(status->statusPtr, &randPar);
    CHECKSTATUSPTR (status);
  #endif

  /* fprintf(stdout,"Total number of tests completed = %i. \n", testNumber);
  fflush(stdout); */

  LALFree(pSFTParams);
  if (numSpinDown > 0) {
    LALDDestroyVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown));
    CHECKSTATUSPTR (status);
  }
  LALFree(pPulsarSignalParams);

  /* deallocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */
  XLALDestroySFTVector( fastOutputSFTs);
  LALFree(pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi);
  LALFree(pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi);
  LALFree(pSkyConstAndZeroPsiAMResponse->skyConst);
  LALFree(pSkyConstAndZeroPsiAMResponse);
  /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */
  if (pSFTandSignalParams->resTrig > 0) {
    LALFree(pSFTandSignalParams->trigArg);
    LALFree(pSFTandSignalParams->sinVal);
    LALFree(pSFTandSignalParams->cosVal);
  }
  LALFree(pSFTandSignalParams);

  /* deallocate skyPosData */
  for(i=0;i<numSkyPosTotal;i++)
  {
      LALFree(skyPosData[i]);
  }
  LALFree(skyPosData);

  if (numSpinDown > 0) {
    /* deallocate freqDerivData */
    for(i=0;i<numFreqDerivTotal;i++)
    {
        LALFree(freqDerivData[i]);
    }
    LALFree(freqDerivData);
  }

  LALFree(timeStamps->data);
  LALFree(timeStamps);

  XLALDestroyEphemerisData(edat);

  CHECKSTATUSPTR (status);
  DETATCHSTATUSPTR (status);
}
Пример #15
0
void
LALGenerateRing(
    LALStatus          *stat,
    CoherentGW         *output,
    REAL4TimeSeries    UNUSED *series,
    SimRingdownTable   *simRingdown,
    RingParamStruc     *params
    )

{
  UINT4 i;      /* number of and index over samples */
  REAL8 t, dt;         /* time, interval */
  REAL8 gtime ;    /* central time, decay time */
  REAL8 f0, quality;   /* frequency and quality factor */
  REAL8 twopif0;       /* 2*pi*f0 */
  REAL4 h0;            /* peak strain for ringdown */
  REAL4 *fData;        /* pointer to frequency data */
  REAL8 *phiData;      /* pointer to phase data */
  REAL8 init_phase;    /*initial phase of injection */
  REAL4 *aData;        /* pointer to frequency data */
  UINT4 nPointInj; /* number of data points in a block */
#if 0
  UINT4 n;
  REAL8 t0;
  REAL4TimeSeries signalvec; /* start time of block that injection is injected into */
  LALTimeInterval  interval;
  INT8 geoc_tns;       /* geocentric_start_time of the injection in ns */
  INT8 block_tns;      /* start time of block in ns */
  REAL8 deltaTns;
  INT8 inj_diff;       /* time between start of segment and injection */
  LALTimeInterval dummyInterval;
#endif

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Make sure parameter and output structures exist. */
  ASSERT( params, stat, GENERATERINGH_ENUL,
	  GENERATERINGH_MSGENUL );
  ASSERT( output, stat, GENERATERINGH_ENUL,
	  GENERATERINGH_MSGENUL );

  /* Make sure output fields don't exist. */
  ASSERT( !( output->a ), stat, GENERATERINGH_EOUT,
	  GENERATERINGH_MSGEOUT );
  ASSERT( !( output->f ), stat, GENERATERINGH_EOUT,
	  GENERATERINGH_MSGEOUT );
  ASSERT( !( output->phi ), stat, GENERATERINGH_EOUT,
	  GENERATERINGH_MSGEOUT );
  ASSERT( !( output->shift ), stat, GENERATERINGH_EOUT,
	  GENERATERINGH_MSGEOUT );


  /* Set up some other constants, to avoid repeated dereferencing. */
  dt = params->deltaT;
/* N_point = 2 * floor(0.5+ 1/ dt); */

  nPointInj = 163840;

  /* Generic ring parameters */
  h0 = simRingdown->amplitude;
  quality = (REAL8)simRingdown->quality;
  f0 = (REAL8)simRingdown->frequency;
  twopif0 = f0*LAL_TWOPI;
  init_phase = simRingdown->phase;


  if ( ( output->a = (REAL4TimeVectorSeries *)
	 LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
    ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
  }
  memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
  if ( ( output->f = (REAL4TimeSeries *)
	 LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
  }
  memset( output->f, 0, sizeof(REAL4TimeSeries) );
  if ( ( output->phi = (REAL8TimeSeries *)
	 LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    LALFree( output->f ); output->f = NULL;
    ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
  }
  memset( output->phi, 0, sizeof(REAL8TimeSeries) );

  /* Set output structure metadata fields. */
  output->position.longitude = simRingdown->longitude;
  output->position.latitude = simRingdown->latitude;
  output->position.system = params->system;
  output->psi = simRingdown->polarization;
   /* set epoch of output time series to that of the block */
  output->a->epoch = output->f->epoch = output->phi->epoch = simRingdown->geocent_start_time;
  output->a->deltaT = params->deltaT;
  output->f->deltaT = output->phi->deltaT = params->deltaT;
  output->a->sampleUnits = lalStrainUnit;
  output->f->sampleUnits = lalHertzUnit;
  output->phi->sampleUnits = lalDimensionlessUnit;
  snprintf( output->a->name, LALNameLength, "Ring amplitudes" );
  snprintf( output->f->name, LALNameLength, "Ring frequency" );
  snprintf( output->phi->name, LALNameLength, "Ring phase" );


  /* Allocate phase and frequency arrays. */
  LALSCreateVector( stat->statusPtr, &( output->f->data ), nPointInj );
  BEGINFAIL( stat ) {
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );

  LALDCreateVector( stat->statusPtr, &( output->phi->data ), nPointInj );
  BEGINFAIL( stat ) {
    TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	 stat );
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );


  /* Allocate amplitude array. */
  {
    CreateVectorSequenceIn in; /* input to create output->a */
    in.length = nPointInj;
    in.vectorLength = 2;
    LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
    BEGINFAIL( stat ) {
      TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	   stat );
      TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
	   stat );
      LALFree( output->a );   output->a = NULL;
      LALFree( output->f );   output->f = NULL;
      LALFree( output->phi ); output->phi = NULL;
    } ENDFAIL( stat );
  }


  /*  set arrays to zero */
  memset( output->f->data->data, 0, sizeof( REAL4 ) *  output->f->data->length );
  memset( output->phi->data->data, 0, sizeof( REAL8 ) * output->phi->data->length );
  memset( output->a->data->data, 0, sizeof( REAL4 ) *
      output->a->data->length * output->a->data->vectorLength );

/* Fill frequency and phase arrays starting at time of injection NOT start */
  fData = output->f->data->data;
  phiData = output->phi->data->data;
  aData = output->a->data->data;

  if ( !( strcmp( simRingdown->waveform, "Ringdown" ) ) )
  {
    for ( i = 0; i < nPointInj; i++ )
    {
      t = i * dt;
      gtime = twopif0 / 2 / quality * t ;
      *(fData++)   = f0;
      *(phiData++) = twopif0 * t+init_phase;
      *(aData++) = h0 * ( 1.0 + pow( cos( simRingdown->inclination ), 2 ) ) *
        exp( - gtime );
      *(aData++) = h0* 2.0 * cos( simRingdown->inclination ) * exp( - gtime );
    }
  }
  else
  {
    ABORT( stat, GENERATERINGH_ETYP, GENERATERINGH_MSGETYP );
  }


/* Set output field and return. */
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
Пример #16
0
/** \see See \ref DetInverse_c for documentation */
void
LALDMatrixInverse( LALStatus *stat, REAL8 *det, REAL8Array *matrix, REAL8Array *inverse )
{
  INT2 sgn;                 /* sign of permutation. */
  UINT4 n, i, j, ij;        /* array dimension and indecies */
  UINT4Vector *indx = NULL; /* permutation storage vector */
  REAL8Vector *col = NULL;  /* columns of inverse matrix */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Check dimension length.  Other argument testing is done by the
     subroutines. */
  ASSERT( matrix, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL );
  ASSERT( matrix->dimLength, stat, MATRIXUTILSH_ENUL,
	  MATRIXUTILSH_MSGENUL );
  ASSERT( matrix->dimLength->data, stat, MATRIXUTILSH_ENUL,
	  MATRIXUTILSH_MSGENUL );
  ASSERT( inverse, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL );
  ASSERT( inverse->dimLength, stat, MATRIXUTILSH_ENUL,
	  MATRIXUTILSH_MSGENUL );
  ASSERT( inverse->dimLength->data, stat, MATRIXUTILSH_ENUL,
	  MATRIXUTILSH_MSGENUL );
  ASSERT( inverse->dimLength->length == 2, stat, MATRIXUTILSH_EDIM,
	  MATRIXUTILSH_MSGEDIM );
  n = inverse->dimLength->data[0];
  ASSERT( n, stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM );
  ASSERT( n == inverse->dimLength->data[1], stat, MATRIXUTILSH_EDIM,
	  MATRIXUTILSH_MSGEDIM );

  /* Allocate vectors to store the matrix permutation and column
     vectors. */
  TRY( LALU4CreateVector( stat->statusPtr, &indx, n ), stat );
  LALDCreateVector( stat->statusPtr, &col, n );
  BEGINFAIL( stat ) {
    TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
  } ENDFAIL( stat );

  /* Decompose the matrix. */
  LALDLUDecomp( stat->statusPtr, &sgn, matrix, indx );
  BEGINFAIL( stat ) {
    TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
    TRY( LALDDestroyVector( stat->statusPtr, &col ), stat );
  } ENDFAIL( stat );

  /* Compute the determinant, if available. */
  if ( det ) {
    *det = sgn;
    for ( i = 0; i < n; i++ )
      *det *= matrix->data[i*(n+1)];
  }

  /* Compute each column of inverse matrix. */
  for ( j = 0; j < n; j++ ) {
    memset( col->data, 0, n*sizeof(REAL8) );
    col->data[j] = 1.0;
    LALDLUBackSub( stat->statusPtr, col, matrix, indx );
    BEGINFAIL( stat ) {
      TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
      TRY( LALDDestroyVector( stat->statusPtr, &col ), stat );
    } ENDFAIL( stat );
    for ( i = 0, ij = j; i < n; i++, ij += n )
      inverse->data[ij] = col->data[i];
  }

  /* Clean up. */
  TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
  TRY( LALDDestroyVector( stat->statusPtr, &col ), stat );
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
Пример #17
0
int
main(int argc, char **argv)
{
  /* top-level status structure */
 UINT4   numPSDpts=8193;
  static LALStatus status;
  static InspiralCoarseBankIn coarseIn;
  void *noisemodel = LALLIGOIPsd;
  double beta;
  SnglInspiralTable *tiles=NULL, *first=NULL;
  FILE *fpr;

/* Number of templates is nlist */
  INT4 nlist1, j;


  fpr = fopen("BCVSpinTemplates.out", "w");
  nlist1 = 0;
  coarseIn.HighGM = 6.;
  coarseIn.LowGM = -4.;
  coarseIn.fLower = 40.L;
  coarseIn.fUpper = 400.L;
  coarseIn.tSampling = 4096.L;
  coarseIn.order = twoPN;
  coarseIn.mmCoarse = 0.90;
  coarseIn.mmFine = 0.90;
  coarseIn.iflso = 0.0L;
  coarseIn.mMin = 3.0;
  coarseIn.mMax = 20.0;
  coarseIn.MMax = coarseIn.mMax * 2.;
  coarseIn.massRange = MinMaxComponentMass;
  /* coarseIn.massRange = MinComponentMassMaxTotalMass;*/
  /* minimum value of eta */
  coarseIn.etamin = coarseIn.mMin * ( coarseIn.MMax - coarseIn.mMin) / pow(coarseIn.MMax,2.);
  coarseIn.psi0Min = 1.0e4;
  coarseIn.psi0Max = 6.0e4;
  coarseIn.psi3Min = -5.0e2;
  coarseIn.psi3Max = 1.0e1;
  coarseIn.alpha = 0.L;
  coarseIn.numFcutTemplates = 1;
  coarseIn.betaMin = 10.0;
  coarseIn.betaMax = 700.;
  coarseIn.spinBank = 2;
  coarseIn.iseed = 9295883;
  coarseIn.nTIni = 10000;
  coarseIn.ShMaxSz = 1024;
  coarseIn.gridSpacing = Hexagonal;
  coarseIn.insidePolygon = True;

  memset( &(coarseIn.shf), 0, sizeof(REAL8FrequencySeries) );
  coarseIn.shf.f0 = 0;
  LALDCreateVector( &status, &(coarseIn.shf.data), numPSDpts );
  coarseIn.shf.deltaF = coarseIn.tSampling / (2.*(REAL8) coarseIn.shf.data->length + 1.L);
  LALNoiseSpectralDensity (&status, coarseIn.shf.data, noisemodel, coarseIn.shf.deltaF );

  coarseIn.approximant = BCVSpin;
  coarseIn.space       = Psi0Psi3;


  LALInspiralBCVSpinRandomBank (&status, &tiles, &nlist1, &coarseIn);
/*
  LALInspiralBankGeneration(&status, &coarseIn, &tiles, &nlist1);
*/
  LALDDestroyVector( &status, &(coarseIn.shf.data) );

  fprintf (fpr, "#numtemplaes=%d %e %e %e %e %e %e\n", nlist1, coarseIn.psi0Min, coarseIn.psi0Max, coarseIn.psi3Min, coarseIn.psi3Max, coarseIn.betaMin, coarseIn.betaMax);
  beta = tiles->beta;
  first = tiles;
  for (j=0; j<nlist1; j++)
  {
	  fprintf(fpr, "%7.3f %e %e\n", beta, tiles->psi0, tiles->psi3);
	  tiles = tiles->next;
	  if (tiles != NULL && beta != tiles->beta)
	  {
		  beta = tiles->beta;
	  }
  }
  fclose(fpr);

  tiles = first;
  for (j=0; j<nlist1; j++)
  {
          first = tiles ->next;
	  if (tiles != NULL) LALFree(tiles);
          tiles = first;
  }
  LALCheckMemoryLeaks();
  return 0;
}
/* Function to generate time domain waveform for injection */
void GenerateTimeDomainWaveformForInjection (
        LALStatus              *status,
        REAL4Vector            *buff,
        InspiralTemplate       *param
        )
{

    CoherentGW          waveform;
    PPNParamStruc       ppnParams;
    INT4                nStartPad = 0;

    INITSTATUS(status);
    ATTATCHSTATUSPTR(status);


    memset( &waveform, 0, sizeof(CoherentGW) );

    ppnParams.deltaT               = 1.0 / param->tSampling;
    ppnParams.mTot                 = param->mass1 + param->mass2;
    ppnParams.eta                  = param->eta;
    ppnParams.d                    = param->distance;
    ppnParams.inc                  = param->inclination;
    ppnParams.phi                  = param->startPhase;
    ppnParams.fStartIn             = param->fLower;
    ppnParams.fStopIn              = -1.0 / (6.0 * sqrt(6.0) * LAL_PI * ppnParams.mTot * LAL_MTSUN_SI);
    ppnParams.position.longitude   = param->sourcePhi;
    ppnParams.position.latitude    = param->sourceTheta;
    ppnParams.position.system      = COORDINATESYSTEM_EQUATORIAL;
    ppnParams.psi                  = param->polarisationAngle;
    ppnParams.epoch.gpsSeconds     = 0;
    ppnParams.epoch.gpsNanoSeconds = 0;


    /* the waveform generation itself */

    /* Note that in the call to LALInspiralWaveForInjection,
     * the param.nStartPad will be reset to zero. We do
     * not want to lose the information. So we should save it
     * somewhere (in a temporary variable) before the function
     * call.
     */
    nStartPad = param->nStartPad;

    LALInspiralWaveForInjection(status->statusPtr, &waveform, param, &ppnParams);
    CHECKSTATUSPTR(status);

    /* Now reinstate nStartPad from saved value */
    param->nStartPad = nStartPad;

    /* Generate F+ and Fx and combine it with h+ and hx to get
     * the correct waveform. See equation from BCV2 (Eq 29,
     * 30).  */
    {
        REAL8 t, p, s, a1, a2, phi, phi0, shift;
        REAL8 fp, fc, hp, hc;
        UINT4 kk;

        t = cos(param->sourceTheta);
        p = 2. * param->sourcePhi;
        s = 2. * param->polarisationAngle;

        fp = 0.5*(1 + t*t)*cos(p)*cos(s) - t*sin(p)*sin(s);
        fc = 0.5*(1 + t*t)*cos(p)*sin(s) + t*sin(p)*cos(s);

        phi0 = waveform.phi->data->data[0];
        for (kk=0; kk < waveform.phi->data->length; kk++)
        {
            a1    = waveform.a->data->data[2*kk];
            a2    = waveform.a->data->data[2*kk+1];
/*            phi   = waveform.phi->data->data[kk] - phi0 -
 *            param->startPhase;*/
            phi   = waveform.phi->data->data[kk] - phi0;
            shift = waveform.shift->data->data[kk];
            hp    = a1*cos(shift)*cos(phi) - a2*sin(shift)*sin(phi);
            hc    = a1*sin(shift)*cos(phi) + a2*cos(shift)*sin(phi);
            buff->data[kk + param->nStartPad] = fp*hp + fc*hc;
        }

    LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) );
    CHECKSTATUSPTR( status );
    LALSDestroyVector( status->statusPtr, &(waveform.f->data) );
    CHECKSTATUSPTR( status );
    LALDDestroyVector( status->statusPtr, &(waveform.phi->data) );
    CHECKSTATUSPTR( status );
    LALSDestroyVector( status->statusPtr, &(waveform.shift->data) );
    CHECKSTATUSPTR( status );
    LALFree( waveform.a );
    LALFree( waveform.f );
    LALFree( waveform.phi );
    LALFree( waveform.shift );
    }

    param->fFinal = ppnParams.fStop;
    DETATCHSTATUSPTR(status);
    RETURN(status);
}
Пример #19
0
int
main(int argc, char **argv)
{
  /* Command-line parsing variables. */
  int arg;                   /* command-line argument counter */
  static LALStatus stat;     /* status structure */
  CHAR *sourcefile = NULL;   /* name of sourcefile */
  CHAR *respfile = NULL;     /* name of respfile */
  CHAR *infile = NULL;       /* name of infile */
  CHAR *outfile = NULL;      /* name of outfile */
  INT4 seed = 0;             /* random number seed */
  INT4 sec = SEC;            /* ouput epoch.gpsSeconds */
  INT4 nsec = NSEC;          /* ouput epoch.gpsNanoSeconds */
  INT4 npt = NPT;            /* number of output points */
  REAL8 dt = DT;             /* output sampling interval */
  REAL4 sigma = SIGMA;       /* noise amplitude */

  /* File reading variables. */
  FILE *fp = NULL; /* generic file pointer */
  BOOLEAN ok = 1;  /* whether input format is correct */
  UINT4 i;         /* generic index over file lines */
  INT8 epoch;      /* epoch stored as an INT8 */

  /* Other global variables. */
  RandomParams *params = NULL; /* parameters of pseudorandom sequence */
  DetectorResponse detector;   /* the detector in question */
  INT2TimeSeries output;       /* detector ACD output */


  /*******************************************************************
   * PARSE ARGUMENTS (arg stores the current position)               *
   *******************************************************************/

  /* Exit gracefully if no arguments were given.
  if ( argc <= 1 ) {
    INFO( "No testing done." );
    return 0;
  } */

  arg = 1;
  while ( arg < argc ) {
    /* Parse source file option. */
    if ( !strcmp( argv[arg], "-s" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	sourcefile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse response file option. */
    else if ( !strcmp( argv[arg], "-r" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	respfile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse input file option. */
    else if ( !strcmp( argv[arg], "-i" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	infile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse noise output option. */
    else if ( !strcmp( argv[arg], "-n" ) ) {
      if ( argc > arg + 5 ) {
	arg++;
	sec = atoi( argv[arg++] );
	nsec = atoi( argv[arg++] );
	npt = atoi( argv[arg++] );
	dt = atof( argv[arg++] );
	sigma = atof( argv[arg++] );
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse output file option. */
    else if ( !strcmp( argv[arg], "-o" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	outfile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse debug level option. */
    else if ( !strcmp( argv[arg], "-d" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse random seed option. */
    else if ( !strcmp( argv[arg], "-e" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	seed = atoi( argv[arg++] );
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Check for unrecognized options. */
    else if ( argv[arg][0] == '-' ) {
      ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
      LALPrintError( USAGE, *argv );
      return BASICINJECTTESTC_EARG;
    }
  } /* End of argument parsing loop. */

  /* Check for redundant or bad argument values. */
  CHECKVAL( npt, 0, 2147483647 );
  CHECKVAL( dt, 0, LAL_REAL4_MAX );


  /*******************************************************************
   * SETUP                                                           *
   *******************************************************************/

  /* Set up output, detector, and random parameter structures. */
  output.data = NULL;
  detector.transfer = (COMPLEX8FrequencySeries *)
    LALMalloc( sizeof(COMPLEX8FrequencySeries) );
  if ( !(detector.transfer) ) {
    ERROR( BASICINJECTTESTC_EMEM, BASICINJECTTESTC_MSGEMEM, 0 );
    return BASICINJECTTESTC_EMEM;
  }
  detector.transfer->data = NULL;
  detector.site = NULL;
  SUB( LALCreateRandomParams( &stat, &params, seed ), &stat );

  /* Set up units. */
  output.sampleUnits = lalADCCountUnit;
  if (XLALUnitDivide( &(detector.transfer->sampleUnits),
                      &lalADCCountUnit, &lalStrainUnit ) == NULL) {
    return LAL_EXLAL;
  }

  /* Read response function. */
  if ( respfile ) {
    REAL4VectorSequence *resp = NULL; /* response as vector sequence */
    COMPLEX8Vector *response = NULL;  /* response as complex vector */
    COMPLEX8Vector *unity = NULL;     /* vector of complex 1's */

    if ( ( fp = fopen( respfile, "r" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     respfile );
      return BASICINJECTTESTC_EFILE;
    }

    /* Read header. */
    ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 );
    I8ToLIGOTimeGPS( &( detector.transfer->epoch ), epoch );
    ok &= ( fscanf( fp, "# f0 = %lf\n", &( detector.transfer->f0 ) )
	    == 1 );
    ok &= ( fscanf( fp, "# deltaF = %lf\n",
		    &( detector.transfer->deltaF ) ) == 1 );
    if ( !ok ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     respfile );
      return BASICINJECTTESTC_EINPUT;
    }

    /* Read and convert body to a COMPLEX8Vector. */
    SUB( LALSReadVectorSequence( &stat, &resp, fp ), &stat );
    fclose( fp );
    if ( resp->vectorLength != 2 ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     respfile );
      return BASICINJECTTESTC_EINPUT;
    }
    SUB( LALCCreateVector( &stat, &response, resp->length ), &stat );
    memcpy( response->data, resp->data, 2*resp->length*sizeof(REAL4) );
    SUB( LALSDestroyVectorSequence( &stat, &resp ), &stat );

    /* Convert response function to a transfer function. */
    SUB( LALCCreateVector( &stat, &unity, response->length ), &stat );
    for ( i = 0; i < response->length; i++ ) {
      unity->data[i] = 1.0;
    }
    SUB( LALCCreateVector( &stat, &( detector.transfer->data ),
			   response->length ), &stat );
    SUB( LALCCVectorDivide( &stat, detector.transfer->data, unity,
			    response ), &stat );
    SUB( LALCDestroyVector( &stat, &response ), &stat );
    SUB( LALCDestroyVector( &stat, &unity ), &stat );
  }

  /* No response file, so generate a unit response. */
  else {
    I8ToLIGOTimeGPS( &( detector.transfer->epoch ), EPOCH );
    detector.transfer->f0 = 0.0;
    detector.transfer->deltaF = 1.5*FSTOP;
    SUB( LALCCreateVector( &stat, &( detector.transfer->data ), 2 ),
	 &stat );
    detector.transfer->data->data[0] = 1.0;
    detector.transfer->data->data[1] = 1.0;
  }


  /* Read input data. */
  if ( infile ) {
    REAL4VectorSequence *input = NULL; /* input as vector sequence */
    if ( ( fp = fopen( infile, "r" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     infile );
      return BASICINJECTTESTC_EFILE;
    }

    /* Read header. */
    ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 );
    I8ToLIGOTimeGPS( &( output.epoch ), epoch );
    ok &= ( fscanf( fp, "# deltaT = %lf\n", &( output.deltaT ) )
	    == 1 );
    if ( !ok ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     infile );
      return BASICINJECTTESTC_EINPUT;
    }

    /* Read and convert body. */
    SUB( LALSReadVectorSequence( &stat, &input, fp ), &stat );
    fclose( fp );
    if ( input->vectorLength != 1 ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     infile );
      return BASICINJECTTESTC_EINPUT;
    }
    SUB( LALI2CreateVector( &stat, &( output.data ), input->length ),
	 &stat );
    for ( i = 0; i < input->length; i++ )
      output.data->data[i] = (INT2)( input->data[i] );
    SUB( LALSDestroyVectorSequence( &stat, &input ), &stat );
  }

  /* No input file, so generate one randomly. */
  else {
    output.epoch.gpsSeconds = sec;
    output.epoch.gpsNanoSeconds = nsec;
    output.deltaT = dt;
    SUB( LALI2CreateVector( &stat, &( output.data ), npt ), &stat );
    if ( sigma == 0 ) {
      memset( output.data->data, 0, npt*sizeof(INT2) );
    } else {
      REAL4Vector *deviates = NULL; /* unit Gaussian deviates */
      SUB( LALSCreateVector( &stat, &deviates, npt ), &stat );
      SUB( LALNormalDeviates( &stat, deviates, params ), &stat );
      for ( i = 0; i < (UINT4)( npt ); i++ )
	output.data->data[i] = (INT2)
	  floor( sigma*deviates->data[i] + 0.5 );
      SUB( LALSDestroyVector( &stat, &deviates ), &stat );
    }
  }


  /*******************************************************************
   * INJECTION                                                       *
   *******************************************************************/

  /* Open sourcefile. */
  if ( sourcefile ) {
    if ( ( fp = fopen( sourcefile, "r" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     sourcefile );
      return BASICINJECTTESTC_EFILE;
    }
  }

  /* For each line in the sourcefile... */
  while ( ok ) {
    PPNParamStruc ppnParams;       /* wave generation parameters */
    REAL4 m1, m2, dist, inc, phic; /* unconverted parameters */
    CoherentGW waveform;           /* amplitude and phase structure */
    REAL4TimeSeries signalvec;     /* GW signal */
    REAL8 time;                    /* length of GW signal */
    CHAR timeCode;                 /* code for signal time alignment */
    CHAR message[MSGLEN];          /* warning/info messages */

    /* Read and convert input line. */
    if ( sourcefile ) {
      ok &= ( fscanf( fp, "%c %" LAL_INT8_FORMAT " %f %f %f %f %f\n", &timeCode,
		      &epoch, &m1, &m2, &dist, &inc, &phic ) == 7 );
      ppnParams.mTot = m1 + m2;
      ppnParams.eta = m1*m2/( ppnParams.mTot*ppnParams.mTot );
      ppnParams.d = dist*LAL_PC_SI*1000.0;
      ppnParams.inc = inc*LAL_PI/180.0;
      ppnParams.phi = phic*LAL_PI/180.0;
    } else {
      timeCode = 'i';
      ppnParams.mTot = M1 + M2;
      ppnParams.eta = M1*M2/( ppnParams.mTot*ppnParams.mTot );
      ppnParams.d = DIST;
      ppnParams.inc = INC;
      ppnParams.phi = PHIC;
      epoch = EPOCH;
    }

    if ( ok ) {
      /* Set up other parameter structures. */
      ppnParams.epoch.gpsSeconds = ppnParams.epoch.gpsNanoSeconds = 0;
      ppnParams.position.latitude = ppnParams.position.longitude = 0.0;
      ppnParams.position.system = COORDINATESYSTEM_EQUATORIAL;
      ppnParams.psi = 0.0;
      ppnParams.fStartIn = FSTART;
      ppnParams.fStopIn = FSTOP;
      ppnParams.lengthIn = 0;
      ppnParams.ppn = NULL;
      ppnParams.deltaT = DELTAT;
      memset( &waveform, 0, sizeof(CoherentGW) );

      /* Generate waveform at zero epoch. */
      SUB( LALGeneratePPNInspiral( &stat, &waveform, &ppnParams ),
	   &stat );
      snprintf( message, MSGLEN, "%d: %s", ppnParams.termCode,
		   ppnParams.termDescription );
      INFO( message );
      if ( ppnParams.dfdt > 2.0 ) {
	snprintf( message, MSGLEN,
		     "Waveform sampling interval is too large:\n"
		     "\tmaximum df*dt = %f", ppnParams.dfdt );
	WARNING( message );
      }

      /* Compute epoch for waveform. */
      time = waveform.a->data->length*DELTAT;
      if ( timeCode == 'f' )
	epoch -= (INT8)( 1000000000.0*time );
      else if ( timeCode == 'c' )
	epoch -= (INT8)( 1000000000.0*ppnParams.tc );
      I8ToLIGOTimeGPS( &( waveform.a->epoch ), epoch );
      waveform.f->epoch = waveform.phi->epoch = waveform.a->epoch;

      /* Generate and inject signal. */
      signalvec.epoch = waveform.a->epoch;
      signalvec.epoch.gpsSeconds -= 1;
      signalvec.deltaT = output.deltaT/4.0;
      signalvec.f0 = 0;
      signalvec.data = NULL;
      time = ( time + 2.0 )/signalvec.deltaT;
      SUB( LALSCreateVector( &stat, &( signalvec.data ), (UINT4)time ),
	   &stat );
      SUB( LALSimulateCoherentGW( &stat, &signalvec, &waveform,
				  &detector ), &stat );
      SUB( LALSI2InjectTimeSeries( &stat, &output, &signalvec, params ),
	   &stat );
      SUB( LALSDestroyVectorSequence( &stat, &( waveform.a->data ) ),
	   &stat );
      SUB( LALSDestroyVector( &stat, &( waveform.f->data ) ), &stat );
      SUB( LALDDestroyVector( &stat, &( waveform.phi->data ) ), &stat );
      LALFree( waveform.a );
      LALFree( waveform.f );
      LALFree( waveform.phi );
      SUB( LALSDestroyVector( &stat, &( signalvec.data ) ), &stat );
    }

    /* If there is no source file, inject only one source. */
    if ( !sourcefile )
      ok = 0;
  }

  /* Input file is exhausted (or has a badly-formatted line ). */
  if ( sourcefile )
    fclose( fp );


  /*******************************************************************
   * CLEANUP                                                         *
   *******************************************************************/

  /* Print output file. */
  if ( outfile ) {
    if ( ( fp = fopen( outfile, "w" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     outfile );
      return BASICINJECTTESTC_EFILE;
    }
    epoch = 1000000000LL*(INT8)( output.epoch.gpsSeconds );
    epoch += (INT8)( output.epoch.gpsNanoSeconds );
    fprintf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", epoch );
    fprintf( fp, "# deltaT = %23.16e\n", output.deltaT );
    for ( i = 0; i < output.data->length; i++ )
      fprintf( fp, "%8.1f\n", (REAL4)( output.data->data[i] ) );
    fclose( fp );
  }

  /* Destroy remaining memory. */
  SUB( LALDestroyRandomParams( &stat, &params ), &stat );
  SUB( LALI2DestroyVector( &stat, &( output.data ) ), &stat );
  SUB( LALCDestroyVector( &stat, &( detector.transfer->data ) ),
       &stat );
  LALFree( detector.transfer );

  /* Done! */
  LALCheckMemoryLeaks();
  INFO( BASICINJECTTESTC_MSGENORM );
  return BASICINJECTTESTC_ENORM;
}
Пример #20
0
int main( int argc, char *argv[] ) {
  static LALStatus status;          /* Status structure */
  PtoleMetricIn    in;              /* PtoleMetric() input structure */
  REAL8            mismatch;        /* mismatch threshold of mesh */
  REAL8Vector     *metric;          /* Parameter-space metric */
  int              j, k;            /* Parameter-space indices */
  int              opt;             /* Command-line option. */
  BOOLEAN          grace;           /* Whether or not we use xmgrace */
  BOOLEAN          nongrace;        /* Whether or not to output data to file*/
  int              ra, dec, i;      /* Loop variables for xmgrace option */
  FILE            *pvc = NULL;      /* Temporary file for xmgrace option */
  FILE            *fnongrace = NULL;/* File contaning ellipse coordinates */
  int              metric_code;     /* Which metric code to use: */
                                    /* 1 = Ptolemetric */
                                    /* 2 = CoherentMetric + DTBarycenter */
                                    /* 3 = CoherentMetric + DTEphemeris  */
  REAL8Vector     *tevlambda;       /* (f, a, d, ...) for CoherentMetric */
  MetricParamStruc tevparam;        /* Input structure for CoherentMetric */
  PulsarTimesParamStruc tevpulse;   /* Input structure for CoherentMetric */
                                    /* (this is a member of tevparam) */
  EphemerisData   *eph;             /* To store ephemeris data */
  int             detector;         /* Which detector to use: */
                                    /* 1 = Hanford,  2 = Livingston,  */
                                    /* 3 = Virgo,  4 = GEO,  5 = TAMA */
  REAL8           ra_point;         /* RA at which metric is evaluated */
  REAL8           dec_point;        /* dec at which metric is evaluated */
  float           a,b,c,d,e,f;      /* To input point in standard format */
  int             ra_min, ra_max;   /* Min and max RA for ellipse plot */
  int             dec_min, dec_max; /* Min and max dec for ellipse plot */
  float           c_ellipse;        /* Centers of ellipses */
  float           r_ellipse;        /* Radii of ellipses */
  REAL8           determinant;      /* Determinant of projected metric */
  REAL4           f0;               /* carrier frequency */
  UINT2           numSpindown;      /* Number of spindowns */

  char earth[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz";
  char sun[]   = TEST_DATA_DIR "sun00-19-DE405.dat.gz";


  /* Defaults that can be overwritten: */
  metric_code = 1;
  in.epoch.gpsSeconds = tevpulse.epoch.gpsSeconds = 731265908;
  in.epoch.gpsNanoSeconds = tevpulse.epoch.gpsNanoSeconds = 0.0;
  mismatch = 0.02;
  nongrace = 0;
  in.duration = tevparam.deltaT = DEFAULT_DURATION;
  grace = 0;
  detector = 4;
  ra_point  = (24.1/60)*LAL_PI_180;     /* 47 Tuc */
  dec_point = -(72+5./60)*LAL_PI_180;
  ra_min = 0;
  ra_max = 90;
  dec_min = 0;
  dec_max = 85;
  f0 = 1000;
  numSpindown = 0;

  /* Parse options. */
  while ((opt = LALgetopt( argc, argv, "a:b:c:d:ef:l:m:n:pt:s:x" )) != -1) {
    switch (opt) {
    case 'a':
      metric_code = atoi( LALoptarg );
      break;
    case 'b':
      in.epoch.gpsSeconds = tevpulse.epoch.gpsSeconds = atoi( LALoptarg );
      break;
    case 'c':
      if( sscanf( LALoptarg, "%f:%f:%f:%f:%f:%f", &a, &b, &c, &d, &e, &f ) != 6)
	{
	  fprintf( stderr, "coordinates should be hh:mm:ss:dd:mm:ss\n" );
	}
      ra_point = (15*a+b/4+c/240)*LAL_PI_180;
      dec_point = (d+e/60+f/3600)*LAL_PI_180;
      break;
    case 'd':
      detector = atoi( LALoptarg );
      break;
    case 'e':
      break;
    case 'f':
      f0 = atof( LALoptarg );
      break;
    case 'l':
      if( sscanf( LALoptarg, "%d:%d:%d:%d",
		  &ra_min, &ra_max, &dec_min, &dec_max) != 4)
	{
	  fprintf( stderr, "coordinates should be ra_min, ra_max, dec_min, dec_max all in degrees" );
	}
      break;
    case 'm':
      mismatch = atof( LALoptarg );
      break;
    case 'n':
      numSpindown = atoi( LALoptarg );
      break;
    case 'p':
      nongrace = 1;
      break;
    case 's':
      break;
    case 't':
      in.duration = tevparam.deltaT = atof( LALoptarg );
      break;
    case 'x':
      grace = 1;
      break;
    }
  }

  /* Allocate storage. */
  metric = NULL;
  LALDCreateVector( &status, &metric, (3+numSpindown)*(4+numSpindown)/2 );
  if( status.statusCode )
    {
      printf( "%s line %d: %s\n", __FILE__, __LINE__,
              GENERALMETRICTESTC_MSGEMEM );
      return GENERALMETRICTESTC_EMEM;
    }
  tevlambda = NULL;
  LALDCreateVector( &status, &tevlambda, 3+numSpindown );
  if( status.statusCode )
    {
      printf( "%s line %d: %s\n", __FILE__, __LINE__,
              GENERALMETRICTESTC_MSGEMEM );
      return GENERALMETRICTESTC_EMEM;
    }

  /* Position in parameter space (sky, frequency, spindowns) */
  in.position.system = COORDINATESYSTEM_EQUATORIAL;
  in.position.longitude = tevlambda->data[1] = ra_point;
  in.position.latitude = tevlambda->data[2] = dec_point;
  in.maxFreq = tevlambda->data[0] = f0;
  in.spindown = NULL;
  if( numSpindown > 0 ) {
    LALCreateVector( &status, &(in.spindown), numSpindown );
    if( status.statusCode ) {
      printf( "%s line %d: %s\n", __FILE__, __LINE__,
              GENERALMETRICTESTC_MSGEMEM );
      return GENERALMETRICTESTC_EMEM;
    }
    for( i=0; i<numSpindown; i++ ) {
      in.spindown->data[i] = 0;
      tevlambda->data[i+3] = 0;
    }
  }

  /* Detector site */
  if(detector==1)
    tevpulse.site = &lalCachedDetectors[LALDetectorIndexLHODIFF];
  if(detector==2)
    tevpulse.site = &lalCachedDetectors[LALDetectorIndexLLODIFF];
  if(detector==3)
    tevpulse.site = &lalCachedDetectors[LALDetectorIndexVIRGODIFF];
  if(detector==4)
    tevpulse.site = &lalCachedDetectors[LALDetectorIndexGEO600DIFF];
  if(detector==5)
    tevpulse.site = &lalCachedDetectors[LALDetectorIndexTAMA300DIFF];
  in.site = tevpulse.site;
  tevpulse.latitude = in.site->frDetector.vertexLatitudeRadians;
  tevpulse.longitude = in.site->frDetector.vertexLongitudeRadians;

  /* CoherentMetric constants */
  tevparam.constants = &tevpulse;
  tevparam.n = 1;
  tevparam.errors = 0;
  tevparam.start = 0; /* start time relative to epoch */
  tevpulse.t0 = 0.0;  /* spindown definition time relative to epoch */

  /* Fill in the fields tevpulse.tMidnight & tevpulse.tAutumn: */
  LALGetEarthTimes( &status, &tevpulse );
  if( status.statusCode )
    {
      printf( "%s line %d: %s\n", __FILE__, __LINE__,
              GENERALMETRICTESTC_MSGESUB );
      return GENERALMETRICTESTC_ESUB;
    }

   /* Read in ephemeris data from files: */
   eph = (EphemerisData *)LALMalloc(sizeof(EphemerisData));
   eph->ephiles.earthEphemeris = earth;
   eph->ephiles.sunEphemeris = sun;
   LALInitBarycenter( &status, eph );
   if( status.statusCode )
    {
      printf( "%s line %d: %s\n", __FILE__, __LINE__,
              GENERALMETRICTESTC_MSGESUB );
      return GENERALMETRICTESTC_ESUB;
    }
   tevpulse.ephemeris = eph;

   /* Choose CoherentMetric timing function */
   if( metric_code == 2 ) {
     tevpulse.t1 = LALTBaryPtolemaic;
     tevpulse.dt1 = LALDTBaryPtolemaic;
   }
   if( metric_code == 3 ) {
     tevpulse.t1 = LALTEphemeris;
     tevpulse.dt1 = LALDTEphemeris;
   }
   tevpulse.t2 = LALTSpin;
   tevpulse.dt2 = LALDTSpin;
   tevpulse.constants1 = &tevpulse;
   tevpulse.constants2 = &tevpulse;
   tevpulse.nArgs = 2;
   if( numSpindown > 0 ) {
     tevparam.dtCanon = LALDTComp;
   }
   else {
     if( metric_code == 2 )
       tevparam.dtCanon = LALDTBaryPtolemaic;
     if( metric_code == 3 )
       tevparam.dtCanon = LALDTEphemeris;
   }

   /* Evaluate metric components. */
   if(metric_code==1)
     {
       LALPtoleMetric( &status, metric, &in );
       if( status.statusCode )
	 {
	   printf( "%s line %d: %s\n", __FILE__, __LINE__,
		   GENERALMETRICTESTC_MSGESUB );
	   return GENERALMETRICTESTC_ESUB;
	 }
     }
   if(metric_code==2  || metric_code==3)
     {
       LALCoherentMetric( &status, metric, tevlambda, &tevparam );
       if( status.statusCode )
	 {
	   printf( "%s line %d: %s\n", __FILE__, __LINE__,
		   GENERALMETRICTESTC_MSGESUB );
	   return GENERALMETRICTESTC_ESUB;
	 }
     }

   /* Print metric. */
   printf("\nmetric (f0, alpha, delta, ...) at the requested point\n");
   for (j=0; j<=2+numSpindown; j++) {
     for (k=0; k<=j; k++)
       printf( "  %+.4e", metric->data[k+j*(j+1)/2] );
     printf("\n");
   }

   /* Print determinants. */
   determinant = metric->data[5]*metric->data[2] - pow(metric->data[4],2);
   printf( "\nSky-determinant %e\n", determinant );
   if( numSpindown == 1 ) {
     determinant = metric->data[2] * metric->data[5] * metric->data[9]
                 - metric->data[2] * metric->data[8] * metric->data[8]
                 + metric->data[4] * metric->data[8] * metric->data[7]
                 - metric->data[4] * metric->data[4] * metric->data[9]
                 + metric->data[7] * metric->data[4] * metric->data[8]
                 - metric->data[7] * metric->data[7] * metric->data[5];
     printf( "S&S determinant %e\n", determinant );
   }

   /* Project carrier frequency out of metric. */
   LALProjectMetric( &status, metric, 0 );
   if( status.statusCode )
     {
       printf( "%s line %d: %s\n", __FILE__, __LINE__,
	       GENERALMETRICTESTC_MSGESUB );
       return GENERALMETRICTESTC_ESUB;
     }

   /* Print projected metric. */
   printf("\nf-projected metric (alpha, delta, ...) at the requested point\n");
   for (j=1; j<=2+numSpindown; j++) {
     for (k=1; k<=j; k++)
       printf( "  %+.4e", metric->data[k+j*(j+1)/2] );
     printf( "\n" );
      }

   /* Print determinants. */
   determinant = metric->data[5]*metric->data[2] - pow(metric->data[4],2);
   printf( "\nSky-determinant %e\n", determinant );
   if( numSpindown == 1 ) {
     determinant = metric->data[2] * metric->data[5] * metric->data[9]
                 - metric->data[2] * metric->data[8] * metric->data[8]
                 + metric->data[4] * metric->data[8] * metric->data[7]
                 - metric->data[4] * metric->data[4] * metric->data[9]
                 + metric->data[7] * metric->data[4] * metric->data[8]
                 - metric->data[7] * metric->data[7] * metric->data[5];
     printf( "S&S determinant %e\n", determinant );
   }

  /* Here is the code that uses xmgrace with the -x option, */
  /* and outputs data to a file with the -t option. */
  if (grace || nongrace) {

    /* Take care of preliminaries. */
    if(grace)
      {
	pvc = popen( "xmgrace -pipe", "w" );
	if( !pvc )
	  {
	    printf( "%s line %d: %s\n", __FILE__, __LINE__,
		    GENERALMETRICTESTC_MSGESYS );
	    return GENERALMETRICTESTC_ESYS;
	  }
	fprintf( pvc, "@xaxis label \"Right ascension (degrees)\"\n" );
	fprintf( pvc, "@yaxis label \"Declination (degrees)\"\n" );
      }
    if(nongrace)
      {
	fnongrace = fopen( "nongrace.data", "w" );
	if( !fnongrace )
	  {
	    printf( "%s line %d: %s\n", __FILE__, __LINE__,
		    GENERALMETRICTESTC_MSGESYS );
	    return GENERALMETRICTESTC_ESYS;
	  }
      }

    /* Step around the sky: a grid in ra and dec. */
    j = 0;
    for (dec=dec_max; dec>=dec_min; dec-=10) {
      for (ra=ra_min; ra<=ra_max; ra+=15) {
        REAL8 gaa, gad, gdd, angle, smaj, smin;

        /* Get the metric at this ra, dec. */
        in.position.longitude = tevlambda->data[1] = ra*LAL_PI_180;
        in.position.latitude  = tevlambda->data[2] = dec*LAL_PI_180;

	/* Evaluate metric: */
	if(metric_code==1)
	  {
	    LALPtoleMetric( &status, metric, &in );
	    if( status.statusCode )
	      {
		printf( "%s line %d: %s\n", __FILE__, __LINE__,
			GENERALMETRICTESTC_MSGESUB );
		return GENERALMETRICTESTC_ESUB;
	      }
	  }
	if(metric_code==2  || metric_code==3)
	  {
	    LALCoherentMetric( &status, metric, tevlambda, &tevparam );
	    if( status.statusCode )
	      {
		printf( "%s line %d: %s\n", __FILE__, __LINE__,
			GENERALMETRICTESTC_MSGESUB );
		return GENERALMETRICTESTC_ESUB;
	      }
	  }

	/*  Project metric: */
	LALProjectMetric( &status, metric, 0 );
	if( status.statusCode )
	  {
          printf( "%s line %d: %s\n", __FILE__, __LINE__,
                  GENERALMETRICTESTC_MSGESUB );
          return GENERALMETRICTESTC_ESUB;
	  }
	determinant = metric->data[5]*metric->data[2]-pow(metric->data[4],2.0);
	if(determinant < 0.0)
	  {
	    printf( "%s line %d: %s\n", __FILE__, __LINE__,
		    GENERALMETRICTESTC_MSGEMET );
	    return GENERALMETRICTESTC_EMET;
	  }



        /* Rename \gamma_{\alpha\alpha}. */
        gaa = metric->data[2];
        /* Rename \gamma_{\alpha\delta}. */
        gad = metric->data[4];
        /* Rename \gamma_{\delta\delta}. */
        gdd = metric->data[5];
        /* Semiminor axis from larger eigenvalue of metric. */
        smin = gaa+gdd + sqrt( pow(gaa-gdd,2) + pow(2*gad,2) );
        smin = sqrt(2*mismatch/smin);
        /* Semiminor axis from smaller eigenvalue of metric. */
        smaj = gaa+gdd - sqrt( pow(gaa-gdd,2) + pow(2*gad,2) );
	/*printf("ra = %d, dec = %d, temp = %g\n", ra, dec, smaj);*/
        smaj = sqrt(2*mismatch/smaj);
        /* Angle of semimajor axis with "horizontal" (equator). */
        angle = atan2( gad, mismatch/smaj/smaj-gdd );
        if (angle <= -LAL_PI_2) angle += LAL_PI;
        if (angle > LAL_PI_2) angle -= LAL_PI;

        if(grace)
	  {
	    /* Print set header. */
	    fprintf( pvc, "@s%d color (0,0,0)\n", j );
	    fprintf( pvc, "@target G0.S%d\n@type xy\n", j++ );
	    /* Print center of patch. */
	    fprintf( pvc, "%16.8g %16.8g\n", (float)ra, (float)dec );
	  }
	if(nongrace)
	  /* Print center of patch. */
	  fprintf( fnongrace, "%16.8g %16.8g\n", (float)ra, (float)dec );
	/* Loop around patch ellipse. */
        for (i=0; i<=SPOKES; i++) {
          c_ellipse = LAL_TWOPI*i/SPOKES;
          r_ellipse = MAGNIFY*LAL_180_PI*smaj*smin /
	    sqrt( pow(smaj*sin(c_ellipse),2) + pow(smin*cos(c_ellipse),2) );
	  if(grace)
	    fprintf( pvc, "%e %e\n", ra+r_ellipse*cos(angle-c_ellipse),
		     dec+r_ellipse*sin(angle-c_ellipse) );
	  if(nongrace)
	    fprintf( fnongrace, "%e %e\n", ra+r_ellipse*cos(angle-c_ellipse),
		     dec+r_ellipse*sin(angle-c_ellipse) );

        } /* for (a...) */

      } /* for (ra...) */
    } /* for (dec...) */
    if(grace)
      fclose( pvc );
    if(nongrace)
      fclose( fnongrace );
  } /* if (grace || nongrace) */

  printf("\nCleaning up and leaving...\n");

  LALFree( eph->ephemE );
  if( status.statusCode )
  {
    printf( "%s line %d: %s\n", __FILE__, __LINE__,
            GENERALMETRICTESTC_MSGEMEM );
    return GENERALMETRICTESTC_EMEM;
  }
  LALFree( eph->ephemS );
  if( status.statusCode )
  {
    printf( "%s line %d: %s\n", __FILE__, __LINE__,
            GENERALMETRICTESTC_MSGEMEM );
    return GENERALMETRICTESTC_EMEM;
  }
 LALFree( eph );
 if( status.statusCode )
  {
    printf( "%s line %d: %s\n", __FILE__, __LINE__,
            GENERALMETRICTESTC_MSGEMEM );
    return GENERALMETRICTESTC_EMEM;
  }

  LALDDestroyVector( &status, &metric );
  if( status.statusCode )
  {
    printf( "%s line %d: %s\n", __FILE__, __LINE__,
            GENERALMETRICTESTC_MSGEMEM );
    return GENERALMETRICTESTC_EMEM;
  }
  LALDDestroyVector( &status, &tevlambda );
  if( status.statusCode )
  {
    printf( "%s line %d: %s\n", __FILE__, __LINE__,
            GENERALMETRICTESTC_MSGEMEM );
    return GENERALMETRICTESTC_EMEM;
  }
  if( in.spindown )
    LALDestroyVector( &status, &(in.spindown) );

  if( status.statusCode )
  {
    printf( "%s line %d: %s\n", __FILE__, __LINE__,
            GENERALMETRICTESTC_MSGEMEM );
    return GENERALMETRICTESTC_EMEM;
  }
  LALCheckMemoryLeaks();
  return 0;
} /* main() */
Пример #21
0
/**
 * \brief Computes the parameter space metric for a coherent pulsar search.
 * \author Creighton, T. D., Jolien Creighton
 * \date 2000 - 2003
 * \ingroup StackMetric_h
 *
 * This function computes the metric \f$g_{\alpha\beta}(\mathbf{\lambda})\f$, as
 * discussed in \ref StackMetric_h, under the assumption
 * that the search consists of scanning the Fourier power spectrum
 * constructed from a single time interval \f$\Delta t\f$.  The indecies
 * \f$\alpha\f$ and \f$\beta\f$ are assumed to run from 0 to \f$n\f$, where \f$n\f$ is
 * the total number of shape parameters.
 * The argument \c metric is normally a vector of length
 * \f$(n+1)(n+2)/2\f$ storing all non-redundant coefficients of
 * \f$g_{\alpha\beta}\f$.  The indexing scheme is as follows: Let us assume
 * that \f$\alpha\geq\beta\f$.  Then
 * \f$g_{\alpha\beta} = g_{\beta\alpha} = \f$metric->data[\f$\beta + \alpha(\alpha+1)/2]\f$.
 * If <tt>params->errors</tt> is nonzero, then \a *metric must be double
 * this length, and LALCoherentMetric() will store metric
 * components and their estimated uncertainty in alternate slots; i.e.
 * the metric component
 * \f$g_{\alpha\beta}=\f$metric->data[\f$2\beta+\alpha(\alpha+1)]\f$,
 * and the uncertainty
 * \f$s_{\alpha\beta}=\f$metric->data[\f$1+2\beta+\alpha(\alpha+1)]\f$.
 *
 * The argument \a lambda is another vector, of length \f$n+1\f$,
 * storing the components of \f$\mathbf{\lambda}=(\lambda^0,\ldots,\lambda^n)\f$
 * for the parameter space point at which the metric is being evaluated.
 * The argument \a *params stores the remaining parameters for
 * computing the metric, as given in the Structures section of StackMetric.h.
 *
 * ### Algorithm ###
 *
 * This routine simply computes the function given in \eqref{eq_gab_phi}
 * of \ref StackMetric_h.  Most of the work is done by the
 * function \a params->dtCanon(), which computes the value and
 * parameter derivatives of the canonical time coordinate
 * \f$\tau[t;\vec{\lambda}]\f$.  Since the phase function is simply
 * \f$\phi[t;\mathbf{\lambda}]=2\pi\lambda^0 \tau[t;\vec\lambda]\f$, where
 * \f$\lambda^0=f_0\f$, the metric components are simply:
 * \f{eqnarray}{
 * g_{00}(\mathbf{\lambda}) & = &
 * 4\pi^2\bigg\langle\!(\tau[t;\vec\lambda])^2\bigg\rangle -
 * 4\pi^2\bigg\langle\!\tau[t;\vec\lambda]\bigg\rangle^2 \; , \\
 * g_{i0}(\mathbf{\lambda}) \;\; = \;\;
 * g_{0i}(\mathbf{\lambda}) & = &
 * 4\pi^2 f_0\bigg\langle\!
 * \tau[t;\vec\lambda]
 * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i}
 * \bigg\rangle
 * -
 * 4\pi^2 f_0\bigg\langle\!
 * \tau[t;\vec\lambda]
 * \bigg\rangle
 * \bigg\langle
 * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i}
 * \bigg\rangle \; ,\\
 * g_{ij}(\mathbf{\lambda}) & = &
 * 4\pi^2 f_0^2\bigg\langle
 * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i}
 * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^j}
 * \bigg\rangle
 * -
 * 4\pi^2 f_0^2\bigg\langle
 * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^i}
 * \bigg\rangle
 * \bigg\langle
 * \frac{\partial\tau[t;\vec\lambda]}{\partial\lambda^j}
 * \bigg\rangle \; ,
 * \f}
 * where the indecies \f$i\f$ and \f$j\f$ run from 1 to \f$n\f$.
 *
 * In the rigorous definition of the metric, the angle brackets denote an
 * average over the \em canonical time, not the detector time, so we have:
 * \f{eqnarray}{
 * \bigg\langle\ldots\bigg\rangle
 * & = & \frac{1}{\tau(t_\mathrm{start}+\Delta t)-\tau(t_\mathrm{start})}
 * \int_{\tau(t_\mathrm{start})}^{\tau(t_\mathrm{start}+\Delta t)}
 * \ldots\,d\tau\\
 * & = & \frac{1}{\tau(t_\mathrm{start}+\Delta t)-\tau(t_\mathrm{start})}
 * \int_{t_\mathrm{start}}^{t_\mathrm{start}+\Delta t}
 * \ldots\frac{\partial\tau}{\partial t}\,dt\\
 * & \approx & \frac{1}{\Delta t}
 * \int_{t_\mathrm{start}}^{t_\mathrm{start}+\Delta t}
 * \ldots\,dt \; ,
 * \f}
 * where the approximation is good to order \f$\epsilon\f$ equal to the
 * maximum difference between 1 and \f$\partial\tau/\partial t\f$.  For an
 * Earth-motion barycentred time coordinate, for instance, \f$\epsilon\f$ is
 * of order \f$10^{-4}\f$ and the approximation is quite good.  However, the
 * current implementation of the metric algorithm uses the second, exact
 * formula.  If speed considerations become important, this is one
 * obvious area for simplification.
 *
 * At present, the time averaging is performed by evaluating \f$\tau\f$ and
 * its derivatives at equally-spaced points over \f$\Delta t\f$ and applying
 * a trapezoidal method; i.e.
 * \f[
 * \frac{1}{T}\int_0^T F(t)\,dt \approx \frac{1}{N}\left(\frac{1}{2}F_0
 * + F_1 + F_2 + \ldots + F_{N-1} + \frac{1}{2}F_N \right) \; ,
 * \f]
 * where \f$F_k=F(kT/N)\f$ are the \f$N+1\f$ sample points of the integrand.  The
 * number of points is a compiled-in constant.  The error is on the order
 * of \f$F''T^2/N^2\f$, where \f$F''\f$ is the second derivative of \f$F(t)\f$ at
 * some point in the interval; we liberally estimate the error to be:
 * \f[
 * \sigma = \max_{k\in\{1,\ldots,N-1\}}
 * \left\{F_{k-1} - 2F_k + F_{k+1}\right\} \; .
 * \f]
 * Other more sophisticated integration techniques may be considered in
 * future.  To save on recomputing costs, the derivatives of \f$\tau\f$ at
 * all times are stored in a large vector sequence.
 */
void
LALCoherentMetric( LALStatus        *stat,
		   REAL8Vector      *metric,
		   REAL8Vector      *lambda,
		   MetricParamStruc *params )
{
  UINT4 s = 0;      /* The number of parameters. */
  UINT4 i, j, k, l; /* Indecies. */
  REAL8 dt;         /* The sampling interval, in s. */
  REAL8 f0;         /* The frequency scale, lambda->data[0]. */
  REAL8 *data;      /* Multipurpose pointer to vector data. */
  REAL8Vector *a=NULL;  /* Data for the first time average. */
  REAL8Vector *b=NULL;  /* Data for the second time average. */
  REAL8Vector *c=NULL;  /* Data for the third time average. */
  REAL8Vector d;        /* Temporary variable. */
  REAL8Vector *variables=NULL;    /* Input to time function. */
  REAL8VectorSequence *dSeq=NULL; /* Phase derivatives. */
  CreateVectorSequenceIn in; /* Input structure. */
  PulsarTimesParamStruc *constants; /* Timing constants. */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR(stat);

  /* Make sure parameter structures and their fields exist. */
  ASSERT(metric,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);
  ASSERT(metric->data,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);
  ASSERT(lambda,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);
  ASSERT(lambda->data,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);
  ASSERT(params,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);
  ASSERT(params->dtCanon,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);

  /* Make sure parameters are valid. */
  s=lambda->length;
  ASSERT(s,stat,STACKMETRICH_EBAD,STACKMETRICH_MSGEBAD);
  if(params->errors)
  {
    ASSERT(metric->length==s*(s+1),stat,STACKMETRICH_EBAD,
	   STACKMETRICH_MSGEBAD);
  }
  else
  {
    ASSERT(metric->length==(s*(s+1))>>1,stat,STACKMETRICH_EBAD,
	   STACKMETRICH_MSGEBAD);
  }
  ASSERT(params->n==1,stat,STACKMETRICH_EBAD,
	 STACKMETRICH_MSGEBAD);

  /* Set vector sequence creation structure, and compute sampling
     rate. */
  in.vectorLength=s+1;
  in.length=COHERENTMETRICC_NPTS;
  dt=params->deltaT/(COHERENTMETRICC_NPTS-1.0);

  /* Create temporary storage. */
  TRY(LALDCreateVector(stat->statusPtr,&a,COHERENTMETRICC_NPTS),stat);
  LALDCreateVector(stat->statusPtr,&b,COHERENTMETRICC_NPTS);
  BEGINFAIL(stat)
    TRY(LALDDestroyVector(stat->statusPtr,&a),stat);
  ENDFAIL(stat);
  LALDCreateVector(stat->statusPtr,&c,COHERENTMETRICC_NPTS);
  BEGINFAIL(stat) {
    TRY(LALDDestroyVector(stat->statusPtr,&a),stat);
    TRY(LALDDestroyVector(stat->statusPtr,&b),stat);
  } ENDFAIL(stat);
  LALDCreateVectorSequence(stat->statusPtr,&dSeq,&in);
  BEGINFAIL(stat) {
    TRY(LALDDestroyVector(stat->statusPtr,&a),stat);
    TRY(LALDDestroyVector(stat->statusPtr,&b),stat);
    TRY(LALDDestroyVector(stat->statusPtr,&c),stat);
  } ENDFAIL(stat);
  LALDCreateVector(stat->statusPtr,&variables,s);
  BEGINFAIL(stat) {
    TRY(LALDDestroyVector(stat->statusPtr,&a),stat);
    TRY(LALDDestroyVector(stat->statusPtr,&b),stat);
    TRY(LALDDestroyVector(stat->statusPtr,&c),stat);
    TRY(LALDDestroyVectorSequence(stat->statusPtr,&dSeq),stat);
  } ENDFAIL(stat);

  /* Set up passing structure for the canonical time function. */
  memcpy(variables->data,lambda->data,s*sizeof(REAL8));
  *(variables->data)=params->start;
  f0=lambda->data[0];
  constants=params->constants;
  d.length=s+1;
  d.data=dSeq->data;
  l=COHERENTMETRICC_NPTS;

  /* Compute canonical time and its derivatives. */
  while(l--){
    (params->dtCanon)(stat->statusPtr,&d,variables,constants);
    BEGINFAIL(stat) {
      TRY(LALDDestroyVector(stat->statusPtr,&a),stat);
      TRY(LALDDestroyVector(stat->statusPtr,&b),stat);
      TRY(LALDDestroyVector(stat->statusPtr,&c),stat);
      TRY(LALDDestroyVectorSequence(stat->statusPtr,&dSeq),stat);
      TRY(LALDDestroyVector(stat->statusPtr,&variables),stat);
    } ENDFAIL(stat);
    *(variables->data)+=dt;
    d.data+=s+1;
  }

  /* Compute the overall correction factor to convert the canonical
     time interval into the detector time interval. */
#ifndef APPROXIMATE
  dt=params->deltaT/(dSeq->data[(s+1)*(COHERENTMETRICC_NPTS-1)]
		     - dSeq->data[0]);
#else
  dt=1.0;
#endif

  /* Compute metric components.  First generate the g00 component. */
  /* Fill integrand arrays. */
  data=dSeq->data+1;
  l=COHERENTMETRICC_NPTS;
  k=0;
  while(l--){
#ifndef APPROXIMATE
    a->data[l]=*data*data[-1]*data[-1];
    b->data[l]=c->data[l]=*data*data[-1];
#else
    a->data[l]=data[-1]*data[-1];
    b->data[l]=c->data[l]=data[-1];
#endif
    data+=s+1;
  }
  /* Integrate to get the metric component. */
  if(params->errors){
    REAL8 aErr=0,bErr=0,cErr=0;
    REAL8 aAvg=Average(a,&aErr);
    REAL8 bAvg=Average(b,&bErr);
    REAL8 cAvg=Average(c,&cErr);
    metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*(aAvg-dt*bAvg*cAvg);
    metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*
      (aErr + dt*bErr*fabs(cAvg) + dt*cErr*fabs(bAvg));
  }else
    metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*
      (Average(a,0)-dt*Average(b,0)*Average(c,0));

  for(i=1;i<s;i++){
    /* Now generate the gi0 components. */
    /* Fill integrand arrays. */
    data=dSeq->data+1;
    l=COHERENTMETRICC_NPTS;
    while(l--){
#ifndef APPROXIMATE
      a->data[l]=*data*data[-1]*f0*data[i];
      b->data[l]=*data*data[-1];
      c->data[l]=*data*f0*data[i];
#else
      a->data[l]=data[-1]*f0*data[i];
      b->data[l]=data[-1];
      c->data[l]=f0*data[i];
#endif
      data+=s+1;
    }
    /* Integrate to get the metric component. */
    if(params->errors){
      REAL8 aErr=0,bErr=0,cErr=0;
      REAL8 aAvg=Average(a,&aErr);
      REAL8 bAvg=Average(b,&bErr);
      REAL8 cAvg=Average(c,&cErr);
      metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*(aAvg-dt*bAvg*cAvg);
      metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*
	(aErr + dt*bErr*fabs(cAvg) + dt*cErr*fabs(bAvg));
    }else
      metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*
	(Average(a,0)-dt*Average(b,0)*Average(c,0));

    for(j=1;j<=i;j++){
      /* Now generate the gij components. */
      /* Fill integrand arrays. */
      data=dSeq->data+1;
      l=COHERENTMETRICC_NPTS;
      while(l--){
#ifndef APPROXIMATE
	a->data[l]=*data*f0*f0*data[i]*data[j];
	b->data[l]=*data*f0*data[i];
	c->data[l]=*data*f0*data[j];
#else
	a->data[l]=f0*f0*data[i]*data[j];
	b->data[l]=f0*data[i];
	c->data[l]=f0*data[j];
#endif
	data+=s+1;
      }
      /* Integrate to get the metric component. */
      if(params->errors){
	REAL8 aErr=0,bErr=0,cErr=0;
	REAL8 aAvg=Average(a,&aErr);
	REAL8 bAvg=Average(b,&bErr);
	REAL8 cAvg=Average(c,&cErr);
	metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*(aAvg-dt*bAvg*cAvg);
	metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*
	  (aErr + dt*bErr*fabs(cAvg) + dt*cErr*fabs(bAvg));
      }else
	metric->data[k++]=LAL_TWOPI*LAL_TWOPI*dt*
	  (Average(a,0)-dt*Average(b,0)*Average(c,0));
    }
  }

  /* Destroy temporary storage, and exit. */
  TRY(LALDDestroyVector(stat->statusPtr,&a),stat);
  TRY(LALDDestroyVector(stat->statusPtr,&b),stat);
  TRY(LALDDestroyVector(stat->statusPtr,&c),stat);
  TRY(LALDDestroyVectorSequence(stat->statusPtr,&dSeq),stat);
  TRY(LALDDestroyVector(stat->statusPtr,&variables),stat);
  DETATCHSTATUSPTR(stat);
  RETURN(stat);
}
Пример #22
0
void
LALExtractFrameResponse(LALStatus * status,
    COMPLEX8FrequencySeries * output,
    LALCache * calCache, CalibrationUpdateParams * calfacts)
{
    const LALUnit strainPerCount =
        { 0, {0, 0, 0, 0, 0, 1, -1}, {0, 0, 0, 0, 0, 0, 0} };

    LALCache *refCache = NULL;
    LALCache *facCache = NULL;
    LALFrStream *refStream = NULL;
    LALFrStream *facStream = NULL;
    FrChanIn frameChan;
    LALFrStreamPos facPos;

    CHAR facDsc[LALNameLength];
    CHAR channelName[LALNameLength];

    COMPLEX8FrequencySeries R0;
    COMPLEX8FrequencySeries C0;
    COMPLEX8TimeSeries ab;
    COMPLEX8TimeSeries a;
    /*
     * COMPLEX8Vector                abVec;
     * COMPLEX8Vector                aVec;
     * COMPLEX8                      abData;
     * COMPLEX8                      aData;
     */
    CalibrationFunctions calfuncs;

    LIGOTimeGPS seekEpoch;
    UINT4 length;
    REAL8 duration_real;
    const REAL8 fuzz = 0.1 / 16384.0;

    INITSTATUS(status);
    ATTATCHSTATUSPTR(status);

    ASSERT(output, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(output->data, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(output->data->data, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(calCache, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(calfacts, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(calfacts->ifo, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(crealf(calfacts->alpha) == 0, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(cimagf(calfacts->alpha) == 0, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(crealf(calfacts->alphabeta) == 0, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);
    ASSERT(cimagf(calfacts->alphabeta) == 0, status,
        FRAMECALIBRATIONH_ENULL, FRAMECALIBRATIONH_MSGENULL);

    /*
     *
     * set up and clear the structures to hold the input data
     *
     */

    memset(&R0, 0, sizeof(COMPLEX8FrequencySeries));
    memset(&C0, 0, sizeof(COMPLEX8FrequencySeries));
    memset(&ab, 0, sizeof(COMPLEX8TimeSeries));
    memset(&a, 0, sizeof(COMPLEX8TimeSeries));
    memset(&calfuncs, 0, sizeof(CalibrationFunctions));

    calfuncs.responseFunction = &R0;
    calfuncs.sensingFunction = &C0;
    calfacts->openLoopFactor = &ab;
    calfacts->sensingFactor = &a;
    calfacts->epoch = output->epoch;
    frameChan.name = channelName;

    /*
     *
     * get the reference calibration and cavity gain frequency series
     *
     */

    /* sieve the calibration cache for the reference frame */
    refCache = XLALCacheDuplicate(calCache);
    XLALCacheSieve(refCache, 0, 0, NULL, REF_TYPE, NULL);
    if (!refCache->length) {
        /* if we don't have a reference calibration, we can't do anything */
        XLALDestroyCache(refCache);
        ABORT(status, FRAMECALIBRATIONH_ECREF, FRAMECALIBRATIONH_MSGECREF);
    }

    /* open the reference calibration frame */
    LALFrCacheOpen(status->statusPtr, &refStream, refCache);
    if (status->statusPtr->statusCode) {
        /* if we don't have a reference calibration, we can't do anything */
        XLALDestroyCache(refCache);
        ABORT(status, FRAMECALIBRATIONH_EOREF, FRAMECALIBRATIONH_MSGEOREF);
    }
    XLALDestroyCache(refCache);
    if (status->statusPtr->statusCode) {
        TRY(LALFrClose(status->statusPtr, &refStream), status);
        ABORT(status, FRAMECALIBRATIONH_EDCHE, FRAMECALIBRATIONH_MSGEDCHE);
    }

    /* read in the frequency series for the reference calbration */
    snprintf(channelName, LALNameLength * sizeof(CHAR),
        "%s:" RESPONSE_CHAN, calfacts->ifo);
    LALFrGetCOMPLEX8FrequencySeries(status->statusPtr,
        &R0, &frameChan, refStream);
    if (status->statusCode) {
        /* if we don't have a reference calibration, we can't do anything */
        XLALDestroyCache(refCache);
        ABORT(status, FRAMECALIBRATIONH_EREFR, FRAMECALIBRATIONH_MSGEREFR);
    }

    /* read in the reference cavity gain frequency series */
    snprintf(channelName, LALNameLength * sizeof(CHAR),
        "%s:" CAV_GAIN_CHAN, calfacts->ifo);
    LALFrGetCOMPLEX8FrequencySeries(status->statusPtr,
        &C0, &frameChan, refStream);
    BEGINFAIL(status) {
        /* no cavity gain response to update point cal */
        XLALDestroyCache(refCache);
        TRY(LALFrClose(status->statusPtr, &refStream), status);
        RETURN_POINT_CAL;
    }
    ENDFAIL(status);

    LALFrClose(status->statusPtr, &refStream);
    BEGINFAIL(status) {
        RETURN_POINT_CAL;
    }
    ENDFAIL(status);

    /*
     *
     * get the factors necessary to update the reference calibration
     *
     */

    /* try and get some update factors. first we try to get a cache  */
    /* containing sensemon frames. if that fails, try the S1 type    */
    /* calibration data, otherwise just return the point calibration */
    do {
        /* try and get sensemon frames */
        snprintf(facDsc, LALNameLength * sizeof(CHAR), SENSEMON_FAC_TYPE);
        facCache = XLALCacheDuplicate(calCache);
        XLALCacheSieve(facCache, 0, 0, NULL, facDsc, NULL);
        if (!facCache) {
            RETURN_POINT_CAL;
        }

        if (facCache->length) {
            /* sensemon stores fac times series as real_8 adc trend data */
            REAL8TimeSeries sensemonTS;
            REAL8 alphaDeltaT;
            UINT4 i;

            memset(&sensemonTS, 0, sizeof(REAL8TimeSeries));

            OPEN_FAC;

            snprintf(channelName, LALNameLength * sizeof(CHAR),
                "%s:" CAV_FAC_CHAN ".mean", calfacts->ifo);

            /* get the sample rate of the alpha channel */
            LALFrGetREAL8TimeSeries(status->statusPtr,
                &sensemonTS, &frameChan, facStream);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* determine number of calibration points required */
            duration_real = XLALGPSGetREAL8(&(calfacts->duration));
            length = (UINT4) ceil(duration_real / sensemonTS.deltaT);
            ++length;

            /* make sure we get the first point before the requested cal time */
            alphaDeltaT = sensemonTS.deltaT;
            seekEpoch = output->epoch;
            XLALGPSAdd(&seekEpoch, fuzz - sensemonTS.deltaT);
            sensemonTS.epoch = seekEpoch;

            GET_POS;

            /* create memory for the alpha values */
            LALDCreateVector(status->statusPtr, &(sensemonTS.data), length);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* get the alpha values */
            LALFrGetREAL8TimeSeries(status->statusPtr,
                &sensemonTS, &frameChan, facStream);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            LALCCreateVector(status->statusPtr, &(a.data), length);
            BEGINFAIL(status) {
                TRY(LALDDestroyVector(status->statusPtr, &(sensemonTS.data)),
                    status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            for (i = 0; i < length; ++i) {
                a.data->data[i] = crectf( (REAL4) sensemonTS.data->data[i], 0 );
            }
            a.epoch = sensemonTS.epoch;
            a.deltaT = sensemonTS.deltaT;
            strncpy(a.name, sensemonTS.name, LALNameLength);

            LALFrSetPos(status->statusPtr, &facPos, facStream);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* get the alpha*beta values */
            snprintf(channelName, LALNameLength * sizeof(CHAR),
                "%s:" OLOOP_FAC_CHAN ".mean", calfacts->ifo);
            LALFrGetREAL8TimeSeries(status->statusPtr,
                &sensemonTS, &frameChan, facStream);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* check that alpha and alpha*beta have the same sample rate */
            if (fabs(alphaDeltaT - sensemonTS.deltaT) > LAL_REAL8_EPS) {
                TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
                ABORT(status, FRAMECALIBRATIONH_EDTMM,
                    FRAMECALIBRATIONH_MSGEDTMM);
            }

            LALCCreateVector(status->statusPtr, &(ab.data), length);
            BEGINFAIL(status) {
                TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status);
                TRY(LALDDestroyVector(status->statusPtr, &(sensemonTS.data)),
                    status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            for (i = 0; i < length; ++i) {
                ab.data->data[i] = crectf( (REAL4) sensemonTS.data->data[i], 0 );
            }
            ab.epoch = sensemonTS.epoch;
            ab.deltaT = sensemonTS.deltaT;
            strncpy(ab.name, sensemonTS.name, LALNameLength);

            /* destroy the sensemonTS.data */
            LALDDestroyVector(status->statusPtr, &(sensemonTS.data));
            CHECKSTATUSPTR(status);
            break;
        }

        /* destroy the empty frame cache and try again */
        XLALDestroyCache(facCache);

        /* try and get the the factors from lalapps_mkcalfac frames */
        facCache = XLALCacheDuplicate(calCache);
        XLALCacheSieve(facCache, 0, 0, NULL, FAC_TYPE, NULL);
        if (!facCache) {
            RETURN_POINT_CAL;
        }

        if (facCache->length) {
            /* the lalapps frames are complex_8 proc data */
            OPEN_FAC;

            snprintf(channelName, LALNameLength * sizeof(CHAR),
                "%s:" CAV_FAC_CHAN, calfacts->ifo);

            /* get the sample rate of the alpha channel */
            LALFrGetCOMPLEX8TimeSeries(status->statusPtr,
                &a, &frameChan, facStream);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* determine number of calibration points required */
            duration_real = XLALGPSGetREAL8(&(calfacts->duration));
            length = (UINT4) ceil(duration_real / a.deltaT);
            ++length;

            /* make sure we get the first point before the requested cal time */
            seekEpoch = output->epoch;
            XLALGPSAdd(&seekEpoch, fuzz - a.deltaT);
            a.epoch = ab.epoch = seekEpoch;

            GET_POS;

            /* create storage for the alpha values */
            LALCCreateVector(status->statusPtr, &(a.data), length);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* get the alpha values */
            LALFrGetCOMPLEX8TimeSeries(status->statusPtr,
                &a, &frameChan, facStream);
            BEGINFAIL(status) {
                TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            LALFrSetPos(status->statusPtr, &facPos, facStream);
            BEGINFAIL(status) {
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* create storage for the alpha*beta values */
            LALCCreateVector(status->statusPtr, &(ab.data), length);
            BEGINFAIL(status) {
                TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* get the alpha*beta values */
            snprintf(channelName, LALNameLength * sizeof(CHAR),
                "%s:" OLOOP_FAC_CHAN, calfacts->ifo);
            LALFrGetCOMPLEX8TimeSeries(status->statusPtr,
                &ab, &frameChan, facStream);
            BEGINFAIL(status) {
                TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status);
                TRY(LALCDestroyVector(status->statusPtr, &(ab.data)), status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
            }
            ENDFAIL(status);

            /* check that alpha and alpha*beta have the same sample rate */
            if (fabs(a.deltaT - ab.deltaT) > LAL_REAL8_EPS) {
                TRY(LALCDestroyVector(status->statusPtr, &(a.data)), status);
                TRY(LALCDestroyVector(status->statusPtr, &(ab.data)), status);
                TRY(LALFrClose(status->statusPtr, &facStream), status);
                RETURN_POINT_CAL;
                ABORT(status, FRAMECALIBRATIONH_EDTMM,
                    FRAMECALIBRATIONH_MSGEDTMM);
            }

            break;
        }
Пример #23
0
/**
 * \author Sintes, A. M.
 *
 * \brief Gets data cleaned from line harmonic interference given  a time domain reference signal.
 *
 * ### Description ###
 *
 * This routine cleans data in the time domain from line harmonic interference
 * (from the first harmonic up to the Nyquist frequency). The inputs are:
 *
 * <tt>*in1</tt> the time domain data of type  \c REAL4TVectorCLR,
 * containing also the interference fundamental frequency \f$f_0\f$ and the
 * sampling spacing. This information is needed in order to obtain
 * the total  number of harmonics contained in the data.
 * <dl>
 * <dt><tt>in1->length</tt></dt><dd> The number of elements in <tt>in1->data</tt> \f$=n\f$.</dd>
 * <dt><tt>in1->data</tt></dt><dd>   The (real) time domain data,  \f$x(t)\f$.</dd>
 * <dt><tt>in1->deltaT</tt></dt><dd> The sample spacing in seconds.</dd>
 * <dt><tt>in1->fLine</tt></dt><dd>  The interference fundamental frequency \f$f_0\f$
 * (in Hz), e.g., 60 Hz.</dd>
 * </dl>
 *
 * <tt>*in2</tt> the time domain reference signal (a complex vector).
 * <dl>
 * <dt><tt>in2->length</tt></dt><dd> The number of elements in
 * <tt>in2->data</tt> \f$=n\f$.</dd>
 * <dt><tt>in2->data</tt></dt><dd>    The \f$M(t)\f$ complex data.</dd>
 * </dl>
 *
 * The output <tt>*out</tt> is a real vector containing the clean data.
 * <dl>
 * <dt><tt>out->length</tt></dt><dd> The number of elements in
 * <tt>out->data</tt> \f$=n\f$.</dd>
 * <dt><tt>out->data</tt></dt><dd>    The clean (real) time domain data.</dd>
 * </dl>
 *
 * ### Algorithm ###
 *
 * It takes the reference signal \f$M(t)\f$ and, for all possible harmonics
 * \f$j\f$
 * (\f$j=1,\ldots,\f$<tt>floor(1.0/fabs( 2.02* in1->deltaT * in1->fLine))</tt> ),
 * from the fundamental frequency up to the Nyquist frequency,
 * constructs \f$M(t)^j\f$,  performs a least-squares fit, i.e.,
 * minimizes the power \f$\vert x(t) -\rho_j M(t)^j\vert^2\f$ with
 * respect to \f$\rho_j\f$, and  subtracts \f$\rho_j M(t)^j\f$ from the
 * original data, \f$x(t)\f$.
 */
void LALCleanAll (LALStatus     *status,/**< LAL status pointer */
               REAL4Vector      *out,  /**< clean data */
               COMPLEX8Vector   *in2,  /**< M(t), ref. interference */
               REAL4TVectorCLR  *in1)  /**< x(t), data + information */
{

  INT4    n;
  INT4    i,j;
  INT4    maxH;


  REAL4      *x;
  REAL4      *xc;
  COMPLEX8   *m;

  COMPLEX16  rho,rhon;
  REAL8      rhod;
  REAL8      mr,mi;
  REAL8      amj,phj;

  COMPLEX16Vector *mj    = NULL;
  REAL8Vector     *ampM2 = NULL;
  REAL8Vector     *phaM  = NULL;

/* --------------------------------------------- */

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  /*   Make sure the arguments are not NULL: */
  ASSERT (out, status, CLRH_ENULL, CLRH_MSGENULL);
  ASSERT (in1, status, CLRH_ENULL, CLRH_MSGENULL);
  ASSERT (in2, status, CLRH_ENULL, CLRH_MSGENULL);

  /*   Make sure the data pointers are not NULL: */
  ASSERT (out->data, status, CLRH_ENULL, CLRH_MSGENULL);
  ASSERT (in1->data, status, CLRH_ENULL, CLRH_MSGENULL);
  ASSERT (in2->data, status, CLRH_ENULL, CLRH_MSGENULL);

  /*   Make sure that the size is correct:  */
  ASSERT (out->length > 0, status, CLRH_ESIZE, CLRH_MSGESIZE);

  /*   Make sure that the lengths are correct (size mismatch): */
  ASSERT (in1->length == out->length, status, CLRH_ESZMM, CLRH_MSGESZMM);
  ASSERT (in2->length == out->length, status, CLRH_ESZMM, CLRH_MSGESZMM);

  /*   Make sure the arguments are not pointing to the same memory location */
  /*   ASSERT (out != in2, status, CLRH_ESAME, CLRH_MSGESAME); */

  /*   Make sure F_Nyquist > fLine  */
  ASSERT (fabs(in1->deltaT * in1->fLine) < 0.495,
                status, CLRH_EFREQ, CLRH_MSGEFREQ);

  /* margin 0.495 and not 0.5 in order to avoid errors */


  /* -------------------------------------------   */

  n  = out->length;
  m  = in2->data;
  x  = in1->data;
  xc = out->data;

  /* -------------------------------------------   */
  /*     Removing the fundamental harmonic         */
  /* -------------------------------------------   */

  rhon = 0.0;
  rhod    = 0.0;

  for (i=0; i<n; ++i) {
    mr = crealf(m[i]);
    mi = cimagf(m[i]);

    rhon += crect( x[i]*mr, -x[i]*mi );
    rhod    +=  mr*mr + mi*mi;
  }

  rho = (rhon / ((REAL8) rhod));

  for (i=0; i<n; ++i) {
    xc[i] = x[i] - 2.0*(creal(rho) * crealf(m[i]) - cimag(rho) * cimagf(m[i]) );
  }


  /* -------------------------------------------   */
  /*     Removing the other harmonics              */
  /* -------------------------------------------   */

  maxH= floor(1.0/fabs( 2.02* in1->deltaT * in1->fLine));

  if (maxH > 1) /* in case there are more harmonics */
  {

    /* Create Vectors amplitude and phase m(t) */
    TRY(LALDCreateVector(status->statusPtr, &ampM2, n), status);
    TRY(LALDCreateVector(status->statusPtr, &phaM,  n), status);
    /* reserve space for m^j(t) */
    TRY(LALZCreateVector(status->statusPtr, &mj  ,n), status);

    for (i=0; i<n; ++i) {
      /* calculation of amplitude^2 and phase of m(t)  */
      mr = crealf(m[i]);
      mi = cimagf(m[i]);

      ampM2->data[i] = mr*mr+ mi*mi;

      if( ampM2->data[i] < LAL_REAL4_MIN)
        {  phaM->data[i] = 0.0; /* to avoid NaN */ }
      else
        {  phaM->data[i] = atan2(mi,mr);  }
    }

    for(j=2; j<= maxH; ++j) {
      rhon = 0.0;
      rhod    = 0.0;

      for (i=0; i<n; ++i) {
	/* calculation of m^j(t) for a fixed t */
	amj = pow( ampM2->data[i], 0.5*j);
	phj = j * phaM->data[i];
	mj->data[i] = crect( amj * cos(phj), amj * sin(phj) );
	mr =  creal(mj->data[i]);
	mi =  cimag(mj->data[i]);

	rhon += crect( xc[i]*mr, -xc[i]*mi );
	rhod    +=  mr*mr + mi*mi;
      }

      rho = (rhon / ((REAL8) rhod));

     for (i=0; i<n; ++i) {
       xc[i] += - 2.0*(creal(rho) * creal(mj->data[i]) - cimag(rho) * cimag(mj->data[i]) );
     }

    } /* closes for all harmonics */

    /* Destroy Vectors  */
    TRY(LALDDestroyVector(status->statusPtr, &ampM2), status);
    TRY(LALDDestroyVector(status->statusPtr, &phaM), status);
    TRY(LALZDestroyVector(status->statusPtr, &mj), status);

  } /* closes if */

  /* -------------------------------------------   */

  DETATCHSTATUSPTR (status);

  /* normal exit */
  RETURN (status);
}
Пример #24
0
int
main(int argc, char **argv)
{
  /* Variables for parsing command-line arguments. */
  INT4  arg;               /* argument list counter */
  CHAR *metricfile = NULL; /* metric output filename */
  CHAR *rangefile = NULL;  /* parameter range output filename */
  UINT4 n = NSTACKS;       /* number of stacks */
  REAL8 dt = STACKLENGTH;  /* length of each stack (s) */
  REAL8 t0 = STARTTIME;    /* start time of first stack (GPS s) */
  REAL8 f0 = FREQUENCY;    /* maximum frequency of search */
  REAL8 lat = LATITUDE;    /* latitude of detector (degrees N) */
  REAL8 lon = LONGITUDE;   /* longitude of detector (degrees E) */
  REAL8 ra[2], dec[2];     /* RA and dec ranges (degrees) */

  /* Other variables. */
  UINT4 i, j, k;                 /* indecies */
  UINT4 nRA, nDec;               /* sizes of metric grid in RA and dec */
  REAL8 dRA, dDec;               /* grid intervals in RA and dec */
  UINT4 warnings = 0;            /* points with large uncertainties */
  UINT4 errors = 0;              /* points with bad metrics */
  static LALStatus stat;         /* top-level status structure */
  static LIGOTimeGPS start;      /* GPS start time of first stack */
  REAL4Grid *metricGrid = NULL;  /* grid of metric values */
  REAL4 *gData;                  /* pointer to metricGrid->data->data */
  REAL4Grid *rangeGrid = NULL;   /* grid of range delimiters */
  REAL4 *rData;                  /* pointer to rangeGrid->data->data */
  REAL4 propVol = 0.0;           /* average proper volume element */
  UINT4 nVol = 0;                /* number of points used in average */
  UINT4Vector *dimLength = NULL; /* used to allocate metricGrid */
  REAL8Vector *lambda = NULL;    /* metric parameter space vector */
  REAL8Vector *metric = NULL;    /* metric components */
  REAL8 *mData;                  /* pointer to metric->data */
  INT4 *topRange, *botRange;     /* preliminary grid range limits */
  INT4 *topRange2, *botRange2;   /* adjusted grid range limits */
  static MetricParamStruc params; /* metric computation parameters */
  static PulsarTimesParamStruc baryParams; /* barycentring parameters */


  /* Some more initializations. */
  ra[0] = RA_MIN; dec[0] = DEC_MIN;
  ra[1] = RA_MAX; dec[1] = DEC_MAX;

  /******************************************************************
   * ARGUMENT PARSING                                               *
   ******************************************************************/

  /* Parse argument list.  arg stores the current position. */
  arg = 1;
  while ( arg < argc ) {
    /* Parse output file option. */
    if ( !strcmp( argv[arg], "-o" ) ) {
      if ( argc > arg + 2 ) {
	arg++;
	metricfile = argv[arg++];
	rangefile = argv[arg++];
      } else {
	ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 );
        XLALPrintError( USAGE, *argv );
        return SKYMETRICTESTC_EARG;
      }
    }
    /* Parse search parameter option. */
    else if ( !strcmp( argv[arg], "-p" ) ) {
      if ( argc > arg + 4 ) {
	arg++;
	n = atoi( argv[arg++] );
	dt = atof( argv[arg++] );
	t0 = atof( argv[arg++] );
	f0 = atof( argv[arg++] );
      } else {
	ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 );
        XLALPrintError( USAGE, *argv );
        return SKYMETRICTESTC_EARG;
      }
    }
    /* Parse detector position option. */
    else if ( !strcmp( argv[arg], "-l" ) ) {
      if ( argc > arg + 2 ) {
	arg++;
	lat = atof( argv[arg++] );
	lon = atof( argv[arg++] );
      } else {
	ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 );
        XLALPrintError( USAGE, *argv );
        return SKYMETRICTESTC_EARG;
      }
    }
    /* Parse parameter space range option. */
    else if ( !strcmp( argv[arg], "-r" ) ) {
      if ( argc > arg + 4 ) {
	arg++;
	ra[0] = atof( argv[arg++] );
	ra[1] = atof( argv[arg++] );
	dec[0] = atof( argv[arg++] );
	dec[1] = atof( argv[arg++] );
      } else {
	ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 );
        XLALPrintError( USAGE, *argv );
        return SKYMETRICTESTC_EARG;
      }
    }
    /* Parse debug level option. */
    else if ( !strcmp( argv[arg], "-d" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
      } else {
	ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 );
        XLALPrintError( USAGE, *argv );
        return SKYMETRICTESTC_EARG;
      }
    }
    /* Check for unrecognized options. */
    else if ( argv[arg][0] == '-' ) {
      ERROR( SKYMETRICTESTC_EARG, SKYMETRICTESTC_MSGEARG, 0 );
      XLALPrintError( USAGE, *argv );
      return SKYMETRICTESTC_EARG;
    }
  } /* End of argument parsing loop. */

  /* Do error trapping on input parameters. */
  if ( lalDebugLevel & LALERROR ) {
    CHECKVAL( n, 0, NMAX );
    CHECKVAL( f0, 0.0, F0MAX );
    CHECKVAL( dt, 1.0/f0, DTMAX );
    CHECKVAL( lat, -90.0, 90.0 );
    CHECKVAL( lon, -360.0, 360.0 );
  }

  /******************************************************************
   * METRIC COMPUTATION                                             *
   ******************************************************************/

  /* Set up start time. */
  start.gpsSeconds = (INT4)t0;
  start.gpsNanoSeconds = (INT4)( 1.0e9*( t0 - start.gpsSeconds ) );
  t0 = 0.0;

  /* Set up constant parameters for barycentre transformation. */
  baryParams.epoch = start;
  baryParams.latitude = LAL_PI_180*lat;
  baryParams.longitude = LAL_PI_180*lon;
  SUB( LALGetEarthTimes( &stat, &baryParams ), &stat );

  /* Set up constant parameters for metric calculation. */
  params.dtCanon = LALDTBaryPtolemaic;
  params.constants = &baryParams;
  params.start = t0;
  params.deltaT = dt;
  params.n = n;
  params.errors = 1;

  /* Set up the metric vector, metric grid, and parameter vector. */
  if ( params.errors )
    SUB( LALDCreateVector( &stat, &metric, 12 ), &stat );
  else
    SUB( LALDCreateVector( &stat, &metric, 6 ), &stat );
  mData = metric->data;
  SUB( LALU4CreateVector( &stat, &dimLength, 3 ), &stat );
  nRA = (UINT4)( ( ra[1] - ra[0] )/SPACING ) + 2;
  nDec = (UINT4)( ( dec[1] - dec[0] )/SPACING ) + 2;
  dimLength->data[0] = nDec;
  dimLength->data[1] = nRA;
  dimLength->data[2] = 3;
  SUB( LALSCreateGrid( &stat, &metricGrid, dimLength, 2 ), &stat );
  SUB( LALU4DestroyVector( &stat, &dimLength ), &stat );
  metricGrid->offset->data[0] = dec[0];
  metricGrid->offset->data[1] = ra[0];
  metricGrid->interval->data[0] = dDec = ( dec[1] - dec[0] )/( nDec - 1.0 );
  metricGrid->interval->data[1] = dRA = ( ra[1] - ra[0] )/( nRA - 1.0 );
  gData = metricGrid->data->data;
  SUB( LALDCreateVector( &stat, &lambda, 3 ), &stat );
  lambda->data[0] = f0;

  /* Set up preliminary range delimiters. */
  topRange = (INT4 *)LALMalloc( nRA*sizeof( INT4 ) );
  botRange = (INT4 *)LALMalloc( nRA*sizeof( INT4 ) );
  if ( !topRange || !botRange ) {
    ERROR( SKYMETRICTESTC_EMEM, SKYMETRICTESTC_MSGEMEM, 0 );
    return SKYMETRICTESTC_EMEM;
  }
  for ( i = 0; i < nRA; i++ ) {
    topRange[i] = 0;
    botRange[i] = nRA;
  }

  /* Fill the metric grid with the projected metric. */
  k = 0;
  fprintf( stdout, "Computing metric on %ix%i grid:\n", nDec, nRA );
  for ( i = 0; i < nDec; i++ ) {
    BOOLEAN bottom = 1, top = 0; /* whether we're at the bottom or top
                                    of the grid column */
    lambda->data[2] = LAL_PI_180*( dec[0] + i*dDec );
    for ( j = 0; j < nRA; j++ ) {
      if ( top )
	fprintf( stdout, "o" );
      else {
	REAL4 gxx, gyy, gxy; /* metric components */
	lambda->data[1] = LAL_PI_180*( ra[0] + j*dRA );
	SUB( LALStackMetric( &stat, metric, lambda, &params ), &stat );
	SUB( LALProjectMetric( &stat, metric, params.errors ), &stat );

	/* If uncertainties are given, generate conservative metric. */
	if ( params.errors ) {
	  INT2 sign = 1; /* sign of xy metric component */
	  gxx = mData[10] + mData[11];
	  gyy = mData[4] + mData[5];
	  gxy = mData[8];
	  if ( gxy < 0.0 )
	    sign = -1;
	  if ( fabs( gxy ) <= fabs( mData[9] ) )
	    gxy = 0.0;
	  else
	    gxy = sign*( fabs( gxy ) - fabs( mData[9] ) );
	  if ( gxx < 0.0 || gyy < 0.0 || gxx*gyy - gxy*gxy < 0.0 ) {
	    errors++;
	    fprintf( stdout, "o" );
	  } else if ( fabs( mData[4]*mData[11] ) +
		      fabs( mData[5]*mData[10] ) +
		      fabs( mData[8]*mData[9] )*2.0 >=
		      mData[4]*mData[10] - mData[8]*mData[8] ) {
	    warnings++;
	    fprintf( stdout, "*" );
	  } else
	    fprintf( stdout, "+" );
	}

	/* If uncertainties are not given, just use best estimate. */
	else {
	  gxx = mData[5];
	  gxy = mData[4];
	  gyy = mData[2];
	  if ( gxx < 0.0 || gyy < 0.0 || gxx*gyy - gxy*gxy < 0.0 ) {
	    errors++;
	    fprintf( stdout, "o" );
	  } else
	    fprintf( stdout, "+" );
	}

	/* See whether we've crossed a range boundary. */
	if ( gxx > 0.0 && gyy > 0.0 && gxx*gyy - gxy*gxy > 0.0 ) {
	  if ( bottom ) {
	    bottom = 0;
	    botRange[i] = j - 1;
	  }
	  propVol += LAL_PI_180*LAL_PI_180*sqrt( gxx*gyy - gxy*gxy );
	  nVol++;
	} else {
	  if ( !bottom ) {
	    top = 1;
	    topRange[i] = j;
	  }
	}
	*(gData++) = LAL_PI_180*LAL_PI_180*gxx;
	*(gData++) = LAL_PI_180*LAL_PI_180*gyy;
	*(gData++) = LAL_PI_180*LAL_PI_180*gxy;
      }
      fflush( stdout );
    }
    if ( !top )
      topRange[i] = j;
    fprintf( stdout, "\n" );
  }

  /* Free memory that's no longer needed. */
  SUB( LALDDestroyVector( &stat, &metric ), &stat );
  SUB( LALDDestroyVector( &stat, &lambda ), &stat );

  /* Warn if any points had bad values or large uncertainties. */
  if ( errors ) {
    CHAR msg[MSGLEN];
    snprintf( msg, MSGLEN, "%i of %i points had"
		 " non-positive-definite metric", warnings,
		 nRA*nDec );
    WARNING( msg );
  }
  if ( warnings ) {
    CHAR msg[MSGLEN];
    snprintf( msg, MSGLEN, "%i of %i points had metric component"
		 " errors larger than values", warnings, nRA*nDec );
    WARNING( msg );
  }

  /* Write the proper volume element. */
  fprintf( stdout, "Average proper volume element: %10.3e per square"
	   " degree\n", propVol /= nVol );

  /******************************************************************
   * RANGE COMPUTATION                                              *
   ******************************************************************/

  /* Each bad metric point affects the four squares adjoining it, so
     top and bottom ranges need to be adjusted down or up one point
     based on the adjoining columns. */
  topRange2 = (INT4 *)LALMalloc( nDec*sizeof(INT4) );
  botRange2 = (INT4 *)LALMalloc( nDec*sizeof(INT4) );
  if ( !topRange2 || !botRange2 ) {
    ERROR( SKYMETRICTESTC_EMEM, SKYMETRICTESTC_MSGEMEM, 0 );
    return SKYMETRICTESTC_EMEM;
  }
  topRange2[0] = topRange[1] < topRange[0] ?
    topRange[1] - 1 : topRange[0] - 1;
  botRange2[0] = botRange[1] > botRange[0] ?
    botRange[1] + 1 : botRange[0] + 1;
  topRange2[nDec-1] = topRange[nDec] < topRange[nDec-1] ?
    topRange[nDec] - 1 : topRange[nDec-1] - 1;
  botRange2[nDec-1] = botRange[nDec] > botRange[nDec-1] ?
    botRange[nDec] + 1 : botRange[nDec-1] + 1;
  for ( i = 1; i < nDec - 1; i++ ) {
    INT4 topMin = topRange[i-1], botMax = botRange[i-1];
    if ( topRange[i] < topMin )
      topMin = topRange[i];
    if ( topRange[i+1] < topMin )
      topMin = topRange[i+1];
    if ( botRange[i] > botMax )
      botMax = botRange[i];
    if ( botRange[i+1] > botMax )
      botMax = botRange[i+1];
    topRange2[i] = topMin - 1;
    botRange2[i] = botMax + 1;
  }
  LALFree( topRange );
  LALFree( botRange );

  /* Determine the contiguous domain with open range intervals. */
  if ( topRange2[0] > botRange2[0] && topRange2[1] > botRange2[1] )
    i = 0;
  else {
    i = 1;
    while ( i < nDec - 1 && topRange2[i] <= botRange2[i] &&
	    topRange2[i+1] <= botRange2[i+1] )
      i++;
  }
  j = i;
  while ( j < nDec - 1 && topRange2[j+1] > botRange2[j+1] )
    j++;
  if ( j == i ) {
    ERROR( SKYMETRICTESTC_ERNG, SKYMETRICTESTC_MSGERNG, 0 );
    return SKYMETRICTESTC_ERNG;
  }

  /* Set up range grid. */
  j = j - i + 1;
  SUB( LALU4CreateVector( &stat, &dimLength, 2 ), &stat );
  dimLength->data[0] = j;
  dimLength->data[1] = 2;
  SUB( LALSCreateGrid( &stat, &rangeGrid, dimLength, 1 ), &stat );
  SUB( LALU4DestroyVector( &stat, &dimLength ), &stat );
  rangeGrid->offset->data[0] = dec[0] + i*dDec;
  rangeGrid->interval->data[0] = dDec;
  rData = rangeGrid->data->data;
  nVol = 0;
  for ( k = 0; k < j; k++ ) {
    *(rData++) = ra[0] + botRange2[k]*dRA;
    *(rData++) = ra[0] + topRange2[k]*dRA;
    nVol += topRange2[k] - botRange2[k] - 1;
  }
  nVol -= topRange2[j-1] - botRange2[j-1] - 1;
  LALFree( topRange2 );
  LALFree( botRange2 );

  /* Write the total proper volume of the covered range. */
  fprintf( stdout, "Total proper volume:           %10.3e\n",
	   propVol*nVol*dRA*dDec );

  /******************************************************************
   * FINISH                                                         *
   ******************************************************************/

  /* Write the output files, if requested. */
  if ( metricfile ) {
    FILE *fp = fopen( metricfile, "w" ); /* output file pointer */
    if ( !fp ) {
      ERROR( SKYMETRICTESTC_EFILE, "- " SKYMETRICTESTC_MSGEFILE,
	     metricfile );
      return SKYMETRICTESTC_EFILE;
    }
    SUB( LALSWriteGrid( &stat, fp, metricGrid ), &stat );
    fclose( fp );
  }
  if ( rangefile ) {
    FILE *fp = fopen( rangefile, "w" ); /* output file pointer */
    if ( !fp ) {
      ERROR( SKYMETRICTESTC_EFILE, "- " SKYMETRICTESTC_MSGEFILE,
	     rangefile );
      return SKYMETRICTESTC_EFILE;
    }
    SUB( LALSWriteGrid( &stat, fp, rangeGrid ), &stat );
    fclose( fp );
  }

  /* Clean up and exit. */
  SUB( LALSDestroyGrid( &stat, &metricGrid ), &stat );
  SUB( LALSDestroyGrid( &stat, &rangeGrid ), &stat );
  LALCheckMemoryLeaks();
  INFO( SKYMETRICTESTC_MSGENORM );
  return SKYMETRICTESTC_ENORM;
}
Пример #25
0
int main( void )
{
  static LALStatus status;

  REAL4Sequence       *sSequenceIn;
  REAL4Sequence       *sSequenceOut;
  REAL8Sequence       *dSequenceIn;
  REAL8Sequence       *dSequenceOut;

  COMPLEX8Sequence    *cSequenceIn;
  COMPLEX8Sequence    *cSequenceOut;
  COMPLEX16Sequence   *zSequenceIn;
  COMPLEX16Sequence   *zSequenceOut;


  REAL4FrequencySeries      sFrequencySeries;
  REAL8FrequencySeries      dFrequencySeries;
  COMPLEX8FrequencySeries   cFrequencySeries;
  COMPLEX16FrequencySeries  zFrequencySeries;

  REAL4FrequencySeries      sFrequencySeries2;
  REAL8FrequencySeries      dFrequencySeries2;
  COMPLEX8FrequencySeries   cFrequencySeries2;
  COMPLEX16FrequencySeries  zFrequencySeries2;

  REAL4TimeSeries           sTimeSeries;
  REAL8TimeSeries           dTimeSeries;
  COMPLEX8TimeSeries        cTimeSeries;
  COMPLEX16TimeSeries       zTimeSeries;

  REAL4TimeSeries           sTimeSeries2;
  REAL8TimeSeries           dTimeSeries2;
  COMPLEX8TimeSeries        cTimeSeries2;
  COMPLEX16TimeSeries       zTimeSeries2;

  REAL4            *sData;
  REAL8            *dData;
  COMPLEX8         *cData;
  COMPLEX16        *zData;

  /* Boolean Vars */
  BOOLEAN     unitComp;

  /* variables for units */
  RAT4        raise;
  LALUnit     strainToMinus2;
  LALUnit     adcToMinus2;
  LALUnit     adcStrain;


  /* This routine should generate a file with data */
  /* to be read by ReadFTSeries.c*/
  LIGOTimeGPS  t;
  UINT4         i;


  /* Data Test Variable */
  UINT4   j;


  fprintf(stderr,"Testing value of LALUnitTextSize ... ");
  if ( (int)LALSupportUnitTextSize != (int)LALUnitTextSize )
  {
    fprintf(stderr,"UnitTextSize mismatch: [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  fprintf(stderr,"PASS\n");

  t.gpsSeconds = 0;
  t.gpsNanoSeconds = 0;

  fprintf(stderr,"Testing Print/Read COMPLEX8FrequencySeries ... ");

  cSequenceIn = NULL;
  LALCCreateVector(&status, &cSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }
  for ( i=1, cData=cSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, cData++ )
  {
    *(cData) = crectf( i, i+1 );
    }

  strncpy(cFrequencySeries.name,"Complex frequency series",LALNameLength);
  cFrequencySeries.sampleUnits = lalHertzUnit;
  cFrequencySeries.deltaF = 1;
  cFrequencySeries.epoch = t;
  cFrequencySeries.f0 = 5;

  cFrequencySeries.data = cSequenceIn;

  LALCPrintFrequencySeries(&cFrequencySeries, "cFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  cSequenceOut = NULL;
  LALCCreateVector( &status, &cSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  cFrequencySeries2.data = cSequenceOut;

  LALCReadFrequencySeries(&status, &cFrequencySeries2, "./cFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (fabs(cFrequencySeries.deltaF - cFrequencySeries.deltaF)/
      cFrequencySeries.deltaF > READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"DeltaF MisMatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (strcmp(cFrequencySeries.name,cFrequencySeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((cFrequencySeries.epoch.gpsSeconds) !=
      (cFrequencySeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Second Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((cFrequencySeries.epoch.gpsNanoSeconds) !=
      (cFrequencySeries2.epoch.gpsNanoSeconds))
  {
    fprintf(stderr,"Epoch NanosecondMismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((cFrequencySeries.f0) ?
      (fabs(cFrequencySeries.f0 - cFrequencySeries2.f0)/cFrequencySeries.f0) :
      (fabs(cFrequencySeries.f0 - cFrequencySeries2.f0)  >
      READFTSERIESTEST_TOL))
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  unitComp = XLALUnitCompare(&cFrequencySeries.sampleUnits,&cFrequencySeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  for (j = 0; j < cSequenceIn->length;j++)
  {
    if ((crealf(cSequenceIn->data[j]) ?
	 fabs((crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))
	      /crealf(cSequenceIn->data[j]))
	 :fabs(crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
    if ((cimagf(cSequenceIn->data[j]) ?
	 fabs((cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))
	      /cimagf(cSequenceIn->data[j]))
	 :fabs(cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }

  fprintf(stderr,"PASS\n");

  fprintf(stderr,"Testing Print/Read COMPLEX16FrequencySeries ... ");

  /* Test case 2 */

  t.gpsSeconds = 45678;
  t.gpsNanoSeconds = 89065834;

  zSequenceIn = NULL;
  LALZCreateVector( &status, &zSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  for ( i=1, zData=zSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, zData++ )
  {
    *(zData) = crect( i/4.0, (i+1)/5.0 );
  }
  zFrequencySeries.sampleUnits = lalDimensionlessUnit;
  strncpy(zFrequencySeries.name,"Complex frequency series",LALNameLength);
  zFrequencySeries.deltaF = 1.3;
  zFrequencySeries.epoch = t;
  zFrequencySeries.f0 = 0;
  zFrequencySeries.data = zSequenceIn;

  LALZPrintFrequencySeries(&zFrequencySeries, "zFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  zSequenceOut = NULL;
  LALZCreateVector( &status, &zSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  zFrequencySeries2.data = zSequenceOut;

  LALZReadFrequencySeries(&status, &zFrequencySeries2, "./zFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if ((zFrequencySeries.deltaF) != (zFrequencySeries2.deltaF))
  {
    fprintf(stderr,"DeltaF Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (strcmp(zFrequencySeries.name,zFrequencySeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((zFrequencySeries.epoch.gpsSeconds) !=
      (zFrequencySeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((zFrequencySeries.epoch.gpsNanoSeconds) !=
      (zFrequencySeries2.epoch.gpsNanoSeconds))
  {
    fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (zFrequencySeries.f0 ?
       (fabs(zFrequencySeries.f0 - zFrequencySeries2.f0)/zFrequencySeries.f0)
       : (fabs(zFrequencySeries.f0 - zFrequencySeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  unitComp = XLALUnitCompare(&zFrequencySeries.sampleUnits,&zFrequencySeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  for (j = 0; j < zSequenceIn->length;j++)
  {
    if ((creal(zSequenceIn->data[j]) ?
	fabs((creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))
	     /creal(zSequenceIn->data[j])) :
	fabs(creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))) >
	READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
   if ((cimag(zSequenceIn->data[j]) ?
	fabs((cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))
	     /cimag(zSequenceIn->data[j])) :
	fabs(cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))) >
	READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }

  fprintf(stderr,"PASS\n");

  fprintf(stderr,"Testing Print/Read REAL8FrequencySeries ... ");

  /* Test case 3 */
  t.gpsSeconds = 45678;
  t.gpsNanoSeconds = 89065834;

  dSequenceIn = NULL;
  LALDCreateVector( &status, &dSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  for ( i=1, dData=dSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, dData++ )
  {
    *(dData) = 0.005;
  }

  strncpy(dFrequencySeries.name,"Complex frequency series",LALNameLength);
  /* set units */
  raise.numerator = -2;
  raise.denominatorMinusOne = 0;
  if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&dFrequencySeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  dFrequencySeries.deltaF = 1.3;
  dFrequencySeries.epoch = t;
  dFrequencySeries.f0 = 0;
  dFrequencySeries.data = dSequenceIn;
  LALDPrintFrequencySeries(&dFrequencySeries, "dFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  dSequenceOut = NULL;
  LALDCreateVector( &status, &dSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  dFrequencySeries2.data = dSequenceOut;

  LALDReadFrequencySeries(&status, &dFrequencySeries2, "./dFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if ((dFrequencySeries.deltaF) != (dFrequencySeries.deltaF))
  {
    fprintf(stderr,"DeltaF Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (strcmp(dFrequencySeries.name,dFrequencySeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((dFrequencySeries.epoch.gpsSeconds)
      != (dFrequencySeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((dFrequencySeries.epoch.gpsSeconds)
      != (dFrequencySeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (dFrequencySeries.f0 ?
       (fabs(dFrequencySeries.f0 - dFrequencySeries2.f0)/dFrequencySeries.f0)
       : (fabs(dFrequencySeries.f0 - dFrequencySeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  unitComp = XLALUnitCompare(&dFrequencySeries.sampleUnits,&dFrequencySeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }


  for (j = 0; j < dSequenceIn->length;j++)
  {
    if ((dSequenceIn->data[j] ?
	 fabs((dSequenceIn->data[j] - dSequenceOut->data[j])
	      /dSequenceIn->data[j])
	 :fabs(dSequenceIn->data[j] - dSequenceOut->data[j])) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }

  }


  fprintf(stderr,"PASS\n");

  fprintf(stderr,"Testing Print/Read REAL4FrequencySeries ... ");


 /* Test case 4 */
  t.gpsSeconds = 45678;
  t.gpsNanoSeconds = 89065834;

  sSequenceIn = NULL;
  LALSCreateVector( &status, &sSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  for ( i=1, sData=sSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, sData++ )
  {
    *(sData) = 0.005;
  }

  strncpy(sFrequencySeries.name,"Complex frequency series",LALNameLength);
  /* set units */
  raise.numerator = -2;
  raise.denominatorMinusOne = 0;
  if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&sFrequencySeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  sFrequencySeries.deltaF = 1.3;
  sFrequencySeries.epoch = t;
  sFrequencySeries.f0 = 5;
  sFrequencySeries.data = sSequenceIn;

  sSequenceOut = NULL;
  LALSCreateVector( &status, &sSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  sFrequencySeries2.data = sSequenceOut;
  LALSPrintFrequencySeries(&sFrequencySeries, "sFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALSReadFrequencySeries(&status, &sFrequencySeries2, "./sFSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (fabs(sFrequencySeries.deltaF - sFrequencySeries2.deltaF)
      /sFrequencySeries.deltaF > READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"Deltaf Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if (strcmp(sFrequencySeries.name,sFrequencySeries2.name)!=0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if ((sFrequencySeries.epoch.gpsSeconds) !=
      (sFrequencySeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((sFrequencySeries.epoch.gpsNanoSeconds) !=
      (sFrequencySeries2.epoch.gpsNanoSeconds))
  {
    fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (sFrequencySeries.f0 ?
       (fabs(sFrequencySeries.f0 - sFrequencySeries2.f0)/sFrequencySeries.f0)
       : (fabs(sFrequencySeries.f0 - sFrequencySeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  unitComp = XLALUnitCompare(&sFrequencySeries.sampleUnits,&sFrequencySeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  for (j = 0; j < sSequenceIn->length;j++)
  {
    if ((sSequenceIn->data[j] ?
	 fabs((sSequenceIn->data[j] - sSequenceOut->data[j])
	      /sSequenceIn->data[j])
	 :fabs(sSequenceIn->data[j] - sSequenceOut->data[j])) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }


  LALCDestroyVector(&status, &cSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALCDestroyVector(&status, &cSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALZDestroyVector(&status, &zSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }
  LALZDestroyVector(&status, &zSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALDDestroyVector(&status, &dSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALDDestroyVector(&status, &dSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALSDestroyVector(&status, &sSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALSDestroyVector(&status, &sSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  fprintf(stderr,"PASS\n");


  fprintf(stderr,"Testing Print/Read REAL4TimeSeries ... ");

  /* Here is where testing for ReadTimeSeries is done */
  /* S Case ReadTimeSeries */

  raise.numerator = -2;
  raise.denominatorMinusOne = 0;
  if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&sTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  t.gpsSeconds = 45678;
  t.gpsNanoSeconds = 89065834;

  sSequenceIn = NULL;
  LALSCreateVector( &status, &sSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  for ( i=1, sData=sSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, sData++ )
  {
    *(sData) = 0.005;
  }
  strncpy(sTimeSeries.name,"Real4 Time series",LALNameLength);
  sTimeSeries.deltaT = 1.3;
  sTimeSeries.epoch = t;
  sTimeSeries.data = sSequenceIn;
  sTimeSeries.f0 = 5;
  LALSPrintTimeSeries(&sTimeSeries, "sTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  sSequenceOut = NULL;
  LALSCreateVector( &status, &sSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  sTimeSeries2.data = sSequenceOut;

  LALSReadTimeSeries(&status, &sTimeSeries2, "./sTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (fabs(sTimeSeries.deltaT-sTimeSeries2.deltaT) /
      sTimeSeries.deltaT > READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if (strcmp(sFrequencySeries.name,sFrequencySeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if ((sTimeSeries.epoch.gpsSeconds) != (sTimeSeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((sTimeSeries.epoch.gpsNanoSeconds) != (sTimeSeries2.epoch.gpsNanoSeconds))
  {
    fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  /*  printf("%f ... %f  f0 value\n",sTimeSeries.f0,sTimeSeries2.f0);*/
  if (sTimeSeries.f0 ?
       (fabs(sTimeSeries.f0 - sTimeSeries2.f0)/sTimeSeries.f0)
       : (fabs(sTimeSeries.f0 - sTimeSeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  unitComp = XLALUnitCompare(&sTimeSeries.sampleUnits,&sTimeSeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  for (j = 0; j < sSequenceIn->length;j++)
  {
    if ((sSequenceIn->data[j] ?
	 fabs((sSequenceIn->data[j] - sSequenceOut->data[j])
	      /sSequenceIn->data[j])
	 :fabs(sSequenceIn->data[j] - sSequenceOut->data[j])) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }

  fprintf(stderr,"PASS\n");

  fprintf(stderr,"Testing Print/Read COMPLEX16TimeSeries ... ");

  /* Z case ReadTimeSeries*/

  raise.numerator = -2;
  raise.denominatorMinusOne = 0;
  if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&zTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  t.gpsSeconds = 45678;
  t.gpsNanoSeconds = 89065834;

  zSequenceIn = NULL;
  LALZCreateVector( &status, &zSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  for ( i=1, zData=zSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, zData++ )
  {
    *(zData) = crect( 0.005, 1 );
  }
  strncpy(zTimeSeries.name,"Complex16 Time series",LALNameLength);
  zTimeSeries.deltaT = 1.3;
  zTimeSeries.epoch = t;
  zTimeSeries.data = zSequenceIn;
  zTimeSeries.f0 = 0;
  LALZPrintTimeSeries(&zTimeSeries, "zTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  zSequenceOut = NULL;
  LALZCreateVector( &status, &zSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  zTimeSeries2.data = zSequenceOut;

  LALZReadTimeSeries(&status, &zTimeSeries2, "./zTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (fabs(zTimeSeries.deltaT) - (zTimeSeries2.deltaT)/zTimeSeries.deltaT >
      READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"Mismatch DeltaT [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }


  if (strcmp(zTimeSeries.name,zTimeSeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if ((zTimeSeries.epoch.gpsSeconds) != (zTimeSeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Second Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ( (zTimeSeries.epoch.gpsNanoSeconds)
       != (zTimeSeries2.epoch.gpsNanoSeconds) )
  {
    fprintf(stderr,"Epoch Nanosecond Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if (zTimeSeries.f0 ?
       (fabs(zTimeSeries.f0 - zTimeSeries2.f0)/zTimeSeries.f0)
       : (fabs(zTimeSeries.f0 - zTimeSeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  unitComp = XLALUnitCompare(&zTimeSeries.sampleUnits,&zTimeSeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFUN;
  }

  for (j = 0; j < zSequenceIn->length;j++)
  {
    if ((creal(zSequenceIn->data[j]) ?
	 fabs((creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))
	      /creal(zSequenceIn->data[j]))
	 :fabs(creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
    if ((cimag(zSequenceIn->data[j]) ?
	 fabs((cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))
	      /cimag(zSequenceIn->data[j]))
	 :fabs(cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }

  fprintf(stderr,"PASS\n");

  fprintf(stderr,"Testing Print/Read REAL8TimeSeries ... ");

  /* D case  ReadTimeSeries*/

  raise.numerator = -2;
  raise.denominatorMinusOne = 0;
  if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }
  if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&sTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  strncpy(dTimeSeries.name,"REAL8 Time series",LALNameLength);
  dTimeSeries.sampleUnits = lalHertzUnit;
  t.gpsSeconds = 4578;
  t.gpsNanoSeconds = 890634;

  dSequenceIn = NULL;
  LALDCreateVector( &status, &dSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }


  for ( i=1, dData=dSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, dData++ )
  {
    *(dData) = 0.005;
  }

  dTimeSeries.deltaT = 1.3;
  dTimeSeries.epoch = t;
  dTimeSeries.data = dSequenceIn;
  dTimeSeries.f0 = 0;
  LALDPrintTimeSeries(&dTimeSeries, "dTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  dSequenceOut = NULL;
  LALDCreateVector( &status, &dSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  dTimeSeries2.data = dSequenceOut;
  LALDReadTimeSeries(&status, &dTimeSeries2, "./dTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (fabs(dTimeSeries.deltaT) - (dTimeSeries2.deltaT)/dTimeSeries.deltaT
      > READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%d,%s]\n",status.statusCode,
	    status.statusDescription );
    return READFTSERIESTESTC_EFLS;
  }
  if (strcmp(dTimeSeries.name,dTimeSeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%d,%s]\n",status.statusCode,
	    status.statusDescription );
    return READFTSERIESTESTC_EFLS;
  }

  if ((dTimeSeries.epoch.gpsSeconds) != (dTimeSeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if ((dTimeSeries.epoch.gpsNanoSeconds)
      != (dTimeSeries2.epoch.gpsNanoSeconds))
  {
    fprintf(stderr,"Epoch Nanoseconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if (dTimeSeries.f0 ?
       (fabs(dTimeSeries.f0 - dTimeSeries2.f0)/dTimeSeries.f0)
       : (fabs(dTimeSeries.f0 - dTimeSeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  unitComp = XLALUnitCompare(&dTimeSeries.sampleUnits,&dTimeSeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  for (j = 0; j < dSequenceIn->length;j++)
  {
    if ((dSequenceIn->data[j] ?
	 fabs((dSequenceIn->data[j] - dSequenceOut->data[j])
	      /dSequenceIn->data[j])
	 :fabs(dSequenceIn->data[j] - dSequenceOut->data[j])) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }

  fprintf(stderr,"PASS\n");

  fprintf(stderr,"Testing Print/Read COMPLEX8TimeSeries ... ");

  /* C case ReadTimeSeries*/

  raise.numerator = -2;
  raise.denominatorMinusOne = 0;
  if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (XLALUnitMultiply(&cTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  t.gpsSeconds = 45678;
  t.gpsNanoSeconds = 89065834;

  cSequenceIn = NULL;
  LALCCreateVector( &status, &cSequenceIn, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  for ( i=1, cData=cSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, cData++ )
  {
    *(cData) = crectf( 0.005, 1 );
  }
  strncpy(cTimeSeries.name,"Complex8 Time series",LALNameLength);
  cTimeSeries.deltaT = 1.3;
  cTimeSeries.epoch = t;
  cTimeSeries.data = cSequenceIn;
  cTimeSeries.f0 = 0;
  cSequenceOut = NULL;
  LALCPrintTimeSeries(&cTimeSeries, "cTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }
  LALCCreateVector( &status, &cSequenceOut, READFTSERIESTEST_LEN);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  cTimeSeries2.data = cSequenceOut;

  LALCReadTimeSeries(&status, &cTimeSeries2, "./cTSInput.dat");
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  if (fabs(cTimeSeries.deltaT - cTimeSeries2.deltaT)/cTimeSeries.deltaT
      > READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  if (strcmp(cTimeSeries.name,cTimeSeries2.name) != 0)
  {
    fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((cTimeSeries.epoch.gpsSeconds) != (cTimeSeries2.epoch.gpsSeconds))
  {
    fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if ((cTimeSeries.epoch.gpsNanoSeconds)!=(cTimeSeries2.epoch.gpsNanoSeconds))
  {
    fprintf(stderr,"Epoch Nanoseconds Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }
  if (cTimeSeries.f0 ?
       (fabs(cTimeSeries.f0 - cTimeSeries2.f0)/cTimeSeries.f0)
       : (fabs(cTimeSeries.f0 - cTimeSeries2.f0)) >
       READFTSERIESTEST_TOL)
  {
    fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  unitComp = XLALUnitCompare(&cTimeSeries.sampleUnits,&cTimeSeries2.sampleUnits);

  if (unitComp != 0)
  {
    fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n",
	    READFTSERIESTESTC_MSGEFLS);
    return READFTSERIESTESTC_EFLS;
  }

  for (j = 0; j < cSequenceIn->length;j++)
  {
    if ((crealf(cSequenceIn->data[j]) ?
	 fabs((crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))
	      /crealf(cSequenceIn->data[j]))
	 :fabs(crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
    if ((cimagf(cSequenceIn->data[j]) ?
	 fabs((cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))
	      /cimagf(cSequenceIn->data[j]))
	 :fabs(cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))) >
	 READFTSERIESTEST_TOL)
    {
      fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n",
	      READFTSERIESTESTC_MSGEFLS);
      return READFTSERIESTESTC_EFLS;
    }
  }

  fprintf(stderr,"PASS\n");

  /* *******************Deallocate all memory****************** */
  LALCDestroyVector(&status, &cSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALCDestroyVector(&status, &cSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALZDestroyVector(&status, &zSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALZDestroyVector(&status, &zSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALDDestroyVector(&status, &dSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALDDestroyVector(&status, &dSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALSDestroyVector(&status, &sSequenceIn);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALSDestroyVector(&status, &sSequenceOut);
  if (status.statusCode != 0)
  {
    fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode,
	    status.statusDescription, READFTSERIESTESTC_MSGEFUN);
    return READFTSERIESTESTC_EFUN;
  }

  LALCheckMemoryLeaks();

  fprintf(stderr,"ReadFTSeries passed all tests.\n");

  return READFTSERIESTESTC_ENOM;

}
/**
 * \author Creighton, T. D.
 *
 * \brief Computes the response of a detector to a coherent gravitational wave.
 *
 * This function takes a quasiperiodic gravitational waveform given in
 * <tt>*signal</tt>, and estimates the corresponding response of the
 * detector whose position, orientation, and transfer function are
 * specified in <tt>*detector</tt>.  The result is stored in
 * <tt>*output</tt>.
 *
 * The fields <tt>output-\>epoch</tt>, <tt>output->deltaT</tt>, and
 * <tt>output-\>data</tt> must already be set, in order to specify the time
 * period and sampling rate for which the response is required.  If
 * <tt>output-\>f0</tt> is nonzero, idealized heterodyning is performed (an
 * amount \f$2\pi f_0(t-t_0)\f$ is subtracted from the phase before computing
 * the sinusoid, where \f$t_0\f$ is the heterodyning epoch defined in
 * \c detector).  For the input signal, <tt>signal-\>h</tt> is ignored,
 * and the signal is treated as zero at any time for which either
 * <tt>signal-\>a</tt> or <tt>signal-\>phi</tt> is not defined.
 *
 * This routine will convert <tt>signal-\>position</tt> to equatorial
 * coordinates, if necessary.
 *
 * ### Algorithm ###
 *
 * The routine first accounts for the time delay between the detector and
 * the solar system barycentre, based on the detector position
 * information stored in <tt>*detector</tt> and the propagation direction
 * specified in <tt>*signal</tt>.  Values of the propagation delay are
 * precomuted at fixed intervals and stored in a table, with the
 * intervals \f$\Delta T_\mathrm{delay}\f$ chosen such that the value
 * interpolated from adjacent table entries will never differ from the
 * true value by more than some timing error \f$\sigma_T\f$.  This implies
 * that:
 * \f[
 * \Delta T_\mathrm{delay} \leq \sqrt{
 * \frac{8\sigma_T}{\max\{a/c\}} } \; ,
 * \f]
 * where \f$\max\{a/c\}=1.32\times10^{-10}\mathrm{s}^{-1}\f$ is the maximum
 * acceleration of an Earth-based detector in the barycentric frame.  The
 * total propagation delay also includes Einstein and Shapiro delay, but
 * these are more slowly varying and thus do not constrain the table
 * spacing.  At present, a 400s table spacing is hardwired into the code,
 * implying \f$\sigma_T\approx3\mu\f$s, comparable to the stated accuracy of
 * <tt>LALBarycenter()</tt>.
 *
 * Next, the polarization response functions of the detector
 * \f$F_{+,\times}(\alpha,\delta)\f$ are computed for every 10 minutes of the
 * signal's duration, using the position of the source in <tt>*signal</tt>,
 * the detector information in <tt>*detector</tt>, and the function
 * <tt>LALComputeDetAMResponseSeries()</tt>.  Subsequently, the
 * polarization functions are estimated for each output sample by
 * interpolating these precomputed values.  This guarantees that the
 * interpolated value is accurate to \f$\sim0.1\%\f$.
 *
 * Next, the frequency response of the detector is estimated in the
 * quasiperiodic limit as follows:
 * <ul>
 * <li> At each sample point in <tt>*output</tt>, the propagation delay is
 * computed and added to the sample time, and the instantaneous
 * amplitudes \f$A_1\f$, \f$A_2\f$, frequency \f$f\f$, phase \f$\phi\f$, and polarization
 * shift \f$\Phi\f$ are found by interpolating the nearest values in
 * <tt>signal-\>a</tt>, <tt>signal-\>f</tt>, <tt>signal-\>phi</tt>, and
 * <tt>signal-\>shift</tt>, respectively.  If <tt>signal-\>f</tt> is not
 * defined at that point in time, then \f$f\f$ is estimated by differencing
 * the two nearest values of \f$\phi\f$, as \f$f\approx\Delta\phi/2\pi\Delta
 * t\f$.  If <tt>signal-\>shift</tt> is not defined, then \f$\Phi\f$ is treated as
 * zero.</li>
 * <li> The complex transfer function of the detector the frequency \f$f\f$
 * is found by interpolating <tt>detector-\>transfer</tt>.  The amplitude of
 * the transfer function is multiplied with \f$A_1\f$ and \f$A_2\f$, and the
 * phase of the transfer function is added to \f$\phi\f$,</li>
 * <li> The plus and cross contributions \f$o_+\f$, \f$o_\times\f$ to the
 * detector output are computed as in \eqref{eq_quasiperiodic_hpluscross}
 * of \ref PulsarSimulateCoherentGW_h, but
 * using the response-adjusted amplitudes and phase.</li>
 * <li> The final detector response \f$o\f$ is computed as
 * \f$o=(o_+F_+)+(o_\times F_\times)\f$.</li>
 * </ul>
 *
 * ### A note on interpolation: ###
 *
 * Much of the computational work in this routine involves interpolating
 * various time series to find their values at specific output times.
 * The algorithm is summarized below.
 *
 * Let \f$A_j = A( t_A + j\Delta t_A )\f$ be a sampled time series, which we
 * want to resample at new (output) time intervals \f$t_k = t_0 + k\Delta
 * t\f$.  We first precompute the following quantities:
 * \f{eqnarray}{
 * t_\mathrm{off} & = & \frac{t_0-t_A}{\Delta t_A}  \; , \\
 * dt & = & \frac{\Delta t}{\Delta t_A} \; .
 * \f}
 * Then, for each output sample time \f$t_k\f$, we compute:
 * \f{eqnarray}{
 * t & = & t_\mathrm{off} + k \times dt \; , \\
 * j & = & \lfloor t \rfloor            \; , \\
 * f & = & t - j                        \; ,
 * \f}
 * where \f$\lfloor x\rfloor\f$ is the "floor" function; i.e.\ the largest
 * integer \f$\leq x\f$.  The time series sampled at the new time is then:
 * \f[
 * A(t_k) = f \times A_{j+1} + (1-f) \times A_j \; .
 * \f]
 *
 * ### Notes ###
 *
 * The major computational hit in this routine comes from computing the
 * sine and cosine of the phase angle in
 * \eqref{eq_quasiperiodic_hpluscross} of
 * \ref PulsarSimulateCoherentGW_h.  For better online performance, these can
 * be replaced by other (approximate) trig functions.  Presently the code
 * uses the native \c libm functions by default, or the function
 * <tt>sincosp()</tt> in \c libsunmath \e if this function is
 * available \e and the constant \c ONLINE is defined.
 * Differences at the level of 0.01 begin to appear only for phase
 * arguments greater than \f$10^{14}\f$ or so (corresponding to over 500
 * years between phase epoch and observation time for frequencies of
 * around 1kHz).
 *
 * To activate this feature, be sure that <tt>sunmath.h</tt> and
 * \c libsunmath are on your system, and add <tt>-DONLINE</tt> to the
 * <tt>--with-extra-cppflags</tt> configuration argument.  In future this
 * flag may be used to turn on other efficient trig algorithms on other
 * (non-Solaris) platforms.
 *
 */
void
LALPulsarSimulateCoherentGW( LALStatus        *stat,
                       REAL4TimeSeries  *output,
                       PulsarCoherentGW       *CWsignal,
                       PulsarDetectorResponse *detector )
{
  INT4 i, n;          /* index over output->data, and its final value */
  INT4 nMax;          /* used to store limits on index ranges */
  INT4 fInit, fFinal; /* index range for which CWsignal->f is defined */
  INT4 shiftInit, shiftFinal; /* ditto for CWsignal->shift */
  UINT4 dtDelayBy2;     /* delay table half-interval (s) */
  UINT4 dtPolBy2;       /* polarization table half-interval (s) */
  REAL4 *outData;             /* pointer to output data */
  REAL8 delayMin, delayMax;   /* min and max values of time delay */
  SkyPosition source;         /* source sky position */
  BOOLEAN transfer;  /* 1 if transfer function is specified */
  BOOLEAN fFlag = 0; /* 1 if frequency left detector->transfer range */
  BOOLEAN pFlag = 0; /* 1 if frequency was estimated from phase */

  /* get delay table and polaristion tables half intervals if defined (>0) in
     the PulsarCoherentGW structure otherwise default to 400s for dtDelatBy2 and 300s
     for dtPolBy2 */
  dtDelayBy2 = CWsignal->dtDelayBy2 > 0 ? CWsignal->dtDelayBy2 : 400;
  dtPolBy2   = CWsignal->dtPolBy2   > 0 ? CWsignal->dtPolBy2   : 300;

  /* The amplitude, frequency, phase, polarization shift, polarization
     response, and propagation delay are stored in arrays that must be
     interpolated.  For a quantity x, we define a pointer xData to the
     data array.  At some time t measured in units of output->deltaT,
     the interpolation point in xData is given by ( xOff + t*xDt ),
     where xOff is an offset and xDt is a relative sampling rate. */
  LALDetAMResponseSeries polResponse;
  REAL8Vector *delay = NULL;
  REAL4 *aData, *fData, *shiftData, *plusData, *crossData;
  REAL8 *phiData, *delayData;
  REAL8 aOff, fOff, phiOff, shiftOff, polOff, delayOff;
  REAL8 aDt, fDt, phiDt, shiftDt, polDt, delayDt;

  /* Frequencies in the detector transfer function are interpolated
     similarly, except everything is normalized with respect to
     detector->transfer->deltaF. */
  REAL4Vector *aTransfer = NULL;
  REAL4Vector *phiTransfer = NULL;
  REAL4Vector *phiTemp = NULL;
  REAL4 *aTransData = NULL, *phiTransData = NULL;
  REAL8 f0 = 1.0;
  REAL8 phiFac = 1.0, fFac = 1.0;

  /* Heterodyning phase factor LAL_TWOPI*output->f0*output->deltaT,
     and phase offset at the start of the series
     LAL_TWOPI*output->f0*(time offset). */
  REAL8 heteroFac, phi0;

  /* Variables required by the TCENTRE() macro, above. */
  REAL8 realIndex;
  INT4 intIndex;
  REAL8 indexFrac;

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Make sure parameter structures and their fields exist. */
  ASSERT( CWsignal, stat, SIMULATECOHERENTGWH_ENUL,
          SIMULATECOHERENTGWH_MSGENUL );
  if ( !( CWsignal->a ) ) {
    ABORT( stat, SIMULATECOHERENTGWH_ESIG,
           SIMULATECOHERENTGWH_MSGESIG );
  }
  ASSERT( CWsignal->a->data, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  ASSERT( CWsignal->a->data->data, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  if ( !( CWsignal->phi ) ) {
    ABORT( stat, SIMULATECOHERENTGWH_ESIG,
           SIMULATECOHERENTGWH_MSGESIG );
  }
  ASSERT( CWsignal->phi->data, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  ASSERT( CWsignal->phi->data->data, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  if ( CWsignal->f ) {
    ASSERT( CWsignal->f->data, stat,
            SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
    ASSERT( CWsignal->f->data->data, stat,
            SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  }
  if ( CWsignal->shift ) {
    ASSERT( CWsignal->shift->data, stat,
            SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
    ASSERT( CWsignal->shift->data->data, stat,
            SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  }
  ASSERT( detector, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  if ( ( transfer = ( detector->transfer != NULL ) ) ) {
    ASSERT( detector->transfer->data, stat,
            SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
    ASSERT( detector->transfer->data->data, stat,
            SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  }
  ASSERT( output, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  ASSERT( output->data, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );
  ASSERT( output->data->data, stat,
          SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL );

  /* Check dimensions of amplitude array. */
  ASSERT( CWsignal->a->data->vectorLength == 2, stat,
          SIMULATECOHERENTGWH_EDIM, SIMULATECOHERENTGWH_MSGEDIM );

  /* Make sure we never divide by zero. */
  ASSERT( CWsignal->a->deltaT != 0.0, stat,
          SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  ASSERT( CWsignal->phi->deltaT != 0.0, stat,
          SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  aDt = output->deltaT / CWsignal->a->deltaT;
  phiDt = output->deltaT / CWsignal->phi->deltaT;
  ASSERT( aDt != 0.0, stat,
          SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  ASSERT( phiDt != 0.0, stat,
          SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  if ( CWsignal->f ) {
    ASSERT( CWsignal->f->deltaT != 0.0, stat,
            SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
    fDt = output->deltaT / CWsignal->f->deltaT;
    ASSERT( fDt != 0.0, stat,
            SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  } else
    fDt = 0.0;
  if ( CWsignal->shift ) {
    ASSERT( CWsignal->shift->deltaT != 0.0, stat,
            SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
    shiftDt = output->deltaT / CWsignal->shift->deltaT;
    ASSERT( shiftDt != 0.0, stat,
            SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  } else
    shiftDt = 0.0;
  if ( transfer ) {
    ASSERT( detector->transfer->deltaF != 0.0, stat,
            SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
    fFac = 1.0 / detector->transfer->deltaF;
    phiFac = fFac / ( LAL_TWOPI*CWsignal->phi->deltaT );
    f0 = detector->transfer->f0/detector->transfer->deltaF;
  }
  heteroFac = LAL_TWOPI*output->f0*output->deltaT;
  phi0 = (REAL8)( output->epoch.gpsSeconds -
                  detector->heterodyneEpoch.gpsSeconds );
  phi0 += 0.000000001*(REAL8)( output->epoch.gpsNanoSeconds -
                               detector->heterodyneEpoch.gpsNanoSeconds );
  phi0 *= LAL_TWOPI*output->f0;
  if ( phi0 > 1.0/LAL_REAL8_EPS ) {
    LALWarning( stat, "REAL8 arithmetic is not sufficient to maintain"
                " heterodyne phase to within a radian." );
  }

  /* Check units on input, and set units on output. */
  {
    ASSERT( XLALUnitCompare( &(CWsignal->f->sampleUnits), &lalHertzUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT );
    ASSERT( XLALUnitCompare( &(CWsignal->phi->sampleUnits), &lalDimensionlessUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT );
    if( CWsignal->shift ) {
      ASSERT( XLALUnitCompare( &(CWsignal->shift->sampleUnits), &lalDimensionlessUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT );
    }
    if ( transfer ) {
      if ( XLALUnitMultiply( &(output->sampleUnits), &(CWsignal->a->sampleUnits), &(detector->transfer->sampleUnits) ) == NULL ) {
        ABORT( stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT );
      }
    } else {
      output->sampleUnits = CWsignal->a->sampleUnits;
    }
    snprintf( output->name, LALNameLength, "response to %s", CWsignal->a->name );
  }

  /* Define temporary variables to access the data of CWsignal->a,
     CWsignal->f, and CWsignal->phi. */
  aData = CWsignal->a->data->data;
  INT4 aLen = CWsignal->a->data->length * CWsignal->a->data->vectorLength;
  phiData = CWsignal->phi->data->data;
  INT4 phiLen = CWsignal->phi->data->length;
  outData = output->data->data;
  INT4 fLen=0, shiftLen=0;
  if ( CWsignal->f )
    {
      fData = CWsignal->f->data->data;
      fLen = CWsignal->f->data->length;
    }
  else
    {
      fData = NULL;
    }

  if ( CWsignal->shift )
    {
      shiftData = CWsignal->shift->data->data;
      shiftLen = CWsignal->shift->data->length;
    }
  else
    {
      shiftData = NULL;
    }

  /* Convert source position to equatorial coordinates, if
     required. */
  if ( detector->site ) {
    source = CWsignal->position;
    if ( source.system != COORDINATESYSTEM_EQUATORIAL ) {
      ConvertSkyParams params; /* parameters for conversion */
      EarthPosition location;  /* location of detector */
      params.gpsTime = &( output->epoch );
      params.system = COORDINATESYSTEM_EQUATORIAL;
      if ( source.system == COORDINATESYSTEM_HORIZON ) {
        params.zenith = &( location.geodetic );
        location.x = detector->site->location[0];
        location.y = detector->site->location[1];
        location.z = detector->site->location[2];
        TRY( LALGeocentricToGeodetic( stat->statusPtr, &location ),
             stat );
      }
      TRY( LALConvertSkyCoordinates( stat->statusPtr, &source,
                                     &source, &params ), stat );
    }
  }

  /* Generate the table of propagation delays.
     dtDelayBy2 = (UINT4)( 38924.9/sqrt( output->f0 +
     1.0/output->deltaT ) ); */
  delayDt = output->deltaT/( 2.0*dtDelayBy2 );
  nMax = (UINT4)( output->data->length*delayDt ) + 3;
  TRY( LALDCreateVector( stat->statusPtr, &delay, nMax ), stat );
  delayData = delay->data;

  /* Compute delay from solar system barycentre. */
  if ( detector->site && detector->ephemerides ) {
    LIGOTimeGPS gpsTime;   /* detector time when we compute delay */
    EarthState state;      /* Earth position info at that time */
    BarycenterInput input; /* input structure to LALBarycenter() */
    EmissionTime emit;     /* output structure from LALBarycenter() */

    /* Arrange nested pointers, and set initial values. */
    gpsTime = input.tgps = output->epoch;
    gpsTime.gpsSeconds -= dtDelayBy2;
    input.tgps.gpsSeconds -= dtDelayBy2;
    input.site = *(detector->site);
    for ( i = 0; i < 3; i++ )
      input.site.location[i] /= LAL_C_SI;
    input.alpha = source.longitude;
    input.delta = source.latitude;
    input.dInv = 0.0;
    delayMin = delayMax = 1.1*LAL_AU_SI/( LAL_C_SI*output->deltaT );
    delayMax *= -1;

    /* Compute table. */
    for ( i = 0; i < nMax; i++ ) {
      REAL8 tDelay; /* propagation time */
      LALBarycenterEarth( stat->statusPtr, &state, &gpsTime,
                          detector->ephemerides );
      BEGINFAIL( stat )
        TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
      ENDFAIL( stat );
      LALBarycenter( stat->statusPtr, &emit, &input, &state );
      BEGINFAIL( stat )
        TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
      ENDFAIL( stat );
      delayData[i] = tDelay = emit.deltaT/output->deltaT;
      if ( tDelay < delayMin )
        delayMin = tDelay;
      if ( tDelay > delayMax )
        delayMax = tDelay;
      gpsTime.gpsSeconds += 2*dtDelayBy2;
      input.tgps.gpsSeconds += 2*dtDelayBy2;
    }
  }

  /* No information from which to compute delays. */
  else {
    LALInfo( stat, "Detector site and ephemerides absent; simulating hplus with no"
             " propagation delays" );
    memset( delayData, 0, nMax*sizeof(REAL8) );
    delayMin = delayMax = 0.0;
  }

  /* Generate the table of polarization response functions. */
  polDt = output->deltaT/( 2.0*dtPolBy2 );
  nMax = (UINT4)( output->data->length*polDt ) + 3;
  memset( &polResponse, 0, sizeof( LALDetAMResponseSeries ) );
  polResponse.pPlus = (REAL4TimeSeries *)
    LALMalloc( sizeof(REAL4TimeSeries) );
  polResponse.pCross = (REAL4TimeSeries *)
    LALMalloc( sizeof(REAL4TimeSeries) );
  polResponse.pScalar = (REAL4TimeSeries *)
    LALMalloc( sizeof(REAL4TimeSeries) );
  if ( !polResponse.pPlus || !polResponse.pCross ||
       !polResponse.pScalar ) {
    if ( polResponse.pPlus )
      LALFree( polResponse.pPlus );
    if ( polResponse.pCross )
      LALFree( polResponse.pCross );
    if ( polResponse.pScalar )
      LALFree( polResponse.pScalar );
    TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
    ABORT( stat, SIMULATECOHERENTGWH_EMEM,
           SIMULATECOHERENTGWH_MSGEMEM );
  }
  memset( polResponse.pPlus, 0, sizeof(REAL4TimeSeries) );
  memset( polResponse.pCross, 0, sizeof(REAL4TimeSeries) );
  memset( polResponse.pScalar, 0, sizeof(REAL4TimeSeries) );
  LALSCreateVector( stat->statusPtr, &( polResponse.pPlus->data ),
                    nMax );
  BEGINFAIL( stat ) {
    LALFree( polResponse.pPlus );
    LALFree( polResponse.pCross );
    LALFree( polResponse.pScalar );
    TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
  } ENDFAIL( stat );
  LALSCreateVector( stat->statusPtr, &( polResponse.pCross->data ),
                    nMax );
  BEGINFAIL( stat ) {
    TRY( LALSDestroyVector( stat->statusPtr,
                            &( polResponse.pPlus->data ) ), stat );
    LALFree( polResponse.pPlus );
    LALFree( polResponse.pCross );
    LALFree( polResponse.pScalar );
    TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
  } ENDFAIL( stat );
  LALSCreateVector( stat->statusPtr, &( polResponse.pScalar->data ),
                    nMax );
  BEGINFAIL( stat ) {
    TRY( LALSDestroyVector( stat->statusPtr,
                            &( polResponse.pPlus->data ) ), stat );
    TRY( LALSDestroyVector( stat->statusPtr,
                            &( polResponse.pCross->data ) ), stat );
    LALFree( polResponse.pPlus );
    LALFree( polResponse.pCross );
    LALFree( polResponse.pScalar );
    TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
  } ENDFAIL( stat );
  plusData = polResponse.pPlus->data->data;
  crossData = polResponse.pCross->data->data;
  INT4 plusLen = polResponse.pPlus->data->length;
  INT4 crossLen = polResponse.pCross->data->length;
  if ( plusLen != crossLen ) {
    XLALPrintError ("plusLen = %d != crossLen = %d\n", plusLen, crossLen );
    ABORT ( stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD );
  }

  if ( detector->site ) {
    LALSource polSource;     /* position and polarization angle */
    LALDetAndSource input;            /* response input structure */
    LALTimeIntervalAndNSample params; /* response parameter structure */

    /* Arrange nested pointers, and set initial values. */
    polSource.equatorialCoords = source;
    polSource.orientation = (REAL8)( CWsignal->psi );
    input.pSource = &polSource;
    input.pDetector = detector->site;
    params.epoch = output->epoch;
    params.epoch.gpsSeconds -= dtPolBy2;
    params.deltaT = 2.0*dtPolBy2;
    params.nSample = nMax;

    /* Compute table of responses. */
    LALComputeDetAMResponseSeries( stat->statusPtr, &polResponse,
                                   &input, &params );
    BEGINFAIL( stat ) {
      TRY( LALSDestroyVector( stat->statusPtr,
                              &( polResponse.pPlus->data ) ), stat );
      TRY( LALSDestroyVector( stat->statusPtr,
                              &( polResponse.pCross->data ) ), stat );
      TRY( LALSDestroyVector( stat->statusPtr,
                              &( polResponse.pScalar->data ) ), stat );
      LALFree( polResponse.pPlus );
      LALFree( polResponse.pCross );
      LALFree( polResponse.pScalar );
      TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat );
    } ENDFAIL( stat );
  } else {
Пример #27
0
/**
 * \brief Unified "wrapper" to provide a uniform interface to LALPtoleMetric() and LALCoherentMetric().
 * \author Reinhard Prix
 *
 * The parameter structure of LALPtoleMetric() was used, because it's more compact.
 */
void LALPulsarMetric ( LALStatus *stat,
		       REAL8Vector **metric,
		       PtoleMetricIn *input )
{
  MetricParamStruc params = empty_MetricParamStruc;
  PulsarTimesParamStruc spinParams = empty_PulsarTimesParamStruc;
  PulsarTimesParamStruc baryParams = empty_PulsarTimesParamStruc;
  PulsarTimesParamStruc compParams = empty_PulsarTimesParamStruc;
  REAL8Vector *lambda = NULL;
  UINT4 i, nSpin, dim;

  INITSTATUS(stat);
  ATTATCHSTATUSPTR (stat);

  ASSERT ( input, stat, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL );
  ASSERT ( metric != NULL, stat, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL );
  ASSERT ( *metric == NULL, stat, PTOLEMETRICH_ENONULL, PTOLEMETRICH_MSGENONULL );

  if (input->metricType == LAL_PMETRIC_COH_EPHEM) {
    ASSERT ( input->ephemeris != NULL, stat, PTOLEMETRICH_ENULL, PTOLEMETRICH_MSGENULL);
  }


  if ( input->spindown )
    nSpin = input->spindown->length;
  else
    nSpin = 0;


  /* allocate the output-metric */
  dim = 3 + nSpin;	/* dimensionality of parameter-space: Alpha,Delta,f + spindowns */

  TRY ( LALDCreateVector (stat->statusPtr, metric, dim * (dim+1)/2), stat);

  switch (input->metricType)
    {
    case LAL_PMETRIC_COH_PTOLE_ANALYTIC: /* use Ben&Ian's analytic ptolemaic metric */
      LALPtoleMetric (stat->statusPtr, *metric, input);
      BEGINFAIL(stat) {
	LALDDestroyVector (stat->statusPtr, metric);
      }ENDFAIL(stat);
      break;

    case LAL_PMETRIC_COH_PTOLE_NUMERIC:   /* use CoherentMetric + Ptolemaic timing */
    case LAL_PMETRIC_COH_EPHEM:   /* use CoherentMetric + ephemeris timing */
      /* Set up constant parameters for barycentre transformation. */
      baryParams.epoch = input->epoch;
      baryParams.t0 = 0;
      /* FIXME: should be redundant now, with Detector passed */
      baryParams.latitude = input->site->frDetector.vertexLatitudeRadians;
      baryParams.longitude = input->site->frDetector.vertexLongitudeRadians;

      baryParams.site = input->site;
      LALGetEarthTimes( stat->statusPtr, &baryParams );
      BEGINFAIL(stat) {
	LALDDestroyVector (stat->statusPtr, metric);
      }ENDFAIL(stat);

      /* set timing-function for earth-motion: either ptolemaic or ephemeris */
      if (input->metricType == LAL_PMETRIC_COH_PTOLE_NUMERIC)
	{
	  baryParams.t1 = LALTBaryPtolemaic;
	  baryParams.dt1 = LALDTBaryPtolemaic;
	}
      else	/* use precise ephemeris-timing */
	{
	  baryParams.t1 = LALTEphemeris;	/* LAL-bug: fix type of LALTEphemeris! */
	  baryParams.dt1 = LALDTEphemeris;
	  baryParams.ephemeris = input->ephemeris;
	}


      /* Set up input structure for CoherentMetric()  */
      if (nSpin)
	{
	  /* Set up constant parameters for spindown transformation. */
	  spinParams.epoch = input->epoch;
	  spinParams.t0 = 0;

	  /* Set up constant parameters for composed transformation. */
	  compParams.epoch = input->epoch;
	  compParams.t1 = baryParams.t1;
	  compParams.dt1 = baryParams.dt1;
	  compParams.t2 = LALTSpin;
	  compParams.dt2 = LALDTSpin;
	  compParams.constants1 = &baryParams;
	  compParams.constants2 = &spinParams;
	  compParams.nArgs = 2;

	  params.dtCanon = LALDTComp;
	  params.constants = &compParams;
	}
      else	/* simple case: just account for earth motion */
	{
	  params.dtCanon = baryParams.dt1;
	  params.constants = &baryParams;
	}

      params.start = 0;
      params.deltaT = (REAL8) input->duration;
      params.n = 1; 	/* only 1 stack */
      params.errors = 0;

      /* Set up the parameter list. */
      LALDCreateVector( stat->statusPtr, &lambda, nSpin + 2 + 1 );
      BEGINFAIL(stat) {
	LALDDestroyVector (stat->statusPtr, metric);
      }ENDFAIL(stat);

      lambda->data[0] = (REAL8) input->maxFreq;
      lambda->data[1] = (REAL8) input->position.longitude;	/* Alpha */
      lambda->data[2] = (REAL8) input->position.latitude;	/* Delta */

      if ( nSpin )
	{
	  for (i=0; i < nSpin; i++)
	    lambda->data[3 + i] = (REAL8) input->spindown->data[i];
	}

      /* _finally_ we can call the metric */
      LALCoherentMetric( stat->statusPtr, *metric, lambda, &params );
      BEGINFAIL(stat) {
	LALDDestroyVector (stat->statusPtr, metric);
	LALDDestroyVector( stat->statusPtr, &lambda );
      }ENDFAIL(stat);

      LALDDestroyVector( stat->statusPtr, &lambda );
      BEGINFAIL(stat) {
	LALDDestroyVector (stat->statusPtr, metric);
      }ENDFAIL(stat);

      break;

    default:
      XLALPrintError ("Unknown metric type `%d`\n", input->metricType);
      ABORT (stat, PTOLEMETRICH_EMETRIC,  PTOLEMETRICH_MSGEMETRIC);
      break;

    } /* switch type */

  DETATCHSTATUSPTR (stat);
  RETURN (stat);

} /* LALPulsarMetric() */
Пример #28
0
void
LALRingInjectSignals(
    LALStatus               *stat,
    REAL4TimeSeries         *series,
    SimRingdownTable        *injections,
    COMPLEX8FrequencySeries *resp,
    INT4                     calType
    )

{
  UINT4              k;
  INT4               injStartTime;
  INT4               injStopTime;
  DetectorResponse   detector;
  COMPLEX8Vector    *unity = NULL;
  CoherentGW         waveform;
  RingParamStruc     ringParam;
  REAL4TimeSeries    signalvec;
  SimRingdownTable  *simRingdown=NULL;
  LALDetector       *tmpDetector=NULL /*,*nullDetector=NULL*/;
  COMPLEX8FrequencySeries    *transfer = NULL;

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* set up start and end of injection zone TODO: fix this hardwired 10 */
  injStartTime = series->epoch.gpsSeconds - 10;
  injStopTime = series->epoch.gpsSeconds + 10 + (INT4)(series->data->length
      * series->deltaT);

  /*
   *compute the transfer function
   */

  /* allocate memory and copy the parameters describing the freq series */
  memset( &detector, 0, sizeof( DetectorResponse ) );
  transfer = (COMPLEX8FrequencySeries *)
    LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) );
  if ( ! transfer )
  {
    ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
  }
  memcpy( &(transfer->epoch), &(resp->epoch),
      sizeof(LIGOTimeGPS) );
  transfer->f0 = resp->f0;
  transfer->deltaF = resp->deltaF;

  tmpDetector = detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) );
  /* set the detector site */
  switch ( series->name[0] )
  {
    case 'H':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF];
      LALWarning( stat, "computing waveform for Hanford." );
      break;
    case 'L':
      *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF];
      LALWarning( stat, "computing waveform for Livingston." );
      break;
    default:
      LALFree( detector.site );
      detector.site = NULL;
      tmpDetector = NULL;
      LALWarning( stat, "Unknown detector site, computing plus mode "
          "waveform with no time delay" );
      break;
  }

  /* set up units for the transfer function */
  if (XLALUnitDivide( &(detector.transfer->sampleUnits),
                      &lalADCCountUnit, &lalStrainUnit ) == NULL) {
    ABORTXLAL(stat);
  }

  /* invert the response function to get the transfer function */
  LALCCreateVector( stat->statusPtr, &( transfer->data ),
      resp->data->length );
  CHECKSTATUSPTR( stat );

  LALCCreateVector( stat->statusPtr, &unity, resp->data->length );
  CHECKSTATUSPTR( stat );
  for ( k = 0; k < resp->data->length; ++k )
  {
    unity->data[k] = 1.0;
  }

  LALCCVectorDivide( stat->statusPtr, transfer->data, unity,
      resp->data );
  CHECKSTATUSPTR( stat );

  LALCDestroyVector( stat->statusPtr, &unity );
  CHECKSTATUSPTR( stat );

  /* Set up a time series to hold signal in ADC counts */
  signalvec.deltaT = series->deltaT;
  if ( ( signalvec.f0 = series->f0 ) != 0 )
  {
    ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
  }
  signalvec.sampleUnits = lalADCCountUnit;

  signalvec.data=NULL;
  LALSCreateVector( stat->statusPtr, &(signalvec.data),
      series->data->length );
  CHECKSTATUSPTR( stat );

  /* loop over list of waveforms and inject into data stream */
  simRingdown = injections;
  while ( simRingdown )
  {
    /* only do the work if the ring is in injection zone */
    if( (injStartTime - simRingdown->geocent_start_time.gpsSeconds) *
        (injStopTime - simRingdown->geocent_start_time.gpsSeconds) > 0 )
    {
      simRingdown = simRingdown->next;
      continue;
    }

    /* set the ring params */
    ringParam.deltaT = series->deltaT;
    if( !( strcmp( simRingdown->coordinates, "HORIZON" ) ) )
    {
      ringParam.system = COORDINATESYSTEM_HORIZON;
    }
    else if ( !( strcmp( simRingdown->coordinates, "ZENITH" ) ) )
    {
      /* set coordinate system for completeness */
      ringParam.system = COORDINATESYSTEM_EQUATORIAL;
      detector.site = NULL;
    }
    else if ( !( strcmp( simRingdown->coordinates, "GEOGRAPHIC" ) ) )
    {
     ringParam.system = COORDINATESYSTEM_GEOGRAPHIC;
    }
    else if ( !( strcmp( simRingdown->coordinates, "EQUATORIAL" ) ) )
    {
      ringParam.system = COORDINATESYSTEM_EQUATORIAL;
    }
    else if ( !( strcmp( simRingdown->coordinates, "ECLIPTIC" ) ) )
    {
      ringParam.system = COORDINATESYSTEM_ECLIPTIC;
    }
    else if ( !( strcmp( simRingdown->coordinates, "GALACTIC" ) ) )
    {
      ringParam.system = COORDINATESYSTEM_GALACTIC;
    }
    else
      ringParam.system = COORDINATESYSTEM_EQUATORIAL;

    /* generate the ring */
    memset( &waveform, 0, sizeof(CoherentGW) );
    LALGenerateRing( stat->statusPtr, &waveform, series, simRingdown, &ringParam );
    CHECKSTATUSPTR( stat );

    /* print the waveform to a file */
    if ( 0 )
      {
        FILE *fp;
        char fname[512];
        UINT4 jj, kplus, kcross;
        snprintf( fname, sizeof(fname) / sizeof(*fname),
            "waveform-%d-%d-%s.txt",
            simRingdown->geocent_start_time.gpsSeconds,
            simRingdown->geocent_start_time.gpsNanoSeconds,
            simRingdown->waveform );
        fp = fopen( fname, "w" );

        for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length;
            ++jj, kplus += 2, kcross +=2 )
          {
            fprintf(fp, "%d %e %e %le %e\n", jj,
                waveform.a->data->data[kplus],
                waveform.a->data->data[kcross],
                waveform.phi->data->data[jj],
                waveform.f->data->data[jj]);
            }
        fclose( fp );
        }
    /* end */
#if 0
    fprintf( stderr, "a->epoch->gpsSeconds = %d\na->epoch->gpsNanoSeconds = %d\n",
        waveform.a->epoch.gpsSeconds, waveform.a->epoch.gpsNanoSeconds );
    fprintf( stderr, "phi->epoch->gpsSeconds = %d\nphi->epoch->gpsNanoSeconds = %d\n",
        waveform.phi->epoch.gpsSeconds, waveform.phi->epoch.gpsNanoSeconds );
    fprintf( stderr, "f->epoch->gpsSeconds = %d\nf->epoch->gpsNanoSeconds = %d\n",
        waveform.f->epoch.gpsSeconds, waveform.f->epoch.gpsNanoSeconds );
#endif
    /* must set the epoch of signal since it's used by coherent GW */
    signalvec.epoch = series->epoch;
    memset( signalvec.data->data, 0, signalvec.data->length * sizeof(REAL4) );

    /* decide which way to calibrate the data; defaul to old way */
    if( calType )
      detector.transfer=NULL;
    else
      detector.transfer=transfer;

    /* convert this into an ADC signal */
    LALSimulateCoherentGW( stat->statusPtr,
        &signalvec, &waveform, &detector );
    CHECKSTATUSPTR( stat );


/* print the waveform to a file */
    if ( 0 )
      {
        FILE *fp;
        char fname[512];
        UINT4 jj;
        snprintf( fname, sizeof(fname) / sizeof(*fname),
            "signal-%d-%d-%s.txt",
            simRingdown->geocent_start_time.gpsSeconds,
            simRingdown->geocent_start_time.gpsNanoSeconds,
            simRingdown->waveform );
        fp = fopen( fname, "w" );

        for( jj = 0; jj < signalvec.data->length; ++jj )
          {
            fprintf( fp, "%d %le\n", jj, signalvec.data->data[jj] );
          }
        fclose( fp );
        }
    /* end */
#if 0
    fprintf( stderr, "series.epoch->gpsSeconds = %d\nseries.epoch->gpsNanoSeconds = %d\n",
        series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds );
    fprintf( stderr, "signalvec->epoch->gpsSeconds = %d\nsignalvec->epoch->gpsNanoSeconds = %d\n",
        signalvec.epoch.gpsSeconds, signalvec.epoch.gpsNanoSeconds );
#endif
    /* if calibration using RespFilt */
    if( calType == 1 )
      XLALRespFilt(&signalvec, transfer);

    /* inject the signal into the data channel */
    LALSSInjectTimeSeries( stat->statusPtr, series, &signalvec );
    CHECKSTATUSPTR( stat );

/* free memory in coherent GW structure.  TODO:  fix this */
    LALSDestroyVectorSequence( stat->statusPtr, &( waveform.a->data ) );
    CHECKSTATUSPTR( stat );
    LALSDestroyVector( stat->statusPtr, &( waveform.f->data ) );
    CHECKSTATUSPTR( stat );
    LALDDestroyVector( stat->statusPtr, &( waveform.phi->data ) );
    CHECKSTATUSPTR( stat );
    LALFree( waveform.a );   waveform.a = NULL;
    LALFree( waveform.f );   waveform.f = NULL;
    LALFree( waveform.phi );  waveform.phi = NULL;

    /* reset the detector site information in case it changed */
    detector.site = tmpDetector;

    /* move on to next one */
    simRingdown = simRingdown->next;
  }

  /* destroy the signal */
  LALSDestroyVector( stat->statusPtr, &(signalvec.data) );
  CHECKSTATUSPTR( stat );

  LALCDestroyVector( stat->statusPtr, &( transfer->data ) );
  CHECKSTATUSPTR( stat );

  if ( detector.site ) LALFree( detector.site );
  LALFree( transfer );

  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
Пример #29
0
void
LALFindChirpTDTemplate (
    LALStatus                  *status,
    FindChirpTemplate          *fcTmplt,
    InspiralTemplate           *tmplt,
    FindChirpTmpltParams       *params
    )

{
  UINT4         j;
  UINT4         shift;
  UINT4         waveLength;
  UINT4         numPoints;
  REAL4        *xfac;
  REAL8         deltaF;
  REAL8         deltaT;
  REAL8         sampleRate;
  const REAL4   cannonDist = 1.0; /* Mpc */
  /*CHAR          infomsg[512];*/
  PPNParamStruc ppnParams;
  CoherentGW    waveform;

  REAL4Vector  *tmpxfac = NULL; /* Used for band-passing */


  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );


  /*
   *
   * check that the arguments are reasonable
   *
   */


  /* check that the output structures exist */
  ASSERT( fcTmplt, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );
  ASSERT( fcTmplt->data, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );
  ASSERT( fcTmplt->data->data, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );

  /* check that the parameter structure exists */
  ASSERT( params, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );
  ASSERT( params->xfacVec, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );
  ASSERT( params->xfacVec->data, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );

  /* check we have an fft plan for the template */
  ASSERT( params->fwdPlan, status,
      FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );

  /* check that the timestep is positive */
  ASSERT( params->deltaT > 0, status,
      FINDCHIRPTDH_EDELT, FINDCHIRPTDH_MSGEDELT );

  /* check that the input exists */
  ASSERT( tmplt, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );

  /* check that the parameter structure is set to a time domain approximant */
  switch ( params->approximant )
  {
    case TaylorT1:
    case TaylorT2:
    case TaylorT3:
    case TaylorT4:
    case GeneratePPN:
    case PadeT1:
    case EOB:
    case EOBNR:
    case FindChirpPTF:
    case EOBNRv2:
    case IMRPhenomB:
    case IMRPhenomC:
      break;

    default:
      ABORT( status, FINDCHIRPTDH_EMAPX, FINDCHIRPTDH_MSGEMAPX );
      break;
  }

  /* store deltaT and zero out the time domain waveform vector */
  deltaT = params->deltaT;
  sampleRate = 1.0 / deltaT;
  xfac = params->xfacVec->data;
  numPoints =  params->xfacVec->length;
  memset( xfac, 0, numPoints * sizeof(REAL4) );

  ASSERT( numPoints == (2 * (fcTmplt->data->length - 1)), status,
      FINDCHIRPTDH_EMISM, FINDCHIRPTDH_MSGEMISM );


  /* choose the time domain template */
  if ( params->approximant == GeneratePPN )
  {


    /*
     *
     * generate the waveform using LALGeneratePPNInspiral() from inject
     *
     */



    /* input parameters */
    memset( &ppnParams, 0, sizeof(PPNParamStruc) );
    ppnParams.deltaT = deltaT;
    ppnParams.mTot = tmplt->mass1 + tmplt->mass2;
    ppnParams.eta = tmplt->mass1 * tmplt->mass2 /
      ( ppnParams.mTot * ppnParams.mTot );
    ppnParams.d = 1.0;
    ppnParams.fStartIn = params->fLow;
    ppnParams.fStopIn = -1.0 /
      (6.0 * sqrt(6.0) * LAL_PI * ppnParams.mTot * LAL_MTSUN_SI);

    /* generate waveform amplitude and phase */
    memset( &waveform, 0, sizeof(CoherentGW) );
    LALGeneratePPNInspiral( status->statusPtr, &waveform, &ppnParams );
    CHECKSTATUSPTR( status );

    /* print termination information and check sampling */
    LALInfo( status, ppnParams.termDescription );
    if ( ppnParams.dfdt > 2.0 )
    {
      ABORT( status, FINDCHIRPTDH_ESMPL, FINDCHIRPTDH_MSGESMPL );
    }
    if ( waveform.a->data->length > numPoints )
    {
      ABORT( status, FINDCHIRPTDH_ELONG, FINDCHIRPTDH_MSGELONG );
    }

    /* compute h(t) */
    for ( j = 0; j < waveform.a->data->length; ++j )
    {
      xfac[j] =
        waveform.a->data->data[2*j] * cos( waveform.phi->data->data[j] );
    }

    /* free the memory allocated by LALGeneratePPNInspiral() */
    LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) );
    CHECKSTATUSPTR( status );

    LALSDestroyVector( status->statusPtr, &(waveform.f->data) );
    CHECKSTATUSPTR( status );

    LALDDestroyVector( status->statusPtr, &(waveform.phi->data) );
    CHECKSTATUSPTR( status );

    LALFree( waveform.a );
    LALFree( waveform.f );
    LALFree( waveform.phi );

    /* waveform parameters needed for findchirp filter */
    tmplt->approximant = params->approximant;
    tmplt->tC = ppnParams.tc;
    tmplt->fFinal = ppnParams.fStop;

    fcTmplt->tmpltNorm = params->dynRange / ( cannonDist * 1.0e6 * LAL_PC_SI );
    fcTmplt->tmpltNorm *= fcTmplt->tmpltNorm;
  }
  else
  {


    /*
     *
     * generate the waveform by calling LALInspiralWave() from inspiral
     *
     */


    /* set up additional template parameters */
    deltaF = 1.0 / ((REAL8) numPoints * deltaT);
    tmplt->ieta            = 1;
    tmplt->approximant     = params->approximant;
    tmplt->order           = params->order;
    tmplt->massChoice      = m1Andm2;
    tmplt->tSampling       = sampleRate;
    tmplt->fLower          = params->fLow;
    tmplt->fCutoff         = sampleRate / 2.0 - deltaF;
    /* get the template norm right */
    if ( params->approximant==EOBNR )
    {
     /* lalinspiral EOBNR code produces correct norm when 
        fed unit signalAmplitude and non-physical distance */
      tmplt->signalAmplitude = 1.0;
      tmplt->distance      = -1.0;
    }
    else if ( params->approximant==EOBNRv2 )
    {
     /* this formula sets the ampl0 variable to 1.0 
      * within the lalsimulation EOBNRv2 waveform engine 
      * which again produces a correct template norm     */
      tmplt->distance      = tmplt->totalMass*LAL_MRSUN_SI;
    }
    else if ( (params->approximant==IMRPhenomB) || (params->approximant==IMRPhenomC) )
    {
      /* 1Mpc standard distance - not clear if this produces correct norm */
      tmplt->distance      = 1.0;
      tmplt->spin1[2]      = 2 * tmplt->chi/(1. + sqrt(1.-4.*tmplt->eta));
    }

    /* compute the tau parameters from the input template */
    LALInspiralParameterCalc( status->statusPtr, tmplt );
    CHECKSTATUSPTR( status );

    /* determine the length of the chirp in sample points */
    LALInspiralWaveLength( status->statusPtr, &waveLength, *tmplt );
    CHECKSTATUSPTR( status );

    if ( waveLength > numPoints )
    {
      ABORT( status, FINDCHIRPTDH_ELONG, FINDCHIRPTDH_MSGELONG );
    }

    /* generate the chirp in the time domain */
    LALInspiralWave( status->statusPtr, params->xfacVec, tmplt );
    CHECKSTATUSPTR( status );


    /* template dependent normalization */
    fcTmplt->tmpltNorm  = 2 * tmplt->mu;
    fcTmplt->tmpltNorm *= 2 * LAL_MRSUN_SI / ( cannonDist * 1.0e6 * LAL_PC_SI );
    fcTmplt->tmpltNorm *= params->dynRange;
    fcTmplt->tmpltNorm *= fcTmplt->tmpltNorm;
  }


  /* Taper the waveform if required */
  if ( params->taperTmplt != LAL_SIM_INSPIRAL_TAPER_NONE )
  {
    if ( XLALSimInspiralREAL4WaveTaper( params->xfacVec, params->taperTmplt )
           == XLAL_FAILURE )
    {
      ABORTXLAL( status );
    }
  }

  /* Find the end of the chirp */
  j = numPoints - 1;
  while ( xfac[j] == 0 )
  {
    /* search for the end of the chirp but don't fall off the array */
    if ( --j == 0 )
    {
      ABORT( status, FINDCHIRPTDH_EEMTY, FINDCHIRPTDH_MSGEEMTY );
    }
  }
  ++j;

  /* Band pass the template if required */
  if ( params->bandPassTmplt )
  {
    REAL4Vector bpVector; /*Used to save time */

    /* We want to shift the template to the middle of the vector so */
    /* that band-passing will work properly */
    shift = ( numPoints - j ) / 2;
    memmove( xfac + shift, xfac, j * sizeof( *xfac ) );
    memset( xfac, 0, shift * sizeof( *xfac ) );
    memset( xfac + ( numPoints + j ) / 2, 0,
         ( numPoints - ( numPoints + j ) / 2 ) * sizeof( *xfac ) );


    /* Select an appropriate part of the vector to band pass. */
    /* band passing the whole thing takes a lot of time */
    if ( j > 2 * sampleRate && 2 * j <= numPoints )
    {
      bpVector.length = 2 * j;
      bpVector.data   = params->xfacVec->data + numPoints / 2 - j;
    }
    else if ( j <= 2 * sampleRate && j + 2 * sampleRate <= numPoints )
    {
      bpVector.length = j + 2 * sampleRate;
      bpVector.data   = params->xfacVec->data
                   + ( numPoints - j ) / 2 - (INT4)sampleRate;
    }
    else
    {
      bpVector.length = params->xfacVec->length;
      bpVector.data   = params->xfacVec->data;
    }

    if ( XLALBandPassInspiralTemplate( &bpVector, 0.95 * tmplt->fLower,
                 1.02 * tmplt->fFinal, sampleRate ) == XLAL_FAILURE )
    {
      ABORTXLAL( status );
    }

    /* Now we need to do the shift to the end. */
    /* Use a temporary vector to avoid mishaps */
    if ( ( tmpxfac = XLALCreateREAL4Vector( numPoints ) ) == NULL )
    {
      ABORTXLAL( status );
    }

    if ( params->approximant == EOBNR || params->approximant == EOBNRv2
        || params->approximant == IMRPhenomB || params->approximant == IMRPhenomC )
    {
      /* We need to do something slightly different for EOBNR */
      UINT4 endIndx = (UINT4) (tmplt->tC * sampleRate);

      memcpy( tmpxfac->data, xfac + ( numPoints - j ) / 2 + endIndx,
          ( numPoints - ( numPoints - j ) / 2 - endIndx ) * sizeof( *xfac ) );

      memcpy( tmpxfac->data + numPoints - ( numPoints - j ) / 2 - endIndx,
                  xfac, ( ( numPoints - j ) / 2 + endIndx ) * sizeof( *xfac ) );
    }
    else
    {
      memcpy( tmpxfac->data, xfac + ( numPoints + j ) / 2,
          ( numPoints - ( numPoints + j ) / 2 ) * sizeof( *xfac ) );

      memcpy( tmpxfac->data + numPoints - ( numPoints + j ) / 2,
                    xfac, ( numPoints + j ) / 2 * sizeof( *xfac ) );
    }

    memcpy( xfac, tmpxfac->data, numPoints * sizeof( *xfac ) );

    XLALDestroyREAL4Vector( tmpxfac );
    tmpxfac = NULL;
  }
  else if ( params->approximant == EOBNR || params->approximant == EOBNRv2
      || params->approximant == IMRPhenomB || params->approximant == IMRPhenomC )
  {
    /* For EOBNR we shift so that tC is at the end of the vector */
    if ( ( tmpxfac = XLALCreateREAL4Vector( numPoints ) ) == NULL )
    {
      ABORTXLAL( status );
    }

    /* Set the coalescence index depending on tC */
    j = (UINT4) (tmplt->tC * sampleRate);
    memcpy( tmpxfac->data + numPoints - j, xfac, j * sizeof( *xfac ) );
    memcpy( tmpxfac->data, xfac + j, ( numPoints - j ) * sizeof( *xfac ) );
    memcpy( xfac, tmpxfac->data, numPoints * sizeof( *xfac ) );
    XLALDestroyREAL4Vector( tmpxfac );
    tmpxfac = NULL;
  }
  else
  {
    /* No need for so much shifting around if not band passing */
    /* shift chirp to end of vector so it is the correct place for the filter */
    memmove( xfac + numPoints - j, xfac, j * sizeof( *xfac ) );
    memset( xfac, 0, ( numPoints - j ) * sizeof( *xfac ) );
  }

  /*
   *
   * create the frequency domain findchirp template
   *
   */

  /* fft chirp */
  if ( XLALREAL4ForwardFFT( fcTmplt->data, params->xfacVec,
      params->fwdPlan ) == XLAL_FAILURE )
  {
    ABORTXLAL( status );
  }

  /* copy the template parameters to the findchirp template structure */
  memcpy( &(fcTmplt->tmplt), tmplt, sizeof(InspiralTemplate) );

  /* normal exit */
  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Пример #30
0
/**
 * \brief Computes the parameter space metric for a coherent pulsar search.
 * \author Creighton, T. D.
 * \date 2000, 2001
 * \ingroup StackMetric_h
 *
 * ### Description ###
 *
 * This function computes the metric \f$g_{\alpha\beta}(\mathbf{\lambda})\f$, as
 * discussed in \ref StackMetric_h, under the assumption
 * that the detected power is constructed from the incoherent sum of \f$N\f$
 * separate power spectrum, each derived from separate time intervals of
 * length \f$\Delta t\f$.  The indecies \f$\alpha\f$ and \f$\beta\f$ are assumed to
 * run from 0 to \f$n\f$, where \f$n\f$ is the total number of ``shape''
 * parameters.
 *
 * This routine has exactly the same calling structure and data storage
 * as the LALCoherentMetric() function.  Thus, the argument
 * \a *metric is a vector of length \f$(n+1)(n+2)/2\f$ storing all
 * non-redundant coefficients of \f$g_{\alpha\beta}\f$, or twice this length
 * if \a params->errors is nonzero.  See LALCoherentMetric() for
 * the indexing scheme.  The argument \a lambda is another vector,
 * of length \f$n+1\f$, storing the components of
 * \f$\mathbf{\lambda}=(\lambda^0,\ldots,\lambda^n)\f$ for the parameter space
 * point at which the metric is being evaluated.  The argument
 * \a *params stores the remaining parameters for computing the
 * metric, as given in the Structures section of \ref StackMetric_h.
 *
 * ### Algorithm ###
 *
 * Most of what this routine does is set up arguments to be passed to the
 * function LALCoherentMetric().  Each metric component in the stack
 * metric is given simply by:
 * \f[
 * g_{\alpha\beta}(\mathbf{\lambda}) = \frac{1}{N} \sum_{k=1}^N
 * g^{(k)}_{\alpha\beta}(\mathbf{\lambda}) \; ,
 * \f]
 * where \f$g^{(k)}_{\alpha\beta}\f$ is just the coherent metric computed on
 * the time interval \f$[t_\mathrm{start}+(k-1)\Delta t,
 * t_\mathrm{start}+k\Delta t]\f$.  The estimated uncertainty
 * \f$s_{\alpha\beta}\f$ in this component is taken to be:
 * \f[
 * s_{\alpha\beta} = \frac{1}{\sqrt{N}} \max_{k\in\{1,\ldots,N\}}
 * s^{(k)}_{\alpha\beta} \; .
 * \f]
 * There are no clever tricks involved in any of these computations.
 */
void
LALStackMetric( LALStatus        *stat,
		REAL8Vector      *metric,
		REAL8Vector      *lambda,
		MetricParamStruc *params )
{
  INT4 n;  /* Number of metric coefficients. */
  INT4 i;  /* An index. */
  INT4 j;  /* Another index. */
  REAL8 t; /* Time at start of each coherent stretch. */
  REAL8Vector *subMetric=NULL; /* Coherent metric on each stack. */
  MetricParamStruc subParams;  /* Parameters passed to coherent metric
				  computation. */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR(stat);

  /* Make sure parameter structures and their fields exist. */
  ASSERT(metric,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);
  ASSERT(metric->data,stat,STACKMETRICH_ENUL,STACKMETRICH_MSGENUL);

  /* Make sure that metric length is positive. */
  n=metric->length;
  ASSERT(n>0,stat,STACKMETRICH_EBAD,STACKMETRICH_MSGEBAD);

  /* Set up parameters for coherent metric computation. */
  memset(metric->data,0,n*sizeof(REAL8));
  memcpy(&subParams,params,sizeof(MetricParamStruc));
  subParams.n=1;
  TRY(LALDCreateVector(stat->statusPtr,&subMetric,n),stat);
  t=params->start;

  /* Compute coherent metrics and accumulate them. */
  i=params->n;
  while(i--){
    subParams.start=t;
    LALCoherentMetric(stat->statusPtr,subMetric,lambda,&subParams);
    BEGINFAIL(stat)
      TRY(LALDDestroyVector(stat->statusPtr,&subMetric),stat);
    ENDFAIL(stat);
    if(params->errors)
      for(j=0;j<n;j+=2){
	metric->data[j]+=subMetric->data[j];
	if(metric->data[j+1]<subMetric->data[j+1])
	  metric->data[j+1]=subMetric->data[j+1];
      }
    else
      for(j=0;j<n;j++)
	metric->data[j]+=subMetric->data[j];
    t+=params->deltaT;
  }

  /* Compute the average. */
  if(params->errors)
    for(j=0;j<n;j+=2){
      metric->data[j]/=params->n;
      metric->data[j+1]/=sqrt(params->n);
    }
  else
    for(j=0;j<n;j++)
      metric->data[j]/=params->n;

  /* Cleanup and exit. */
  TRY(LALDDestroyVector(stat->statusPtr,&subMetric),stat);
  DETATCHSTATUSPTR(stat);
  RETURN(stat);
}