/* Parse command line, sanity check arguments, and return a newly * allocated GSParams object */ static GSParams *parse_args(ssize_t argc, char **argv) { ssize_t i; GSParams *params; params = (GSParams *) XLALMalloc(sizeof(GSParams)); memset(params, 0, sizeof(GSParams)); /* Set default values to the arguments */ params->waveFlags = XLALSimInspiralCreateWaveformFlags(); params->nonGRparams = NULL; params->approximant = TaylorT1; params->domain = LAL_SIM_DOMAIN_TIME; params->phaseO = 7; params->ampO = 0; params->phiRef = 0.; params->deltaT = 1./4096.; params->deltaF = 0.125; params->m1 = 10. * LAL_MSUN_SI; params->m2 = 1.4 * LAL_MSUN_SI; params->f_min = 40.; params->fRef = 0.; params->f_max = 0.; /* Generate as much as possible */ params->distance = 100. * 1e6 * LAL_PC_SI; params->inclination = 0.; params->s1x = 0.; params->s1y = 0.; params->s1z = 0.; params->s2x = 0.; params->s2y = 0.; params->s2z = 0.; params->lambda1 = 0.; params->lambda2 = 0.; strncpy(params->outname, "simulation.dat", 256); /* output to this file */ params->ampPhase = 0; /* output h+ and hx */ params->verbose = 0; /* No verbosity */ /* consume command line */ for (i = 1; i < argc; ++i) { if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { printf("%s", usage); XLALFree(params); exit(0); } else if (strcmp(argv[i], "--verbose") == 0) { params->verbose = 1; } else if (strcmp(argv[i], "--amp-phase") == 0) { params->ampPhase = 1; } else if ( ( i == argc ) || ( !argv[i+1] ) ) { XLALPrintError("Error: value required for option %s\n", argv[i]); } else if (strcmp(argv[i], "--approximant") == 0) { params->approximant = XLALSimInspiralGetApproximantFromString(argv[++i]); if ( (int) params->approximant == XLAL_FAILURE) { XLALPrintError("Error: invalid value %s for --interaction-flag\n", argv[i]); goto fail; } } else if (strcmp(argv[i], "--domain") == 0) { i++; if (strcmp(argv[i], "TD") == 0) params->domain = LAL_SIM_DOMAIN_TIME; else if (strcmp(argv[i], "FD") == 0) params->domain = LAL_SIM_DOMAIN_FREQUENCY; else { XLALPrintError("Error: Unknown domain\n"); goto fail; } } else if (strcmp(argv[i], "--phase-order") == 0) { params->phaseO = atoi(argv[++i]); } else if (strcmp(argv[i], "--amp-order") == 0) { params->ampO = atoi(argv[++i]); } else if (strcmp(argv[i], "--phiRef") == 0) { params->phiRef = atof(argv[++i]); } else if (strcmp(argv[i], "--fRef") == 0) { params->fRef = atof(argv[++i]); } else if (strcmp(argv[i], "--sample-rate") == 0) { params->deltaT = 1./atof(argv[++i]); } else if (strcmp(argv[i], "--deltaF") == 0) { params->deltaF = atof(argv[++i]); } else if (strcmp(argv[i], "--m1") == 0) { params->m1 = atof(argv[++i]) * LAL_MSUN_SI; } else if (strcmp(argv[i], "--m2") == 0) { params->m2 = atof(argv[++i]) * LAL_MSUN_SI; } else if (strcmp(argv[i], "--spin1x") == 0) { params->s1x = atof(argv[++i]); } else if (strcmp(argv[i], "--spin1y") == 0) { params->s1y = atof(argv[++i]); } else if (strcmp(argv[i], "--spin1z") == 0) { params->s1z = atof(argv[++i]); } else if (strcmp(argv[i], "--spin2x") == 0) { params->s2x = atof(argv[++i]); } else if (strcmp(argv[i], "--spin2y") == 0) { params->s2y = atof(argv[++i]); } else if (strcmp(argv[i], "--spin2z") == 0) { params->s2z = atof(argv[++i]); } else if (strcmp(argv[i], "--tidal-lambda1") == 0) { params->lambda1 = atof(argv[++i]); } else if (strcmp(argv[i], "--tidal-lambda2") == 0) { params->lambda2 = atof(argv[++i]); } else if (strcmp(argv[i], "--spin-order") == 0) { XLALSimInspiralSetSpinOrder( params->waveFlags, atoi(argv[++i]) ); } else if (strcmp(argv[i], "--tidal-order") == 0) { XLALSimInspiralSetTidalOrder( params->waveFlags, atoi(argv[++i]) ); } else if (strcmp(argv[i], "--f-min") == 0) { params->f_min = atof(argv[++i]); } else if (strcmp(argv[i], "--f-max") == 0) { params->f_max = atof(argv[++i]); } else if (strcmp(argv[i], "--distance") == 0) { params->distance = atof(argv[++i]) * 1e6 * LAL_PC_SI; } else if (strcmp(argv[i], "--inclination") == 0) { params->inclination = atof(argv[++i]); } else if (strcmp(argv[i], "--axis") == 0) { XLALSimInspiralSetFrameAxis( params->waveFlags, XLALGetFrameAxisFromString(argv[++i]) ); if ( (int) XLALSimInspiralGetFrameAxis(params->waveFlags) == (int) XLAL_FAILURE) { XLALPrintError("Error: invalid value %s for --axis\n", argv[i]); goto fail; } } else if (strcmp(argv[i], "--modes") == 0) { XLALSimInspiralSetModesChoice( params->waveFlags, XLALGetHigherModesFromString(argv[++i]) ); if ( (int) XLALSimInspiralGetModesChoice(params->waveFlags) == (int) XLAL_FAILURE) { XLALPrintError("Error: invalid value %s for --modes\n", argv[i]); goto fail; } } else if (strcmp(argv[i], "--nonGRpar") == 0) { char name[100]; strcpy(name,argv[++i]); if ( ( i == argc ) || ( !argv[i+1] ) ) { XLALPrintError("Error: 'name value' pair required for option %s\n", argv[i-1]); } else if (params->nonGRparams==NULL) { params->nonGRparams=XLALSimInspiralCreateTestGRParam(name,atof(argv[++i])); } else { XLALSimInspiralAddTestGRParam(¶ms->nonGRparams,name,atof(argv[++i])); } } else if (strcmp(argv[i], "--outname") == 0) { strncpy(params->outname, argv[++i], 256); } else { XLALPrintError("Error: invalid option: %s\n", argv[i]); goto fail; } } return params; fail: printf("%s", usage); XLALFree(params); exit(1); }
int main(void) { static LALStatus mystatus; /* variables for timing purposes */ clock_t start, diff; int msec; REAL4TimeSeries *h_plus; REAL4TimeSeries *h_cross; REAL8TimeSeries *hplus; REAL8TimeSeries *hcross; InspiralTemplate params; FILE *outputfile; INT4 i,length; REAL8 dt, m, m1, m2, nu, lambda1, lambda2; LIGOTimeGPS tc = LIGOTIMEGPSZERO; memset( &mystatus, 0, sizeof(LALStatus) ); memset( ¶ms, 0, sizeof(InspiralTemplate) ); m1 = 5.; m2 = 5.; m = m1 + m2; nu = m1 * m2 / m / m; lambda1 = 0.; lambda2 = 0.; LALSimInspiralWaveformFlags *waveFlags; waveFlags = XLALSimInspiralCreateWaveformFlags(); params.approximant = TaylorT4; params.order = LAL_PNORDER_THREE_POINT_FIVE; params.ampOrder = LAL_PNORDER_NEWTONIAN; params.mass1 = m1; params.mass2 = m2; params.totalMass = m; params.eta = nu; params.tSampling = 4096; params.fCutoff = 2047.; params.fLower = 40.; params.distance = 1e6 * LAL_PC_SI; params.ieta = 1; dt = 1. / params.tSampling; start = clock(); length = XLALSimInspiralTaylorT4PNRestricted(&hplus, &hcross, 0., dt, params.mass1*LAL_MSUN_SI, params.mass2*LAL_MSUN_SI, params.fLower, 0., params.distance, lambda1, lambda2, XLALSimInspiralGetTidalOrder(waveFlags), 0, 7); diff = clock() - start; msec = diff * 1000 / CLOCKS_PER_SEC; printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000); fprintf(stderr, "length = %i\n", length); fprintf(stderr, "T = %f\n", (float) length * dt); outputfile = fopen("T4wave1.dat","w"); length = hplus->data->length; for(i = 0; i < length; i++) { fprintf(outputfile,"%e\t%e\t%e\n", i*dt, hplus->data->data[i], hcross->data->data[i]); } fclose(outputfile); fprintf(stdout,"waveform saved in T4wave1.dat\n" ); start = clock(); h_plus = XLALCreateREAL4TimeSeries("", &tc, 0.0, dt, &lalDimensionlessUnit, 4096*3); h_cross = XLALCreateREAL4TimeSeries("", &tc, 0.0, dt, &lalDimensionlessUnit, 4096*3); fprintf(stderr, "Lower cut-off frequency used will be %fHz\n", params.fLower); /* --- now we can call the injection function --- */ LALTaylorT4WaveformTemplates(&mystatus, h_plus->data, h_cross->data, ¶ms); diff = clock() - start; msec = diff * 1000 / CLOCKS_PER_SEC; printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000); if ( mystatus.statusCode ) { fprintf( stderr, "LALInspiralTaylorT4Test: error generating waveform\n" ); exit( 1 ); } /* --- and finally save in a file --- */ outputfile = fopen("T4wave2.dat","w"); length = h_plus->data->length; for(i = 0; i < length; i++) { fprintf(outputfile,"%e\t%e\t%e\n", i*dt, h_plus->data->data[i], h_cross->data->data[i]); } fclose(outputfile); fprintf(stdout,"waveform saved in T4wave2.dat\n" ); return 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 */ lambda1=0.0,lambda2=0.0; LALSimInspiralWaveformFlags *waveFlags= XLALSimInspiralCreateWaveformFlags(); /* 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); */ /* When nonGR terms stored in the table, we can add them here. (If they are only phase deformations, they won't change the SNR though) */ LALSimInspiralTestGRParam *nonGRparams=NULL; /* Linked list of non-GR parameters. Pass in NULL (or None in python) for standard GR waveforms */ LALPNOrder order; /* Phase order of the model */ INT4 amporder=0; order = XLALGetOrderFromString(inj->waveform); amporder = 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=start_freq; 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; XLAL_TRY(ret=XLALSimInspiralChooseFDWaveform(&hptilde,&hctilde, phi0, deltaF, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, 0.0, 0.0, LAL_PC_SI * 1.0e6, iota, lambda1, lambda2, waveFlags, nonGRparams, amporder, order, approx),errnum ); 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, phi0, deltaT, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, 0., LAL_PC_SI*1.0e6, iota, lambda1, lambda2, waveFlags, nonGRparams, amporder, order, approx), errnum); if (ret == XLAL_FAILURE || hplus == NULL || hcross == NULL) { XLALPrintError(" ERROR in XLALSimInspiralChooseTDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum ); exit(1); } 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(f_min / 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; 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 (waveFlags) XLALSimInspiralDestroyWaveformFlags(waveFlags); if (nonGRparams) XLALSimInspiralDestroyTestGRParam(nonGRparams); if (detector) free(detector); return sqrt(this_snr*2.0); }