/** * Restrict the EphemerisData 'edat' to the smallest number of entries * required to cover the GPS time range ['startGPS', 'endGPS'] * * \ingroup LALBarycenter_h */ int XLALRestrictEphemerisData ( EphemerisData *edat, const LIGOTimeGPS *startGPS, const LIGOTimeGPS *endGPS ) { // Check input XLAL_CHECK(edat != NULL, XLAL_EFAULT); XLAL_CHECK(startGPS != NULL, XLAL_EFAULT); XLAL_CHECK(endGPS != NULL, XLAL_EFAULT); XLAL_CHECK(XLALGPSCmp(startGPS, endGPS) < 0, XLAL_EINVAL); // Convert 'startGPS' and 'endGPS' to REAL8s const REAL8 start = XLALGPSGetREAL8(startGPS), end = XLALGPSGetREAL8(endGPS); // Increase 'ephemE' and decrease 'nentriesE' to fit the range ['start', 'end'] PosVelAcc *const old_ephemE = edat->ephemE; do { if (edat->nentriesE > 1 && edat->ephemE[0].gps < start && edat->ephemE[1].gps <= start) { ++edat->ephemE; --edat->nentriesE; } else if (edat->nentriesE > 1 && edat->ephemE[edat->nentriesE-1].gps > end && edat->ephemE[edat->nentriesE-2].gps >= end) { --edat->nentriesE; } else { break; } } while(1); // Reallocate 'ephemE' to new table size, and free old table PosVelAcc *const new_ephemE = XLALMalloc(edat->nentriesE * sizeof(*new_ephemE)); XLAL_CHECK(new_ephemE != NULL, XLAL_ENOMEM); memcpy(new_ephemE, edat->ephemE, edat->nentriesE * sizeof(*new_ephemE)); edat->ephemE = new_ephemE; XLALFree(old_ephemE); // Increase 'ephemS' and decrease 'nentriesS' to fit the range ['start', 'end'] PosVelAcc *const old_ephemS = edat->ephemS; do { if (edat->nentriesS > 1 && edat->ephemS[0].gps < start && edat->ephemS[1].gps <= start) { ++edat->ephemS; --edat->nentriesS; } else if (edat->nentriesS > 1 && edat->ephemS[edat->nentriesS-1].gps > end && edat->ephemS[edat->nentriesS-2].gps >= end) { --edat->nentriesS; } else { break; } } while(1); // Reallocate 'ephemS' to new table size, and free old table PosVelAcc *const new_ephemS = XLALMalloc(edat->nentriesS * sizeof(*new_ephemS)); XLAL_CHECK(new_ephemS != NULL, XLAL_ENOMEM); memcpy(new_ephemS, edat->ephemS, edat->nentriesS * sizeof(*new_ephemS)); edat->ephemS = new_ephemS; XLALFree(old_ephemS); return XLAL_SUCCESS; } /* XLALRestrictEphemerisData() */
static int dump_TD2(FILE *f, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross) { size_t i; REAL8 t0 = XLALGPSGetREAL8(&(hplus->epoch)); REAL8 threshold=5.; // Threshold to determine phase wrap-around REAL8 *dataPtr1 = hplus->data->data; REAL8 *dataPtr2 = hcross->data->data; if (hplus->data->length != hcross->data->length) { XLALPrintError("Error: hplus and hcross are not the same length\n"); return 1; } else if (hplus->deltaT != hcross->deltaT) { XLALPrintError("Error: hplus and hcross do not have the same sample rate\n"); return 1; } REAL8 amp[hplus->data->length]; REAL8 phase[hplus->data->length]; REAL8 phaseUW[hplus->data->length]; for (i=0; i < hplus->data->length; i++) { amp[i] = sqrt( dataPtr1[i]*dataPtr1[i] + dataPtr2[i]*dataPtr2[i]); phase[i] = atan2(-dataPtr2[i], dataPtr1[i]); } unwind_phase(phaseUW, phase, hplus->data->length, threshold); fprintf(f, "# t amp phase\n"); for (i=0; i < hplus->data->length; i++) fprintf(f, "%.16e %.16e %.16e\n", t0 + i * hplus->deltaT, amp[i], phaseUW[i]); return 0; }
/** * Compare 2 SSBtimes vectors and return the maximal difference in * DeltaT in s, and in Tdot (dimensionless) */ int XLALCompareSSBtimes ( REAL8 *err_DeltaT, REAL8 *err_Tdot, const SSBtimes *t1, const SSBtimes *t2 ) { XLAL_CHECK ( err_DeltaT != NULL, XLAL_EINVAL ); XLAL_CHECK ( err_Tdot != NULL, XLAL_EINVAL ); XLAL_CHECK ( t1 != NULL, XLAL_EINVAL ); XLAL_CHECK ( t2 != NULL, XLAL_EINVAL ); XLAL_CHECK ( (t1->DeltaT != NULL) && (t1->Tdot != NULL), XLAL_EINVAL ); XLAL_CHECK ( XLALGPSDiff ( &(t1->refTime), &(t2->refTime) ) == 0, XLAL_ETOL, "Different reference-times: %f != %f\n", XLALGPSGetREAL8(&(t1->refTime)), XLALGPSGetREAL8(&(t2->refTime))); UINT4 numSteps = t1->DeltaT->length; XLAL_CHECK ( t1->Tdot->length == numSteps, XLAL_EINVAL ); XLAL_CHECK ( t2->DeltaT->length == numSteps, XLAL_EINVAL ); XLAL_CHECK ( t2->Tdot->length == numSteps, XLAL_EINVAL ); REAL8 max_DeltaT = 0; REAL8 max_Tdot = 0; for ( UINT4 i = 0; i < numSteps; i ++ ) { REAL8 DeltaT_i = fabs ( t1->DeltaT->data[i] - t2->DeltaT->data[i] ); REAL8 Tdot_i = fabs ( t1->Tdot->data[i] - t2->Tdot->data[i] ); max_DeltaT = fmax ( max_DeltaT, DeltaT_i ); max_Tdot = fmax ( max_Tdot, Tdot_i ); } // for i < numSteps (*err_DeltaT) = max_DeltaT; (*err_Tdot) = max_Tdot; return XLAL_SUCCESS; } // XLALCompareSSBtimes()
/** * Divide a GPS time by a number. Computes gps / x and places the result * in gps. Returns gps on success, NULL on failure. */ LIGOTimeGPS *XLALGPSDivide( LIGOTimeGPS *gps, REAL8 x ) { LIGOTimeGPS quotient; double residual; if(isnan(x)) { XLALPrintError("%s(): NaN", __func__); XLAL_ERROR_NULL(XLAL_EFPINVAL); } if(x == 0) { XLALPrintError("%s(): divide by zero", __func__); XLAL_ERROR_NULL(XLAL_EFPDIV0); } /* initial guess */ if(!XLALGPSSetREAL8("ient, XLALGPSGetREAL8(gps) / x)) XLAL_ERROR_NULL(XLAL_EFUNC); /* use Newton's method to iteratively solve for quotient. strictly * speaking we're using Newton's method to solve for the inverse of * XLALGPSMultiply(), which we assume implements multiplication. */ do { LIGOTimeGPS workspace = quotient; if(!XLALGPSMultiply(&workspace, x)) XLAL_ERROR_NULL(XLAL_EFUNC); residual = XLALGPSDiff(gps, &workspace) / x; if(!XLALGPSAdd("ient, residual)) XLAL_ERROR_NULL(XLAL_EFUNC); } while(fabs(residual) > 0.5e-9); *gps = quotient; return gps; }
void LALInferenceDumptemplateTimeDomain(LALInferenceVariables *currentParams, LALInferenceModel *model, const char *filename) /* de-bugging function writing (frequency-domain) template to a CSV file */ /* File contains real & imaginary parts of plus & cross components. */ /* Template amplitude is scaled to 1Mpc distance. */ { FILE *outfile=NULL; REAL8 deltaT, t, epoch; // deltaF - set but not used UINT4 i; LALInferenceCopyVariables(currentParams, model->params); model->templt(model); if (model->domain == LAL_SIM_DOMAIN_FREQUENCY) LALInferenceExecuteInvFT(model); outfile = fopen(filename, "w"); fprintf(outfile, "\"t\",\"signalPlus\",\"signalCross\"\n"); deltaT = model->deltaT; epoch = XLALGPSGetREAL8(&model->timehPlus->epoch); for (i=0; i<model->timehPlus->data->length; ++i){ t = epoch + ((double) i) * deltaT; fprintf(outfile, "%f,%e,%e\n", t, model->timehPlus->data->data[i], model->timehCross->data->data[i]); } fclose(outfile); fprintf(stdout, " wrote (time-domain) template to CSV file \"%s\".\n", filename); }
static PyObject *__float__(PyObject *self) { LIGOTimeGPS gps; if(!pyobject_to_ligotimegps(self, &gps)) return NULL; return PyFloat_FromDouble(XLALGPSGetREAL8(&gps)); }
/** * \brief Split the data into segments * * This function is deprecated to \c chop_n_merge, but gives the functionality of the old code. * * It cuts the data into as many contiguous segments of data as possible of length \c chunkMax. Where contiguous is * defined as containing consecutive point within 180 seconds of each other. The length of segments that do not fit into * a \c chunkMax length are also included. * * \param ifo [in] the LALInferenceIFOModel variable * \param chunkMax [in] the maximum length of a data chunk/segment * * \return A vector of chunk/segment lengths */ UINT4Vector *get_chunk_lengths( LALInferenceIFOModel *ifo, UINT4 chunkMax ){ UINT4 i = 0, j = 0, count = 0; UINT4 length; REAL8 t1, t2; UINT4Vector *chunkLengths = NULL; length = ifo->times->length; chunkLengths = XLALCreateUINT4Vector( length ); REAL8 dt = *(REAL8*)LALInferenceGetVariable( ifo->params, "dt" ); /* create vector of data segment length */ while( 1 ){ count++; /* counter */ /* break clause */ if( i > length - 2 ){ /* set final value of chunkLength */ chunkLengths->data[j] = count; j++; break; } i++; t1 = XLALGPSGetREAL8( &ifo->times->data[i-1] ); t2 = XLALGPSGetREAL8( &ifo->times->data[i] ); /* if consecutive points are within two sample times of each other count as in the same chunk */ if( t2 - t1 > 2.*dt || count == chunkMax ){ chunkLengths->data[j] = count; count = 0; /* reset counter */ j++; } } chunkLengths = XLALResizeUINT4Vector( chunkLengths, j ); return chunkLengths; }
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; }
/** * @brief Opens a LALFrStream associated with a LALCache * @details * This routine creates a #LALFrStream that is a stream associated with * the frame files contained in a LALCache. * @param cache Pointer to a LALCache structure describing the frame files to stream. * @returns Pointer to a newly created #LALFrStream structure. * @retval NULL Failure. */ LALFrStream *XLALFrStreamCacheOpen(LALCache * cache) { LALFrStream *stream; size_t i; if (!cache) XLAL_ERROR_NULL(XLAL_EFAULT); stream = LALCalloc(1, sizeof(*stream)); if (!stream) XLAL_ERROR_NULL(XLAL_ENOMEM); stream->cache = XLALCacheDuplicate(cache); /* check cache entries for t0 and dt; if these are not set then read * the framefile to try to get them */ for (i = 0; i < stream->cache->length; ++i) { if (stream->cache->list[i].t0 == 0 || stream->cache->list[i].dt == 0) { LIGOTimeGPS end; size_t nFrame; if (XLALFrStreamFileOpen(stream, i) < 0) { XLALFrStreamClose(stream); XLAL_ERROR_NULL(XLAL_EIO); } nFrame = XLALFrFileQueryNFrame(stream->file); stream->cache->list[i].t0 = stream->epoch.gpsSeconds; XLALFrFileQueryGTime(&end, stream->file, nFrame - 1); XLALGPSAdd(&end, XLALFrFileQueryDt(stream->file, nFrame - 1)); stream->cache->list[i].dt = ceil(XLALGPSGetREAL8(&end)) - stream->cache->list[i].t0; XLALFrStreamFileClose(stream); } } /* sort and uniqify the cache */ if (XLALCacheSort(stream->cache) || XLALCacheUniq(stream->cache)) { XLALFrStreamClose(stream); XLAL_ERROR_NULL(XLAL_EFUNC); } stream->mode = LAL_FR_STREAM_DEFAULT_MODE; /* open up the first file */ if (XLALFrStreamFileOpen(stream, 0) < 0) { XLALFrStreamClose(stream); XLAL_ERROR_NULL(XLAL_EFUNC); } return stream; }
void LALInferenceTemplateSineGaussian(LALInferenceModel *model) /*****************************************************/ /* Sine-Gaussian (burst) template. */ /* Signal is (by now?) linearly polarised, */ /* i.e., the cross-waveform remains zero. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The (plus-) waveform is: */ /* a * exp(-((t-mu)/sigma)^2) * sin(2*pi*f*t-phi) */ /* Note that by setting f=0, phi=pi/2 you also get */ /* a `pure' Gaussian template. */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * ************************************/ /* Required (`model->params') parameters are: */ /* - "time" (the "mu" parameter of the Gaussian part; REAL8, GPS sec.) */ /* - "sigma" (width, the "sigma" parameter of the Gaussian part; REAL8, seconds) */ /* - "frequency" (frequency of the sine part; REAL8, Hertz) */ /* - "phase" (phase (at above "mu"); REAL8, radians) */ /* - "amplitude" (amplitude, REAL8) */ /****************************************************************************************/ { double endtime = *(REAL8*) LALInferenceGetVariable(model->params, "time"); /* time parameter ("mu"), GPS sec. */ double sigma = *(REAL8*) LALInferenceGetVariable(model->params, "sigma"); /* width parameter, seconds */ double f = *(REAL8*) LALInferenceGetVariable(model->params, "frequency"); /* frequency, Hz */ double phi = *(REAL8*) LALInferenceGetVariable(model->params, "phase"); /* phase, rad */ double a = *(REAL8*) LALInferenceGetVariable(model->params, "amplitude"); /* amplitude */ double t, tsigma, twopif = LAL_TWOPI*f; double epochGPS = XLALGPSGetREAL8(&(model->timehPlus->epoch)); unsigned long i; if (sigma <= 0.0) { fprintf(stderr, " ERROR in templateSineGaussian(): zero or negative \"sigma\" parameter (sigma=%e).\n", sigma); exit(1); } if (f < 0.0) fprintf(stderr, " WARNING in templateSineGaussian(): negative \"frequency\" parameter (f=%e).\n", f); if (a < 0.0) fprintf(stderr, " WARNING in templateSineGaussian(): negative \"amplitude\" parameter (a=%e).\n", a); for (i=0; i<model->timehPlus->data->length; ++i){ t = ((double)i)*model->deltaT + (epochGPS-endtime); /* t-mu */ tsigma = t/sigma; /* (t-mu)/sigma */ if (fabs(tsigma) < 5.0) /* (only do computations within a 10 sigma range) */ model->timehPlus->data->data[i] = a * exp(-0.5*tsigma*tsigma) * sin(twopif*t+phi); else model->timehPlus->data->data[i] = 0.0; model->timehCross->data->data[i] = 0.0; } model->domain = LAL_SIM_DOMAIN_TIME; return; }
static int dump_TD(FILE *f, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross) { size_t i; REAL8 t0 = XLALGPSGetREAL8(&(hplus->epoch)); if (hplus->data->length != hcross->data->length) { XLALPrintError("Error: hplus and hcross are not the same length\n"); return 1; } else if (hplus->deltaT != hcross->deltaT) { XLALPrintError("Error: hplus and hcross do not have the same sample rate\n"); return 1; } fprintf(f, "# t hplus hcross\n"); for (i=0; i < hplus->data->length; i++) fprintf(f, "%.16e %.16e %.16e\n", t0 + i * hplus->deltaT, hplus->data->data[i], hcross->data->data[i]); return 0; }
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; }
void LALInferenceTemplateDampedSinusoid(LALInferenceModel *model) /*****************************************************/ /* Damped Sinusoid (burst) template. */ /* Signal is linearly polarized, */ /* i.e., cross term is zero. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The (plus-) waveform is an exponentially decaying */ /* sine wave: */ /* a * exp((t-time)/tau) * sin(2*pi*f*(t-time)) */ /* where "time" is the time parameter denoting the */ /* instant where the signal starts. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * **************************/ /* Required (`model->params') parameters are: */ /* - "time" (the instant at which the signal starts; REAL8, GPS sec.) */ /* - "tau" (width parameter; REAL8, seconds) */ /* - "frequency" (frequency of the sine part; REAL8, Hertz) */ /* - "amplitude" (amplitude, REAL8) */ /******************************************************************************/ { double endtime = *(REAL8*) LALInferenceGetVariable(model->params, "time"); /* time parameter ("mu"), GPS sec. */ double tau = *(REAL8*) LALInferenceGetVariable(model->params, "tau"); /* width parameter, seconds */ double f = *(REAL8*) LALInferenceGetVariable(model->params, "frequency"); /* frequency, Hz */ double a = *(REAL8*) LALInferenceGetVariable(model->params, "amplitude"); /* amplitude */ double t, ttau, twopif = LAL_TWOPI*f; double epochGPS = XLALGPSGetREAL8(&(model->timehPlus->epoch)); unsigned long i; if (tau <= 0.0) { fprintf(stderr, " ERROR in templateDampedSinusoid(): zero or negative \"tau\" parameter (tau=%e).\n", tau); exit(1); } if (f < 0.0) fprintf(stderr, " WARNING in templateDampedSinusoid(): negative \"frequency\" parameter (f=%e).\n", f); for (i=0; i<model->timehPlus->data->length; ++i){ t = ((double)i)*model->deltaT + (epochGPS-endtime); /* t-mu */ if ((t>0.0) && ((ttau=t/tau) < 10.0)) /* (only do computations within a 10 tau range) */ model->timehPlus->data->data[i] = a * exp(-ttau) * sin(twopif*t); else model->timehPlus->data->data[i] = 0.0; model->timehCross->data->data[i] = 0.0; } model->domain = LAL_SIM_DOMAIN_TIME; return; }
/** * Write a REAL4TimeSeries in a 2-column ASCII format (lines of "GPS_i data_i") * into an open file 'fp' */ int XLALWriteREAL4TimeSeries2fp ( FILE *fp, const REAL4TimeSeries *TS ) { XLAL_CHECK ( fp != NULL, XLAL_EINVAL ); XLAL_CHECK ( TS != NULL, XLAL_EINVAL ); XLAL_CHECK ( (TS->data != NULL) && (TS->data->length >0) && (TS->data->data != NULL), XLAL_EINVAL ); REAL8 t0 = XLALGPSGetREAL8( &(TS->epoch) ); XLAL_CHECK ( xlalErrno == 0, XLAL_EFAULT, "XLALGPSGetREAL8(%d,%d) failed\n", TS->epoch.gpsSeconds, TS->epoch.gpsNanoSeconds ); for( UINT4 i = 0; i < TS->data->length; i++) { REAL8 ti = t0 + i * TS->deltaT; XLAL_CHECK ( fprintf( fp, "%16.9f %e\n", ti, TS->data->data[i] ) > 0, XLAL_EIO ); } return XLAL_SUCCESS; } /* XLALWriteREAL4TimeSeries2fp() */
/* writes a time-domain waveform to stdout as tab-separated values */ int output_td_waveform(REAL8TimeSeries * h_plus, REAL8TimeSeries * h_cross, struct params p) { double t0; size_t j; t0 = XLALGPSGetREAL8(&h_plus->epoch); if (p.amp_phase) { REAL8Sequence *amp = XLALCreateREAL8Sequence(h_plus->data->length); REAL8Sequence *phi = XLALCreateREAL8Sequence(h_plus->data->length); double phi0; /* compute the amplitude and phase of h+ - i hx */ for (j = 0; j < h_plus->data->length; ++j) { double complex z = h_plus->data->data[j] - I * h_cross->data->data[j]; amp->data[j] = cabs(z); phi->data[j] = carg(z); } /* unwrap the phase */ XLALREAL8VectorUnwrapAngle(phi, phi); /* make phase in range -pi to +pi at end of waveform */ /* extrapolate the end of the waveform using last and second last points */ phi0 = 2 * phi->data[phi->length - 1] - phi->data[phi->length - 2]; // phi0 = phi->data[phi->length - 1]; phi0 -= fmod(phi0 + copysign(LAL_PI, phi0), 2.0 * LAL_PI) - copysign(LAL_PI, phi0); for (j = 0; j < phi->length; ++j) phi->data[j] -= phi0; fprintf(stdout, "# time (s)\th_abs (strain)\t h_arg (rad)\n"); for (j = 0; j < h_plus->data->length; ++j) fprintf(stdout, "%.9f\t%e\t%e\n", t0 + j * h_plus->deltaT, amp->data[j], phi->data[j]); XLALDestroyREAL8Sequence(phi); XLALDestroyREAL8Sequence(amp); } else { fprintf(stdout, "# time (s)\th_+ (strain)\th_x (strain)\n"); for (j = 0; j < h_plus->data->length; ++j) fprintf(stdout, "%.9f\t%e\t%e\n", t0 + j * h_plus->deltaT, h_plus->data->data[j], h_cross->data->data[j]); } return 0; }
void LALInferenceTemplateASinOmegaT(LALInferenceModel *model) /************************************************************/ /* Trivial h(t)=A*sin(Omega*t) template */ /* Required (`model->params') parameters are: */ /* - "A" (dimensionless amplitude, REAL8) */ /* - "Omega" (frequency; REAL8, radians/sec) */ /************************************************************/ { double A = *(REAL8*) LALInferenceGetVariable(model->params, "A"); /* dim-less */ double Omega = *(REAL8*) LALInferenceGetVariable(model->params, "Omega"); /* rad/sec */ double t; double epochGPS = XLALGPSGetREAL8(&(model->timehPlus->epoch)); unsigned long i; for (i=0; i<model->timehPlus->data->length; ++i){ t = ((double)i)*model->deltaT + (epochGPS); /* t-mu */ model->timehPlus->data->data[i] = A * sin(Omega*t); model->timehCross->data->data[i] = 0.0; } model->domain = LAL_SIM_DOMAIN_TIME; return; }
void LALInferenceTemplateSinc(LALInferenceModel *model) /*****************************************************/ /* Sinc function (burst) template. */ /* Signal is linearly polarized, */ /* i.e., cross term is zero. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The (plus-) waveform is a sinc function of given */ /* frequency: */ /* a * sinc(2*pi*f*(t-time)) */ /* = a * sin(2*pi*f*(t-time)) / (2*pi*f*(t-time)) */ /* where "time" is the time parameter denoting the */ /* signal's central peak location. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * *************************/ /* Required (`model->params') parameters are: */ /* - "time" (the instant at which the signal peaks; REAL8, GPS sec.) */ /* - "frequency" (frequency of the sine part; REAL8, Hertz) */ /* - "amplitude" (amplitude, REAL8) */ /*****************************************************************************/ { double endtime = *(REAL8*) LALInferenceGetVariable(model->params, "time"); /* time parameter ("mu"), GPS sec. */ double f = *(REAL8*) LALInferenceGetVariable(model->params, "frequency"); /* frequency, Hz */ double a = *(REAL8*) LALInferenceGetVariable(model->params, "amplitude"); /* amplitude */ double t, sinArg, sinc, twopif = LAL_TWOPI*f; double epochGPS = XLALGPSGetREAL8(&(model->timehPlus->epoch)); unsigned long i; if (f < 0.0) fprintf(stderr, " WARNING in templateSinc(): negative \"frequency\" parameter (f=%e).\n", f); for (i=0; i<model->timehPlus->data->length; ++i){ t = ((double)i)*model->deltaT + (epochGPS-endtime); /* t-mu */ sinArg = twopif*t; sinc = (sinArg==0.0) ? 1.0 : sin(sinArg)/sinArg; model->timehPlus->data->data[i] = a * sinc; model->timehCross->data->data[i] = 0.0; } model->domain = LAL_SIM_DOMAIN_TIME; return; }
int GetNextCrossCorrTemplate(BOOLEAN *binaryParamsFlag, BOOLEAN *firstPoint, PulsarDopplerParams *dopplerpos, PulsarDopplerParams *binaryTemplateSpacings, PulsarDopplerParams *minBinaryTemplate, PulsarDopplerParams *maxBinaryTemplate, UINT8 *fCount, UINT8 *aCount, UINT8 *tCount, UINT8 *pCount, UINT8 fSpacingNum, UINT8 aSpacingNum, UINT8 tSpacingNum, UINT8 pSpacingNum) { /* basic sanity checks */ if (binaryTemplateSpacings == NULL) return -1; if (minBinaryTemplate == NULL) return -1; if (maxBinaryTemplate == NULL) return -1; /* check spacings not negative */ if ( *fCount < fSpacingNum) /*loop over f at first*/ { dopplerpos->fkdot[0] = minBinaryTemplate->fkdot[0] + (*fCount + 1) * binaryTemplateSpacings->fkdot[0]; *binaryParamsFlag = FALSE; *fCount += 1; return 0; } else { if ( *aCount < aSpacingNum ) /*after looping all f, initialize f and loop over a_p*/ { dopplerpos->asini = minBinaryTemplate->asini + (*aCount + 1) * binaryTemplateSpacings->asini; dopplerpos->fkdot[0] = minBinaryTemplate->fkdot[0]; *fCount = 0; *binaryParamsFlag = TRUE; *aCount += 1; return 0; } else { if ( *pCount < pSpacingNum ) /*after looping the plane of f and a_p, initialize f, a_p and loop over P*/ { dopplerpos->period = minBinaryTemplate->period + (*pCount + 1) * binaryTemplateSpacings->period; dopplerpos->fkdot[0] = minBinaryTemplate->fkdot[0]; *fCount = 0; dopplerpos->asini = minBinaryTemplate->asini; *aCount = 0; *binaryParamsFlag = TRUE; *pCount += 1; return 0; } else { if ( *tCount < tSpacingNum ) /*after looping f, a_p and P, initialize f, a_p and P, then loop over T*/ { REAL8 nextGPSTime = XLALGPSGetREAL8(&minBinaryTemplate->tp) + (*tCount + 1) * XLALGPSGetREAL8(&binaryTemplateSpacings->tp); XLALGPSSetREAL8( &dopplerpos->tp, nextGPSTime); dopplerpos->fkdot[0] = minBinaryTemplate->fkdot[0]; *fCount = 0; dopplerpos->asini = minBinaryTemplate->asini; *aCount = 0; dopplerpos->period = minBinaryTemplate->period; *pCount = 0; *binaryParamsFlag = TRUE; *tCount += 1; return 0; } else { if (*firstPoint == TRUE) /*go back to search at the beginning point in parameter space*/ { dopplerpos->fkdot[0] = minBinaryTemplate->fkdot[0]; dopplerpos->asini = minBinaryTemplate->asini; dopplerpos->period = minBinaryTemplate->period; dopplerpos->tp = minBinaryTemplate->tp; *firstPoint = FALSE; *binaryParamsFlag = TRUE; return 0; } else return 1; } } } } }
/** * Handle user-input and set up shop accordingly, and do all * consistency-checks on user-input. */ int XLALInitMakefakedata ( ConfigVars_t *cfg, UserVariables_t *uvar ) { XLAL_CHECK ( cfg != NULL, XLAL_EINVAL, "Invalid NULL input 'cfg'\n" ); XLAL_CHECK ( uvar != NULL, XLAL_EINVAL, "Invalid NULL input 'uvar'\n"); cfg->VCSInfoString = XLALGetVersionString(0); XLAL_CHECK ( cfg->VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); // version info was requested: output then exit if ( uvar->version ) { printf ("%s\n", cfg->VCSInfoString ); exit (0); } /* if requested, log all user-input and code-versions */ if ( uvar->logfile ) { XLAL_CHECK ( XLALWriteMFDlog ( uvar->logfile, cfg ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALWriteMFDlog() failed with xlalErrno = %d\n", xlalErrno ); } /* Init ephemerides */ XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC ); /* check for negative fMin and Band, which would break the fMin_eff, fBand_eff calculation below */ XLAL_CHECK ( uvar->fmin >= 0, XLAL_EDOM, "Invalid negative frequency fMin=%f!\n\n", uvar->fmin ); XLAL_CHECK ( uvar->Band > 0, XLAL_EDOM, "Invalid non-positive frequency band Band=%f!\n\n", uvar->Band ); // ---------- check user-input consistency ---------- // ----- check if frames + frame channels given BOOLEAN have_frames = (uvar->inFrames != NULL); BOOLEAN have_channels= (uvar->inFrChannels != NULL); XLAL_CHECK ( !(have_frames || have_channels) || (have_frames && have_channels), XLAL_EINVAL, "Need both --inFrames and --inFrChannels, or NONE\n"); // ----- IFOs : only from one of {--IFOs, --noiseSFTs, --inFrChannels}: mutually exclusive BOOLEAN have_IFOs = (uvar->IFOs != NULL); BOOLEAN have_noiseSFTs = (uvar->noiseSFTs != NULL); XLAL_CHECK ( have_frames || have_IFOs || have_noiseSFTs, XLAL_EINVAL, "Need one of --IFOs, --noiseSFTs or --inFrChannels to determine detectors\n"); if ( have_frames ) { XLAL_CHECK ( !have_IFOs && !have_noiseSFTs, XLAL_EINVAL, "If --inFrames given, cannot handle --IFOs or --noiseSFTs input\n"); XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->inFrChannels ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { // !have_frames XLAL_CHECK ( !(have_IFOs && have_noiseSFTs), XLAL_EINVAL, "Cannot handle both --IFOs and --noiseSFTs input\n"); } if ( have_IFOs ) { XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); } // ----- TIMESTAMPS: either from --timestampsFiles, --startTime+duration, or --noiseSFTs BOOLEAN have_startTime = XLALUserVarWasSet ( &uvar->startTime ); BOOLEAN have_duration = XLALUserVarWasSet ( &uvar->duration ); BOOLEAN have_timestampsFiles = ( uvar->timestampsFiles != NULL ); // need BOTH startTime+duration or none XLAL_CHECK ( ( have_duration && have_startTime) || !( have_duration || have_startTime ), XLAL_EINVAL, "Need BOTH {--startTime,--duration} or NONE\n"); // at least one of {startTime,timestamps,noiseSFTs,inFrames} required XLAL_CHECK ( have_timestampsFiles || have_startTime || have_noiseSFTs || have_frames, XLAL_EINVAL, "Need at least one of {--timestampsFiles, --startTime+duration, --noiseSFTs, --inFrames}\n" ); // don't allow timestamps + {startTime+duration OR noiseSFTs} XLAL_CHECK ( !have_timestampsFiles || !(have_startTime||have_noiseSFTs), XLAL_EINVAL, "--timestampsFiles incompatible with {--noiseSFTs or --startTime+duration}\n"); // note, however, that we DO allow --noiseSFTs and --startTime+duration, which will act as a constraint // on the noise-SFTs to load in // don't allow --SFToverlap with either --noiseSFTs OR --timestampsFiles XLAL_CHECK ( uvar->SFToverlap >= 0, XLAL_EDOM ); BOOLEAN haveOverlap = ( uvar->SFToverlap > 0 ); XLAL_CHECK ( !haveOverlap || !( have_noiseSFTs || have_timestampsFiles ), XLAL_EINVAL, "--SFToverlap incompatible with {--noiseSFTs or --timestampsFiles}\n" ); // now handle the 3 mutually-exclusive cases: have_noiseSFTs || have_timestampsFiles || have_startTime (only) if ( have_noiseSFTs ) { SFTConstraints XLAL_INIT_DECL(constraints); if ( have_startTime && have_duration ) // use optional (startTime+duration) as constraints, { LIGOTimeGPS minStartTime, maxStartTime; minStartTime = uvar->startTime; maxStartTime = uvar->startTime; XLALGPSAdd ( &maxStartTime, uvar->duration ); constraints.minStartTime = &minStartTime; constraints.maxStartTime = &maxStartTime; char bufGPS1[32], bufGPS2[32]; XLALPrintWarning ( "Only noise-SFTs between GPS [%s, %s] will be used!\n", XLALGPSToStr(bufGPS1, &minStartTime), XLALGPSToStr(bufGPS2, &maxStartTime) ); } /* if start+duration given */ XLAL_CHECK ( (cfg->noiseCatalog = XLALSFTdataFind ( uvar->noiseSFTs, &constraints )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( cfg->noiseCatalog->length > 0, XLAL_EINVAL, "No noise-SFTs matching (start+duration, timestamps) were found!\n" ); XLAL_CHECK ( (cfg->multiNoiseCatalogView = XLALGetMultiSFTCatalogView ( cfg->noiseCatalog )) != NULL, XLAL_EFUNC ); // extract multi-timestamps from the multi-SFT-catalog view XLAL_CHECK ( (cfg->multiTimestamps = XLALTimestampsFromMultiSFTCatalogView ( cfg->multiNoiseCatalogView )) != NULL, XLAL_EFUNC ); // extract IFOs from multi-SFT catalog XLAL_CHECK ( XLALMultiLALDetectorFromMultiSFTCatalogView ( &(cfg->multiIFO), cfg->multiNoiseCatalogView ) == XLAL_SUCCESS, XLAL_EFUNC ); } // endif have_noiseSFTs else if ( have_timestampsFiles ) { XLAL_CHECK ( (cfg->multiTimestamps = XLALReadMultiTimestampsFiles ( uvar->timestampsFiles )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (cfg->multiTimestamps->length > 0) && (cfg->multiTimestamps->data != NULL), XLAL_EINVAL, "Got empty timestamps-list from XLALReadMultiTimestampsFiles()\n" ); for ( UINT4 X=0; X < cfg->multiTimestamps->length; X ++ ) { cfg->multiTimestamps->data[X]->deltaT = uvar->Tsft; // Tsft information not given by timestamps-file } } // endif have_timestampsFiles else if ( have_startTime && have_duration ) { XLAL_CHECK ( ( cfg->multiTimestamps = XLALMakeMultiTimestamps ( uvar->startTime, uvar->duration, uvar->Tsft, uvar->SFToverlap, cfg->multiIFO.length )) != NULL, XLAL_EFUNC ); } // endif have_startTime // check if the user asked for Gaussian white noise to be produced (sqrtSn[X]!=0), otherwise leave noise-floors at 0 if ( uvar->sqrtSX != NULL ) { XLAL_CHECK ( XLALParseMultiNoiseFloor ( &(cfg->multiNoiseFloor), uvar->sqrtSX, cfg->multiIFO.length ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { cfg->multiNoiseFloor.length = cfg->multiIFO.length; // values remain at their default sqrtSn[X] = 0; } #ifdef HAVE_LIBLALFRAME // if user requested time-series data from frames to be added: try to read the frames now if ( have_frames ) { UINT4 numDetectors = uvar->inFrChannels->length; XLAL_CHECK ( uvar->inFrames->length == numDetectors, XLAL_EINVAL, "Need equal number of channel names (%d) as frame specifications (%d)\n", uvar->inFrChannels->length, numDetectors ); XLAL_CHECK ( (cfg->inputMultiTS = XLALCalloc ( 1, sizeof(*cfg->inputMultiTS))) != NULL, XLAL_ENOMEM ); cfg->inputMultiTS->length = numDetectors; XLAL_CHECK ( (cfg->inputMultiTS->data = XLALCalloc ( numDetectors, sizeof(cfg->inputMultiTS->data[0]) )) != NULL, XLAL_ENOMEM ); if ( cfg->multiTimestamps == NULL ) { XLAL_CHECK ( (cfg->multiTimestamps = XLALCalloc ( 1, sizeof(*cfg->multiTimestamps) )) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( (cfg->multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(cfg->multiTimestamps->data[0]))) != NULL, XLAL_ENOMEM ); cfg->multiTimestamps->length = numDetectors; } for ( UINT4 X = 0; X < numDetectors; X ++ ) { LALCache *cache; XLAL_CHECK ( (cache = XLALCacheImport ( uvar->inFrames->data[X] )) != NULL, XLAL_EFUNC, "Failed to import cache file '%s'\n", uvar->inFrames->data[X] ); // this is a sorted cache, so extract its time-range: REAL8 cache_tStart = cache->list[0].t0; REAL8 cache_tEnd = cache->list[cache->length-1].t0 + cache->list[cache->length-1].dt; REAL8 cache_duration = (cache_tEnd - cache_tStart); LIGOTimeGPS ts_start; REAL8 ts_duration; // check that it's consistent with timestamps, if given, otherwise create timestamps from this if ( cfg->multiTimestamps->data[X] != NULL ) // FIXME: implicitly assumes timestamps are sorted, which is not guaranteed by timestamps-reading from file { const LIGOTimeGPSVector *timestampsX = cfg->multiTimestamps->data[X]; REAL8 tStart = XLALGPSGetREAL8( ×tampsX->data[0] ); REAL8 tEnd = XLALGPSGetREAL8( ×tampsX->data[timestampsX->length-1]) + timestampsX->deltaT; XLAL_CHECK ( tStart >= cache_tStart && tEnd <= cache_tEnd, XLAL_EINVAL, "Detector X=%d: Requested timestamps-range [%.0f, %.0f]s outside of cache range [%.0f,%.0f]s\n", X, tStart, tEnd, cache_tStart, cache_tEnd ); XLALGPSSetREAL8 ( &ts_start, tStart ); ts_duration = (tEnd - tStart); } else { XLALGPSSetREAL8 ( &ts_start, (REAL8)cache_tStart + 1); // cache times can apparently be by rounded up or down by 1s, so shift by 1s to be safe ts_duration = cache_duration - 1; XLAL_CHECK ( (cfg->multiTimestamps->data[X] = XLALMakeTimestamps ( ts_start, ts_duration, uvar->Tsft, uvar->SFToverlap ) ) != NULL, XLAL_EFUNC ); } // ----- now open frame stream and read *all* the data within this time-range [FIXME] ---------- LALFrStream *stream; XLAL_CHECK ( (stream = XLALFrStreamCacheOpen ( cache )) != NULL, XLAL_EFUNC, "Failed to open stream from cache file '%s'\n", uvar->inFrames->data[X] ); XLALDestroyCache ( cache ); const char *channel = uvar->inFrChannels->data[X]; size_t limit = 0; // unlimited read REAL8TimeSeries *ts; XLAL_CHECK ( (ts = XLALFrStreamInputREAL8TimeSeries ( stream, channel, &ts_start, ts_duration, limit )) != NULL, XLAL_EFUNC, "Frame reading failed for stream created for '%s': ts_start = {%d,%d}, duration=%.0f\n", uvar->inFrames->data[X], ts_start.gpsSeconds, ts_start.gpsNanoSeconds, ts_duration ); cfg->inputMultiTS->data[X] = ts; XLAL_CHECK ( XLALFrStreamClose ( stream ) == XLAL_SUCCESS, XLAL_EFUNC, "Stream closing failed for cache file '%s'\n", uvar->inFrames->data[X] ); } // for X < numDetectors } // if inFrames // if user requested timeseries *output* to frame files, handle deprecated options XLAL_CHECK ( !(uvar->TDDframedir && uvar->outFrameDir), XLAL_EINVAL, "Specify only ONE of {--TDDframedir or --outFrameDir} or NONE\n"); if ( uvar->TDDframedir ) { cfg->outFrameDir = uvar->TDDframedir; } else if ( uvar->outFrameDir ) { cfg->outFrameDir = uvar->outFrameDir; } #endif return XLAL_SUCCESS; } /* XLALInitMakefakedata() */
void LALappsTSAMergeMap(LALStatus *status, TSAMap **output, TSAMap mapA, TSAMap mapB) { TSAMap *inputA=NULL; TSAMap *inputB=NULL; TSAMap *inputC=NULL; TSAMap *outputPtr=NULL; REAL8 timeA=0; REAL8 timeB=0; REAL8 timeAstop=0; REAL8 timeBstop=0; REAL8 timeResA=0; REAL8 timeResB=0; REAL8 avgTimeRes=0; const REAL8 resTolPercent=0.01;/*map time resolution tol*/ BOOLEAN linkMaps=0; INT4 i=0; INT4 j=0; INT4 k=0; INT4 splitPixelA=0; INT4 splitPixelB=0; INT4 relativePixelMarkerB=0; INT4 pixelOverlap=0; INT4 outputTimeBins=0; TrackSearchMapMarkingParams imageBordersOut; CreateTimeFreqIn imageCreateParamsOut; /* * User pointers to place input maps in time order */ inputA=&mapA; inputB=&mapB; timeA = XLALGPSGetREAL8(&(inputA->imageBorders.mapStartGPS)); timeB = XLALGPSGetREAL8(&(inputB->imageBorders.mapStartGPS)); LALappsTSassert((*output==NULL), TRACKSEARCHAVERAGERC_ENPTR, TRACKSEARCHAVERAGERC_MSGENPTR); /* TimeB comes before TimeA swap pointers so A comes before B*/ if (timeB < timeA) { inputC=inputA; inputA=NULL; inputA=inputB; inputB=NULL; inputB=inputC; inputC=NULL; } /* * Check inputs A and B are same dimensions in frequency */ LALappsTSassert((inputA->imageRep->fRow==inputB->imageRep->fRow), TRACKSEARCHAVERAGERC_EDIMS, TRACKSEARCHAVERAGERC_MSGEDIMS); /* * LALappsTSassert((inputA->imageRep->tCol==inputB->imageRep->tCol), * TRACKSEARCHAVERAGERC_EDIMS, * TRACKSEARCHAVERAGERC_MSGEDIMS); */ timeA = XLALGPSGetREAL8(&(inputA->imageBorders.mapStartGPS)); timeB = XLALGPSGetREAL8(&(inputB->imageBorders.mapStartGPS)); timeAstop = XLALGPSGetREAL8(&(inputA->imageBorders.mapStopGPS)); timeBstop = XLALGPSGetREAL8(&(inputB->imageBorders.mapStopGPS)); /* * InputA should end before inputB ends and after equal B starts */ LALappsTSassert(((timeAstop<=timeBstop) && (timeAstop >= timeB)), TRACKSEARCHAVERAGERC_EMAPO, TRACKSEARCHAVERAGERC_MSGEMAPO); /* * Check to see that mapB starts before or at end of mapA and starts * after mapA starts */ LALappsTSassert(((timeAstop>=timeB) && (timeA<=timeB)), TRACKSEARCHAVERAGERC_EMAPO, TRACKSEARCHAVERAGERC_MSGEMAPO); /* * Check that both maps don't cover matching time stretches */ LALappsTSassert(((timeA!=timeB)||(timeAstop!=timeBstop)), TRACKSEARCHAVERAGERC_EMAPO, TRACKSEARCHAVERAGERC_MSGEMAPO); /* *Determine the number of time bins in the output structure */ timeResA=(REAL8)((timeAstop-timeA)/(REAL8)inputA->imageCreateParams.tCol); timeResB=(REAL8)((timeBstop-timeB)/(REAL8)inputB->imageCreateParams.tCol); /* * Check that the resolutions of the maps match */ avgTimeRes=(timeResA+timeResB)/2; LALappsTSassert((fabs((timeResA-timeResB)/avgTimeRes)<resTolPercent), TRACKSEARCHAVERAGERC_EDIMS, TRACKSEARCHAVERAGERC_MSGEDIMS); outputTimeBins=floor((timeBstop-timeA)/avgTimeRes); /* * Check for reasonable outputTimeBins must be less that sum of * the two input maps timebins and greate that 2 time cols */ LALappsTSassert((outputTimeBins<=(inputA->imageCreateParams.tCol + inputB->imageCreateParams.tCol)), TRACKSEARCHAVERAGERC_ESUB, TRACKSEARCHAVERAGERC_MSGESUB); LALappsTSassert((outputTimeBins>=2), TRACKSEARCHAVERAGERC_ESUB, TRACKSEARCHAVERAGERC_MSGESUB); /* * Allocate an output map equal to the two maps combined in time * we account for the overlaping sections such that our new output * maps spans the time inputA..gpsStart until inputB..gpsStop */ imageBordersOut=inputA->imageBorders; imageBordersOut.mapTimeBins=outputTimeBins; imageBordersOut.mapStopGPS=inputB->imageBorders.mapStopGPS; imageCreateParamsOut=inputA->imageCreateParams; imageCreateParamsOut.tCol=outputTimeBins; /* * Allocate output map struct */ LALappsTSACreateMap(status, output, &imageBordersOut, &imageCreateParamsOut); /* * Handle map "blending" if sets are overlapped * or handle a straight joining if possible */ outputPtr=*output; if ((outputPtr)->imageRep->tCol== (inputB->imageRep->tCol + inputA->imageRep->tCol)) linkMaps=1; if (linkMaps) { fprintf(stdout,"Doing a direct map joining\n"); /* * Copy over the map matrix */ outputPtr->clippedWith=0; /* * Start appending in time */ for (i=0; i<inputA->imageRep->fRow/2+1; i++) { for (j=0,k=0; j<inputA->imageRep->tCol; j++,k++) { /*[time][freq]*/ outputPtr->imageRep->map[k][i]=inputA->imageRep->map[j][i]; } } for (i=0; i<inputB->imageRep->fRow/2+1; i++) { for (j=0,k=inputA->imageRep->tCol; j<inputB->imageRep->tCol; j++,k++) { /*[time][freq]*/ outputPtr->imageRep->map[k][i]=inputB->imageRep->map[j][i]; } } } else { fprintf(stdout,"Doing a mergee/clip of the two maps\n"); /* * Figure out how to merge the two maps accordingly */ /* * Since we are "clipping inputB" we need to set the clipping field */ outputPtr->clippedWith=1; outputPtr->clipperMapStart=inputB->imageBorders.mapStartGPS; /* * We assume that outputPtr->imageRep has been correctly allocated * outside of this function via a call to LALCreateTimeFreqRep */ /* * We must determine where to mark the maps for the truncations * and then the appending the marked sections into outputPtr */ relativePixelMarkerB=(timeB-timeA)/avgTimeRes; pixelOverlap=inputA->imageRep->tCol-relativePixelMarkerB; splitPixelA= inputA->imageRep->tCol-(pixelOverlap/2); splitPixelB=(pixelOverlap/2+1); /* *Stop inputA copy at splitPixelA *Start inputB copy at splitPixelB */ for (i=0; i<inputA->imageRep->fRow/2+1; i++) { for (j=0; j<splitPixelA; j++) { /*[time][freq]*/ outputPtr->imageRep->map[j][i]=inputA->imageRep->map[j][i]; } } for (i=0; i<inputB->imageRep->fRow/2+1; i++) { for (k=splitPixelA,j=splitPixelB; j<inputB->imageRep->tCol; j++,k++) { /*[time][freq]*/ outputPtr->imageRep->map[k][i]=inputB->imageRep->map[j][i]; } } } /* * NonCritical Tue-Oct-30-2007:200710301618 * Add in manipulation of freqBin and timeInstant entries after the * collapse or merge of the map. */ return; }
/** * Compute the "data-quality factor" \f$\mathcal{Q}(f) = \sum_X \frac{\epsilon_X}{\mathcal{S}_X(f)}\f$ over the given SFTs. * The input \a multiPSD is a pre-computed PSD map \f$\mathcal{S}_{X,i}(f)\f$, over IFOs \f$X\f$, SFTs \f$i\f$ * and frequency \f$f\f$. * * \return the output is a vector \f$\mathcal{Q}(f)\f$. * */ REAL8FrequencySeries * XLALComputeSegmentDataQ ( const MultiPSDVector *multiPSDVect, /**< input PSD map over IFOs, SFTs, and frequencies */ LALSeg segment /**< segment to compute Q for */ ) { /* check input consistency */ if ( multiPSDVect == NULL ) { XLALPrintError ("%s: NULL input 'multiPSDVect'\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( multiPSDVect->length == 0 || multiPSDVect->data==0 ) { XLALPrintError ("%s: invalid multiPSDVect input (length=0 or data=NULL)\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } REAL8 Tseg = XLALGPSDiff ( &segment.end, &segment.start ); if ( Tseg <= 0 ) { XLALPrintError ("%s: negative segment-duration '%g'\n", __func__, Tseg ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } REAL8 Tsft = 1.0 / multiPSDVect->data[0]->data[0].deltaF; REAL8 f0 = multiPSDVect->data[0]->data[0].f0; REAL8 dFreq = multiPSDVect->data[0]->data[0].deltaF; UINT4 numFreqs = multiPSDVect->data[0]->data[0].data->length; REAL8FrequencySeries *Q, *SXinv; if ( (Q = XLALCreateREAL8FrequencySeries ( "Qfactor", &segment.start, f0, dFreq, &lalHertzUnit, numFreqs )) == NULL ) { XLALPrintError ("%s: Q = XLALCreateREAL8FrequencySeries(numFreqs=%d) failed with xlalErrno = %d\n", __func__, numFreqs, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } if ( (SXinv = XLALCreateREAL8FrequencySeries ( "SXinv", &segment.start, f0, dFreq, &lalHertzUnit, numFreqs )) == NULL ) { XLALPrintError ("%s: SXinv = XLALCreateREAL8FrequencySeries(numFreqs=%d) failed with xlalErrno = %d\n", __func__, numFreqs, xlalErrno ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* initialize Q-array to zero, as we'll keep adding to it */ memset ( Q->data->data, 0, Q->data->length * sizeof(Q->data->data[0]) ); /* ----- loop over IFOs ----- */ UINT4 numIFOs = multiPSDVect->length; UINT4 X; for ( X = 0; X < numIFOs; X ++ ) { PSDVector *thisPSDVect = multiPSDVect->data[X]; /* initialize SXinv-array to zero, as we'll keep adding to it */ memset ( SXinv->data->data, 0, SXinv->data->length * sizeof(SXinv->data->data[0]) ); UINT4 numSFTsInSeg = 0; /* reset counter of SFTs within this segment */ /* ----- loop over all timestamps ----- */ /* find SFTs inside segment, count them and combine their PSDs */ UINT4 numTS = thisPSDVect->length; UINT4 iTS; for ( iTS = 0; iTS < numTS; iTS++ ) { REAL8FrequencySeries *thisPSD = &thisPSDVect->data[iTS]; /* some internal consistency/paranoia checks */ if ( ( f0 != thisPSD->f0) || ( dFreq != thisPSD->deltaF ) || (numFreqs != thisPSD->data->length ) ) { XLALPrintError ("%s: %d-th timestamp %f: inconsistent PSDVector: f0 = %g : %g, dFreq = %g : %g, numFreqs = %d : %d \n", __func__, iTS, XLALGPSGetREAL8( &thisPSD->epoch ), f0, thisPSD->f0, dFreq, thisPSD->deltaF, numFreqs, thisPSD->data->length ); XLAL_ERROR_NULL ( XLAL_EDOM ); } int cmp = XLALCWGPSinRange( thisPSD->epoch, &segment.start, &segment.end ); if ( cmp < 0 ) /* SFT-end before segment => advance to the next one */ continue; if ( cmp > 0 ) /* SFT-start past end of segment: ==> terminate loop */ break; if ( cmp == 0 ) /* this SFT is inside segment */ { numSFTsInSeg ++; /* add SXinv(f) += 1/SX_i(f) over all frequencies */ UINT4 iFreq; for ( iFreq = 0; iFreq < numFreqs; iFreq++ ) SXinv->data->data[iFreq] += 1.0 / thisPSD->data->data[iFreq] ; } /* if SFT inside segment */ } /* for iTS < numTS */ /* compute duty-cycle eps_X = nX * Tsft / Tseg for this IFO */ REAL8 duty_X = numSFTsInSeg * Tsft / Tseg; /* sanity check: eps in [0, 1]*/ if ( (duty_X < 0) && (duty_X > 1 ) ) { XLALPrintError ("%s: something is WRONG: duty-cyle = %g not within [0,1]!\n", __func__, duty_X ); XLAL_ERROR_NULL ( XLAL_EFAILED ); } /* add duty_X-weighted SXinv to Q */ UINT4 iFreq; for ( iFreq = 0; iFreq < numFreqs; iFreq ++ ) Q->data->data[iFreq] += duty_X * SXinv->data->data[iFreq] / numSFTsInSeg; } /* for X < numIFOs */ /* clean up, free memory */ XLALDestroyREAL8FrequencySeries ( SXinv ); return Q; } /* XLALComputeSegmentDataQ() */
/** Computes the binary parameter space boundaries given the user input args * * For each search dimension we define the min, max, mid, and span of that dimension * plus we give each dimension a name. * */ int XLALDefineBinaryParameterSpace( REAL8Space **space, /**< [out] the parameter space */ LIGOTimeGPS epoch, /**< [in] the observation start epoch */ REAL8 span, /**< [in] the observation span */ UserInput_t *uvar /**< [in] the user input variables */ ) { REAL8 midpoint; /* the midpoint of the observation */ REAL8 mintasc; /* the minimum time of ascension */ REAL8 maxtasc; /* the maximum time of ascension */ /* validate input variables */ if ( ( *space ) != NULL ) { LogPrintf( LOG_CRITICAL, "%s : Invalid input, input REAL8Space boundary structure != NULL.\n", __func__ ); XLAL_ERROR( XLAL_EINVAL ); } if ( uvar == NULL ) { LogPrintf( LOG_CRITICAL, "%s : Invalid input, input UserInput_t structure = NULL.\n", __func__ ); XLAL_ERROR( XLAL_EINVAL ); } if ( epoch.gpsSeconds < 0 ) { LogPrintf( LOG_CRITICAL, "%s : Invalid input, observation epoch < 0.\n", __func__ ); XLAL_ERROR( XLAL_EINVAL ); } if ( span < 0 ) { LogPrintf( LOG_CRITICAL, "%s : Invalid input, observation span < 0.\n", __func__ ); XLAL_ERROR( XLAL_EINVAL ); } /* allocate memory for the parameter space */ if ( ( ( *space ) = XLALCalloc( 1, sizeof( REAL8Space ) ) ) == NULL ) { LogPrintf( LOG_CRITICAL, "%s: XLALCalloc() failed with error = %d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_ENOMEM ); } ( *space )->ndim = NBINMAX; if ( ( ( *space )->data = XLALCalloc( ( *space )->ndim, sizeof( REAL8Dimension ) ) ) == NULL ) { LogPrintf( LOG_CRITICAL, "%s: XLALCalloc() failed with error = %d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_ENOMEM ); } /* define observaton midpoint */ midpoint = XLALGPSGetREAL8( &epoch ) + 0.5 * span; /* find the closest instance of ascension to the midpoint */ /* the midpoint is defined in the detector frame and the time of */ /* ascension is in the SSB frame but we only need to be roughly */ /* correct in the number of orbits we shift by */ if ( uvar->tasc > 0 ) { REAL8 meanperiod = 0.5 * ( uvar->maxorbperiod + uvar->minorbperiod ); INT4 n = ( INT4 )floor( 0.5 + ( midpoint - uvar->tasc ) / meanperiod ); REAL8 newtasc = uvar->tasc + n * meanperiod; mintasc = newtasc - 0.5 * uvar->maxorbperiod * uvar->deltaorbphase; maxtasc = newtasc + 0.5 * uvar->maxorbperiod * uvar->deltaorbphase; LogPrintf( LOG_DEBUG, "%s : shifted tasc by %d orbits\n", __func__, n ); } else { /* we have no orbital info so we search a full period at the midpoint */ mintasc = midpoint - 0.5 * uvar->maxorbperiod; maxtasc = midpoint + 0.5 * uvar->maxorbperiod; } /* this represents a hyper-cubic parameter space */ /* we make sure that parameter ranges are consistent i.e asini > 0 etc.. */ /* frequency */ snprintf( ( *space )->data[0].name, LALNameLength, "nu" ); ( *space )->data[0].min = uvar->freq; ( *space )->data[0].max = uvar->freq + uvar->freqband; ( *space )->data[0].span = ( *space )->data[0].max - ( *space )->data[0].min; /* asini */ snprintf( ( *space )->data[1].name, LALNameLength, "asini" ); ( *space )->data[1].min = uvar->minasini; ( *space )->data[1].max = uvar->maxasini; ( *space )->data[1].span = ( *space )->data[1].max - ( *space )->data[1].min; /* orbphase */ snprintf( ( *space )->data[2].name, LALNameLength, "tasc" ); ( *space )->data[2].min = mintasc; ( *space )->data[2].max = maxtasc; ( *space )->data[2].span = ( *space )->data[2].max - ( *space )->data[2].min; /* omega */ snprintf( ( *space )->data[3].name, LALNameLength, "omega" ); ( *space )->data[3].min = LAL_TWOPI / uvar->maxorbperiod; ( *space )->data[3].max = LAL_TWOPI / uvar->minorbperiod; ( *space )->data[3].span = ( *space )->data[3].max - ( *space )->data[3].min; /* output boundaries to screen */ LogPrintf( LOG_DEBUG, "%s : using flat priors on the following ranges\n", __func__ ); LogPrintf( LOG_DEBUG, "%s : parameter space, %s = [%e -> %e]\n", __func__, ( *space )->data[0].name, ( *space )->data[0].min, ( *space )->data[0].max ); LogPrintf( LOG_DEBUG, "%s : parameter space, %s = [%e -> %e]\n", __func__, ( *space )->data[1].name, ( *space )->data[1].min, ( *space )->data[1].max ); LogPrintf( LOG_DEBUG, "%s : parameter space, %s = [%e -> %e]\n", __func__, ( *space )->data[2].name, ( *space )->data[2].min, ( *space )->data[2].max ); LogPrintf( LOG_DEBUG, "%s : parameter space, %s = [%e -> %e]\n", __func__, ( *space )->data[3].name, ( *space )->data[3].min, ( *space )->data[3].max ); LogPrintf( LOG_DEBUG, "%s : leaving.\n", __func__ ); return XLAL_SUCCESS; }
int test_XLALSincInterpolateCOMPLEX8TimeSeries ( void ) { COMPLEX8TimeSeries* tsIn; REAL8 f0 = 100; // heterodyning frequency REAL8 dt = 0.1; // sampling frequency = 10Hz LIGOTimeGPS epoch = { 100, 0 }; REAL8 tStart = XLALGPSGetREAL8 ( &epoch ); UINT4 numSamples = 1000; REAL8 Tspan = numSamples * dt; XLAL_CHECK ( (tsIn = XLALCreateCOMPLEX8TimeSeries ( "test TS_in", &epoch, f0, dt, &emptyLALUnit, numSamples )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamples; j ++ ) { tsIn->data->data[j] = testSignal ( tStart + j * dt, 0 ); } // for j < numSamples // ---------- interpolate this onto new time-samples UINT4 Dterms = 16; REAL8 safety = (Dterms+1.0) * dt; // avoid truncated interpolation to minimize errors, set to 0 for seeing boundary-effects [they're not so bad...] LIGOTimeGPS epochOut = epoch; XLALGPSAdd ( &epochOut, safety ); REAL8 TspanOut = Tspan - 2 * safety; REAL8 dtOut = dt / 10; UINT4 numSamplesOut = lround ( TspanOut / dtOut ); COMPLEX8TimeSeries *tsOut; XLAL_CHECK ( (tsOut = XLALCreateCOMPLEX8TimeSeries ( "test TS_out", &epochOut, f0, dtOut, &emptyLALUnit, numSamplesOut )) != NULL, XLAL_EFUNC ); REAL8 tStartOut = XLALGPSGetREAL8 ( &epochOut ); REAL8Vector *times_out; XLAL_CHECK ( (times_out = XLALCreateREAL8Vector ( numSamplesOut )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamplesOut; j ++ ) { REAL8 t_j = tStartOut + j * dtOut; times_out->data[j] = t_j; } // for j < numSamplesOut XLAL_CHECK ( XLALSincInterpolateCOMPLEX8TimeSeries ( tsOut->data, times_out, tsIn, Dterms ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyREAL8Vector ( times_out ); // ---------- check accuracy of interpolation COMPLEX8TimeSeries *tsFull; XLAL_CHECK ( (tsFull = XLALCreateCOMPLEX8TimeSeries ( "test TS_full", &epochOut, f0, dtOut, &emptyLALUnit, numSamplesOut )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamplesOut; j ++ ) { tsFull->data->data[j] = testSignal ( tStartOut + j * dtOut, 0 ); } // for j < numSamplesOut // ----- out debug info if ( lalDebugLevel & LALINFO ) { XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_in.dat", tsIn ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_out.dat", tsOut ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALdumpCOMPLEX8TimeSeries ( "TS_full.dat", tsFull ) == XLAL_SUCCESS, XLAL_EFUNC ); } // if LALINFO VectorComparison XLAL_INIT_DECL(tol); tol.relErr_L1 = 2e-2; tol.relErr_L2 = 2e-2; tol.angleV = 2e-2; tol.relErr_atMaxAbsx = 2e-2; tol.relErr_atMaxAbsy = 2e-2; XLALPrintInfo ("Comparing sinc-interpolated timeseries to exact signal timeseries:\n"); VectorComparison XLAL_INIT_DECL(cmp); XLAL_CHECK ( XLALCompareCOMPLEX8Vectors ( &cmp, tsOut->data, tsFull->data, &tol ) == XLAL_SUCCESS, XLAL_EFUNC ); // ---------- free memory XLALDestroyCOMPLEX8TimeSeries ( tsIn ); XLALDestroyCOMPLEX8TimeSeries ( tsOut ); XLALDestroyCOMPLEX8TimeSeries ( tsFull ); return XLAL_SUCCESS; } // test_XLALSincInterpolateCOMPLEX8TimeSeries()
/** * Wrapper to iterate over the entries in a sim_burst linked list and * inject them into a time series. Passing NULL for the response disables * it (input time series is strain). */ int XLALBurstInjectSignals( REAL8TimeSeries *series, const SimBurst *sim_burst, const TimeSlide *time_slide_table_head, const COMPLEX16FrequencySeries *response ) { /* to be deduced from the time series' channel name */ const LALDetector *detector; /* FIXME: fix the const entanglement so as to get rid of this */ LALDetector detector_copy; /* + and x time series for injection waveform */ REAL8TimeSeries *hplus = NULL; REAL8TimeSeries *hcross = NULL; /* injection time series as added to detector's */ REAL8TimeSeries *h; /* skip injections whose geocentre times are more than this many * seconds outside of the target time series */ const double injection_window = 100.0; /* turn the first two characters of the channel name into a * detector */ detector = XLALDetectorPrefixToLALDetector(series->name); if(!detector) XLAL_ERROR(XLAL_EFUNC); XLALPrintInfo("%s(): channel name is '%s', instrument appears to be '%s'\n", __func__, series->name, detector->frDetector.prefix); detector_copy = *detector; /* iterate over injections */ for(; sim_burst; sim_burst = sim_burst->next) { LIGOTimeGPS time_geocent_gps; const TimeSlide *time_slide_row; /* determine the offset to be applied to this injection */ time_slide_row = XLALTimeSlideConstGetByIDAndInstrument(time_slide_table_head, sim_burst->time_slide_id, detector->frDetector.prefix); if(!time_slide_row) { XLALPrintError("%s(): cannot find time shift offset for injection 'sim_burst:simulation_id:%ld'. need 'time_slide:time_slide_id:%ld' for instrument '%s'", __func__, sim_burst->simulation_id, sim_burst->time_slide_id, detector->frDetector.prefix); XLAL_ERROR(XLAL_EINVAL); } /* skip injections whose "times" are too far outside of the * target time series */ time_geocent_gps = sim_burst->time_geocent_gps; XLALGPSAdd(&time_geocent_gps, -time_slide_row->offset); if(XLALGPSDiff(&series->epoch, &time_geocent_gps) > injection_window || XLALGPSDiff(&time_geocent_gps, &series->epoch) > (series->data->length * series->deltaT + injection_window)) continue; XLALPrintInfo("%s(): injection 'sim_burst:simulation_id:%ld' in '%s' at %d.%09u s (GPS) will be shifted by %.16g s to %d.%09u s (GPS)\n", __func__, sim_burst->simulation_id, series->name, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, -time_slide_row->offset, time_geocent_gps.gpsSeconds, time_geocent_gps.gpsNanoSeconds); /* construct the h+ and hx time series for the injection * waveform. */ if(XLALGenerateSimBurst(&hplus, &hcross, sim_burst, series->deltaT)) XLAL_ERROR(XLAL_EFUNC); #if 0 { char name[100]; FILE *f; unsigned i; sprintf(name, "%d.%09u_%s.txt", sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, series->name); f = fopen(name, "w"); for(i = 0; i < hplus->data->length; i++) { LIGOTimeGPS t = hplus->epoch; XLALGPSAdd(&t, i * hplus->deltaT); fprintf(f, "%.16g %.16g %.16g\n", XLALGPSGetREAL8(&t), hplus->data->data[i], hcross->data->data[i]); } fclose(f); } #endif /* project the wave onto the detector to produce the strain * in the detector. */ h = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross, sim_burst->ra, sim_burst->dec, sim_burst->psi, &detector_copy); XLALDestroyREAL8TimeSeries(hplus); XLALDestroyREAL8TimeSeries(hcross); hplus = hcross = NULL; if(!h) XLAL_ERROR(XLAL_EFUNC); /* shift the waveform by the time slide offset */ XLALGPSAdd(&h->epoch, -time_slide_row->offset); #if 0 { char name[100]; FILE *f; unsigned i; sprintf(name, "%d.%09u_%s.txt", sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, series->name); f = fopen(name, "w"); for(i = 0; i < h->data->length; i++) { LIGOTimeGPS t = h->epoch; XLALGPSAdd(&t, i * h->deltaT); fprintf(f, "%d.%09u %.16g\n", t.gpsSeconds, t.gpsNanoSeconds, h->data->data[i]); } fclose(f); } #endif /* add the injection strain time series to the detector * data */ if(XLALSimAddInjectionREAL8TimeSeries(series, h, response)) { XLALDestroyREAL8TimeSeries(h); XLAL_ERROR(XLAL_EFUNC); } XLALDestroyREAL8TimeSeries(h); } /* done */ return 0; }
void LALInferenceTemplateXLALSimInspiralChooseWaveform(LALInferenceModel *model) /*************************************************************************************************************************/ /* Wrapper for LALSimulation waveforms: */ /* XLALSimInspiralChooseFDWaveform() and XLALSimInspiralChooseTDWaveform(). */ /* */ /* model->params parameters are: */ /* - "name" description; type OPTIONAL (default value) */ /* */ /* MODEL PARAMETERS */ /* - "LAL_APPROXIMANT Approximant; Approximant */ /* - "LAL_PNORDER" Phase PN order; INT4 */ /* - "LAL_AMPORDER" Amplitude PN order; INT4 OPTIONAL (-1) */ /* - "spinO" Spin order; LALSimInspiralSpinOrder OPTIONAL (LAL_SIM_INSPIRAL_SPIN_ORDER_DEFAULT) */ /* - "tideO" Tidal order; LALSimInspiralTidalOrder OPTIONAL (LAL_SIM_INSPIRAL_TIDAL_ORDER_DEFAULT) */ /* - "f_ref" frequency at which the (frequency dependent) parameters are defined; REAL8 OPTIONAL (0.0) */ /* - "fLow" lower frequency bound; REAL8 OPTIONAL (model->fLow) */ /* */ /* MASS PARAMETERS; either: */ /* - "mass1" mass of object 1 in solar mass; REAL8 */ /* - "mass2" mass of object 1 in solar mass; REAL8 */ /* OR */ /* - "chirpmass" chirpmass in solar mass; REAL8 */ /* - "q" asymmetric mass ratio m2/m1, 0<q<1; REAL8 */ /* OR */ /* - "chirpmass" chirpmass in solar mass; REAL8 */ /* - "eta" symmetric mass ratio (m1*m2)/(m1+m2)^2; REAL8 */ /* */ /* ORIENTATION AND SPIN PARAMETERS */ /* - "phi0" reference phase as per LALSimulation convention; REAL8 */ /* - "distance" distance in Mpc */ /* - "costheta_jn"); cos of zenith angle between J and N in radians; REAL8 */ /* - "phi_jl"); azimuthal angle of L_N on its cone about J radians; REAL8 */ /* - "tilt_spin1"); zenith angle between S1 and LNhat in radians; REAL8 */ /* - "tilt_spin2"); zenith angle between S2 and LNhat in radians; REAL8 */ /* - "phi12"); difference in azimuthal angle between S1, S2 in radians; REAL8 */ /* - "a_spin1" magnitude of spin 1 in general configuration, -1<a_spin1<1; REAL8 OPTIONAL (0.0) */ /* - "a_spin2" magnitude of spin 2 in general configuration, -1<a_spin1<1; REAL8 OPTIONAL (0.0) */ /* */ /* OTHER PARAMETERS */ /* - "lambda1" tidal parameter of object 1; REAL8 OPTIONAL (0.0) */ /* - "lambda2" tidal parameter of object 1; REAL8 OPTIONAL (0.0) */ /* */ /* - "time" used as an OUTPUT only; REAL8 */ /* */ /* */ /* model needs to also contain: */ /* - model->fLow Unless - "fLow" OPTIONAL */ /* - model->deltaT */ /* - if model->domain == LAL_SIM_DOMAIN_FREQUENCY */ /* - model->deltaF */ /* - model->freqhCross */ /* - model->freqhPlus */ /* - else */ /* - model->timehPlus */ /* - model->timehCross */ /*************************************************************************************************************************/ { Approximant approximant = (Approximant) 0; INT4 order=-1; INT4 amporder; static int sizeWarning = 0; int ret=0; INT4 errnum=0; REAL8TimeSeries *hplus=NULL; /**< +-polarization waveform [returned] */ REAL8TimeSeries *hcross=NULL; /**< x-polarization waveform [returned] */ COMPLEX16FrequencySeries *hptilde=NULL, *hctilde=NULL; REAL8 mc; REAL8 phi0, deltaT, m1, m2, f_low, f_start, distance, inclination; REAL8 *m1_p,*m2_p; REAL8 deltaF, f_max; /* Sampling rate for time domain models */ deltaT = model->deltaT; if (LALInferenceCheckVariable(model->params, "LAL_APPROXIMANT")) approximant = *(Approximant*) LALInferenceGetVariable(model->params, "LAL_APPROXIMANT"); else { XLALPrintError(" ERROR in templateLALGenerateInspiral(): (INT4) \"LAL_APPROXIMANT\" parameter not provided!\n"); XLAL_ERROR_VOID(XLAL_EDATA); } if (LALInferenceCheckVariable(model->params, "LAL_PNORDER")) order = *(INT4*) LALInferenceGetVariable(model->params, "LAL_PNORDER"); else { XLALPrintError(" ERROR in templateLALGenerateInspiral(): (INT4) \"LAL_PNORDER\" parameter not provided!\n"); XLAL_ERROR_VOID(XLAL_EDATA); } /* Explicitly set the default amplitude order if one is not specified. * This serves two purposes: * 1) The default behavior of the code won't change unexpectedly due to changes in LALSimulation. * 2) We need to know the amplitude order in order to set the starting frequency of the waveform properly. */ if (LALInferenceCheckVariable(model->params, "LAL_AMPORDER")) amporder = *(INT4*) LALInferenceGetVariable(model->params, "LAL_AMPORDER"); else amporder = -1; REAL8 f_ref = 100.0; if (LALInferenceCheckVariable(model->params, "f_ref")) f_ref = *(REAL8 *)LALInferenceGetVariable(model->params, "f_ref"); REAL8 fTemp = f_ref; if(LALInferenceCheckVariable(model->params,"chirpmass")) { mc = *(REAL8*) LALInferenceGetVariable(model->params, "chirpmass"); if (LALInferenceCheckVariable(model->params,"q")) { REAL8 q = *(REAL8 *)LALInferenceGetVariable(model->params,"q"); q2masses(mc, q, &m1, &m2); } else { REAL8 eta = *(REAL8*) LALInferenceGetVariable(model->params, "eta"); mc2masses(mc, eta, &m1, &m2); } } else if((m1_p=(REAL8 *)LALInferenceGetVariable(model->params, "mass1")) && (m2_p=(REAL8 *)LALInferenceGetVariable(model->params, "mass2"))) { m1=*m1_p; m2=*m2_p; } else { fprintf(stderr,"No mass parameters found!"); exit(0); } distance = LALInferenceGetREAL8Variable(model->params,"distance")* LAL_PC_SI * 1.0e6; /* distance (1 Mpc) in units of metres */ phi0 = LALInferenceGetREAL8Variable(model->params, "phase"); /* START phase as per lalsimulation convention, radians*/ /* Zenith angle between J and N in radians. Also known as inclination angle when spins are aligned */ REAL8 thetaJN = acos(LALInferenceGetREAL8Variable(model->params, "costheta_jn")); /* zenith angle between J and N in radians */ /* Check if fLow is a model parameter, otherwise use data structure definition */ if(LALInferenceCheckVariable(model->params, "flow")) f_low = *(REAL8*) LALInferenceGetVariable(model->params, "flow"); else f_low = model->fLow; f_start = fLow2fStart(f_low, amporder, approximant); f_max = 0.0; /* for freq domain waveforms this will stop at ISCO. Previously found using model->fHigh causes NaNs in waveform (see redmine issue #750)*/ /* ==== SPINS ==== */ /* We will default to spinless signal and then add in the spin components if required */ /* If there are non-aligned spins, we must convert between the System Frame coordinates * and the cartestian coordinates */ /* The cartesian spin coordinates (default 0), as passed to LALSimulation */ REAL8 spin1x = 0.0; REAL8 spin1y = 0.0; REAL8 spin1z = 0.0; REAL8 spin2x = 0.0; REAL8 spin2y = 0.0; REAL8 spin2z = 0.0; /* System frame coordinates as used for jump proposals */ REAL8 a_spin1 = 0.0; /* Magnitude of spin1 */ REAL8 a_spin2 = 0.0; /* Magnitude of spin2 */ REAL8 phiJL = 0.0; /* azimuthal angle of L_N on its cone about J radians */ REAL8 tilt1 = 0.0; /* zenith angle between S1 and LNhat in radians */ REAL8 tilt2 = 0.0; /* zenith angle between S2 and LNhat in radians */ REAL8 phi12 = 0.0; /* difference in azimuthal angle btwn S1, S2 in radians */ /* Now check if we have spin amplitudes */ if(LALInferenceCheckVariable(model->params, "a_spin1")) a_spin1 = *(REAL8*) LALInferenceGetVariable(model->params, "a_spin1"); if(LALInferenceCheckVariable(model->params, "a_spin2")) a_spin2 = *(REAL8*) LALInferenceGetVariable(model->params, "a_spin2"); /* Check if we have spin angles too */ if(LALInferenceCheckVariable(model->params, "phi_jl")) phiJL = LALInferenceGetREAL8Variable(model->params, "phi_jl"); if(LALInferenceCheckVariable(model->params, "tilt_spin1")) tilt1 = LALInferenceGetREAL8Variable(model->params, "tilt_spin1"); if(LALInferenceCheckVariable(model->params, "tilt_spin2")) tilt2 = LALInferenceGetREAL8Variable(model->params, "tilt_spin2"); if(LALInferenceCheckVariable(model->params, "phi12")) phi12 = LALInferenceGetREAL8Variable(model->params, "phi12"); /* If we have tilt angles zero, then the spins are aligned and we just set the z component */ /* However, if the waveform supports precession then we still need to get the right coordinate components */ SpinSupport spin_support=XLALSimInspiralGetSpinSupportFromApproximant(approximant); if(tilt1==0.0 && tilt2==0.0 && (spin_support==LAL_SIM_INSPIRAL_SPINLESS || spin_support==LAL_SIM_INSPIRAL_ALIGNEDSPIN)) { spin1z=a_spin1; spin2z=a_spin2; inclination = thetaJN; /* Inclination angle is just thetaJN */ } else { /* Template is not aligned-spin only. */ /* Set all the other spin components according to the angles we received above */ /* The transformation function doesn't know fLow, so f_ref==0 isn't interpretted as a request to use the starting frequency for reference. */ if(fTemp==0.0) fTemp = f_start; XLAL_TRY(ret=XLALSimInspiralTransformPrecessingNewInitialConditions( &inclination, &spin1x, &spin1y, &spin1z, &spin2x, &spin2y, &spin2z, thetaJN, phiJL, tilt1, tilt2, phi12, a_spin1, a_spin2, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, fTemp), errnum); if (ret == XLAL_FAILURE) { XLALPrintError(" ERROR in XLALSimInspiralTransformPrecessingNewInitialConditions(): error converting angles. errnum=%d\n",errnum ); return; } } /* ==== TIDAL PARAMETERS ==== */ REAL8 lambda1 = 0.; if(LALInferenceCheckVariable(model->params, "lambda1")) lambda1 = *(REAL8*) LALInferenceGetVariable(model->params, "lambda1"); REAL8 lambda2 = 0.; if(LALInferenceCheckVariable(model->params, "lambda2")) lambda2 = *(REAL8*) LALInferenceGetVariable(model->params, "lambda2"); REAL8 lambdaT = 0.; REAL8 dLambdaT = 0.; REAL8 sym_mass_ratio_eta = 0.; if(LALInferenceCheckVariable(model->params, "lambdaT")&&LALInferenceCheckVariable(model->params, "dLambdaT")){ lambdaT = *(REAL8*) LALInferenceGetVariable(model->params, "lambdaT"); dLambdaT = *(REAL8*) LALInferenceGetVariable(model->params, "dLambdaT"); sym_mass_ratio_eta = m1*m2/((m1+m2)*(m1+m2)); LALInferenceLambdaTsEta2Lambdas(lambdaT,dLambdaT,sym_mass_ratio_eta,&lambda1,&lambda2); } /* Only use GR templates */ LALSimInspiralTestGRParam *nonGRparams = NULL; /* ==== Call the waveform generator ==== */ if(model->domain == LAL_SIM_DOMAIN_FREQUENCY) { deltaF = model->deltaF; XLAL_TRY(ret=XLALSimInspiralChooseFDWaveformFromCache(&hptilde, &hctilde, phi0, deltaF, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, f_start, f_max, f_ref, distance, inclination,lambda1, lambda2, model->waveFlags, nonGRparams, amporder, order, approximant,model->waveformCache, NULL), errnum); /* if the waveform failed to generate, fill the buffer with zeros * so that the previous waveform is not left there */ if (ret != XLAL_SUCCESS || hptilde == NULL || hctilde == NULL) { XLALPrintError(" ERROR in XLALSimInspiralChooseWaveformFromCache(): error generating waveform. errnum=%d\n",errnum ); memset(model->freqhPlus->data->data,0,sizeof(model->freqhPlus->data->data[0])*model->freqhPlus->data->length); memset(model->freqhCross->data->data,0,sizeof(model->freqhCross->data->data[0])*model->freqhCross->data->length); if ( hptilde ) XLALDestroyCOMPLEX16FrequencySeries(hptilde); if ( hctilde ) XLALDestroyCOMPLEX16FrequencySeries(hctilde); XLALSimInspiralDestroyTestGRParam(nonGRparams); XLAL_ERROR_VOID(XLAL_FAILURE); } if (hptilde==NULL || hptilde->data==NULL || hptilde->data->data==NULL ) { XLALPrintError(" ERROR in LALInferenceTemplateXLALSimInspiralChooseWaveform(): encountered unallocated 'hptilde'.\n"); XLAL_ERROR_VOID(XLAL_EFAULT); } if (hctilde==NULL || hctilde->data==NULL || hctilde->data->data==NULL ) { XLALPrintError(" ERROR in LALInferenceTemplateXLALSimInspiralChooseWaveform(): encountered unallocated 'hctilde'.\n"); XLAL_ERROR_VOID(XLAL_EFAULT); } INT4 rem=0; UINT4 size=hptilde->data->length; if(size>model->freqhPlus->data->length) size=model->freqhPlus->data->length; memcpy(model->freqhPlus->data->data,hptilde->data->data,sizeof(hptilde->data->data[0])*size); if( (rem=(model->freqhPlus->data->length - size)) > 0) memset(&(model->freqhPlus->data->data[size]),0, rem*sizeof(hptilde->data->data[0]) ); size=hctilde->data->length; if(size>model->freqhCross->data->length) size=model->freqhCross->data->length; memcpy(model->freqhCross->data->data,hctilde->data->data,sizeof(hctilde->data->data[0])*size); if( (rem=(model->freqhCross->data->length - size)) > 0) memset(&(model->freqhCross->data->data[size]),0, rem*sizeof(hctilde->data->data[0]) ); /* Destroy the nonGr params */ XLALSimInspiralDestroyTestGRParam(nonGRparams); REAL8 instant = model->freqhPlus->epoch.gpsSeconds + 1e-9*model->freqhPlus->epoch.gpsNanoSeconds; LALInferenceSetVariable(model->params, "time", &instant); } else { XLAL_TRY(ret=XLALSimInspiralChooseTDWaveformFromCache(&hplus, &hcross, phi0, deltaT, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, f_start, f_ref, distance, inclination, lambda1, lambda2, model->waveFlags, nonGRparams, amporder, order, approximant,model->waveformCache), errnum); XLALSimInspiralDestroyTestGRParam(nonGRparams); if (ret == XLAL_FAILURE || hplus == NULL || hcross == NULL) { XLALPrintError(" ERROR in XLALSimInspiralChooseWaveformFromCache(): error generating waveform. errnum=%d\n",errnum ); memset(model->timehPlus->data->data,0,sizeof(model->timehPlus->data->data[0]) * model->timehPlus->data->length); memset(model->timehCross->data->data,0,sizeof(model->timehCross->data->data[0]) * model->timehCross->data->length); if ( hplus ) XLALDestroyREAL8TimeSeries(hplus); if ( hcross ) XLALDestroyREAL8TimeSeries(hcross); XLALSimInspiralDestroyTestGRParam(nonGRparams); XLAL_ERROR_VOID(XLAL_FAILURE); } /* The following complicated mess is a result of the following considerations: 1) The discrete time samples of the template and the timeModel buffers will not, in general line up. 2) The likelihood function will timeshift the template in the frequency domain to align it properly with the desired tc in each detector (these are different because the detectors receive the signal at different times). Because this timeshifting is done in the frequency domain, the effective time-domain template is periodic. We want to avoid the possibility of non-zero template samples wrapping around from the start/end of the buffer, since real templates are not periodic! 3) If the template apporaches the ends of the timeModel buffer, then it should be tapered in the same way as the timeData (currently 0.4 seconds, hard-coded! Tukey window; see LALInferenceReadData.c, near line 233) so that template and signal in the data match. However, as an optimization, we perform only one tapering and FFT-ing in the likelihood function; subsequent timeshifts for the different detectors will cause the tapered regions of the template and data to become mis-aligned. The algorthim we use is the following: 1) Inject the template to align with the nearest sample in the timeModel buffer to the desired geocent_end time. 2) Check whether either the start or the end of the template overlaps the tapered region, plus a safety buffer corresponding to a conservative estimate of the largest geocenter <--> detector timeshift. a) If there is no overlap at the start or end of the buffer, we're done. b) If there is an overlap, issue one warning per process (which can be disabled by setting the LAL debug level) about a too-short segment length, and return. */ size_t waveLength = hplus->data->length; size_t bufLength = model->timehPlus->data->length; /* 2*Rearth/(c*deltaT)---2 is safety factor---is the maximum time shift for any earth-based detector. */ size_t maxShift = (size_t)lround(4.255e-2/deltaT); /* Taper 0.4 seconds at start and end (hard-coded! in LALInferenceReadData.c, around line 233). */ size_t taperLength = (size_t)lround(0.4/deltaT); /* Within unsafeLength of ends of buffer, possible danger of wrapping and/or tapering interactions. */ size_t unsafeLength = taperLength + maxShift; REAL8 desiredTc = *(REAL8 *)LALInferenceGetVariable(model->params, "time"); REAL8 tStart = XLALGPSGetREAL8(&(model->timehPlus->epoch)); REAL8 tEnd = tStart + deltaT * model->timehPlus->data->length; if (desiredTc < tStart || desiredTc > tEnd) { XLALDestroyREAL8TimeSeries(hplus); XLALDestroyREAL8TimeSeries(hcross); XLAL_PRINT_ERROR("desired tc (%.4f) outside data buffer\n", desiredTc); XLAL_ERROR_VOID(XLAL_EDOM); } /* The nearest sample in model buffer to the desired tc. */ size_t tcSample = (size_t)lround((desiredTc - XLALGPSGetREAL8(&(model->timehPlus->epoch)))/deltaT); /* The acutal coalescence time that corresponds to the buffer sample on which the waveform's tC lands. */ REAL8 injTc = XLALGPSGetREAL8(&(model->timehPlus->epoch)) + tcSample*deltaT; /* The sample at which the waveform reaches tc. */ size_t waveTcSample = (size_t)lround(-XLALGPSGetREAL8(&(hplus->epoch))/deltaT); /* 1 + (number of samples post-tc in waveform) */ size_t wavePostTc = waveLength - waveTcSample; size_t bufStartIndex = (tcSample >= waveTcSample ? tcSample - waveTcSample : 0); size_t bufEndIndex = (wavePostTc + tcSample <= bufLength ? wavePostTc + tcSample : bufLength); size_t bufWaveLength = bufEndIndex - bufStartIndex; size_t waveStartIndex = (tcSample >= waveTcSample ? 0 : waveTcSample - tcSample); if (bufStartIndex < unsafeLength || (bufLength - bufEndIndex) <= unsafeLength) { /* The waveform could be timeshifted into a region where it will be tapered improperly, or even wrap around from the periodic timeshift. Issue warning. */ if (!sizeWarning) { fprintf(stderr, "WARNING: Generated template is too long to guarantee that it will not\n"); fprintf(stderr, "WARNING: (a) lie in a tapered region of the time-domain buffer\n"); fprintf(stderr, "WARNING: (b) wrap periodically when timeshifted in likelihood computation\n"); fprintf(stderr, "WARNING: Either of these may cause differences between the template and the\n"); fprintf(stderr, "WARNING: correct GW waveform in each detector.\n"); fprintf(stderr, "WARNING: Parameter estimation will continue, but you should consider\n"); fprintf(stderr, "WARNING: increasing the data segment length (using the --seglen) option.\n"); sizeWarning = 1; } } /* Clear model buffers */ memset(model->timehPlus->data->data, 0, sizeof(REAL8)*model->timehPlus->data->length); memset(model->timehCross->data->data, 0, sizeof(REAL8)*model->timehCross->data->length); /* Inject */ memcpy(model->timehPlus->data->data + bufStartIndex, hplus->data->data + waveStartIndex, bufWaveLength*sizeof(REAL8)); memcpy(model->timehCross->data->data + bufStartIndex, hcross->data->data + waveStartIndex, bufWaveLength*sizeof(REAL8)); LALInferenceSetVariable(model->params, "time", &injTc); } if ( hplus ) XLALDestroyREAL8TimeSeries(hplus); if ( hcross ) XLALDestroyREAL8TimeSeries(hcross); if ( hptilde ) XLALDestroyCOMPLEX16FrequencySeries(hptilde); if ( hctilde ) XLALDestroyCOMPLEX16FrequencySeries(hctilde); return; }
/** * Dump complete multi-PSDVector over IFOs, timestamps and frequency-bins into * per-IFO ASCII output-files 'outbname-IFO' * */ int XLALDumpMultiPSDVector ( const CHAR *outbname, /**< output basename 'outbname' */ const MultiPSDVector *multiPSDVect /**< multi-psd vector to output */ ) { /* check input consistency */ if ( outbname == NULL ) { XLALPrintError ("%s: NULL input 'outbname'\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } if ( multiPSDVect == NULL ) { XLALPrintError ("%s: NULL input 'multiPSDVect'\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } if ( multiPSDVect->length == 0 || multiPSDVect->data==0 ) { XLALPrintError ("%s: invalid multiPSDVect input (length=0 or data=NULL)\n", __func__ ); XLAL_ERROR ( XLAL_EINVAL ); } CHAR *fname; FILE *fp; UINT4 len = strlen ( outbname ) + 4; if ( ( fname = XLALMalloc ( len * sizeof(CHAR) )) == NULL ) { XLALPrintError ("%s: XLALMalloc(%d) failed.\n", __func__, len ); XLAL_ERROR ( XLAL_ENOMEM); } UINT4 numIFOs = multiPSDVect->length; UINT4 X; for ( X = 0; X < numIFOs; X ++ ) { PSDVector *thisPSDVect = multiPSDVect->data[X]; char buf[100]; sprintf ( fname, "%s-%c%c", outbname, thisPSDVect->data[0].name[0], thisPSDVect->data[0].name[1] ); if ( ( fp = fopen( fname, "wb" )) == NULL ) { XLALPrintError ("%s: Failed to open PSDperSFT file '%s' for writing!\n", __func__, fname ); XLALFree ( fname ); XLAL_ERROR ( XLAL_ESYS ); } REAL8 f0 = thisPSDVect->data[0].f0; REAL8 dFreq = thisPSDVect->data[0].deltaF; UINT4 numFreqs = thisPSDVect->data[0].data->length; UINT4 iFreq; /* write comment header line into this output file */ /* FIXME: output code-version/cmdline/history info */ fprintf(fp,"%%%% first line holds frequencies [Hz] of PSD-Columns\n"); /* loop over frequency and output comnment-header markers */ fprintf(fp,"%%%%%-17s", "dummy"); for ( iFreq = 0; iFreq < numFreqs; iFreq ++ ) { sprintf (buf, "f%d [Hz]", iFreq + 1 ); fprintf (fp, " %-21s", buf ); } fprintf (fp, "\n"); /* write parseable header-line giving bin frequencies for PSDs */ fprintf (fp, "%-19d", -1 ); for (iFreq = 0; iFreq < numFreqs; iFreq++ ) fprintf (fp, " %-21.16g", f0 + iFreq * dFreq ); fprintf (fp, "\n\n\n"); /* output another header line describing the following format "ti[GPS] PSD(f1) ... " */ fprintf(fp,"%%%%%-17s", "ti[GPS]"); for ( iFreq = 0; iFreq < numFreqs; iFreq ++ ) { sprintf (buf, "PSD(f%d)", iFreq + 1 ); fprintf (fp, " %-21s", buf ); } fprintf (fp, "\n"); /* loop over timestamps: dump all PSDs over frequencies into one line */ UINT4 numTS = thisPSDVect->length; UINT4 iTS; for ( iTS = 0; iTS < numTS; iTS++ ) { REAL8FrequencySeries *thisPSD = &thisPSDVect->data[iTS]; /* first output timestamp GPS time for this line */ REAL8 tGPS = XLALGPSGetREAL8( &thisPSD->epoch ); fprintf (fp, "%-19.18g", tGPS ); /* some internal consistency/paranoia checks */ if ( ( f0 != thisPSD->f0) || ( dFreq != thisPSD->deltaF ) || (numFreqs != thisPSD->data->length ) ) { XLALPrintError ("%s: %d-th timestamp %f: inconsistent PSDVector: f0 = %g : %g, dFreq = %g : %g, numFreqs = %d : %d \n", __func__, iTS, tGPS, f0, thisPSD->f0, dFreq, thisPSD->deltaF, numFreqs, thisPSD->data->length ); XLALFree ( fname ); fclose ( fp ); XLAL_ERROR ( XLAL_EDOM ); } /* loop over all frequencies and dump PSD-value */ for ( iFreq = 0; iFreq < numFreqs; iFreq ++ ) fprintf (fp, " %-21.16g", thisPSD->data->data[iFreq] ); fprintf (fp, "\n"); } /* for iTS < numTS */ fclose ( fp ); } /* for X < numIFOs */ XLALFree ( fname ); return XLAL_SUCCESS; } /* XLALDumpMultiPSDVector() */
int main(int argc, char *argv[]){ UserInput_t XLAL_INIT_DECL(uvar); static ConfigVariables config; /* sft related variables */ MultiSFTVector *inputSFTs = NULL; MultiPSDVector *multiPSDs = NULL; MultiNoiseWeights *multiWeights = NULL; MultiLIGOTimeGPSVector *multiTimes = NULL; MultiLALDetector multiDetectors; MultiDetectorStateSeries *multiStates = NULL; MultiAMCoeffs *multiCoeffs = NULL; SFTIndexList *sftIndices = NULL; SFTPairIndexList *sftPairs = NULL; REAL8Vector *shiftedFreqs = NULL; UINT4Vector *lowestBins = NULL; COMPLEX8Vector *expSignalPhases = NULL; REAL8VectorSequence *sincList = NULL; PulsarDopplerParams XLAL_INIT_DECL(dopplerpos); PulsarDopplerParams thisBinaryTemplate, binaryTemplateSpacings; PulsarDopplerParams minBinaryTemplate, maxBinaryTemplate; SkyPosition XLAL_INIT_DECL(skyPos); MultiSSBtimes *multiBinaryTimes = NULL; INT4 k; UINT4 j; REAL8 fMin, fMax; /* min and max frequencies read from SFTs */ REAL8 deltaF; /* frequency resolution associated with time baseline of SFTs */ REAL8 diagff = 0; /*diagonal metric components*/ REAL8 diagaa = 0; REAL8 diagTT = 0; REAL8 diagpp = 1; REAL8 ccStat = 0; REAL8 evSquared=0; REAL8 estSens=0; /*estimated sensitivity(4.13)*/ BOOLEAN dopplerShiftFlag = TRUE; toplist_t *ccToplist=NULL; CrossCorrBinaryOutputEntry thisCandidate; UINT4 checksum; LogPrintf (LOG_CRITICAL, "Starting time\n"); /*for debug convenience to record calculating time*/ /* initialize and register user variables */ LIGOTimeGPS computingStartGPSTime, computingEndGPSTime; XLALGPSTimeNow (&computingStartGPSTime); /* record the rough starting GPS time*/ if ( XLALInitUserVars( &uvar ) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read user input from the command line or config file */ if ( XLALUserVarReadAllInput ( argc, argv ) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALUserVarReadAllInput() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if (uvar.help) /* if help was requested, then exit */ return 0; CHAR *VCSInfoString = XLALGetVersionString(0); /**<LAL + LALapps Vsersion string*/ /*If the version information was requested, output it and exit*/ if ( uvar.version ){ XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); printf ("%s\n", VCSInfoString ); exit (0); } /* configure useful variables based on user input */ if ( XLALInitializeConfigVars ( &config, &uvar) != XLAL_SUCCESS ) { LogPrintf ( LOG_CRITICAL, "%s: XLALInitUserVars() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } deltaF = config.catalog->data[0].header.deltaF; REAL8 Tsft = 1.0 / deltaF; if (XLALUserVarWasSet(&uvar.spacingF) && XLALUserVarWasSet(&uvar.mismatchF)) LogPrintf (LOG_CRITICAL, "spacingF and mismatchF are both set, use spacingF %.9g by default\n\n", uvar.spacingF); if (XLALUserVarWasSet(&uvar.spacingA) && XLALUserVarWasSet(&uvar.mismatchA)) LogPrintf (LOG_CRITICAL, "spacingA and mismatchA are both set, use spacingA %.9g by default\n\n", uvar.spacingA); if (XLALUserVarWasSet(&uvar.spacingT) && XLALUserVarWasSet(&uvar.mismatchT)) LogPrintf (LOG_CRITICAL, "spacingT and mismatchT are both set, use spacingT %.9g by default\n\n", uvar.spacingT); if (XLALUserVarWasSet(&uvar.spacingP) && XLALUserVarWasSet(&uvar.mismatchP)) LogPrintf (LOG_CRITICAL, "spacingP and mismatchP are both set, use spacingP %.9g by default\n\n", uvar.spacingP); /* create the toplist */ create_crossCorrBinary_toplist( &ccToplist, uvar.numCand); /* now read the data */ /* /\* get SFT parameters so that we can initialise search frequency resolutions *\/ */ /* /\* calculate deltaF_SFT *\/ */ /* deltaF_SFT = catalog->data[0].header.deltaF; /\* frequency resolution *\/ */ /* timeBase= 1.0/deltaF_SFT; /\* sft baseline *\/ */ /* /\* catalog is ordered in time so we can get start, end time and tObs *\/ */ /* firstTimeStamp = catalog->data[0].header.epoch; */ /* lastTimeStamp = catalog->data[catalog->length - 1].header.epoch; */ /* tObs = XLALGPSDiff( &lastTimeStamp, &firstTimeStamp ) + timeBase; */ /* /\*set pulsar reference time *\/ */ /* if (LALUserVarWasSet ( &uvar_refTime )) { */ /* XLALGPSSetREAL8(&refTime, uvar_refTime); */ /* } */ /* else { /\*if refTime is not set, set it to midpoint of sfts*\/ */ /* XLALGPSSetREAL8(&refTime, (0.5*tObs) + XLALGPSGetREAL8(&firstTimeStamp)); */ /* } */ /* /\* set frequency resolution defaults if not set by user *\/ */ /* if (!(LALUserVarWasSet (&uvar_fResolution))) { */ /* uvar_fResolution = 1/tObs; */ /* } */ /* { */ /* /\* block for calculating frequency range to read from SFTs *\/ */ /* /\* user specifies freq and fdot range at reftime */ /* we translate this range of fdots to start and endtime and find */ /* the largest frequency band required to cover the */ /* frequency evolution *\/ */ /* PulsarSpinRange spinRange_startTime; /\**< freq and fdot range at start-time of observation *\/ */ /* PulsarSpinRange spinRange_endTime; /\**< freq and fdot range at end-time of observation *\/ */ /* PulsarSpinRange spinRange_refTime; /\**< freq and fdot range at the reference time *\/ */ /* REAL8 startTime_freqLo, startTime_freqHi, endTime_freqLo, endTime_freqHi, freqLo, freqHi; */ /* REAL8Vector *fdotsMin=NULL; */ /* REAL8Vector *fdotsMax=NULL; */ /* UINT4 k; */ /* fdotsMin = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */ /* fdotsMin->length = N_SPINDOWN_DERIVS; */ /* fdotsMin->data = (REAL8 *)LALCalloc(fdotsMin->length, sizeof(REAL8)); */ /* fdotsMax = (REAL8Vector *)LALCalloc(1, sizeof(REAL8Vector)); */ /* fdotsMax->length = N_SPINDOWN_DERIVS; */ /* fdotsMax->data = (REAL8 *)LALCalloc(fdotsMax->length, sizeof(REAL8)); */ /* XLAL_INIT_MEM(spinRange_startTime); */ /* XLAL_INIT_MEM(spinRange_endTime); */ /* XLAL_INIT_MEM(spinRange_refTime); */ /* spinRange_refTime.refTime = refTime; */ /* spinRange_refTime.fkdot[0] = uvar_f0; */ /* spinRange_refTime.fkdotBand[0] = uvar_fBand; */ /* } */ /* FIXME: need to correct fMin and fMax for Doppler shift, rngmedian bins and spindown range */ /* this is essentially just a place holder for now */ /* FIXME: this running median buffer is overkill, since the running median block need not be centered on the search frequency */ REAL8 vMax = LAL_TWOPI * (uvar.orbitAsiniSec + uvar.orbitAsiniSecBand) / uvar.orbitPSec + LAL_TWOPI * LAL_REARTH_SI / (LAL_DAYSID_SI * LAL_C_SI) + LAL_TWOPI * LAL_AU_SI/(LAL_YRSID_SI * LAL_C_SI); /*calculate the maximum relative velocity in speed of light*/ fMin = uvar.fStart * (1 - vMax) - 0.5 * uvar.rngMedBlock * deltaF; fMax = (uvar.fStart + uvar.fBand) * (1 + vMax) + 0.5 * uvar.rngMedBlock * deltaF; /* read the SFTs*/ if ((inputSFTs = XLALLoadMultiSFTs ( config.catalog, fMin, fMax)) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALLoadMultiSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* calculate the psd and normalize the SFTs */ if (( multiPSDs = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.rngMedBlock, NULL )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALNormalizeMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* compute the noise weights for the AM coefficients */ if (( multiWeights = XLALComputeMultiNoiseWeights ( multiPSDs, uvar.rngMedBlock, 0 )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiNoiseWeights() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read the timestamps from the SFTs */ if ((multiTimes = XLALExtractMultiTimestampsFromSFTs ( inputSFTs )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALExtractMultiTimestampsFromSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* read the detector information from the SFTs */ if ( XLALMultiLALDetectorFromMultiSFTs ( &multiDetectors, inputSFTs ) != XLAL_SUCCESS){ LogPrintf ( LOG_CRITICAL, "%s: XLALMultiLALDetectorFromMultiSFTs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Find the detector state for each SFT */ /* Offset by Tsft/2 to get midpoint as timestamp */ if ((multiStates = XLALGetMultiDetectorStates ( multiTimes, &multiDetectors, config.edat, 0.5 * Tsft )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiDetectorStates() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Note this is specialized to a single sky position */ /* This might need to be moved into the config variables */ skyPos.system = COORDINATESYSTEM_EQUATORIAL; skyPos.longitude = uvar.alphaRad; skyPos.latitude = uvar.deltaRad; /* Calculate the AM coefficients (a,b) for each SFT */ if ((multiCoeffs = XLALComputeMultiAMCoeffs ( multiStates, multiWeights, skyPos )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALComputeMultiAMCoeffs() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Construct the flat list of SFTs (this sort of replicates the catalog, but there's not an obvious way to get the information back) */ if ( ( XLALCreateSFTIndexListFromMultiSFTVect( &sftIndices, inputSFTs ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTIndexListFromMultiSFTVect() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* Construct the list of SFT pairs */ #define PCC_SFTPAIR_HEADER "# The length of SFT-pair list is %u #\n" #define PCC_SFTPAIR_BODY "%u %u\n" #define PCC_SFT_HEADER "# The length of SFT list is %u #\n" #define PCC_SFT_BODY "%s %d %d\n" FILE *fp = NULL; if (XLALUserVarWasSet(&uvar.pairListInputFilename)) { /* If the user provided a list for reading, use it */ if((sftPairs = XLALCalloc(1, sizeof(sftPairs))) == NULL){ XLAL_ERROR(XLAL_ENOMEM); } if((fp = fopen(uvar.pairListInputFilename, "r")) == NULL){ LogPrintf ( LOG_CRITICAL, "didn't find SFT-pair list file with given input name\n"); XLAL_ERROR( XLAL_EFUNC ); } if(fscanf(fp,PCC_SFTPAIR_HEADER,&sftPairs->length)==EOF){ LogPrintf ( LOG_CRITICAL, "can't read the length of SFT-pair list from the header\n"); XLAL_ERROR( XLAL_EFUNC ); } if((sftPairs->data = XLALCalloc(sftPairs->length, sizeof(*sftPairs->data)))==NULL){ XLALFree(sftPairs); XLAL_ERROR(XLAL_ENOMEM); } for(j = 0; j < sftPairs->length; j++){ /*read in the SFT-pair list */ if(fscanf(fp,PCC_SFTPAIR_BODY, &sftPairs->data[j].sftNum[0], &sftPairs->data[j].sftNum[1])==EOF){ LogPrintf ( LOG_CRITICAL, "The length of SFT-pair list doesn't match!"); XLAL_ERROR( XLAL_EFUNC ); } } fclose(fp); } else { /* if not, construct the list of pairs */ if ( ( XLALCreateSFTPairIndexList( &sftPairs, sftIndices, inputSFTs, uvar.maxLag, uvar.inclAutoCorr ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCreateSFTPairIndexList() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } } if (XLALUserVarWasSet(&uvar.pairListOutputFilename)) { /* Write the list of pairs to a file, if a name was provided */ if((fp = fopen(uvar.pairListOutputFilename, "w")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in SFT-pair list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_SFTPAIR_HEADER, sftPairs->length ); /*output the length of SFT-pair list to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_SFTPAIR_BODY, sftPairs->data[j].sftNum[0], sftPairs->data[j].sftNum[1]); } fclose(fp); } if (XLALUserVarWasSet(&uvar.sftListOutputFilename)) { /* Write the list of SFTs to a file for sanity-checking purposes */ if((fp = fopen(uvar.sftListOutputFilename, "w")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in flat SFT list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_SFT_HEADER, sftIndices->length ); /*output the length of SFT list to the header*/ for(j = 0; j < sftIndices->length; j++){ /*output the SFT list */ fprintf(fp,PCC_SFT_BODY, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds, inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds); } fclose(fp); } else if(XLALUserVarWasSet(&uvar.sftListInputFilename)){ /*do a sanity check of the order of SFTs list if the name of input SFT list is given*/ UINT4 numofsft=0; if((fp = fopen(uvar.sftListInputFilename, "r")) == NULL){ LogPrintf ( LOG_CRITICAL, "Can't read in flat SFT list \n"); XLAL_ERROR( XLAL_EFUNC ); } if (fscanf(fp, PCC_SFT_HEADER, &numofsft)==EOF){ LogPrintf ( LOG_CRITICAL, "can't read in the length of SFT list from header\n"); XLAL_ERROR( XLAL_EFUNC ); } CHARVectorSequence *checkDet=NULL; if ((checkDet = XLALCreateCHARVectorSequence (numofsft, LALNameLength) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateCHARVector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } INT4 checkGPS[numofsft], checkGPSns[numofsft]; if(numofsft == sftIndices->length){ for (j=0; j<numofsft; j++){ if( fscanf(fp,PCC_SFT_BODY,&checkDet->data[j * LALNameLength], &checkGPS[j], &checkGPSns[j])==EOF){ LogPrintf ( LOG_CRITICAL, "The length of SFT list doesn't match\n"); XLAL_ERROR( XLAL_EFUNC ); } if(strcmp( inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].name, &checkDet->data[j * LALNameLength] ) != 0 ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsSeconds != checkGPS[j] ||inputSFTs->data[sftIndices->data[j].detInd]->data[sftIndices->data[j].sftInd].epoch.gpsNanoSeconds != checkGPSns[j] ){ LogPrintf ( LOG_CRITICAL, "The order of SFTs has been changed, it's the end of civilization\n"); XLAL_ERROR( XLAL_EFUNC ); } } fclose(fp); XLALDestroyCHARVectorSequence(checkDet); } else{ LogPrintf ( LOG_CRITICAL, "Run for your life, the length of SFT list doesn't match"); XLAL_ERROR( XLAL_EFUNC ); } } else { } /* Get weighting factors for calculation of metric */ /* note that the sigma-squared is now absorbed into the curly G because the AM coefficients are noise-weighted. */ REAL8Vector *GammaAve = NULL; REAL8Vector *GammaCirc = NULL; if ( ( XLALCalculateCrossCorrGammas( &GammaAve, &GammaCirc, sftPairs, sftIndices, multiCoeffs) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrGammas() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } #define PCC_GAMMA_HEADER "# The normalization Sinv_Tsft is %g #\n" #define PCC_GAMMA_BODY "%.10g\n" if (XLALUserVarWasSet(&uvar.gammaAveOutputFilename)) { /* Write the aa+bb weight for each pair to a file, if a name was provided */ if((fp = fopen(uvar.gammaAveOutputFilename, "w")) == NULL) { LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_ave list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_GAMMA_BODY, GammaAve->data[j]); } fclose(fp); } if (XLALUserVarWasSet(&uvar.gammaCircOutputFilename)) { /* Write the ab-ba weight for each pair to a file, if a name was provided */ if((fp = fopen(uvar.gammaCircOutputFilename, "w")) == NULL) { LogPrintf ( LOG_CRITICAL, "Can't write in Gamma_circ list \n"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp,PCC_GAMMA_HEADER, multiWeights->Sinv_Tsft); /*output the normalization factor to the header*/ for(j = 0; j < sftPairs->length; j++){ fprintf(fp,PCC_GAMMA_BODY, GammaCirc->data[j]); } fclose(fp); } /*initialize binary parameters structure*/ XLAL_INIT_MEM(minBinaryTemplate); XLAL_INIT_MEM(maxBinaryTemplate); XLAL_INIT_MEM(thisBinaryTemplate); XLAL_INIT_MEM(binaryTemplateSpacings); /*fill in minbinaryOrbitParams*/ XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc); minBinaryTemplate.argp = 0.0; minBinaryTemplate.asini = uvar.orbitAsiniSec; minBinaryTemplate.ecc = 0.0; minBinaryTemplate.period = uvar.orbitPSec; minBinaryTemplate.fkdot[0] = uvar.fStart; /*fill in maxBinaryParams*/ XLALGPSSetREAL8( &maxBinaryTemplate.tp, uvar.orbitTimeAsc + uvar.orbitTimeAscBand); maxBinaryTemplate.argp = 0.0; maxBinaryTemplate.asini = uvar.orbitAsiniSec + uvar.orbitAsiniSecBand; maxBinaryTemplate.ecc = 0.0; maxBinaryTemplate.period = uvar.orbitPSec; maxBinaryTemplate.fkdot[0] = uvar.fStart + uvar.fBand; /*fill in thisBinaryTemplate*/ XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * uvar.orbitTimeAscBand); thisBinaryTemplate.argp = 0.0; thisBinaryTemplate.asini = 0.5*(minBinaryTemplate.asini + maxBinaryTemplate.asini); thisBinaryTemplate.ecc = 0.0; thisBinaryTemplate.period =0.5*(minBinaryTemplate.period + maxBinaryTemplate.period); thisBinaryTemplate.fkdot[0]=0.5*(minBinaryTemplate.fkdot[0] + maxBinaryTemplate.fkdot[0]); /*Get metric diagonal components, also estimate sensitivity i.e. E[rho]/(h0)^2 (4.13)*/ if ( (XLALCalculateLMXBCrossCorrDiagMetric(&estSens, &diagff, &diagaa, &diagTT, thisBinaryTemplate, GammaAve, sftPairs, sftIndices, inputSFTs, multiWeights /*, kappaValues*/) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateLMXBCrossCorrDiagMetric() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* spacing in frequency from diagff */ /* set spacings in new dopplerparams struct */ if (XLALUserVarWasSet(&uvar.spacingF)) /* If spacing was given by CMD line, use it, else calculate spacing by mismatch*/ binaryTemplateSpacings.fkdot[0] = uvar.spacingF; else binaryTemplateSpacings.fkdot[0] = sqrt(uvar.mismatchF / diagff); if (XLALUserVarWasSet(&uvar.spacingA)) binaryTemplateSpacings.asini = uvar.spacingA; else binaryTemplateSpacings.asini = sqrt(uvar.mismatchA / diagaa); /* this is annoying: tp is a GPS time while we want a difference in time which should be just REAL8 */ if (XLALUserVarWasSet(&uvar.spacingT)) XLALGPSSetREAL8( &binaryTemplateSpacings.tp, uvar.spacingT); else XLALGPSSetREAL8( &binaryTemplateSpacings.tp, sqrt(uvar.mismatchT / diagTT)); if (XLALUserVarWasSet(&uvar.spacingP)) binaryTemplateSpacings.period = uvar.spacingP; else binaryTemplateSpacings.period = sqrt(uvar.mismatchP / diagpp); /* metric elements for eccentric case not considered? */ UINT8 fCount = 0, aCount = 0, tCount = 0 , pCount = 0; const UINT8 fSpacingNum = floor( uvar.fBand / binaryTemplateSpacings.fkdot[0]); const UINT8 aSpacingNum = floor( uvar.orbitAsiniSecBand / binaryTemplateSpacings.asini); const UINT8 tSpacingNum = floor( uvar.orbitTimeAscBand / XLALGPSGetREAL8(&binaryTemplateSpacings.tp)); const UINT8 pSpacingNum = floor( uvar.orbitPSecBand / binaryTemplateSpacings.period); /*reset minbinaryOrbitParams to shift the first point a factor so as to make the center of all seaching points centers at the center of searching band*/ minBinaryTemplate.fkdot[0] = uvar.fStart + 0.5 * (uvar.fBand - fSpacingNum * binaryTemplateSpacings.fkdot[0]); minBinaryTemplate.asini = uvar.orbitAsiniSec + 0.5 * (uvar.orbitAsiniSecBand - aSpacingNum * binaryTemplateSpacings.asini); XLALGPSSetREAL8( &minBinaryTemplate.tp, uvar.orbitTimeAsc + 0.5 * (uvar.orbitTimeAscBand - tSpacingNum * XLALGPSGetREAL8(&binaryTemplateSpacings.tp))); minBinaryTemplate.period = uvar.orbitPSec + 0.5 * (uvar.orbitPSecBand - pSpacingNum * binaryTemplateSpacings.period); /* initialize the doppler scan struct which stores the current template information */ XLALGPSSetREAL8(&dopplerpos.refTime, config.refTime); dopplerpos.Alpha = uvar.alphaRad; dopplerpos.Delta = uvar.deltaRad; dopplerpos.fkdot[0] = minBinaryTemplate.fkdot[0]; /* set all spindowns to zero */ for (k=1; k < PULSAR_MAX_SPINS; k++) dopplerpos.fkdot[k] = 0.0; dopplerpos.asini = minBinaryTemplate.asini; dopplerpos.period = minBinaryTemplate.period; dopplerpos.tp = minBinaryTemplate.tp; dopplerpos.ecc = minBinaryTemplate.ecc; dopplerpos.argp = minBinaryTemplate.argp; /* now set the initial values of binary parameters */ /* thisBinaryTemplate.asini = uvar.orbitAsiniSec; thisBinaryTemplate.period = uvar.orbitPSec; XLALGPSSetREAL8( &thisBinaryTemplate.tp, uvar.orbitTimeAsc); thisBinaryTemplate.ecc = 0.0; thisBinaryTemplate.argp = 0.0;*/ /* copy to dopplerpos */ /* Calculate SSB times (can do this once since search is currently only for one sky position, and binary doppler shift is added later) */ MultiSSBtimes *multiSSBTimes = NULL; if ((multiSSBTimes = XLALGetMultiSSBtimes ( multiStates, skyPos, dopplerpos.refTime, SSBPREC_RELATIVISTICOPT )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALGetMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* "New" general metric computation */ /* For now hard-code circular parameter space */ const DopplerCoordinateSystem coordSys = { .dim = 4, .coordIDs = { DOPPLERCOORD_FREQ, DOPPLERCOORD_ASINI, DOPPLERCOORD_TASC, DOPPLERCOORD_PORB, }, }; REAL8VectorSequence *phaseDerivs = NULL; if ( ( XLALCalculateCrossCorrPhaseDerivatives ( &phaseDerivs, &thisBinaryTemplate, config.edat, sftIndices, multiSSBTimes, &coordSys ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseDerivatives() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* fill in metric and parameter offsets */ gsl_matrix *g_ij = NULL; gsl_vector *eps_i = NULL; REAL8 sumGammaSq = 0; if ( ( XLALCalculateCrossCorrPhaseMetric ( &g_ij, &eps_i, &sumGammaSq, phaseDerivs, sftPairs, GammaAve, GammaCirc, &coordSys ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculateCrossCorrPhaseMetric() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } XLALDestroyREAL8VectorSequence ( phaseDerivs ); XLALDestroyREAL8Vector ( GammaCirc ); if ((fp = fopen("gsldata.dat","w"))==NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in gsl matrix file"); XLAL_ERROR( XLAL_EFUNC ); } XLALfprintfGSLvector(fp, "%g", eps_i); XLALfprintfGSLmatrix(fp, "%g", g_ij); /* Allocate structure for binary doppler-shifting information */ if ((multiBinaryTimes = XLALDuplicateMultiSSBtimes ( multiSSBTimes )) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALDuplicateMultiSSBtimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } UINT8 numSFTs = sftIndices->length; if ((shiftedFreqs = XLALCreateREAL8Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((lowestBins = XLALCreateUINT4Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateUINT4Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((expSignalPhases = XLALCreateCOMPLEX8Vector ( numSFTs ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8Vector() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ((sincList = XLALCreateREAL8VectorSequence ( numSFTs, uvar.numBins ) ) == NULL){ LogPrintf ( LOG_CRITICAL, "%s: XLALCreateREAL8VectorSequence() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* args should be : spacings, min and max doppler params */ BOOLEAN firstPoint = TRUE; /* a boolean to help to search at the beginning point in parameter space, after the search it is set to be FALSE to end the loop*/ if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /*Need to apply additional doppler shifting before the loop, or the first point in parameter space will be lost and return a wrong SNR when fBand!=0*/ while ( GetNextCrossCorrTemplate(&dopplerShiftFlag, &firstPoint, &dopplerpos, &binaryTemplateSpacings, &minBinaryTemplate, &maxBinaryTemplate, &fCount, &aCount, &tCount, &pCount, fSpacingNum, aSpacingNum, tSpacingNum, pSpacingNum) == 0) { /* do useful stuff here*/ /* Apply additional Doppler shifting using current binary orbital parameters */ /* Might want to be clever about checking whether we've changed the orbital parameters or only the frequency */ if (dopplerShiftFlag == TRUE) { if ( (XLALAddMultiBinaryTimes( &multiBinaryTimes, multiSSBTimes, &dopplerpos ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALAddMultiBinaryTimes() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } } if ( (XLALGetDopplerShiftedFrequencyInfo( shiftedFreqs, lowestBins, expSignalPhases, sincList, uvar.numBins, &dopplerpos, sftIndices, inputSFTs, multiBinaryTimes, Tsft ) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALGetDopplerShiftedFrequencyInfo() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } if ( (XLALCalculatePulsarCrossCorrStatistic( &ccStat, &evSquared, GammaAve, expSignalPhases, lowestBins, sincList, sftPairs, sftIndices, inputSFTs, multiWeights, uvar.numBins) != XLAL_SUCCESS ) ) { LogPrintf ( LOG_CRITICAL, "%s: XLALCalculatePulsarCrossCorrStatistic() failed with errno=%d\n", __func__, xlalErrno ); XLAL_ERROR( XLAL_EFUNC ); } /* fill candidate struct and insert into toplist if necessary */ thisCandidate.freq = dopplerpos.fkdot[0]; thisCandidate.tp = XLALGPSGetREAL8( &dopplerpos.tp ); thisCandidate.argp = dopplerpos.argp; thisCandidate.asini = dopplerpos.asini; thisCandidate.ecc = dopplerpos.ecc; thisCandidate.period = dopplerpos.period; thisCandidate.rho = ccStat; thisCandidate.evSquared = evSquared; thisCandidate.estSens = estSens; insert_into_crossCorrBinary_toplist(ccToplist, thisCandidate); } /* end while loop over templates */ /* write candidates to file */ sort_crossCorrBinary_toplist( ccToplist ); /* add error checking */ final_write_crossCorrBinary_toplist_to_file( ccToplist, uvar.toplistFilename, &checksum); REAL8 h0Sens = sqrt((10 / sqrt(estSens))); /*for a SNR=10 signal, the h0 we can detect*/ XLALGPSTimeNow (&computingEndGPSTime); /*record the rough end time*/ UINT4 computingTime = computingEndGPSTime.gpsSeconds - computingStartGPSTime.gpsSeconds; /* make a meta-data file*/ if(XLALUserVarWasSet(&uvar.logFilename)){ CHAR *CMDInputStr = XLALUserVarGetLog ( UVAR_LOGFMT_CFGFILE ); if ((fp = fopen(uvar.logFilename,"w"))==NULL){ LogPrintf ( LOG_CRITICAL, "Can't write in logfile"); XLAL_ERROR( XLAL_EFUNC ); } fprintf(fp, "[UserInput]\n\n"); fprintf(fp, "%s\n", CMDInputStr); fprintf(fp, "[CalculatedValues]\n\n"); fprintf(fp, "g_ff = %.9f\n", diagff ); fprintf(fp, "g_aa = %.9f\n", diagaa ); fprintf(fp, "g_TT = %.9f\n", diagTT ); fprintf(fp, "FSpacing = %.9g\n", binaryTemplateSpacings.fkdot[0]); fprintf(fp, "ASpacing = %.9g\n", binaryTemplateSpacings.asini); fprintf(fp, "TSpacing = %.9g\n", XLALGPSGetREAL8(&binaryTemplateSpacings.tp)); /* fprintf(fp, "PSpacing = %.9g\n", binaryTemplateSpacings.period );*/ fprintf(fp, "TemplatenumF = %" LAL_UINT8_FORMAT "\n", (fSpacingNum + 1)); fprintf(fp, "TemplatenumA = %" LAL_UINT8_FORMAT "\n", (aSpacingNum + 1)); fprintf(fp, "TemplatenumT = %" LAL_UINT8_FORMAT "\n", (tSpacingNum + 1)); fprintf(fp, "TemplatenumP = %" LAL_UINT8_FORMAT "\n", (pSpacingNum + 1)); fprintf(fp, "TemplatenumTotal = %" LAL_UINT8_FORMAT "\n",(fSpacingNum + 1) * (aSpacingNum + 1) * (tSpacingNum + 1) * (pSpacingNum + 1)); fprintf(fp, "Sens = %.9g\n", estSens);/*(E[rho]/h0^2)^2*/ fprintf(fp, "h0_min_SNR10 = %.9g\n", h0Sens);/*for rho = 10 in our pipeline*/ fprintf(fp, "startTime = %" LAL_INT4_FORMAT "\n", computingStartGPSTime.gpsSeconds );/*start time in GPS-time*/ fprintf(fp, "endTime = %" LAL_INT4_FORMAT "\n", computingEndGPSTime.gpsSeconds );/*end time in GPS-time*/ fprintf(fp, "computingTime = %" LAL_UINT4_FORMAT "\n", computingTime );/*total time in sec*/ fprintf(fp, "SFTnum = %" LAL_UINT4_FORMAT "\n", sftIndices->length);/*total number of SFT*/ fprintf(fp, "pairnum = %" LAL_UINT4_FORMAT "\n", sftPairs->length);/*total number of pair of SFT*/ fprintf(fp, "Tsft = %.6g\n", Tsft);/*SFT duration*/ fprintf(fp, "\n[Version]\n\n"); fprintf(fp, "%s", VCSInfoString); fclose(fp); XLALFree(CMDInputStr); } XLALFree(VCSInfoString); XLALDestroyCOMPLEX8Vector ( expSignalPhases ); XLALDestroyUINT4Vector ( lowestBins ); XLALDestroyREAL8Vector ( shiftedFreqs ); XLALDestroyREAL8VectorSequence ( sincList ); XLALDestroyMultiSSBtimes ( multiBinaryTimes ); XLALDestroyMultiSSBtimes ( multiSSBTimes ); XLALDestroyREAL8Vector ( GammaAve ); XLALDestroySFTPairIndexList( sftPairs ); XLALDestroySFTIndexList( sftIndices ); XLALDestroyMultiAMCoeffs ( multiCoeffs ); XLALDestroyMultiDetectorStateSeries ( multiStates ); XLALDestroyMultiTimestamps ( multiTimes ); XLALDestroyMultiNoiseWeights ( multiWeights ); XLALDestroyMultiPSDVector ( multiPSDs ); XLALDestroyMultiSFTVector ( inputSFTs ); /* de-allocate memory for configuration variables */ XLALDestroyConfigVars ( &config ); /* de-allocate memory for user input variables */ XLALDestroyUserVars(); /* free toplist memory */ free_crossCorr_toplist(&ccToplist); /* check memory leaks if we forgot to de-allocate anything */ LALCheckMemoryLeaks(); LogPrintf (LOG_CRITICAL, "End time\n");/*for debug convenience to record calculating time*/ return 0; } /* main */ /* initialize and register user variables */ int XLALInitUserVars (UserInput_t *uvar) { /* initialize with some defaults */ uvar->help = FALSE; uvar->maxLag = 0.0; uvar->inclAutoCorr = FALSE; uvar->fStart = 100.0; uvar->fBand = 0.1; /* uvar->fdotStart = 0.0; */ /* uvar->fdotBand = 0.0; */ uvar->alphaRad = 0.0; uvar->deltaRad = 0.0; uvar->refTime = 0.0; uvar->rngMedBlock = 50; uvar->numBins = 1; /* zero binary orbital parameters means not a binary */ uvar->orbitAsiniSec = 0.0; uvar->orbitAsiniSecBand = 0.0; uvar->orbitPSec = 0.0; uvar->orbitPSecBand = 0.0; uvar->orbitTimeAsc = 0; uvar->orbitTimeAscBand = 0; /*default mismatch values */ /* set to 0.1 by default -- for no real reason */ /* make 0.1 a macro? */ uvar->mismatchF = 0.1; uvar->mismatchA = 0.1; uvar->mismatchT = 0.1; uvar->mismatchP = 0.1; uvar->ephemEarth = XLALStringDuplicate("earth00-19-DE405.dat.gz"); uvar->ephemSun = XLALStringDuplicate("sun00-19-DE405.dat.gz"); uvar->sftLocation = XLALCalloc(1, MAXFILENAMELENGTH+1); /* initialize number of candidates in toplist -- default is just to return the single best candidate */ uvar->numCand = 1; uvar->toplistFilename = XLALStringDuplicate("toplist_crosscorr.dat"); uvar->version = FALSE; /* register user-variables */ XLALregBOOLUserStruct ( help, 'h', UVAR_HELP, "Print this message"); XLALregINTUserStruct ( startTime, 0, UVAR_REQUIRED, "Desired start time of analysis in GPS seconds"); XLALregINTUserStruct ( endTime, 0, UVAR_REQUIRED, "Desired end time of analysis in GPS seconds"); XLALregREALUserStruct ( maxLag, 0, UVAR_OPTIONAL, "Maximum lag time in seconds between SFTs in correlation"); XLALregBOOLUserStruct ( inclAutoCorr, 0, UVAR_OPTIONAL, "Include auto-correlation terms (an SFT with itself)"); XLALregREALUserStruct ( fStart, 0, UVAR_OPTIONAL, "Start frequency in Hz"); XLALregREALUserStruct ( fBand, 0, UVAR_OPTIONAL, "Frequency band to search over in Hz "); /* XLALregREALUserStruct ( fdotStart, 0, UVAR_OPTIONAL, "Start value of spindown in Hz/s"); */ /* XLALregREALUserStruct ( fdotBand, 0, UVAR_OPTIONAL, "Band for spindown values in Hz/s"); */ XLALregREALUserStruct ( alphaRad, 0, UVAR_OPTIONAL, "Right ascension for directed search (radians)"); XLALregREALUserStruct ( deltaRad, 0, UVAR_OPTIONAL, "Declination for directed search (radians)"); XLALregREALUserStruct ( refTime, 0, UVAR_OPTIONAL, "SSB reference time for pulsar-parameters [Default: midPoint]"); XLALregREALUserStruct ( orbitAsiniSec, 0, UVAR_OPTIONAL, "Start of search band for projected semimajor axis (seconds) [0 means not a binary]"); XLALregREALUserStruct ( orbitAsiniSecBand, 0, UVAR_OPTIONAL, "Width of search band for projected semimajor axis (seconds)"); XLALregREALUserStruct ( orbitPSec, 0, UVAR_OPTIONAL, "Binary orbital period (seconds) [0 means not a binary]"); XLALregREALUserStruct ( orbitPSecBand, 0, UVAR_OPTIONAL, "Band for binary orbital period (seconds) "); XLALregREALUserStruct ( orbitTimeAsc, 0, UVAR_OPTIONAL, "Start of orbital time-of-ascension band in GPS seconds"); XLALregREALUserStruct ( orbitTimeAscBand, 0, UVAR_OPTIONAL, "Width of orbital time-of-ascension band (seconds)"); XLALregSTRINGUserStruct( ephemEarth, 0, UVAR_OPTIONAL, "Earth ephemeris file to use"); XLALregSTRINGUserStruct( ephemSun, 0, UVAR_OPTIONAL, "Sun ephemeris file to use"); XLALregSTRINGUserStruct( sftLocation, 0, UVAR_REQUIRED, "Filename pattern for locating SFT data"); XLALregINTUserStruct ( rngMedBlock, 0, UVAR_OPTIONAL, "Running median block size for PSD estimation"); XLALregINTUserStruct ( numBins, 0, UVAR_OPTIONAL, "Number of frequency bins to include in calculation"); XLALregREALUserStruct ( mismatchF, 0, UVAR_OPTIONAL, "Desired mismatch for frequency spacing"); XLALregREALUserStruct ( mismatchA, 0, UVAR_OPTIONAL, "Desired mismatch for asini spacing"); XLALregREALUserStruct ( mismatchT, 0, UVAR_OPTIONAL, "Desired mismatch for periapse passage time spacing"); XLALregREALUserStruct ( mismatchP, 0, UVAR_OPTIONAL, "Desired mismatch for period spacing"); XLALregREALUserStruct ( spacingF, 0, UVAR_OPTIONAL, "Desired frequency spacing"); XLALregREALUserStruct ( spacingA, 0, UVAR_OPTIONAL, "Desired asini spacing"); XLALregREALUserStruct ( spacingT, 0, UVAR_OPTIONAL, "Desired periapse passage time spacing"); XLALregREALUserStruct ( spacingP, 0, UVAR_OPTIONAL, "Desired period spacing"); XLALregINTUserStruct ( numCand, 0, UVAR_OPTIONAL, "Number of candidates to keep in toplist"); XLALregSTRINGUserStruct( pairListInputFilename, 0, UVAR_OPTIONAL, "Name of file from which to read list of SFT pairs"); XLALregSTRINGUserStruct( pairListOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write list of SFT pairs"); XLALregSTRINGUserStruct( sftListOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write list of SFTs (for sanity checks)"); XLALregSTRINGUserStruct( sftListInputFilename, 0, UVAR_OPTIONAL, "Name of file to which to read in list of SFTs (for sanity checks)"); XLALregSTRINGUserStruct( gammaAveOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write aa+bb weights (for e.g., false alarm estimation)"); XLALregSTRINGUserStruct( gammaCircOutputFilename, 0, UVAR_OPTIONAL, "Name of file to which to write ab-ba weights (for e.g., systematic error)"); XLALregSTRINGUserStruct( toplistFilename, 0, UVAR_OPTIONAL, "Output filename containing candidates in toplist"); XLALregSTRINGUserStruct( logFilename, 0, UVAR_OPTIONAL, "Output a meta-data file for the search"); XLALregBOOLUserStruct ( version, 'V', UVAR_SPECIAL, "Output version(VCS) information"); if ( xlalErrno ) { XLALPrintError ("%s: user variable initialization failed with errno = %d.\n", __func__, xlalErrno ); XLAL_ERROR ( XLAL_EFUNC ); } return XLAL_SUCCESS; }
/** * Get the detector-time series for the given MultiLIGOTimeGPSVector. * NOTE: contrary to the deprecated XLALGetMultiDetectorStatesFromMultiSFTs() interface, this * function computes detector-states at the given timestamps shifted by tOffset * */ MultiDetectorStateSeries * XLALGetMultiDetectorStates( const MultiLIGOTimeGPSVector *multiTS, /**< [in] multi-IFO timestamps */ const MultiLALDetector *multiIFO, /**< [in] multi-IFO array holding detector info */ const EphemerisData *edat, /**< [in] ephemeris data */ REAL8 tOffset /**< [in] shift all timestamps by this amount */ ) { /* check input consistency */ if ( !multiIFO || !multiTS || !edat ) { XLALPrintError ("%s: invalid NULL input (multiIFO=%p, multiTS=%p or edat=%p)\n", __func__, multiIFO, multiTS, edat ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } UINT4 numDetectors; numDetectors = multiIFO->length; if ( numDetectors != multiTS->length ) { XLALPrintError ("%s: inconsistent number of IFOs in 'multiIFO' (%d) and 'multiTS' (%d)\n", __func__, multiIFO->length, multiTS->length ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* prepare return-structure */ MultiDetectorStateSeries *ret = NULL; if ( ( ret = LALCalloc ( 1, sizeof( *ret ) )) == NULL ) { XLALPrintError ("%s: LALCalloc ( 1, %zu ) failed\n", __func__, sizeof(*ret) ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } if ( ( ret->data = LALCalloc ( numDetectors, sizeof( *(ret->data) ) )) == NULL ) { XLALFree ( ret ); XLALPrintError ("%s: LALCalloc ( %d, %zu ) failed\n", __func__, numDetectors, sizeof(*(ret->data)) ); XLAL_ERROR_NULL ( XLAL_ENOMEM ); } ret->length = numDetectors; REAL8 t0=LAL_REAL4_MAX; REAL8 t1=0; REAL8 deltaT = multiTS->data[0]->deltaT; LIGOTimeGPS startTime = {0, 0}; /* loop over detectors */ UINT4 X; for ( X=0; X < numDetectors; X ++ ) { LIGOTimeGPSVector *tsX = multiTS->data[X]; const LALDetector *detX = &(multiIFO->sites[X]); if ( !tsX || !detX ) { XLALPrintError ("%s: invalid NULL data-vector tsX[%d] = %p, detX[%d] = %p\n", __func__, X, tsX, X, detX ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } if ( multiTS->data[X]->deltaT != deltaT ) { XLALPrintError ("%s: inconsistent time-base multi-timeseries deltaT[%d]=%f != deltaT[0] = %f\n", __func__, X, multiTS->data[X]->deltaT, deltaT ); XLAL_ERROR_NULL ( XLAL_EINVAL ); } /* fill in the detector-state series for this detector */ if ( ( ret->data[X] = XLALGetDetectorStates ( tsX, detX, edat, tOffset )) == NULL ) { XLALPrintError ("%s: XLALGetDetectorStates() failed.\n", __func__ ); XLAL_ERROR_NULL ( XLAL_EFUNC ); } /* keep track of earliest/latest timestamp in order to determine total Tspan */ UINT4 numTS = tsX->length; REAL8 t0_X = XLALGPSGetREAL8( &tsX->data[0] ); REAL8 t1_X = XLALGPSGetREAL8( &tsX->data[numTS-1] ); if ( t0_X < t0 ) { t0 = t0_X; startTime = tsX->data[0]; } if ( t1_X > t1 ) t1 = t1_X; } /* for X < numDetectors */ ret->Tspan = t1 - t0 + deltaT; /* total time spanned by all SFTs */ ret->startTime = startTime; /* earliest start-time of observation */ return ret; } /* XLALGetMultiDetectorStates() */
int test_XLALSincInterpolateSFT ( void ) { REAL8 f0 = 0; // heterodyning frequency REAL8 sigmaN = 0.001; REAL8 dt = 0.1; // sampling frequency = 10Hz LIGOTimeGPS epoch = { 100, 0 }; REAL8 tStart = XLALGPSGetREAL8 ( &epoch ); UINT4 numSamples = 1000; REAL8 Tspan = numSamples * dt; REAL8 df = 1.0 / Tspan; UINT4 numSamples0padded = 3 * numSamples; REAL8 Tspan0padded = numSamples0padded * dt; REAL8 df0padded = 1.0 / Tspan0padded; UINT4 numBins = NhalfPosDC ( numSamples ); UINT4 numBins0padded = NhalfPosDC ( numSamples0padded ); // original timeseries REAL4TimeSeries* ts; XLAL_CHECK ( (ts = XLALCreateREAL4TimeSeries ( "test TS_in", &epoch, f0, dt, &emptyLALUnit, numSamples )) != NULL, XLAL_EFUNC ); for ( UINT4 j = 0; j < numSamples; j ++ ) { ts->data->data[j] = crealf ( testSignal ( tStart + j * dt, sigmaN ) ); } // for j < numSamples // zero-padded to double length REAL4TimeSeries* ts0padded; XLAL_CHECK ( (ts0padded = XLALCreateREAL4TimeSeries ( "test TS_padded", &epoch, f0, dt, &emptyLALUnit, numSamples0padded )) != NULL, XLAL_EFUNC ); memcpy ( ts0padded->data->data, ts->data->data, numSamples * sizeof(ts0padded->data->data[0]) ); memset ( ts0padded->data->data + numSamples, 0, (numSamples0padded - numSamples) * sizeof(ts0padded->data->data[0]) ); // compute FFT on ts and ts0padded REAL4FFTPlan *plan, *plan0padded; XLAL_CHECK ( (plan = XLALCreateForwardREAL4FFTPlan ( numSamples, 0 )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (plan0padded = XLALCreateForwardREAL4FFTPlan ( numSamples0padded, 0 )) != NULL, XLAL_EFUNC ); COMPLEX8Vector *fft, *fft0padded; XLAL_CHECK ( (fft = XLALCreateCOMPLEX8Vector ( numBins )) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( (fft0padded = XLALCreateCOMPLEX8Vector ( numBins0padded )) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( XLALREAL4ForwardFFT ( fft, ts->data, plan ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALREAL4ForwardFFT ( fft0padded, ts0padded->data, plan0padded ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyREAL4TimeSeries ( ts ); XLALDestroyREAL4TimeSeries ( ts0padded ); XLALDestroyREAL4FFTPlan( plan ); XLALDestroyREAL4FFTPlan( plan0padded ); SFTtype XLAL_INIT_DECL(tmp); tmp.f0 = f0; tmp.deltaF = df; tmp.data = fft; REAL8 Band = 0.5/dt - f0; SFTtype *sft = NULL; XLAL_CHECK ( XLALExtractBandFromSFT ( &sft, &tmp, f0, Band ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyCOMPLEX8Vector ( fft ); tmp.f0 = f0; tmp.deltaF = df0padded; tmp.data = fft0padded; SFTtype *sft0padded = NULL; XLAL_CHECK ( XLALExtractBandFromSFT ( &sft0padded, &tmp, f0, Band ) == XLAL_SUCCESS, XLAL_EFUNC ); XLALDestroyCOMPLEX8Vector ( fft0padded ); // ---------- interpolate input SFT onto frequency bins of padded-ts FFT for comparison UINT4 Dterms = 16; REAL8 safetyBins = (Dterms + 1.0); // avoid truncated interpolation to minimize errors, set to 0 for seeing boundary-effects [they're not so bad...] REAL8 fMin = f0 + safetyBins * df; fMin = round(fMin / df0padded) * df0padded; UINT4 numBinsOut = numBins0padded - 3 * safetyBins; REAL8 BandOut = (numBinsOut-1) * df0padded; SFTtype *sftUpsampled = NULL; XLAL_CHECK ( XLALExtractBandFromSFT ( &sftUpsampled, sft0padded, fMin + 0.5*df0padded, BandOut - df0padded ) == XLAL_SUCCESS, XLAL_EFUNC ); SFTtype *sftInterpolated; XLAL_CHECK ( (sftInterpolated = XLALSincInterpolateSFT ( sft, fMin, df0padded, numBinsOut, Dterms )) != NULL, XLAL_EFUNC ); // ----- out debug info if ( lalDebugLevel & LALINFO ) { XLAL_CHECK ( write_SFTdata ( "SFT_in.dat", sft ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( write_SFTdata ( "SFT_in0padded.dat", sft0padded ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( write_SFTdata ( "SFT_upsampled.dat", sftUpsampled ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( write_SFTdata ( "SFT_interpolated.dat", sftInterpolated ) == XLAL_SUCCESS, XLAL_EFUNC ); } // if LALINFO // ---------- check accuracy of interpolation VectorComparison XLAL_INIT_DECL(tol); tol.relErr_L1 = 8e-2; tol.relErr_L2 = 8e-2; tol.angleV = 8e-2; tol.relErr_atMaxAbsx = 4e-3; tol.relErr_atMaxAbsy = 4e-3; XLALPrintInfo ("Comparing Dirichlet SFT interpolation with upsampled SFT:\n"); XLAL_CHECK ( XLALCompareSFTs ( sftUpsampled, sftInterpolated, &tol ) == XLAL_SUCCESS, XLAL_EFUNC ); // ---------- free memory XLALDestroySFT ( sft ); XLALDestroySFT ( sft0padded ); XLALDestroySFT ( sftUpsampled ); XLALDestroySFT ( sftInterpolated ); return XLAL_SUCCESS; } // test_XLALSincInterpolateSFT()
int XLALOutputDopplerMetric ( FILE *fp, const DopplerPhaseMetric *Pmetric, const DopplerFstatMetric *Fmetric, const ResultHistory_t *history ) { UINT4 i; REAL8 A, B, C, D; // ----- input sanity checks XLAL_CHECK ( fp != NULL, XLAL_EFAULT ); XLAL_CHECK ( Pmetric != NULL || Fmetric != NULL, XLAL_EFAULT ); const DopplerMetricParams *meta = (Pmetric != NULL) ? &(Pmetric->meta) : &(Fmetric->meta); XLAL_CHECK ( XLALSegListIsInitialized ( &(meta->segmentList) ), XLAL_EINVAL, "Got un-initialized segment list in 'metric->meta.segmentList'\n" ); UINT4 Nseg = meta->segmentList.length; XLAL_CHECK ( Nseg >= 1, XLAL_EDOM, "Got invalid zero-length segment list 'metric->meta.segmentList'\n" ); /* useful shortcuts */ const PulsarDopplerParams *doppler = &(meta->signalParams.Doppler); const PulsarAmplitudeParams *Amp = &(meta->signalParams.Amp); /* output history info */ if ( history ) { if ( history->app_name ) fprintf (fp, "%%%% app_name: %s\n", history->app_name ); if ( history->cmdline) fprintf (fp, "%%%% commandline: %s\n", history->cmdline ); if ( history->VCSInfoString ) fprintf (fp, "%%%% Code Version: %s\n", history->VCSInfoString ); } fprintf ( fp, "DopplerCoordinates = { " ); for ( i=0; i < meta->coordSys.dim; i ++ ) { if ( i > 0 ) fprintf ( fp, ", " ); fprintf ( fp, "\"%s\"", XLALDopplerCoordinateName(meta->coordSys.coordIDs[i])); } fprintf ( fp, "};\n"); { /* output projection info */ const char *pname; if ( meta->projectCoord < 0 ) pname = "None"; else pname = XLALDopplerCoordinateName ( meta->coordSys.coordIDs[meta->projectCoord] ); fprintf ( fp, "%%%% Projection onto subspace orthogonal to coordinate: '%s'\n", pname); } fprintf ( fp, "%%%% DetectorMotionType = '%s'\n", XLALDetectorMotionName(meta->detMotionType) ); fprintf ( fp, "h0 = %g;\ncosi = %g;\npsi = %g;\nphi0 = %g;\n", Amp->h0, Amp->cosi, Amp->psi, Amp->phi0 ); fprintf ( fp, "%%%% DopplerPoint = {\n"); fprintf ( fp, "refTime = %.1f;\n", XLALGPSGetREAL8 ( &doppler->refTime ) ); fprintf ( fp, "Alpha = %f;\nDelta = %f;\n", doppler->Alpha, doppler->Delta ); fprintf ( fp, "fkdot = [%f, %g, %g, %g ];\n", doppler->fkdot[0], doppler->fkdot[1], doppler->fkdot[2], doppler->fkdot[3] ); if ( doppler->asini > 0 ) { fprintf ( fp, "%%%% orbit = { \n"); fprintf ( fp, "%%%% tp = {%d, %d}\n", doppler->tp.gpsSeconds, doppler->tp.gpsNanoSeconds ); fprintf ( fp, "%%%% argp = %g\n", doppler->argp ); fprintf ( fp, "%%%% asini = %g\n", doppler->asini ); fprintf ( fp, "%%%% ecc = %g\n", doppler->ecc ); fprintf ( fp, "%%%% period = %g\n", doppler->period ); fprintf ( fp, "%%%% }\n"); } /* if doppler->orbit */ fprintf ( fp, "%%%% }\n"); LIGOTimeGPS *tStart = &(meta->segmentList.segs[0].start); LIGOTimeGPS *tEnd = &(meta->segmentList.segs[Nseg-1].end); REAL8 Tspan = XLALGPSDiff ( tEnd, tStart ); fprintf ( fp, "startTime = %.1f;\n", XLALGPSGetREAL8 ( tStart ) ); fprintf ( fp, "Tspan = %.1f;\n", Tspan ); fprintf ( fp, "Nseg = %d;\n", Nseg ); fprintf ( fp, "detectors = {"); for ( i=0; i < meta->multiIFO.length; i ++ ) { if ( i > 0 ) fprintf ( fp, ", "); fprintf ( fp, "\"%s\"", meta->multiIFO.sites[i].frDetector.name ); } fprintf ( fp, "};\n"); fprintf ( fp, "detectorWeights = ["); for ( i=0; i < meta->multiNoiseFloor.length; i ++ ) { if ( i > 0 ) fprintf ( fp, ", "); fprintf ( fp, "%f", meta->multiNoiseFloor.sqrtSn[i] ); } fprintf ( fp, "];\n"); /* ----- output phase metric ---------- */ if ( Pmetric != NULL ) { fprintf ( fp, "\ng_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Pmetric->g_ij ); fprintf ( fp, "maxrelerr_gPh = %.2e;\n", Pmetric->maxrelerr ); gsl_matrix *gN_ij = NULL; if ( XLALNaturalizeMetric ( &gN_ij, NULL, Pmetric->g_ij, meta ) != XLAL_SUCCESS ) { XLALPrintError ("%s: something failed Naturalizing phase metric g_ij!\n", __func__ ); XLAL_ERROR ( XLAL_EFUNC ); } fprintf ( fp, "\ngN_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, gN_ij ); gsl_matrix_free ( gN_ij ); gsl_matrix *gDN_ij = NULL; if ( XLALDiagNormalizeMetric ( &gDN_ij, NULL, Pmetric->g_ij ) != XLAL_SUCCESS ) { XLALPrintError ("%s: something failed NormDiagonalizing phase metric g_ij!\n", __func__ ); XLAL_ERROR ( XLAL_EFUNC ); } fprintf ( fp, "\ngDN_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, gDN_ij ); gsl_matrix_free ( gDN_ij ); } /* ----- output F-metric (and related matrices ---------- */ if ( Fmetric != NULL ) { fprintf ( fp, "\ngF_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->gF_ij ); fprintf ( fp, "\ngFav_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->gFav_ij ); fprintf ( fp, "\nm1_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m1_ij ); fprintf ( fp, "\nm2_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m2_ij ); fprintf ( fp, "\nm3_ij = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->m3_ij ); fprintf ( fp, "maxrelerr_gF = %.2e;\n", Fmetric->maxrelerr ); } /* ----- output Fisher matrix ---------- */ if ( Fmetric != NULL && Fmetric->Fisher_ab != NULL ) { A = gsl_matrix_get ( Fmetric->Fisher_ab, 0, 0 ); B = gsl_matrix_get ( Fmetric->Fisher_ab, 1, 1 ); C = gsl_matrix_get ( Fmetric->Fisher_ab, 0, 1 ); D = A * B - C * C; fprintf ( fp, "\nA = %.16g;\nB = %.16g;\nC = %.16g;\nD = %.16g;\n", A, B, C, D ); fprintf ( fp, "\nrho2 = %.16g;\n", Fmetric->rho2 ); fprintf (fp, "\nFisher_ab = \\\n" ); XLALfprintfGSLmatrix ( fp, METRIC_FORMAT, Fmetric->Fisher_ab ); } // ---------- output segment list at the end, as this can potentially become quite long and distracting char *seglist_octave; XLAL_CHECK ( (seglist_octave = XLALSegList2String ( &(meta->segmentList) )) != NULL, XLAL_EFUNC, "XLALSegList2String() with xlalErrno = %d\n", xlalErrno ); fprintf ( fp, "\n\nsegmentList = %s;\n", seglist_octave ); XLALFree ( seglist_octave ); return XLAL_SUCCESS; } /* XLALOutputDopplerMetric() */