Ejemplo n.º 1
0
/* creates a waveform in the frequency domain; the waveform might be generated
 * in the time-domain and transformed */
int create_fd_waveform(COMPLEX16FrequencySeries ** htilde_plus, COMPLEX16FrequencySeries ** htilde_cross, struct params p)
{
    clock_t timer_start = 0;
    double chirplen, deltaF;
    int chirplen_exp;

    /* length of the chirp in samples */
    chirplen = imr_time_bound(p.f_min, p.m1, p.m2, p.s1z, p.s2z) * p.srate;
    /* make chirplen next power of two */
    frexp(chirplen, &chirplen_exp);
    chirplen = ldexp(1.0, chirplen_exp);
    deltaF = p.srate / chirplen;
    if (p.verbose)
        fprintf(stderr, "using frequency resolution deltaF = %g Hz\n", deltaF);

    if (p.condition) {
        if (p.verbose) {
            fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralFD...\n");
            timer_start = clock();
        }
        XLALSimInspiralFD(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
    } else if (p.domain == LAL_SIM_DOMAIN_FREQUENCY) {
        if (p.verbose) {
            fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralChooseFDWaveform...\n");
            timer_start = clock();
        }
        XLALSimInspiralChooseFDWaveform(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
    } else {
        REAL8TimeSeries *h_plus = NULL;
        REAL8TimeSeries *h_cross = NULL;
        REAL8FFTPlan *plan;

        /* generate time domain waveform */
        if (p.verbose) {
            fprintf(stderr, "generating waveform in time domain using XLALSimInspiralChooseTDWaveform...\n");
            timer_start = clock();
        }
        XLALSimInspiralChooseTDWaveform(&h_plus, &h_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, 1.0 / p.srate, p.f_min, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);

        /* resize the waveforms to the required length */
        XLALResizeREAL8TimeSeries(h_plus, h_plus->data->length - (size_t) chirplen, (size_t) chirplen);
        XLALResizeREAL8TimeSeries(h_cross, h_cross->data->length - (size_t) chirplen, (size_t) chirplen);

        /* put the waveform in the frequency domain */
        /* (the units will correct themselves) */
        if (p.verbose) {
            fprintf(stderr, "transforming waveform to frequency domain...\n");
            timer_start = clock();
        }
        *htilde_plus = XLALCreateCOMPLEX16FrequencySeries("htilde_plus", &h_plus->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
        *htilde_cross = XLALCreateCOMPLEX16FrequencySeries("htilde_cross", &h_cross->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
        plan = XLALCreateForwardREAL8FFTPlan((size_t) chirplen, 0);
        XLALREAL8TimeFreqFFT(*htilde_cross, h_cross, plan);
        XLALREAL8TimeFreqFFT(*htilde_plus, h_plus, plan);
        if (p.verbose)
            fprintf(stderr, "transformation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);

        /* clean up */
        XLALDestroyREAL8FFTPlan(plan);
        XLALDestroyREAL8TimeSeries(h_cross);
        XLALDestroyREAL8TimeSeries(h_plus);
    }
    return 0;
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
0
int main(void) {
    clock_t s1, e1, s2, e2;
    double diff1, diff2;
    unsigned int i;
    REAL8 plusdiff, crossdiff, temp;
    REAL8TimeSeries *hplus = NULL;
    REAL8TimeSeries *hcross = NULL;
    REAL8TimeSeries *hplusC = NULL;
    REAL8TimeSeries *hcrossC = NULL;
    COMPLEX16FrequencySeries *hptilde = NULL;
    COMPLEX16FrequencySeries *hctilde = NULL;
    COMPLEX16FrequencySeries *hptildeC = NULL;
    COMPLEX16FrequencySeries *hctildeC = NULL;
    REAL8 m1 = 10. * LAL_MSUN_SI, m2 = 10 * LAL_MSUN_SI;
    REAL8 s1x = 0., s1y = 0., s1z = 0., s2x = 0., s2y = 0., s2z = 0.;
    REAL8 f_min = 40., f_ref = 0., lambda1 = 0., lambda2 = 0.i, f_max = 0.;
    REAL8 dt = 1./16384., df = 1./16.;
    int ret, phaseO = 7, ampO = 0;
    Approximant approx = SEOBNRv1;
    Approximant approxFD = TaylorF2;
    REAL8 phiref1 = 0., phiref2 = 0.3;
    REAL8 inc1 = 0.2, inc2 = 1.3;
    REAL8 dist1 = 1.e6 * LAL_PC_SI, dist2 = 2.e6 * LAL_PC_SI;
    LALSimInspiralWaveformCache *cache = XLALCreateSimInspiralWaveformCache();

    //
    // Test TD path with SEOBNRv1
    //

    // Generate waveform via usual ChooseTDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseTDWaveform(&hplus, &hcross, phiref1, dt, m1, m2,
        s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist1, inc1,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will call ChooseWaveform this 1st time
    s2 = clock();
    ret = XLALSimInspiralChooseTDWaveformFromCache(&hplusC, &hcrossC, phiref1,
        dt, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist1, inc1,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx, cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hplus->data->length; i++)
    {
        temp = abs(hplus->data->data[i] - hplusC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hcross->data->data[i] - hcrossC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseTDWaveform and ChooseTDWaveformFromCache\n");
    printf("when both must be generated from scratch...\n");
    printf("ChooseTDWaveform took %f seconds\n", diff1);
    printf("ChooseTDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    // Generate another waveform via ChooseTDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseTDWaveform(&hplus, &hcross, phiref2, dt, m1, m2,
        s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist2, inc2,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will transform previous waveform
    s2 = clock();
    ret = XLALSimInspiralChooseTDWaveformFromCache(&hplusC, &hcrossC, phiref2,
        dt, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_ref, dist2, inc2,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approx, cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hplus->data->length; i++)
    {
        temp = abs(hplus->data->data[i] - hplusC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hcross->data->data[i] - hcrossC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseTDWaveform and ChooseTDWaveformFromCache\n");
    printf("when the latter is cached and transformed...\n");
    printf("ChooseTDWaveform took %f seconds\n", diff1);
    printf("ChooseTDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    XLALDestroyREAL8TimeSeries(hplus);
    XLALDestroyREAL8TimeSeries(hcross);
    XLALDestroyREAL8TimeSeries(hplusC);
    XLALDestroyREAL8TimeSeries(hcrossC);


    //
    // Test FD path with TaylorF2
    //

    // Generate waveform via usual ChooseFDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde, phiref1, df,
            m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max, dist1, inc1,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will call ChooseWaveform this 1st time
    s2 = clock();
    ret = XLALSimInspiralChooseFDWaveformFromCache(&hptildeC, &hctildeC,
            phiref1, df, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max,
            dist1, inc1, lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD,
            cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hptilde->data->length; i++)
    {
        temp = abs(hptilde->data->data[i] - hptildeC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hctilde->data->data[i] - hctildeC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseFDWaveform and ChooseFDWaveformFromCache\n");
    printf("when both must be generated from scratch...\n");
    printf("ChooseFDWaveform took %f seconds\n", diff1);
    printf("ChooseFDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(hctilde);
    XLALDestroyCOMPLEX16FrequencySeries(hptildeC);
    XLALDestroyCOMPLEX16FrequencySeries(hctildeC);
    hptilde = hctilde = hptildeC = hctildeC = NULL;

    // Generate another waveform via ChooseFDWaveform path
    s1 = clock();
    ret = XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde, phiref2, df,
            m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max, dist2, inc2,
        lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD);
    e1 = clock();
    diff1 = (double) (e1 - s1) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Generate waveform via FromCache - will transform previous waveform
    s2 = clock();
    ret = XLALSimInspiralChooseFDWaveformFromCache(&hptildeC, &hctildeC,
            phiref2, df, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, f_max,
            dist2, inc2, lambda1, lambda2, NULL, NULL, ampO, phaseO, approxFD,
            cache);
    e2 = clock();
    diff2 = (double) (e2 - s2) / CLOCKS_PER_SEC;
    if( ret == XLAL_FAILURE )
        XLAL_ERROR(XLAL_EFUNC);

    // Find level of agreement
    plusdiff = crossdiff = 0.;
    for(i=0; i < hptilde->data->length; i++)
    {
        temp = abs(hptilde->data->data[i] - hptildeC->data->data[i]);
        if(temp > plusdiff) plusdiff = temp;
        temp = abs(hctilde->data->data[i] - hctildeC->data->data[i]);
        if(temp > crossdiff) crossdiff = temp;
    }
    printf("Comparing waveforms from ChooseFDWaveform and ChooseFDWaveformFromCache\n");
    printf("when the latter is cached and transformed...\n");
    printf("ChooseFDWaveform took %f seconds\n", diff1);
    printf("ChooseFDWaveformFromCache took %f seconds\n", diff2);
    printf("Largest difference in plus polarization is: %.16g\n", plusdiff);
    printf("Largest difference in cross polarization is: %.16g\n\n", crossdiff);

    XLALDestroySimInspiralWaveformCache(cache);
    XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(hctilde);
    XLALDestroyCOMPLEX16FrequencySeries(hptildeC);
    XLALDestroyCOMPLEX16FrequencySeries(hctildeC);

    LALCheckMemoryLeaks();

    return 0;
}
Ejemplo n.º 4
0
/*
 * main
 */
int main (int argc , char **argv) {
    FILE *f;
    int status;
    int start_time;
    COMPLEX16FrequencySeries *hptilde = NULL, *hctilde = NULL;
    REAL8TimeSeries *hplus = NULL;
    REAL8TimeSeries *hcross = NULL;
    GSParams *params;

    /* set us up to fail hard */
    XLALSetErrorHandler(XLALAbortErrorHandler);

    /* parse commandline */
    params = parse_args(argc, argv);

    /* generate waveform */
    start_time = time(NULL);
    switch (params->domain) {
    case LAL_SIM_DOMAIN_FREQUENCY:
        XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde, params->phiRef,
                                        params->deltaF, params->m1, params->m2, params->s1x,
                                        params->s1y, params->s1z, params->s2x, params->s2y,
                                        params->s2z, params->f_min, params->f_max, params->fRef,
                                        params->distance, params->inclination, params->lambda1,
                                        params->lambda2, params->waveFlags, params->nonGRparams,
                                        params->ampO, params->phaseO, params->approximant);
        break;
    case LAL_SIM_DOMAIN_TIME:
        XLALSimInspiralChooseTDWaveform(&hplus, &hcross, params->phiRef,
                                        params->deltaT, params->m1, params->m2, params->s1x,
                                        params->s1y, params->s1z, params->s2x, params->s2y,
                                        params->s2z, params->f_min, params->fRef,
                                        params->distance, params->inclination, params->lambda1,
                                        params->lambda2, params->waveFlags,
                                        params->nonGRparams, params->ampO, params->phaseO,
                                        params->approximant);
        break;
    default:
        XLALPrintError("Error: domain must be either TD or FD\n");
    }
    if (params->verbose)
        XLALPrintInfo("Generation took %.0f seconds\n",
                      difftime(time(NULL), start_time));
    if (((params->domain == LAL_SIM_DOMAIN_FREQUENCY) && (!hptilde || !hctilde)) ||
            ((params->domain == LAL_SIM_DOMAIN_TIME) && (!hplus || !hcross))) {
        XLALPrintError("Error: waveform generation failed\n");
        goto fail;
    }

    /* dump file */
    if ( strlen(params->outname) > 0 ) {
        f = fopen(params->outname, "w");
        if (f==NULL) {
            printf("**ERROR** Impossible to write file %s\n",params->outname);
            exit(1);
        }
        else {
            if (params->domain == LAL_SIM_DOMAIN_FREQUENCY)
                if (params->ampPhase == 1)
                    status = dump_FD2(f, hptilde, hctilde);
                else
                    status = dump_FD(f, hptilde, hctilde);
            else if (params->ampPhase == 1)
                status = dump_TD2(f, hplus, hcross);
            else
                status = dump_TD(f, hplus, hcross);
            fclose(f);
        }
        if (status) goto fail;
    }

    /* clean up */
    XLALSimInspiralDestroyWaveformFlags(params->waveFlags);
    XLALSimInspiralDestroyTestGRParam(params->nonGRparams);
    XLALFree(params);
    XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(hctilde);
    return 0;

fail:
    XLALSimInspiralDestroyWaveformFlags(params->waveFlags);
    XLALSimInspiralDestroyTestGRParam(params->nonGRparams);
    XLALFree(params);
    XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    XLALDestroyCOMPLEX16FrequencySeries(hctilde);
    return 1;
}
/**
 * Chooses between different approximants when requesting a waveform to be generated
 * Returns the waveform in the frequency domain.
 * The parameters passed must be in SI units.
 *
 * This version allows caching of waveforms. The most recently generated
 * waveform and its parameters are stored. If the next call requests a waveform
 * that can be obtained by a simple transformation, then it is done.
 * This bypasses the waveform generation and speeds up the code.
 */
int XLALSimInspiralChooseFDWaveformFromCache(
        COMPLEX16FrequencySeries **hptilde,     /**< +-polarization waveform */
        COMPLEX16FrequencySeries **hctilde,     /**< x-polarization waveform */
        REAL8 phiRef,                           /**< reference orbital phase (rad) */
        REAL8 deltaF,                           /**< sampling interval (Hz) */
        REAL8 m1,                               /**< mass of companion 1 (kg) */
        REAL8 m2,                               /**< mass of companion 2 (kg) */
        REAL8 S1x,                              /**< x-component of the dimensionless spin of object 1 */
        REAL8 S1y,                              /**< y-component of the dimensionless spin of object 1 */
        REAL8 S1z,                              /**< z-component of the dimensionless spin of object 1 */
        REAL8 S2x,                              /**< x-component of the dimensionless spin of object 2 */
        REAL8 S2y,                              /**< y-component of the dimensionless spin of object 2 */
        REAL8 S2z,                              /**< z-component of the dimensionless spin of object 2 */
        REAL8 f_min,                            /**< starting GW frequency (Hz) */
        REAL8 f_max,                            /**< ending GW frequency (Hz) */
        REAL8 f_ref,                            /**< Reference GW frequency (Hz) */
        REAL8 r,                                /**< distance of source (m) */
        REAL8 i,                                /**< inclination of source (rad) */
        LALDict *LALpars,                       /**< LALDictionary containing non-mandatory variables/flags */
        Approximant approximant,                /**< post-Newtonian approximant to use for waveform production */
        LALSimInspiralWaveformCache *cache,     /**< waveform cache structure */
        REAL8Sequence *frequencies              /**< sequence of frequencies for which the waveform will be computed. Pass in NULL (or None in python) for standard f_min to f_max sequence. */
        )
{
    int status;
    size_t j;
    REAL8 dist_ratio, incl_ratio_plus, incl_ratio_cross, phase_diff;
    COMPLEX16 exp_dphi;
    CacheVariableDiffersBitmask changedParams;


    // If nonGRparams are not NULL, don't even try to cache.
    if ( !XLALSimInspiralWaveformParamsNonGRAreDefault(LALpars) || (!cache) ) {
        if (frequencies != NULL)
            return XLALSimInspiralChooseFDWaveformSequence(hptilde, hctilde, phiRef,
                                                           m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_ref,
                                                           r, i,
                                                           LALpars, approximant,frequencies);
        else
            return XLALSimInspiralChooseFDWaveform(hptilde, hctilde, m1, m2,
				S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef,
				0., 0., 0., deltaF, f_min, f_max, f_ref,
				LALpars,
				approximant);
    }

    // Check which parameters have changed
    changedParams = CacheArgsDifferenceBitmask(cache, phiRef, deltaF,
            m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, f_max, r, i,
	    LALpars, approximant, frequencies);

    // No parameters have changed! Copy the cached polarizations
    if( changedParams == NO_DIFFERENCE ) {
        *hptilde = XLALCutCOMPLEX16FrequencySeries(cache->hptilde, 0,
                cache->hptilde->data->length);
        if (*hptilde == NULL) return XLAL_ENOMEM;
        *hctilde = XLALCutCOMPLEX16FrequencySeries(cache->hctilde, 0,
                cache->hctilde->data->length);
        if (*hctilde == NULL) {
            XLALDestroyCOMPLEX16FrequencySeries(*hptilde);
            *hptilde = NULL;
            return XLAL_ENOMEM;
        }

        return XLAL_SUCCESS;
    }

    // Intrinsic parameters have changed. We must generate a new waveform
    if( (changedParams & INTRINSIC) != 0 ) {
        if ( frequencies != NULL ){
            status =  XLALSimInspiralChooseFDWaveformSequence(hptilde, hctilde, phiRef,
                m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_ref,
	        r, i, LALpars, approximant, frequencies);
        }
        else {
	  status = XLALSimInspiralChooseFDWaveform(hptilde, hctilde, m1, m2,
						   S1x, S1y, S1z, S2x, S2y, S2z,
						   r, i, phiRef, 0., 0., 0.,
						   deltaF, f_min, f_max, f_ref,
						   LALpars, approximant);
        }
        if (status == XLAL_FAILURE) return status;

        return StoreFDHCache(cache, *hptilde, *hctilde, phiRef, deltaF, m1, m2,
			     S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, f_max, r, i, LALpars, approximant, frequencies);
    }

    // case 1: Non-precessing, 2nd harmonic only
    if( approximant == TaylorF2 || approximant == TaylorF2RedSpin
                || approximant == TaylorF2RedSpinTidal
                || approximant == IMRPhenomA || approximant == IMRPhenomB
                || approximant == IMRPhenomC ) {
        // If polarizations are not cached we must generate a fresh waveform
        // FIXME: Will need to check hlms and/or dynamical variables as well
        if( cache->hptilde == NULL || cache->hctilde == NULL) {
            if ( frequencies != NULL ){
                status =  XLALSimInspiralChooseFDWaveformSequence(hptilde, hctilde, phiRef,
                    m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_ref,
		    r, i, LALpars, approximant,frequencies);
            }
            else {
	      status = XLALSimInspiralChooseFDWaveform(hptilde, hctilde, m1, m2,
						       S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef,
						       0., 0., 0., deltaF, f_min, f_max, f_ref,
						       LALpars, approximant);
            }
            if (status == XLAL_FAILURE) return status;

            return StoreFDHCache(cache, *hptilde, *hctilde, phiRef, deltaF,
                    m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, f_max, r, i,
                    LALpars, approximant, frequencies);
        }

        // Set transformation coefficients for identity transformation.
        // We'll adjust them depending on which extrinsic parameters changed.
        dist_ratio = incl_ratio_plus = incl_ratio_cross = 1.;
        phase_diff = 0.;
        exp_dphi = 1.;

        if( changedParams & PHI_REF ) {
            // Only 2nd harmonic present, so {h+,hx} \propto e^(2 i phiRef)
            phase_diff = 2.*(phiRef - cache->phiRef);
            exp_dphi = cpolar(1., phase_diff);
        }
        if( changedParams & INCLINATION) {
            // Rescale h+, hx by ratio of new/old inclination dependence
            incl_ratio_plus = (1.0 + cos(i)*cos(i))
                    / (1.0 + cos(cache->i)*cos(cache->i));
            incl_ratio_cross = cos(i) / cos(cache->i);
        }
        if( changedParams & DISTANCE ) {
            // Rescale h+, hx by ratio of (1/new_dist)/(1/old_dist) = old/new
            dist_ratio = cache->r / r;
        }

        // Create the output polarizations
        *hptilde = XLALCreateCOMPLEX16FrequencySeries(cache->hptilde->name,
                &(cache->hptilde->epoch), cache->hptilde->f0,
                cache->hptilde->deltaF, &(cache->hptilde->sampleUnits),
                cache->hptilde->data->length);
        if (*hptilde == NULL) return XLAL_ENOMEM;

        *hctilde = XLALCreateCOMPLEX16FrequencySeries(cache->hctilde->name,
                &(cache->hctilde->epoch), cache->hctilde->f0,
                cache->hctilde->deltaF, &(cache->hctilde->sampleUnits),
                cache->hctilde->data->length);
        if (*hctilde == NULL) {
            XLALDestroyCOMPLEX16FrequencySeries(*hptilde);
            *hptilde = NULL;
            return XLAL_ENOMEM;
        }

        // Get new polarizations by transforming the old
        incl_ratio_plus *= dist_ratio;
        incl_ratio_cross *= dist_ratio;
        for (j = 0; j < cache->hptilde->data->length; j++) {
            (*hptilde)->data->data[j] = exp_dphi * incl_ratio_plus
                    * cache->hptilde->data->data[j];
            (*hctilde)->data->data[j] = exp_dphi * incl_ratio_cross
                    * cache->hctilde->data->data[j];
        }

        return XLAL_SUCCESS;
    }

    // case 2: Precessing
    /*else if( approximant == SpinTaylorF2 ) {

    }*/

    // Catch-all. Unsure what to do, don't try to cache.
    // Basically, you requested a waveform type which is not setup for caching
    // b/c of lack of interest or it's unclear what/how to cache for that model
    else {
        if ( frequencies != NULL ){
            return XLALSimInspiralChooseFDWaveformSequence(hptilde, hctilde, phiRef,
                    m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_ref,
                    r, i, LALpars, approximant,frequencies);
        }
        else {
	  return XLALSimInspiralChooseFDWaveform(hptilde, hctilde, m1, m2,
						 S1x, S1y, S1z, S2x, S2y, S2z,
						 r, i, phiRef, 0., 0., 0.,
						 deltaF, f_min, f_max, f_ref,
						 NULL, approximant);
        }
    }

}