Exemplo n.º 1
0
REAL8 calculate_lalsim_snr(SimInspiralTable *inj, char *IFOname, REAL8FrequencySeries *psd, REAL8 start_freq)
{
  /* Calculate and return the single IFO SNR
   *
   * Required options:
   *
   * inj:     SimInspiralTable entry for which the SNR has to be calculated
   * IFOname: The canonical name (e.g. H1, L1, V1) name of the IFO for which the SNR must be calculated
   * PSD:     PSD curve to be used for the overlap integrap
   * start_freq: lower cutoff of the overlap integral
   *
   * */

  int ret=0;
  INT4 errnum=0;
  UINT4 j=0;
  /* Fill detector site info */
  LALDetector*  detector=NULL;
  detector=calloc(1,sizeof(LALDetector));
  if(!strcmp(IFOname,"H1"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLHODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"H2"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLHODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"LLO")||!strcmp(IFOname,"L1"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLLODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"V1")||!strcmp(IFOname,"VIRGO"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexVIRGODIFF],sizeof(LALDetector));

  Approximant approx=TaylorF2;
  approx=XLALGetApproximantFromString(inj->waveform);
  LALSimulationDomain modelDomain;

  if(XLALSimInspiralImplementedFDApproximants(approx)) modelDomain = LAL_SIM_DOMAIN_FREQUENCY;
  else if(XLALSimInspiralImplementedTDApproximants(approx)) modelDomain = LAL_SIM_DOMAIN_TIME;
  else
  {
      fprintf(stderr,"ERROR. Unknown approximant number %i. Unable to choose time or frequency domain model.",approx);
      exit(1);
  }

  REAL8 m1,m2, s1x,s1y,s1z,s2x,s2y,s2z,phi0,f_min,f_max,iota,polarization;

  /* No tidal PN terms until injtable is able to get them */

  LALDict *LALpars= XLALCreateDict();

  /* Spin and tidal interactions at the highest level (default) until injtable stores them.
   * When spinO and tideO are added to injtable we can un-comment those lines and should be ok
   *
  int spinO = inj->spinO;
  int tideO = inj->tideO;
  XLALSimInspiralSetSpinOrder(waveFlags, *(LALSimInspiralSpinOrder*) spinO);
  XLALSimInspiralSetTidalOrder(waveFlags, *(LALSimInspiralTidalOrder*) tideO);
  */

  XLALSimInspiralWaveformParamsInsertPNPhaseOrder(LALpars,XLALGetOrderFromString(inj->waveform));
  XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALpars,inj->amp_order);
  /* Read parameters */
  m1=inj->mass1*LAL_MSUN_SI;
  m2=inj->mass2*LAL_MSUN_SI;
  s1x=inj->spin1x;
  s1y=inj->spin1y;
  s1z=inj->spin1z;
  s2x=inj->spin2x;
  s2y=inj->spin2y;
  s2z=inj->spin2z;
  iota=inj->inclination;
  f_min=XLALSimInspiralfLow2fStart(inj->f_lower,XLALSimInspiralWaveformParamsLookupPNAmplitudeOrder(LALpars),XLALGetApproximantFromString(inj->waveform));
  phi0=inj->coa_phase;
  polarization=inj->polarization;
  REAL8 latitude=inj->latitude;
  REAL8 longitude=inj->longitude;

  LIGOTimeGPS epoch;
  memcpy(&epoch,&(inj->geocent_end_time),sizeof(LIGOTimeGPS));

  /* Hardcoded values of srate and segment length. If changed here they must also be changed in inspinj.c */
  REAL8 srate=4096.0;
  const CHAR *WF=inj->waveform;
  /* Increase srate for EOB WFs */
  if (strstr(WF,"EOB"))
    srate=8192.0;
  REAL8 segment=64.0;

  f_max=(srate/2.0-(1.0/segment));
  size_t seglen=(size_t) segment*srate;
  REAL8 deltaF=1.0/segment;
  REAL8 deltaT=1.0/srate;

  /* Frequency domain h+ and hx. They are going to be filled either by a FD WF or by the FFT of a TD WF*/
  COMPLEX16FrequencySeries *freqHplus;
  COMPLEX16FrequencySeries *freqHcross;
  freqHplus=  XLALCreateCOMPLEX16FrequencySeries("fhplus",
    &epoch,
    0.0,
    deltaF,
    &lalDimensionlessUnit,
    seglen/2+1
  );

  freqHcross=XLALCreateCOMPLEX16FrequencySeries("fhcross",
    &epoch,
    0.0,
    deltaF,
    &lalDimensionlessUnit,
    seglen/2+1
  );

  /* If the approximant is on the FD call XLALSimInspiralChooseFDWaveform */
  if (modelDomain == LAL_SIM_DOMAIN_FREQUENCY)
  {

    COMPLEX16FrequencySeries *hptilde=NULL;
    COMPLEX16FrequencySeries *hctilde=NULL;
    //We do not pass the polarization here, we assume it is taken into account when projecting h+,x onto the detector.
    XLAL_TRY(ret=XLALSimInspiralChooseFDWaveform(&hptilde,&hctilde, m1, m2,
						 s1x, s1y, s1z, s2x, s2y, s2z,
						 LAL_PC_SI * 1.0e6, iota, phi0, 0., 0., 0.,
						 deltaF, f_min, 0.0, 0.0,
						 LALpars,approx),errnum);
    XLALDestroyDict(LALpars);

    if(!hptilde|| hptilde->data==NULL || hptilde->data->data==NULL ||!hctilde|| hctilde->data==NULL || hctilde->data->data==NULL)
    {
      XLALPrintError(" ERROR in XLALSimInspiralChooseFDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum );
      exit(1);
    }

    COMPLEX16 *dataPtr = hptilde->data->data;
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      if(j < hptilde->data->length)
      {
        freqHplus->data->data[j] = dataPtr[j];
      }
      else
      {
        freqHplus->data->data[j]=0.0 + I*0.0;
      }
    }
    dataPtr = hctilde->data->data;
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      if(j < hctilde->data->length)
      {
        freqHcross->data->data[j] = dataPtr[j];
      }
      else
      {
        freqHcross->data->data[j]=0.0+0.0*I;
      }
    }
    /* Clean */
    if(hptilde) XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    if(hctilde) XLALDestroyCOMPLEX16FrequencySeries(hctilde);

  }
  else
  {

    /* Otherwise use XLALSimInspiralChooseTDWaveform */
    REAL8FFTPlan *timeToFreqFFTPlan = XLALCreateForwardREAL8FFTPlan((UINT4) seglen, 0 );
    REAL8TimeSeries *hplus=NULL;
    REAL8TimeSeries *hcross=NULL;
    REAL8TimeSeries *timeHplus=NULL;
    REAL8TimeSeries *timeHcross=NULL;
    REAL8 padding =0.4;//seconds
    REAL8Window *window=XLALCreateTukeyREAL8Window(seglen,(REAL8)2.0*padding*srate/(REAL8)seglen);
    REAL4 WinNorm = sqrt(window->sumofsquares/window->data->length);
    timeHcross=XLALCreateREAL8TimeSeries("timeModelhCross",
      &epoch,
      0.0,
      deltaT,
      &lalStrainUnit,
      seglen
    );
    timeHplus=XLALCreateREAL8TimeSeries("timeModelhplus",
      &epoch,
      0.0,
      deltaT,
      &lalStrainUnit,
      seglen
    );
    for (j=0;j<(UINT4) timeHcross->data->length;++j)
      timeHcross->data->data[j]=0.0;
    for (j=0;j<(UINT4) timeHplus->data->length;++j)
      timeHplus->data->data[j]=0.0;
    XLAL_TRY(ret=XLALSimInspiralChooseTDWaveform(&hplus, &hcross, m1, m2,
						 s1x, s1y, s1z, s2x, s2y, s2z,
						 LAL_PC_SI*1.0e6, iota,
						 phi0, 0., 0., 0., deltaT, f_min, 0.,
						 LALpars, approx),
        errnum);

    if (ret == XLAL_FAILURE || hplus == NULL || hcross == NULL)
    {
      XLALPrintError(" ERROR in XLALSimInspiralChooseTDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum );
      exit(1);
    }

    hplus->epoch  = timeHplus->epoch;
    hcross->epoch = timeHcross->epoch;

    XLALSimAddInjectionREAL8TimeSeries(timeHplus, hplus, NULL);
    XLALSimAddInjectionREAL8TimeSeries(timeHcross, hcross, NULL);
    for (j=0; j<(UINT4) timeHplus->data->length; ++j)
      timeHplus->data->data[j]*=window->data->data[j];
    for (j=0; j<(UINT4) timeHcross->data->length; ++j)
      timeHcross->data->data[j]*=window->data->data[j];
      
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      freqHplus->data->data[j]=0.0+I*0.0;
      freqHcross->data->data[j]=0.0+I*0.0;
    }

    /* FFT into freqHplus and freqHcross */
    XLALREAL8TimeFreqFFT(freqHplus,timeHplus,timeToFreqFFTPlan);
    XLALREAL8TimeFreqFFT(freqHcross,timeHcross,timeToFreqFFTPlan);
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      freqHplus->data->data[j]/=WinNorm;
      freqHcross->data->data[j]/=WinNorm;
    }
    /* Clean... */
    if ( hplus ) XLALDestroyREAL8TimeSeries(hplus);
    if ( hcross ) XLALDestroyREAL8TimeSeries(hcross);
    if ( timeHplus ) XLALDestroyREAL8TimeSeries(timeHplus);
    if ( timeHcross ) XLALDestroyREAL8TimeSeries(timeHcross);
    if (timeToFreqFFTPlan) LALFree(timeToFreqFFTPlan);
    if (window) XLALDestroyREAL8Window(window);
  }

  /* The WF has been generated and is in freqHplus/cross. Now project into the IFO frame */
  double Fplus, Fcross;
  double FplusScaled, FcrossScaled;
  double HSquared;
  double GPSdouble=(REAL8) inj->geocent_end_time.gpsSeconds+ (REAL8) inj->geocent_end_time.gpsNanoSeconds*1.0e-9;
  double gmst;
  LIGOTimeGPS GPSlal;
  XLALGPSSetREAL8(&GPSlal, GPSdouble);
  gmst=XLALGreenwichMeanSiderealTime(&GPSlal);

  /* Fill Fplus and Fcross*/
  XLALComputeDetAMResponse(&Fplus, &Fcross, (const REAL4 (*)[3])detector->response,longitude, latitude, polarization, gmst);
  /* And take the distance into account */
  FplusScaled  = Fplus  / (inj->distance);
  FcrossScaled = Fcross / (inj->distance);

  REAL8 timedelay = XLALTimeDelayFromEarthCenter(detector->location,longitude, latitude, &GPSlal);
  REAL8 timeshift =  timedelay;
  REAL8 twopit    = LAL_TWOPI * timeshift;

  UINT4 lower = (UINT4)ceil(start_freq / deltaF);
  UINT4 upper = (UINT4)floor(f_max / deltaF);
  REAL8 re = cos(twopit*deltaF*lower);
  REAL8 im = -sin(twopit*deltaF*lower);

  /* Incremental values, using cos(theta) - 1 = -2*sin(theta/2)^2 */
  REAL8 dim = -sin(twopit*deltaF);
  REAL8 dre = -2.0*sin(0.5*twopit*deltaF)*sin(0.5*twopit*deltaF);
  REAL8 TwoDeltaToverN = 2.0 *deltaT / ((double) seglen);

  REAL8 plainTemplateReal,  plainTemplateImag,templateReal,templateImag;
  REAL8 newRe, newIm,temp;
  REAL8 this_snr=0.0;
  if ( psd )
  {
    psd = XLALInterpolatePSD(psd,  deltaF);
  } 
  for (j=lower; j<=(UINT4) upper; ++j)
  {
    /* derive template (involving location/orientation parameters) from given plus/cross waveforms: */
    plainTemplateReal = FplusScaled * creal(freqHplus->data->data[j])
                        +  FcrossScaled *creal(freqHcross->data->data[j]);
    plainTemplateImag = FplusScaled * cimag(freqHplus->data->data[j])
                        +  FcrossScaled * cimag(freqHcross->data->data[j]);

    /* do time-shifting...             */
    /* (also un-do 1/deltaT scaling): */
    templateReal = (plainTemplateReal*re - plainTemplateImag*im) / deltaT;
    templateImag = (plainTemplateReal*im + plainTemplateImag*re) / deltaT;
    HSquared  = templateReal*templateReal + templateImag*templateImag ;
    temp = ((TwoDeltaToverN * HSquared) / psd->data->data[j]);
    this_snr  += temp;
    /* Now update re and im for the next iteration. */
    newRe = re + re*dre - im*dim;
    newIm = im + re*dim + im*dre;

    re = newRe;
    im = newIm;
  }

  /* Clean */
  if (freqHcross) XLALDestroyCOMPLEX16FrequencySeries(freqHcross);
  if (freqHplus) XLALDestroyCOMPLEX16FrequencySeries(freqHplus);
  if (detector) free(detector);

  return sqrt(this_snr*2.0);

}
Exemplo n.º 2
0
void
LALGalacticInspiralParamsToSimInspiralTable(
    LALStatus                  *status,
    SimInspiralTable           *output,
    GalacticInspiralParamStruc *input,
    RandomParams               *params
    )

{
  PPNParamStruc         ppnParams;
  SkyPosition           skyPos;
  LALSource             source;
  LALDetector           lho = lalCachedDetectors[LALDetectorIndexLHODIFF];
  LALDetector           llo = lalCachedDetectors[LALDetectorIndexLLODIFF];
  LALDetAndSource       detAndSource;
  LALDetAMResponse      resp;
  REAL8     time_diff;
  REAL4                 splus, scross, cosiota;

  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  ASSERT( output, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( input, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( params, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );


  /*
   *
   * compute sky position and inspiral params
   *
   */


  /* generate the ppn inspiral params */
  memset( &ppnParams, 0, sizeof(PPNParamStruc) );
  LALGetInspiralParams( status->statusPtr, &ppnParams, input, params );
  CHECKSTATUSPTR( status );

  if ( ppnParams.position.system != COORDINATESYSTEM_EQUATORIAL )
  {
    ABORT( status, LIGOMETADATAUTILSH_ECOOR, LIGOMETADATAUTILSH_MSGECOOR );
  }

  /* copy the inspiral data into sim_inspiral table */
  output->mass1        = input->m1;
  output->mass2        = input->m2;
  output->eta          = ppnParams.eta;
  output->distance     = ppnParams.d / (1.0e6 * LAL_PC_SI); /* Mpc */
  output->longitude    = ppnParams.position.longitude;
  output->latitude     = ppnParams.position.latitude;
  output->inclination  = ppnParams.inc;
  output->coa_phase    = ppnParams.phi;
  output->polarization = ppnParams.psi;

  /* populate geocentric end time */
  output->geocent_end_time = input->geocentEndTime;

  /* populate gmst field (hours) */
  output->end_time_gmst = fmod(XLALGreenwichMeanSiderealTime(
      &output->geocent_end_time), LAL_TWOPI) * 24.0 / LAL_TWOPI;  /* hours*/
  ASSERT( !XLAL_IS_REAL8_FAIL_NAN(output->end_time_gmst), status, LAL_FAIL_ERR, LAL_FAIL_MSG );

  /* set up params for the site end times and detector response */
  memset( &skyPos, 0, sizeof(SkyPosition) );
  memset( &source, 0, sizeof(LALSource) );
  memset( &detAndSource, 0, sizeof(LALDetAndSource) );

  skyPos.longitude = output->longitude;
  skyPos.latitude  = output->latitude;
  skyPos.system    = COORDINATESYSTEM_EQUATORIAL;

  source.equatorialCoords = skyPos;
  source.orientation      = output->polarization;

  detAndSource.pSource = &source;


  /*
   *
   * compute site end times
   *
   */


  /* initialize end times with geocentric value */
  output->h_end_time = output->l_end_time = input->geocentEndTime;

  /* ligo hanford observatory */
  time_diff = XLALTimeDelayFromEarthCenter( lho.location, skyPos.longitude, skyPos.latitude, &(output->geocent_end_time) );
  XLALGPSAdd(&(output->h_end_time), time_diff);

  /* ligo livingston observatory */
  time_diff = XLALTimeDelayFromEarthCenter( llo.location, skyPos.longitude, skyPos.latitude, &(output->geocent_end_time) );
  XLALGPSAdd(&(output->l_end_time), time_diff);


  /*
   *
   * compute the effective distance of the inspiral
   *
   */


  /* initialize distances with real distance and compute splus and scross */
  output->eff_dist_h = output->eff_dist_l = 2.0 * output->distance;
  cosiota = cos( output->inclination );
  splus = -( 1.0 + cosiota * cosiota );
  scross = -2.0 * cosiota;

  /* compute the response of the LHO detectors */
  detAndSource.pDetector = &lho;
  LALComputeDetAMResponse( status->statusPtr, &resp, &detAndSource,
      &output->geocent_end_time );
  CHECKSTATUSPTR( status );

  /* compute the effective distance for LHO */
  output->eff_dist_h /= sqrt(
      splus*splus*resp.plus*resp.plus + scross*scross*resp.cross*resp.cross );

  /* compute the response of the LLO detector */
  detAndSource.pDetector = &llo;
  LALComputeDetAMResponse( status->statusPtr, &resp, &detAndSource,
      &output->geocent_end_time );
  CHECKSTATUSPTR( status );

  /* compute the effective distance for LLO */
  output->eff_dist_l /= sqrt(
      splus*splus*resp.plus*resp.plus + scross*scross*resp.cross*resp.cross );


  /*
   *
   * normal exit
   *
   */


  DETATCHSTATUSPTR (status);
  RETURN (status);
}
Exemplo n.º 3
0
void
LALInspiralSiteTimeAndDist(
    LALStatus         *status,
    SimInspiralTable  *output,
    LALDetector       *detector,
    LIGOTimeGPS       *endTime,
    REAL4             *effDist,
    SkyPosition       *skyPos
    )

{
  LALSource             source;
  LALDetAndSource       detAndSource;
  LALDetAMResponse      resp;
  REAL8                 time_diff;
  REAL4                 splus, scross, cosiota;

  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  /* check that the arguments are not null */
  ASSERT( output, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( detector, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( endTime, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( effDist, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( skyPos, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );

  memset( &source, 0, sizeof(LALSource) );
  memset( &detAndSource, 0, sizeof(LALDetAndSource) );

  source.equatorialCoords = *skyPos;
  source.orientation      = output->polarization;

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

  /* initialize end time with geocentric value */
  *endTime = output->geocent_end_time;

  /* calculate the detector end time */
  time_diff = XLALTimeDelayFromEarthCenter( detector->location, skyPos->longitude, skyPos->latitude, &(output->geocent_end_time) );
  XLALGPSAdd(endTime, time_diff);

  /* initialize distance with real distance and compute splus and scross */
  *effDist = 2.0 * output->distance;
  cosiota = cos( output->inclination );
  splus = -( 1.0 + cosiota * cosiota );
  scross = -2.0 * cosiota;

  /* compute the response of the detector */
  LALComputeDetAMResponse( status->statusPtr, &resp, &detAndSource,
      &output->geocent_end_time );
  CHECKSTATUSPTR( status );

  /* compute the effective distance */
  *effDist /= sqrt(
      splus*splus*resp.plus*resp.plus + scross*scross*resp.cross*resp.cross );

  /* normal exit */
  DETATCHSTATUSPTR (status);
  RETURN (status);
}
Exemplo n.º 4
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;
}