/** * Adds a double to a GPS time. Computes epoch + dt and places the result * in epoch. Returns epoch on success, NULL on error. */ LIGOTimeGPS * XLALGPSAdd( LIGOTimeGPS *epoch, REAL8 dt ) { LIGOTimeGPS dt_gps; if(!XLALGPSSetREAL8(&dt_gps, dt)) XLAL_ERROR_NULL(XLAL_EFUNC); return XLALGPSAddGPS(epoch, &dt_gps); }
/** * Multiply a GPS time by a number. Computes gps * x and places the result * in gps. Returns gps on success, NULL on failure. */ LIGOTimeGPS *XLALGPSMultiply( LIGOTimeGPS *gps, REAL8 x ) { LIGOTimeGPS workspace = *gps; double slo, shi; double xlo, xhi; double addendlo[4], addendhi[4]; if(isnan(x) || isinf(x)) { XLALPrintError("%s(): invalid multiplicand %g", __func__, x); XLAL_ERROR_NULL(XLAL_EFPINVAL); } /* ensure the seconds and nanoseconds components have the same sign so * that the addend fragments we compute below all have the same sign */ if(workspace.gpsSeconds < 0 && workspace.gpsNanoSeconds > 0) { workspace.gpsSeconds += 1; workspace.gpsNanoSeconds -= 1000000000; } else if(workspace.gpsSeconds > 0 && workspace.gpsNanoSeconds < 0) { workspace.gpsSeconds -= 1; workspace.gpsNanoSeconds += 1000000000; } /* split seconds and multiplicand x into leading-order and low-order * components */ slo = workspace.gpsSeconds % (1<<16); shi = workspace.gpsSeconds - slo; split_double(x, &xhi, &xlo); /* the count of seconds and the multiplicand x have each been split into * two parts, a high part and a low part. from these, there are 4 terms * in their product, and each term has sufficiently low dynamic range * that it can be computed using double precision floating point * arithmetic. we compute the 4 terms, split each into an integer and * fractional part on its own, then sum the fractional parts and integer * parts separately, adding the product of the nanoseconds and x into the * fractional parts when summing them. because the storage locations for * those sums have relatively low dynamic range no care need be taken in * computing the sums. */ addendlo[0] = modf(slo * xlo, &addendhi[0]); addendlo[1] = modf(shi * xlo, &addendhi[1]); addendlo[2] = modf(slo * xhi, &addendhi[2]); addendlo[3] = modf(shi * xhi, &addendhi[3]); /* initialize result with the sum of components that contribute to the * fractional part */ if(!XLALGPSSetREAL8(gps, addendlo[0] + addendlo[1] + addendlo[2] + addendlo[3] + workspace.gpsNanoSeconds * x / XLAL_BILLION_REAL8)) XLAL_ERROR_NULL(XLAL_EFUNC); /* now add the components that contribute only to the integer seconds * part */ if(!XLALGPSSetREAL8(&workspace, addendhi[0] + addendhi[1] + addendhi[2] + addendhi[3])) XLAL_ERROR_NULL(XLAL_EFUNC); return XLALGPSAddGPS(gps, &workspace); }
static PyObject *__add__(PyObject *self, PyObject *other) { LIGOTimeGPS self_gps; LIGOTimeGPS other_gps; if(!pyobject_to_ligotimegps(self, &self_gps)) return NULL; if(!pyobject_to_ligotimegps(other, &other_gps)) return NULL; XLALGPSAddGPS(&self_gps, &other_gps); return pylal_LIGOTimeGPS_new(self_gps); }
/** * Generate the + and x time series for a single sim_burst table row. * Note: only the row pointed to by sim_burst is processed, the linked * list is not iterated over. The hplus and hcross time series objects * will be allocated by this function. The time-at-geocentre is applied, * but the time shift offset must be applied separately. delta_t is the * sample interval for the time series. The return value is 0 in success, * non-0 on failure. */ int XLALGenerateSimBurst( REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const SimBurst *sim_burst, double delta_t ) { if(!strcmp(sim_burst->waveform, "BTLWNB")) { /* E_{GW}/r^{2} is in M_{sun} / pc^{2}, so we multiply by * (M_{sun} c^2) to convert to energy/pc^{2}, and divide by * (distance/pc)^{2} to convert to energy/distance^{2}, * which is then multiplied by (4 G / c^3) to convert to a * value of \int \dot{h}^{2} \diff t. From the values of * the LAL constants, the total factor multiplying * egw_over_rsquared is 1.8597e-21. */ double int_hdot_squared_dt = sim_burst->egw_over_rsquared * LAL_GMSUN_SI * 4 / LAL_C_SI / LAL_PC_SI / LAL_PC_SI; /* the waveform number is interpreted as the seed for GSL's * Mersenne twister random number generator */ gsl_rng *rng = gsl_rng_alloc(gsl_rng_mt19937); if(!rng) { XLALPrintError("%s(): failure creating random number generator\n", __func__); XLAL_ERROR(XLAL_ENOMEM); } gsl_rng_set(rng, sim_burst->waveform_number); XLALPrintInfo("%s(): BTLWNB @ %9d.%09u s (GPS): f = %.16g Hz, df = %.16g Hz, dt = %.16g s, hdot^2 = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->frequency, sim_burst->bandwidth, sim_burst->duration, int_hdot_squared_dt); if(XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(hplus, hcross, sim_burst->duration, sim_burst->frequency, sim_burst->bandwidth, sim_burst->pol_ellipse_e, int_hdot_squared_dt, delta_t, rng)) { gsl_rng_free(rng); XLAL_ERROR(XLAL_EFUNC); } gsl_rng_free(rng); } else if(!strcmp(sim_burst->waveform, "StringCusp")) { XLALPrintInfo("%s(): string cusp @ %9d.%09u s (GPS): A = %.16g, fhigh = %.16g Hz\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->amplitude, sim_burst->frequency); if(XLALGenerateStringCusp(hplus, hcross, sim_burst->amplitude, sim_burst->frequency, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else if(!strcmp(sim_burst->waveform, "SineGaussian")) { XLALPrintInfo("%s(): sine-Gaussian @ %9d.%09u s (GPS): f = %.16g Hz, Q = %.16g, hrss = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->frequency, sim_burst->q, sim_burst->hrss); if(XLALSimBurstSineGaussian(hplus, hcross, sim_burst->q, sim_burst->frequency, sim_burst->hrss, sim_burst->pol_ellipse_e, sim_burst->pol_ellipse_angle, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else if(!strcmp(sim_burst->waveform, "Gaussian")) { XLALPrintInfo("%s(): Gaussian @ %9d.%09u s (GPS): duration = %.16g, hrss = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->duration, sim_burst->hrss); if(XLALSimBurstGaussian(hplus, hcross, sim_burst->duration, sim_burst->hrss, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else if(!strcmp(sim_burst->waveform, "Impulse")) { XLALPrintInfo("%s(): impulse @ %9d.%09u s (GPS): hpeak = %.16g\n", __func__, sim_burst->time_geocent_gps.gpsSeconds, sim_burst->time_geocent_gps.gpsNanoSeconds, sim_burst->amplitude); if(XLALGenerateImpulseBurst(hplus, hcross, sim_burst->amplitude, delta_t)) XLAL_ERROR(XLAL_EFUNC); } else { /* unrecognized waveform */ XLALPrintError("%s(): error: unrecognized waveform\n", __func__); XLAL_ERROR(XLAL_EINVAL); } /* add the time of the injection at the geocentre to the start * times of the h+ and hx time series. after this, their epochs * mark the start of those time series at the geocentre. */ if(!XLALGPSAddGPS(&(*hcross)->epoch, &sim_burst->time_geocent_gps) || !XLALGPSAddGPS(&(*hplus)->epoch, &sim_burst->time_geocent_gps)) { XLALPrintError("%s(): bad geocentre time or waveform too long\n", __func__); XLALDestroyREAL8TimeSeries(*hcross); XLALDestroyREAL8TimeSeries(*hplus); *hplus = *hcross = NULL; XLAL_ERROR(XLAL_EFUNC); } /* done */ return 0; }