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

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

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

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

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

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

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

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

  /* deallocate stuff and return */
bail_out:

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

  if (errnum)
    XLAL_ERROR (errnum);

  *yout = output;
  return outputlen;
}
/*------------------------------------------------------------------------------------------
 *
 *    Definitions of functions (only one in this file, so no prototypes needed).
 *
 *------------------------------------------------------------------------------------------
 */
static int SEOBNRv3OptimizedInterpolatorGeneral(
                REAL8 * yin, /**<< Data to be interpolated; time first */
                REAL8 tinit, /**<< time at which to begin interpolating */
                REAL8 deltat, /**<< Spacing between interpolated times */
                UINT4 num_input_times, /**<< The number of input times */
                REAL8Array ** yout, /**<< Interpolation output */
                size_t dim /**<< Number of quantities interpolated (e.g. if yin = {t,x,y,z} then dim 3) */
                )
{
    int errnum = 0;

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

    /* note: for speed, this replaces the single CALLGSL wrapper applied before each GSL call */
    interp = gsl_spline_alloc(gsl_interp_cspline, num_input_times);
    accel = gsl_interp_accel_alloc();

    outputlen = (int)(yin[num_input_times-1] / deltat) + 1;

    output = XLALCreateREAL8ArrayL(2, dim+1, outputlen);/* Original (dim+1)*/

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

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

    /* interpolate! */
    for (unsigned int i = 1; i <= dim; i++) { /* Original (dim)  */
     //gsl_spline_init(interp, &yin->data[0], &yin->data[num_input_times * i], num_input_times + 1);
     gsl_spline_init(interp, yin, &(yin[num_input_times * i]), num_input_times);

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

    /* deallocate stuff and return */
  bail_out:

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

    if (errnum)
        XLAL_ERROR(errnum);

    *yout = output;
    return outputlen;
}
Пример #3
0
int main( int argc, char **argv )
{
  INT4 i,j;
  struct coh_PTF_params      *params    = NULL;
  ProcessParamsTable      *procpar   = NULL;
  REAL4FFTPlan            *fwdplan   = NULL;
  REAL4FFTPlan            *psdplan   = NULL;
  REAL4FFTPlan            *revplan   = NULL;
  COMPLEX8FFTPlan         *invPlan   = NULL;
  REAL4TimeSeries         *channel[LAL_NUM_IFO+1];
  REAL4FrequencySeries    *invspec[LAL_NUM_IFO+1];
  RingDataSegments        *segments[LAL_NUM_IFO+1];
  INT4                    numTmplts = 0;
  INT4  startTemplate     = -1;           /* index of first template      */
  INT4  stopTemplate      = -1;           /* index of last template       */
  INT4 numSegments        = 0;
  InspiralTemplate        *PTFtemplate = NULL;
  InspiralTemplate        *PTFbankhead = NULL;
  SnglInspiralTable       *PTFSpinTmplt = NULL;
  SnglInspiralTable       *PTFSpinTmpltHead = NULL;
  SnglInspiralTable       *PTFNoSpinTmplt = NULL;
  SnglInspiralTable       *PTFNoSpinTmpltHead = NULL;
  SnglInspiralTable       *PTFLastTmplt = NULL;
  FindChirpTemplate       *fcTmplt     = NULL;
  FindChirpTmpltParams    *fcTmpltParams      = NULL;
  FindChirpInitParams     *fcInitParams = NULL;
  UINT4                   numPoints,ifoNumber,spinTemplate;
  REAL8Array              *PTFM[LAL_NUM_IFO+1];
  REAL8Array              *PTFN[LAL_NUM_IFO+1];
  COMPLEX8VectorSequence  *PTFqVec[LAL_NUM_IFO+1];
  time_t                  startTime;
  LALDetector             *detectors[LAL_NUM_IFO+1];
  REAL4                   *timeOffsets;
  REAL4                   *Fplus;
  REAL8                   FplusTmp;
  REAL4                   *Fcross;
  REAL8                   FcrossTmp;
  REAL8                   detLoc[3];
  REAL4TimeSeries         UNUSED *pValues[10];
  REAL4TimeSeries         UNUSED *gammaBeta[2];
  LIGOTimeGPS             segStartTime;
  MultiInspiralTable      *eventList = NULL;
  UINT4                   numDetectors = 0;
  UINT4                   singleDetector = 0;
  char                    bankFileName[256];
  
  startTime = time(NULL);

  /* set error handlers to abort on error */
  set_abrt_on_error();

  /* options are parsed and debug level is set here... */
  

  /* no lal mallocs before this! */
  params = coh_PTF_get_params( argc, argv );

  /* create process params */
  procpar = create_process_params( argc, argv, PROGRAM_NAME );

  verbose("Read input params %ld \n", time(NULL)-startTime);

  /* create forward and reverse fft plans */
  fwdplan = coh_PTF_get_fft_fwdplan( params );
  psdplan = coh_PTF_get_fft_psdplan( params );
  revplan = coh_PTF_get_fft_revplan( params );

  verbose("Made fft plans %ld \n", time(NULL)-startTime);

  /* Determine if we are analyzing single or multiple ifo data */

  for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
  {
    if ( params->haveTrig[ifoNumber] )
    {
      numDetectors++;
    }
  }
  /* NULL out the pValues pointer array */
  for ( i = 0 ; i < 10 ; i++ )
  {
    pValues[i] = NULL;
  }   
  gammaBeta[0] = NULL;
  gammaBeta[1] = NULL;

  if (numDetectors == 0 )
  {
    fprintf(stderr,"You have not specified any detectors to analyse");
    return 1;
  }
  else if (numDetectors == 1 )
  {
    fprintf(stdout,"You have only specified one detector, why are you using the coherent code? \n");
    singleDetector = 1;
  }

  /* Convert the file names */
  if ( params->bankFile )
    strncpy(bankFileName,params->bankFile,sizeof(bankFileName)-1);

  REAL4                    *timeSlideVectors;
  timeSlideVectors=LALCalloc(1, (LAL_NUM_IFO+1)*
                                params->numOverlapSegments*sizeof(REAL4));
  memset(timeSlideVectors, 0,
         (LAL_NUM_IFO+1) * params->numOverlapSegments * sizeof(REAL4));

  for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
  {
    /* Initialize some of the structures */
    channel[ifoNumber] = NULL;
    invspec[ifoNumber] = NULL;
    segments[ifoNumber] = NULL;
    PTFM[ifoNumber] = NULL;
    PTFN[ifoNumber] = NULL;
    PTFqVec[ifoNumber] = NULL;
    if ( params->haveTrig[ifoNumber] )
    {
      /* Read in data from the various ifos */
      channel[ifoNumber] = coh_PTF_get_data(params,params->channel[ifoNumber],\
                               params->dataCache[ifoNumber],ifoNumber );
      coh_PTF_rescale_data (channel[ifoNumber],1E20);

      /* compute the spectrum */
      invspec[ifoNumber] = coh_PTF_get_invspec( channel[ifoNumber], fwdplan,\
                               revplan, psdplan, params );

      /* create the segments */
      segments[ifoNumber] = coh_PTF_get_segments( channel[ifoNumber],\
           invspec[ifoNumber], fwdplan, ifoNumber, timeSlideVectors, params );
      
      numSegments = segments[ifoNumber]->numSgmnt;

      verbose("Created segments for one ifo %ld \n", time(NULL)-startTime);
    }
  }

  /* Determine time delays and response functions */ 

  timeOffsets = LALCalloc(1, numSegments*LAL_NUM_IFO*sizeof( REAL4 ));
  Fplus = LALCalloc(1, numSegments*LAL_NUM_IFO*sizeof( REAL4 ));
  Fcross = LALCalloc(1, numSegments*LAL_NUM_IFO*sizeof( REAL4 ));
  for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
  {
    detectors[ifoNumber] = LALCalloc( 1, sizeof( *detectors[ifoNumber] ));
    XLALReturnDetector(detectors[ifoNumber] ,ifoNumber);
    for ( i = 0; i < 3; i++ )
    {
      detLoc[i] = (double) detectors[ifoNumber]->location[i];
    }
    for ( j = 0; j < numSegments; ++j )
    {
      /* Despite being called segStartTime we use the time at the middle 
      * of a segment */
      segStartTime = params->startTime;
      
      /*XLALGPSAdd(&segStartTime,(j+1)*params->segmentDuration/2.0);*/
      XLALGPSAdd(&segStartTime,8.5*params->segmentDuration/2.0);
      /*XLALGPSMultiply(&segStartTime,0.);
      XLALGPSAdd(&segStartTime,874610713.072549154);*/
      timeOffsets[j*LAL_NUM_IFO+ifoNumber] = (REAL4)
          XLALTimeDelayFromEarthCenter(detLoc,params->rightAscension,
          params->declination,&segStartTime);
      XLALComputeDetAMResponse(&FplusTmp, &FcrossTmp,
         (const REAL4 (*)[3])detectors[ifoNumber]->response,params->rightAscension,
         params->declination,0.,XLALGreenwichMeanSiderealTime(&segStartTime));
      Fplus[j*LAL_NUM_IFO + ifoNumber] = (REAL4) FplusTmp;
      Fcross[j*LAL_NUM_IFO + ifoNumber] = (REAL4) FcrossTmp;
    }
    LALFree(detectors[ifoNumber]);
  }
  

  numPoints = floor( params->segmentDuration * params->sampleRate + 0.5 );

  /* Initialize some of the structures */
  ifoNumber = LAL_NUM_IFO;
  channel[ifoNumber] = NULL;
  invspec[ifoNumber] = NULL;
  segments[ifoNumber] = NULL;
  PTFM[ifoNumber] = NULL;
  PTFN[ifoNumber] = NULL;
  PTFqVec[ifoNumber] = NULL;

  /* Create the relevant structures that will be needed */
  fcInitParams = LALCalloc( 1, sizeof( *fcInitParams ));
  fcTmplt = LALCalloc( 1, sizeof( *fcTmplt ) );
  fcTmpltParams = LALCalloc ( 1, sizeof( *fcTmpltParams ) );
  fcTmpltParams->approximant = FindChirpPTF;
  fcTmplt->PTFQtilde =
      XLALCreateCOMPLEX8VectorSequence( 5, numPoints / 2 + 1 );
/*  fcTmplt->PTFBinverse = XLALCreateArrayL( 2, 5, 5 );
  fcTmplt->PTFB = XLALCreateArrayL( 2, 5, 5 );*/
  fcTmplt->PTFQ = XLALCreateVectorSequence( 5, numPoints );
  fcTmpltParams->PTFphi = XLALCreateVector( numPoints );
  fcTmpltParams->PTFomega_2_3 = XLALCreateVector( numPoints );
  fcTmpltParams->PTFe1 = XLALCreateVectorSequence( 3, numPoints );
  fcTmpltParams->PTFe2 = XLALCreateVectorSequence( 3, numPoints );
  fcTmpltParams->fwdPlan =
        XLALCreateForwardREAL4FFTPlan( numPoints, 1 );
  fcTmpltParams->deltaT = 1.0/params->sampleRate;
  for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
  {
    if ( params->haveTrig[ifoNumber] )
    {
      PTFM[ifoNumber] = XLALCreateREAL8ArrayL( 2, 5, 5 );
      PTFN[ifoNumber] = XLALCreateREAL8ArrayL( 2, 5, 5 );
      PTFqVec[ifoNumber] = XLALCreateCOMPLEX8VectorSequence ( 5, numPoints );
    }
  }
  /* Create an inverser FFT plan */
  invPlan = XLALCreateReverseCOMPLEX8FFTPlan( numPoints, 1 );

  /* Read in the tmpltbank xml file */
  numTmplts = InspiralTmpltBankFromLIGOLw( &PTFtemplate,bankFileName,
      startTemplate, stopTemplate );
  PTFbankhead = PTFtemplate;
  /*fake_template (PTFtemplate);*/

  for (i = 0; (i < numTmplts); PTFtemplate = PTFtemplate->next, i++)
  {
    /* Determine if we can model this template as non-spinning */
    spinTemplate = 1;
    if (PTFtemplate->chi < 0.1) 
      spinTemplate = 0;
    PTFtemplate->approximant = FindChirpPTF;
    PTFtemplate->order = LAL_PNORDER_TWO;
    PTFtemplate->fLower = 38.;
    /* Generate the Q freq series of the template */
    coh_PTF_template(fcTmplt,PTFtemplate,fcTmpltParams);

    verbose("Generated template %d at %ld \n", i, time(NULL)-startTime);

    for ( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
    {
      if ( params->haveTrig[ifoNumber] )
      {
        memset( PTFM[ifoNumber]->data, 0, 25 * sizeof(REAL8) );
        memset( PTFN[ifoNumber]->data, 0, 25 * sizeof(REAL8) );
        memset( PTFqVec[ifoNumber]->data, 0,
                  5 * numPoints * sizeof(COMPLEX8) );
        coh_PTF_normalize(params,fcTmplt,invspec[ifoNumber],PTFM[ifoNumber],
              PTFN[ifoNumber],PTFqVec[ifoNumber],
              &segments[ifoNumber]->sgmnt[0],invPlan,1);
      }
    }

    spinTemplate = coh_PTF_spin_checker(PTFM,PTFN,params,singleDetector,Fplus,Fcross,numSegments/2); 
    if (spinTemplate)
      verbose("Template %d treated as spin at %ld \n",i,time(NULL)-startTime);
    else
      verbose("Template %d treated as non spin at %ld \n",i,time(NULL)-startTime);
    if (spinTemplate)
    {
      if ( !PTFSpinTmplt )
      {
        PTFSpinTmpltHead = conv_insp_tmpl_to_sngl_table(PTFtemplate,i);
        PTFSpinTmplt = PTFSpinTmpltHead;
      }
      else
      {
        PTFLastTmplt = PTFSpinTmplt;
        PTFSpinTmplt = conv_insp_tmpl_to_sngl_table(PTFtemplate,i);
        PTFLastTmplt->next = PTFSpinTmplt;
      }
    }
    else
    {
      if ( !PTFNoSpinTmplt )
      {
        PTFNoSpinTmpltHead = conv_insp_tmpl_to_sngl_table(PTFtemplate,i);
        PTFNoSpinTmplt = PTFNoSpinTmpltHead;
      }
      else
      {
        PTFLastTmplt = PTFNoSpinTmplt;
        PTFNoSpinTmplt = conv_insp_tmpl_to_sngl_table(PTFtemplate,i);
        PTFLastTmplt->next = PTFNoSpinTmplt;
      }
    }

    if (! PTFtemplate->event_id)
    {
      PTFtemplate->event_id = (EventIDColumn *)
            LALCalloc(1, sizeof(EventIDColumn) );
      PTFtemplate->event_id->id = i;
    }
  }

  coh_PTF_output_tmpltbank(params->spinBankName,PTFSpinTmpltHead,procpar,params);
  coh_PTF_output_tmpltbank(params->noSpinBankName,PTFNoSpinTmpltHead,procpar,params);

  verbose("Generated output xml files, cleaning up and exiting at %ld \n",
      time(NULL)-startTime);

  LALFree(timeSlideVectors);
  coh_PTF_cleanup(params,procpar,fwdplan,psdplan,revplan,invPlan,channel,
      invspec,segments,eventList,NULL,PTFbankhead,fcTmplt,fcTmpltParams,
      fcInitParams,PTFM,PTFN,PTFqVec,timeOffsets,NULL,Fplus,Fcross,NULL,NULL,\
      NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  while ( PTFSpinTmpltHead )
  {
    PTFSpinTmplt = PTFSpinTmpltHead;
    PTFSpinTmpltHead = PTFSpinTmplt->next;
    if ( PTFSpinTmplt->event_id )
    {
      LALFree( PTFSpinTmplt->event_id );
    }
    LALFree( PTFSpinTmplt );
  }
  while ( PTFNoSpinTmpltHead )
  {
    PTFNoSpinTmplt = PTFNoSpinTmpltHead;
    PTFNoSpinTmpltHead = PTFNoSpinTmplt->next;
    if ( PTFNoSpinTmplt->event_id )
    {
      LALFree( PTFNoSpinTmplt->event_id );
    }
    LALFree( PTFNoSpinTmplt );
  }

  LALCheckMemoryLeaks();
  return 0;
}