Esempio n. 1
0
void
LALFreqTimeRealFFT(
    LALStatus               *status,
    REAL4TimeSeries         *time,
    COMPLEX8FrequencySeries *freq,
    RealFFTPlan             *plan
    )
{
  INITSTATUS(status);
  XLAL_PRINT_DEPRECATION_WARNING("XLALREAL4FreqTimeFFT");
  ATTATCHSTATUSPTR( status );

  ASSERT( plan, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( freq, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( time, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( time->data, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( time->data->length, status,
      TIMEFREQFFTH_ESIZE, TIMEFREQFFTH_MSGESIZE );
  ASSERT( freq->deltaF > 0, status, TIMEFREQFFTH_ERATE, TIMEFREQFFTH_MSGERATE );

  /* call the XLAL function */
  if ( XLALREAL4FreqTimeFFT( time, freq, plan ) == XLAL_FAILURE )
  {
    XLALClearErrno();
    ABORTXLAL( status );
  }

  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Esempio n. 2
0
void
LALNormalDeviates (
    LALStatus    *status,
    REAL4Vector  *deviates,
    RandomParams *params
    )
{
  INITSTATUS(status);

  ASSERT (params, status, RANDOMH_ENULL, RANDOMH_MSGENULL);
  ASSERT (deviates, status, RANDOMH_ENULL, RANDOMH_MSGENULL);
  ASSERT (deviates->data, status, RANDOMH_ENULL, RANDOMH_MSGENULL);
  ASSERT (deviates->length > 0, status, RANDOMH_ESIZE, RANDOMH_MSGESIZE);

  if ( XLALNormalDeviates( deviates, params ) != XLAL_SUCCESS )
  {
    int errnum = xlalErrno;
    XLALClearErrno();
    switch ( errnum )
    {
      case XLAL_EFAULT:
        ABORT( status, RANDOMH_ENULL, RANDOMH_MSGENULL );
      case XLAL_EBADLEN:
        ABORT( status, RANDOMH_ESIZE, RANDOMH_MSGESIZE );
      default:
        ABORTXLAL( status );
    }
  }

  RETURN (status);
}
Esempio n. 3
0
void
LALTimeFreqComplexFFT(
    LALStatus               *status,
    COMPLEX8FrequencySeries *freq,
    COMPLEX8TimeSeries      *time,
    ComplexFFTPlan          *plan
    )
{
  INITSTATUS(status);
  XLAL_PRINT_DEPRECATION_WARNING("XLALCOMPLEX8TimeFreqFFT");

  ASSERT( plan, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( freq, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( time, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( time->data, status, TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( time->data->length, status, TIMEFREQFFTH_ESIZE, TIMEFREQFFTH_MSGESIZE );
  ASSERT( time->deltaT > 0, status, TIMEFREQFFTH_ERATE, TIMEFREQFFTH_MSGERATE );
  ASSERT( plan->sign == -1, status, TIMEFREQFFTH_ESIGN, TIMEFREQFFTH_MSGESIGN );

  if ( XLALCOMPLEX8TimeFreqFFT( freq, time, plan ) == XLAL_FAILURE )
  {
    XLALClearErrno();
    ABORTXLAL( status );
  }

  RETURN( status );
}
Esempio n. 4
0
/**
 * DEPRECATED.
 * \deprecated Use XLALCreateDetector() instead.
 */
void LALCreateDetector( LALStatus             *status,
                        LALDetector           *output,
                        const LALFrDetector   *input,
                        const LALDetectorType  type )
{
    INITSTATUS(status);

    ASSERT( input != NULL, status, LALDETECTORSH_ENULLP,
            LALDETECTORSH_MSGENULLP );

    ASSERT( output != NULL, status, LALDETECTORSH_ENULLP,
            LALDETECTORSH_MSGENULLP );

    output = XLALCreateDetector( output, input, type );
    if ( ! output )
        switch ( XLALClearErrno() )
        {
        case XLAL_EINVAL:
            ABORT( status, LALDETECTORSH_ETYPE, LALDETECTORSH_MSGETYPE );
            break;
        default:
            ABORTXLAL( status );
        }

    RETURN(status);
}
Esempio n. 5
0
// LAL wrapper to XLAL Generator function
void LALSQTPNGenerator(LALStatus *status, LALSQTPNWave *waveform, LALSQTPNWaveformParams *params) {
	XLAL_PRINT_DEPRECATION_WARNING("XLALSQTPNGenerator");
	INITSTATUS(status);
	ATTATCHSTATUSPTR(status);

	if(XLALSQTPNGenerator(waveform, params))
		ABORTXLAL(status);

	DETATCHSTATUSPTR(status);
	RETURN(status);
}
void LALSQTPNWaveform (LALStatus *status, REAL4Vector *signalvec, InspiralTemplate *params){

	XLAL_PRINT_DEPRECATION_WARNING("XLALSQTPNWaveform");
	INITSTATUS(status);
	ATTATCHSTATUSPTR(status);

	if(XLALSQTPNWaveform(signalvec, params))
		ABORTXLAL(status);

	DETATCHSTATUSPTR(status);
	RETURN(status);
}
void LALSQTPNWaveformForInjection(LALStatus *status, CoherentGW *waveform,
		InspiralTemplate *params, PPNParamStruc *ppnParams) {

	XLAL_PRINT_DEPRECATION_WARNING("XLALSQTPNWaveformForInjection");
	INITSTATUS(status);
	ATTATCHSTATUSPTR(status);

	if(XLALSQTPNWaveformForInjection(waveform, params, ppnParams))
		ABORTXLAL(status);

	DETATCHSTATUSPTR(status);
	RETURN(status);
}
void
LALInspiralRestrictedAmplitude (LALStatus        *status,
				InspiralTemplate *params )
{
  XLAL_PRINT_DEPRECATION_WARNING("XLALInspiralRestrictedAmplitude");

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  if ( XLALInspiralRestrictedAmplitude(params) == XLAL_FAILURE )
  {
    ABORTXLAL(status);
  }
  DETATCHSTATUSPTR(status);
  RETURN(status);
}
/** \see See \ref LALInspiralMoments_c for documentation */
void
LALInspiralMoments(
    LALStatus         *status,	/**< LAL status pointer */
    REAL8             *moment,	/**< [out] the value of the moment */
    InspiralMomentsIn  pars	/**< [in] input parameters */
    )

{
  INITSTATUS(status);
  XLAL_PRINT_DEPRECATION_WARNING("XLALInspiralMoments");

  *moment = XLALInspiralMoments(pars.xmin, pars.xmax, pars.ndx, pars.norm, pars.shf);
  if (XLAL_IS_REAL8_FAIL_NAN(*moment)){
    ABORTXLAL( status );
  };
  RETURN (status);
}
void
LALInspiralChooseModel(
   LALStatus        *status,
   expnFunc         *f,
   expnCoeffs       *ak,
   InspiralTemplate *params
   )
{
   XLAL_PRINT_DEPRECATION_WARNING("XLALInspiralChooseModel");

   INITSTATUS(status);
   ATTATCHSTATUSPTR(status);

   if (XLALInspiralChooseModel(f, ak, params))
      ABORTXLAL(status);

   DETATCHSTATUSPTR(status);
   RETURN (status);
}
Esempio n. 11
0
/** \see See \ref LALInspiralMoments_c for documentation */
void
LALGetInspiralMoments (
    LALStatus            *status,
    InspiralMomentsEtc   *moments,
    REAL8FrequencySeries *psd,
    InspiralTemplate     *params
    )

{
  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );
  XLAL_PRINT_DEPRECATION_WARNING("XLALGetInspiralMoments");

  if (XLALGetInspiralMoments(moments, params->fLower, params->fCutoff, psd)!= XLAL_SUCCESS){
     ABORTXLAL( status );
  }
  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Esempio n. 12
0
/**
 * Deprecated.
 * \deprecated Use XLALWToZCOMPLEX16ZPGFilter() instead
 */
void
LALWToZCOMPLEX16ZPGFilter( LALStatus          *stat,
			   COMPLEX16ZPGFilter *filter )
{
  INITSTATUS(stat);

  if(XLALWToZCOMPLEX16ZPGFilter(filter)<0)
  {
    int code=xlalErrno;
    XLALClearErrno();
    switch(code){
      case XLAL_EFAULT:
        ABORT(stat,ZPGFILTERH_ENUL,ZPGFILTERH_MSGENUL);
      case XLAL_EINVAL:
        ABORT(stat,ZPGFILTERH_EBAD,ZPGFILTERH_MSGEBAD);
      default:
        ABORTXLAL(stat);
    }
  }

  RETURN(stat);
}
void
LALInspiralPhasing2_7PN (
   LALStatus  *status,
   REAL8      *phase,
   REAL8       v,
   expnCoeffs *ak
   )
{
  XLAL_PRINT_DEPRECATION_WARNING("XLALInspiralPhasing2_7PN");

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  ASSERT(phase, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);

  *phase = XLALInspiralPhasing2_7PN(v, ak);
  if (XLAL_IS_REAL8_FAIL_NAN(*phase))
    ABORTXLAL(status);

  DETATCHSTATUSPTR(status);
  RETURN(status);
}
void
LALCreateTwoIFOCoincListEllipsoid(
    LALStatus                  *status,
    CoincInspiralTable        **coincOutput,
    SnglInspiralTable          *snglInput,
    InspiralAccuracyList       *accuracyParams
    )

{
  INT8                          currentTriggerNS[2];
  CoincInspiralTable           *coincHead = NULL;
  CoincInspiralTable           *thisCoinc = NULL;
  INT4                          numEvents = 0;
  INT8                          maxTimeDiff = 0;
  TriggerErrorList             *errorListHead = NULL;
  TriggerErrorList             UNUSED *thisErrorList = NULL;
  TriggerErrorList             *currentError[2];
  fContactWorkSpace            *workSpace;
  REAL8                        timeError = 0.0;


  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  ASSERT( snglInput, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( coincOutput, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( ! *coincOutput, status,
      LIGOMETADATAUTILSH_ENNUL, LIGOMETADATAUTILSH_MSGENNUL );

  memset( currentTriggerNS, 0, 2 * sizeof(INT8) );

  /* Loop through triggers and assign each of them an error ellipsoid */
  errorListHead = XLALCreateTriggerErrorList( snglInput, accuracyParams->eMatch, &timeError );
  if ( !errorListHead )
  {
    ABORTXLAL( status );
  }

  /* Initialise the workspace for ellipsoid overlaps */
  workSpace = XLALInitFContactWorkSpace( 3, NULL, NULL, gsl_min_fminimizer_brent, 1.0e-2 );
  if (!workSpace)
  {
    XLALDestroyTriggerErrorList( errorListHead );
    ABORTXLAL( status );
  }

  /* calculate the maximum time delay
   * set it equal to 2 * worst IFO timing accuracy plus
   * light travel time for earths diameter
   * (detectors cant be further apart than this) */

  maxTimeDiff = (INT8) (1e9 * 2.0 * timeError);
  maxTimeDiff += (INT8) ( 1e9 * 2 * LAL_REARTH_SI / LAL_C_SI );

  for ( currentError[0] = errorListHead; currentError[0]->next;
      currentError[0] = currentError[0]->next)
  {

    /* calculate the time of the trigger */
    currentTriggerNS[0] = XLALGPSToINT8NS(
                 &(currentError[0]->trigger->end_time) );

    /* set next trigger for comparison */
    currentError[1] = currentError[0]->next;
    currentTriggerNS[1] = XLALGPSToINT8NS(
                 &(currentError[1]->trigger->end_time) );

    while ( (currentTriggerNS[1] - currentTriggerNS[0]) < maxTimeDiff )
    {

      INT2 match;

      /* test whether we have coincidence */
      match = XLALCompareInspiralsEllipsoid( currentError[0],
                 currentError[1], workSpace, accuracyParams );
      if ( match == XLAL_FAILURE )
      {
        /* Error in the comparison function */
        XLALDestroyTriggerErrorList( errorListHead );
        XLALFreeFContactWorkSpace( workSpace );
        ABORTXLAL( status );
      }

      /* Check whether the event was coincident */
      if ( match )
      {
#if 0
        REAL8 etp = XLALCalculateEThincaParameter( currentError[0]->trigger,  currentError[1]->trigger, accuracyParams );
#endif
        /* create a 2 IFO coinc and store */
        if ( ! coincHead  )
        {
          coincHead = thisCoinc = (CoincInspiralTable *)
            LALCalloc( 1, sizeof(CoincInspiralTable) );
        }
        else
        {
          thisCoinc = thisCoinc->next = (CoincInspiralTable *)
            LALCalloc( 1, sizeof(CoincInspiralTable) );
        }
        if ( !thisCoinc )
        {
          /* Error allocating memory */
          thisCoinc = coincHead;
          while ( thisCoinc )
          {
            coincHead = thisCoinc->next;
            LALFree( thisCoinc );
            thisCoinc = coincHead;
          }
          XLALDestroyTriggerErrorList( errorListHead );
          XLALFreeFContactWorkSpace( workSpace );
          ABORT( status, LAL_NOMEM_ERR, LAL_NOMEM_MSG );
        }

        /* Add the two triggers to the coinc */
        LALAddSnglInspiralToCoinc( status->statusPtr, &thisCoinc,
            currentError[0]->trigger );
        LALAddSnglInspiralToCoinc( status->statusPtr, &thisCoinc,
            currentError[1]->trigger );

        ++numEvents;

      }

      /* scroll on to the next sngl inspiral */

      if ( (currentError[1] = currentError[1]->next) )
      {
        currentTriggerNS[1] = XLALGPSToINT8NS( &(currentError[1]->trigger->end_time) );
      }
      else
      {
        LALInfo(status, "Second trigger has reached end of list");
        break;
      }
    }
  }

  *coincOutput = coincHead;

  /* Free all the memory allocated for the ellipsoid overlap */
  thisErrorList = errorListHead;
  XLALDestroyTriggerErrorList( errorListHead );
  XLALFreeFContactWorkSpace( workSpace );

  DETATCHSTATUSPTR (status);
  RETURN (status);
}
Esempio n. 15
0
void
LALFindChirpClusterEvents (
    LALStatus                  *status,
    SnglInspiralTable         **eventList,
    FindChirpFilterInput       *input,
    FindChirpFilterParams      *params,
    FindChirpBankVetoData      *bankVetoData,
    UINT4                       subBankIndex,
    int                         writeCData,
    InspiralTemplate           *bankCurrent
    )

{

  int                   xlalRetCode = 0;
  INT8                  bvTimeNS = 0;
  UINT4                 numPoints = 0;
  UINT4                 ignoreIndex = 0;
  UINT4                 eventStartIdx = 0;
  UINT4  		deltaEventIndex = 0;
  UINT4                 lowerIndex = 0;
  UINT4                 upperIndex = 0;
  UINT4                 buffer = 0;
  UINT4                 bvTimeIndex = 0;
  UINT4                 j, kmax;
  UINT4 		doChisqFlag = 1;
  REAL4                 norm = 0;
  REAL4                 deltaT;
  REAL8                 deltaF;
  REAL4                 modqsqThresh = 0;
  REAL4                 chisqThreshFac = 0;
  UINT4                 numChisqBins = 0;
  COMPLEX8             *q = NULL;
  SnglInspiralTable    *thisEvent = NULL;
  CHAR                  searchName[LIGOMETA_SEARCH_MAX];
  UINT4			bvDOF = 0;
  REAL4			bvChisq = 0;
  UINT4                 ccDOF = 0;
  REAL4                 ccChisq = 0;
  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );


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


  /* make sure the output handle exists, but points to a null pointer */
  ASSERT( eventList, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL );
  ASSERT( !*eventList, status, FINDCHIRPH_ENNUL, FINDCHIRPH_MSGENNUL );

  /* check the allowed approximants */
  xlalRetCode = XLALInspiralGetApproximantString( searchName, LIGOMETA_SEARCH_MAX,
                 params->approximant, params->order );

  if ( xlalRetCode == XLAL_FAILURE )
  {
    ABORTXLAL( status );
  }

  /* make sure the approximant in the tmplt and segment agree */
  if ( params->approximant != input->fcTmplt->tmplt.approximant ||
      params->approximant != input->segment->approximant )
  {
    ABORT( status, FINDCHIRPH_EAPRX, FINDCHIRPH_MSGEAPRX );
  }


  /*
   *
   * set up the variables needed to cluster
   *
   */

  q = params->qVec->data;
  numPoints = params->qVec->length;
  ignoreIndex = params->ignoreIndex;
  lowerIndex = ignoreIndex;
  upperIndex = numPoints - ignoreIndex;
  deltaT = params->deltaT;
  deltaF = 1.0 / ( (REAL4) params->deltaT * (REAL4) numPoints );
  kmax = input->fcTmplt->tmplt.fFinal / deltaF < numPoints/2 ?
    input->fcTmplt->tmplt.fFinal / deltaF : numPoints/2;

  /* normalisation */
  norm = input->fcTmplt->norm;

  /* normalised snr threhold */
  modqsqThresh = params->rhosqThresh / norm;

  /* the length of the chisq bin vec is the number of bin boundaries so the */
  /* number of chisq bins is (length - 1) or 0 if there are no boundaries   */
  numChisqBins = input->segment->chisqBinVec->length ?
    input->segment->chisqBinVec->length - 1 : 0;


  /* we threshold on the "modified" chisq threshold computed from       */
  /*   chisqThreshFac = chisqDelta * norm / p                           */
  /*                                                                    */
  /*   rho^2 = norm * modqsq                                            */
  /*                                                                    */
  /* So we actually threshold on                                        */
  /*                                                                    */
  /*    r^2 < chisqThresh * ( 1 + modqsq * chisqThreshFac )             */
  /*                                                                    */
  /* which is the same as thresholding on                               */
  /*    r^2 < chisqThresh * ( 1 + rho^2 * chisqDelta / p )              */
  /* and since                                                          */
  /*    chisq = p r^2                                                   */
  /* this is equivalent to thresholding on                              */
  /*    chisq < chisqThresh * ( p + rho^2 chisqDelta )                  */
  /*                                                                    */
  /* The raw chisq is stored in the database. this quantity is chisq    */
  /* distributed with 2p-2 degrees of freedom.                          */
  chisqThreshFac = norm * params->chisqDelta / (REAL4) numChisqBins;


  /*
   *
   * Apply one of the clustering algorithms
   *
   */


   /* set deltaEventIndex depending on clustering method used */
   if ( params->clusterMethod == FindChirpClustering_tmplt )
   {
     deltaEventIndex =
       (UINT4) rint( (input->fcTmplt->tmplt.tC / deltaT) + 1.0 );
   }
   else if ( params->clusterMethod == FindChirpClustering_window )
   {
     deltaEventIndex =
       (UINT4) rint( (params->clusterWindow / deltaT) + 1.0 );
   }
   else if ( params->clusterMethod == FindChirpClustering_tmpltwindow )
   {
     if ( input->fcTmplt->tmplt.tC > params->clusterWindow )
     {
       deltaEventIndex =
        (UINT4) rint( (input->fcTmplt->tmplt.tC / deltaT) + 1.0 );
     }
     else
     {
       deltaEventIndex =
        (UINT4) rint( (params->clusterWindow / deltaT) + 1.0 );
     }
   }

  /* In coherent stage cluster around trigbank-coherent triggers */
  if (writeCData) {
    /* set the event LIGO GPS time of the bankVetoTrigger */
    bvTimeNS = 1000000000L * (INT8) (bankCurrent->end_time.gpsSeconds);
    bvTimeNS += (INT8) (bankCurrent->end_time.gpsNanoSeconds);
    bvTimeNS -= XLALGPSToINT8NS( &(input->segment->data->epoch) );
    bvTimeIndex = (UINT4) rint( ((REAL8) bvTimeNS)/ (deltaT*1.0e9) );

    buffer = (UINT4) rint( 64.0 / deltaT );
    if ( (bvTimeIndex < buffer ) || (bvTimeIndex > (numPoints-buffer) ) ) {
      upperIndex = 0;
      lowerIndex = 0;
    }
    else {
      lowerIndex = ( ( bvTimeIndex > deltaEventIndex ) ? (bvTimeIndex) : 0 );
      upperIndex = bvTimeIndex + deltaEventIndex;
    }
  }

  /* look for an events in the filter output */
  for ( j = lowerIndex; j < upperIndex; ++j )
  {
    REAL4 modqsq = crealf(q[j]) * crealf(q[j]) + cimagf(q[j]) * cimagf(q[j]);

    /* if snrsq exceeds threshold at any point */
    if ( modqsq > modqsqThresh )
    {
      /* If it crosses the threshold see if we need to do a chisq test
         since this is no longer computed in FindChirpFilterSegment */
      if ( input->segment->chisqBinVec->length && doChisqFlag)
      {
        /* compute the chisq vector for this segment */
        memset( params->chisqVec->data, 0,
          params->chisqVec->length * sizeof(REAL4) );

        /* pointers to chisq input */
        params->chisqInput->qtildeVec = params->qtildeVec;
        params->chisqInput->qVec      = params->qVec;

        /* pointer to the chisq bin vector in the segment */
        params->chisqParams->chisqBinVec = input->segment->chisqBinVec;
        params->chisqParams->norm        = norm;

        /* compute the chisq bin boundaries for this template */
        if (params->chisqParams->chisqBinVec->data)
        {
          LALFree(params->chisqParams->chisqBinVec->data);
          params->chisqParams->chisqBinVec->data = NULL;
        }

        LALFindChirpComputeChisqBins( status->statusPtr,
            params->chisqParams->chisqBinVec, input->segment, kmax );
            CHECKSTATUSPTR( status );

        /* compute the chisq threshold: this is slow! */
        LALFindChirpChisqVeto( status->statusPtr, params->chisqVec,
          params->chisqInput, params->chisqParams );
        CHECKSTATUSPTR (status);
        doChisqFlag = 0;
      }

      /* if we have don't have a chisq or the chisq drops below the       */
      /* modified chisq threshold, start processing events                */
      if ( ! input->segment->chisqBinVec->length ||
          params->chisqVec->data[j] <
          (params->chisqThresh * ( 1.0 + modqsq * chisqThreshFac )) )
      {
        if (1) /* eventually check bank veto ! */
        {

          /*
           *
           * find the local maximum of the event
           *
           */


          if ( ! *eventList )
          {
            /* store the start of the crossing */
            eventStartIdx = j;

            /* if this is the first event, start the list */
            thisEvent = *eventList = (SnglInspiralTable *)
              LALCalloc( 1, sizeof(SnglInspiralTable) );
            if ( ! thisEvent )
            {
              ABORT( status, FINDCHIRPH_EALOC, FINDCHIRPH_MSGEALOC );
            }

            /* record the data that we need for the clustering algorithm */
            thisEvent->end_time.gpsSeconds = j;
            thisEvent->snr = modqsq;
          }
          else if (  ! params->clusterMethod == FindChirpClustering_none  &&
              j <= thisEvent->end_time.gpsSeconds + deltaEventIndex &&
             modqsq > thisEvent->snr )
          {
            /* if this is the same event, update the maximum */
            thisEvent->end_time.gpsSeconds = j;
            thisEvent->snr = modqsq;
          }
          else if ( j > thisEvent->end_time.gpsSeconds + deltaEventIndex ||
                params->clusterMethod == FindChirpClustering_none  )
          {
            /* clean up this event */
            SnglInspiralTable *lastEvent;
            if ( bankVetoData->length > 1 )
            {
              bvChisq = XLALComputeBankVeto( bankVetoData, subBankIndex,
					     thisEvent->end_time.gpsSeconds, deltaT, &bvDOF);
            }

	    if ( !writeCData ) {
	      ccChisq = XLALComputeFullChisq(bankVetoData,input,params,q,
                subBankIndex, thisEvent->end_time.gpsSeconds, &ccDOF, norm);
	    }

            LALFindChirpStoreEvent(status->statusPtr, input, params,
                thisEvent, q, kmax, norm, eventStartIdx, numChisqBins,
                searchName );
            CHECKSTATUSPTR( status );

            /* Set bank_chisq and cont_chisq */
            thisEvent->bank_chisq_dof = bvDOF;
            thisEvent->bank_chisq = bvChisq;
            thisEvent->cont_chisq_dof = ccDOF;
            thisEvent->cont_chisq = ccChisq;

            if ( writeCData ) {
              if ( !thisEvent->event_id )
                thisEvent->event_id = (EventIDColumn *) LALCalloc(1, sizeof(EventIDColumn) );
              thisEvent->event_id->id = bankVetoData->fcInputArray[subBankIndex]->fcTmplt->tmplt.event_id->id;
            }

            /* store the start of the crossing */
            eventStartIdx = j;

            /* allocate memory for the newEvent */
            lastEvent = thisEvent;

            lastEvent->next = thisEvent = (SnglInspiralTable *)
              LALCalloc( 1, sizeof(SnglInspiralTable) );
            if ( ! lastEvent->next )
            {
              ABORT( status, FINDCHIRPH_EALOC, FINDCHIRPH_MSGEALOC );
            }

            /* stick minimal data into the event */
            thisEvent->end_time.gpsSeconds = j;
            thisEvent->snr = modqsq;
          }
        } /* end if bank veto */
      } /* end if chisq */
    }
  }

  /*
   *
   * clean up last event
   *
   */

  if ( thisEvent )
  {
    if ( bankVetoData->length > 1 )
    {
      bvChisq = XLALComputeBankVeto( bankVetoData, subBankIndex,
				     thisEvent->end_time.gpsSeconds, deltaT, &bvDOF);
    }

    if ( !writeCData ) {
      ccChisq = XLALComputeFullChisq(bankVetoData, input,params,q,
            subBankIndex, thisEvent->end_time.gpsSeconds, &ccDOF, norm);
    }

    LALFindChirpStoreEvent(status->statusPtr, input, params,
         thisEvent, q, kmax, norm, eventStartIdx, numChisqBins,
         searchName );

    thisEvent->bank_chisq_dof = bvDOF;
    thisEvent->bank_chisq = bvChisq;
    thisEvent->cont_chisq_dof = ccDOF;
    thisEvent->cont_chisq = ccChisq;

    if ( writeCData ) {
      if ( !thisEvent->event_id )
	thisEvent->event_id = (EventIDColumn *) LALCalloc(1, sizeof(EventIDColumn) );
      
      thisEvent->event_id->id = bankVetoData->fcInputArray[subBankIndex]->fcTmplt->tmplt.event_id->id;
    }

    CHECKSTATUSPTR( status );
  }

  /* normal exit */
  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Esempio n. 16
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 );
}
Esempio n. 17
0
void
LALREAL4AverageSpectrum (
    LALStatus                   *status,
    REAL4FrequencySeries        *fSeries,
    REAL4TimeSeries             *tSeries,
    AverageSpectrumParams       *params
    )

{
  UINT4                 i, j, k;          /* seg, ts and freq counters       */
  UINT4                 numSeg;           /* number of segments in average   */
  UINT4                 fLength;          /* length of requested power spec  */
  UINT4                 tLength;          /* length of time series segments  */
  REAL4Vector          *tSegment = NULL;  /* dummy time series segment       */
  COMPLEX8Vector       *fSegment = NULL;  /* dummy freq series segment       */
  REAL4                *tSeriesPtr;       /* pointer to the segment data     */
  REAL4                 psdNorm = 0;      /* factor to multiply windows data */
  REAL4                 fftRe, fftIm;     /* real and imag parts of fft      */
  REAL4                *s;                /* work space for computing mean   */
  REAL4                *psdSeg = NULL;    /* storage for individual specta   */
  LALUnit               unit;
  /* RAT4                  negRootTwo = { -1, 1 }; */

  INITSTATUS(status);
  XLAL_PRINT_DEPRECATION_WARNING("XLALREAL4AverageSpectrumWelch");
  ATTATCHSTATUSPTR (status);

  /* check the input and output data pointers are non-null */
  ASSERT( fSeries, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( fSeries->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( fSeries->data->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries->data->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );

  /* check the contents of the parameter structure */
  ASSERT( params, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( params->window, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( params->window->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( params->window->data->length > 0, status,
      TIMEFREQFFTH_EZSEG, TIMEFREQFFTH_MSGEZSEG );
  ASSERT( params->plan, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  if ( !  ( params->method == useUnity || params->method == useMean ||
        params->method == useMedian ) )
  {
    ABORT( status, TIMEFREQFFTH_EUAVG, TIMEFREQFFTH_MSGEUAVG );
  }

  /* check that the window length and fft storage lengths agree */
  fLength = fSeries->data->length;
  tLength = params->window->data->length;
  if ( fLength != tLength / 2 + 1 )
  {
    ABORT( status, TIMEFREQFFTH_EMISM, TIMEFREQFFTH_MSGEMISM );
  }

  /* compute the number of segs, check that the length and overlap are valid */
  numSeg = (tSeries->data->length - params->overlap) / (tLength - params->overlap);
  if ( (tSeries->data->length - params->overlap) % (tLength - params->overlap) )
  {
    ABORT( status, TIMEFREQFFTH_EMISM, TIMEFREQFFTH_MSGEMISM );
  }

  /* clear the output spectrum and the workspace frequency series */
  memset( fSeries->data->data, 0, fLength * sizeof(REAL4) );

  /* compute the parameters of the output frequency series data */
  fSeries->epoch = tSeries->epoch;
  fSeries->f0 = tSeries->f0;
  fSeries->deltaF = 1.0 / ( (REAL8) tLength * tSeries->deltaT );
  if ( XLALUnitMultiply( &unit, &(tSeries->sampleUnits), &(tSeries->sampleUnits) ) == NULL ) {
    ABORTXLAL(status);
  }
  if ( XLALUnitMultiply( &(fSeries->sampleUnits), &unit, &lalSecondUnit ) == NULL ) {
    ABORTXLAL(status);
  }

  /* if this is a unit spectrum, just set the conents to unity and return */
  if ( params->method == useUnity )
  {
    for ( k = 0; k < fLength; ++k )
    {
      fSeries->data->data[k] = 1.0;
    }
    DETATCHSTATUSPTR( status );
    RETURN( status );
  }

  /* create temporary storage for the dummy time domain segment */
  LALCreateVector( status->statusPtr, &tSegment, tLength );
  CHECKSTATUSPTR( status );

  /* create temporary storage for the individual ffts */
  LALCCreateVector( status->statusPtr, &fSegment, fLength );
  CHECKSTATUSPTR( status );

  if ( params->method == useMedian )
  {
    /* create enough storage for the indivdiual power spectra */
    psdSeg = XLALCalloc( numSeg, fLength * sizeof(REAL4) );
  }

  /* compute each of the power spectra used in the average */
  for ( i = 0, tSeriesPtr = tSeries->data->data; i < (UINT4) numSeg; ++i )
  {
    /* copy the time series data to the dummy segment */
    memcpy( tSegment->data, tSeriesPtr, tLength * sizeof(REAL4) );

    /* window the time series segment */
    for ( j = 0; j < tLength; ++j )
    {
      tSegment->data[j] *= params->window->data->data[j];
    }

    /* compute the fft of the data segment */
    LALForwardRealFFT( status->statusPtr, fSegment, tSegment, params->plan );
    CHECKSTATUSPTR (status);

    /* advance the segment data pointer to the start of the next segment */
    tSeriesPtr += tLength - params->overlap;

    /* compute the psd components */
    if ( params->method == useMean )
    {
      /* we can get away with less storage */
      for ( k = 0; k < fLength; ++k )
      {
        fftRe = crealf(fSegment->data[k]);
        fftIm = cimagf(fSegment->data[k]);
        fSeries->data->data[k] += fftRe * fftRe + fftIm * fftIm;
      }

      /* halve the DC and Nyquist components to be consistent with T010095 */
      fSeries->data->data[0] /= 2;
      fSeries->data->data[fLength - 1] /= 2;
    }
    else if ( params->method == useMedian )
    {
      /* we must store all the spectra */
      for ( k = 0; k < fLength; ++k )
      {
        fftRe = crealf(fSegment->data[k]);
        fftIm = cimagf(fSegment->data[k]);
        psdSeg[i * fLength + k] = fftRe * fftRe + fftIm * fftIm;
      }

      /* halve the DC and Nyquist components to be consistent with T010095 */
      psdSeg[i * fLength] /= 2;
      psdSeg[i * fLength + fLength - 1] /= 2;
    }
  }

  /* destroy the dummy time series segment and the fft scratch space */
  LALDestroyVector( status->statusPtr, &tSegment );
  CHECKSTATUSPTR( status );
  LALCDestroyVector( status->statusPtr, &fSegment );
  CHECKSTATUSPTR( status );

  /* compute the desired average of the spectra */
  if ( params->method == useMean )
  {
    /* normalization constant for the arithmentic mean */
    psdNorm = ( 2.0 * tSeries->deltaT ) /
      ( (REAL4) numSeg * params->window->sumofsquares );

    /* normalize the psd to it matches the conventions document */
    for ( k = 0; k < fLength; ++k )
    {
      fSeries->data->data[k] *= psdNorm;
    }
  }
  else if ( params->method == useMedian )
  {
    REAL8 bias;

    /* determine the running median bias */
    /* note: this is not the correct bias if the segments are overlapped */
    if ( params->overlap )
    {
      LALWarning( status, "Overlapping segments with median method causes a biased spectrum." );
    }
    TRY( LALRngMedBias( status->statusPtr, &bias, numSeg ), status );

    /* normalization constant for the median */
    psdNorm = ( 2.0 * tSeries->deltaT ) /
      ( bias * params->window->sumofsquares );

    /* allocate memory array for insert sort */
    s = XLALMalloc( numSeg * sizeof(REAL4) );
    if ( ! s )
    {
      ABORT( status, TIMEFREQFFTH_EMALLOC, TIMEFREQFFTH_MSGEMALLOC );
    }

    /* compute the median spectra and normalize to the conventions doc */
    for ( k = 0; k < fLength; ++k )
    {
      fSeries->data->data[k] = psdNorm *
        MedianSpec( psdSeg, s, k, fLength, numSeg );
    }

    /* free memory used for sort array */
    XLALFree( s );

    /* destroy the storage for the individual spectra */
    XLALFree( psdSeg );
  }

  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Esempio n. 18
0
void
LALCOMPLEX8AverageSpectrum (
    LALStatus                   *status,
    COMPLEX8FrequencySeries     *fSeries,
    REAL4TimeSeries             *tSeries0,
    REAL4TimeSeries             *tSeries1,
    AverageSpectrumParams       *params
    )

{
  UINT4                 i, j, k, l;          /* seg, ts and freq counters       */
  UINT4                 numSeg;           /* number of segments in average   */
  UINT4                 fLength;          /* length of requested power spec  */
  UINT4                 tLength;          /* length of time series segments  */
  REAL4Vector          *tSegment[2] = {NULL,NULL};
  COMPLEX8Vector       *fSegment[2] = {NULL,NULL};
  REAL4                *tSeriesPtr0,*tSeriesPtr1 ;
  REAL4                 psdNorm = 0;      /* factor to multiply windows data */
  REAL4                 fftRe0, fftIm0, fftRe1, fftIm1;
  LALUnit               unit;
  /* RAT4                  negRootTwo = { -1, 1 }; */

  INITSTATUS(status);
  XLAL_PRINT_DEPRECATION_WARNING("XLALREAL8AverageSpectrumWelch");
  ATTATCHSTATUSPTR (status);

  /* check the input and output data pointers are non-null */
  ASSERT( fSeries, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( fSeries->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( fSeries->data->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries0, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries0->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries0->data->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
   ASSERT( tSeries1, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries1->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( tSeries1->data->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );

  /* check the contents of the parameter structure */
  ASSERT( params, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( params->window, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( params->window->data, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  ASSERT( params->window->data->length > 0, status,
      TIMEFREQFFTH_EZSEG, TIMEFREQFFTH_MSGEZSEG );
  ASSERT( params->plan, status,
      TIMEFREQFFTH_ENULL, TIMEFREQFFTH_MSGENULL );
  if ( !  ( params->method == useUnity || params->method == useMean ||
        params->method == useMedian ) )
  {
    ABORT( status, TIMEFREQFFTH_EUAVG, TIMEFREQFFTH_MSGEUAVG );
  }

  /* check that the window length and fft storage lengths agree */
  fLength = fSeries->data->length;
  tLength = params->window->data->length;
  if ( fLength != tLength / 2 + 1 )
  {
    ABORT( status, TIMEFREQFFTH_EMISM, TIMEFREQFFTH_MSGEMISM );
  }

  /* compute the number of segs, check that the length and overlap are valid */
  numSeg = (tSeries0->data->length - params->overlap) / (tLength - params->overlap);
  if ( (tSeries0->data->length - params->overlap) % (tLength - params->overlap) )
  {
    ABORT( status, TIMEFREQFFTH_EMISM, TIMEFREQFFTH_MSGEMISM );
  }

  /* clear the output spectrum and the workspace frequency series */
  memset( fSeries->data->data, 0, fLength * sizeof(COMPLEX8) );

  /* compute the parameters of the output frequency series data */
  fSeries->epoch = tSeries0->epoch;
  fSeries->f0 = tSeries0->f0;
  fSeries->deltaF = 1.0 / ( (REAL8) tLength * tSeries0->deltaT );
  if ( XLALUnitMultiply( &unit, &(tSeries0->sampleUnits), &(tSeries0->sampleUnits) ) == NULL ) {
    ABORTXLAL(status);
  }
  if ( XLALUnitMultiply( &(fSeries->sampleUnits), &unit, &lalSecondUnit ) == NULL ) {
    ABORTXLAL(status);
  }

  /* create temporary storage for the dummy time domain segment */
  for (l = 0; l < 2; l ++){
  LALCreateVector( status->statusPtr, &tSegment[l], tLength );
  CHECKSTATUSPTR( status );

  /* create temporary storage for the individual ffts */
  LALCCreateVector( status->statusPtr, &fSegment[l], fLength );
  CHECKSTATUSPTR( status );}


  /* compute each of the power spectra used in the average */
  for ( i = 0, tSeriesPtr0 = tSeries0->data->data, tSeriesPtr1 = tSeries1->data->data; i < (UINT4) numSeg; ++i )
  {
    /* copy the time series data to the dummy segment */
    memcpy( tSegment[0]->data, tSeriesPtr0, tLength * sizeof(REAL4) );
    memcpy( tSegment[1]->data, tSeriesPtr1, tLength * sizeof(REAL4) );
    /* window the time series segment */
    for ( j = 0; j < tLength; ++j )
    {
      tSegment[0]->data[j] *= params->window->data->data[j];
      tSegment[1]->data[j] *= params->window->data->data[j];
    }

    /* compute the fft of the data segment */
    LALForwardRealFFT( status->statusPtr, fSegment[0], tSegment[0], params->plan );
    CHECKSTATUSPTR (status);
    LALForwardRealFFT( status->statusPtr, fSegment[1], tSegment[1], params->plan );
    CHECKSTATUSPTR (status);

    /* advance the segment data pointer to the start of the next segment */
    tSeriesPtr0 += tLength - params->overlap;
    tSeriesPtr1 += tLength - params->overlap;

    /* compute the psd components */
    /*use mean method here*/
      /* we can get away with less storage */
      for ( k = 0; k < fLength; ++k )
      {
        fftRe0 = crealf(fSegment[0]->data[k]);
        fftIm0 = cimagf(fSegment[0]->data[k]);
        fftRe1 = crealf(fSegment[1]->data[k]);
        fftIm1 = cimagf(fSegment[1]->data[k]);
        fSeries->data->data[k] += fftRe0 * fftRe1 + fftIm0 * fftIm1;
        fSeries->data->data[k] += I * (- fftIm0 * fftRe1 + fftRe0 * fftIm1);

      }

      /* halve the DC and Nyquist components to be consistent with T010095 */
      fSeries->data->data[0] /= 2;
      fSeries->data->data[fLength - 1] /= 2;

      }

  /* destroy the dummy time series segment and the fft scratch space */
  for (l = 0; l < 2; l ++){
  LALDestroyVector( status->statusPtr, &tSegment[l] );
  CHECKSTATUSPTR( status );
  LALCDestroyVector( status->statusPtr, &fSegment[l] );
  CHECKSTATUSPTR( status );}

  /* compute the desired average of the spectra */

    /* normalization constant for the arithmentic mean */
    psdNorm = ( 2.0 * tSeries1->deltaT ) /
      ( (REAL4) numSeg * params->window->sumofsquares );

    /* normalize the psd to it matches the conventions document */
    for ( k = 0; k < fLength; ++k )
      fSeries->data->data[k] *= psdNorm;


  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Esempio n. 19
0
void
FUNC ( LALStatus *stat, FILE *stream, GTYPE *grid )
{
  UINT4 i, j, length; /* indecies, and line/string length */
  UINT4 pLength, np;  /* length and number of data ``paragraphs'' */
  TYPE *data;         /* pointer to grid->data->data */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Check for valid input arguments. */
  ASSERT( stream, stat, STREAMOUTPUTH_ENUL, STREAMOUTPUTH_MSGENUL );
  ASSERT( grid, stat, STREAMOUTPUTH_ENUL, STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->dimUnits, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->offset, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->offset->data, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->interval, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->interval->data, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->data, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->data->data, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->data->dimLength, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );
  ASSERT( grid->data->dimLength->data, stat, STREAMOUTPUTH_ENUL,
	  STREAMOUTPUTH_MSGENUL );

  /*******************************************************************
   * PRINT METADATA HEADER                                           *
   *******************************************************************/

  /* Print the datatype. */
  if ( fprintf( stream, "# datatype = " STRING(GTYPE) "\n" ) < 0 ) {
    ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
  }

  /* Print the name. */
  if ( fprintf( stream, "# name = " ) < 0 ||
       LALWriteLiteral( stream, grid->name ) ||
       fprintf( stream, "\n" ) < 0 ) {
    ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
  }

  /* Print the sample units and dimension units. */
  {
    CHAR unitString[LALUnitTextSize];

    /* First, use XLALUnitAsString() to generate unit string. */
    if ( XLALUnitAsString( unitString, LALUnitTextSize, &(grid->sampleUnits) ) == NULL ) {
      ABORTXLAL(stat);
    }

    /* Write the resulting unit string enclosed in quotes. */
    if ( fprintf( stream, "# sampleUnits = \"%s\"\n", unitString ) < 0 ) {
      ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
    }
  }
  {
    CHAR unitString[LALUnitTextSize];

    if ( fprintf( stream, "# dimUnits =" ) < 0 ) {
      ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
    }
    for ( i = 0; i < grid->offset->length; i++ ) {

      /* First, use XLALUnitAsString() to generate unit string. */
      if ( XLALUnitAsString( unitString, LALUnitTextSize, grid->dimUnits + i ) == NULL ) {
        ABORTXLAL(stat);
      }

      /* Write the resulting unit string enclosed in quotes. */
      if ( fprintf( stream, " \"%s\"\n", unitString ) < 0 ) {
        ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
      }

    }
  }

  /* Print the offset, interval, and dimLength. */
  if ( fprintf( stream, "# offset =" ) < 0 ) {
    ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
  }
  for ( i = 0; i < grid->offset->length; i++ ) {
    if ( fprintf( stream, " %.16e", grid->offset->data[i] ) < 0 ) {
      ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
    }
  }
  if ( fprintf( stream, "\n# interval =" ) < 0 ) {
    ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
  }
  for ( i = 0; i < grid->interval->length; i++ ) {
    if ( fprintf( stream, " %.16e", grid->interval->data[i] ) < 0 ) {
      ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
    }
  }
  if ( fprintf( stream, "\n# dimLength =" ) < 0 ) {
    ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
  }
  for ( i = 0; i < grid->data->dimLength->length; i++ ) {
    if ( fprintf( stream, " %" LAL_UINT4_FORMAT ,
		  grid->data->dimLength->data[i] ) < 0 ) {
      ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
    }
  }
  if ( fprintf( stream, "\n" ) < 0 ) {
    ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
  }

  /*******************************************************************
   * PRINT DATA                                                      *
   *******************************************************************/

  /* Compute number of data per line, per ``paragraph'' (grid point),
     and number of grid points.  length equals one *less* than the
     number of data per line. */
  pLength = np = 1;
  for ( i = 0; i < grid->offset->length; i++ )
    np *= grid->data->dimLength->data[i];
  for ( ; i < grid->data->dimLength->length - 1; i++ )
    pLength *= grid->data->dimLength->data[i];
  if ( i >= grid->offset->length )
    length = grid->data->dimLength->data[i] - 1;
  else
    length = 0;

  /* If each grid point is a single line, don't bother with
     ``paragraph'' breaks. */
  if ( pLength == 1 ) {
    pLength = np;
    np = 1;
  }
  data = grid->data->data;

  /* Print data. */
  while ( np-- ) {
    fprintf( stream, "\n" );
    for ( i = 0; i < pLength; i++ ) {
#if COMPLEX
      for ( j = 0; j < length; j++ ) {
	if ( fprintf( stream, FMT " " FMT " ", creal(*data), cimag(*data) ) < 0 ) {
	  ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
	}
	data++;
      }
      if ( fprintf( stream, FMT " " FMT "\n", creal(*data), cimag(*data) ) < 0 ) {
	ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
      }
      data++;
#else
      for ( j = 0; j < length; j++ ) {
	if ( fprintf( stream, FMT " ", *(data++) ) < 0 ) {
	  ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
	}
      }
      if ( fprintf( stream, FMT "\n", *(data++) ) < 0 ) {
	ABORT( stat, STREAMOUTPUTH_EPRN, STREAMOUTPUTH_MSGEPRN );
      }
#endif
    }
  }
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
void
LALOverlapReductionFunction(
    LALStatus                                *status,
    REAL4FrequencySeries                     *output,
    const LALDetectorPair                    *detectors,
    const OverlapReductionFunctionParameters *parameters)

{
  UINT4 length;
  REAL8 deltaF;
  REAL8 f0;
  UINT4 i, j;
  REAL4 trace1, trace2;
  REAL4 d1DotS[3], d2DotS[3];
  REAL4 s[3];
  REAL4 distance;
  REAL4 c1, c2, c3;
  REAL4 alpha, alpha0, deltaAlpha;
  REAL4 rho[3];
  REAL4 d1[3][3], d2[3][3];

  /* initialize status structure */
  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* check that pointer to parameters is not null */
  ASSERT(parameters!=NULL, status, \
			STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* check that specified length of output vector is > 0 */
  length = parameters->length;
  ASSERT(length > 0, status, \
			STOCHASTICCROSSCORRELATIONH_EZEROLEN, \
      STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN);

  /* check that frequency spacing is > 0 */
  deltaF = parameters->deltaF;
  ASSERT(deltaF > 0, status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF, \
      STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF);

  /* check that minimum frequency is >= 0 */
  f0 = parameters->f0;
  if (f0 < 0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_ENEGFMIN, \
				STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN);
  }

  /* check that pointer to output frequency series is not null */
  ASSERT(output != NULL, status, \
			STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
			STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* check that pointer to data member of output frequency series is
	 * not null */
  ASSERT(output->data != NULL, status, \
			STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
			STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* check that length of the data member of output frequency series
	 * agrees with length specified in input parameters */
  if(output->data->length != length)
	{
		ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
				STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }

  /* check that pointer to data-data member of output vector is not null */
  ASSERT(output->data->data != NULL, status, \
			STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
			STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* check that pointer to input structure is not null */
  ASSERT(detectors != NULL, status, \
			STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
			STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* everything okay here -------------------------------------------- */

  /* the overlap reduction function has units of strain^2 */
  if (XLALUnitRaiseINT2(&(output->sampleUnits), &lalStrainUnit, 2) == NULL) {
    ABORTXLAL(status);
  }

  /* set parameters for output */
  strncpy(output->name, "Overlap reduction function", LALNameLength);
  output->epoch.gpsSeconds = 0.0;
  output->epoch.gpsNanoSeconds = 0.0;
  output->deltaF = parameters->deltaF;
  output->f0 = parameters->f0;

  /* calculate separation vector between sites */
  for (i = 0; i < 3; i++)
	{
		s[i] = (REAL4)(detectors->detectorOne.location[i] - \
				detectors->detectorTwo.location[i]);
		d1[i][i] = detectors->detectorOne.response[i][i];
    d2[i][i] = detectors->detectorTwo.response[i][i];

		for (j = i; j<3; j++) {
      d1[i][j] = d1[j][i] = detectors->detectorOne.response[i][j];
      d2[i][j] = d2[j][i] = detectors->detectorTwo.response[i][j];

			/* check for non symmetric response tensor */
      ASSERT(d1[j][i] == detectors->detectorOne.response[j][i], status, \
					STOCHASTICCROSSCORRELATIONH_ENONSYMDIJ, \
					STOCHASTICCROSSCORRELATIONH_MSGENONSYMDIJ);
      ASSERT(d2[j][i] == detectors->detectorTwo.response[j][i], status, \
					STOCHASTICCROSSCORRELATIONH_ENONSYMDIJ, \
					STOCHASTICCROSSCORRELATIONH_MSGENONSYMDIJ);
		}
	}

	/* calculate distance between sites, in meters */
  distance = sqrt(cartesianInnerProduct(s,s));

  /* calculate unit separation vector */
  if (distance != 0)
	{
		for (i = 0; i < 3; i++)
		{
      s[i] /= distance;
    }
  }

  trace1 = d1[0][0] + d1[1][1] + d1[2][2];
  if (trace1)
	{
    trace1 /= 3.0;
    for (i = 0; i < 3; i++)
		{
      d1[i][i] -= trace1;
    }
  }
  trace2 = d2[0][0] + d2[1][1] + d2[2][2];
  if (trace2)
	{
    trace2 /= 3.0;
    for (i = 0; i < 3; i++)
		{
      d2[i][i] -= trace2;
    }
  }

  /* calculate coefficients c1, c2, c3 for overlap reduction funtion */

  /* c1 = d1 : d2 */
  c1 = 0;
  for (i = 0; i < 3; i++)
	{
    for (j = 0; j < 3; j++)
		{
      c1 += d1[i][j] * d2[i][j];
    }
  }

  for (i = 0; i < 3; i++)
	{
    d1DotS[i] = cartesianInnerProduct(d1[i], s);
    d2DotS[i] = cartesianInnerProduct(d2[i], s);
  }

  /* c2 = s . d1 . d2 . s */
  c2 = cartesianInnerProduct(d1DotS, d2DotS);

  /* c3 = (s . d1 . s)(s . d2 . s) */
  c3 = cartesianInnerProduct(s, d1DotS) * cartesianInnerProduct(s, d2DotS);

  distance *= (2 * LAL_PI / LAL_C_SI);
  deltaAlpha = deltaF * distance;
  alpha0 = f0 * distance;

  if (f0 == 0)
  {
    for (i = 0; i < length; ++i)
    {
      alpha = deltaAlpha * (REAL4)i;
      evaluateBessels(rho, alpha);
      output->data->data[i] = c1 * rho[0] + c2 * rho[1] + c3 * rho[2];
    }
  }
  else
  {
    for (i = 0; i < length; ++i)
    {
      alpha = alpha0 + deltaAlpha * (REAL4)i;
      evaluateBessels(rho, alpha);
      output->data->data[i] = c1 * rho[0] + c2 * rho[1] + c3 * rho[2];
    }
  }

  /* normal exit */
  DETATCHSTATUSPTR(status);
  RETURN(status);
}
void
LALStochasticOptimalFilter(
    LALStatus                          *status,
    COMPLEX8FrequencySeries            *optimalFilter,
    const StochasticOptimalFilterInput *input,
    const REAL4WithUnits               *lambda)

{
  REAL4 mygamma;
  REAL4 omega;
  COMPLEX8 p1HWInv;
  COMPLEX8 p2HWInv;

  COMPLEX8 *cPtrOptimalFilter;

  REAL8 f;
  REAL8 f0;
  REAL8 f3;
  REAL8 deltaF;

  /* normalization factor */
  UINT4 i;
  REAL8 realFactor;

  UINT4 length;

  RAT4 power;
  LALUnit tmpUnit1, tmpUnit2, checkUnit;

  /* initialize status pointer */
  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* ERROR CHECKING ----------------------------------------------------- */

  /***** check for null pointers *****/
  /* input structure */
  ASSERT(input != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* output structure */
  ASSERT(optimalFilter != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* overlap member of input */
  ASSERT(input->overlapReductionFunction != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* omega member of input */
  ASSERT(input->omegaGW != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* half-calibrated inverse noise 1 of input */
  ASSERT(input->halfCalibratedInverseNoisePSD1 != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* half-calibrated inverse noise 2 of input */
  ASSERT(input->halfCalibratedInverseNoisePSD2 != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of overlap */
  ASSERT(input->overlapReductionFunction->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of omega */
  ASSERT(input->omegaGW->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of half-calibrated inverse noise 1 */
  ASSERT(input->halfCalibratedInverseNoisePSD1->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of half-calibrated inverse noise 2 */
  ASSERT(input->halfCalibratedInverseNoisePSD2->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of output */
  ASSERT(optimalFilter->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of overlap */
  ASSERT(input->overlapReductionFunction->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of omega */
  ASSERT(input->omegaGW->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of half calibrated inverse noise 1 */
  ASSERT(input->halfCalibratedInverseNoisePSD1->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of half calibrated inverse noise 2 */
  ASSERT(input->halfCalibratedInverseNoisePSD2->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of output structure */
  ASSERT(optimalFilter->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /*** done with null pointers ***/

  /* extract parameters from overlap */
  length = input->overlapReductionFunction->data->length;
  f0 = input->overlapReductionFunction->f0;
  deltaF = input->overlapReductionFunction->deltaF;

  /**** check for legality ****/
  /* length must be positive */
  ASSERT(length != 0, status, \
      STOCHASTICCROSSCORRELATIONH_EZEROLEN, \
      STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN);

  /* start frequency must not be negative */
  if (f0 < 0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_ENEGFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN );
  }

  /* frequency spacing must be positive */
  ASSERT(deltaF > 0, status, \
      STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF, \
      STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF);

  /** check for mismatches **/
  /* length */
  if (input->omegaGW->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }
  if (input->halfCalibratedInverseNoisePSD1->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }
  if (input->halfCalibratedInverseNoisePSD2->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }
  if (optimalFilter->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }

  /* initial frequency */
  if (input->omegaGW->f0 != f0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMFMIN);
  }
  if (input->halfCalibratedInverseNoisePSD1->f0 != f0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMFMIN);
  }
  if (input->halfCalibratedInverseNoisePSD2->f0 != f0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMFMIN);
  }

  /* frequency spacing */
  if (input->omegaGW->deltaF != deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMDELTAF, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMDELTAF);
  }
  if (input->halfCalibratedInverseNoisePSD1->deltaF != deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMDELTAF, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMDELTAF);
  }
  if (input->halfCalibratedInverseNoisePSD2->deltaF != deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMDELTAF, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMDELTAF);
  }
  /* EVERYHTING OKAY HERE! ---------------------------------------------- */

  /* assign parameters to optimalFilter */
  optimalFilter->f0 = f0;
  optimalFilter->deltaF = deltaF;
  optimalFilter->epoch.gpsSeconds = 0;
  optimalFilter->epoch.gpsNanoSeconds = 0;
  strncpy(optimalFilter->name, "Optimal filter for stochastic search", \
           LALNameLength);

  /* All the powers we use are integers, so we can do this once here */
  power.denominatorMinusOne = 0;

  /* Set tmpUnit1 to dims of Omega/H0^2 ******/

  /* First, set it to dims of H0 */

  tmpUnit1 = lalHertzUnit;

  /* Account for scaled units of Hubble constant */
  tmpUnit1.powerOfTen -= 18;

  /* Now set tmpUnit2 to dims of H0^-2 */
  power.numerator = -2;
  if (XLALUnitRaiseRAT4(&tmpUnit2, &tmpUnit1, &power) == NULL) {
    ABORTXLAL(status);
  }

  if (XLALUnitMultiply(&tmpUnit1, &(input->omegaGW->sampleUnits), &tmpUnit2) == NULL) {
    ABORTXLAL(status);
  }

  /* Now tmpUnit1 has units of Omega/H0^2 */

  /* Now we need to set the Optimal Filter Units equal to the units of */
  /* lambda*mygamma*Omega*f^-3*P1HW^-1*P2HW^-1) */

  if (XLALUnitMultiply(&tmpUnit1, &(input->halfCalibratedInverseNoisePSD1->sampleUnits), &(input->halfCalibratedInverseNoisePSD2->sampleUnits)) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit1 now holds the units of P1HW^-1*P2HW^-1 */

  power.numerator = -3;
  if (XLALUnitRaiseRAT4(&tmpUnit2, &lalHertzUnit, &power) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit2 now holds the units of f^-3 */

  if (XLALUnitMultiply(&checkUnit, &tmpUnit1, &tmpUnit2) == NULL) {
    ABORTXLAL(status);
  }

  /* checkUnit now holds the units of f^-3*P1HW^-1*P2HW^-1) */
  if (XLALUnitMultiply(&tmpUnit1, &checkUnit, &(input->omegaGW->sampleUnits)) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit1 now holds units of Omega*f^-3*P1HW^-1*P2HW^-1) */

  if (XLALUnitMultiply(&tmpUnit2, &tmpUnit1, &(input->overlapReductionFunction->sampleUnits)) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit2 now holds units of mygamma*Omega*f^-3*P1HW^-1*P2HW^-1) */

  if (XLALUnitMultiply(&(optimalFilter->sampleUnits), &(lambda->units), &tmpUnit2) == NULL) {
    ABORTXLAL(status);
  }

  /* Done with unit manipulation */

  optimalFilter->data->data[0] = 0.0;

  /* calculate optimal filter values */
  for (i = (f0 == 0 ? 1 : 0) ; i < length; ++i)
  {
    f = f0 + deltaF * (REAL8)i;

    f3 = f * f * f;

    omega = input->omegaGW->data->data[i];
    mygamma = input->overlapReductionFunction->data->data[i];
    p1HWInv = input->halfCalibratedInverseNoisePSD1->data->data[i];
    p2HWInv = input->halfCalibratedInverseNoisePSD2->data->data[i];

    cPtrOptimalFilter = &(optimalFilter->data->data[i]);

    realFactor = (mygamma * omega * lambda->value) / f3;

    *(cPtrOptimalFilter) = crectf( realFactor * ((crealf(p1HWInv) * crealf(p2HWInv)) + (cimagf(p1HWInv) * cimagf(p2HWInv))), realFactor * ((crealf(p1HWInv) * cimagf(p2HWInv)) - (cimagf(p1HWInv) * crealf(p2HWInv))) );
  }

  DETATCHSTATUSPTR(status);
  RETURN(status);
} /* LALStochasticOptimalFilter() */
void
LALInspiralEccentricityEngine(
		LALStatus        *status,
		REAL4Vector      *signalvec1,
		REAL4Vector      *signalvec2,
		REAL4Vector      *a,
		REAL4Vector      UNUSED *ff,
		REAL8Vector      UNUSED *phi,
		INT4             *countback,
		InspiralTemplate *params)
{
   INT4 number_of_diff_equations = 3;
   INT4 count = 0;
   ecc_CBC_ODE_Input in3;
   REAL8 phase;
   REAL8 orbital_element_p,orbital_element_e_squared;
   REAL8 orbital_element_e;
   REAL8 twoPhim2Beta = 0;
   REAL8 threePhim2Beta = 0;
   REAL8 phim2Beta = 0;
   REAL8 twoBeta;
   REAL8 rbyM=1e6, rbyMFlso=6.;
   REAL8 sin2Beta,cos2Beta,iota,onepCosSqI, SinSqI, cosI, e0, f_min, beta, p0;



   REAL8 amp, m, dt, t,  h1, h2, f,  fHigh, piM, fu;
   REAL8Vector dummy, values, dvalues, valuesNew, yt, dym, dyt;
   INT4 done=0;
   rk4In in4;
   rk4GSLIntegrator *integrator;
   void *funcParams;
   expnCoeffs ak;
   expnFunc func;

#if 0
   REAL8 mTot = 0;
   REAL8 unitHz = 0;
   REAL8 f2a = 0;
   REAL8 mu = 0;
   REAL8 etab = 0;
   REAL8 fFac = 0; /* SI normalization for f and t */
   REAL8 f2aFac = 0;/* factor multiplying f in amplitude function */
   REAL8 apFac = 0, acFac = 0;/* extra factor in plus and cross amplitudes */
#endif

   INITSTATUS(status);
   ATTATCHSTATUSPTR(status);

   ASSERT (params,  status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
   ASSERT (params->nStartPad >= 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
   ASSERT (params->nEndPad >= 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
   ASSERT (params->fLower > 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
   ASSERT (params->tSampling > 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);

   LALInspiralSetup (status->statusPtr, &ak, params);
   CHECKSTATUSPTR(status);
   LALInspiralChooseModel(status->statusPtr, &func, &ak, params);
   CHECKSTATUSPTR(status);

   m = ak.totalmass = params->mass1+params->mass2;

   values.length = dvalues.length = valuesNew.length =
   yt.length = dym.length = dyt.length = number_of_diff_equations;
   dummy.length = number_of_diff_equations * 6;
   if (!(dummy.data = (REAL8 * ) LALMalloc(sizeof(REAL8) * number_of_diff_equations * 6))) {
      ABORT(status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM);
   }

   values.data = &dummy.data[0];
   dvalues.data = &dummy.data[number_of_diff_equations];
   valuesNew.data = &dummy.data[2*number_of_diff_equations];
   yt.data = &dummy.data[3*number_of_diff_equations];
   dym.data = &dummy.data[4*number_of_diff_equations];
   dyt.data = &dummy.data[5*number_of_diff_equations];

/*   m = ak.totalmass;*/
   dt = 1./params->tSampling;

   if (a)
   {
     /*to be implemented. */


/*      mTot   = params->mass1 + params->mass2;
      etab   = params->mass1 * params->mass2;
      etab  /= mTot;
      etab  /= mTot;
      unitHz = mTot *LAL_MTSUN_SI*(REAL8)LAL_PI;
      cosI   = cos( params->inclination );
      mu     = etab * mTot;
      fFac   = 1.0 / ( 4.0*LAL_TWOPI*LAL_MTSUN_SI*mTot );
      f2aFac = LAL_PI*LAL_MTSUN_SI*mTot*fFac;
      apFac  = acFac = -2.0 * mu * LAL_MRSUN_SI/params->distance;
      apFac *= 1.0 + cosI*cosI;
      acFac *= 2.0*cosI;
      params->nStartPad = 0;
      */
   }

   ASSERT(ak.totalmass > 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);

   t = 0.0;



   in3.totalMass = (params->mass1 + params->mass2) * LAL_MTSUN_SI ;
   in3.eta = (params->mass1 * params->mass2) /(params->mass1 + params->mass2) / (params->mass1 + params->mass2);
   funcParams = (void *) &in3;


   piM = LAL_PI * m * LAL_MTSUN_SI;
/*   f = (v*v*v)/piM;

   fu = params->fCutoff;
   if (fu)
      fHigh = (fu < ak.flso) ? fu : ak.flso;
   else
      fHigh = ak.flso;
   f = (v*v*v)/(LAL_PI*m);

   ASSERT(fHigh < 0.5/dt, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
   ASSERT(fHigh > params->fLower, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
*/


   /* e0 is set at f_min */
   e0 = params->eccentricity;

   /* the second harmonic will start at fLower*2/3 */
   f_min = params->fLower;
   iota = params->inclination; /*overwritten later */

   beta = 0.;
   twoBeta = 2.* beta;
   cos2Beta = cos(twoBeta);
   sin2Beta = sin(twoBeta);
   iota = LAL_PI/4.;
   onepCosSqI = 1. + cos(iota) * cos(iota);
   SinSqI = sin(iota) * sin(iota);
   cosI = cos(iota);

   p0 = (1. - e0*e0)/pow(2. * LAL_PI * m * LAL_MTSUN_SI* f_min/3. , 2./3.);

   *(values.data) = orbital_element_p = p0;
   *(values.data+1) = phase = params->startPhase;
   *(values.data+2) = orbital_element_e = e0;




   in4.function = LALInspiralEccentricityDerivatives;
   in4.x = t;
   in4.y = &values;
   in4.h = dt;
   in4.n = number_of_diff_equations;
   in4.yt = &yt;
   in4.dym = &dym;
   in4.dyt = &dyt;

   xlalErrno = 0;
   /* Initialize GSL integrator */
   if (!(integrator = XLALRungeKutta4Init(number_of_diff_equations, &in4)))
   {
     INT4 errNum = XLALClearErrno();
     LALFree(dummy.data);

     if (errNum == XLAL_ENOMEM)
       ABORT(status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM);
     else
       ABORTXLAL( status );
   }

   count = 0;
   if (signalvec2) {
   params->nStartPad = 0;} /* for template generation, that value must be zero*/

   else if (signalvec1) {
     count = params->nStartPad;
   }

   t = 0.0;


   fu = params->fCutoff;
   if (fu)
      fHigh = (fu < ak.flso) ? fu : ak.flso;
   else
      fHigh = ak.flso;

   f = 1./(pow(orbital_element_p, 3./2.))/piM;


   /*fprintf(stderr, "fFinal = %f %f %f %f\n", fu,fHigh,f,ak.flso);*/
 done = 0;
   do {
      /* Free up memory and abort if writing beyond the end of vector*/
      /*if ((signalvec1 && (UINT4)count >= signalvec1->length) || (ff && (UINT4)count >= ff->length))*/
      if ((signalvec1 && (UINT4)count >= signalvec1->length))
      {
          XLALRungeKutta4Free( integrator );
          LALFree(dummy.data);
          ABORT(status, LALINSPIRALH_EVECTOR, LALINSPIRALH_MSGEVECTOR);
      }

      /* Non-injection case */
      if (signalvec1)
      {
        twoPhim2Beta = 2.* phase - twoBeta;
        phim2Beta = phase - twoBeta;
        threePhim2Beta = 3.* phase - twoBeta;
        orbital_element_e_squared = orbital_element_e * orbital_element_e;
        amp = params->signalAmplitude / orbital_element_p;

/*        fprintf(stderr, "%e %e %e %e %e\n", twoBeta, twoPhim2Beta, phim2Beta, threePhim2Beta, orbital_element_e_squared);*/


        h1 = amp * ( ( 2. * cos(twoPhim2Beta) + 2.5 * orbital_element_e * cos(phim2Beta)
          + 0.5 * orbital_element_e * cos(threePhim2Beta) + orbital_element_e_squared * cos2Beta) * onepCosSqI +
          + ( orbital_element_e * cos(orbital_element_p) + orbital_element_e_squared) * SinSqI);
        if ((f >= params->fLower) && (done == 0))
        {
        /*fprintf(stderr, "freq=%e p=%e, e=%e, phase = %e\n", f,orbital_element_p, orbital_element_e, phase);fflush(stderr);
*/
        params->alpha1 =  orbital_element_e;
        done = 1;
         }
         /*if (f>=params->fLower)*/
        {
          *(signalvec1->data + count) = (REAL4) h1;
         }

	 if (signalvec2)
	 {
            h2 = amp * ( ( 4. * sin(twoPhim2Beta) + 5 * orbital_element_e * sin(phim2Beta)
          + orbital_element_e * sin(threePhim2Beta) - 2. * orbital_element_e_squared * sin2Beta) * cosI);
/*           if (f>=params->fLower)*/
           {
              *(signalvec2->data + count) = (REAL4) h2;
            }
	 }
      }

      /* Injection case */
      else if (a)
      {
        /*to be done*/
        /*
        omega = v*v*v;

          ff->data[count]       = (REAL4)(omega/unitHz);
          f2a                   = pow (f2aFac * omega, 2./3.);
          a->data[2*count]      = (REAL4)(4.*apFac * f2a);
          a->data[2*count+1]    = (REAL4)(4.*acFac * f2a);
          phi->data[count]      = (REAL8)(p);
          */
      }

      LALInspiralEccentricityDerivatives(&values, &dvalues,funcParams);
      CHECKSTATUSPTR(status);

      in4.dydx = &dvalues;
      in4.x=t;

      LALRungeKutta4(status->statusPtr, &valuesNew, integrator, funcParams);
      CHECKSTATUSPTR(status);

      *(values.data) = orbital_element_p = *(valuesNew.data);
      *(values.data+1) = phase = *(valuesNew.data+1);
      *(values.data+2) = orbital_element_e = *(valuesNew.data+2);

      t = (++count-params->nStartPad) * dt;
      /* v^3 is equal to p^(3/2)*/
      f = 1./(pow(orbital_element_p, 3./2.))/piM;
/*      fprintf(stderr, "p=%e, e=%e, phase = %e\n", orbital_element_p, orbital_element_e, phase);
      fflush(stderr);*/
      rbyM = orbital_element_p/(1.+orbital_element_e * cos(phase));
      /*fprintf(stderr, "rbyM=%e rbyMFlso=%e t=%e, ak.tn=%e f=%e e=%e\n",rbyM, rbyMFlso, t, ak.tn,f,orbital_element_e);
      fflush(stderr);*/

   } while ( (t < ak.tn) && (rbyM>rbyMFlso) && (f<fHigh));


   /*fprintf(stderr, "t=%e ak.tn=%e rbyM=%e rbyMFlso=%e f=%f fHigh=%f", t, ak.tn, rbyM, rbyMFlso, f, fHigh);*/

   /*also need to add for the fupper nyquist frequency**/
   params->vFinal = orbital_element_p;
   params->fFinal = f;
   params->tC = t;
   *countback = count;

   XLALRungeKutta4Free( integrator );
   LALFree(dummy.data);

   DETATCHSTATUSPTR(status);
   RETURN (status);

}
void
LALSTPNAdaptiveWaveformEngine( LALStatus *status,
                							 REAL4Vector *signalvec1,REAL4Vector *signalvec2,
                							 REAL4Vector *a,REAL4Vector *ff,REAL8Vector *phi,REAL4Vector *shift,
                							 UINT4 *countback,
                							 InspiralTemplate *params,InspiralInit *paramsInit
                						 )
{
	/* PN parameters */
  LALSTPNparams mparams;

	/* needed for integration */
  LALAdaptiveRungeKutta4Integrator *integrator;
	unsigned int len;
	int intreturn;
	REAL8 yinit[11];
  REAL8Array *yout;

  /* other computed values */
  REAL8 unitHz, dt, m, lengths, norm;

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

 	/* Make sure parameter and waveform structures exist. */
  ASSERT(params,     status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
  ASSERT(paramsInit, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);

  /* units */
  unitHz = params->totalMass * LAL_MTSUN_SI * (REAL8)LAL_PI;
  dt = 1.0/params->tSampling;	  /* tSampling is in Hz, so dt is in seconds */
  m = params->totalMass * LAL_MTSUN_SI;

  /* length estimation (Newtonian); since integration is adaptive, we could use a better estimate */
  lengths = (5.0/256.0) * pow(LAL_PI,-8.0/3.0) * pow(params->chirpMass * LAL_MTSUN_SI * params->fLower,-5.0/3.0) / params->fLower;

  /* setup coefficients for PN equations */
	XLALSTPNAdaptiveSetParams(&mparams,params,paramsInit);

  /* initialize the coordinates */
	yinit[0] = 0.0;                     							/* vphi */
	yinit[1] = params->fLower * unitHz; 							/* omega (really pi M f) */

	yinit[2] = sin(params->inclination);							/* LNh(x,y,z) */
	yinit[3] = 0.0;
	yinit[4] = cos(params->inclination);

	norm = pow(params->mass1/params->totalMass,2.0);
	yinit[5] = norm * params->spin1[0];								/* S1(x,y,z) */
	yinit[6] = norm * params->spin1[1];
	yinit[7] = norm * params->spin1[2];

	norm = pow(params->mass2/params->totalMass,2.0);	/* S2(x,y,z) */
	yinit[8] = norm * params->spin2[0];
	yinit[9] = norm * params->spin2[1];
	yinit[10]= norm * params->spin2[2];

  xlalErrno = 0;

	/* allocate the integrator */
	integrator = XLALAdaptiveRungeKutta4Init(11,XLALSTPNAdaptiveDerivatives,XLALSTPNAdaptiveTest,1.0e-6,1.0e-6);
  if (!integrator) {
		fprintf(stderr,"LALSTPNWaveform2: Cannot allocate integrator.\n");
    if (XLALClearErrno() == XLAL_ENOMEM)
      ABORT(status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM);
    else
      ABORTXLAL(status);
  }

	/* stop the integration only when the test is true */
	integrator->stopontestonly = 1;

	/* run the integration; note: time is measured in units of total mass */
	len = XLALAdaptiveRungeKutta4(integrator,(void *)&mparams,yinit,0.0,lengths/m,dt/m,&yout);

	intreturn = integrator->returncode;
	XLALAdaptiveRungeKutta4Free(integrator);

	if (!len) {
    if (XLALClearErrno() == XLAL_ENOMEM) {
      ABORT(status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM);
    } else {
			fprintf(stderr,"LALSTPNWaveform2: integration failed with errorcode %d.\n",intreturn);
			ABORTXLAL(status);
		}
	}

	/* report on abnormal termination (TO DO: throw some kind of LAL error?) */
	if (intreturn != 0 && intreturn != LALSTPN_TEST_ENERGY && intreturn != LALSTPN_TEST_OMEGADOT) {
		fprintf(stderr,"LALSTPNWaveform2 WARNING: integration terminated with code %d.\n",intreturn);
    fprintf(stderr,"                          Waveform parameters were m1 = %e, m2 = %e, s1 = (%e,%e,%e), s2 = (%e,%e,%e), inc = %e.",
     							 params->mass1, params->mass2,
     							 params->spin1[0], params->spin1[1], params->spin1[2],
     							 params->spin2[0], params->spin2[1], params->spin2[2],
     							 params->inclination);
	}

	/* check that we're not above Nyquist */
	if (yinit[1]/unitHz > 0.5 * params->tSampling) {
		fprintf(stderr,"LALSTPNWaveform2 WARNING: final frequency above Nyquist.\n");
	}

	/* if we have enough space, compute the waveform components; otherwise abort */
  if ((signalvec1 && len >= signalvec1->length) || (ff && len >= ff->length)) {
		if (signalvec1) {
			fprintf(stderr,"LALSTPNWaveform2: no space to write in signalvec1: %d vs. %d\n",len,signalvec1->length);
		} else if (ff) {
			fprintf(stderr,"LALSTPNWaveform2: no space to write in ff: %d vs. %d\n",len,ff->length);
		} else {
			fprintf(stderr,"LALSTPNWaveform2: no space to write anywhere!\n");
		}
		ABORT(status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
  } else {
		/* set up some aliases for the returned arrays; note vector 0 is time */

  //  REAL8 *thet = yout->data;
		REAL8 *vphi = &yout->data[1*len]; REAL8 *omega = &yout->data[2*len];
		REAL8 *LNhx = &yout->data[3*len]; REAL8 *LNhy  = &yout->data[4*len];	REAL8 *LNhz  = &yout->data[5*len];

		/* these are not needed for the waveforms:
		REAL8 *S1x  = &yout->data[6*len]; REAL8 *S1y   = &yout->data[7*len];  REAL8 *S1z   = &yout->data[8*len];
		REAL8 *S2x  = &yout->data[9*len]; REAL8 *S2y   = &yout->data[10*len]; REAL8 *S2z   = &yout->data[11*len];	*/

		*countback = len;

		if (signalvec1) { /* return polarizations */
			REAL8 v=0, amp=0, alpha=0, alpha0 = atan2(LNhy[0],LNhx[0]);

			for(unsigned int i=0;i<len;i++) {
				v = pow(omega[i],(1./3.));
				amp = params->signalAmplitude * (v*v);
				if(LNhx[i]*LNhx[i] + LNhy[i]*LNhy[i] > 0.0) {
          alpha = atan2(LNhy[i],LNhx[i]); alpha0 = alpha;
        } else {
          alpha = alpha0;
        }

				signalvec1->data[i]   = (REAL4)(-0.5 * amp * cos(2*vphi[i]) * cos(2*alpha) * (1.0 + LNhz[i]*LNhz[i]) \
				                                     + amp * sin(2*vphi[i]) * sin(2*alpha) * LNhz[i]);

				if (signalvec2) {
					signalvec2->data[i] = (REAL4)(-0.5 * amp * cos(2*vphi[i]) * sin(2*alpha) * (1.0 + LNhz[i]*LNhz[i]) \
																				     - amp * sin(2*vphi[i]) * cos(2*alpha) * LNhz[i]);
				}
			}

			params->fFinal = pow(v,3.0)/(LAL_PI*m);
			if (!signalvec2) params->tC = yout->data[len-1];	/* TO DO: why only in this case? */
		} else if (a) {	/* return coherentGW components */
			REAL8 apcommon, f2a, alpha, alpha0 = atan2(LNhy[0],LNhx[0]);

			/* (minus) amplitude for distance in m; should be (1e6 * LAL_PC_SI * params->distance) for distance in Mpc */
			apcommon = -4.0 * params->mu * LAL_MRSUN_SI/(params->distance);

			for(unsigned int i=0;i<len;i++) {
				f2a = pow(omega[i],(2./3.));
				if(LNhx[i]*LNhx[i] + LNhy[i]*LNhy[i] > 0.0) {
          alpha = atan2(LNhy[i],LNhx[i]); alpha0 = alpha;
        } else {
          alpha = alpha0;
        }

			  ff   ->data[i]     = (REAL4)(omega[i]/unitHz);
			  a    ->data[2*i]   = (REAL4)(apcommon * f2a * 0.5 * (1 + LNhz[i]*LNhz[i]));
			  a    ->data[2*i+1] = (REAL4)(apcommon * f2a * LNhz[i]);
			  phi  ->data[i]     = (REAL8)(2.0 * vphi[i]);
			  shift->data[i]     = (REAL4)(2.0 * alpha);
			}

			params->fFinal = ff->data[len-1];
		}
	}

	if (yout) XLALDestroyREAL8Array(yout);

  DETATCHSTATUSPTR(status);
  RETURN(status);
}
void
LALTaylorT4WaveformForInjection(
                             LALStatus        *status,
                             CoherentGW       *waveform,
                             InspiralTemplate *params,
                             PPNParamStruc  *ppnParams
                             )
{
  UINT4        count, i;
  REAL8       phiC;

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

  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->h ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );
  ASSERT( !( waveform->f ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );
  ASSERT( !( waveform->phi ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL );

  params->ampOrder = (LALPNOrder) 0;
  XLALPrintInfo( "WARNING: Amp Order has been reset to %d", params->ampOrder);

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

  if (paramsInit.nbins == 0)
  {
      XLALPrintError( "Error: Estimated length of injection is zero.\n" );
      ABORT( status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE );
  }

  /* Now we can allocate memory and vector for coherentGW structure*/
  ff  = XLALCreateREAL4Vector( paramsInit.nbins );
  a   = XLALCreateREAL4Vector( 2*paramsInit.nbins );
  phi = XLALCreateREAL8Vector( paramsInit.nbins );
  if ( !ff || !a || !phi )
  {
    if ( ff )
      XLALDestroyREAL4Vector( ff );
    if ( a )
      XLALDestroyREAL4Vector( a );
    if ( phi )
      XLALDestroyREAL8Vector( phi );
    ABORTXLAL( status );
  }

  /* Call the engine function */
  LALTaylorT4WaveformEngine(status->statusPtr, NULL, NULL, a, ff,
                             phi, &count, params, &paramsInit);
  BEGINFAIL( status )
  {
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
  }
  ENDFAIL( status );

  /*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 )
  {
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORT( status, LALINSPIRALH_EMEM,
           LALINSPIRALH_MSGEMEM );
  }
  if ( ( waveform->f = (REAL4TimeSeries *)
         LALCalloc(1, sizeof(REAL4TimeSeries) ) ) == NULL )
  {
    LALFree( waveform->a ); waveform->a = NULL;
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    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;
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORT( status, LALINSPIRALH_EMEM,
               LALINSPIRALH_MSGEMEM );
  }

  waveform->a->data = XLALCreateREAL4VectorSequence( (UINT4)count, 2 );
  waveform->f->data = XLALCreateREAL4Vector( count );
  waveform->phi->data = XLALCreateREAL8Vector( count );

  if ( !waveform->a->data || !waveform->f->data || !waveform->phi->data )
  {
    if ( waveform->a->data )
      XLALDestroyREAL4VectorSequence( waveform->a->data );
    if ( waveform->f->data )
      XLALDestroyREAL4Vector( waveform->f->data );
    if ( waveform->phi->data )
      XLALDestroyREAL8Vector( waveform->phi->data );
    LALFree( waveform->a ); waveform->a = NULL;
    LALFree( waveform->f ); waveform->f = NULL;
    XLALDestroyREAL4Vector( ff );
    XLALDestroyREAL4Vector( a );
    XLALDestroyREAL8Vector( phi );
    ABORTXLAL( 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,   "T4 inspiral amplitude" );
  snprintf( waveform->f->name, LALNameLength,   "T4 inspiral frequency" );
  snprintf( waveform->phi->name, LALNameLength, "T4 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 --- */
  XLALDestroyREAL4Vector( ff );
  XLALDestroyREAL4Vector( a );
  XLALDestroyREAL8Vector( phi );

  DETATCHSTATUSPTR(status);
  RETURN (status);
}
Esempio n. 25
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 RunGeneratePulsarSignalTest(LALStatus *status, int argc, char **argv) */ /* 02/02/05 gam */
void RunGeneratePulsarSignalTest(LALStatus *status)
{
  INT4    i, j, k;         /* all purpose indices */
  INT4    iSky = 0;        /* for loop over sky positions */
  INT4    jDeriv = 0;      /* for loop over spindowns */
  INT4    testNumber = 0;  /* which test is being run */

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

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

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

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

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

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

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

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

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       XLALDestroySFTVector( outputSFTs);

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

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

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

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

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

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

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

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

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

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

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

  XLALDestroyEphemerisData(edat);

  CHECKSTATUSPTR (status);
  DETATCHSTATUSPTR (status);
}
void
LALStochasticOptimalFilterNormalization(
    LALStatus                                            *status,
    StochasticOptimalFilterNormalizationOutput           *output,
    const StochasticOptimalFilterNormalizationInput      *input,
    const StochasticOptimalFilterNormalizationParameters *parameters)

{
  REAL4 omegaTimesGamma;
  REAL4 p1Inv;
  REAL4 p2Inv;

  REAL8 f;
  REAL8 f0;
  REAL8 f3;
  REAL8 deltaF;

  /* normalization factor */
  UINT4 i;
  UINT4 xRef;
  REAL4 omega1;
  REAL4 omega2;
  REAL8 freq1;
  REAL8 freq2;
  REAL4 exponent;
  REAL4 omegaRef;
  REAL8 lambdaInv;
  REAL8 f6;

  /* windowing */
  REAL4 w2, meanW2, meanW4;
  REAL4 *sPtrW1, *sPtrW2, *sStopPtr;
  UINT4 winLength = 0;

  UINT4 length;

  LALUnit tmpUnit1, tmpUnit2, checkUnit;
  REAL4WithUnits *lamPtr;

  /* initialize status pointer */
  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* ERROR CHECKING ----------------------------------------------------- */

  /* check for null pointers *****/
  /* input structure */
  ASSERT(input != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* output structure */
  ASSERT(output != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* parameter structure */
  ASSERT(parameters != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* overlap member of input */
  ASSERT(input->overlapReductionFunction != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* omega member of input */
  ASSERT(input->omegaGW != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* inverse noise 1 of input */
  ASSERT(input->inverseNoisePSD1 != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* inverse noise 2 of input */
  ASSERT(input->inverseNoisePSD2 != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of overlap */
  ASSERT(input->overlapReductionFunction->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of omega */
  ASSERT(input->omegaGW->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of inverse noise 1 */
  ASSERT(input->inverseNoisePSD1->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data member of inverse noise 2 */
  ASSERT(input->inverseNoisePSD2->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of overlap */
  ASSERT(input->overlapReductionFunction->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of omega */
  ASSERT(input->omegaGW->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of inverse noise 1 */
  ASSERT(input->inverseNoisePSD1->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* data-data member of inverse noise 2 */
  ASSERT(input->inverseNoisePSD2->data->data != NULL, status, \
      STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
      STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

  /* Checks that only apply if windowing is specified */

  if (parameters->window1 || parameters->window2)
  {
    /* window 1 parameter */
    ASSERT(parameters->window1 != NULL, status, \
        STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
        STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

    /* window 2 parameter */
    ASSERT(parameters->window2 != NULL, status, \
        STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
        STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

    /* data member of window 1 */
    ASSERT(parameters->window1->data != NULL, status, \
        STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
        STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

    /* data member of window 2 */
    ASSERT(parameters->window2->data != NULL, status, \
        STOCHASTICCROSSCORRELATIONH_ENULLPTR, \
        STOCHASTICCROSSCORRELATIONH_MSGENULLPTR);

    winLength = parameters->window1->length;

    ASSERT(winLength != 0, status, \
        STOCHASTICCROSSCORRELATIONH_EZEROLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN);

    /* Check that windows are the same length */
    if (parameters->window2->length != winLength)
    {
      ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
          STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
    }
  }

  /* done with null pointers ***/

  /* extract parameters from overlap */
  length = input->overlapReductionFunction->data->length;
  f0 = input->overlapReductionFunction->f0;
  deltaF = input->overlapReductionFunction->deltaF;

  /* check for legality ****/
  /* length must be positive */
  ASSERT(length != 0, status, \
      STOCHASTICCROSSCORRELATIONH_EZEROLEN, \
      STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN);

  /* start frequency must not be negative */
  if (f0 < 0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_ENEGFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN);
  }

  /* frequency spacing must be positive */
  ASSERT(deltaF > 0, status, \
      STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF, \
      STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF);

  /* check for mismatches **/
  /* length */
  if (input->omegaGW->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }
  if (input->inverseNoisePSD1->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }
  if (input->inverseNoisePSD2->data->length != length)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMLEN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMLEN);
  }

  /* initial frequency */
  if (input->omegaGW->f0 != f0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMFMIN);
  }
  if (input->inverseNoisePSD1->f0 != f0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMFMIN);
  }
  if (input->inverseNoisePSD2->f0 != f0)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMFMIN, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMFMIN);
  }

  /* frequency spacing */
  if (input->omegaGW->deltaF != deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMDELTAF, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMDELTAF);
  }
  if (input->inverseNoisePSD1->deltaF != deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMDELTAF, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMDELTAF);
  }
  if (input->inverseNoisePSD2->deltaF != deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EMMDELTAF, \
        STOCHASTICCROSSCORRELATIONH_MSGEMMDELTAF);
  }
  /* check for reference frequency lower and upper limits **/
  if (parameters->fRef < f0 + deltaF)
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EOORFREF, \
        STOCHASTICCROSSCORRELATIONH_MSGEOORFREF);
  }
  if (parameters->fRef > f0 + ((REAL8)(length-1)*deltaF))
  {
    ABORT(status, STOCHASTICCROSSCORRELATIONH_EOORFREF, \
        STOCHASTICCROSSCORRELATIONH_MSGEOORFREF);
  }

  /* EVERYHTING OKAY HERE! ---------------------------------------------- */

  /* check that units of gamma, Omega, P1 and P2 are consistent
   * we must have (gamma*Omega)^2 with the same units as f^2*P1*P2
   * up to a power of ten. We check this by constructing
   * checkUnit = f^2*P1*P2*(gamma*Omega)^-2 */
  if (XLALUnitMultiply(&tmpUnit1, &(input->inverseNoisePSD1->sampleUnits), &(input->inverseNoisePSD2->sampleUnits)) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit1 holds units of 1/(P1*P2) */

  if (XLALUnitRaiseINT2(&tmpUnit2, &tmpUnit1, -1) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit2 holds units of P1*P2 */

  if (XLALUnitMultiply(&tmpUnit1, &(input->overlapReductionFunction->sampleUnits), &(input->omegaGW->sampleUnits)) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit1 holds units of Omega*Gamma */

  if (XLALUnitMultiply(&checkUnit, &tmpUnit1, &lalSecondUnit) == NULL) {
    ABORTXLAL(status);
  }

  /* checkUnit holds units of f^-1*Omega*Gamma */

  if (XLALUnitRaiseINT2(&tmpUnit1, &checkUnit, -2) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit1 holds units of f^2*(Omega*Gamma)^-2 */

  if (XLALUnitMultiply(&checkUnit, &tmpUnit1, &tmpUnit2) == NULL) {
    ABORTXLAL(status);
  }

  /* checkUnit holds units of f^2*P1*P2(Omega*Gamma)^-2 */

  /* Check that checkUnit is dimensionless up to a power of ten ***/

  for (i=0; i<LALNumUnits; ++i)
  {
    if (checkUnit.unitNumerator[i] || checkUnit.unitDenominatorMinusOne[i])
    {
      ABORT(status, STOCHASTICCROSSCORRELATIONH_EWRONGUNITS, \
          STOCHASTICCROSSCORRELATIONH_MSGEWRONGUNITS);
    }
  }

  /* Set tmpUnit1 to dims of Omega/H0^2 ******/

  /* First, set it to dims of H0 */

  tmpUnit1 = lalHertzUnit;

  /* Account for scaled units of Hubble constant */
  tmpUnit1.powerOfTen -= 18;

  /* Now set tmpUnit2 to dims of H0^-2 */
  if (XLALUnitRaiseINT2(&tmpUnit2, &tmpUnit1, -2) == NULL) {
    ABORTXLAL(status);
  }
  if (XLALUnitMultiply(&tmpUnit1, &(input->omegaGW->sampleUnits), &tmpUnit2) == NULL) {
    ABORTXLAL(status);
  }

  /* Now tmpUnit1 has units of Omega/H0^2 */

  /* assign correct units to normalization constant ********/
  /* These are Omega/H0^2*f^5*P1*P2*(gamma*Omega)^-2
   * which is the same as tmpUnit1*f^3*checkUnit */
  if (XLALUnitMultiply(&tmpUnit2, &tmpUnit1, &checkUnit) == NULL) {
    ABORTXLAL(status);
  }

  /* tmpUnit2 has units of Omega/H0^2*f^2*P1*P2*(gamma*Omega)^-2 */

  /* Now that we've used checkUnit, we don't need it any more and */
  /* can use it for temp storage (of f^3) */
  if (XLALUnitRaiseINT2(&checkUnit, &lalHertzUnit, 3) == NULL) {
    ABORTXLAL(status);
  }

  /* In case the normalization output was NULL, we need to allocate it
   * since we still use it as an intermediate; we do so here to
   * minimize the BEGINFAIL/ENDFAIL pairs needed */

  if (output->normalization != NULL)
  {
    lamPtr = output->normalization;
  }
  else
  {
    lamPtr = (REAL4WithUnits*)LALMalloc(sizeof(REAL4WithUnits));
  }

  if (XLALUnitMultiply(&(lamPtr->units), &tmpUnit2, &checkUnit) == NULL) {
    if (output->normalization == NULL) LALFree(lamPtr);
    ABORTXLAL(status);
  }

  if (output->variance != NULL)
  {
    /* assign correct units to variance per time of CC stat ********/
    if (XLALUnitMultiply(&(output->variance->units), &(lamPtr->units), &tmpUnit1) == NULL) {
      if (output->normalization == NULL) LALFree(lamPtr);
      ABORTXLAL(status);
    }
  }

  /* Calculate properties of windows */
  if (parameters->window1 == NULL)
  {
    meanW2 = meanW4 = 1.0;
  }
  else
  {
    meanW2 = meanW4 = 0.0;
    for (sPtrW1 = parameters->window1->data, \
        sPtrW2 = parameters->window2->data, sStopPtr = sPtrW1 + winLength; \
        sPtrW1 < sStopPtr; ++sPtrW1, ++sPtrW2)
    {
      w2 = *sPtrW1 * *sPtrW2;
      meanW2 += w2;
      meanW4 += w2 * w2;
    }
    meanW2 /= winLength;
    meanW4 /= winLength;

    if (meanW2 <= 0)
    {
      ABORT(status, STOCHASTICCROSSCORRELATIONH_ENONPOSWIN, \
            STOCHASTICCROSSCORRELATIONH_MSGENONPOSWIN);
    }
  }

  /* ************* calculate lambda ***********************/
  /* find omegaRef */
  xRef = (UINT4)((parameters->fRef - f0)/deltaF);
  if (((parameters->fRef - f0)/deltaF) == (REAL8)(xRef))
  {
    omegaRef = input->omegaGW->data->data[xRef];
  }
  else
  {
    omega1 = input->omegaGW->data->data[xRef];
    omega2 = input->omegaGW->data->data[xRef+1];
    freq1 = f0 + xRef * deltaF;
    freq2 = f0 + (xRef + 1) * deltaF;
    if (omega1 <= 0)
    {
      ABORT(status, STOCHASTICCROSSCORRELATIONH_ENONPOSOMEGA, \
          STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA);
    }
    else
    {
      exponent = ((log((parameters->fRef)/freq1))/(log(freq2/freq1)));
    }
    omegaRef = omega1*(pow((omega2/omega1),exponent));
  }

  /* calculate inverse lambda value */
  lambdaInv = 0.0;

  for (i = (f0 == 0 ? 1 : 0) ; i < length; ++i)
  {
    f = f0 + deltaF * (REAL8) i;

    f3 = f * f * f;
    f6 = f3 * f3;

    omegaTimesGamma = input->omegaGW->data->data[i] * \
                      input->overlapReductionFunction->data->data[i];
    p1Inv = input->inverseNoisePSD1->data->data[i];
    p2Inv = input->inverseNoisePSD2->data->data[i];
    lambdaInv += (omegaTimesGamma * omegaTimesGamma * p1Inv * p2Inv) / f6;
  }

  lambdaInv /= (omegaRef / deltaF) * ((20.0L * LAL_PI * LAL_PI) / \
      (3.0L * (LAL_H0FAC_SI*1e+18) * (LAL_H0FAC_SI*1e+18) * meanW2));

  if (!parameters->heterodyned)
    lambdaInv *= 2.0;

  lamPtr->value = 1 / lambdaInv;

  if (output->variance != NULL)
  {
    output->variance->value = (meanW4/meanW2) * ((5.0L * LAL_PI * LAL_PI) / \
        (3.0L * (LAL_H0FAC_SI*1e+18) * (LAL_H0FAC_SI*1e+18))) * \
                              omegaRef / lambdaInv;
  }
  if (output->normalization == NULL)
    LALFree(lamPtr);

  DETATCHSTATUSPTR(status);
  RETURN(status);
}
Esempio n. 28
0
void
LALFindChirpTDTemplate (
    LALStatus                  *status,
    FindChirpTemplate          *fcTmplt,
    InspiralTemplate           *tmplt,
    FindChirpTmpltParams       *params
    )

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

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


  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );


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


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

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

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

  /* check that the timestep is positive */
  ASSERT( params->deltaT > 0, status,
      FINDCHIRPTDH_EDELT, FINDCHIRPTDH_MSGEDELT );

  /* check that the input exists */
  ASSERT( tmplt, status, FINDCHIRPTDH_ENULL, FINDCHIRPTDH_MSGENULL );

  /* check that the parameter structure is set to a time domain approximant */
  switch ( params->approximant )
  {
    case TaylorT1:
    case TaylorT2:
    case TaylorT3:
    case TaylorT4:
    case GeneratePPN:
    case PadeT1:
    case EOB:
    case EOBNR:
    case FindChirpPTF:
    case EOBNRv2:
    case IMRPhenomB:
    case IMRPhenomC:
      break;

    default:
      ABORT( status, FINDCHIRPTDH_EMAPX, FINDCHIRPTDH_MSGEMAPX );
      break;
  }

  /* store deltaT and zero out the time domain waveform vector */
  deltaT = params->deltaT;
  sampleRate = 1.0 / deltaT;
  xfac = params->xfacVec->data;
  numPoints =  params->xfacVec->length;
  memset( xfac, 0, numPoints * sizeof(REAL4) );

  ASSERT( numPoints == (2 * (fcTmplt->data->length - 1)), status,
      FINDCHIRPTDH_EMISM, FINDCHIRPTDH_MSGEMISM );


  /* choose the time domain template */
  if ( params->approximant == GeneratePPN )
  {


    /*
     *
     * generate the waveform using LALGeneratePPNInspiral() from inject
     *
     */



    /* input parameters */
    memset( &ppnParams, 0, sizeof(PPNParamStruc) );
    ppnParams.deltaT = deltaT;
    ppnParams.mTot = tmplt->mass1 + tmplt->mass2;
    ppnParams.eta = tmplt->mass1 * tmplt->mass2 /
      ( ppnParams.mTot * ppnParams.mTot );
    ppnParams.d = 1.0;
    ppnParams.fStartIn = params->fLow;
    ppnParams.fStopIn = -1.0 /
      (6.0 * sqrt(6.0) * LAL_PI * ppnParams.mTot * LAL_MTSUN_SI);

    /* generate waveform amplitude and phase */
    memset( &waveform, 0, sizeof(CoherentGW) );
    LALGeneratePPNInspiral( status->statusPtr, &waveform, &ppnParams );
    CHECKSTATUSPTR( status );

    /* print termination information and check sampling */
    LALInfo( status, ppnParams.termDescription );
    if ( ppnParams.dfdt > 2.0 )
    {
      ABORT( status, FINDCHIRPTDH_ESMPL, FINDCHIRPTDH_MSGESMPL );
    }
    if ( waveform.a->data->length > numPoints )
    {
      ABORT( status, FINDCHIRPTDH_ELONG, FINDCHIRPTDH_MSGELONG );
    }

    /* compute h(t) */
    for ( j = 0; j < waveform.a->data->length; ++j )
    {
      xfac[j] =
        waveform.a->data->data[2*j] * cos( waveform.phi->data->data[j] );
    }

    /* free the memory allocated by LALGeneratePPNInspiral() */
    LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) );
    CHECKSTATUSPTR( status );

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

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

    LALFree( waveform.a );
    LALFree( waveform.f );
    LALFree( waveform.phi );

    /* waveform parameters needed for findchirp filter */
    tmplt->approximant = params->approximant;
    tmplt->tC = ppnParams.tc;
    tmplt->fFinal = ppnParams.fStop;

    fcTmplt->tmpltNorm = params->dynRange / ( cannonDist * 1.0e6 * LAL_PC_SI );
    fcTmplt->tmpltNorm *= fcTmplt->tmpltNorm;
  }
  else
  {


    /*
     *
     * generate the waveform by calling LALInspiralWave() from inspiral
     *
     */


    /* set up additional template parameters */
    deltaF = 1.0 / ((REAL8) numPoints * deltaT);
    tmplt->ieta            = 1;
    tmplt->approximant     = params->approximant;
    tmplt->order           = params->order;
    tmplt->massChoice      = m1Andm2;
    tmplt->tSampling       = sampleRate;
    tmplt->fLower          = params->fLow;
    tmplt->fCutoff         = sampleRate / 2.0 - deltaF;
    /* get the template norm right */
    if ( params->approximant==EOBNR )
    {
     /* lalinspiral EOBNR code produces correct norm when 
        fed unit signalAmplitude and non-physical distance */
      tmplt->signalAmplitude = 1.0;
      tmplt->distance      = -1.0;
    }
    else if ( params->approximant==EOBNRv2 )
    {
     /* this formula sets the ampl0 variable to 1.0 
      * within the lalsimulation EOBNRv2 waveform engine 
      * which again produces a correct template norm     */
      tmplt->distance      = tmplt->totalMass*LAL_MRSUN_SI;
    }
    else if ( (params->approximant==IMRPhenomB) || (params->approximant==IMRPhenomC) )
    {
      /* 1Mpc standard distance - not clear if this produces correct norm */
      tmplt->distance      = 1.0;
      tmplt->spin1[2]      = 2 * tmplt->chi/(1. + sqrt(1.-4.*tmplt->eta));
    }

    /* compute the tau parameters from the input template */
    LALInspiralParameterCalc( status->statusPtr, tmplt );
    CHECKSTATUSPTR( status );

    /* determine the length of the chirp in sample points */
    LALInspiralWaveLength( status->statusPtr, &waveLength, *tmplt );
    CHECKSTATUSPTR( status );

    if ( waveLength > numPoints )
    {
      ABORT( status, FINDCHIRPTDH_ELONG, FINDCHIRPTDH_MSGELONG );
    }

    /* generate the chirp in the time domain */
    LALInspiralWave( status->statusPtr, params->xfacVec, tmplt );
    CHECKSTATUSPTR( status );


    /* template dependent normalization */
    fcTmplt->tmpltNorm  = 2 * tmplt->mu;
    fcTmplt->tmpltNorm *= 2 * LAL_MRSUN_SI / ( cannonDist * 1.0e6 * LAL_PC_SI );
    fcTmplt->tmpltNorm *= params->dynRange;
    fcTmplt->tmpltNorm *= fcTmplt->tmpltNorm;
  }


  /* Taper the waveform if required */
  if ( params->taperTmplt != LAL_SIM_INSPIRAL_TAPER_NONE )
  {
    if ( XLALSimInspiralREAL4WaveTaper( params->xfacVec, params->taperTmplt )
           == XLAL_FAILURE )
    {
      ABORTXLAL( status );
    }
  }

  /* Find the end of the chirp */
  j = numPoints - 1;
  while ( xfac[j] == 0 )
  {
    /* search for the end of the chirp but don't fall off the array */
    if ( --j == 0 )
    {
      ABORT( status, FINDCHIRPTDH_EEMTY, FINDCHIRPTDH_MSGEEMTY );
    }
  }
  ++j;

  /* Band pass the template if required */
  if ( params->bandPassTmplt )
  {
    REAL4Vector bpVector; /*Used to save time */

    /* We want to shift the template to the middle of the vector so */
    /* that band-passing will work properly */
    shift = ( numPoints - j ) / 2;
    memmove( xfac + shift, xfac, j * sizeof( *xfac ) );
    memset( xfac, 0, shift * sizeof( *xfac ) );
    memset( xfac + ( numPoints + j ) / 2, 0,
         ( numPoints - ( numPoints + j ) / 2 ) * sizeof( *xfac ) );


    /* Select an appropriate part of the vector to band pass. */
    /* band passing the whole thing takes a lot of time */
    if ( j > 2 * sampleRate && 2 * j <= numPoints )
    {
      bpVector.length = 2 * j;
      bpVector.data   = params->xfacVec->data + numPoints / 2 - j;
    }
    else if ( j <= 2 * sampleRate && j + 2 * sampleRate <= numPoints )
    {
      bpVector.length = j + 2 * sampleRate;
      bpVector.data   = params->xfacVec->data
                   + ( numPoints - j ) / 2 - (INT4)sampleRate;
    }
    else
    {
      bpVector.length = params->xfacVec->length;
      bpVector.data   = params->xfacVec->data;
    }

    if ( XLALBandPassInspiralTemplate( &bpVector, 0.95 * tmplt->fLower,
                 1.02 * tmplt->fFinal, sampleRate ) == XLAL_FAILURE )
    {
      ABORTXLAL( status );
    }

    /* Now we need to do the shift to the end. */
    /* Use a temporary vector to avoid mishaps */
    if ( ( tmpxfac = XLALCreateREAL4Vector( numPoints ) ) == NULL )
    {
      ABORTXLAL( status );
    }

    if ( params->approximant == EOBNR || params->approximant == EOBNRv2
        || params->approximant == IMRPhenomB || params->approximant == IMRPhenomC )
    {
      /* We need to do something slightly different for EOBNR */
      UINT4 endIndx = (UINT4) (tmplt->tC * sampleRate);

      memcpy( tmpxfac->data, xfac + ( numPoints - j ) / 2 + endIndx,
          ( numPoints - ( numPoints - j ) / 2 - endIndx ) * sizeof( *xfac ) );

      memcpy( tmpxfac->data + numPoints - ( numPoints - j ) / 2 - endIndx,
                  xfac, ( ( numPoints - j ) / 2 + endIndx ) * sizeof( *xfac ) );
    }
    else
    {
      memcpy( tmpxfac->data, xfac + ( numPoints + j ) / 2,
          ( numPoints - ( numPoints + j ) / 2 ) * sizeof( *xfac ) );

      memcpy( tmpxfac->data + numPoints - ( numPoints + j ) / 2,
                    xfac, ( numPoints + j ) / 2 * sizeof( *xfac ) );
    }

    memcpy( xfac, tmpxfac->data, numPoints * sizeof( *xfac ) );

    XLALDestroyREAL4Vector( tmpxfac );
    tmpxfac = NULL;
  }
  else if ( params->approximant == EOBNR || params->approximant == EOBNRv2
      || params->approximant == IMRPhenomB || params->approximant == IMRPhenomC )
  {
    /* For EOBNR we shift so that tC is at the end of the vector */
    if ( ( tmpxfac = XLALCreateREAL4Vector( numPoints ) ) == NULL )
    {
      ABORTXLAL( status );
    }

    /* Set the coalescence index depending on tC */
    j = (UINT4) (tmplt->tC * sampleRate);
    memcpy( tmpxfac->data + numPoints - j, xfac, j * sizeof( *xfac ) );
    memcpy( tmpxfac->data, xfac + j, ( numPoints - j ) * sizeof( *xfac ) );
    memcpy( xfac, tmpxfac->data, numPoints * sizeof( *xfac ) );
    XLALDestroyREAL4Vector( tmpxfac );
    tmpxfac = NULL;
  }
  else
  {
    /* No need for so much shifting around if not band passing */
    /* shift chirp to end of vector so it is the correct place for the filter */
    memmove( xfac + numPoints - j, xfac, j * sizeof( *xfac ) );
    memset( xfac, 0, ( numPoints - j ) * sizeof( *xfac ) );
  }

  /*
   *
   * create the frequency domain findchirp template
   *
   */

  /* fft chirp */
  if ( XLALREAL4ForwardFFT( fcTmplt->data, params->xfacVec,
      params->fwdPlan ) == XLAL_FAILURE )
  {
    ABORTXLAL( status );
  }

  /* copy the template parameters to the findchirp template structure */
  memcpy( &(fcTmplt->tmplt), tmplt, sizeof(InspiralTemplate) );

  /* normal exit */
  DETATCHSTATUSPTR( status );
  RETURN( status );
}
void LALRandomInspiralSignal
(
 LALStatus              *status,
 REAL4Vector            *signalvec,
 RandomInspiralSignalIn *randIn
 )
{

    REAL8                   maxTemp; /* temporary variable */
    INT4                    iMax;    /* temporary index    */
    UINT4                   indice;
    REAL8                   epsilon1, epsilon2, norm;
    REAL4Vector             noisy, buff;
    AddVectorsIn            addIn;
    INT4                    valid;
    static RandomParams     *randomparams;
    InspiralWaveNormaliseIn normin;

    INITSTATUS(status);
    ATTATCHSTATUSPTR(status);

    ASSERT (signalvec->data,  status, LALNOISEMODELSH_ENULL, LALNOISEMODELSH_MSGENULL);
    ASSERT (randIn->psd.data,  status, LALNOISEMODELSH_ENULL, LALNOISEMODELSH_MSGENULL);
    ASSERT (randIn->mMin > 0, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);
    ASSERT (randIn->MMax > 2*randIn->mMin, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);
    ASSERT (randIn->type >= 0, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);
    ASSERT (randIn->type <= 2, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);

    buff.length = signalvec->length;
    if (!(buff.data = (REAL4*) LALCalloc(buff.length, sizeof(REAL4)) )) {
        ABORT (status, LALNOISEMODELSH_EMEM, LALNOISEMODELSH_MSGEMEM);
    }

    /* Use the seed to initialize random(). */
    srandom(randIn->useed);
    /* use the random number so generated as the next seed */
    randIn->useed = random();

    /* we need random parameters only if we need to generate a signal (i.e. type 0/2) */
    if (randIn->type==0 || randIn->type==2)
    {
        valid = 0;
        /* Keep generating random parameters until they
         * are located within the specified region */
        while (!valid)
        {
            epsilon1 = (float) random()/(float)RAND_MAX;
            epsilon2 = (float) random()/(float)RAND_MAX;
            switch (randIn->param.massChoice)
            {

                case bhns:
                    ASSERT(randIn->mMin<=3 && randIn->mMax>=3, status, 10,
                            "if massChoice is set to bhns, mass1 must be <= 3 "
                            "solar mass and mass2 >= 3 solar mass\n");
                    randIn->param.mass1 = randIn->mMin +
                            (3 - randIn->mMin) * epsilon1;
                    randIn->param.mass2 = 3  +
                            (randIn->mMax - 3) * epsilon2;
                    randIn->param.massChoice=m1Andm2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice=bhns;
                    break;

                case m1Andm2:
                    /*
                     * restriction is on the minimum and maximum individual
                     * masses of the two component stars.
                     */
                    randIn->param.mass1 = randIn->mMin +
                            (randIn->mMax - randIn->mMin) * epsilon1;
                    randIn->param.mass2 = randIn->mMin  +
                            (randIn->mMax - randIn->mMin) * epsilon2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case minmaxTotalMass:
                    /*
                     * restriction is on the min and max Total mass. Should be
                     * check carefully. Right now, I think that it is almost
                     * uniformly distributed in total mass but seem to drop at
                     * very high mass. I'm not sure about the etaMin either. I
                     * might remove this code anyway soon. This is for a quick
                     * test for Craig Robinson and the high mass CBC search
                     * */
                    {
                     REAL8 etaMin ;
                     randIn->param.totalMass = randIn->MMin + (randIn->MMax - randIn->MMin)*epsilon1 ;

                    if (randIn->param.totalMass < (randIn->mMin+ randIn->mMax)) {
                      etaMin = (randIn->mMin / randIn->param.totalMass);
                      etaMin = etaMin - etaMin *etaMin;
                    }
                    else {
                      etaMin = (randIn->mMax / randIn->param.totalMass);
                      etaMin = etaMin - etaMin *etaMin;
                    }
                    randIn->param.eta = etaMin + epsilon2 * (.25 - etaMin);

                    }
                    randIn->param.massChoice = totalMassAndEta;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = minmaxTotalMass;
                    break;


                case totalMassAndEta:
                    /*
                     * restriction is on the total mass of the binary
                     * and the minimum mass of the component stars
                     */


                    randIn->param.mass1 = randIn->mMin
                            + (randIn->MMax - 2.*randIn->mMin) * epsilon1;
                    randIn->param.mass2 = randIn->mMin
                            + (randIn->MMax - randIn->param.mass1 - randIn->mMin) * epsilon2;
                    randIn->param.totalMass = randIn->param.mass1 + randIn->param.mass2 ;
                    randIn->param.eta = (randIn->param.mass1*randIn->param.mass2) / pow(randIn->param.totalMass,2.L);
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case totalMassUAndEta:
                    /*
                     * restriction is on the total mass of the binary
                     * and the etaMin which depends on max total mass.
                     */
                    {
                        REAL4 etaMin;

                        randIn->param.totalMass =  2*randIn->mMin  +  epsilon1 * (randIn->MMax - 2 * randIn->mMin) ;

                        if (randIn->param.totalMass < (randIn->mMin+ randIn->mMax)) {
                            etaMin = (randIn->mMin / randIn->param.totalMass);
                            etaMin = etaMin - etaMin *etaMin;
                        }
                        else {
                            etaMin = (randIn->mMax / randIn->param.totalMass);
                            etaMin = etaMin - etaMin *etaMin;
                        }
                        randIn->param.eta = etaMin + epsilon2 * (.25 - etaMin);

                        LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                        CHECKSTATUSPTR(status);
                    }
                    break;

                case fixedMasses: /* the user has already given individual masses*/
                    randIn->param.massChoice = m1Andm2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedMasses;
                    break;

                case fixedPsi: /* the user has already given psi0/psi3*/
                    randIn->param.massChoice = psi0Andpsi3;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedPsi;
                    break;

                case fixedTau: /* the user has already given tau0/tau3*/
                    randIn->param.massChoice = t03;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedTau;
                    break;

                case t02:
                    /* chirptimes t0 and t2 are required in a specified range */
                    randIn->param.t0 = randIn->t0Min +
                            (randIn->t0Max - randIn->t0Min)*epsilon1;
                    randIn->param.t2 = randIn->tnMin +
                            (randIn->tnMax - randIn->tnMin)*epsilon2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case t03:
                    /* chirptimes t0 and t3 are required in a specified range */
                    randIn->param.t0 = randIn->t0Min +
                            (randIn->t0Max - randIn->t0Min)*epsilon1;
                    randIn->param.t3 = randIn->tnMin +
                            (randIn->tnMax - randIn->tnMin)*epsilon2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case psi0Andpsi3:
                    /* BCV parameters are required in a specified range */
                    randIn->param.psi0 = randIn->psi0Min +
                            (randIn->psi0Max - randIn->psi0Min)*epsilon1;
                    randIn->param.psi3 = randIn->psi3Min +
                            (randIn->psi3Max - randIn->psi3Min)*epsilon2;
                    break;

                case massesAndSpin:
                    /* masses, spin parameters and sky position needs to be set */

                    /* Set the random masses first */
                    randIn->param.mass1 = randIn->mMin +
                            (randIn->mMax - randIn->mMin) * epsilon1;
                    randIn->param.mass2 = randIn->mMin  +
                            (randIn->mMax - randIn->mMin) * epsilon2;

                    /* Set the random spin parameters */
                    GenerateRandomSpinTaylorParameters ( status->statusPtr, randIn );
                    CHECKSTATUSPTR(status);

                    /* Set the random sky position and polarisation angle */
                    GenerateRandomSkyPositionAndPolarisation ( status->statusPtr,randIn );
                    CHECKSTATUSPTR(status);

                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case t04:
                default:
                    /* if the choice of parameters is wrong abort the run */
                    ABORT (status, LALNOISEMODELSH_ECHOICE, LALNOISEMODELSH_MSGECHOICE);
                    break;
            }


            /* Validate the random parameters generated above */
            switch (randIn->param.massChoice)
            {
                case bhns:
                    valid=1;
                    break;
                case minmaxTotalMass:
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax &&
                            (randIn->param.eta > randIn->etaMin) &&
                            (randIn->param.mass1+randIn->param.mass2) < randIn->MMax  &&
                            (randIn->param.mass1+randIn->param.mass2) > randIn->MMin
                       )
                    {
                        valid = 1;
                    }
                     break;

                case fixedMasses:
                case fixedTau:
                  valid = 1;
                  break;
                case m1Andm2:
                case t03:
                case t02:
                    /*
                     * The following imposes a range in which min and
                     * max of component masses are restricted.
                     */
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax &&
                            randIn->param.eta <= 0.25 &&
                            randIn->param.eta >= randIn->etaMin
                       )
                    {
                        valid = 1;
                    }
                    break;

                case totalMassAndEta:
                case totalMassUAndEta:

                    /*
                     * The following imposes a range in which min of
                     * component masses and max total mass are restricted.
                     */
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.totalMass <= randIn->MMax &&
                            randIn->param.eta <= 0.25 &&
                            randIn->param.eta >= randIn->etaMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax
                       )

                    {
                        valid = 1;
                    }
                    break;
                case fixedPsi:
                    randIn->param.massChoice = psi0Andpsi3;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedPsi;
                    valid = 1;
                case psi0Andpsi3:
                    /*
                     * the following makes sure that the BCV has
                     * a well defined end-frequency
                     */
                    randIn->param.massChoice = psi0Andpsi3;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    valid = 1;
                    /*	       if (randIn->param.totalMass > 0.)
                               {
                               REAL8 fLR, fLSO, fend;
                               epsilon1 = (float) random()/(float)RAND_MAX;
                               fLR = 1.L/(LAL_PI * pow (3.L,1.5) * randIn->param.totalMass * LAL_MTSUN_SI);
                               fLSO = 1.L/(LAL_PI * pow (6.L,1.5) * randIn->param.totalMass * LAL_MTSUN_SI);
                               fend = fLSO + (fLR - fLSO) * epsilon1;
                               if (fend > randIn->param.tSampling/2. || fend < randIn->param.fLower) break;
                               randIn->param.fFinal = fend;
                               valid = 1;
                               }*/
                    break;

                case massesAndSpin:
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax &&
                            randIn->param.eta <= 0.25
                       )
                    {
                        valid = 1;
                    }
                    break;

                case t04:
                default:
                    ABORT (status, LALNOISEMODELSH_ECHOICE, LALNOISEMODELSH_MSGECHOICE);
                    break;
            }
        }
    }


    /* set up the structure for normalising the signal */
    normin.psd          = &(randIn->psd);
    normin.df           = randIn->param.tSampling / (REAL8) signalvec->length;
    normin.fCutoff      = randIn->param.fCutoff;
    normin.samplingRate = randIn->param.tSampling;

    switch (randIn->type)
    {
        case 0:

            /* First deal with the signal only case:
             * if the signal is generated in the Fourier domain no
             * need for Fourier transform
             */
            if (randIn->param.approximant == BCV ||
                    randIn->param.approximant == BCVSpin  ||
                    randIn->param.approximant == TaylorF1 ||
                    randIn->param.approximant == TaylorF2 ||
                    randIn->param.approximant == PadeF1)
            {
                LALInspiralWave(status->statusPtr, signalvec, &randIn->param);
                CHECKSTATUSPTR(status);
            }
            else /* Else - generate a time domain waveform */
            {
                /* Note that LALInspiralWave generates only the plus
                 * polarisation of the GW in the time/frequency domain.
                 * For SpinTaylor we need both plus and
                 * the cross polarisations - therefore for this case, we
                 * treat the waveform generation differently. For all other
                 * timedomain approximants, we recourse to calling
                 * LALInspiralWave () function.
                 */
                if (randIn->param.approximant == SpinTaylor)
                {
                    randIn->param.fFinal=0;
                    GenerateTimeDomainWaveformForInjection (status->statusPtr, &buff, &randIn->param);
                    CHECKSTATUSPTR(status);
                }
                else
                {
                    /* force to compute fFinal is it really necessary  ? */
                    randIn->param.fFinal=0;
                    LALInspiralWave(status->statusPtr, &buff, &randIn->param);
                    CHECKSTATUSPTR(status);
                }

                /* Once the time domain waveform has been generated, take its
                 * Fourier transform [i.e buff (t) ---> signal (f)].
                 */
                if (XLALREAL4VectorFFT(signalvec, &buff, randIn->fwdp) != 0)
                  ABORTXLAL(status);

            } /* End of else if time domain waveform */

            /* we might want to know where is the signalvec injected*/
            maxTemp  = 0;
            iMax     = 0;
            for ( indice = 0 ; indice< signalvec->length; indice++)
            {
                if (fabs(signalvec->data[indice]) > maxTemp){
                    iMax = indice;
                    maxTemp = fabs(signalvec->data[indice]);
                }
            }
            randIn->coalescenceTime = iMax;

            normin.fCutoff = randIn->param.fFinal;
            LALInspiralWaveNormaliseLSO(status->statusPtr, signalvec, &norm, &normin);
            CHECKSTATUSPTR(status);
            break;

        case 1:
            /*
             * next deal with the noise only case:
             */
            /*
                Old method of generating Gaussian noise
                LALGaussianNoise(status->statusPtr, &buff, &randIn->useed);
                */
            /*LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);*/
            LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);
            CHECKSTATUSPTR(status);
            LALNormalDeviates(status->statusPtr, &buff, randomparams);
            CHECKSTATUSPTR(status);
            LALDestroyRandomParams(status->statusPtr, &randomparams);
            CHECKSTATUSPTR(status);
            if (XLALREAL4VectorFFT(signalvec, &buff, randIn->fwdp) != 0)
              ABORTXLAL(status);
            LALColoredNoise(status->statusPtr, signalvec, randIn->psd);
            CHECKSTATUSPTR(status);

            /* multiply the noise vector by the correct normalisation factor */
            {
                double a2 = randIn->NoiseAmp * sqrt (randIn->param.tSampling)/2.L;
                UINT4 i;
                for (i=0; i<signalvec->length; i++) signalvec->data[i] *= a2;
            }
            break;

        default:
            /*
             * finally deal with the noise+signal only case:
             */
            noisy.length = signalvec->length;
            if (!(noisy.data = (REAL4*) LALMalloc(sizeof(REAL4)*noisy.length)))
            {
                if (buff.data != NULL) LALFree(buff.data);
                buff.data = NULL;
                ABORT (status, LALNOISEMODELSH_EMEM, LALNOISEMODELSH_MSGEMEM);
            }
            /*LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);*/
            LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);
            CHECKSTATUSPTR(status);
            LALNormalDeviates(status->statusPtr, &buff, randomparams);
            CHECKSTATUSPTR(status);
            LALDestroyRandomParams(status->statusPtr, &randomparams);
            CHECKSTATUSPTR(status);
            if (XLALREAL4VectorFFT(&noisy, &buff, randIn->fwdp) != 0)
              ABORTXLAL(status);
            LALColoredNoise(status->statusPtr, &noisy, randIn->psd);
            CHECKSTATUSPTR(status);

            if (randIn->param.approximant == BCV ||
                    randIn->param.approximant == BCVSpin  ||
                    randIn->param.approximant == TaylorF1 ||
                    randIn->param.approximant == TaylorF2 ||
                    randIn->param.approximant == PadeF1)
            {
                LALInspiralWave(status->statusPtr, &buff, &randIn->param);
                CHECKSTATUSPTR(status);
            }
            else
            {
                LALInspiralWave(status->statusPtr, signalvec, &randIn->param);
                CHECKSTATUSPTR(status);


                /* Now convert from time domain signal(t) ---> frequency
                 * domain waveform buff(f) i.e signal(t) -> buff(f)*/
                if (XLALREAL4VectorFFT(&buff, signalvec, randIn->fwdp) != 0)
                  ABORTXLAL(status);

            }

            /* we might want to know where is the signal injected*/
            maxTemp  = 0;
            iMax     = 0;
            for ( indice = 0 ; indice< signalvec->length; indice++)
            {
                if (fabs(signalvec->data[indice]) > maxTemp){
                    iMax = indice;
                    maxTemp = fabs(signalvec->data[indice]);
                }
            }
            randIn->coalescenceTime = iMax;

            normin.fCutoff = randIn->param.fFinal;
            LALInspiralWaveNormaliseLSO(status->statusPtr, &buff, &norm, &normin);
            CHECKSTATUSPTR(status);

            addIn.v1 = &buff;
            addIn.a1 = randIn->SignalAmp;
            addIn.v2 = &noisy;
            /* After experimenting we found that the following factor SamplingRate*sqrt(2)
             * is needed for noise amplitude to get the output of the signalless correlation
             * equal to unity; the proof of this is still needed
             */
            addIn.a2 = randIn->NoiseAmp * sqrt (randIn->param.tSampling)/2.L;
            LALAddVectors(status->statusPtr, signalvec, addIn);
            CHECKSTATUSPTR(status);
            if (noisy.data != NULL) LALFree(noisy.data);
            break;
    }

    /* Hash out signal for all frequencies less than or equal to the
     * lower cut-off frequency.
     */


    if (buff.data != NULL) LALFree(buff.data);

    DETATCHSTATUSPTR(status);
    RETURN(status);
}