예제 #1
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 );
}
int main( int argc, char *argv[] )
{
  static LALStatus status;

  RealFFTPlan    *fwd = NULL;
  RealFFTPlan    *rev = NULL;
  REAL4Vector    *dat = NULL;
  REAL4Vector    *rfft = NULL;
  REAL4Vector    *ans = NULL;
  COMPLEX8Vector *dft = NULL;
  COMPLEX8Vector *fft = NULL;
#if LAL_CUDA_ENABLED
  /* The test itself should pass at 1e-4, but it might fail at
   * some rare cases where accuracy is bad for some numbers. */
  REAL8           eps = 3e-4;
#else
  /* very conservative floating point precision */
  REAL8           eps = 1e-6;
#endif
  REAL8           lbn;
  REAL8           ssq;
  REAL8           var;
  REAL8           tol;

  UINT4 nmax;
  UINT4 m;
  UINT4 n;
  UINT4 i;
  UINT4 j;
  UINT4 k;
  UINT4 s = 0;

  FILE *fp;


  ParseOptions( argc, argv );
  m = m_;
  n = n_;

  fp = verbose ? stdout : NULL ;

  if ( n == 0 )
  {
    nmax = 65536;
  }
  else
  {
    nmax = n--;
  }

  while ( n < nmax )
  {
    if ( n < 128 )
    {
      ++n;
    }
    else
    {
      n *= 2;
    }

    LALSCreateVector( &status, &dat, n );
    TestStatus( &status, CODES( 0 ), 1 );
    LALSCreateVector( &status, &rfft, n );
    TestStatus( &status, CODES( 0 ), 1 );
    LALSCreateVector( &status, &ans, n );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCCreateVector( &status, &dft, n / 2 + 1 );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCCreateVector( &status, &fft, n / 2 + 1 );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCreateForwardRealFFTPlan( &status, &fwd, n, 0 );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCreateReverseRealFFTPlan( &status, &rev, n, 0 );
    TestStatus( &status, CODES( 0 ), 1 );

    /*
     *
     * Do m trials of random data.
     *
     */
    for ( i = 0; i < m; ++i )
    {
      srand( s++ ); /* seed the random number generator */

      /*
       *
       * Create data and compute error tolerance.
       *
       * Reference: Kaneko and Liu,
       * "Accumulation of round-off error in fast fourier tranforms"
       * J. Asssoc. Comp. Mach, Vol 17 (No 4) 637-654, October 1970.
       *
       */
      srand( i ); /* seed the random number generator */
      ssq = 0;
      for ( j = 0; j < n; ++j )
      {
        dat->data[j] = 20.0 * rand() / (REAL4)( RAND_MAX + 1.0 ) - 10.0;
        ssq += dat->data[j] * dat->data[j];
        fp ? fprintf( fp, "%e\n", dat->data[j] ) : 0;
      }
      lbn = log( n ) / log( 2 );
      var = 2.5 * lbn * eps * eps * ssq / n;
      tol = 5 * sqrt( var ); /* up to 5 sigma excursions */
      fp ? fprintf( fp, "\neps = %e \ntol = %e\n", eps, tol ) : 0;

      /*
       *
       * Perform forward FFT and DFT (only if n < 100).
       *
       */
      LALForwardRealFFT( &status, fft, dat, fwd );
      TestStatus( &status, CODES( 0 ), 1 );
      LALREAL4VectorFFT( &status, rfft, dat, fwd );
      TestStatus( &status, CODES( 0 ), 1 );
      LALREAL4VectorFFT( &status, ans, rfft, rev );
      TestStatus( &status, CODES( 0 ), 1 );
      fp ?  fprintf( fp, "rfft()\t\trfft(rfft())\trfft(rfft())\n\n"  ) : 0;
      for ( j = 0; j < n; ++j )
      {
        fp ? fprintf( fp, "%e\t%e\t%e\n",
            rfft->data[j], ans->data[j], ans->data[j] / n ) : 0;
      }
      if ( n < 128 )
      {
        LALForwardRealDFT( &status, dft, dat );
        TestStatus( &status, CODES( 0 ), 1 );

        /*
         *
         * Check accuracy of FFT vs DFT.
         *
         */
        fp ? fprintf( fp, "\nfftre\t\tfftim\t\t" ) : 0;
        fp ? fprintf( fp, "dtfre\t\tdftim\n" ) : 0;
        for ( k = 0; k <= n / 2; ++k )
        {
          REAL8 fftre = creal(fft->data[k]);
          REAL8 fftim = cimag(fft->data[k]);
          REAL8 dftre = creal(dft->data[k]);
          REAL8 dftim = cimag(dft->data[k]);
          REAL8 errre = fabs( dftre - fftre );
          REAL8 errim = fabs( dftim - fftim );
          REAL8 avere = fabs( dftre + fftre ) / 2 + eps;
          REAL8 aveim = fabs( dftim + fftim ) / 2 + eps;
          REAL8 ferre = errre / avere;
          REAL8 ferim = errim / aveim;
          fp ? fprintf( fp, "%e\t%e\t", fftre, fftim ) : 0;
          fp ? fprintf( fp, "%e\t%e\n", dftre, dftim ) : 0;
          /* fp ? fprintf( fp, "%e\t%e\t", errre, errim ) : 0; */
          /* fp ? fprintf( fp, "%e\t%e\n", ferre, ferim ) : 0; */
          if ( ferre > eps && errre > tol )
          {
            fputs( "FAIL: Incorrect result from forward transform\n", stderr );
            fprintf( stderr, "\tdifference = %e\n", errre );
            fprintf( stderr, "\ttolerance  = %e\n", tol );
            fprintf( stderr, "\tfrac error = %e\n", ferre );
            fprintf( stderr, "\tprecision  = %e\n", eps );
            return 1;
          }
          if ( ferim > eps && errim > tol )
          {
            fputs( "FAIL: Incorrect result from forward transform\n", stderr );
            fprintf( stderr, "\tdifference = %e\n", errim );
            fprintf( stderr, "\ttolerance  = %e\n", tol );
            fprintf( stderr, "\tfrac error = %e\n", ferim );
            fprintf( stderr, "\tprecision  = %e\n", eps );
            return 1;
          }
        }
      }

      /*
       *
       * Perform reverse FFT and check accuracy vs original data.
       *
       */
      LALReverseRealFFT( &status, ans, fft, rev );
      TestStatus( &status, CODES( 0 ), 1 );
      fp ? fprintf( fp, "\ndat->data[j]\tans->data[j] / n\n" ) : 0;
      for ( j = 0; j < n; ++j )
      {
        REAL8 err = fabs( dat->data[j] - ans->data[j] / n );
        REAL8 ave = fabs( dat->data[j] + ans->data[j] / n ) / 2 + eps;
        REAL8 fer = err / ave;
        fp ? fprintf( fp, "%e\t%e\n", dat->data[j], ans->data[j] / n ) : 0;
        /* fp ? fprintf( fp, "%e\t%e\n", err, fer ) : 0; */
        if ( fer > eps && err > tol )
        {
          fputs( "FAIL: Incorrect result after reverse transform\n", stderr );
          fprintf( stderr, "\tdifference = %e\n", err );
          fprintf( stderr, "\ttolerance  = %e\n", tol );
          fprintf( stderr, "\tfrac error = %e\n", fer );
          fprintf( stderr, "\tprecision  = %e\n", eps );
          return 1;
        }
      }
    }

    LALSDestroyVector( &status, &dat );
    TestStatus( &status, CODES( 0 ), 1 );
    LALSDestroyVector( &status, &rfft );
    TestStatus( &status, CODES( 0 ), 1 );
    LALSDestroyVector( &status, &ans );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCDestroyVector( &status, &dft );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCDestroyVector( &status, &fft );
    TestStatus( &status, CODES( 0 ), 1 );
    LALDestroyRealFFTPlan( &status, &fwd );
    TestStatus( &status, CODES( 0 ), 1 );
    LALDestroyRealFFTPlan( &status, &rev );
    TestStatus( &status, CODES( 0 ), 1 );
  }

  LALCheckMemoryLeaks();
  return 0;
}
예제 #3
0
int
main ( int argc, char *argv[] )
{
  const int size = 8;
  COMPLEX8Vector *z1 = NULL;
  COMPLEX8Vector *z2 = NULL;
  COMPLEX8Vector *z3 = NULL;
  REAL4Vector    *x1 = NULL;
  REAL4Vector    *x2 = NULL;
  REAL4Vector    *x3 = NULL;
  REAL4Vector    *y_1 = NULL;
  REAL4Vector    *y2 = NULL;
  REAL4Vector    *y3 = NULL;
  static LALStatus   status;
  INT4            i;


  ParseOptions( argc, argv );

  LALCCreateVector(&status, &z1, size);
  TestStatus( &status, CODES(0), 1 );
  LALCCreateVector(&status, &z2, size);
  TestStatus( &status, CODES(0), 1 );
  LALCCreateVector(&status, &z3, size);
  TestStatus( &status, CODES(0), 1 );
  LALSCreateVector(&status, &x1, size);
  TestStatus( &status, CODES(0), 1 );
  LALSCreateVector(&status, &x2, size);
  TestStatus( &status, CODES(0), 1 );
  LALSCreateVector(&status, &x3, size);
  TestStatus( &status, CODES(0), 1 );
  LALSCreateVector(&status, &y_1, size/2);
  TestStatus( &status, CODES(0), 1 );
  y2         = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector));
  y2->data   = NULL;
  y2->length = size;
  y3         = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector));
  y3->data   = (REAL4 *)LALMalloc(size*sizeof(REAL4));
  y3->length = 0;

  for (i = 0; i < size; ++i)
  {
    z1->data[i] = 1 + i;
    z1->data[i] += I * (2 + i*i);
    z2->data[i] = 3 + i + i*i*i;
    z2->data[i] += I * (4 + i*i + i*i*i);
    x1->data[i]    = 5 + i + i*i;
    x2->data[i]    = 6 + i + i*i + i*i*i;
  }

  if (verbose) printf("\n");
  LALCCVectorMultiply(&status, z3, z1, z2);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf("(% 6.0f,% 6.0f) x (% 6.0f,% 6.0f) = (% 6.0f,% 6.0f)\n",
        crealf(z1->data[i]), cimagf(z1->data[i]),
        crealf(z2->data[i]), cimagf(z2->data[i]),
        crealf(z3->data[i]), cimagf(z3->data[i]));

  if (verbose) printf("\n");
  LALCCVectorMultiplyConjugate(&status, z3, z1, z2);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf("(% 6.0f,% 6.0f) x (% 6.0f,% 6.0f)* = (% 6.0f,% 6.0f)\n",
        crealf(z1->data[i]), cimagf(z1->data[i]),
        crealf(z2->data[i]), cimagf(z2->data[i]),
        crealf(z3->data[i]), cimagf(z3->data[i]));

  if (verbose) printf("\n");
  LALCCVectorDivide(&status, z3, z1, z2);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf("(% 6.0f,% 6.0f) / (% 6.0f,% 6.0f) = (% 9.6f,% 9.6f)\n",
        crealf(z1->data[i]), cimagf(z1->data[i]),
        crealf(z2->data[i]), cimagf(z2->data[i]),
        crealf(z3->data[i]), cimagf(z3->data[i]));

  if (verbose) printf("\n");
  LALSCVectorMultiply(&status, z3, x1, z1);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf("% 6.0f x (% 6.0f,% 6.0f) = (% 6.0f,% 6.0f)\n",
        crealf(x1->data[i]),
        crealf(z1->data[i]), cimagf(z1->data[i]),
        crealf(z3->data[i]), cimagf(z3->data[i]));

  if (verbose) printf("\n");
  LALSSVectorMultiply(&status, x3, x1, x2);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf("% 6.0f x % 6.0f = % 6.0f\n",
        x1->data[i], x2->data[i], x3->data[i]);

  if (verbose) printf("\n");
#ifndef LAL_NDEBUG
  if ( ! lalNoDebug )
  {
    LALSSVectorMultiply(&status, x3, x1, NULL);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALSSVectorMultiply(&status, x3, y2, x2);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALSSVectorMultiply(&status, y3, x1, x2);
    TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 );
    LALSSVectorMultiply(&status, x3, x1, y_1);
    TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 );
  }
#endif

  LALCDestroyVector(&status, &z1);
  TestStatus( &status, CODES(0), 1 );
  LALCDestroyVector(&status, &z2);
  TestStatus( &status, CODES(0), 1 );
  LALCDestroyVector(&status, &z3);
  TestStatus( &status, CODES(0), 1 );
  LALSDestroyVector(&status, &x1);
  TestStatus( &status, CODES(0), 1 );
  LALSDestroyVector(&status, &x2);
  TestStatus( &status, CODES(0), 1 );
  LALSDestroyVector(&status, &x3);
  TestStatus( &status, CODES(0), 1 );
  LALSDestroyVector(&status, &y_1);
  TestStatus( &status, CODES(0), 1 );
  LALFree(y2);
  LALFree(y3->data);
  LALFree(y3);

  x1 = x2 = x3 = y_1 = y2 = y3 = NULL;
  z1 = z2 = z3 = NULL;


  LALCCreateVector(&status, &z1, size);
  TestStatus( &status, CODES(0), 1 );

  LALSCreateVector(&status, &x1, size);
  TestStatus( &status, CODES(0), 1 );
  LALSCreateVector(&status, &x2, size);
  TestStatus( &status, CODES(0), 1 );
  LALSCreateVector(&status, &x3, size);
  TestStatus( &status, CODES(0), 1 );


  for (i = 0; i < size; ++i)
  {
    z1->data[i] = (12.0 + i) *cos(LAL_PI/3.0*i);
    z1->data[i] += I * (12.0 + i )*sin(LAL_PI/3.0*i);
  }

  if (verbose) printf("\n");
  LALCVectorAbs(&status, x1, z1);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf(" Abs(% f,%f)  = %f \n",
        crealf(z1->data[i]), cimagf(z1->data[i]),
        x1->data[i]);

  LALCVectorAngle(&status, x2, z1);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf(" Angle(%f,%f)  = %f \n",
        crealf(z1->data[i]), cimagf(z1->data[i]),
        x2->data[i]);

  LALUnwrapREAL4Angle(&status, x3, x2);
  TestStatus( &status, CODES(0), 1 );
  for (i = 0; i < size; ++i)
    if (verbose) printf(" Unwrap Phase Angle ( %f )  = %f \n",
        x2->data[i],
        x3->data[i]);


  LALSCreateVector(&status, &y_1, size/2);
  TestStatus( &status, CODES(0), 1 );

  y2         = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector));
  y2->data   = NULL;
  y2->length = size;

  y3         = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector));
  y3->data   = (REAL4 *)LALMalloc(size*sizeof(REAL4));
  y3->length = 0;

  if (verbose) printf("\n");

#ifndef LAL_NDEBUG
  if ( ! lalNoDebug )
  {
    LALCVectorAbs(&status, x1, NULL);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALCVectorAbs(&status, NULL, z1);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALCVectorAbs(&status, y_1, z1);
    TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 );
    LALCVectorAbs(&status, y2, z1);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALCVectorAbs(&status, y3, z1);
    TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 );


    LALCVectorAngle(&status, x2, NULL);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALCVectorAngle(&status, NULL, z1);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALCVectorAngle(&status, y_1, z1);
    TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 );
    LALCVectorAngle(&status, y2, z1);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALCVectorAngle(&status, y3, z1);
    TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 );

    LALUnwrapREAL4Angle(&status, x3, NULL);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALUnwrapREAL4Angle(&status, NULL, x2);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALUnwrapREAL4Angle(&status, y_1, x2);
    TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 );
    LALUnwrapREAL4Angle(&status, y2, x2);
    TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 );
    LALUnwrapREAL4Angle(&status, y3, x2);
    TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 );
    LALUnwrapREAL4Angle(&status, x2, x2);
    TestStatus( &status, CODES(VECTOROPSH_ESAME), 1 );
  }
#endif


  LALCDestroyVector(&status, &z1);
  TestStatus( &status, CODES(0), 1 );

  LALSDestroyVector(&status, &x1);
  TestStatus( &status, CODES(0), 1 );
  LALSDestroyVector(&status, &x2);
  TestStatus( &status, CODES(0), 1 );
  LALSDestroyVector(&status, &x3);
  TestStatus( &status, CODES(0), 1 );

  LALSDestroyVector(&status, &y_1);
  TestStatus( &status, CODES(0), 1 );
  LALFree(y2);
  LALFree(y3->data);
  LALFree(y3);

  LALCheckMemoryLeaks();
  return 0;
}
/**
 * \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 );
}
예제 #5
0
int
main(int argc, char **argv)
{
  static LALStatus stat; /* LALStatus pointer */
  CHAR *infile = NULL;   /* The input filename */
  CHAR *outfile = NULL;  /* The output filename */
  INT4 arg;              /* Argument counter */
  UINT4 npts = NPTS;     /* Number of points in time series */
  UINT4 offset = OFFSET; /* Position of delta function */
  REAL8 dt = DT;         /* Sampling interval. */
  static REAL4TimeSeries series;    /* Time series */
  static PassBandParamStruc params; /* Filter parameters */

  XLALSetErrorHandler( XLALAbortErrorHandler );

  /* Set up the default filter parameters. */
  params.f1 = F1;
  params.f2 = F2;
  params.a1 = A1;
  params.a2 = A2;
  params.nMax = ORDER;

  /* Parse argument list.  i stores the current position. */
  arg = 1;
  while ( arg < argc ) {
    /* Parse debuglevel option. */
    if ( !strcmp( argv[arg], "-d" ) ) {
      if ( argc > arg + 1 ) {
        arg++;
      } else {
	ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BANDPASSTESTC_EARG;
      }
    }
    /* Parse input file option. */
    else if ( !strcmp( argv[arg], "-i" ) ) {
      if ( argc > arg + 1 ) {
        arg++;
        infile = argv[arg++];
      } else {
	ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BANDPASSTESTC_EARG;
      }
    }
    /* Parse output file option. */
    else if ( !strcmp( argv[arg], "-o" ) ) {
      if ( argc > arg + 1 ) {
        arg++;
        outfile = argv[arg++];
      } else {
	ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BANDPASSTESTC_EARG;
      }
    }
    /* Parse filter options. */
    else if ( !strcmp( argv[arg], "-f" ) ) {
      if ( argc > arg + 5 ) {
        arg++;
	params.f1=atof(argv[arg++]);
	params.f2=atof(argv[arg++]);
	params.a1=atof(argv[arg++]);
	params.a2=atof(argv[arg++]);
	params.nMax=atoi(argv[arg++]);
      } else {
	ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BANDPASSTESTC_EARG;
      }
    }
    /* Parse time series options. */
    else if ( !strcmp( argv[arg], "-n" ) ) {
      if ( argc > arg + 3 ) {
        arg++;
	npts=atoi(argv[arg++]);
	dt=atof(argv[arg++]);
	offset=atoi(argv[arg++]);
      } else {
	ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BANDPASSTESTC_EARG;
      }
    }
    /* Unrecognized option. */
    else {
      ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
      LALPrintError( USAGE, *argv );
      return BANDPASSTESTC_EARG;
    }
  } /* End of argument parsing loop. */

  /* Check input values. */
  if ( !infile ) {
    if ( offset >= npts ) {
      ERROR( BANDPASSTESTC_EBAD, BANDPASSTESTC_MSGEBAD, 0 );
      LALPrintError( "\toffset=%i must be less than npts=%i\n", offset,
		     npts );
      return BANDPASSTESTC_EBAD;
    }
  }

  /* Create the time series. */
  if ( infile ) {
    FILE *fp = fopen( infile, "r" );
    if ( !fp ) {
      ERROR( BANDPASSTESTC_EFILE, BANDPASSTESTC_MSGEFILE, infile );
      return BANDPASSTESTC_EFILE;
    }
    SUB( LALSReadTSeries( &stat, &series, fp ), &stat );
    fclose( fp );
  } else {
    snprintf( series.name, LALNameLength, "%s", "Impulse" );
    series.deltaT = dt;
    SUB( LALSCreateVector( &stat, &(series.data), npts ), &stat );
    memset( series.data->data, 0, npts*sizeof(REAL4) );
    series.data->data[offset] = 1.0;
  }

  /* Filter the time series. */
  SUB( LALDButterworthREAL4TimeSeries( &stat, &series, &params ),
       &stat );

  /* Print the output, if the -o option was given. */
  if ( outfile ) {
    FILE *fp = fopen( outfile, "w" );
    if ( !fp ){
      ERROR( BANDPASSTESTC_EFILE, BANDPASSTESTC_MSGEFILE, outfile );
      return BANDPASSTESTC_EFILE;
    }
    SUB( LALSWriteTSeries( &stat, fp, &series ), &stat );
    fclose( fp );
  }

  /* Free memory and exit. */
  SUB( LALSDestroyVector( &stat, &(series.data) ), &stat );
  LALCheckMemoryLeaks();
  INFO( BANDPASSTESTC_MSGENORM );
  return BANDPASSTESTC_ENORM;
}
예제 #6
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 );
}
void
LALFitToPulsarStudentT	( 	LALStatus            *status,
		    		CoarseFitOutput      *output,
		    		FitInputStudentT       *input,
		    		CoarseFitParams      *params )		

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

	UINT4 			n,i,j,k;		
	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 */
	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;

	INT4Vector *kVec=NULL;
	UINT4 count=0;
	REAL8 meanSegLength=0.0;
  
  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /******* CHECK VALIDITY OF ARGUMENTS  ************/	 
	 
  
  ASSERT(params != (CoarseFitParams *)NULL, status,
         FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS);
	 
  ASSERT(input != (FitInputStudentT *)NULL, status,
         FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT);

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

  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;

  /******* INITIALIZE VARIABLES *******************/
  for (i=0;i<params->meshH0[2]*params->meshCosIota[2]*params->meshPhase[2]*params->meshPsi[2];i++) 
     output->mChiSquare->data[i] = 0.0;

 	/* create kVec of chunk lengths within lock stretches */
	LALI4CreateVector(status->statusPtr, &kVec, n);

	j=i=0;

	while(1){
		count++;

		if((input->t[i+1].gpsSeconds - input->t[i].gpsSeconds)>180.0 || count==input->N){
			kVec->data[j] = count;
			count = 0;
			
			/* check if last segment is found this loop */
			if(i+1 > n-1)
				break;
				
			j++;
		}

		i++;

		/* break clause */
		if(i>n-1){
			/* set final value of kVec */
			kVec->data[j] = count;
			break;
		}
	}

	kVec->length = j+1;
 
 	for(i=0;i<kVec->length;i++){
		meanSegLength += kVec->data[i];
	}
 	fprintf(stderr, "Mean segment length = %f.\n",
	meanSegLength/(double)kVec->length);
 
	j=i=count=0;

  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;
   
   	/* create vectors containing amplitude response of detector for specified times */ 
   	for (i=0;i<n;i++){ 
     	pGPSandAcc.gps.gpsNanoSeconds =  input->t[i].gpsNanoSeconds;
     	pGPSandAcc.gps.gpsSeconds =  input->t[i].gpsSeconds;
     	pGPSandAcc.accuracy = 1.0; 
     	LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &pGPSandAcc);          
     	Fp->data[i] = (REAL8)computedResponse.plus;
     	Fc->data[i] = (REAL8)computedResponse.cross;	
   	}
   	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++){
       	INT4 tempLength;
				
				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;

        /*k = input->N;*/
        
				count=0;     
      	for (i = 0; i < n-kVec->data[kVec->length-1]; i+=tempLength){ 
       		tempLength = kVec->data[count];
					
					/* don't include data segments under 5 mins long */
					if(kVec->data[count] < 5){
						count++;
						continue;
					}
		
					sumBB = 0.0;
					sumAA = 0.0;
					sumAB = 0.0;
	
        	for (j=i;j<i+kVec->data[count];j++){
	 					B.re = input->B->data[j].re;
	 					B.im = input->B->data[j].im;
	    
	 					A.re = Fp->data[j]*Xp.re + Fc->data[j]*Xc.re;
	 					A.im = Fp->data[j]*Xp.im + Fc->data[j]*Xc.im;	
	
	 					sumBB += B.re*B.re + B.im*B.im;
	 					sumAA += A.re*A.re + A.im*A.im;
	 					sumAB += B.re*A.re + B.im*A.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;
	  				arg = iH0 + params->meshH0[2]*(iCosIota +  params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi));
	  				output->mChiSquare->data[arg] += 2.0*((REAL8)kVec->data[count])*log(chiSquare); 
        	} /* iH0 */
				
					count++;
      	} /* n*/
        
				/* find best fit */
      	for (iH0 = 0; iH0 < params->meshH0[2]; iH0++){
	  			arg = iH0 + params->meshH0[2]*(iCosIota +  params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi));
	  			if ((output->mChiSquare->data[arg])<minChiSquare){
	     			minChiSquare = output->mChiSquare->data[arg];
	     			h0 = params->meshH0[0] + (float)iH0*params->meshH0[1]; 
	     			h0BestFit = h0;
	     			cosIotaBestFit = cosIota;
	     			psiBestFit = psi;
	     			phaseBestFit = phase;	 
	  			}	  
      	}  /* end find best fit */
    	}  /* iCosIota */
  	} /* iPhase */
	} /* iPsi */

  
  /******* 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); 
  
  LALI4DestroyVector(status->statusPtr, &kVec);
  LALSDestroyVector(status->statusPtr, &Fp);
  LALSDestroyVector(status->statusPtr, &Fc);
  DETATCHSTATUSPTR(status);
  RETURN(status);
 
  
}
예제 #8
0
/* Actually, we don't need it -- JTW
struct tagRealFFTPlan
{
  INT4  sign;
  UINT4 size;
  void* junk;
};
*/
int
main( int argc, char *argv[] )
{

   static LALStatus         status;

   UINT4      i;
   REAL8      f;


   const REAL4    testInputDataData[SZEROPADANDFFTTESTC_LENGTH]
                     = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};

   COMPLEX8 expectedOutputDataData[SZEROPADANDFFTTESTC_LENGTH]
                     = {crectf(+3.600000000000000e+01, 0.0),
                        crectf(-1.094039137097177e+01, -2.279368601990178e+01),
                        crectf(+3.693524635113721e-01, +9.326003289238411e+00),
                        crectf(-8.090169943749448e-01, -7.918722831227928e+00),
                        crectf(+3.502214272222959e-01, +5.268737078678177e+00),
                        crectf(+5.329070518200751e-15, -5.196152422706625e+00),
                        crectf(+3.090169943749475e-01, +4.306254604896173e+00),
                        crectf(+2.208174802380956e-01, -4.325962305777781e+00)};

   REAL4TimeSeries             goodInput;
   COMPLEX8FrequencySeries     goodOutput;

   int                    result;
   LALUnit                expectedUnit;
   CHAR                   unitString[LALUnitTextSize];

   SZeroPadAndFFTParameters   goodParams;


   goodParams.window = NULL;
   goodParams.fftPlan = NULL;
   goodParams.length = SZEROPADANDFFTTESTC_FULLLENGTH;

   /* build window */
   goodParams.window = XLALCreateRectangularREAL4Window(SZEROPADANDFFTTESTC_LENGTH);
#ifndef LAL_NDEBUG
   SZeroPadAndFFTParameters badParams = goodParams;
#endif

   /* Fill in expected output */

   for (i=0; i<SZEROPADANDFFTTESTC_LENGTH; ++i)
   {
     expectedOutputDataData[i] *= SZEROPADANDFFTTESTC_DELTAT;
   }

   ParseOptions( argc, argv );

   /* TEST INVALID DATA HERE ------------------------------------------- */

   /* define valid parameters */
   goodInput.f0                   = 0.0;
   goodInput.deltaT               = SZEROPADANDFFTTESTC_DELTAT;
   goodInput.epoch.gpsSeconds     = SZEROPADANDFFTTESTC_EPOCHSEC;
   goodInput.epoch.gpsNanoSeconds = SZEROPADANDFFTTESTC_EPOCHNS;
   goodInput.data                 = NULL;
   goodOutput.data                = NULL;

#ifndef LAL_NDEBUG
   REAL4TimeSeries badInput = goodInput;
   COMPLEX8FrequencySeries badOutput = goodOutput;
#endif

   /* construct plan */
   LALCreateForwardRealFFTPlan(&status, &(goodParams.fftPlan),
			       SZEROPADANDFFTTESTC_FULLLENGTH,
			       SZEROPADANDFFTTESTC_FALSE);
   if ( ( code = CheckStatus( &status, 0 , "",
			      SZEROPADANDFFTTESTC_EFLS,
			      SZEROPADANDFFTTESTC_MSGEFLS ) ) )
   {
     return code;
   }
   /* allocate input and output vectors */
   LALSCreateVector(&status, &(goodInput.data), SZEROPADANDFFTTESTC_LENGTH);
   if ( ( code = CheckStatus( &status, 0 , "",
			      SZEROPADANDFFTTESTC_EFLS,
			      SZEROPADANDFFTTESTC_MSGEFLS ) ) )
   {
     return code;
   }
   LALCCreateVector(&status, &(goodOutput.data), SZEROPADANDFFTTESTC_LENGTH);
   if ( ( code = CheckStatus( &status, 0 , "",
			      SZEROPADANDFFTTESTC_EFLS,
			      SZEROPADANDFFTTESTC_MSGEFLS ) ) )
   {
     return code;
   }

#ifndef LAL_NDEBUG
   if ( ! lalNoDebug )
   {
     /* test behavior for null pointer to output series */
     LALSZeroPadAndFFT(&status, NULL, &goodInput, &goodParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to output series results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

     /* test behavior for null pointer to input series */
     LALSZeroPadAndFFT(&status, &goodOutput, NULL, &goodParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to input series results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

     /* test behavior for null pointer to parameter structure */
     LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, NULL);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to parameter structure results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

     /* test behavior for null pointer to FFT plan */
     badParams.fftPlan = NULL;
     LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &badParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to FFT plan results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);
     badParams.fftPlan = goodParams.fftPlan;

     /* test behavior for null pointer to data member of output series */
     LALSZeroPadAndFFT(&status, &badOutput, &goodInput, &goodParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to data member of output series results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

     /* test behavior for null pointer to data member of input series */
     LALSZeroPadAndFFT(&status, &goodOutput, &badInput, &goodParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to data member of input series results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

     /* test behavior for null pointer to data member of data member of output series */
     LALCCreateVector(&status, &(badOutput.data), SZEROPADANDFFTTESTC_LENGTH);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }
     COMPLEX8                *cPtr;
     cPtr = badOutput.data->data;
     badOutput.data->data = NULL;
     LALSZeroPadAndFFT(&status, &badOutput, &goodInput, &goodParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to data member of data member of output series results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);
     badOutput.data->data = cPtr;
     LALCDestroyVector(&status, &(badOutput.data));
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }

     /* test behavior for null pointer to data member of data member of output series */
     LALSCreateVector(&status, &(badInput.data), SZEROPADANDFFTTESTC_LENGTH);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }
     REAL4                   *sPtr;
     sPtr = badInput.data->data;
     badInput.data->data = NULL;
     LALSZeroPadAndFFT(&status, &goodOutput, &badInput, &goodParams);
     if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
				STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
				SZEROPADANDFFTTESTC_ECHK,
				SZEROPADANDFFTTESTC_MSGECHK ) ) )
     {
       return code;
     }
     printf("  PASS: null pointer to data member of data member of input series results in error:\n       \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);
     badInput.data->data = sPtr;
     LALSDestroyVector(&status, &(badInput.data));
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }

     /* test behavior for zero length */
     goodInput.data->length = goodOutput.data->length = 0;
     /* plan->size = -1; */
     LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
     if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EZEROLEN,
			       STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN,
			       SZEROPADANDFFTTESTC_ECHK,
			       SZEROPADANDFFTTESTC_MSGECHK) ) )
     {
       return code;
     }
     printf("  PASS: zero length results in error:\n       \"%s\"\n",
            STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN);
     /* reassign valid length */
     goodInput.data->length = goodOutput.data->length
       = SZEROPADANDFFTTESTC_LENGTH;
     /* plan->size = SZEROPADANDFFTTESTC_FULLLENGTH; */

     /* test behavior for negative time spacing */
     goodInput.deltaT = -SZEROPADANDFFTTESTC_DELTAT;
     LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
     if ( ( code = CheckStatus(&status,
			       STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAT,
			       STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT,
			       SZEROPADANDFFTTESTC_ECHK,
			       SZEROPADANDFFTTESTC_MSGECHK) ) )
     {
       return code;
     }
     printf("  PASS: negative time spacing results in error:\n       \"%s\"\n",
            STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT);

     /* test behavior for zero time spacing */
     goodInput.deltaT = 0;
     LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
     if ( ( code = CheckStatus(&status,
			       STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAT,
			       STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT,
			       SZEROPADANDFFTTESTC_ECHK,
			       SZEROPADANDFFTTESTC_MSGECHK) ) )
     {
       return code;
     }
     printf("  PASS: zero time spacing results in error:\n       \"%s\"\n",
            STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT);
     /* reassign valid time spacing */
     goodInput.deltaT = SZEROPADANDFFTTESTC_DELTAT;

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

   /* test behavior for negative heterodyning frequency */
   goodInput.f0 = -100.0;
   LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
   if ( ( code = CheckStatus(&status,
			     STOCHASTICCROSSCORRELATIONH_ENONZEROHETERO,
			     STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO,
			     SZEROPADANDFFTTESTC_ECHK,
			     SZEROPADANDFFTTESTC_MSGECHK) ) )
   {
     return code;
   }
   printf("  PASS: negative heterodyning frequency results in error:\n       \"%s\"\n",
            STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO);
   /* test behavior for positive heterodyning frequency */
   goodInput.f0 = 100.0;
   LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
   if ( ( code = CheckStatus(&status,
			     STOCHASTICCROSSCORRELATIONH_ENONZEROHETERO,
			     STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO,
			     SZEROPADANDFFTTESTC_ECHK,
			     SZEROPADANDFFTTESTC_MSGECHK) ) )
   {
     return code;
   }
   printf("  PASS: positive heterodyning frequency results in error:\n       \"%s\"\n",
          STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO);
   goodInput.f0 = 0.0;

   /* test behavior for length mismatch between input series and output series */
   goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH + 1;
   LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
   if ( ( code = CheckStatus(&status,
			     STOCHASTICCROSSCORRELATIONH_EMMLEN,
			     STOCHASTICCROSSCORRELATIONH_MSGEMMLEN,
			     SZEROPADANDFFTTESTC_ECHK,
			     SZEROPADANDFFTTESTC_MSGECHK) ) )
   {
     return code;
   }
   printf("  PASS: length mismatch between input series and output series results in error:\n       \"%s\"\n",
          STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
   goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH;

   /* TEST VALID DATA HERE --------------------------------------------- */

   /* fill input time-series parameters */
   strncpy(goodInput.name,"Dummy test data",LALNameLength);
   goodInput.sampleUnits  = lalDimensionlessUnit;
   goodInput.sampleUnits.unitNumerator[LALUnitIndexADCCount] = 1;

     /* fill input time-series data */
   for (i=0; i<SZEROPADANDFFTTESTC_LENGTH; ++i)
   {
     goodInput.data->data[i] = testInputDataData[i];
   }

   /* zero-pad and FFT */
   LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
   if ( ( code = CheckStatus( &status, 0 , "",
			      SZEROPADANDFFTTESTC_EFLS,
			      SZEROPADANDFFTTESTC_MSGEFLS) ) )
   {
     return code;
   }

   /* check output f0 */
   if (optVerbose)
   {
     printf("f0=%g, should be 0\n", goodOutput.f0);
   }
   if (goodOutput.f0)
   {
     printf("  FAIL: Valid data test\n");
     if (optVerbose)
     {
       printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS);
     }
     return SZEROPADANDFFTTESTC_EFLS;
   }

   /* check output deltaF */
   if (optVerbose)
   {
     printf("deltaF=%g, should be %g\n", goodOutput.deltaF,
            SZEROPADANDFFTTESTC_DELTAF);
   }
   if ( fabs(goodOutput.deltaF-SZEROPADANDFFTTESTC_DELTAF)
        / SZEROPADANDFFTTESTC_DELTAF > SZEROPADANDFFTTESTC_TOL )
   {
     printf("  FAIL: Valid data test\n");
     if (optVerbose)
     {
       printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS);
     }
     return SZEROPADANDFFTTESTC_EFLS;
   }

   /* check output epoch */
   if (optVerbose)
   {
     printf("epoch=%d seconds, %d nanoseconds; should be %d seconds, %d nanoseconds\n",
            goodOutput.epoch.gpsSeconds, goodOutput.epoch.gpsNanoSeconds,
            SZEROPADANDFFTTESTC_EPOCHSEC, SZEROPADANDFFTTESTC_EPOCHNS);
   }
   if ( goodOutput.epoch.gpsSeconds != SZEROPADANDFFTTESTC_EPOCHSEC
        || goodOutput.epoch.gpsNanoSeconds != SZEROPADANDFFTTESTC_EPOCHNS )
   {
     printf("  FAIL: Valid data test\n");
     if (optVerbose)
     {
       printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS);
     }
     return SZEROPADANDFFTTESTC_EFLS;
   }

   /* check output units */
   expectedUnit = lalDimensionlessUnit;
   expectedUnit.unitNumerator[LALUnitIndexADCCount] = 1;
   expectedUnit.unitNumerator[LALUnitIndexSecond] = 1;
   result = XLALUnitCompare(&expectedUnit, &(goodOutput.sampleUnits));
   if (optVerbose)
   {
     if ( XLALUnitAsString( unitString, LALUnitTextSize, &(goodOutput.sampleUnits)) == NULL ) {
       return SZEROPADANDFFTTESTC_EFLS;
     }
     printf( "Units are \"%s\", ", unitString );
     if ( XLALUnitAsString( unitString, LALUnitTextSize, &expectedUnit) == NULL ) {
       return SZEROPADANDFFTTESTC_EFLS;
     }
     printf( "should be \"%s\"\n", unitString );
   }

   if (result != 0)
   {
     printf("  FAIL: Valid data test #1\n");
     if (optVerbose)
     {
       printf("Exiting with error: %s\n",
              SZEROPADANDFFTTESTC_MSGEFLS);
     }
     return SZEROPADANDFFTTESTC_EFLS;
   }

   /* check output values */
   if (optVerbose)
   {
     printf("hBarTilde(0)=%g + %g i, should be %g\n",
            crealf(goodOutput.data->data[0]), cimagf(goodOutput.data->data[0]),
            crealf(expectedOutputDataData[0]));
   }
   if ( fabsf(crealf(goodOutput.data->data[0]) - crealf(expectedOutputDataData[0]))
        /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL
        || fabsf(cimagf(goodOutput.data->data[0])) > SZEROPADANDFFTTESTC_TOL )
   {
     printf("  FAIL: Valid data test\n");
     if (optVerbose)
       {
         printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS);
       }
     return SZEROPADANDFFTTESTC_EFLS;
   }

   for (i=1; i<SZEROPADANDFFTTESTC_LENGTH; ++i)
   {
     f = i * SZEROPADANDFFTTESTC_DELTAF;
     if (optVerbose)
     {
       printf("hBarTilde(%f Hz)=%g + %g i, should be %g + %g i\n",
              f, crealf(goodOutput.data->data[i]), cimagf(goodOutput.data->data[i]),
              crealf(expectedOutputDataData[i]), cimagf(expectedOutputDataData[i]));
     }
     if (fabsf(crealf(goodOutput.data->data[i]) - crealf(expectedOutputDataData[i]))
         /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL
         || fabsf(cimagf(goodOutput.data->data[i]) - cimagf(expectedOutputDataData[i]))
         /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL)
     {
       printf("  FAIL: Valid data test\n");
       if (optVerbose)
       {
         printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS);
       }
       return SZEROPADANDFFTTESTC_EFLS;
     }
   }

    /* write results to output file
   LALSPrintTimeSeries(&input, "zeropadgoodInput.dat");
   LALCPrintFrequencySeries(&output, "zeropadgoodOutput.dat");*/

   /* clean up valid data */
   LALSDestroyVector(&status, &goodInput.data);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
   {
     return code;
   }
   LALCDestroyVector(&status, &goodOutput.data);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
   {
     return code;
   }
   LALDestroyRealFFTPlan(&status, &(goodParams.fftPlan));
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
   {
     return code;
   }
   XLALDestroyREAL4Window(goodParams.window);

   LALCheckMemoryLeaks();

   printf("PASS: all tests\n");

   /**************** Process User-Entered Data, If Any **************/

   /* ::TODO:: Fix this with length and window type to be specified */

   if (optInputFile[0] && optOutputFile[0]){
     /* construct plan*/
     LALCreateForwardRealFFTPlan(&status, &(goodParams.fftPlan), 2*optLength - 1,
				   optMeasurePlan);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }

     goodInput.data  = NULL;
     goodOutput.data = NULL;

     LALSCreateVector(&status, &goodInput.data, optLength);
     if ( ( code = CheckStatus( &status, 0 , "",
				SZEROPADANDFFTTESTC_EUSE,
				SZEROPADANDFFTTESTC_MSGEUSE) ) )
     {
       return code;
     }
     LALCCreateVector(&status, &goodOutput.data, optLength);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }

     /* Read input file */
     LALSReadTimeSeries(&status, &goodInput, optInputFile);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }

     /* calculate zero-pad and FFT */
     LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }

     LALCPrintFrequencySeries(&goodOutput, optOutputFile);

     printf("===== FFT of Zero-Padded User-Specified Data Written to File %s =====\n", optOutputFile);

     /* clean up valid data */
     LALSDestroyVector(&status, &goodInput.data);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }
     LALCDestroyVector(&status, &goodOutput.data);
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }
     LALDestroyRealFFTPlan(&status, &(goodParams.fftPlan));
     if ( ( code = CheckStatus(&status, 0 , "",
			       SZEROPADANDFFTTESTC_EFLS,
			       SZEROPADANDFFTTESTC_MSGEFLS) ) )
     {
       return code;
     }
     LALCheckMemoryLeaks();
   }
   return SZEROPADANDFFTTESTC_ENOM;
}
예제 #9
0
/**
 * Computes REAL4TimeSeries containing time series of response amplitudes.
 * \deprecated Use XLALComputeDetAMResponseSeries() instead.
 */
void LALComputeDetAMResponseSeries(LALStatus * status, LALDetAMResponseSeries * pResponseSeries, const LALDetAndSource * pDetAndSource, const LALTimeIntervalAndNSample * pTimeInfo)
{
	/* Want to loop over the time and call LALComputeDetAMResponse() */
	LALDetAMResponse instResponse;
	unsigned i;

	INITSTATUS(status);
	ATTATCHSTATUSPTR(status);

	/*
	 * Error-checking assertions
	 */
	ASSERT(pResponseSeries != (LALDetAMResponseSeries *) NULL, status, DETRESPONSEH_ENULLOUTPUT, DETRESPONSEH_MSGENULLOUTPUT);

	ASSERT(pDetAndSource != (LALDetAndSource *) NULL, status, DETRESPONSEH_ENULLINPUT, DETRESPONSEH_MSGENULLINPUT);

	ASSERT(pTimeInfo != (LALTimeIntervalAndNSample *) NULL, status, DETRESPONSEH_ENULLINPUT, DETRESPONSEH_MSGENULLINPUT);

	/*
	 * Set names
	 */
	pResponseSeries->pPlus->name[0] = '\0';
	pResponseSeries->pCross->name[0] = '\0';
	pResponseSeries->pScalar->name[0] = '\0';

	strncpy(pResponseSeries->pPlus->name, "plus", LALNameLength);
	strncpy(pResponseSeries->pCross->name, "cross", LALNameLength);
	strncpy(pResponseSeries->pScalar->name, "scalar", LALNameLength);

	/*
	 * Set sampling parameters
	 */
	pResponseSeries->pPlus->epoch = pTimeInfo->epoch;
	pResponseSeries->pPlus->deltaT = pTimeInfo->deltaT;
	pResponseSeries->pPlus->f0 = 0.;
	pResponseSeries->pPlus->sampleUnits = lalDimensionlessUnit;

	pResponseSeries->pCross->epoch = pTimeInfo->epoch;
	pResponseSeries->pCross->deltaT = pTimeInfo->deltaT;
	pResponseSeries->pCross->f0 = 0.;
	pResponseSeries->pCross->sampleUnits = lalDimensionlessUnit;

	pResponseSeries->pScalar->epoch = pTimeInfo->epoch;
	pResponseSeries->pScalar->deltaT = pTimeInfo->deltaT;
	pResponseSeries->pScalar->f0 = 0.;
	pResponseSeries->pScalar->sampleUnits = lalDimensionlessUnit;

	/*
	 * Ensure enough memory for requested vectors
	 */
	if(pResponseSeries->pPlus->data->length < pTimeInfo->nSample) {
		if(lalDebugLevel >= 8)
			LALInfo(status, "plus sequence too short -- reallocating");

		TRY(LALSDestroyVector(status->statusPtr, &(pResponseSeries->pPlus->data)), status);

		TRY(LALSCreateVector(status->statusPtr, &(pResponseSeries->pPlus->data), pTimeInfo->nSample), status);

		if(lalDebugLevel > 0)
			printf("pResponseSeries->pPlus->data->length = %d\n", pResponseSeries->pPlus->data->length);

	}

	if(pResponseSeries->pCross->data->length < pTimeInfo->nSample) {
		if(lalDebugLevel >= 8)
			LALInfo(status, "cross sequence too short -- reallocating");

		TRY(LALSDestroyVector(status->statusPtr, &(pResponseSeries->pCross->data)), status);

		TRY(LALSCreateVector(status->statusPtr, &(pResponseSeries->pCross->data), pTimeInfo->nSample), status);

	}

	if(pResponseSeries->pScalar->data->length < pTimeInfo->nSample) {
		if(lalDebugLevel & 0x08)
			LALInfo(status, "scalar sequence too short -- reallocating");

		TRY(LALSDestroyVector(status->statusPtr, &(pResponseSeries->pScalar->data)), status);

		TRY(LALSCreateVector(status->statusPtr, &(pResponseSeries->pScalar->data), pTimeInfo->nSample), status);
	}


	/*
	 * Loop to compute each element in time series.
	 */

	for(i = 0; i < pTimeInfo->nSample; ++i) {
		LIGOTimeGPS gps = pTimeInfo->epoch;
		XLALGPSAdd(&gps, i * pTimeInfo->deltaT);

		TRY(LALComputeDetAMResponse(status->statusPtr, &instResponse, pDetAndSource, &gps), status);

		pResponseSeries->pPlus->data->data[i] = instResponse.plus;
		pResponseSeries->pCross->data->data[i] = instResponse.cross;
		pResponseSeries->pScalar->data->data[i] = instResponse.scalar;
	}

	DETATCHSTATUSPTR(status);
	RETURN(status);
}
예제 #10
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;
}
예제 #11
0
int main( void )
{

  /* Declare inputs of LAL function */
  static LALStatus     status;
  REAL4Vector		*output;
  FoldAmplitudesInput   input;
  FoldAmplitudesInput   badinput;
  FoldAmplitudesParams  param;

  /* Declare other variables */
  REAL4 		f = FOLDAMPLITUDESTESTC_FREQ;  /* A frequency for producing test amplitudes */
  REAL4 		fDot = FOLDAMPLITUDESTESTC_FREQDOT;    /* A frequency for producing test phases */
  REAL4			delT = FOLDAMPLITUDESTESTC_TIMESTEP;       /* A time step for producing test data */
  REAL4			twoPi = (REAL4) LAL_TWOPI;                 /* For phase bins between 0 an 2*pi    */
  REAL4			binRange;				   /* binMax - binMin */
  INT4                  lengthAmpVec = FOLDAMPLITUDESTESTC_LENGTH; /* length of the vector of amplitudes */
  INT4			i;                                         /* generic integer index */
  INT4			j;                                         /* generic integer index */
  INT4			k;					   /* generic integer index */
  INT2			gotError = 0;                                /* Set nonzero if error condition occurs */


  /* Allocate memory */
  input.phaseVec = NULL;
  input.amplitudeVec = NULL;
  badinput.phaseVec = NULL;
  badinput.amplitudeVec = NULL;
  output = NULL;
  LALSCreateVector( &status, &input.phaseVec, FOLDAMPLITUDESTESTC_LENGTH  );
  LALSCreateVector( &status, &input.amplitudeVec, FOLDAMPLITUDESTESTC_LENGTH  );
  LALSCreateVector( &status, &badinput.phaseVec, FOLDAMPLITUDESTESTC_BADLENGTH  );
  LALSCreateVector( &status, &badinput.amplitudeVec, FOLDAMPLITUDESTESTC_LENGTH  );
  LALSCreateVector( &status, &output, FOLDAMPLITUDESTESTC_NUMBINS );

  /* ******  TEST RESPONSE TO INVALID DATA  ************/

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

#ifndef LAL_NDEBUG
  if ( ! lalNoDebug )
  {

    /* Test NULL output */
    param.numBins = FOLDAMPLITUDESTESTC_NUMBINS;
    param.binMin = 0.0;
    param.binMax = twoPi;

    LALFoldAmplitudes( &status, NULL, &input, &param );

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

    /* Test input vectors of different length */
    param.numBins = FOLDAMPLITUDESTESTC_NUMBINS;
    param.binMin = 0.0;
    param.binMax = twoPi;

    LALFoldAmplitudes( &status, output, &badinput, &param );

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

    /* Test number of bins < 1 */
    param.numBins = 0;
    param.binMin = 0.0;
    param.binMax = twoPi;

    LALFoldAmplitudes( &status, output, &input, &param );

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

    /* Test bin max <= bin min */
    param.numBins = FOLDAMPLITUDESTESTC_NUMBINS;
    param.binMin = 0.0;
    param.binMax = 0.0;

    LALFoldAmplitudes( &status, output, &input, &param );

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

    /* Test bin min != 0 */
    param.numBins = FOLDAMPLITUDESTESTC_NUMBINS;
    param.binMin = -0.5;
    param.binMax = 0.5;

    LALFoldAmplitudes( &status, output, &input, &param );

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

  }
#endif /* LAL_NDEBUG */

  /* ******  TEST RESPONSE TO VALID DATA  ************/

  /* Test that valid data generate the correct answers */

  /* Test 1: Simple test with constant amplitudes and constant phases  */
  /* All the amplitudes should end up in one bin; specifically the (j + 8)/2 % param.numBins bin.  */

  for (k = 0; k < 2; ++k) {
    param.numBins = 4;
    param.binMin = 0.0;
    if (k == 0) {
    	param.binMax = 1.0;      /* test phase measured in cycles */
    } else {
    	param.binMax = twoPi;   /* test phase measured in radians */
    }
    binRange = param.binMax - param.binMin;

    for (j = -8; j <= 8; ++j) {

  	for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  	{
		input.amplitudeVec->data[i] = 1.0;
                /* Set the phase:  Add in a multiple of twoPi to check that values bin correctly */
		input.phaseVec->data[i] = j*(binRange/8.0) + j*j*j*binRange + .001;
  	}

  	/* Initialize the output vector */
  	for ( i = 0 ; i < (INT4)output->length ; ++i )
  	{
		output->data[i] = 0.0;
  	}

  	/*
  	printf("\n");
  	for ( i = 0 ; i < input.amplitudeVec->length ; ++i )
  	{
		printf("Index %i  Input Amplitude %f \n",i, input.amplitudeVec->data[i]);
  	}

  	printf("\n");
  	for ( i = 0 ; i < input.phaseVec->length ; ++i )
  	{
		printf("Index %i  Input Phase %f \n",i, input.phaseVec->data[i]);
  	}
        */

  	LALFoldAmplitudes( &status, output, &input, &param );

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

  	printf("\n");
  	for ( i = 0 ; i < param.numBins ; ++i )
  	{
  	        printf("Constant phase test binRange %g, index %i, Bin %i, Output Amplitude %f \n",binRange,j,i,output->data[i]);
		if (i == (j + 8)/2 % param.numBins) {
		    if (output->data[i] != lengthAmpVec*1.0) {
		    	printf ("For binRange %g expected all the amplitudes to fold into bin %i but instead got %g in this bin. \n",binRange, i,output->data[i]);
		    	gotError = 1;
		    }
		} else  {
		    if (output->data[i] != 0.0) {
		    	printf ("For binRange %g expected no amplitudes to fold into bin %i but instead got %g in this bin. \n",binRange, i,output->data[i]);
		    	gotError = 1;
		    }
		}
	}

    }  /* end for (j = -8; j < 8; ++j) */

  } /* end for (k = 0; k < 1; ++k) */

  printf("\n");
  if  (gotError > 0) {
  	printf("Test 1 in FoldAmplitudesTest.c Failed. \n");
  	return FOLDAMPLITUDESTESTC_EFLS;
  } else {
  	printf("Test 1 in FoldAmplitudesTest.c Passed. \n");
  }

  /* Test 2: Constant amplitudes, simple phases */
  /* One should end up in each bin. */

  param.numBins = 10;
  param.binMin = 0.0;
  param.binMax = twoPi;   /* test phase measured in radians */
  binRange = param.binMax - param.binMin;

  for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  {
	input.amplitudeVec->data[i] = 1;
	input.phaseVec->data[i] = twoPi*i/10.0 + .0001;
  }

  /* Initialize the output vector */
  for ( i = 0 ; i < (INT4)output->length ; ++i )
  {
	output->data[i] = 0.0;
  }

  /*
  printf("\n");
  for ( i = 0 ; i < input.amplitudeVec->length ; ++i )
  {
	printf("Index %i  Input Amplitude %f \n",i, input.amplitudeVec->data[i]);
  }

  printf("\n");
  for ( i = 0 ; i < input.phaseVec->length ; ++i )
  {
	printf("Index %i  Input Phase %f \n",i, input.phaseVec->data[i]);
  }
  */

  LALFoldAmplitudes( &status, output, &input, &param );

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

  printf("\n");
  for ( i = 0 ; i < param.numBins ; ++i )
  {
	printf("Bin %i  Output Amplitude %f \n",i,output->data[i]);
	if (output->data[i] != 1.0) {
		printf ("In bin %i expected 1 but instead got %g in this bin. \n",i,output->data[i]);
		gotError = 1;
	}

  }

  printf("\n");
  if  (gotError > 0) {
  	printf("Test 2 in FoldAmplitudesTest.c Failed. \n");
  	return FOLDAMPLITUDESTESTC_EFLS;
  } else {
  	printf("Test 2 in FoldAmplitudesTest.c Passed. \n");
  }


  /* Test 3: One amplitude goes into each bin, so that sin(\PHI) should return sin(\PHI) */

  param.numBins = 10;
  param.binMin = 0.0;
  param.binMax = twoPi;   /* test phase measured in radians */
  binRange = param.binMax - param.binMin;

  for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  {
	input.amplitudeVec->data[i] = sin(twoPi*i/10.0 + .0001);
	input.phaseVec->data[i] = twoPi*i/10.0 + .0001;
  }

  /* Initialize the output vector */
  for ( i = 0 ; i < (INT4)output->length ; ++i )
  {
	output->data[i] = 0.0;
  }

  /*
  printf("\n");
  for ( i = 0 ; i < input.amplitudeVec->length ; ++i )
  {
	printf("Index %i  Input Amplitude %f \n",i, input.amplitudeVec->data[i]);
  }

  printf("\n");
  for ( i = 0 ; i < input.phaseVec->length ; ++i )
  {
	printf("Index %i  Input Phase %f \n",i, input.phaseVec->data[i]);
  }
  */

  LALFoldAmplitudes( &status, output, &input, &param );

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

  printf("\n");
  for ( i = 0 ; i < param.numBins ; ++i )
  {
	printf("Bin %i  Output Amplitude %f \n",i,output->data[i]);
	if (fabs(output->data[i] - sin(twoPi*i/10.0 + .0001)) > fabs(output->data[i]*FOLDAMPLITUDESTESTC_TOL)) {
		printf ("In bin %i expected %g but instead got %g in this bin. \n",i,sin(twoPi*i/10.0 + .0001),output->data[i]);
		gotError = 1;
	}

  }

  printf("\n");
  if  (gotError > 0) {
  	printf("Test 3 in FoldAmplitudesTest.c Failed. \n");
  	return FOLDAMPLITUDESTESTC_EFLS;
  } else {
  	printf("Test 3 in FoldAmplitudesTest.c Passed. \n");
  }


  /* Test 4: Two amplitudes go into each bin, such that sin(2*\PHI) should return 2*sin(\PHI) */
  /* Also, phases are input as cycles. */

  param.numBins = 5;
  param.binMin = 0.0;
  param.binMax = 1.0;   /* test phase measured in radians */
  binRange = param.binMax - param.binMin;

  for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  {
	input.amplitudeVec->data[i] = sin(2.0*twoPi*i/5.0 + .001);
	input.phaseVec->data[i] = i/5.0 + .001;
  }

  /* Initialize the output vector */
  for ( i = 0 ; i < (INT4)output->length ; ++i )
  {
	output->data[i] = 0.0;
  }

  printf("\n");
  for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  {
	printf("Index %i  Input Amplitude %f \n",i, input.amplitudeVec->data[i]);
  }

  printf("\n");
  for ( i = 0 ; i < (INT4)input.phaseVec->length ; ++i )
  {
	printf("Index %i  Input Phase in Cycles %f \n",i, input.phaseVec->data[i]);
  }

  LALFoldAmplitudes( &status, output, &input, &param );

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

  printf("\n");
  for ( i = 0 ; i < param.numBins ; ++i )
  {
	printf("Bin %i  Output Amplitude %f \n",i,output->data[i]);
	if (fabs(output->data[i] - 2.0*sin(2.0*twoPi*i/5.0 + .001)) > fabs(output->data[i]*FOLDAMPLITUDESTESTC_TOL)) {
		printf ("In bin %i expected %g but instead got %g in this bin. \n",i,2.0*sin(2.0*twoPi*i/5.0 + .001),output->data[i]);
		gotError = 1;
	}

  }

  printf("\n");
  if  (gotError > 0) {
  	printf("Test 4 in FoldAmplitudesTest.c Failed. \n");
  	return FOLDAMPLITUDESTESTC_EFLS;
  } else {
  	printf("Test 4 in FoldAmplitudesTest.c Passed. \n");
  }


  /* Test 5: More realistic data; check output by hand */

  param.numBins = FOLDAMPLITUDESTESTC_NUMBINS;
  param.binMin = 0.0;
  param.binMax = twoPi;

  printf("\n");
  printf("Test 5 check by hand: numBins, binMax = %i, %g \n",param.numBins,param.binMax);

  for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  {
	input.amplitudeVec->data[i] = sin(twoPi*f*i*delT + 0.5*fDot*i*delT*i*delT - 10.001);
	input.phaseVec->data[i] = twoPi*f*i*delT + 0.5*fDot*i*delT*i*delT - 10.001;
  }

  for ( i = 0 ; i < (INT4)output->length ; ++i )
  {
	output->data[i] = 0.0;
  }

  printf("\n");
  for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i )
  {
	printf("Index %i  Input Amplitude %f \n",i, input.amplitudeVec->data[i]);
  }

  printf("\n");
  for ( i = 0 ; i < (INT4)input.phaseVec->length ; ++i )
  {
	printf("Index %i  Input Phase %f \n",i, input.phaseVec->data[i]);
  }

  LALFoldAmplitudes( &status, output, &input, &param );

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

  printf("\n");
  for ( i = 0 ; i < param.numBins ; ++i )
  {
	printf("Bin %i  Output Amplitude %f \n",i,output->data[i]);
  }

  printf("\n");
  if  (gotError > 0) {
  	printf("Test 5in FoldAmplitudesTest.c Failed. \n");
  	return FOLDAMPLITUDESTESTC_EFLS;
  } else {
  	printf("Test 5 in FoldAmplitudesTest.c Passed. \n");
  }


  /* some check on the contents of output */

  /* ******  CLEAN UP  ************/
  LALSDestroyVector( &status, &input.phaseVec );
  LALSDestroyVector( &status, &input.amplitudeVec );
  LALSDestroyVector( &status, &badinput.phaseVec );
  LALSDestroyVector( &status, &badinput.amplitudeVec );
  LALSDestroyVector( &status, &output );

  LALCheckMemoryLeaks();

  printf("\n");
  printf("PASS: All tests \n");
  printf("\n");

  return FOLDAMPLITUDESTESTC_ENOM;
}
/**
 * \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 );
}
예제 #13
0
/**
 * \ingroup LALInspiralBank_h
 * \author Hanna, C. R. and Owen, B. J.
 * \brief This function creates a bank of BCVSpin templates to search for precessing binaries.
 *
 * ### Algorithm ###
 *
 * The code checks <tt>coarseIn-\>mMin</tt> to determine whether the limits on
 * the target region are in terms of masses or phenomenological parameters.
 * A positive value indicates that mass limits are being used.
 *
 * If mass limits are used, the target region of parameter space is a
 * distorted box in the coordinates \f$(x=\psi_0, y=\psi_3, z=\beta)\f$. The
 * metric at high values of \f$\beta\f$ is constant. It is convenient to rotate
 * to coordinates \f$(x',y',z')\f$ which lie along eigenvectors of the metric.
 *
 * The algorithm first draws a rectilinear box in the primed coordinates
 * which includes the target region, then steps through along the
 * directions of the primed coordinates.  At each point it tests if the
 * point lies within the target region. If the point is inside the target
 * region, the algorithm adds a template to the linked list. If not, it
 * continues through the box containing the target region.
 *
 * The tiling is done with a body-centered cubic lattice. People usually
 * solve the non-overlapping bcc problem rather than the overlapping one
 * here, so it's worth mentioning how we do it. I don't have time to stick
 * in the 3D figures you need to show it properly, but you can figure out
 * the spacing by finding the smallest sphere that contains the
 * Wigner-Seitz cell. When you do that you find that the lattice constant
 * (spacing between templates in the plane, in proper distance) is
 * \f$(4/3)\sqrt{2\mu}\f$. So the coordinate spacing is that divided by the
 * square root of the corresponding eigenvalue of the metric. (The vertical
 * spacing in the bcc lattice is multiplied by a further 1/2.)
 *
 * If \f$(\psi_0, \psi_3, \beta)\f$ limits are used, the tiling is done in the
 * given box with a bcc lattice.
 *
 * ### Notes ###
 *
 * Currently we use a static function for the metric based on an
 * approximation that is good only for large \f$\beta\f$. We should update it
 * and put it out in the LAL namespace.
 *
 * The metric relies on approximations that make it valid only for a binary
 * system with a total mass \f$<15M\odot\f$ where the larger body's minimum mass
 * is at least twice the smaller body's maximum mass.  If the parameter
 * range is specified with physical parameters rather than the
 * phenomenological parameters \f$(\psi_0, \psi_3, \beta)\f$ then using mass
 * values that violate these conditions will result in an error message.
 *
 */
void
LALInspiralSpinBank(
    LALStatus         	 *status,
    SnglInspiralTable   **tiles,
    INT4      		 *ntiles,
    InspiralCoarseBankIn *coarseIn
    )

{
  SnglInspiralTable *tmplt = 	  NULL; /* loop counter */
  REAL4Array *metric = 		  NULL; /* parameter-space metric */
  UINT4Vector *metricDimensions = NULL;	/* contains the dimension of metric */
  REAL4Vector *eigenval =  	  NULL; /* eigenvalues of metric */
  InspiralMomentsEtc moments; 		/* Added for LALGetInspiralMoments() */
  InspiralTemplate inspiralTemplate; 	/* Added for LALGetInspiralMoments() */
  REAL4 x, y, z;             		/* psi0, psi3, beta coordinates */
  REAL4 x0, myy0, z0;          		/* minimum values of x, y, z */
  REAL4 x1, myy1, z1;          		/* maximum values of x, y, z */
  REAL4 xp, yp, zp;          		/* metric eigenvector coordinates */
  REAL4 xp0, yp0, UNUSED zp0;       		/* minimum values of xp, yp, zp */
  REAL4 xp1, yp1, zp1;       		/* maximum values of xp, yp, zp */
  REAL4 dxp, dyp, dzp;       		/* step sizes in xp, yp, zp */
  REAL4 theta;               		/* angle of rotation for xp and yp */
  REAL4 m1Min=0, m1Max=0;       		/* range of m1 to search */
  REAL4 m2Min=0, m2Max=0;        		/* range of m2 to search */
  REAL4 f0 = -1;  			/* frequency of minimum of noise curve */
  INT2 bccFlag = 0;      		/* determines offset for bcc tiling */
  INT4 cnt = 0;				/* loop counter set to value of ntiles */
  REAL4 shf0 = 1;			/* used to find minimum of shf */
  BOOLEAN havePsi;			/* are we using phenom parameters?  */

  /* Set up status pointer. */
  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );


  ASSERT( coarseIn, status, LALINSPIRALBANKH_ENULL,
          LALINSPIRALBANKH_MSGENULL );
  /* Check that minimal match is OK. */
  ASSERT( coarseIn->mmCoarse > 0, status, LALINSPIRALBANKH_ECHOICE,
          LALINSPIRALBANKH_MSGECHOICE );
  /* Sanity check parameter bounds. */
  if( coarseIn->mMin > 0 )
  {
    ASSERT( coarseIn->MMax > 0, status, LALINSPIRALBANKH_ECHOICE,
            LALINSPIRALBANKH_MSGECHOICE );
    ASSERT( coarseIn->MMax > 2*coarseIn->mMin, status,
            LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
    havePsi = 0;
  }
  /* Sanity check phenomenological parameter bounds. */
  else
  {
    ASSERT( coarseIn->psi0Min > 0, status, LALINSPIRALBANKH_ECHOICE,
            LALINSPIRALBANKH_MSGECHOICE );
    ASSERT( coarseIn->psi0Max > coarseIn->psi0Min, status,
            LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
    ASSERT( coarseIn->psi3Min < 0, status, LALINSPIRALBANKH_ECHOICE,
            LALINSPIRALBANKH_MSGECHOICE );
    ASSERT( coarseIn->psi3Max > coarseIn->psi3Min, status,
            LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
    ASSERT( coarseIn->betaMax > coarseIn->betaMin, status,
            LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE );
    havePsi = 1;
  }
  /* Check that noise curve exists. */
  ASSERT( coarseIn->shf.data, status, LALINSPIRALBANKH_ENULL,
          LALINSPIRALBANKH_MSGENULL );
  ASSERT( coarseIn->shf.data->data, status, LALINSPIRALBANKH_ENULL,
          LALINSPIRALBANKH_MSGENULL );

  /* Allocate memory for 3x3 parameter-space metric & eigenvalues. */
  LALU4CreateVector( status->statusPtr, &metricDimensions, (UINT4) 2 );
  BEGINFAIL(status)
    cleanup(status->statusPtr, &metric, &metricDimensions, &eigenval, *tiles, tmplt, ntiles);
  ENDFAIL(status);
  metricDimensions->data[0] = 3;
  metricDimensions->data[1] = 3;
  LALSCreateArray( status->statusPtr, &metric, metricDimensions );
  BEGINFAIL(status)
    cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt, ntiles);
  ENDFAIL(status);
  eigenval = NULL;
  LALSCreateVector( status->statusPtr, &eigenval, 3 );
  BEGINFAIL(status)
    cleanup(status->statusPtr,&metric, &metricDimensions,&eigenval,*tiles,tmplt, ntiles);
  ENDFAIL(status);

  /* Set f0 to frequency of minimum of noise curve. */
  for( cnt = 0; cnt < (INT4) coarseIn->shf.data->length; cnt++ )
  {
    if( coarseIn->shf.data->data[cnt] > 0 && coarseIn->shf.data->data[cnt] <
        shf0 )
    {
      f0 = (REAL4) coarseIn->shf.deltaF * cnt;
      shf0 = coarseIn->shf.data->data[cnt];
    }
  }
  /* Compute noise moments. */
  inspiralTemplate.fLower = coarseIn->fLower;
  inspiralTemplate.fCutoff = coarseIn->fUpper;
  LALGetInspiralMoments( status->statusPtr, &moments, &(coarseIn->shf),
                         &inspiralTemplate );
  BEGINFAIL(status)
    cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
  ENDFAIL(status);

  /* Find the metric. */
  LALInspiralSpinBankMetric(status->statusPtr, metric, &moments, &inspiralTemplate, &f0);
  BEGINFAIL(status)
    cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt, ntiles);
  ENDFAIL(status);
  /* Find eigenvalues and eigenvectors. */
  LALSSymmetricEigenVectors( status->statusPtr, eigenval, metric );
  BEGINFAIL(status)
    cleanup(status->statusPtr,&metric, &metricDimensions,&eigenval,*tiles,tmplt, ntiles);
  ENDFAIL(status);

  /* Allocate first template, which will remain blank. */
  *tiles = tmplt = (SnglInspiralTable *) LALCalloc( 1,
                   sizeof( SnglInspiralTable ) );
  if ( *tiles == NULL )
  {
    cleanup( status->statusPtr, &metric, &metricDimensions, &eigenval,
             *tiles, tmplt, ntiles);
    ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
  }
  *ntiles = 0;

  /* Set stepsizes from eigenvalues and angle from eigenvectors. */
  if( eigenval->data[0] <= 0 || eigenval->data[1] <=0 || eigenval->data[2]
      <= 0 )
  {
    ABORT(status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE);
  }
  dxp = 1.333333*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[0]);
  dyp = 1.333333*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[1]);
  dzp = 0.6666667*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[2]);
  theta = atan2( -metric->data[3], -metric->data[0] );
printf( "theta is %e\n", theta );

  /* If target region is given in terms of masses... */
  if ( ! havePsi )
  {
    /* Hardcode mass range on higher mass for the moment. */
    m2Min = coarseIn->mMin*LAL_MTSUN_SI;
    m2Max = coarseIn->MMax*LAL_MTSUN_SI/2;
    m1Min = 2.0*m2Max;
    m1Max = 15.0*LAL_MTSUN_SI - m2Max;

    /* Set box on unprimed phenom coordinates including region. */
    x0 = 0.9*(3.0/128) / (pow(LAL_PI*f0*(m1Max+m2Max),1.666667)
         *(m1Max*m2Max/pow(m1Max+m2Max,2)));
    myy0 = 1.1*(-.375*LAL_PI) / (pow(LAL_PI*f0*(m1Max+m2Min),0.6666667)*(m1Max*m2Min/pow(m1Max+m2Min,2)));
    z0 = 0;
    x1 = 1.1*(3.0/128) / (pow(LAL_PI*f0*(m1Min+m2Min),1.666667)*(m1Min*m2Min/pow(m1Min+m2Min,2)));
    myy1 = .9*(-.375*LAL_PI) / (pow(LAL_PI*f0*(m1Min+m2Max),0.6666667)*(m1Min*m2Max/pow(m1Min+m2Max,2)));
    z1 = 3.8* LAL_PI/29.961432 * (1+0.75*m2Max/m1Min) * (m1Max/m2Min) * pow(LAL_MTSUN_SI*100.0/(m1Min+m2Min), 0.6666667);
  }
  /* Target region is given in terms of psi etc (unprimed). */
  else
  {
    /* Rescale to dimensionless parameters used internally. */
    x0 = coarseIn->psi0Min / pow( f0, 5./3 );
    x1 = coarseIn->psi0Max / pow( f0, 5./3 );
    myy0 = coarseIn->psi3Min / pow( f0, 2./3 );
    myy1 = coarseIn->psi3Max / pow( f0, 2./3 );
    z0 = coarseIn->betaMin / pow( f0, 2./3 );
    z1 = coarseIn->betaMax / pow( f0, 2./3 );
  }

  /* Set boundaries of bigger box in primed (eigen) coordinates. */
  xp0 = x0 + sin(theta)*sin(theta) * (x1 - x0);
  yp0 = myy0 - cos(theta)*sin(theta) * (x1 - x0);
  yp1 = sin(theta) * (x1 - x0) + cos(theta) * (myy1 - myy0);
  xp1 = sin(theta) * (myy1 - myy0) + cos(theta) * (x1 - x0);
  zp0 = z0;
  zp1 = z1;

  /* This loop generates the template bank. */
  for (zp = 0; zp <= zp1; zp += dzp)
  {
    bccFlag++;
    for (yp = 0; yp<= yp1; yp += dyp)
    {
      for (xp = 0; xp <= xp1; xp += dxp)
      {

        /* If the point is in the target region, allocate a template. */
        x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta);
        y = calculateY(0, yp0, xp, dxp, yp, dyp, bccFlag, theta);
        z = calculateZ(0, zp, dzp);
        if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
          if( tmplt == NULL )
          {
            cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
            ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
          }
        }

        /* If dx behind is not in region, try dx/2 behind. */
        x = calculateX(-1, xp0, xp, dxp, yp, dyp, bccFlag, theta);
        if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          x = calculateX(-0.5, xp0, xp, dxp, yp, dyp, bccFlag, theta);
          if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
              || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
          {
            allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
            if( tmplt == NULL )
            {
              cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
              ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
            }
          }
        }

        /* If dy behind is not in region, try dy/2 behind. */
        x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta);
        y = calculateY(-1, yp0, xp, dxp, yp, dyp, bccFlag, theta);
        if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          y = calculateY(-0.5, yp0, xp, dxp, yp, dyp, bccFlag, theta);
          if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
              || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
          {
            allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
            if (!tmplt){
              cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
              ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
              }
          }
        }

        /* If dz behind is not in region, try dz/2 behind. */
        y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta);
        z = calculateZ(-1, zp, dzp);
        if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          z = calculateZ(-0.5, zp, dzp);
          if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
              || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
          {
            allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
            if (!tmplt){
              cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
              ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
              }
          }
        }

        /* If dx ahead is not in region, try dx/2 ahead. */
        x = calculateX(1, xp0, xp, dxp, yp, dyp, bccFlag, theta);
        y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta);
        z = calculateZ(0, zp, dzp);
        if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          x = calculateX(0.5, xp0, xp, dxp, yp, dyp, bccFlag, theta);
          if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
              || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
          {
            allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
            if (!tmplt){
              cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
              ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
              }
          }
        }

        /* If dy ahead is not in region, try dy/2 ahead. */
        x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta);
        y = calculateY(1, yp0, xp, dxp, yp, dyp, bccFlag, theta);
        if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          y = calculateY(0.5, yp0, xp, dxp, yp, dyp, bccFlag, theta);
          if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
              || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
          {
            allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
            if (!tmplt){
              cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
              ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
              }
          }
        }

        /* If dz ahead is not in region, try dz/2 ahead. */
        y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta);
        z = calculateZ(1, zp, dzp);
        if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) )
            || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
        {
          z = calculateZ(0.5, zp, dzp);
          if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) )
              || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) )
          {
            allocate( x, y, z, f0, &tmplt, ntiles, havePsi );
            if (!tmplt){
              cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
              ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM);
              }
          }
        }
      } /* for (zp...) */
    } /* for (yp...) */
  } /* for (zp...) */

  /* Trim the first template, which was left blank. */
  tmplt = (*tiles)->next;
  LALFree( *tiles );
  *tiles = tmplt;

  /* What if no templates were allocated? ABORT */
  if (*tiles == NULL)
  {
    cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles);
    ABORT(status, INSPIRALSPINBANKC_ENOTILES, INSPIRALSPINBANKC_MSGENOTILES);
  }

  /* free memory allocated for the vectors and arrays */
  cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,NULL,NULL,&cnt);
  DETATCHSTATUSPTR( status );
  RETURN( status );
} /* LALInspiralSpinBank() */
예제 #14
0
int main(int argc, char *argv[])
{
long i;
double window_sum;
LALStatus status={level:0, statusPtr: NULL};
PassBandParamStruc filterpar;
REAL4TimeSeries chan; /* must zero the f0 field */

fprintf(stderr,"make_sft_op version %s\n", MAKE_SFT_VERSION);
fprintf(stderr,"Using frame library %s\n", FrLibVersionF());
fprintf(stderr,"Using LAL version %s\n", LAL_VERSION);


yylex();

if(freq_start<0)freq_start=0;
if(freq_stop<0)freq_stop=total_samples;

/* post_init various subsystems */

post_init_response_files();
post_init_alpha_beta();

/* print settings */
print_settings(stderr);

/* start processing data */
print_data_stats();
print_data(file_debug1, "debug 1");

verify_loaded_data();

generate_fake_data();

linear_interpolate_gaps();
print_data(file_debug2, "debug 2");

/* this is a hack, but it significantly reduces memory footprint */
td_data=do_alloc(1,sizeof(*td_data));
td_data->length=total_samples;
td_data->data=data;

/* setup structure to hold input for Butterworth filter */
chan.data=NULL;
strncpy(chan.name,channel,LALNameLength);
chan.f0=0;
chan.name[LALNameLength-1]=0; /* make sure it is null-terminated */
chan.deltaT=1.0/samples_per_second;
chan.epoch.gpsSeconds=gps_start; /* no need */
chan.epoch.gpsNanoSeconds=0;

if(trace_power){
	fprintf(stderr, "Input data total power=%.*g\n",
		precision, sum_r4_squares(data, total_samples)/samples_per_second);
	}

if(!bypass_highpass_filter && (highpass_filter_f>0) && (highpass_filter_a>0)){
	fprintf(stderr,"Applying high pass filter, f=%g a=%g order=%d\n",
		highpass_filter_f, highpass_filter_a, highpass_filter_order);
	/* Setup Butterworth filter */
	filterpar.name="Butterworth High Pass";
	filterpar.nMax=highpass_filter_order;
	filterpar.f2=highpass_filter_f;
	filterpar.a2=highpass_filter_a;
	/* values that are 'not given' = out of range */
	filterpar.f1=-1.0;
	filterpar.a1=-1.0;
	
	/* REAL4Sequence is the same as REAL4Vector - according to lal/Datatypes.h */
	chan.data=(REAL4Sequence *)td_data;
	LALDButterworthREAL4TimeSeries(&status, &chan, &filterpar);
	TESTSTATUS(&status);

	if(trace_power){
		fprintf(stderr, "After highpass filter total power=%.*g\n",
			precision, sum_r4_squares(data, total_samples)/samples_per_second);
		}
	}
	
if(!bypass_lowpass_filter && (lowpass_filter_f>0) && (lowpass_filter_a > 0)){
	fprintf(stderr,"Applying low pass filter, f=%g a=%g order=%d\n",
		lowpass_filter_f, lowpass_filter_a, lowpass_filter_order);
	/* Setup Butterworth filter */
	filterpar.name="Butterworth Low Pass";
	filterpar.nMax=lowpass_filter_order;
	filterpar.f1=lowpass_filter_f;
	filterpar.a1=lowpass_filter_a;
	/* values that are 'not given' = out of range */
	/* why 2*nsamples ? LAL used to have a bug in it where
	   the pairs were sorted before deciding whether the filter 
	   is lowpass or highpass. Therefore, we need to specify a 
	   large, out of range, frequency f so that we get a low-pass filter.
	   The maximum frequency is Nyquist, hence 2*nsamples is definitely out of range */
	filterpar.f2=2*total_samples;
	filterpar.a2=-1.0;
		/* REAL4Sequence is the same as REAL4Vector - according to lal/Datatypes.h */
	chan.data=(REAL4Sequence *)td_data;
	LALDButterworthREAL4TimeSeries(&status, &chan, &filterpar);
	TESTSTATUS(&status);

	if(trace_power){
		fprintf(stderr, "After lowpass filter total power=%.*g\n",
			precision, sum_r4_squares(data, total_samples)/samples_per_second);
		}
	}

if(!bypass_first_window){
	fprintf(stderr,"Applying Hann window to input data\n");
	for(i=0;i<total_samples;i++)data[i]*=0.5*(1.0-cos((2.0*M_PI*i)/total_samples));
	window_sum=0.5;
	} else {
	window_sum=1.0;
	}

if(trace_power){
	fprintf(stderr, "After windowing total power=%.*g\n",
		precision, sum_r4_squares(data, total_samples)/samples_per_second);
	}

for(i=0;i<3;i++){
	fprintf(stderr,"Allocating phi[%ld]\n", i);
	LALCCreateVector(&status, &(phi[i]), freq_stop-freq_start);
	TESTSTATUS(&status);
	}

compute_test_fft(td_data, phi, 3, freq_start, freq_stop);

/* now free td_data to conserve space */
free(td_data->data);
data=NULL;
free(td_data);
td_data=NULL;

LALCCreateVector(&status, &pgram, freq_stop-freq_start);
TESTSTATUS(&status);

compute_calibrated_periodogram3(phi, freq_start, freq_stop, pgram, window_sum);

print_COMPLEX8Vector(pgram, output_sft, "CALIBRATED FREQUENCY DOMAIN DATA", output_mode, 0, freq_stop-freq_start);

if(output_power!=NULL){
	/* we need more space */
	for(i=0;i<3;i++){
		LALCDestroyVector(&status, &(phi[i]));
		TESTSTATUS(&status);
		}
	LALSCreateVector(&status, &power, freq_stop-freq_start);
	TESTSTATUS(&status);
	for(i=0;i<freq_stop-freq_start;i++)
		power->data[i]=(pgram->data[i].re*pgram->data[i].re+pgram->data[i].im*pgram->data[i].im);
	print_REAL4Vector(power, output_power, "CALIBRATED POWER", output_mode, 0, freq_stop-freq_start);
	}

/* we do not destroy large vectors when we are done unless we need
  to allocate a lot of space again. This reduces run time 
  of the program */
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);  
}
예제 #16
0
void LALTfrWv (LALStatus *stat, REAL4Vector* sig, TimeFreqRep *tfr, TimeFreqParam *param)
{

  INT4    nf;
  INT4    time;
  INT4    column, row;
  INT4    taumax, tau;
  REAL4Vector  *lacf = NULL;      /* local autocorrelation function */
  COMPLEX8Vector  *vtmp = NULL;
  RealFFTPlan  *plan = NULL;

  INITSTATUS(stat);
  ATTATCHSTATUSPTR (stat);

  /* Make sure the arguments are not NULL: */
  ASSERT (sig, stat, TFR_ENULL, TFR_MSGENULL);
  ASSERT (tfr, stat, TFR_ENULL, TFR_MSGENULL);
  ASSERT (param, stat, TFR_ENULL, TFR_MSGENULL);

  /* Make sure the data pointers are not NULL: */
  ASSERT (sig->data, stat, TFR_ENULL, TFR_MSGENULL);
  ASSERT (tfr->timeInstant, stat, TFR_ENULL, TFR_MSGENULL);
  ASSERT (tfr->freqBin, stat, TFR_ENULL, TFR_MSGENULL);
  ASSERT (tfr->map, stat, TFR_ENULL, TFR_MSGENULL);

  /* Make sure the requested TFR type corresponds to what will be done */
  ASSERT (tfr->type == WignerVille , stat, TFR_ENAME, TFR_MSGENAME);
  ASSERT (param->type == WignerVille , stat, TFR_ENAME, TFR_MSGENAME);

  /* Make sure the number of freq bins is a positive number: */
  nf = tfr->fRow;
  ASSERT (nf > 0 , stat, TFR_EFROW, TFR_MSGEFROW);

  /* Make sure the number of freq bins is a power of 2: */
  while(!(nf & 1))
      nf = nf>>1;

  ASSERT (nf == 1, stat, TFR_EFROW, TFR_MSGEFROW);

  /* Make sure the timeInstant indicates existing time instants */
  for (column=0 ; column<tfr->tCol ; column++)
    {
      if ((tfr->timeInstant[column] < 0) || (tfr->timeInstant[column] > (INT4)(sig->length-1)))
	{
	  ASSERT (tfr->timeInstant[column] > 0, stat, TFR_EBADT, TFR_MSGEBADT);
	  ASSERT (tfr->timeInstant[column] < (INT4)sig->length, stat, TFR_EBADT, TFR_MSGEBADT);
	}
    }
    TRY(LALCreateForwardRealFFTPlan(stat->statusPtr, &plan,(UINT4)tfr->fRow,0),stat);

  TRY(LALSCreateVector(stat->statusPtr, &lacf, tfr->fRow), stat);
  TRY(LALCCreateVector(stat->statusPtr, &vtmp, tfr->fRow/2+1), stat);

  for (column = 0; column < tfr->tCol; column++)
    {

      for (row = 0; row < tfr->fRow; row++)
	lacf->data[row] = 0.0;

      time = tfr->timeInstant[column];
      taumax = MIN (time, (INT4)(sig->length -1 - time));
      taumax = MIN (taumax, (tfr->fRow / 2 - 1));

      for (tau = -taumax; tau <= taumax; tau++)
	{
	  row = (tfr->fRow+tau)%tfr->fRow;
	  lacf->data[row] =   sig->data[time + tau]*sig->data[time - tau];
        }

      tau=tfr->fRow/2;
      if ((time<=(INT4)sig->length-tau-1)&(time>=tau))
	lacf->data[tau] =  sig->data[time+tau]*sig->data[time-tau];

      LALForwardRealFFT(stat->statusPtr, vtmp, lacf, plan);

      for (row = 0; row < (tfr->fRow/2+1); row++)
	tfr->map[column][row] = crealf(vtmp->data[row]);

    }
  /* Reflecting frequency halfing in WV distrob so multiply by 1/2 */
  for (row = 0; row < (tfr->fRow/2+1) ; row++)
    tfr->freqBin[row] = (REAL4) row / (2 *tfr->fRow);

  TRY(LALSDestroyVector(stat->statusPtr, &lacf), stat);
  TRY(LALCDestroyVector(stat->statusPtr, &vtmp), stat);

  TRY(LALDestroyRealFFTPlan(stat->statusPtr, &plan), stat);

  DETATCHSTATUSPTR (stat);

  (void)param;

  /* normal exit */
  RETURN (stat);
}
예제 #17
0
/**
 * Handle user-input and check its validity.
 * Load ephemeris and calculate AM-coefficients (stored globally)
 */
void
Initialize (LALStatus *status, struct CommandLineArgsTag *CLA)
{
  EphemerisData *edat=NULL;          /* Stores earth/sun ephemeris data for barycentering */
  BarycenterInput baryinput;         /* Stores detector location and other barycentering data */
  EarthState earth;
  AMCoeffsParams *amParams;
  LIGOTimeGPS *midTS=NULL;           /* Time stamps for amplitude modulation coefficients */
  LALDetector *Detector;              /* Our detector*/
  INT4 k;

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  if ( XLALUserVarWasSet ( &(CLA->nTsft) ) )
    CLA->duration = 1.0 * CLA->nTsft * CLA->Tsft;

  /* read or generate SFT timestamps */
  if ( XLALUserVarWasSet(&(CLA->timestamps)) ) 
    { 
      XLAL_CHECK_LAL ( status, ( timestamps = XLALReadTimestampsFile ( CLA->timestamps ) ) != NULL, XLAL_EFUNC );
      if ( (CLA->nTsft > 0) && ( (UINT4)CLA->nTsft < timestamps->length ) )	/* truncate if required */
	timestamps->length = CLA->nTsft;
      
      CLA->nTsft = timestamps->length;
    } /* if have_timestamps */
  else 
    {
      LIGOTimeGPS tStart;
      tStart.gpsSeconds = CLA->gpsStart;
      tStart.gpsNanoSeconds = 0;

      XLAL_CHECK_LAL ( status, ( timestamps = XLALMakeTimestamps( tStart, CLA->duration, CLA->Tsft, 0 ) ) != NULL, XLAL_EFUNC );
      CLA->nTsft = timestamps->length;

    } /* no timestamps */

  /*---------- initialize detector ---------- */
  {
    BOOLEAN have_IFO       = XLALUserVarWasSet ( &CLA->IFO );
    BOOLEAN have_detector  = XLALUserVarWasSet ( &CLA->detector );
    CHAR *IFO;

    if ( !have_IFO  && !have_detector ) {
      fprintf (stderr, "\nNeed to specify the detector (--IFO) !\n\n");
      ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT);
    }
    if ( have_IFO )
      IFO = CLA->IFO;
    else
      IFO = CLA->detector;

    if ( ( Detector = XLALGetSiteInfo ( IFO ) ) == NULL ) {
      ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT);
    }
  }

  /* ---------- load ephemeris-files ---------- */
  {
    edat = XLALInitBarycenter( CLA->ephemEarth, CLA->ephemSun );
    if ( !edat ) {
      XLALPrintError("XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", CLA->ephemEarth, CLA->ephemSun);
      ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT);
    }
  } /* ephemeris-reading */


  /* ---------- calculate AM-coefficients ---------- */

  /* prepare call to barycentering routing */
  baryinput.site.location[0] = Detector->location[0]/LAL_C_SI;
  baryinput.site.location[1] = Detector->location[1]/LAL_C_SI;
  baryinput.site.location[2] = Detector->location[2]/LAL_C_SI;
  baryinput.alpha = CLA->Alpha;
  baryinput.delta = CLA->Delta;
  baryinput.dInv = 0.e0;

  /* amParams structure to compute a(t) and b(t) */

  /* Allocate space for amParams stucture */
  /* Here, amParams->das is the Detector and Source info */
  amParams = (AMCoeffsParams *)LALMalloc(sizeof(AMCoeffsParams));
  amParams->das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource));
  amParams->das->pSource = (LALSource *)LALMalloc(sizeof(LALSource));
  /* Fill up AMCoeffsParams structure */
  amParams->baryinput = &baryinput;
  amParams->earth = &earth; 
  amParams->edat = edat;
  amParams->das->pDetector = Detector; 
  amParams->das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
  amParams->das->pSource->equatorialCoords.longitude = CLA->Alpha;
  amParams->das->pSource->equatorialCoords.latitude = CLA->Delta;
  amParams->das->pSource->orientation = 0.0;

  amParams->polAngle = amParams->das->pSource->orientation ; /* These two have to be the same!!!!!!!!!*/
  
  /* Allocate space for AMCoeffs */
  XLAL_INIT_MEM(amc);
  TRY ( LALSCreateVector(status->statusPtr, &(amc.a), (UINT4)  CLA->nTsft), status);
  TRY ( LALSCreateVector(status->statusPtr, &(amc.b), (UINT4)  CLA->nTsft), status);
  
  /* Mid point of each SFT */
  midTS = (LIGOTimeGPS *)LALCalloc(CLA->nTsft,sizeof(LIGOTimeGPS));
  for(k=0; k < CLA->nTsft; k++)
    {
      /* FIXME:  loss of precision; consider
      midTS[k] = timestamps->data[k];
      XLALGPSAdd(&midTS[k], 0.5*CLA->Tsft);
      */
      REAL8 teemp=0.0;
      teemp = XLALGPSGetREAL8(&(timestamps->data[k]));
      teemp += 0.5*CLA->Tsft;
      XLALGPSSetREAL8(&(midTS[k]), teemp);
    }
  
  TRY ( LALComputeAM(status->statusPtr, &amc, midTS, amParams), status);

  /* Free memory */
  XLALDestroyTimestampVector ( timestamps);

  LALFree(midTS);
  LALFree(Detector);
  XLALDestroyEphemerisData(edat);

  LALFree(amParams->das->pSource);
  LALFree(amParams->das);
  LALFree(amParams);


  DETATCHSTATUSPTR (status);
  RETURN(status);

} /* ParseUserInput() */
/**
 * \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 {
예제 #19
0
int main( int argc, char *argv[] )
{
  static LALStatus                status;

  StochasticOmegaGWParameters   parameters;
  REAL4FrequencySeries     omegaGW;

  UINT4 i;
  REAL4 omega, f;
  INT4 code;


  /* define valid parameters */

  parameters.alpha    = STOCHASTICOMEGAGWTESTC_ALPHA;
  parameters.fRef     = STOCHASTICOMEGAGWTESTC_FREF;
  parameters.omegaRef = STOCHASTICOMEGAGWTESTC_OMEGAREF;
  parameters.length   = STOCHASTICOMEGAGWTESTC_LENGTH;
  parameters.f0       = STOCHASTICOMEGAGWTESTC_F0;
  parameters.deltaF   = STOCHASTICOMEGAGWTESTC_DELTAF;

  omegaGW.data = NULL;

#ifndef LAL_NDEBUG
  REAL4FrequencySeries     dummyOutput;
  dummyOutput.data = NULL;
#endif


  ParseOptions( argc, argv );

  LALSCreateVector(&status, &(omegaGW.data), STOCHASTICOMEGAGWTESTC_LENGTH);
  if ( ( code = CheckStatus(&status, 0 , "",
			    STOCHASTICOMEGAGWTESTC_EFLS,
			    STOCHASTICOMEGAGWTESTC_MSGEFLS) ) )
  {
    return code;
  }

  /* TEST INVALID DATA HERE ------------------------------------------ */
#ifndef LAL_NDEBUG
  if ( ! lalNoDebug )
  {
    /* test behavior for null pointer to real frequency series for output */
    LALStochasticOmegaGW(&status, NULL, &parameters);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
			      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
      return code;
    }
    printf("  PASS: null pointer to output series results in error:       \n\"%s\"\n",
	   STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);


    /* test behavior for null pointer to parameter structure */
    LALStochasticOmegaGW(&status, &omegaGW, NULL);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
			      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
      return code;
    }
    printf("  PASS: null pointer to parameter structure results in error:       \n\"%s\"\n",
	   STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);


    /* test behavior for null pointer to data member of real frequency
       series for output */
    LALStochasticOmegaGW(&status, &dummyOutput, &parameters);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
			      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
      return code;
    }
    printf("  PASS: null pointer to data member of output series results in error:       \n\"%s\"\n",
           STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);


    /* Create a vector for testing null data-data pointer */
    LALSCreateVector(&status, &(dummyOutput.data), STOCHASTICOMEGAGWTESTC_LENGTH);
    if ( ( code = CheckStatus(&status, 0 , "",
			      STOCHASTICOMEGAGWTESTC_EFLS,
			      STOCHASTICOMEGAGWTESTC_MSGEFLS) ) )
    {
      return code;
    }
    REAL4                *tempPtr;
    tempPtr = dummyOutput.data->data;
    dummyOutput.data->data = NULL;

    /* test behavior for null pointer to data member of data member of
       real frequency series for output */
    LALStochasticOmegaGW(&status, &dummyOutput, &parameters);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR,
			      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
      return code;
    }
    printf("  PASS: null pointer to data member of data member of output series results in error:       \n\"%s\"\n",
           STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

    /* clean up */

    dummyOutput.data->data = tempPtr;
    LALSDestroyVector(&status, &(dummyOutput.data));
    if ( ( code = CheckStatus(&status, 0 , "",
			      STOCHASTICOMEGAGWTESTC_EFLS,
			      STOCHASTICOMEGAGWTESTC_MSGEFLS) ) )
    {
      return code;
    }

    /* test behavior for length parameter equal to zero */
    parameters.length = 0;
    LALStochasticOmegaGW(&status, &omegaGW, &parameters);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EZEROLEN,
			      STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
      return code;
    }
    printf("  PASS: zero length parameter results in error:       \n\"%s\"\n",
	   STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN);
    /* assign valid length parameter */
    parameters.length = STOCHASTICOMEGAGWTESTC_LENGTH;

    /* test behavior for frequency spacing less than or equal to zero */
    parameters.deltaF = -1;
    LALStochasticOmegaGW(&status, &omegaGW, &parameters);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF,
			      STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
      return code;
    }
    printf("  PASS: negative frequency spacing results in error:       \n\"%s\"\n",
	   STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF);

    parameters.deltaF = 0;
    LALStochasticOmegaGW(&status, &omegaGW, &parameters);
    if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF,
			      STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF,
			      STOCHASTICOMEGAGWTESTC_ECHK,
			      STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
    {
        return code;
    }
    printf("  PASS: zero frequency spacing results in error:       \n\"%s\"\n",
	   STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF);
    /* assign valid frequency spacing */
    parameters.deltaF = STOCHASTICOMEGAGWTESTC_DELTAF;
  }

#endif /* LAL_NDEBUG */

  /* test behavior for negative start frequency */
  parameters.f0 = -20.0;
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENEGFMIN,
			    STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN,
			    STOCHASTICOMEGAGWTESTC_ECHK,
			    STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
  {
    return code;
  }
  printf("  PASS: negative start frequency results in error:\n       \"%s\"\n",
         STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN);

  /* reassign valid start frequency */
  parameters.f0 = STOCHASTICOMEGAGWTESTC_F0;

  /* test behavior for length of data member of real frequency series
     for output not equal to length specified in input parameters */
  parameters.length += 1;
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EMMLEN,
			    STOCHASTICCROSSCORRELATIONH_MSGEMMLEN,
			    STOCHASTICOMEGAGWTESTC_ECHK,
			    STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
  {
    return code;
  }
  printf("  PASS: mismatch between length of output series and length parameter results in error:       \n\"%s\"\n",
	 STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  /* reassign valid length to data member of dummy output */
  parameters.length -= 1;

  /* test behavior for fRef < deltaf */
  parameters.fRef = 0;
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EOORFREF,
                          STOCHASTICCROSSCORRELATIONH_MSGEOORFREF,
			  STOCHASTICOMEGAGWTESTC_ECHK,
			    STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
  {
    return code;
  }
  printf("  PASS: zero reference frequency results in error:       \n\"%s\"\n",
	 STOCHASTICCROSSCORRELATIONH_MSGEOORFREF);
  parameters.fRef = STOCHASTICOMEGAGWTESTC_FREF;

  /* test behavior for omegaRef <=0 */
  parameters.omegaRef = -1.0;
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status,  STOCHASTICCROSSCORRELATIONH_ENONPOSOMEGA,
                          STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA,
			  STOCHASTICOMEGAGWTESTC_ECHK,
			    STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
  {
    return code;
  }
  printf("  PASS: negative amplitude parameter results in error:       \n\"%s\"\n",
	 STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA);

  parameters.omegaRef = 0.0;
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status,  STOCHASTICCROSSCORRELATIONH_ENONPOSOMEGA,
			    STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA,
			    STOCHASTICOMEGAGWTESTC_ECHK,
			    STOCHASTICOMEGAGWTESTC_MSGECHK) ) )
  {
    return code;
  }
  printf("  PASS: zero amplitude parameter results in error:       \n\"%s\"\n",
	 STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA);
  parameters.omegaRef = STOCHASTICOMEGAGWTESTC_OMEGAREF;

  /* TEST VALID DATA HERE -------------------------------------------- */

  /* generate omegaGW */
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status,0, "",
			    STOCHASTICOMEGAGWTESTC_EFLS,
			    STOCHASTICOMEGAGWTESTC_MSGEFLS) ) )
  {
    return code;
  }

  /* test values */

  for (i=0; i<STOCHASTICOMEGAGWTESTC_LENGTH; ++i)
  {
    f = i * STOCHASTICOMEGAGWTESTC_DELTAF;
    omega = STOCHASTICOMEGAGWTESTC_OMEGAREF
      * pow(f/STOCHASTICOMEGAGWTESTC_FREF,STOCHASTICOMEGAGWTESTC_ALPHA);
    if (optVerbose)
    {
      printf("Omega(%f Hz)=%g, should be %g\n",
             f, omegaGW.data->data[i], omega);
    }
    if ( (omegaGW.data->data[i] - omega) &&
         abs((omegaGW.data->data[i] - omega)/omega) > STOCHASTICOMEGAGWTESTC_TOL )
    {
      printf("  FAIL: Valid data test #1 (alpha=%f)\n",STOCHASTICOMEGAGWTESTC_ALPHA);
      return STOCHASTICOMEGAGWTESTC_EFLS;
    }
  }
  printf("  PASS: Valid data test #1 (alpha=%f)\n",STOCHASTICOMEGAGWTESTC_ALPHA);

  /* change parameters */
  parameters.alpha = 0.0;

  /* generate omegaGW */
  LALStochasticOmegaGW(&status, &omegaGW, &parameters);
  if ( ( code = CheckStatus(&status,0, "",
			    STOCHASTICOMEGAGWTESTC_EFLS,
			    STOCHASTICOMEGAGWTESTC_MSGEFLS) ) )
  {
    return code;
  }

  /* test values */

  for (i=0; i<STOCHASTICOMEGAGWTESTC_LENGTH; ++i)
  {
    f = i * STOCHASTICOMEGAGWTESTC_DELTAF;
    if (optVerbose) {
      printf("Omega(%f Hz)=%g, should be %g\n",
             f, omegaGW.data->data[i], STOCHASTICOMEGAGWTESTC_OMEGAREF);
    }
    if ( abs(omegaGW.data->data[i] - STOCHASTICOMEGAGWTESTC_OMEGAREF)
         / STOCHASTICOMEGAGWTESTC_OMEGAREF > STOCHASTICOMEGAGWTESTC_TOL )
    {
      printf("  FAIL: Valid data test #2 (alpha=0)\n");
      return STOCHASTICOMEGAGWTESTC_EFLS;
    }
  }
  printf("  PASS: Valid data test #2 (alpha=0)\n");

  /* clean up valid data */
  LALSDestroyVector(&status, &(omegaGW.data));
  if ( ( code = CheckStatus(&status, 0 , "",
			    STOCHASTICOMEGAGWTESTC_EFLS,
			    STOCHASTICOMEGAGWTESTC_MSGEFLS) ) )
  {
    return code;
  }

  LALCheckMemoryLeaks();

  printf("PASS: all tests\n");

  if (optFile[0]) {
    parameters.alpha = optAlpha;
    parameters.length = optLength;
    parameters.deltaF = optDeltaF;
    parameters.f0 = optF0;
    parameters.omegaRef = optOmegaR;
    parameters.fRef = optFR;
    LALSCreateVector(&status, &(omegaGW.data), optLength);
    if ( ( code = CheckStatus(&status, 0 , "",
			      STOCHASTICOMEGAGWTESTC_EUSE,
			      STOCHASTICOMEGAGWTESTC_MSGEUSE) ) )
    {
      return code;
    }
    LALStochasticOmegaGW(&status, &omegaGW, &parameters);
    if ( ( code = CheckStatus(&status,0, "",
			      STOCHASTICOMEGAGWTESTC_EUSE,
			      STOCHASTICOMEGAGWTESTC_MSGEUSE) ) )
    {
      return code;
    }
    LALSPrintFrequencySeries( &omegaGW, optFile );

    printf("=== Stochastic Gravitational-wave Spectrum Written to File %s ===\n", optFile);


    LALSDestroyVector(&status, &(omegaGW.data));
    if ( ( code = CheckStatus(&status, 0 , "",
			      STOCHASTICOMEGAGWTESTC_EUSE,
			      STOCHASTICOMEGAGWTESTC_MSGEUSE) ) )
    {
      return code;
    }
    LALCheckMemoryLeaks();
  }

  return STOCHASTICOMEGAGWTESTC_ENOM;
}
예제 #20
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 );
}
void
LALInspiralEccentricityForInjection(
			     LALStatus        *status,
			     CoherentGW       *waveform,
			     InspiralTemplate *params,
			     PPNParamStruc  *ppnParams
			     )
{

  INT4        count, i;
  REAL8       p, phiC;

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

  CreateVectorSequenceIn in;

  CHAR message[256];

  InspiralInit paramsInit;

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

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

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

  if (paramsInit.nbins == 0){
      DETATCHSTATUSPTR(status);
      RETURN (status);
  }

  /* Now we can allocate memory and vector for coherentGW structure*/

  ff.length  = paramsInit.nbins;
  a.length   = 2* paramsInit.nbins;
  phi.length = paramsInit.nbins;

  ff.data = (REAL4 *) LALCalloc(paramsInit.nbins, sizeof(REAL4));
  a.data  = (REAL4 *) LALCalloc(2 * paramsInit.nbins, sizeof(REAL4));
  phi.data= (REAL8 *) LALCalloc(paramsInit.nbins, sizeof(REAL8));

  /* Check momory allocation is okay */
  if (!(ff.data) || !(a.data) || !(phi.data))
  {
    if (ff.data)  LALFree(ff.data);
    if (a.data)   LALFree(a.data);
    if (phi.data) LALFree(phi.data);

    ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM );
  }

  count = 0;

  /* Call the engine function */
  LALInspiralEccentricityEngine(status->statusPtr, NULL, NULL, &a, &ff, &phi, &count, params);
  BEGINFAIL( status )
  {
    LALFree(ff.data);
    LALFree(a.data);
    LALFree(phi.data);
  }
  ENDFAIL( status );

  p = phi.data[count-1];

  params->fFinal = ff.data[count-1];
  sprintf(message, "cycles = %f", p/(double)LAL_TWOPI);
  LALInfo(status, message);

  if ( (INT4)(p/LAL_TWOPI) < 2 ){
    sprintf(message, "The waveform has only %f cycles; we don't keep waveform with less than 2 cycles.",
	       p/(double)LAL_TWOPI );
    XLALPrintError("%s", message);
    LALWarning(status, message);
  }

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

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


      in.length = (UINT4)(count);
      in.vectorLength = 2;

      LALSCreateVectorSequence( status->statusPtr, &( waveform->a->data ), &in );
      CHECKSTATUSPTR(status);

      LALSCreateVector( status->statusPtr, &( waveform->f->data ), count);
      CHECKSTATUSPTR(status);

      LALDCreateVector( status->statusPtr, &( waveform->phi->data ), count );
      CHECKSTATUSPTR(status);

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

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

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

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

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

      ppnParams->fStart   = ppnParams->fStartIn;

  /* --- free memory --- */
  LALFree(ff.data);
  LALFree(a.data);
  LALFree(phi.data);

  DETATCHSTATUSPTR(status);
  RETURN (status);
}
예제 #22
0
int main(void)
{
  const INT4 Nsignal=16;
  const INT4 Nwindow=5;
  const INT4 Nfft=8;

  static LALStatus status;

  REAL4Vector  *signalvec = NULL;
  CreateTimeFreqIn tfrIn;
  TimeFreqRep  *tfr = NULL;
  TimeFreqParam *param = NULL;

  INT4 column;
  INT4 row;


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

  LALSCreateVector(&status, &signalvec, Nsignal);

  for (column = 0; column < (INT4)signalvec->length; column++)
    signalvec->data[column]=(rand() % 10) / 2.0;

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

  tfrIn.type=Spectrogram;
  tfrIn.fRow=Nfft;
  tfrIn.tCol=Nsignal;
  tfrIn.wlengthT=Nwindow;
  tfrIn.wlengthF=0;

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

  LALCreateTimeFreqRep(&status, &tfr, &tfrIn);

  for (column = 0; column < tfr->tCol; column++)
    tfr->timeInstant[column]=column;

  LALCreateTimeFreqParam(&status, &param, &tfrIn);

  for (column = 0; column < (INT4)param->windowT->length; column++)
    param->windowT->data[column]=1.0;

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

  LALTfrSp(&status,signalvec,tfr,param);
  REPORTSTATUS(&status);

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

  printf("Signal:\n");
  for (column= 0; column < (INT4)signalvec->length; column++)
    printf("%1.1f ",signalvec->data[column]);
  printf("\n\n");

  printf("TFR:\n");
  for (row= 0; row < (tfr->fRow/2+1); row++)
    {
    for (column= 0; column < tfr->tCol; column++)
      printf("%2.2f ",tfr->map[column][row]);
    printf("\n");
    }

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

  LALSDestroyVector(&status,&signalvec);
  LALDestroyTimeFreqRep(&status,&tfr);
  LALDestroyTimeFreqParam(&status,&param);

  LALCheckMemoryLeaks();

  return 0;
}
예제 #23
0
int main( int argc, char *argv[] )
{
  const UINT4 n  = 65536;
  const REAL4 dt = 1.0 / 16384.0;
  static LALStatus status;

  static REAL4TimeSeries         x;
  static COMPLEX8FrequencySeries X;

  static REAL4TimeSeries         y;
  static REAL4FrequencySeries    Y;

  static COMPLEX8TimeSeries      z;
  static COMPLEX8FrequencySeries Z;

  RealFFTPlan    *fwdRealPlan    = NULL;
  RealFFTPlan    *revRealPlan    = NULL;
  ComplexFFTPlan *fwdComplexPlan = NULL;
  ComplexFFTPlan *revComplexPlan = NULL;
  RandomParams   *randpar        = NULL;

  AverageSpectrumParams avgSpecParams;

  UINT4 srate[] = { 4096, 9000 };
  UINT4 npts[] = { 262144, 1048576 };
  REAL4 var[] = { 5, 16 };

  UINT4 j, sr, np, vr;


  /*CHAR fname[2048];*/

  ParseOptions( argc, argv );

  LALSCreateVector( &status, &x.data, n );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCCreateVector( &status, &X.data, n / 2 + 1 );
  TestStatus( &status, CODES( 0 ), 1 );

  LALCCreateVector( &status, &z.data, n );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCCreateVector( &status, &Z.data, n );
  TestStatus( &status, CODES( 0 ), 1 );

  LALCreateForwardRealFFTPlan( &status, &fwdRealPlan, n, 0 );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCreateReverseRealFFTPlan( &status, &revRealPlan, n, 0 );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCreateForwardComplexFFTPlan( &status, &fwdComplexPlan, n, 0 );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCreateReverseComplexFFTPlan( &status, &revComplexPlan, n, 0 );
  TestStatus( &status, CODES( 0 ), 1 );

  randpar = XLALCreateRandomParams( 100 );


  /*
   *
   * Try the real transform.
   *
   */


  x.f0 = 0;
  x.deltaT = dt;
  x.sampleUnits = lalMeterUnit;
  snprintf( x.name, sizeof( x.name ), "x" );
  XLALNormalDeviates( x.data, randpar );
  for ( j = 0; j < n; ++j ) /* add a 60 Hz line */
  {
    REAL4 t = j * dt;
    x.data->data[j] += 0.1 * cos( LAL_TWOPI * 60.0 * t );
  }
  LALSPrintTimeSeries( &x, "x.out" );

  snprintf( X.name, sizeof( X.name ), "X" );
  LALTimeFreqRealFFT( &status, &X, &x, fwdRealPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCPrintFrequencySeries( &X, "X.out" );

  LALFreqTimeRealFFT( &status, &x, &X, revRealPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALSPrintTimeSeries( &x, "xx.out" );


  /*
   *
   * Try the average power spectum.
   *
   */


  avgSpecParams.method = useMean;

  for ( np = 0; np < XLAL_NUM_ELEM(npts) ; ++np )
  {
    /* length of time series for 7 segments, overlapped by 1/2 segment */
    UINT4 tsLength = npts[np] * 7 - 6 * npts[np] / 2;
    LALCreateVector( &status, &y.data, tsLength );
    TestStatus( &status, CODES( 0 ), 1 );
    LALCreateVector( &status, &Y.data, npts[np] / 2 + 1  );
    TestStatus( &status, CODES( 0 ), 1 );
    avgSpecParams.overlap = npts[np] / 2;

    /* create the window */
    avgSpecParams.window = XLALCreateHannREAL4Window(npts[np]);
    avgSpecParams.plan = NULL;
    LALCreateForwardRealFFTPlan( &status, &avgSpecParams.plan, npts[np], 0 );
    TestStatus( &status, CODES( 0 ), 1 );

    for ( sr = 0; sr < XLAL_NUM_ELEM(srate) ; ++sr )
    {
      /* set the sample rate of the time series */
      y.deltaT = 1.0 / (REAL8) srate[sr];
      for ( vr = 0; vr < XLAL_NUM_ELEM(var) ; ++vr )
      {
        REAL4 eps = 1e-6; /* very conservative fp precision */
        REAL4 Sfk = 2.0 * var[vr] * var[vr] * y.deltaT;
        REAL4 sfk = 0;
        REAL4 lbn;
        REAL4 sig;
        REAL4 ssq;
        REAL4 tol;

        /* create the data */
        XLALNormalDeviates( y.data, randpar );
        ssq = 0;
        for ( j = 0; j < y.data->length; ++j )
        {
          y.data->data[j] *= var[vr];
          ssq += y.data->data[j] * y.data->data[j];
        }

        /* compute tolerance for comparison */
        lbn = log( y.data->length ) / log( 2 );
        sig = sqrt( 2.5 * lbn * eps * eps * ssq / y.data->length );
        tol = 5 * sig;

        /* compute the psd and find the average */
        LALREAL4AverageSpectrum( &status, &Y, &y, &avgSpecParams );
        TestStatus( &status, CODES( 0 ), 1 );
        LALSMoment( &status, &sfk, Y.data, 1 );
        TestStatus( &status, CODES( 0 ), 1 );

        /* check the result */
        if ( fabs(Sfk-sfk) > tol )
        {
          fprintf( stderr, "FAIL: PSD estimate appears incorrect\n");
          fprintf( stderr, "expected %e, got %e ", Sfk, sfk );
          fprintf( stderr, "(difference = %e, tolerance = %e)\n",
              fabs(Sfk-sfk), tol );
          exit(2);
        }

      }
    }

    /* destroy structures that need to be resized */
    LALDestroyRealFFTPlan( &status, &avgSpecParams.plan );
    TestStatus( &status, CODES( 0 ), 1 );
    XLALDestroyREAL4Window( avgSpecParams.window );
    LALDestroyVector( &status, &y.data );
    TestStatus( &status, CODES( 0 ), 1 );
    LALDestroyVector( &status, &Y.data );
    TestStatus( &status, CODES( 0 ), 1 );
  }


  /*
   *
   * Try the complex transform.
   *
   */


  z.f0 = 0;
  z.deltaT = dt;
  z.sampleUnits = lalVoltUnit;
  snprintf( z.name, sizeof( z.name ), "z" );
  { /* dirty hack */
    REAL4Vector tmp;
    tmp.length = 2 * z.data->length;
    tmp.data   = (REAL4 *)z.data->data;
    XLALNormalDeviates( &tmp, randpar );
  }
  for ( j = 0; j < n; ++j ) /* add a 50 Hz line and a 500 Hz ringdown */
  {
    REAL4 t = j * dt;
    z.data->data[j] += 0.2 * cos( LAL_TWOPI * 50.0 * t );
    z.data->data[j] += I * exp( -t ) * sin( LAL_TWOPI * 500.0 * t );
  }
  LALCPrintTimeSeries( &z, "z.out" );
  TestStatus( &status, CODES( 0 ), 1 );

  snprintf( Z.name, sizeof( Z.name ), "Z" );
  LALTimeFreqComplexFFT( &status, &Z, &z, fwdComplexPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCPrintFrequencySeries( &Z, "Z.out" );

  LALFreqTimeComplexFFT( &status, &z, &Z, revComplexPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCPrintTimeSeries( &z, "zz.out" );

  XLALDestroyRandomParams( randpar );

  LALDestroyRealFFTPlan( &status, &fwdRealPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALDestroyRealFFTPlan( &status, &revRealPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALDestroyComplexFFTPlan( &status, &fwdComplexPlan );
  TestStatus( &status, CODES( 0 ), 1 );
  LALDestroyComplexFFTPlan( &status, &revComplexPlan );
  TestStatus( &status, CODES( 0 ), 1 );

  LALCDestroyVector( &status, &Z.data );
  TestStatus( &status, CODES( 0 ), 1 );
  LALCDestroyVector( &status, &z.data );
  TestStatus( &status, CODES( 0 ), 1 );

  LALCDestroyVector( &status, &X.data );
  TestStatus( &status, CODES( 0 ), 1 );
  LALSDestroyVector( &status, &x.data );
  TestStatus( &status, CODES( 0 ), 1 );

  LALCheckMemoryLeaks();
  return 0;
}
예제 #24
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;
}
예제 #25
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);


}
예제 #26
0
void LALCreateTimeFreqParam (LALStatus *status,
			TimeFreqParam **param,
			CreateTimeFreqIn *in)
{
  /* Initialize status */
  INITSTATUS(status);

  /* Check input structure: report if NULL */
  ASSERT (in != NULL, status, CREATETFP_ENULL, CREATETFP_MSGENULL);

  /* Check return structure  */
  ASSERT (param != NULL, status, CREATETFP_ENULL, CREATETFP_MSGENULL);
  ASSERT (*param == NULL, status, CREATETFP_ENNUL, CREATETFP_MSGENNUL);

  *param = (TimeFreqParam *) LALMalloc(sizeof(TimeFreqParam));

  /* Check Allocation */
  ASSERT (*param != NULL, status, CREATETFP_EMALL, CREATETFP_MSGEMALL);

  (*param)->type=Undefined; /* Undefined until storage allocated */
  (*param)->windowT = NULL; /* NULL data until allocated */
  (*param)->windowF = NULL; /* NULL data until allocated */

  switch (in->type) {
  case Spectrogram :

    /* Make sure the window length is a odd number */
    ASSERT (in->wlengthT%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ);

    LALSCreateVector(status,&(*param)->windowT,in->wlengthT);
    (*param)->type = Spectrogram;

    break;
  case WignerVille :

    (*param)->type = WignerVille;

    break;
  case PSWignerVille :

    /* Make sure the window length is a odd number */
    ASSERT (in->wlengthT%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ);

    /* Make sure the window length is a odd number */
    ASSERT (in->wlengthF%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ);

    LALSCreateVector(status,&(*param)->windowT,in->wlengthT);
    LALSCreateVector(status,&(*param)->windowF,in->wlengthF);
    (*param)->type = PSWignerVille;

    break;
  case RSpectrogram :

    /* Make sure the window length is a odd number */
    ASSERT (in->wlengthT%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ);

    LALSCreateVector(status,&(*param)->windowT,in->wlengthT);
    (*param)->type = RSpectrogram;

    break;
  default :
    ABORT(status,CREATETFP_ETYPE, CREATETFP_MSGETYPE);

  }

  /* We be done: Normal exit */

  RETURN (status);
}
예제 #27
0
/** \see See \ref DetInverse_c for documentation */
void
LALSMatrixInverse( LALStatus *stat, REAL4 *det, REAL4Array *matrix, REAL4Array *inverse )
{
  INT2 sgn;                 /* sign of permutation. */
  UINT4 n, i, j, ij;        /* array dimension and indecies */
  UINT4Vector *indx = NULL; /* permutation storage vector */
  REAL4Vector *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 );
  LALSCreateVector( stat->statusPtr, &col, n );
  BEGINFAIL( stat ) {
    TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
  } ENDFAIL( stat );

  /* Decompose the matrix. */
  sgn = 0;	/* silence -Werror=maybe-uninitialized.  note:  there is no check here that LALSLUDecomp() is successful and the compiler knows this.  *that's* the real problem, but I'm not fixing (Kipp) */
  LALSLUDecomp( stat->statusPtr, &sgn, matrix, indx );
  BEGINFAIL( stat ) {
    TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
    TRY( LALSDestroyVector( 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(REAL4) );
    col->data[j] = 1.0;
    LALSLUBackSub( stat->statusPtr, col, matrix, indx );
    BEGINFAIL( stat ) {
      TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat );
      TRY( LALSDestroyVector( 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( LALSDestroyVector( stat->statusPtr, &col ), stat );
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
예제 #28
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 a continuous waveform with frequency drift and Doppler
 * modulation from an elliptical 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$\notin(0,1]\f$
 * (an open 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 elliptical 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 the eccentric anomaly \f$E\f$:
 * \f{eqnarray}{
 * \label{eq_tr-e1}
 * t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega\\
 * & + & \left(\frac{P}{2\pi}\right) \left( E +
 * \left[v_p(1-e)\cos\omega - e\right]\sin E
 * + \left[v_p\sqrt{\frac{1-e}{1+e}}\sin\omega\right]
 * [\cos 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$P=2\pi\sqrt{(1+e)/(1-e)^3}/\dot{\upsilon}_p\f$ is the
 * period of the orbit.  For simplicity we write this as:
 * \f{equation}{
 * \label{eq_tr-e2}
 * t_r = T_p + \frac{1}{n}\left( E + A\sin E + B[\cos E - 1] \right) \;,
 * \f}
 *
 * \figure{inject_eanomaly,eps,0.23,Function to be inverted to find eccentric anomaly}
 *
 * where \f$T_p\f$ is the \e observed time of periapsis passage and
 * \f$n=2\pi/P\f$ is the mean angular speed around the orbit.  Thus the key
 * numerical procedure in this routine is to invert the expression
 * \f$x=E+A\sin E+B(\cos E - 1)\f$ to get \f$E(x)\f$.  We note that
 * \f$E(x+2n\pi)=E(x)+2n\pi\f$, so we only need to solve this expression in
 * the interval \f$[0,2\pi)\f$, sketched to the right.
 *
 * We further 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 the point of inflection, and an
 * initial guess or iteration landing near this point will send the next
 * iteration off to unacceptably large or small values.  However, by
 * restricting all initial guesses and iterations to the domain
 * \f$E\in[0,2\pi)\f$, one will always end up on a trajectory branch that
 * will converge uniformly.  This should converge faster than the more
 * generically robust technique of bisection. (Note: the danger with Newton's method
 * has been found to be unstable for certain binary orbital parameters. So if
 * Newton's method fails to converge, a bisection algorithm is employed.)
 *
 * In this algorithm, we start the computation with an arbitrary initial
 * guess of \f$E=0\f$, and refine it until the 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 an orbital period, 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 an orbital period.
 * This sequence of guesses will have to readjust itself once every orbit
 * (as \f$E\f$ jumps from \f$2\pi\f$ down to 0), but this is relatively
 * infrequent; we don't bother trying to smooth this out because the
 * additional tests would probably slow down the algorithm overall.
 *
 * 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$(1-e)/(1-e\cos E)\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.
 *
 * The routine does not account for variations in special relativistic or
 * gravitational time dilation due to the elliptical orbit, nor does it
 * deal with other gravitational effects such as Shapiro delay.  To a
 * very rough approximation, the amount of phase error induced by
 * gravitational redshift goes something like \f$\Delta\phi\sim
 * fT(v/c)^2\Delta(r_p/r)\f$, where \f$f\f$ is the typical wave frequency, \f$T\f$
 * is either the length of data or the orbital period (whichever is
 * \e smaller), \f$v\f$ is the \e true (unprojected) speed at
 * periapsis, and \f$\Delta(r_p/r)\f$ is the total range swept out by the
 * quantity \f$r_p/r\f$ over the course of the observation.  Other
 * relativistic effects such as special relativistic time dilation are
 * comparable in magnitude.  We make a crude estimate of when this is
 * significant by noting that \f$v/c\gtrsim v_p\f$ but
 * \f$\Delta(r_p/r)\lesssim 2e/(1+e)\f$; we take these approximations as
 * equalities and require that \f$\Delta\phi\lesssim\pi\f$, giving:
 * \f{equation}{
 * \label{eq_relativistic-orbit}
 * f_0Tv_p^2\frac{4e}{1+e}\lesssim1 \;.
 * \f}
 * When this critereon is violated, a warning is generated.  Furthermore,
 * as noted earlier, when \f$v_p\geq1\f$ the routine will return an error, as
 * faster-than-light speeds can cause the emission and reception times to
 * be non-monotonic functions of one another.
 */
void
LALGenerateEllipticSpinOrbitCW( 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 p, vDotAvg;        /* orbital period, and 2*pi/(period) */
  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 dx, dxMax;         /* current and target errors in x */
  REAL8 a, b;              /* constants in equation for x */
  REAL8 ecc;               /* orbital eccentricity */
  REAL8 oneMinusEcc, onePlusEcc; /* 1 - ecc and 1 + ecc */
  REAL8 e = 0.0;                 /* eccentric anomaly */
  REAL8 de = 0.0;                /* eccentric anomaly step */
  REAL8 sine = 0.0, cose = 0.0;  /* sine of e, and cosine 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. */
  oneMinusEcc = params->oneMinusEcc;
  ecc = 1.0 - oneMinusEcc;
  onePlusEcc = 1.0 + ecc;
  if ( ecc < 0.0 || oneMinusEcc <= 0.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EECC,
	   GENERATESPINORBITCWH_MSGEECC );
  }
  vp = params->rPeriNorm*params->angularSpeed;
  n = params->length;
  dt = params->deltaT;
  f0 = fPrev = params->f0;
  vDotAvg = params->angularSpeed
    *sqrt( oneMinusEcc*oneMinusEcc*oneMinusEcc/onePlusEcc );
  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;
  p = LAL_TWOPI/vDotAvg;
  a = vp*oneMinusEcc*cos( argument ) + oneMinusEcc - 1.0;
  b = vp*sqrt( oneMinusEcc/( onePlusEcc ) )*sin( argument );
  eCosOmega = ecc*cos( argument );
  if ( n*dt > p )
    dxMax = 0.01/( f0*n*dt );
  else
    dxMax = 0.01/( f0*p );
  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 > p )
      tau = p;
    if ( f0*tau*vp*vp*ecc/onePlusEcc > 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 );

  /* 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++ ) {
    INT4 nOrb; /* number of orbits since the specified orbit epoch */

    /* First, find x in the range [0,2*pi]. */
    x = vDotAvg*( i*dt - tPeriObs );
    nOrb = (INT4)( x/LAL_TWOPI );
    if ( x < 0.0 )
      nOrb -= 1;
    x -= LAL_TWOPI*nOrb;

    /* Newton-Raphson iteration to find E(x). Maximum of 100 iterations. */
    INT4 maxiter = 100, iter = 0;
    while ( iter<maxiter && fabs( dx = e + a*sine + b*cose - x ) > dxMax ) {
      iter++;
      //Make a check on the step-size so we don't step too far
      de = dx/( 1.0 + a*cose + a - b*sine );
      if ( de > LAL_PI )
        de = LAL_PI;
      else if ( de < -LAL_PI )
        de = -LAL_PI;
      e -= de;

      if ( e < 0.0 )
        e = 0.0;
      else if ( e > LAL_TWOPI )
        e = LAL_TWOPI;
      sine = sin( e );
      cose = cos( e ) - 1.0;
    }
    /* Bisection algorithm from GSL if Newton's method (above) fails to converge. */
    if (iter==maxiter && fabs( dx = e + a*sine + b*cose - x ) > dxMax ) {
       //Initialize solver
       const gsl_root_fsolver_type *T = gsl_root_fsolver_bisection;
       gsl_root_fsolver *s = gsl_root_fsolver_alloc(T);
       REAL8 e_lo = 0.0, e_hi = LAL_TWOPI;
       gsl_function F;
       struct E_solver_params pars = {a, b, x};
       F.function = &gsl_E_solver;
       F.params = &pars;

       if (gsl_root_fsolver_set(s, &F, e_lo, e_hi) != 0) {
          LALFree( output->a );   output->a = NULL;
          LALFree( output->f );   output->f = NULL;
          LALFree( output->phi ); output->phi = NULL;
          ABORT( stat, -1, "GSL failed to set initial points" );
       }

       INT4 keepgoing = 1;
       INT4 success = 0;
       INT4 root_status = keepgoing;
       e = 0.0;
       iter = 0;
       while (root_status==keepgoing && iter<maxiter) {
          iter++;
          root_status = gsl_root_fsolver_iterate(s);
          if (root_status!=keepgoing && root_status!=success) {
             LALFree( output->a );   output->a = NULL;
             LALFree( output->f );   output->f = NULL;
             LALFree( output->phi ); output->phi = NULL;
             ABORT( stat, -1, "gsl_root_fsolver_iterate() failed" );
          }
          e = gsl_root_fsolver_root(s);
          sine = sin(e);
          cose = cos(e) - 1.0;
          if (fabs( dx = e + a*sine + b*cose - x ) > dxMax) root_status = keepgoing;
          else root_status = success;
       }

       if (root_status!=success) {
          LALFree( output->a );   output->a = NULL;
          LALFree( output->f );   output->f = NULL;
          LALFree( output->phi ); output->phi = NULL;
          gsl_root_fsolver_free(s);
          ABORT( stat, -1, "Could not converge using bisection algorithm" );
       }

       gsl_root_fsolver_free(s);
    }

    /* Compute source emission time, phase, and frequency. */
    phi = t = tPow =
      ( e + LAL_TWOPI*nOrb - ecc*sine )/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(onePlusEcc/oneMinusEcc) * sin(0.5*e), cos(0.5*e) );
    f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega ) /onePlusEcc );
    phi *= twopif0;
    if ( (i > 0) && (fabs( f - fPrev ) > df) )
      df = fabs( f - fPrev );
    *(fData++) = fPrev = f;
    *(phiData++) = phi + phi0;

  } /* for i < n */

  /* Set output field and return. */
  params->dfdt = df*dt;
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}