int main(void) { REAL8TimeSeries *conv, *data, *response, *exactConv; const UINT4 N = 101; const LIGOTimeGPS zero = {0, 0}; UINT4 i; conv = XLALCreateREAL8TimeSeries("FFT Convolution", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); data = XLALCreateREAL8TimeSeries("data", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); response = XLALCreateREAL8TimeSeries("response function", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); exactConv = XLALCreateREAL8TimeSeries("exact convolution", &zero, 0.0, 0.01, &lalDimensionlessUnit, N); data->data->data[0] = 1.0; for (i = 1; i < N; i++) { /* Data is 1/i */ data->data->data[i] = 1.0 / i; } response->data->data[0] = 1.0; for (i = 1; i <= (N-1)/2; i++) { response->data->data[i] = exp(-(i/10.0)); /* Decaying exponential with time constant 10. */ response->data->data[N-i] = exp(-(i/10.0)); /* Same in the negative, wrapped dimension. */ } if (N % 2 == 0) { response->data->data[N/2] = exp(-(N/20.0)); } /* Exact, O(N^2) convolution */ for (i = 0; i < N; i++) { REAL8 sum = 0.0; UINT4 j; for (j = MAX_INT(0, ((int)i)-((int) N/2)); j <= MIN_INT(i+N/2, N-1); j++) { UINT4 rIndex = (j > i ? i + (N - j) : i - j); sum += data->data->data[j]*response->data->data[rIndex]; } exactConv->data->data[i] = sum; } convolveTimeSeries(conv, data, response); for (i = 0; i < N; i++) { if (fabs(exactConv->data->data[i] - conv->data->data[i]) > 1e-8) { fprintf(stderr, "Index %d differs (exact = %g, FFT = %g)\n", i, exactConv->data->data[i], conv->data->data[i]); } } XLALDestroyREAL8TimeSeries(conv); XLALDestroyREAL8TimeSeries(data); XLALDestroyREAL8TimeSeries(response); XLALDestroyREAL8TimeSeries(exactConv); return 0; }
/** * Window and IFFT a FD waveform to TD, then window in TD. * Requires that the FD waveform be generated outside of f_min and f_max. * FD waveform is modified. */ static int FDToTD(REAL8TimeSeries **signalTD, const COMPLEX16FrequencySeries *signalFD, const REAL8 totalMass, const REAL8 deltaT, const REAL8 f_min, const REAL8 f_max, const REAL8 f_min_wide, const REAL8 f_max_wide) { const LIGOTimeGPS gpstime_zero = {0, 0}; const size_t nf = signalFD->data->length; const size_t nt = 2 * (nf - 1); /* Calculate the expected lengths of the FD and TD vectors from the * deltaF and deltaT passed in to this function */ //const size_t exp_nt = (size_t) 1. / (signalFD->deltaF * deltaT); //const size_t exp_nf = (exp_nt / 2) + 1; const REAL8 windowLength = 20. * totalMass * LAL_MTSUN_SI / deltaT; const REAL8 winFLo = 0.2*f_min_wide + 0.8*f_min; /* frequency used for tapering, slightly less than f_min to minimize FFT artifacts * equivalent to winFLo = f_min_wide + 0.8*(f_min - f_min_wide) */ REAL8 winFHi = f_max_wide; COMPLEX16 *FDdata = signalFD->data->data; REAL8FFTPlan *revPlan; REAL8 *TDdata; size_t k; /* check inputs */ if (f_min_wide >= f_min) XLAL_ERROR(XLAL_EDOM); /* apply the softening window function */ if (winFHi > 0.5 / deltaT) winFHi = 0.5 / deltaT; for (k = nf;k--;) { const REAL8 f = k / (deltaT * nt); REAL8 softWin = PlanckTaper(f, f_min_wide, winFLo) * (1.0 - PlanckTaper(f, f_max, winFHi)); FDdata[k] *= softWin; } /* allocate output */ *signalTD = XLALCreateREAL8TimeSeries("h", &gpstime_zero, 0.0, deltaT, &lalStrainUnit, nt); /* Inverse Fourier transform */ revPlan = XLALCreateReverseREAL8FFTPlan(nt, 1); if (!revPlan) { XLALDestroyREAL8TimeSeries(*signalTD); *signalTD = NULL; XLAL_ERROR(XLAL_EFUNC); } XLALREAL8FreqTimeFFT(*signalTD, signalFD, revPlan); XLALDestroyREAL8FFTPlan(revPlan); if (!(*signalTD)) XLAL_ERROR(XLAL_EFUNC); /* apply a linearly decreasing window at the end * of the waveform in order to avoid edge effects. */ if (windowLength > (*signalTD)->data->length) XLAL_ERROR(XLAL_ERANGE); TDdata = (*signalTD)->data->data; for (k = windowLength; k--;) TDdata[nt-k-1] *= k / windowLength; return XLAL_SUCCESS; }
int main(int argc, char *argv[]) { char tstr[32]; // string to hold GPS time -- 31 characters is enough const double H0 = 0.72 * LAL_H0FAC_SI; // Hubble's constant in seconds const size_t length = 65536; // number of points in a segment const size_t stride = length / 2; // number of points in a stride size_t i, n; REAL8FrequencySeries *OmegaGW = NULL; REAL8TimeSeries **seg = NULL; LIGOTimeGPS epoch; gsl_rng *rng; XLALSetErrorHandler(XLALAbortErrorHandler); parseargs(argc, argv); XLALGPSSetREAL8(&epoch, tstart); gsl_rng_env_setup(); rng = gsl_rng_alloc(gsl_rng_default); OmegaGW = XLALSimSGWBOmegaGWFlatSpectrum(Omega0, flow, srate/length, length/2 + 1); n = duration * srate; seg = LALCalloc(numDetectors, sizeof(*seg)); printf("# time (s)"); for (i = 0; i < numDetectors; ++i) { char name[LALNameLength]; snprintf(name, sizeof(name), "%s:STRAIN", detectors[i].frDetector.prefix); seg[i] = XLALCreateREAL8TimeSeries(name, &epoch, 0.0, 1.0/srate, &lalStrainUnit, length); printf("\t%s (strain)", name); } printf("\n"); XLALSimSGWB(seg, detectors, numDetectors, 0, OmegaGW, H0, rng); // first time to initilize while (1) { // infinite loop size_t j; for (j = 0; j < stride; ++j, --n) { // output first stride points LIGOTimeGPS t = seg[0]->epoch; if (n == 0) // check if we're done goto end; printf("%s", XLALGPSToStr(tstr, XLALGPSAdd(&t, j * seg[0]->deltaT))); for (i = 0; i < numDetectors; ++i) printf("\t%e", seg[i]->data->data[j]); printf("\n"); } XLALSimSGWB(seg, detectors, numDetectors, stride, OmegaGW, H0, rng); // make more data } end: for (i = 0; i < numDetectors; ++i) XLALDestroyREAL8TimeSeries(seg[i]); XLALFree(seg); XLALDestroyREAL8FrequencySeries(OmegaGW); LALCheckMemoryLeaks(); return 0; }
int main(int argc, char *argv[]) { const double H0 = 0.72 * LAL_H0FAC_SI; // Hubble's constant in seconds const double srate = 16384.0; // sampling rate in Hertz const size_t length = 65536; // number of points in a segment const size_t stride = length / 2; // number of points in a stride size_t i, n; REAL8FrequencySeries *OmegaGW = NULL; REAL8TimeSeries **seg = NULL; LIGOTimeGPS epoch; gsl_rng *rng; XLALSetErrorHandler(XLALAbortErrorHandler); parseargs(argc, argv); XLALGPSSetREAL8(&epoch, tstart); gsl_rng_env_setup(); rng = gsl_rng_alloc(gsl_rng_default); OmegaGW = XLALSimSGWBOmegaGWFlatSpectrum(Omega0, flow, srate/length, length/2 + 1); n = duration * srate; seg = LALCalloc(numDetectors, sizeof(*seg)); for (i = 0; i < numDetectors; ++i) seg[i] = XLALCreateREAL8TimeSeries("STRAIN", &epoch, 0.0, 1.0/srate, &lalStrainUnit, length); XLALSimSGWB(seg, detectors, numDetectors, 0, OmegaGW, H0, rng); // first time to initilize while (1) { // infinite loop double t0 = XLALGPSGetREAL8(&seg[0]->epoch); size_t j; for (j = 0; j < stride; ++j, --n) { // output first stride points if (n == 0) // check if we're done goto end; printf("%.9f", t0 + j * seg[0]->deltaT); for (i = 0; i < numDetectors; ++i) printf("\t%e", seg[i]->data->data[j]); printf("\n"); } XLALSimSGWB(seg, detectors, numDetectors, stride, OmegaGW, H0, rng); // make more data } end: for (i = 0; i < numDetectors; ++i) XLALDestroyREAL8TimeSeries(seg[i]); XLALFree(seg); XLALDestroyREAL8FrequencySeries(OmegaGW); LALCheckMemoryLeaks(); return 0; }
void XLALSimInjectNinjaSignals( REAL4TimeSeries* chan, const char *ifo, REAL8 dynRange, SimInspiralTable* events ) { /* New REAL8, NINJA-2 code */ UINT4 j; SimInspiralTable *thisInj = NULL; REAL8TimeSeries *tempStrain = NULL; REAL8TimeSeries *tempChan = NULL; /* Make a REAL8 version of the channel data */ /* so we can call Jolien's new inject function */ tempChan = XLALCreateREAL8TimeSeries( chan->name, &(chan->epoch), chan->f0, chan->deltaT, &(chan->sampleUnits), chan->data->length); for ( j = 0 ; j < tempChan->data->length ; ++j ) { tempChan->data->data[j] = (REAL8) ( chan->data->data[j] ); } /* loop over injections */ for ( thisInj = events; thisInj; thisInj = thisInj->next ) { tempStrain = XLALNRInjectionStrain(ifo, thisInj); for ( j = 0 ; j < tempStrain->data->length ; ++j ) { tempStrain->data->data[j] *= dynRange; } XLALSimAddInjectionREAL8TimeSeries( tempChan, tempStrain, NULL); XLALDestroyREAL8TimeSeries(tempStrain); } /* loop over injections */ /* Back to REAL4 */ for ( j = 0 ; j < tempChan->data->length ; ++j ) { chan->data->data[j] = (REAL4) ( tempChan->data->data[j] ); } XLALDestroyREAL8TimeSeries(tempChan); }
int main(void) { size_t len=100; double dt=0.02; double drift=0.0; REAL8Sequence *sample_time = XLALCreateREAL8Sequence(len); size_t i=0; sample_time->data[0] = dt*i; for(i=1; i<len; i++) { sample_time->data[i] = dt*i+drift; drift += 1e-3; } double frequency = 20.0 / 2 / 3.14159; //FILE* fref = fopen( "fref.txt", "w" ); REAL8Sequence *fcn = XLALCreateREAL8Sequence(len); for(i=0; i<len; i++) { fcn->data[i] = sin( sample_time->data[i] * frequency ); //fprintf( fref, "%f %f\n", sample_time->data[i], fcn->data[i] ); } //fclose(fref); LIGOTimeGPS ep = {0, 0}; REAL8TimeSeries *ts = XLALCreateREAL8TimeSeries("intrp test", &ep, 0.0, dt*0.9, &lalDimensionlessUnit, len); int ret = XLALREAL8TimeSeriesInterpolation(ts, fcn, sample_time, NULL, len, gsl_interp_cspline); REAL8 start = XLALGPSGetREAL8(&ts->epoch); REAL8 tolerance = 1e-6; //FILE* fout = fopen( "fout.txt", "w" ); for(i=0; i<ts->data->length; i++) { REAL8 t = ts->deltaT * i + start; REAL8 fcnval = sin(frequency*t); REAL8 diff = fabs(ts->data->data[i] - fcnval); //fprintf( fout, "%f %f %f\n", t, fcnval, ts->data->data[i] ); if (diff > tolerance) { fprintf(stderr, "%f %g\n", t, diff); return -1; } } //fclose(fout); return ret; }
/*--------------main function---------------*/ int main(int argc, char **argv){ const CHAR *fn = __func__; InputParams XLAL_INIT_DECL(inputs); REAL8 srate = 16384.0; /*sample rate defaulted to 16384 */ /* read in command line input args */ ReadInput( &inputs, argc, argv ); LALStatus XLAL_INIT_DECL(status); EphemerisData *edat; if ( (edat = InitEphemeris ( inputs.ephemType, inputs.ephemDir)) == NULL ){ XLALPrintError ( "%s: Failed to init ephemeris data\n", fn ); XLAL_ERROR ( XLAL_EFUNC ); } /*init detector info */ LALDetector *site; if ( ( site = XLALGetSiteInfo ( inputs.det )) == NULL ){ XLALPrintError("%s: Failed to get site-info for detector '%s'\n", fn, inputs.det ); XLAL_ERROR ( XLAL_EFUNC ); } if( inputs.geocentre ){ /* set site to the geocentre */ site->location[0] = 0.0; site->location[1] = 0.0; site->location[2] = 0.0; } struct dirent **pulsars; INT4 n=scandir(inputs.pulsarDir, &pulsars, 0, alphasort); if ( n < 0){ XLALPrintError("scandir failed\n"); XLAL_ERROR(XLAL_EIO); } UINT4 numpulsars = (UINT4)n; UINT4 h=0; CHAR parname[256]; PulsarParameters *pulparams[numpulsars]; for(h=2; h<numpulsars; h++){ if(strstr(pulsars[h]->d_name,".par") == NULL){ free(pulsars[h]); continue; } else{ sprintf(parname,"%s/%s", inputs.pulsarDir, pulsars[h]->d_name); fprintf(stderr, "%s\n", parname); FILE *inject; if (( inject = fopen ( parname, "r" )) == NULL ){ fprintf(stderr,"Error opening file: %s\n", parname); XLAL_ERROR ( XLAL_EIO ); } pulparams[h] = XLALReadTEMPOParFile( parname ); fclose( inject ); } } LIGOTimeGPS epoch; UINT4 ndata; epoch.gpsSeconds = inputs.epoch; epoch.gpsNanoSeconds = 0; ndata = inputs.frDur; REAL8TimeSeries *series=NULL; CHAR out_file[256]; sprintf(out_file, "%s-%s-%d-%d.gwf", inputs.det, inputs.outStr, epoch.gpsSeconds, ndata ); LALFrameH *outFrame = NULL; if ((outFrame = XLALFrameNew( &epoch, (REAL8)ndata, inputs.channel, 1, 0, 0 )) == NULL) { LogPrintf(LOG_CRITICAL, "%s : XLALFrameNew() filed with error = %d.\n", fn, xlalErrno); XLAL_ERROR( XLAL_EFAILED); } if ((series = XLALCreateREAL8TimeSeries( inputs.channel, &epoch, 0., 1./srate,&lalSecondUnit, (int)(ndata*srate) )) == NULL) { XLAL_ERROR( XLAL_EFUNC ); } UINT4 counter=0; for (counter = 0; counter < series->data->length; counter++) series->data->data[counter] = 0; /*** Read Pulsar Data ***/ for (h=0; h < numpulsars; h++){ if(strstr(pulsars[h]->d_name,".par")==NULL){ free(pulsars[h]); continue; } else{ PulsarSignalParams XLAL_INIT_DECL(params); /* set signal generation barycenter delay look-up table step size */ params.dtDelayBy2 = 10.; /* generate table every 10 seconds */ if (( params.pulsar.spindown = XLALCreateREAL8Vector(1)) == NULL ){ XLALPrintError("Out of memory"); XLAL_ERROR ( XLAL_EFUNC ); } INT4 dtpos = 0; if ( PulsarCheckParam(pulparams[h], "POSEPOCH") ) dtpos = epoch.gpsSeconds - (INT4)PulsarGetREAL8Param(pulparams[h], "POSEPOCH"); else dtpos = epoch.gpsSeconds - (INT4)PulsarGetREAL8Param(pulparams[h], "PEPOCH"); REAL8 ra = 0., dec = 0.; if ( PulsarCheckParam( pulparams[h], "RAJ" ) ) { ra = PulsarGetREAL8Param( pulparams[h], "RAJ" ); } else if ( PulsarCheckParam( pulparams[h], "RA" ) ){ ra = PulsarGetREAL8Param( pulparams[h], "RA" ); } else{ XLALPrintError("No right ascension found"); XLAL_ERROR ( XLAL_EFUNC ); } if ( PulsarCheckParam( pulparams[h], "DECJ" ) ) { dec = PulsarGetREAL8Param( pulparams[h], "DECJ" ); } else if ( PulsarCheckParam( pulparams[h], "DEC" ) ){ dec = PulsarGetREAL8Param( pulparams[h], "DEC" ); } else{ XLALPrintError("No declination found"); XLAL_ERROR ( XLAL_EFUNC ); } params.pulsar.position.latitude = dec + (REAL8)dtpos * PulsarGetREAL8ParamOrZero(pulparams[h], "PMDEC"); params.pulsar.position.longitude = ra + (REAL8)dtpos * PulsarGetREAL8ParamOrZero(pulparams[h], "PMRA") / cos(params.pulsar.position.latitude); params.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; REAL8Vector *fs = PulsarGetREAL8VectorParam(pulparams[h], "F"); if ( fs->length == 0 ){ XLALPrintError("No frequencies found"); XLAL_ERROR ( XLAL_EFUNC ); } params.pulsar.f0 = 2.*fs->data[0]; if ( fs->length > 1 ){ params.pulsar.spindown->data[0] = 2.*fs->data[1]; } if (( XLALGPSSetREAL8(&(params.pulsar.refTime), PulsarGetREAL8Param(pulparams[h], "PEPOCH")) ) == NULL ) XLAL_ERROR ( XLAL_EFUNC ); params.pulsar.psi = PulsarGetREAL8ParamOrZero(pulparams[h], "PSI"); params.pulsar.phi0 = PulsarGetREAL8ParamOrZero(pulparams[h], "PHI0"); REAL8 cosiota = PulsarGetREAL8ParamOrZero(pulparams[h], "COSIOTA"); REAL8 h0 = PulsarGetREAL8ParamOrZero(pulparams[h], "H0"); params.pulsar.aPlus = 0.5 * h0 * (1. + cosiota * cosiota ); params.pulsar.aCross = h0 * cosiota; /*Add binary later if needed!*/ params.site = site; params.ephemerides = edat; params.startTimeGPS = epoch; params.duration = ndata; params.samplingRate = srate; params.fHeterodyne = 0.; REAL4TimeSeries *TSeries = NULL; LALGeneratePulsarSignal( &status, &TSeries, ¶ms ); if (status.statusCode){ fprintf(stderr, "LAL Routine failed!\n"); XLAL_ERROR (XLAL_EFAILED); } UINT4 i; for (i=0; i < TSeries->data->length; i++) series->data->data[i] += TSeries->data->data[i]; XLALDestroyREAL4TimeSeries(TSeries); XLALDestroyREAL8Vector(params.pulsar.spindown); } } if (XLALFrameAddREAL8TimeSeriesProcData(outFrame,series)){ LogPrintf(LOG_CRITICAL, "%s : XLALFrameAddREAL8TimeSeries() failed with error = %d.\n",fn,xlalErrno); XLAL_ERROR(XLAL_EFAILED); } CHAR OUTFILE[256]; sprintf(OUTFILE, "%s/%s", inputs.outDir, out_file); if ( XLALFrameWrite(outFrame, OUTFILE)){ LogPrintf(LOG_CRITICAL, "%s : XLALFrameWrite() failed with error = %d.\n", fn, xlalErrno); XLAL_ERROR( XLAL_EFAILED ); } XLALFrameFree(outFrame); XLALDestroyREAL8TimeSeries( series ); 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 */ 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); }
/* Everything needs to be declared as unused in case HDF is not enabled. */ int XLALSimInspiralNRWaveformGetHplusHcross( UNUSED REAL8TimeSeries **hplus, /**< Output h_+ vector */ UNUSED REAL8TimeSeries **hcross, /**< Output h_x vector */ UNUSED REAL8 phiRef, /**< orbital phase at reference pt. */ UNUSED REAL8 inclination, /**< inclination angle */ UNUSED REAL8 deltaT, /**< sampling interval (s) */ UNUSED REAL8 m1, /**< mass of companion 1 (kg) */ UNUSED REAL8 m2, /**< mass of companion 2 (kg) */ UNUSED REAL8 r, /**< distance of source (m) */ UNUSED REAL8 fStart, /**< start GW frequency (Hz) */ UNUSED REAL8 fRef, /**< reference GW frequency (Hz) */ UNUSED REAL8 s1x, /**< initial value of S1x */ UNUSED REAL8 s1y, /**< initial value of S1y */ UNUSED REAL8 s1z, /**< initial value of S1z */ UNUSED REAL8 s2x, /**< initial value of S2x */ UNUSED REAL8 s2y, /**< initial value of S2y */ UNUSED REAL8 s2z, /**< initial value of S2z */ UNUSED const char *NRDataFile, /**< Location of NR HDF file */ UNUSED LALValue* ModeArray /**< Container for the ell and m modes to generate. To generate all available modes pass NULL */ ) { #ifndef LAL_HDF5_ENABLED XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled"); #else /* Declarations */ UINT4 curr_idx, nr_file_format; INT4 model, modem; size_t array_length; REAL8 nrEta; REAL8 S1x, S1y, S1z, S2x, S2y, S2z; REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s; REAL8 est_start_time, curr_h_real, curr_h_imag; REAL8 theta, psi, calpha, salpha; REAL8 distance_scale_fac; COMPLEX16 curr_ylm; REAL8TimeSeries *hplus_corr; REAL8TimeSeries *hcross_corr; /* These keys follow a strict formulation and cannot be longer than 11 * characters */ char amp_key[20]; char phase_key[20]; gsl_vector *tmpVector=NULL; LALH5File *file, *group; LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO; REAL8Vector *curr_amp, *curr_phase; /* Use solar masses for units. NR files will use * solar masses as well, so easier for that conversion */ m1 = m1 / LAL_MSUN_SI; m2 = m2 / LAL_MSUN_SI; file = XLALH5FileOpen(NRDataFile, "r"); if (file == NULL) { XLAL_ERROR(XLAL_EIO, "NR SIMULATION DATA FILE %s NOT FOUND.\n", NRDataFile); } /* Sanity checks on physical parameters passed to waveform * generator to guarantee consistency with NR data file. */ XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta"); if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "MASSES (%e and %e) ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION (eta=%e).\n", m1, m2, nrEta); } /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure * the ChooseTDWaveform() input values are consistent with the data * recorded in the metadata of the HDF5 file. * PS: This assumes that the input spins are in the LAL frame! */ XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format"); if (nr_file_format < 2) { XLALPrintInfo("This NR file is format %d. Only formats 2 and above support the use of reference frequency. For formats < 2 the reference frequency always corresponds to the start of the waveform.", nr_file_format); fRef = -1; } XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z, &S2x, &S2y, &S2z, fRef, m1+m2, file); if (fabs(S1x - s1x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1y - s1y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1z - s1z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2x - s2x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2y - s2y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2z - s2z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } /* First estimate the length of time series that is needed. * Demand that 22 mode that is present and use that to figure this out */ XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN"); /* Figure out start time of data */ group = XLALH5GroupOpen(file, "amp_l2_m2"); ReadHDF5RealVectorDataset(group, "X", &tmpVector); time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0)); time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1)); gsl_vector_free(tmpVector); time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI; time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI; /* We don't want to return the *entire* waveform if it will be much longer * than the specified f_lower. Therefore guess waveform length using * the SEOBNR_ROM function and add 10% for safety. * FIXME: Is this correct for precessing waveforms? */ if (fStart < Mflower / (m1 + m2) ) { XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e", fStart, Mflower, Mflower / (m1 + m2)); } XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format"); if (nr_file_format > 1) { if (XLALSimInspiralNRWaveformCheckFRef(file, fStart * (m1+m2)) > 0) { /* Can use Omega array to get start time */ est_start_time = XLALSimInspiralNRWaveformGetRefTimeFromRefFreq(file, fStart * (m1+m2)) * (m1 + m2) * LAL_MTSUN_SI; } else { /* This is the potential weird case where Omega-vs-time does not start * at precisely the same time as flower_at_1MSUN. This gap should be * small, so just use the full waveform here. */ est_start_time = time_start_s; } } else { /* Fall back on SEOBNR chirp time estimate */ XLALSimIMRSEOBNRv4ROMTimeOfFrequency(&est_start_time, fStart, m1 * LAL_MSUN_SI, m2 * LAL_MSUN_SI, s1z, s2z); est_start_time = (-est_start_time) * 1.1; } if (est_start_time > time_start_s) { /* Restrict start time of waveform */ time_start_s = est_start_time; time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI); } array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT)); /* Compute correct angles for hplus and hcross following LAL convention. */ theta = psi = calpha = salpha = 0.; XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha, &salpha, file, inclination, phiRef, fRef*(m1+m2)); /* Create the return time series, use arbitrary epoch here. We set this * properly later. */ XLALGPSAdd(&tmpEpoch, time_start_s); *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { hplus_corr->data->data[curr_idx] = 0.0; hcross_corr->data->data[curr_idx] = 0.0; } /* Create the distance scale factor */ distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r; /* Generate the waveform */ /* NOTE: We assume that for a given ell mode, all m modes are present */ INT4 NRLmax; XLALH5FileQueryScalarAttributeValue(&NRLmax, file, "Lmax"); if ( ModeArray == NULL ) {/* Default behaviour: Generate all modes upto NRLmax */ ModeArray = XLALSimInspiralCreateModeArray(); for (int ell=2; ell<=NRLmax; ell++) { XLALSimInspiralModeArrayActivateAllModesAtL(ModeArray, ell); } } /* else Use the ModeArray given */ for (model=2; model < (NRLmax + 1) ; model++) { for (modem=-model; modem < (model+1); modem++) { /* first check if (l,m) mode is 'activated' in the ModeArray */ /* if activated then generate the mode, else skip this mode. */ if (XLALSimInspiralModeArrayIsModeActive(ModeArray, model, modem) != 1) { XLAL_PRINT_INFO("SKIPPING model = %i modem = %i\n", model, modem); continue; } XLAL_PRINT_INFO("generateing model = %i modem = %i\n", model, modem); snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem); snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem); /* Check that both groups exist */ if (XLALH5FileCheckGroupExists(file, amp_key) == 0) { continue; } if (XLALH5FileCheckGroupExists(file, phase_key) == 0) { continue; } /* Get amplitude and phase from file */ XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2), time_start_s, array_length, deltaT, amp_key); XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2), time_start_s, array_length, deltaT, phase_key); curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2, model, modem); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { curr_h_real = curr_amp->data[curr_idx] * cos(curr_phase->data[curr_idx]) * distance_scale_fac; curr_h_imag = curr_amp->data[curr_idx] * sin(curr_phase->data[curr_idx]) * distance_scale_fac; hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx] + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm); hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx] - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm); } XLALDestroyREAL8Vector(curr_amp); XLALDestroyREAL8Vector(curr_phase); } } /* Correct for the "alpha" angle as given in T1600045 to translate * from the NR wave frame to LAL wave-frame * Helper time series needed. */ for (curr_idx = 0; curr_idx < array_length; curr_idx++) { (*hplus)->data->data[curr_idx] = (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx] - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx]; (*hcross)->data->data[curr_idx] = + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx] + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx]; } XLALDestroyREAL8TimeSeries(hplus_corr); XLALDestroyREAL8TimeSeries(hcross_corr); XLALH5FileClose(file); XLALDestroyValue(ModeArray); return XLAL_SUCCESS; #endif }
int main(int argc, char *argv[]) { char tstr[32]; // string to hold GPS time -- 31 characters is enough size_t length; size_t stride; size_t n; REAL8FrequencySeries *psd = NULL; REAL8TimeSeries *seg = NULL; gsl_rng *rng; XLALSetErrorHandler(XLALAbortErrorHandler); parseargs(argc, argv); if (overrideflow > 0.0) flow = overrideflow; length = segdur * srate; stride = length / 2; /* handle 0noise case first */ if (strcmp(detector, "0noise") == 0) { /* just print out a bunch of zeros */ if (psdonly) { double deltaF = srate / length; size_t klow = flow / deltaF; size_t k; fprintf(stdout, "# freq (s^-1)\tPSD (strain^2 s)\n"); for (k = klow; k < length/2 - 1; ++k) fprintf(stdout, "%e\t%e\n", k * deltaF, 0.0); } else { size_t j; fprintf(stdout, "# time (s)\tNOISE (strain)\n"); n = duration * srate; for (j = 0; j < n; ++j) { LIGOTimeGPS t = tstart; fprintf(stdout, "%s\t%e\n", XLALGPSToStr(tstr, XLALGPSAdd(&t, j/srate)), 0.0); } } return 0; } gsl_rng_env_setup(); rng = gsl_rng_alloc(gsl_rng_default); psd = XLALCreateREAL8FrequencySeries(detector, &tstart, 0.0, srate/length, &strainSquaredPerHertzUnit, length/2 + 1); if (asdfile) XLALSimNoisePSDFromFile(psd, flow, asdfile); else if (official && opsdfunc) opsdfunc(psd, flow); else XLALSimNoisePSD(psd, flow, psdfunc); if (verbose) { double Mpc = 1e6 * LAL_PC_SI; double horizon_distance; fprintf(stderr, "%-39s %s\n", "detector: ", detector); fprintf(stderr, "%-39s %g Hz\n", "low-frequency cutoff: ", flow); horizon_distance = XLALMeasureStandardSirenHorizonDistance(psd, flow, -1.0); fprintf(stderr, "%-39s %g Mpc\n", "standard siren horizon distance: ", horizon_distance / Mpc); fprintf(stderr, "%-39s %g Mpc\n", "sense-monitor range: ", horizon_distance / Mpc / LAL_HORIZON_DISTANCE_OVER_SENSEMON_RANGE); fprintf(stderr, "%-39s GSL_RNG_TYPE=%s\n", "GSL random number generator:", gsl_rng_name(rng)); fprintf(stderr, "%-39s GSL_RNG_SEED=%lu\n", "GSL random number seed:", gsl_rng_default_seed); } if (psdonly) { // output PSD and exit size_t klow = flow / psd->deltaF; size_t k; fprintf(stdout, "# freq (s^-1)\tPSD (strain^2 s)\n"); for (k = klow; k < length/2 - 1; ++k) fprintf(stdout, "%e\t%e\n", k * psd->deltaF, sqrt(psd->data->data[k])); goto end; } n = duration * srate; seg = XLALCreateREAL8TimeSeries("STRAIN", &tstart, 0.0, 1.0/srate, &lalStrainUnit, length); XLALSimNoise(seg, 0, psd, rng); // first time to initialize fprintf(stdout, "# time (s)\tNOISE (strain)\n"); while (1) { // infinite loop size_t j; for (j = 0; j < stride; ++j, --n) { // output first stride points LIGOTimeGPS t = seg->epoch; if (n == 0) // check if we're done goto end; fprintf(stdout, "%s\t%e\n", XLALGPSToStr(tstr, XLALGPSAdd(&t, j * seg->deltaT)), seg->data->data[j]); } XLALSimNoise(seg, stride, psd, rng); // make more data } end: XLALDestroyREAL8TimeSeries(seg); XLALDestroyREAL8FrequencySeries(psd); LALCheckMemoryLeaks(); return 0; }
int main(int argc,char *argv[]) { LALFrameH *frame; /* output frame */ char filename[256]; /* output file name */ REAL8TimeSeries *ht_1; /* H1 strain data */ REAL8TimeSeries *ht_2; /* H2 strain data */ REAL8TimeSeries *ht_m; /* H- strain data */ char cache_name_1[256]; /* H1 frame cache name */ char cache_name_2[256]; /* H2 frame cache name */ LALCache *cache_1; /* H1 frame cache */ LALCache *cache_2; /* H2 frame cache */ LALFrStream *stream_1; /* H1 stream */ LALFrStream *stream_2; /* H2 stream */ int i, p, gps_start_i, gps_end_i, start, end; LIGOTimeGPS gps_start, gps_end; cache_name_1[0]='\0'; cache_name_2[0]='\0'; filename[0]='\0'; ht_1=NULL; ht_2=NULL; /* read arguments */ if(argc!=4){ printf("%s(): usage: lalapps_StringAddFrame [gps_start] [gps_end] [outdir]\n",__func__); printf(" There should be the H1 and H2 cache files ready in [outdir] named H1.cache and H2.cache\n"); return 1; } gps_start_i=atoi(argv[1]); gps_end_i=atoi(argv[2]); sprintf(cache_name_1,"%s/H1.cache", argv[3]); sprintf(cache_name_2,"%s/H2.cache", argv[3]); /* create Frame cache, open frame stream and delete frame cache */ cache_1 = XLALCacheImport(cache_name_1); if(!cache_1){ printf("%s(): no cache named %s\n",__func__,cache_name_1); return 2; } stream_1 = XLALFrStreamCacheOpen(cache_1); XLALDestroyCache(cache_1); if(!stream_1){ printf("%s(): no stream for H1\n",__func__); return 2; } if(!stream_1) XLAL_ERROR(XLAL_EFUNC); cache_2 = XLALCacheImport(cache_name_2); if(!cache_2){ printf("%s(): no cache named %s\n",__func__,cache_name_2); return 3; } stream_2 = XLALFrStreamCacheOpen(cache_2); XLALDestroyCache(cache_2); if(!stream_2){ printf("%s(): no stream for H2\n",__func__); return 3; } /* turn on checking for missing data */ XLALFrStreamSetMode(stream_1, LAL_FR_STREAM_VERBOSE_MODE); XLALFrStreamSetMode(stream_2, LAL_FR_STREAM_VERBOSE_MODE); /* divide the time period into 128s segments */ for(i=gps_start_i; i<gps_end_i; i+=128){ start=i; end=Min(i+128,gps_end_i); printf("Building frame %d-%d...\n",start,end); /* define time segment */ gps_start.gpsSeconds = start; gps_start.gpsNanoSeconds = 0; gps_end.gpsSeconds = end; gps_end.gpsNanoSeconds = 0; /* read H1 and H2 data */ ht_1 = XLALFrStreamReadREAL8TimeSeries(stream_1, "H1:LSC-STRAIN", &gps_start, XLALGPSDiff(&gps_end, &gps_start), 0); if(!ht_1) { XLALFrStreamClose(stream_1); printf("%s(): cannot read data for H1:LSC-STRAIN\n",__func__); } ht_2 = XLALFrStreamReadREAL8TimeSeries(stream_2, "H2:LSC-STRAIN", &gps_start, XLALGPSDiff(&gps_end, &gps_start), 0); if(!ht_2) { XLALFrStreamClose(stream_2); printf("%s(): cannot read data for H2:LSC-STRAIN\n",__func__); } /* units */ ht_1->sampleUnits = lalStrainUnit; ht_2->sampleUnits = lalStrainUnit; /* create H- time series */ ht_m = XLALCreateREAL8TimeSeries("H2:LSC-STRAIN_HNULL", &gps_start, ht_1->f0, ht_1->deltaT, &ht_1->sampleUnits, ht_1->data->length); /* fill H- data vector */ for ( p = 0 ; p < (int)ht_1->data->length; p++ ) ht_m->data->data[p]=ht_1->data->data[p]-ht_2->data->data[p]; /* save time series into a frame */ frame = XLALFrameNew(&gps_start, XLALGPSDiff(&gps_end, &gps_start), "LIGO", 0, 1,LAL_LHO_4K_DETECTOR_BIT); /*XLALFrameAddREAL8TimeSeriesProcData( frame, ht_1 );*/ /*XLALFrameAddREAL8TimeSeriesProcData( frame, ht_2 );*/ XLALFrameAddREAL8TimeSeriesProcData( frame, ht_m ); sprintf(filename,"%s/H-H1H2_COHERENT-%d-%d.gwf", argv[3],start,end-start); XLALFrameWrite(frame, filename); /* cleaning */ XLALDestroyREAL8TimeSeries(ht_1); XLALDestroyREAL8TimeSeries(ht_2); XLALDestroyREAL8TimeSeries(ht_m); XLALFrameFree(frame); } /* close streams */ XLALFrStreamClose(stream_1); XLALFrStreamClose(stream_2); return 0; }
CAMLprim value wrapLALInferenceIFOData(value options) { CAMLparam1(options); CAMLlocal2(data, option); LALInferenceIFOData *d = NULL; ProcessParamsTable *ppt = NULL; /* Set srate. */ option = Field(options, 0); ppt = addCommandLineOption(ppt, "--srate", String_val(option)); /* Flow's */ option = Field(options, 1); if (caml_string_length(option) == 0) { /* Do nothing. */ } else { ppt = addCommandLineOption(ppt, "--flow", String_val(option)); } /* Fhigh's */ option = Field(options, 2); if (caml_string_length(option) == 0) { /* Do nothing. */ } else { ppt = addCommandLineOption(ppt, "--fhigh", String_val(option)); } option = Field(options, 3); ppt = addCommandLineOption(ppt, "--cache", String_val(option)); option = Field(options, 4); ppt = addCommandLineOption(ppt, "--IFO", String_val(option)); option = Field(options, 5); ppt = addCommandLineOption(ppt, "--dataseed", String_val(option)); option = Field(options, 6); ppt = addCommandLineOption(ppt, "--PSDstart", String_val(option)); option = Field(options, 7); ppt = addCommandLineOption(ppt, "--trigtime", String_val(option)); option = Field(options, 8); ppt = addCommandLineOption(ppt, "--PSDlength", String_val(option)); option = Field(options, 9); ppt = addCommandLineOption(ppt, "--seglen", String_val(option)); option = Field(options, 10); if (Is_block(option)) { ppt = addCommandLineOption(ppt, "--injXML", String_val(Field(option,0))); } d = LALInferenceReadData(ppt); LALInferenceInjectInspiralSignal(d,ppt); LALInferenceIFOData *dElt = d; while (dElt != NULL) { /*If two IFOs have the same sampling rate, they should have the same timeModelh*, freqModelh*, and modelParams variables to avoid excess computation in model waveform generation in the future*/ LALInferenceIFOData * dEltCompare=d; int foundIFOwithSameSampleRate=0; while (dEltCompare != NULL && dEltCompare!=dElt) { if(dEltCompare->timeData->deltaT == dElt->timeData->deltaT){ dElt->timeModelhPlus=dEltCompare->timeModelhPlus; dElt->freqModelhPlus=dEltCompare->freqModelhPlus; dElt->timeModelhCross=dEltCompare->timeModelhCross; dElt->freqModelhCross=dEltCompare->freqModelhCross; dElt->modelParams=dEltCompare->modelParams; foundIFOwithSameSampleRate=1; break; } dEltCompare = dEltCompare->next; } if(!foundIFOwithSameSampleRate){ dElt->timeModelhPlus = XLALCreateREAL8TimeSeries("timeModelhPlus", &(dElt->timeData->epoch), 0.0, dElt->timeData->deltaT, &lalDimensionlessUnit, dElt->timeData->data->length); dElt->timeModelhCross = XLALCreateREAL8TimeSeries("timeModelhCross", &(dElt->timeData->epoch), 0.0, dElt->timeData->deltaT, &lalDimensionlessUnit, dElt->timeData->data->length); dElt->freqModelhPlus = XLALCreateCOMPLEX16FrequencySeries("freqModelhPlus", &(dElt->freqData->epoch), 0.0, dElt->freqData->deltaF, &lalDimensionlessUnit, dElt->freqData->data->length); dElt->freqModelhCross = XLALCreateCOMPLEX16FrequencySeries("freqModelhCross", &(dElt->freqData->epoch), 0.0, dElt->freqData->deltaF, &lalDimensionlessUnit, dElt->freqData->data->length); dElt->modelParams = calloc(1, sizeof(LALInferenceVariables)); } dElt = dElt->next; } deletePPT(ppt); data = alloc_ifo_data(d); CAMLreturn(data); }
/** * Evolves a post-Newtonian orbit using the Taylor T4 method. * * See: * Michael Boyle, Duncan A. Brown, Lawrence E. Kidder, Abdul H. Mroue, * Harald P. Pfeiffer, Mark A. Scheel, Gregory B. Cook, and Saul A. Teukolsky * "High-accuracy comparison of numerical relativity simulations with * post-Newtonian expansions" * <a href="http://arxiv.org/abs/0710.0158v2">arXiv:0710.0158v2</a>. */ int XLALSimInspiralTaylorT4PNEvolveOrbit( REAL8TimeSeries **v, /**< post-Newtonian parameter [returned] */ REAL8TimeSeries **phi, /**< orbital phase [returned] */ REAL8 phiRef, /**< reference orbital phase (rad) */ REAL8 deltaT, /**< sampling interval (s) */ REAL8 m1, /**< mass of companion 1 (kg) */ REAL8 m2, /**< mass of companion 2 (kg) */ REAL8 f_min, /**< start frequency (Hz) */ REAL8 fRef, /**< reference frequency (Hz) */ REAL8 lambda1, /**< (tidal deformability of body 1)/(mass of body 1)^5 */ REAL8 lambda2, /**< (tidal deformability of body 2)/(mass of body 2)^5 */ LALSimInspiralTidalOrder tideO, /**< flag to control spin and tidal effects */ int O /**< twice post-Newtonian order */ ) { const UINT4 blocklen = 1024; const REAL8 visco = 1./sqrt(6.); REAL8 VRef = 0.; XLALSimInspiralTaylorT4PNEvolveOrbitParams params; expnFuncTaylorT4 expnfunc; expnCoeffsTaylorT4 ak; expnCoeffsdEnergyFlux akdEF; if(XLALSimInspiralTaylorT4Setup(&ak,&expnfunc,&akdEF,m1,m2,lambda1,lambda2, tideO,O)) XLAL_ERROR(XLAL_EFUNC); params.func=expnfunc.angacc4; params.ak=ak; REAL8 E; UINT4 j, len, idxRef = 0; LIGOTimeGPS tc = LIGOTIMEGPSZERO; double y[2]; double yerr[2]; const gsl_odeiv_step_type *T = gsl_odeiv_step_rk4; gsl_odeiv_step *s; gsl_odeiv_system sys; /* setup ode system */ sys.function = XLALSimInspiralTaylorT4PNEvolveOrbitIntegrand; sys.jacobian = NULL; sys.dimension = 2; sys.params = ¶ms; /* allocate memory */ *v = XLALCreateREAL8TimeSeries( "ORBITAL_VELOCITY_PARAMETER", &tc, 0., deltaT, &lalDimensionlessUnit, blocklen ); *phi = XLALCreateREAL8TimeSeries( "ORBITAL_PHASE", &tc, 0., deltaT, &lalDimensionlessUnit, blocklen ); if ( !v || !phi ) XLAL_ERROR(XLAL_EFUNC); y[0] = (*v)->data->data[0] = cbrt(LAL_PI*LAL_G_SI*ak.m*f_min)/LAL_C_SI; y[1] = (*phi)->data->data[0] = 0.; E = expnfunc.energy4(y[0],&akdEF); if (XLALIsREAL8FailNaN(E)) XLAL_ERROR(XLAL_EFUNC); j = 0; s = gsl_odeiv_step_alloc(T, 2); while (1) { ++j; gsl_odeiv_step_apply(s, j*deltaT, deltaT, y, yerr, NULL, NULL, &sys); /* ISCO termination condition for quadrupole, 1pN, 2.5pN */ if ( y[0] > visco ) { XLALPrintInfo("XLAL Info - %s: PN inspiral terminated at ISCO\n", __func__); break; } if ( j >= (*v)->data->length ) { if ( ! XLALResizeREAL8TimeSeries(*v, 0, (*v)->data->length + blocklen) ) XLAL_ERROR(XLAL_EFUNC); if ( ! XLALResizeREAL8TimeSeries(*phi, 0, (*phi)->data->length + blocklen) ) XLAL_ERROR(XLAL_EFUNC); } (*v)->data->data[j] = y[0]; (*phi)->data->data[j] = y[1]; } gsl_odeiv_step_free(s); /* make the correct length */ if ( ! XLALResizeREAL8TimeSeries(*v, 0, j) ) XLAL_ERROR(XLAL_EFUNC); if ( ! XLALResizeREAL8TimeSeries(*phi, 0, j) ) XLAL_ERROR(XLAL_EFUNC); /* adjust to correct time */ XLALGPSAdd(&(*v)->epoch, -1.0*j*deltaT); XLALGPSAdd(&(*phi)->epoch, -1.0*j*deltaT); /* Do a constant phase shift to get desired value of phiRef */ len = (*phi)->data->length; /* For fRef==0, phiRef is phase of last sample */ if( fRef == 0. ) phiRef -= (*phi)->data->data[len-1]; /* For fRef==fmin, phiRef is phase of first sample */ else if( fRef == f_min ) phiRef -= (*phi)->data->data[0]; /* phiRef is phase when f==fRef */ else { VRef = pow(LAL_PI * LAL_G_SI*(m1+m2) * fRef, 1./3.) / LAL_C_SI; j = 0; do { idxRef = j; j++; } while ((*v)->data->data[j] <= VRef); phiRef -= (*phi)->data->data[idxRef]; } for (j = 0; j < len; ++j) (*phi)->data->data[j] += phiRef; return (int)(*v)->data->length; }
/** * Takes in the l=2, abs(m)=2 decomposed modes as a strain time series and * imposes the effect of a constant cone of precession. This is accomplished * by taking the axis of the binary rotational plane and rotating the Y_lm * such that it appears to "precess" around a fixed J direction. * Note that h_2_2 and h_22 are modified in place. * * Future revisions will change the first two pointers to this: * COMPLEX16TimeSeries** h_lm * * and add * unsigned int l * * Thus the input h_lm will be considered a list of pointers to the h_lm for a * given l and the appropriate action will be taken for *all* of the submodes. */ int XLALSimInspiralConstantPrecessionConeWaveformModes( SphHarmTimeSeries** h_lm_tmp, /**< (l,m) modes, modified in place */ double precess_freq, /**< Precession frequency in Hz */ double a, /**< Opening angle of precession cone in rads */ double phi_precess, /**< initial phase in cone of L around J */ double alpha_0, /**< azimuth btwn center of cone and line of sight */ double beta_0 /**< zenith btwn center of cone and line of sight */ ) { /* * Since the h_22 modes are the most likely to exist, we'll use those * to do our error checking */ SphHarmTimeSeries* h_lm = *h_lm_tmp; COMPLEX16TimeSeries *h_22, *h_2_2; h_22 = XLALSphHarmTimeSeriesGetMode( h_lm, 2, 2 ); h_2_2 = XLALSphHarmTimeSeriesGetMode( h_lm, 2, -2 ); if( !(h_22 && h_2_2) ){ XLALPrintError( "XLAL Error - %s: Currently, ConstantPrecessionConeWaveformModes requires the l=2 m=+/-2 modes to exist to continue.", __func__); XLAL_ERROR( XLAL_EINVAL ); } // Error checking // Since we need at least three points to do any of the numerical work // we intend to, if the waveform is two points or smaller, we're in // trouble. I don't expect this to be a problem. if( h_2_2->data->length <= 2 ){ XLALPrintError( "XLAL Error - %s: Waveform length is too small to evolve accurately.", __func__); XLAL_ERROR( XLAL_EBADLEN ); } if( h_2_2->data->length != h_22->data->length ){ XLALPrintError( "XLAL Error - %s: Input (2,2) and (2,-2) modes have different length.", __func__); XLAL_ERROR( XLAL_EBADLEN ); } unsigned int i; double omg_p = 2*LAL_PI*precess_freq; double t=0; // time evolved Euler angles REAL8TimeSeries* alpha = XLALCreateREAL8TimeSeries( "euler angle alpha", &(h_22->epoch), h_22->f0, h_22->deltaT, &(h_22->sampleUnits), h_22->data->length ); REAL8TimeSeries* beta = XLALCreateREAL8TimeSeries( "euler angle beta", &(h_22->epoch), h_22->f0, h_22->deltaT, &(h_22->sampleUnits), h_22->data->length ); REAL8TimeSeries* gam = XLALCreateREAL8TimeSeries( "euler angle gamma", &(h_22->epoch), h_22->f0, h_22->deltaT, &(h_22->sampleUnits), h_22->data->length ); // Minimal rotation constraint // \gamma(t) = \int \cos(\beta(t)) \alpha'(t) dt // Uses the second order finite difference to estimate dalpha/dt // Then the trapezoid rule for the integration for(i=0; i<alpha->data->length; i++){ t = h_22->deltaT*i; alpha->data->data[i] = a*sin(omg_p * t + phi_precess) + alpha_0; beta->data->data[i] = a*cos(omg_p * t + phi_precess) + beta_0; } // NOTE: The step size cancels out between the difference and sum and // thus does not appear below. // two point forward difference double dalpha_0 = alpha->data->data[1] - alpha->data->data[0]; // three point central difference double dalpha_1 = 0.5*(alpha->data->data[2] - alpha->data->data[0]); gam->data->data[0] = 0.; gam->data->data[1] = cos(beta->data->data[0])*dalpha_0 + cos(beta->data->data[1])*dalpha_1; for(i=2; i<gam->data->length-1; i++){ // three point central difference dalpha_0 = dalpha_1; dalpha_1 = 0.5*(alpha->data->data[i+1] - alpha->data->data[i-1]); // Two point numerical integration over the interval gam->data->data[i] = gam->data->data[i-1] + cos(beta->data->data[i-1])*dalpha_0 + cos(beta->data->data[i])*dalpha_1; } // Use two point backward difference for last point dalpha_0 = dalpha_1; dalpha_1 = alpha->data->data[i] - alpha->data->data[i-1]; gam->data->data[i] = gam->data->data[i-1] + cos(beta->data->data[i-1])*dalpha_0 + cos(beta->data->data[i])*dalpha_1; // Rotate waveform XLALSimInspiralPrecessionRotateModes( h_lm, alpha, beta, gam ); XLALDestroyREAL8TimeSeries( alpha ); XLALDestroyREAL8TimeSeries( beta ); XLALDestroyREAL8TimeSeries( gam ); return XLAL_SUCCESS; }
/* * main program entry point */ INT4 main(INT4 argc, CHAR **argv) { /* status */ LALStatus status = blank_status; /* counters */ int c; UINT4 i; /* mode counters */ UINT4 l, m; /* metadata file/directory */ CHAR *nrMetaFile = NULL; CHAR *nrDataDir = NULL; CHAR file_path[FILENAME_MAX]; /* metadata format */ CHAR *metadata_format = NULL; /* metadata parsing variables */ LALParsedDataFile *meta_file = NULL; BOOLEAN wasRead = 0; CHAR field[HISTORY_COMMENT]; CHAR *wf_name[MAX_L+1][(2*MAX_L) + 1]; /* common metadata */ CHAR *md_mass_ratio = NULL; CHAR *md_spin1x = NULL; CHAR *md_spin1y = NULL; CHAR *md_spin1z = NULL; CHAR *md_spin2x = NULL; CHAR *md_spin2y = NULL; CHAR *md_spin2z = NULL; CHAR *md_freq_start_22 = NULL; /* NINJA1 metadata */ CHAR *md_simulation_details = NULL; CHAR *md_nr_group = NULL; CHAR *md_email = NULL; /* NINJA2 metadata */ CHAR *md_waveform_name = NULL; CHAR *md_initial_separation = NULL; CHAR *md_eccentricity = NULL; CHAR *md_number_of_cycles_22 = NULL; CHAR *md_code = NULL; CHAR *md_submitter_email = NULL; CHAR *md_authors_emails = NULL; /* common metadata strings */ CHAR str_mass_ratio[HISTORY_COMMENT]; CHAR str_spin1x[HISTORY_COMMENT]; CHAR str_spin1y[HISTORY_COMMENT]; CHAR str_spin1z[HISTORY_COMMENT]; CHAR str_spin2x[HISTORY_COMMENT]; CHAR str_spin2y[HISTORY_COMMENT]; CHAR str_spin2z[HISTORY_COMMENT]; CHAR str_freq_start_22[HISTORY_COMMENT]; CHAR str_creator[HISTORY_COMMENT]; /* NINJA1 metadata strings */ CHAR str_simulation_details[HISTORY_COMMENT]; CHAR str_nr_group[HISTORY_COMMENT]; CHAR str_email[HISTORY_COMMENT]; /* NINJA2 metadata strings */ CHAR str_waveform_name[HISTORY_COMMENT]; CHAR str_initial_separation[HISTORY_COMMENT]; CHAR str_eccentricity[HISTORY_COMMENT]; CHAR str_number_of_cycles_22[HISTORY_COMMENT]; CHAR str_code[HISTORY_COMMENT]; CHAR str_submitter_email[HISTORY_COMMENT]; CHAR str_authors_emails[HISTORY_COMMENT]; /* channel names */ CHAR *plus_channel[MAX_L+1][(2*MAX_L) + 1]; CHAR *cross_channel[MAX_L+1][(2*MAX_L) + 1]; /* waveforms */ UINT4 wf_length; REAL4TimeVectorSeries *waveforms[MAX_L][(2*MAX_L) + 1]; REAL4TimeSeries *hplus[MAX_L+1][(2*MAX_L) + 1]; REAL4TimeSeries *hcross[MAX_L+1][(2*MAX_L) + 1]; REAL8TimeVectorSeries *waveformsREAL8[MAX_L][(2*MAX_L) + 1]; REAL8TimeSeries *hplusREAL8[MAX_L+1][(2*MAX_L) + 1]; REAL8TimeSeries *hcrossREAL8[MAX_L+1][(2*MAX_L) + 1]; /* frame variables */ LALFrameH *frame; CHAR *frame_name = NULL; LIGOTimeGPS epoch; INT4 duration; INT4 detector_flags; INT4 generatingREAL8 = 0; /* LALgetopt arguments */ struct LALoption long_options[] = { /* options that set a flag */ {"verbose", no_argument, &vrbflg, 1}, /* options that don't set a flag */ {"format", required_argument, 0, 'f'}, {"nr-meta-file", required_argument, 0, 'm'}, {"nr-data-dir", required_argument, 0, 'd'}, {"output", required_argument, 0, 'o'}, {"double-precision", no_argument, 0, 'p'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {0, 0, 0, 0} }; /* default debug level */ lal_errhandler = LAL_ERR_EXIT; /* parse the arguments */ while(1) { /* LALgetopt_long stores long option here */ int option_index = 0; size_t LALoptarg_len; c = LALgetopt_long_only(argc, argv, "f:m:d:o:phV", long_options, &option_index); /* detect the end of the options */ if (c == -1) break; switch(c) { case 0: /* if this option sets a flag, do nothing else for now */ if (long_options[option_index].flag != 0) break; else { fprintf(stderr, "Error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg); exit(1); } break; case 'h': /* help message */ print_usage(stdout, argv[0]); exit(0); break; case 'V': /* print version information and exit */ fprintf(stdout, "Numerical Relativity Frame Generation\n"); XLALOutputVersionString(stderr, 0); exit(0); break; case 'f': /* create storage for the metadata format */ LALoptarg_len = strlen(LALoptarg) + 1; metadata_format = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR)); memcpy(metadata_format, LALoptarg, LALoptarg_len); break; case 'm': /* create storage for the meta file name */ LALoptarg_len = strlen(LALoptarg) + 1; nrMetaFile = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR)); memcpy(nrMetaFile, LALoptarg, LALoptarg_len); break; case 'd': /* create storage for the meta data directory name */ LALoptarg_len = strlen(LALoptarg) + 1; nrDataDir = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR)); memcpy(nrDataDir, LALoptarg, LALoptarg_len); break; case 'o': /* create storage for the output frame file name */ LALoptarg_len = strlen(LALoptarg) + 1; frame_name = (CHAR *)calloc(LALoptarg_len, sizeof(CHAR)); memcpy(frame_name, LALoptarg, LALoptarg_len); break; case 'p': /* We're generating a double-precision frame */ generatingREAL8 = 1; break; case '?': print_usage(stderr, argv[0]); exit(1); break; default: fprintf(stderr, "Unknown error while parsing arguments\n"); print_usage(stderr, argv[0]); exit(1); break; } } /* check for extraneous command line arguments */ if (LALoptind < argc) { fprintf(stderr, "Extraneous command line arguments:\n"); while(LALoptind < argc) fprintf(stderr, "%s\n", argv[LALoptind++]); exit(1); } /* * check validity of arguments */ /* metadata format specified */ if (metadata_format == NULL) { fprintf(stderr, "warning: --format not specified, assuming NINJA1\n"); metadata_format = (CHAR *)calloc(7, sizeof(CHAR)); memcpy(metadata_format, "NINJA1", 7); } /* check for supported metadata format */ if (strcmp(metadata_format, "NINJA1") == 0); else if (strcmp(metadata_format, "NINJA2") == 0); else { fprintf(stderr, "Supported metadata formats are NINJA1 and NINJA2 (%s specified)\n", metadata_format); exit(1); } /* meta file specified */ if (nrMetaFile == NULL) { fprintf(stderr, "--nr-meta-file must be specified\n"); exit(1); } /* data directory specified */ if (nrDataDir == NULL) { fprintf(stderr, "--nr-data-dir must be specified\n"); exit(1); } /* output frame filename specified */ if (frame_name == NULL) { fprintf(stderr, "--output must be specified\n"); exit(1); } /* * main code */ /* frame metadata */ /* TODO: set these to something sensible */ duration = 0; epoch.gpsSeconds = 0; epoch.gpsNanoSeconds = 0; detector_flags = 0; if (vrbflg) fprintf(stdout, "reading metadata: %s\n", nrMetaFile); /* open metadata file */ XLAL_CHECK ( XLALParseDataFile(&meta_file, nrMetaFile) == XLAL_SUCCESS, XLAL_EFUNC ); /* * get metadata */ /* common metadata */ XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_mass_ratio, meta_file, NULL, "mass-ratio", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin1x, meta_file, NULL, "spin1x", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin1y, meta_file, NULL, "spin1y", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin1z, meta_file, NULL, "spin1z", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin2x, meta_file, NULL, "spin2x", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin2y, meta_file, NULL, "spin2y", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_spin2z, meta_file, NULL, "spin2z", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); /* format specific metadata */ if (strcmp(metadata_format, "NINJA1") == 0) { /* NINJA1 */ XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_simulation_details, meta_file, NULL, "simulation-details", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_nr_group, meta_file, NULL, "nr-group", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_email, meta_file, NULL, "email", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_freq_start_22, meta_file, NULL, "freqStart22", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); } else if (strcmp(metadata_format, "NINJA2") == 0) { /* NINJA2 */ XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_waveform_name, meta_file, NULL, "waveform-name", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_initial_separation, meta_file, NULL, "initial-separation", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_eccentricity, meta_file, NULL, "eccentricity", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_number_of_cycles_22, meta_file, NULL, "number-of-cycles-22", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_code, meta_file, NULL, "code", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_submitter_email, meta_file, NULL, "submitter-email", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_authors_emails, meta_file, NULL, "authors-emails", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &md_freq_start_22, meta_file, NULL, "freq-start-22", &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); } else { /* unknown metadata format - should not be executed */ fprintf(stderr, "error: unsupported metadata format: %s\n", metadata_format); exit(1); } /* * set metadata strings */ /* common waveform */ snprintf(str_mass_ratio, HISTORY_COMMENT, "mass-ratio:%s", md_mass_ratio); snprintf(str_spin1x, HISTORY_COMMENT, "spin1x:%s", md_spin1x); snprintf(str_spin1y, HISTORY_COMMENT, "spin1y:%s", md_spin1y); snprintf(str_spin1z, HISTORY_COMMENT, "spin1z:%s", md_spin1z); snprintf(str_spin2x, HISTORY_COMMENT, "spin2x:%s", md_spin2x); snprintf(str_spin2y, HISTORY_COMMENT, "spin2y:%s", md_spin2y); snprintf(str_spin2z, HISTORY_COMMENT, "spin2z:%s", md_spin2z); snprintf(str_creator, HISTORY_COMMENT, "creator:%s(git:%s)", PROGRAM_NAME, lalAppsVCSId); /* format specific metadata */ if (strcmp(metadata_format, "NINJA1") == 0) { /* NINJA1 */ snprintf(str_freq_start_22, HISTORY_COMMENT, "freqStart22:%s", md_freq_start_22); snprintf(str_simulation_details, HISTORY_COMMENT, "simulation-details:%s", md_simulation_details); snprintf(str_nr_group, HISTORY_COMMENT, "nr-group:%s", md_nr_group); snprintf(str_email, HISTORY_COMMENT, "email:%s", md_email); } else if (strcmp(metadata_format, "NINJA2") == 0) { /* NINJA2 */ snprintf(str_waveform_name, HISTORY_COMMENT, "waveform-name:%s", md_waveform_name); snprintf(str_initial_separation, HISTORY_COMMENT, "inital-separation:%s", md_initial_separation); snprintf(str_eccentricity, HISTORY_COMMENT, "eccentricity:%s", md_eccentricity); snprintf(str_freq_start_22, HISTORY_COMMENT, "freq_start_22:%s", md_freq_start_22); snprintf(str_number_of_cycles_22, HISTORY_COMMENT, "number-of-cycles-22:%s", md_number_of_cycles_22); snprintf(str_code, HISTORY_COMMENT, "code:%s", md_code); snprintf(str_submitter_email, HISTORY_COMMENT, "submitter-email:%s", md_submitter_email); snprintf(str_authors_emails, HISTORY_COMMENT, "authors-emails:%s", md_authors_emails); } else { /* unknown metadata format - should not be executed */ fprintf(stderr, "error: unsupported metadata format: %s\n", metadata_format); exit(1); } /* define frame */ frame = XLALFrameNew(&epoch, duration, "NR", 0, 1, detector_flags); /* * add metadata as FrHistory structures */ /* common metadata */ XLALFrameAddFrHistory(frame, "creator", str_creator); XLALFrameAddFrHistory(frame, "mass-ratio", str_mass_ratio); XLALFrameAddFrHistory(frame, "spin1x", str_spin1x); XLALFrameAddFrHistory(frame, "spin1y", str_spin1y); XLALFrameAddFrHistory(frame, "spin1z", str_spin1z); XLALFrameAddFrHistory(frame, "spin2x", str_spin2x); XLALFrameAddFrHistory(frame, "spin2y", str_spin2y); XLALFrameAddFrHistory(frame, "spin2z", str_spin2z); /* format specific metadata */ if (strcmp(metadata_format, "NINJA1") == 0) { /* NINJA1 */ XLALFrameAddFrHistory(frame, "simulation-details", str_simulation_details); XLALFrameAddFrHistory(frame, "nr-group", str_nr_group); XLALFrameAddFrHistory(frame, "email", str_email); XLALFrameAddFrHistory(frame, "freqStart22", str_freq_start_22); } else if (strcmp(metadata_format, "NINJA2") == 0) { /* NINJA2 */ XLALFrameAddFrHistory(frame, "waveform-name", str_waveform_name); XLALFrameAddFrHistory(frame, "initial-separation", str_initial_separation); XLALFrameAddFrHistory(frame, "eccentricity", str_eccentricity); XLALFrameAddFrHistory(frame, "freq_start_22", str_freq_start_22); XLALFrameAddFrHistory(frame, "number-of-cycles-22", str_number_of_cycles_22); XLALFrameAddFrHistory(frame, "code", str_code); XLALFrameAddFrHistory(frame, "submitter-email", str_code); XLALFrameAddFrHistory(frame, "authors-emails", str_authors_emails); } else { /* unknown metadata format - should not be executed */ fprintf(stderr, "error: unsupported metadata format: %s\n", metadata_format); exit(1); } /* loop over l & m values */ for (l = MIN_L; l <= MAX_L; l++) { for (m = (MAX_L - l); m <= MAX_L + l; m++) { /* ensure pointers are NULL */ wf_name[l][m] = NULL; plus_channel[l][m] = NULL; cross_channel[l][m] = NULL; /* generate channel names */ plus_channel[l][m] = XLALGetNinjaChannelName("plus", l, m - MAX_L); cross_channel[l][m] = XLALGetNinjaChannelName("cross", l, m - MAX_L); if (generatingREAL8) { hplusREAL8[l][m] = NULL; hcrossREAL8[l][m] = NULL; waveformsREAL8[l][m] = NULL; /* initilise waveform time series */ hplusREAL8[l][m] = XLALCreateREAL8TimeSeries(plus_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0); hcrossREAL8[l][m] = XLALCreateREAL8TimeSeries(cross_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0); } else { hplus[l][m] = NULL; hcross[l][m] = NULL; waveforms[l][m] = NULL; /* initilise waveform time series */ hplus[l][m] = XLALCreateREAL4TimeSeries(plus_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0); hcross[l][m] = XLALCreateREAL4TimeSeries(cross_channel[l][m], &epoch, 0, 0, &lalDimensionlessUnit, 0); } /* read ht-data section of metadata file */ snprintf(field, HISTORY_COMMENT, "%d,%d", l, m - MAX_L); XLAL_CHECK ( XLALReadConfigSTRINGVariable( &wf_name[l][m], meta_file, NULL, field, &wasRead) == XLAL_SUCCESS, XLAL_EFUNC ); /* read waveform */ if (wf_name[l][m] != NULL) { /* get full path to waveform data file */ snprintf(file_path, FILENAME_MAX, "%s/%s", nrDataDir, wf_name[l][m]); if (vrbflg) fprintf(stdout, "reading waveform: %s\n", file_path); /* read waveforms */ if (generatingREAL8) { LAL_CALL(LALReadNRWave_raw_real8(&status, &waveformsREAL8[l][m], file_path), &status); } else { LAL_CALL(LALReadNRWave_raw(&status, &waveforms[l][m], file_path), &status); } } /* generate waveform time series from vector series */ /* TODO: should use pointer arithmetic here and update the data * pointer in the REAL4TimeSeries to point to the appropriate * location within the REAL4TimeVector Series */ if (generatingREAL8) { if (waveformsREAL8[l][m]) { /* get length of waveform */ wf_length = waveformsREAL8[l][m]->data->vectorLength; /* allocate memory for waveform */ XLALResizeREAL8TimeSeries(hplusREAL8[l][m], 0, wf_length); XLALResizeREAL8TimeSeries(hcrossREAL8[l][m], 0, wf_length); /* set time spacing */ hplusREAL8[l][m]->deltaT = waveformsREAL8[l][m]->deltaT; hcrossREAL8[l][m]->deltaT = waveformsREAL8[l][m]->deltaT; /* copy waveforms into appropriate series */ for (i = 0; i < wf_length; i ++) { hplusREAL8[l][m]->data->data[i] = waveformsREAL8[l][m]->data->data[i]; hcrossREAL8[l][m]->data->data[i] = waveformsREAL8[l][m]->data->data[wf_length + i]; } /* Done with waveformsREAL8, clean up here to limit memory usage */ LALFree(waveformsREAL8[l][m]->data->data); LALFree(waveformsREAL8[l][m]->data); LALFree(waveformsREAL8[l][m]); } } else /* REAL4 */ { if (waveforms[l][m]) { /* get length of waveform */ wf_length = waveforms[l][m]->data->vectorLength; /* allocate memory for waveform */ XLALResizeREAL4TimeSeries(hplus[l][m], 0, wf_length); XLALResizeREAL4TimeSeries(hcross[l][m], 0, wf_length); /* set time spacing */ hplus[l][m]->deltaT = waveforms[l][m]->deltaT; hcross[l][m]->deltaT = waveforms[l][m]->deltaT; /* copy waveforms into appropriate series */ for (i = 0; i < wf_length; i ++) { hplus[l][m]->data->data[i] = waveforms[l][m]->data->data[i]; hcross[l][m]->data->data[i] = waveforms[l][m]->data->data[wf_length + i]; } } } /* add channels to frame */ if (generatingREAL8) { if ((hplusREAL8[l][m]->data->length) && (hcrossREAL8[l][m]->data->length)) { XLALFrameAddREAL8TimeSeriesSimData(frame, hplusREAL8[l][m]); XLALFrameAddREAL8TimeSeriesSimData(frame, hcrossREAL8[l][m]); } } else { if ((hplus[l][m]->data->length) && (hcross[l][m]->data->length)) { XLALFrameAddREAL4TimeSeriesSimData(frame, hplus[l][m]); XLALFrameAddREAL4TimeSeriesSimData(frame, hcross[l][m]); } } } } if (vrbflg) fprintf(stdout, "writing frame: %s\n", frame_name); /* write frame */ if (XLALFrameWrite(frame, frame_name) != 0 ) { fprintf(stderr, "Error: Cannot save frame file '%s'\n", frame_name); exit(1); } /* * clear memory */ /* strings */ if(nrMetaFile) free(nrMetaFile); if(nrDataDir) free(nrDataDir); if(frame_name) free(frame_name); if(metadata_format) free(metadata_format); /* common metadata */ if(md_mass_ratio) LALFree(md_mass_ratio); if(md_spin1x) LALFree(md_spin1x); if(md_spin1y) LALFree(md_spin1y); if(md_spin1z) LALFree(md_spin1z); if(md_spin2x) LALFree(md_spin2x); if(md_spin2y) LALFree(md_spin2y); if(md_spin2z) LALFree(md_spin2z); if(md_freq_start_22) LALFree(md_freq_start_22); /* NINJA1 metadata */ if(md_simulation_details) LALFree(md_simulation_details); if(md_nr_group) LALFree(md_nr_group); if(md_email) LALFree(md_email); /* NINJA2 metadata */ if(md_waveform_name) LALFree(md_waveform_name); if(md_initial_separation) LALFree(md_initial_separation); if(md_eccentricity) LALFree(md_eccentricity); if(md_number_of_cycles_22) LALFree(md_number_of_cycles_22); if(md_code) LALFree(md_code); if(md_submitter_email) LALFree(md_submitter_email); if(md_authors_emails) LALFree(md_authors_emails); /* config file */ if(meta_file->lines->list->data) LALFree(meta_file->lines->list->data); if(meta_file->lines->list) LALFree(meta_file->lines->list); if(meta_file->lines->tokens) LALFree(meta_file->lines->tokens); if(meta_file->lines) LALFree(meta_file->lines); if(meta_file->wasRead) LALFree(meta_file->wasRead); if(meta_file) LALFree(meta_file); /* waveforms */ if (generatingREAL8) { for (l = MIN_L; l <= MAX_L; l++) { for (m = (MAX_L - l); m <= MAX_L + l; m++) { /* channel names */ if (plus_channel[l][m]) LALFree(plus_channel[l][m]); if (cross_channel[l][m]) LALFree(cross_channel[l][m]); if (wf_name[l][m]) LALFree(wf_name[l][m]); /* hplus */ if (hplusREAL8[l][m]) XLALDestroyREAL8TimeSeries(hplusREAL8[l][m]); /* hcross */ if (hcrossREAL8[l][m]) XLALDestroyREAL8TimeSeries(hcrossREAL8[l][m]); } } } else { for (l = MIN_L; l <= MAX_L; l++) { for (m = (MAX_L - l); m <= MAX_L + l; m++) { /* channel names */ if (plus_channel[l][m]) LALFree(plus_channel[l][m]); if (cross_channel[l][m]) LALFree(cross_channel[l][m]); if (wf_name[l][m]) LALFree(wf_name[l][m]); /* raw waveforms */ if (waveforms[l][m]) { LALFree(waveforms[l][m]->data->data); LALFree(waveforms[l][m]->data); LALFree(waveforms[l][m]); } /* hplus */ if (hplus[l][m]) XLALDestroyREAL4TimeSeries(hplus[l][m]); /* hcross */ if (hcross[l][m]) XLALDestroyREAL4TimeSeries(hcross[l][m]); } } } /* clear frame */ XLALFrameFree(frame); /* check for memory leaks */ LALCheckMemoryLeaks(); exit(0); }
/* Everything needs to be declared as unused in case HDF is not enabled. */ int XLALSimInspiralNRWaveformGetHplusHcross( UNUSED REAL8TimeSeries **hplus, /**< Output h_+ vector */ UNUSED REAL8TimeSeries **hcross, /**< Output h_x vector */ UNUSED REAL8 phiRef, /**< orbital phase at reference pt. */ UNUSED REAL8 inclination, /**< inclination angle */ UNUSED REAL8 deltaT, /**< sampling interval (s) */ UNUSED REAL8 m1, /**< mass of companion 1 (kg) */ UNUSED REAL8 m2, /**< mass of companion 2 (kg) */ UNUSED REAL8 r, /**< distance of source (m) */ UNUSED REAL8 fStart, /**< start GW frequency (Hz) */ UNUSED REAL8 fRef, /**< reference GW frequency (Hz) */ UNUSED REAL8 s1x, /**< initial value of S1x */ UNUSED REAL8 s1y, /**< initial value of S1y */ UNUSED REAL8 s1z, /**< initial value of S1z */ UNUSED REAL8 s2x, /**< initial value of S2x */ UNUSED REAL8 s2y, /**< initial value of S2y */ UNUSED REAL8 s2z, /**< initial value of S2z */ UNUSED const char *NRDataFile /**< Location of NR HDF file */ ) { #ifndef LAL_HDF5_ENABLED XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled"); #else /* Declarations */ UINT4 curr_idx; INT4 model, modem; size_t array_length; REAL8 nrEta; REAL8 S1x, S1y, S1z, S2x, S2y, S2z; REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s; REAL8 chi, est_start_time, curr_h_real, curr_h_imag; REAL8 theta, psi, calpha, salpha; REAL8 distance_scale_fac; COMPLEX16 curr_ylm; REAL8TimeSeries *hplus_corr; REAL8TimeSeries *hcross_corr; /* These keys follow a strict formulation and cannot be longer than 11 * characters */ char amp_key[20]; char phase_key[20]; gsl_vector *tmpVector=NULL; LALH5File *file, *group; LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO; REAL8Vector *curr_amp, *curr_phase; /* Use solar masses for units. NR files will use * solar masses as well, so easier for that conversion */ m1 = m1 / LAL_MSUN_SI; m2 = m2 / LAL_MSUN_SI; file = XLALH5FileOpen(NRDataFile, "r"); /* Sanity checks on physical parameters passed to waveform * generator to guarantee consistency with NR data file. */ XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta"); if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "MASSES ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION.\n"); } /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure * the ChooseTDWaveform() input values are consistent with the data * recorded in the metadata of the HDF5 file. * PS: This assumes that the input spins are in the LAL frame! */ XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z, &S2x, &S2y, &S2z, file); if (fabs(S1x - s1x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1y - s1y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1z - s1z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2x - s2x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2y - s2y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2z - s2z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } /* First estimate the length of time series that is needed. * Demand that 22 mode that is present and use that to figure this out */ XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN"); /* Figure out start time of data */ group = XLALH5GroupOpen(file, "amp_l2_m2"); ReadHDF5RealVectorDataset(group, "knots", &tmpVector); time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0)); time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1)); gsl_vector_free(tmpVector); time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI; time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI; /* We don't want to return the *entire* waveform if it will be much longer * than the specified f_lower. Therefore guess waveform length using * the SEOBNR_ROM function and add 10% for safety. * FIXME: Is this correct for precessing waveforms? */ chi = XLALSimIMRPhenomBComputeChi(m1, m2, s1z, s2z); est_start_time = XLALSimIMRSEOBNRv2ChirpTimeSingleSpin(m1 * LAL_MSUN_SI, m2 * LAL_MSUN_SI, chi, fStart); est_start_time = (-est_start_time) * 1.1; if (est_start_time > time_start_s) { /* Restrict start time of waveform */ time_start_s = est_start_time; time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI); } else if (fStart < Mflower / (m1 + m2) ) { XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e", fStart, Mflower, Mflower / (m1 + m2)); } array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT)); /* Compute correct angles for hplus and hcross following LAL convention. */ theta = psi = calpha = salpha = 0.; XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha, &salpha, file, inclination, phiRef); /* Create the return time series, use arbitrary epoch here. We set this * properly later. */ XLALGPSAdd(&tmpEpoch, time_start_s); *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { hplus_corr->data->data[curr_idx] = 0.0; hcross_corr->data->data[curr_idx] = 0.0; } /* Create the distance scale factor */ distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r; /* Generate the waveform */ for (model=2; model < 9 ; model++) { for (modem=-model; modem < (model+1); modem++) { snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem); snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem); /* Check that both groups exist */ if (XLALH5CheckGroupExists(file, amp_key) == 0) { continue; } if (XLALH5CheckGroupExists(file, phase_key) == 0) { continue; } /* Get amplitude and phase from file */ XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2), time_start_s, array_length, deltaT, amp_key); XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2), time_start_s, array_length, deltaT, phase_key); curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2, model, modem); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { curr_h_real = curr_amp->data[curr_idx] * cos(curr_phase->data[curr_idx]) * distance_scale_fac; curr_h_imag = curr_amp->data[curr_idx] * sin(curr_phase->data[curr_idx]) * distance_scale_fac; hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx] + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm); hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx] - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm); } XLALDestroyREAL8Vector(curr_amp); XLALDestroyREAL8Vector(curr_phase); } } /* Correct for the "alpha" angle as given in T1600045 to translate * from the NR wave frame to LAL wave-frame * Helper time series needed. */ for (curr_idx = 0; curr_idx < array_length; curr_idx++) { (*hplus)->data->data[curr_idx] = (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx] - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx]; (*hcross)->data->data[curr_idx] = + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx] + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx]; } XLALDestroyREAL8TimeSeries(hplus_corr); XLALDestroyREAL8TimeSeries(hcross_corr); XLALH5FileClose(file); return XLAL_SUCCESS; #endif }
int XLALAddNumRelStrainModesREAL8( REAL8TimeSeries **seriesPlus, /**< [out] h+, hx data */ REAL8TimeSeries **seriesCross, /**< [out] h+, hx data */ SimInspiralTable *thisinj /**< [in] injection data */ ) { INT4 modeL, modeM, modeLlo, modeLhi; INT4 len, lenPlus, lenCross, k; CHAR *channel_name_plus; CHAR *channel_name_cross; LALFrStream *frStream = NULL; LALCache frCache; LIGOTimeGPS epoch; REAL8TimeSeries *modePlus=NULL; REAL8TimeSeries *modeCross=NULL; REAL8 massMpc, timeStep; modeLlo = thisinj->numrel_mode_min; modeLhi = thisinj->numrel_mode_max; /* create a frame cache and open the frame stream */ frCache.length = 1; frCache.list = LALCalloc(1, sizeof(frCache.list[0])); frCache.list[0].url = thisinj->numrel_data; frStream = XLALFrStreamCacheOpen( &frCache ); /* the total mass of the binary in Mpc */ massMpc = (thisinj->mass1 + thisinj->mass2) * LAL_MRSUN_SI / ( LAL_PC_SI * 1.0e6); /* Time step in dimensionful units */ timeStep = (thisinj->mass1 + thisinj->mass2) * LAL_MTSUN_SI; /* start time of waveform -- set it to something */ epoch.gpsSeconds = thisinj->geocent_end_time.gpsSeconds; epoch.gpsNanoSeconds = thisinj->geocent_end_time.gpsNanoSeconds; /* loop over l values */ for ( modeL = modeLlo; modeL <= modeLhi; modeL++ ) { /* loop over m values */ for ( modeM = -modeL; modeM <= modeL; modeM++ ) { /* read numrel waveform */ /* first the plus polarization */ channel_name_plus = XLALGetNinjaChannelName("plus", modeL, modeM); /*get number of data points */ if (XLALCheckFrameHasChannel(channel_name_plus, frStream ) ) { lenPlus = XLALFrStreamGetVectorLength ( channel_name_plus, frStream ); } else { lenPlus = -1; } /* now the cross polarization */ channel_name_cross = XLALGetNinjaChannelName("cross", modeL, modeM); /*get number of data points */ if (XLALCheckFrameHasChannel(channel_name_cross, frStream ) ) { lenCross = XLALFrStreamGetVectorLength ( channel_name_cross, frStream ); } else { lenCross = -1; } /* skip on to next mode if mode doesn't exist */ if ( (lenPlus <= 0) || (lenCross <= 0) || (lenPlus != lenCross) ) { XLALClearErrno(); LALFree(channel_name_plus); LALFree(channel_name_cross); continue; } /* note: lenPlus and lenCross must be equal if we got this far*/ len = lenPlus; /* allocate and read the plus/cross time series */ modePlus = XLALCreateREAL8TimeSeries ( channel_name_plus, &epoch, 0, 0, &lalDimensionlessUnit, len); memset(modePlus->data->data, 0, modePlus->data->length*sizeof(REAL8)); XLALFrStreamGetREAL8TimeSeries ( modePlus, frStream ); XLALFrStreamRewind( frStream ); LALFree(channel_name_plus); modeCross = XLALCreateREAL8TimeSeries ( channel_name_cross, &epoch, 0, 0, &lalDimensionlessUnit, len); memset(modeCross->data->data, 0, modeCross->data->length*sizeof(REAL8)); XLALFrStreamGetREAL8TimeSeries ( modeCross, frStream ); XLALFrStreamRewind( frStream ); LALFree(channel_name_cross); /* scale and add */ if (*seriesPlus == NULL) { *seriesPlus = XLALCreateREAL8TimeSeries ( "hplus", &epoch, 0, 0, &lalDimensionlessUnit, len); memset((*seriesPlus)->data->data, 0, (*seriesPlus)->data->length*sizeof(REAL8)); (*seriesPlus)->deltaT = modePlus->deltaT; } if (*seriesCross == NULL) { *seriesCross = XLALCreateREAL8TimeSeries ( "hcross", &epoch, 0, 0, &lalDimensionlessUnit, len); memset((*seriesCross)->data->data, 0, (*seriesCross)->data->length*sizeof(REAL8)); (*seriesCross)->deltaT = modeCross->deltaT; } XLALOrientNRWaveTimeSeriesREAL8( modePlus, modeCross, modeL, modeM, thisinj->inclination, thisinj->coa_phase ); for (k = 0; k < len; k++) { (*seriesPlus)->data->data[k] += massMpc * modePlus->data->data[k]; (*seriesCross)->data->data[k] += massMpc * modeCross->data->data[k]; } /* we are done with seriesPlus and Cross for this iteration */ XLALDestroyREAL8TimeSeries (modePlus); XLALDestroyREAL8TimeSeries (modeCross); } /* end loop over modeM values */ } /* end loop over modeL values */ (*seriesPlus)->deltaT *= timeStep; (*seriesCross)->deltaT *= timeStep; XLALFrStreamClose( frStream ); LALFree(frCache.list); return XLAL_SUCCESS; }
/** * Chooses between different approximants when requesting a waveform to be generated * Returns the waveform in the time 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 XLALSimInspiralChooseTDWaveformFromCache( REAL8TimeSeries **hplus, /**< +-polarization waveform */ REAL8TimeSeries **hcross, /**< x-polarization waveform */ REAL8 phiRef, /**< reference orbital phase (rad) */ REAL8 deltaT, /**< sampling interval (s) */ 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_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; use NULL for no caching */ ) { int status; size_t j; REAL8 phasediff, dist_ratio, incl_ratio_plus, incl_ratio_cross; REAL8 cosrot, sinrot; CacheVariableDiffersBitmask changedParams; // If nonGRparams are not NULL, don't even try to cache. if ( !XLALSimInspiralWaveformParamsNonGRAreDefault(LALpars) || (!cache) ) return XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); // Check which parameters have changed changedParams = CacheArgsDifferenceBitmask(cache, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, 0., r, i, LALpars, approximant, NULL); // No parameters have changed! Copy the cached polarizations if( changedParams == NO_DIFFERENCE ) { *hplus = XLALCutREAL8TimeSeries(cache->hplus, 0, cache->hplus->data->length); if (*hplus == NULL) return XLAL_ENOMEM; *hcross = XLALCutREAL8TimeSeries(cache->hcross, 0, cache->hcross->data->length); if (*hcross == NULL) { XLALDestroyREAL8TimeSeries(*hplus); *hplus = NULL; return XLAL_ENOMEM; } return XLAL_SUCCESS; } // Intrinsic parameters have changed. We must generate a new waveform if( (changedParams & INTRINSIC) != 0 ) { status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } INT4 ampO=XLALSimInspiralWaveformParamsLookupPNAmplitudeOrder(LALpars); // case 1: Precessing waveforms if( approximant == SpinTaylorT4 || approximant == SpinTaylorT2 ) { // 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->hplus == NULL || cache->hcross == NULL) { status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } if( changedParams & INCLINATION ) { // FIXME: For now just treat as intrinsic parameter. // Will come back and put in transformation status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } if( changedParams & PHI_REF ) { // FIXME: For now just treat as intrinsic parameter. // Will come back and put in transformation status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } if( (changedParams & DISTANCE) != 0 ) { // Return rescaled copy of cached polarizations dist_ratio = cache->r / r; *hplus = XLALCreateREAL8TimeSeries(cache->hplus->name, &(cache->hplus->epoch), cache->hplus->f0, cache->hplus->deltaT, &(cache->hplus->sampleUnits), cache->hplus->data->length); if (*hplus == NULL) return XLAL_ENOMEM; *hcross = XLALCreateREAL8TimeSeries(cache->hcross->name, &(cache->hcross->epoch), cache->hcross->f0, cache->hcross->deltaT, &(cache->hcross->sampleUnits), cache->hcross->data->length); if (*hcross == NULL) { XLALDestroyREAL8TimeSeries(*hplus); *hplus = NULL; return XLAL_ENOMEM; } for (j = 0; j < cache->hplus->data->length; j++) { (*hplus)->data->data[j] = cache->hplus->data->data[j] * dist_ratio; (*hcross)->data->data[j] = cache->hcross->data->data[j] * dist_ratio; } } return XLAL_SUCCESS; } // case 2: Non-precessing, ampO = 0 else if( ampO==0 && (approximant==TaylorT1 || approximant==TaylorT2 || approximant==TaylorT3 || approximant==TaylorT4 || approximant==EOBNRv2 || approximant==SEOBNRv1) ) { // If polarizations are not cached we must generate a fresh waveform if( cache->hplus == NULL || cache->hcross == NULL) { status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } // Set transformation coefficients for identity transformation. // We'll adjust them depending on which extrinsic parameters changed. dist_ratio = incl_ratio_plus = incl_ratio_cross = cosrot = 1.; phasediff = sinrot = 0.; if( changedParams & PHI_REF ) { // Only 2nd harmonic present, so {h+,hx} rotates by 2*deltaphiRef phasediff = 2.*(phiRef - cache->phiRef); cosrot = cos(phasediff); sinrot = sin(phasediff); } 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 *hplus = XLALCreateREAL8TimeSeries(cache->hplus->name, &(cache->hplus->epoch), cache->hplus->f0, cache->hplus->deltaT, &(cache->hplus->sampleUnits), cache->hplus->data->length); if (*hplus == NULL) return XLAL_ENOMEM; *hcross = XLALCreateREAL8TimeSeries(cache->hcross->name, &(cache->hcross->epoch), cache->hcross->f0, cache->hcross->deltaT, &(cache->hcross->sampleUnits), cache->hcross->data->length); if (*hcross == NULL) { XLALDestroyREAL8TimeSeries(*hplus); *hplus = NULL; return XLAL_ENOMEM; } // Get new polarizations by transforming the old incl_ratio_plus *= dist_ratio; incl_ratio_cross *= dist_ratio; // FIXME: Do changing phiRef and inclination commute?!?! for (j = 0; j < cache->hplus->data->length; j++) { (*hplus)->data->data[j] = incl_ratio_plus * (cosrot*cache->hplus->data->data[j] - sinrot*cache->hcross->data->data[j]); (*hcross)->data->data[j] = incl_ratio_cross * (sinrot*cache->hplus->data->data[j] + cosrot*cache->hcross->data->data[j]); } return XLAL_SUCCESS; } // case 3: Non-precessing, ampO > 0 // FIXME: EOBNRv2HM actually ignores ampO. If it's given with ampO==0, // it will fall to the catch-all and not be cached. else if( (ampO==-1 || ampO>0) && (approximant==TaylorT1 || approximant==TaylorT2 || approximant==TaylorT3 || approximant==TaylorT4 || approximant==EOBNRv2HM) ) { // If polarizations are not cached we must generate a fresh waveform // FIXME: Add in check that hlms non-NULL if( cache->hplus == NULL || cache->hcross == NULL) { // FIXME: This will change to a code-path: inputs->hlms->{h+,hx} status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } if( changedParams & INCLINATION) { // FIXME: For now just treat as intrinsic parameter. // Will come back and put in transformation status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } if( changedParams & PHI_REF ) { // FIXME: For now just treat as intrinsic parameter. // Will come back and put in transformation status = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); if (status == XLAL_FAILURE) return status; // FIXME: Need to add hlms, dynamic variables, etc. in cache return StoreTDHCache(cache, *hplus, *hcross, phiRef, deltaT, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, f_min, f_ref, r, i, LALpars, approximant); } if( changedParams & DISTANCE ) { // Return rescaled copy of cached polarizations dist_ratio = cache->r / r; *hplus = XLALCreateREAL8TimeSeries(cache->hplus->name, &(cache->hplus->epoch), cache->hplus->f0, cache->hplus->deltaT, &(cache->hplus->sampleUnits), cache->hplus->data->length); if (*hplus == NULL) return XLAL_ENOMEM; *hcross = XLALCreateREAL8TimeSeries(cache->hcross->name, &(cache->hcross->epoch), cache->hcross->f0, cache->hcross->deltaT, &(cache->hcross->sampleUnits), cache->hcross->data->length); if (*hcross == NULL) { XLALDestroyREAL8TimeSeries(*hplus); *hplus = NULL; return XLAL_ENOMEM; } for (j = 0; j < cache->hplus->data->length; j++) { (*hplus)->data->data[j] = cache->hplus->data->data[j] * dist_ratio; (*hcross)->data->data[j] = cache->hcross->data->data[j] * dist_ratio; } } return XLAL_SUCCESS; } // 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 { return XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, r, i, phiRef, 0., 0., 0., deltaT, f_min, f_ref, LALpars, approximant); } }
/* creates a waveform in the time domain; the waveform might be generated in * the frequency-domain and transformed */ int create_td_waveform(REAL8TimeSeries ** h_plus, REAL8TimeSeries ** h_cross, struct params p) { clock_t timer_start = 0; if (p.condition) { if (p.verbose) { fprintf(stderr, "generating waveform in time domain using XLALSimInspiralTD...\n"); timer_start = clock(); } XLALSimInspiralTD(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); } else if (p.domain == LAL_SIM_DOMAIN_TIME) { /* 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); } else { COMPLEX16FrequencySeries *htilde_plus = NULL; COMPLEX16FrequencySeries *htilde_cross = NULL; REAL8FFTPlan *plan; double chirplen, deltaF; int chirplen_exp; /* determine required frequency resolution */ /* 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); /* generate waveform in frequency domain */ 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); /* put the waveform in the time domain */ if (p.verbose) { fprintf(stderr, "transforming waveform to time domain...\n"); timer_start = clock(); } *h_plus = XLALCreateREAL8TimeSeries("h_plus", &htilde_plus->epoch, 0.0, 1.0 / p.srate, &lalStrainUnit, (size_t) chirplen); *h_cross = XLALCreateREAL8TimeSeries("h_cross", &htilde_cross->epoch, 0.0, 1.0 / p.srate, &lalStrainUnit, (size_t) chirplen); plan = XLALCreateReverseREAL8FFTPlan((size_t) chirplen, 0); XLALREAL8FreqTimeFFT(*h_cross, htilde_cross, plan); XLALREAL8FreqTimeFFT(*h_plus, htilde_plus, plan); if (p.verbose) fprintf(stderr, "transformation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC); /* clean up */ XLALDestroyREAL8FFTPlan(plan); XLALDestroyCOMPLEX16FrequencySeries(htilde_cross); XLALDestroyCOMPLEX16FrequencySeries(htilde_plus); } return 0; }
/* read and high pass filter a GEO time series */ REAL4TimeSeries *get_geo_data(LALFrStream *stream, CHAR *channel, LIGOTimeGPS start, LIGOTimeGPS end, INT4 hpf_order, REAL8 hpf_frequency, REAL8 hpf_attenuation) { /* variables */ PassBandParamStruc high_pass_params; REAL4TimeSeries *series; REAL8TimeSeries *geo; size_t length; size_t i; if (vrbflg) fprintf(stdout, "Allocating memory for \"%s\" series...\n", channel); /* create and initialise time series */ geo = XLALCreateREAL8TimeSeries(channel, &start, 0, 0, \ &lalADCCountUnit, 0); if (vrbflg) fprintf(stdout, "Reading \"%s\" series metadata...\n", channel); /* get the series meta data */ XLALFrStreamGetREAL8TimeSeriesMetadata(geo, stream); if (vrbflg) fprintf(stdout, "Resizing \"%s\" series...\n", channel); /* resize series to the correct number of samples */ length = floor((XLALGPSDiff(&end, &start) / geo->deltaT) + 0.5); XLALResizeREAL8TimeSeries(geo, 0, length); if (vrbflg) fprintf(stdout, "Reading channel \"%s\"...\n", channel); /* seek to and read data */ XLALFrStreamSeek(stream, &start); XLALFrStreamGetREAL8TimeSeries(geo, stream); if (vrbflg) fprintf(stdout, "High pass filtering \"%s\"...\n", channel); /* high pass filter before casting to a REAL4 */ high_pass_params.nMax = hpf_order; high_pass_params.f1 = -1; high_pass_params.f2 = hpf_frequency; high_pass_params.a1 = -1; high_pass_params.a2 = hpf_attenuation; XLALButterworthREAL8TimeSeries(geo, &high_pass_params); if (vrbflg) fprintf(stdout, "Casting \"%s\" as a REAL4...\n", channel); /* cast as a REAL4 */ series = XLALCreateREAL4TimeSeries(geo->name, &geo->epoch, geo->f0, \ geo->deltaT, &geo->sampleUnits, geo->data->length); for (i = 0; i < series->data->length; i++) series->data->data[i] = (REAL4)geo->data->data[i]; /* destroy geo series */ XLALDestroyREAL8TimeSeries(geo); return(series); }