def taper_start(input_data): """ Window out the inspiral (everything prior to the biggest peak) """ timeseries = lal.CreateREAL8TimeSeries('blah', 0.0, 0, 1.0/16384, lal.StrainUnit, int(len(input_data))) timeseries.data.data = np.copy(input_data) lalsim.SimInspiralREAL8WaveTaper(timeseries.data, lalsim.SIM_INSPIRAL_TAPER_START) lalsim.SimInspiralREAL8WaveTaper(timeseries.data, lalsim.SIM_INSPIRAL_TAPER_START) return timeseries.data.data
def _compute_waveform(self, df, f_final): """ Since EOBNRv2 is a time domain waveform, we have to generate it, then FFT to frequency domain. """ # need to compute dt from df, duration sample_rate = 2**np.ceil(np.log2(2 * f_final)) dt = 1. / sample_rate # get hplus hplus, hcross = lalsim.SimIMREOBNRv2DominantMode( 0., dt, self.m1 * MSUN_SI, self.m2 * MSUN_SI, self.bank.flow, 1e6 * PC_SI, 0.) # zero-pad up to 1/df N = int(sample_rate / df) hplus = lal.ResizeREAL8TimeSeries(hplus, 0, N) # taper lalsim.SimInspiralREAL8WaveTaper(hplus.data, lalsim.SIM_INSPIRAL_TAPER_START) # create vector to hold output and plan htilde = lal.CreateCOMPLEX16FrequencySeries("h(f)", hplus.epoch, hplus.f0, df, lal.HertzUnit, int(N / 2 + 1)) fftplan = lal.CreateForwardREAL8FFTPlan(N, 0) # do the fft lal.REAL8TimeFreqFFT(htilde, hplus, fftplan) return htilde
def window_inspiral(input_data, delay=0.0): """ Window out the inspiral (everything prior to the biggest peak) """ timeseries = lal.CreateREAL8TimeSeries('blah', 0.0, 0, 1.0/16384, lal.StrainUnit, int(len(input_data))) timeseries.data.data = input_data idx = np.argmax(input_data) + np.ceil(delay/(1.0/16384)) timeseries.data.data[0:idx] = 0.0 lalsim.SimInspiralREAL8WaveTaper(timeseries.data, lalsim.SIM_INSPIRAL_TAPER_START) lalsim.SimInspiralREAL8WaveTaper(timeseries.data, lalsim.SIM_INSPIRAL_TAPER_START) return timeseries.data.data
def _compute_waveform(self, df, f_final): # Time domain, so compute then FFT # need to compute dt from df, duration sample_rate = 2**np.ceil(np.log2(2 * f_final)) dt = 1. / sample_rate # Generate waveform in time domain hplus, hcross = lalsim.SimInspiralSpinTaylorT5( 0, # GW phase at reference freq (rad) dt, # sampling interval (s) self.m1 * lal.MSUN_SI, # mass of companion 1 (kg) self.m2 * lal.MSUN_SI, # mass of companion 2 (kg) self.bank.flow, # start GW frequency (Hz) 1e6 * PC_SI, # distance of source (m) self.s1x, # initial value of S1x self.s1y, # initial value of S1y self.s1z, # initial value of S1z self.s2x, # initial value of S2x self.s2y, # initial value of S2y self.s2z, # initial value of S2z self. inclination, # inclination angle - careful with definition (line of sight to total vs orbital angular momentum) 7, # twice PN phase order 0) # project onto detector hoft = project_hplus_hcross(hplus, hcross, self.theta, self.phi, self.psi) # zero-pad up to 1/df N = int(sample_rate / df) hoft = lal.ResizeREAL8TimeSeries(hoft, 0, N) # taper lalsim.SimInspiralREAL8WaveTaper(hoft.data, lalsim.SIM_INSPIRAL_TAPER_STARTEND) # create vector to hold output and plan htilde = lal.CreateCOMPLEX16FrequencySeries("h(f)", hoft.epoch, hoft.f0, df, lal.HertzUnit, int(N / 2 + 1)) fftplan = lal.CreateForwardREAL8FFTPlan(N, 0) # do the fft lal.REAL8TimeFreqFFT(htilde, hoft, fftplan) return htilde
def apply_taper(TimeSeries, newlen=16384): """ Smoothly taper the start of the data in TimeSeries using LAL tapering routines Also zero pads """ # Create and populate lal time series tmp = lal.CreateREAL8TimeSeries('tmp', lal.LIGOTimeGPS(), 0.0, TimeSeries.delta_t, lal.StrainUnit, newlen) #TimeSeries.delta_t, lal.StrainUnit, len(TimeSeries)) tmp.data.data = np.zeros(newlen) tmp.data.data[0:len(TimeSeries)] = TimeSeries.data # Taper lalsim.SimInspiralREAL8WaveTaper(tmp.data, lalsim.SIM_INSPIRAL_TAPER_START) return pycbc.types.TimeSeries(tmp.data.data, delta_t=TimeSeries.delta_t)
def real_hoft(self, Fp=None, Fc=None): """ Returns the real-valued h(t) that would be produced in a single instrument. Translates epoch as needed. Based on 'hoft' in lalsimutils.py """ # Create complex timessereis htC = self.complex_hoft( force_T=1. / self.P.deltaF, deltaT=self.P.deltaT ) # note P.tref is NOT used in the low-level code TDlen = htC.data.length if rosDebug: print("Size sanity check ", TDlen, 1 / (self.P.deltaF * self.P.deltaT)) print(" Raw complex magnitude , ", np.max(htC.data.data)) # Create working buffers to extract data from it -- wasteful. hp = lal.CreateREAL8TimeSeries("h(t)", htC.epoch, 0., self.P.deltaT, lalsimutils.lsu_DimensionlessUnit, TDlen) hc = lal.CreateREAL8TimeSeries("h(t)", htC.epoch, 0., self.P.deltaT, lalsimutils.lsu_DimensionlessUnit, TDlen) hT = lal.CreateREAL8TimeSeries("h(t)", htC.epoch, 0., self.P.deltaT, lalsimutils.lsu_DimensionlessUnit, TDlen) # Copy data components over hp.data.data = np.real(htC.data.data) hc.data.data = np.imag(htC.data.data) # transform as in lalsimutils.hoft if Fp != None and Fc != None: hp.data.data *= Fp hc.data.data *= Fc hp = lal.AddREAL8TimeSeries(hp, hc) hoft = hp elif self.P.radec == False: fp = lalsimutils.Fplus(self.P.theta, self.P.phi, self.P.psi) fc = lalsimutils.Fcross(self.P.theta, self.P.phi, self.P.psi) hp.data.data *= fp hc.data.data *= fc hp.data.data = lal.AddREAL8TimeSeries(hp, hc) hoft = hp else: # Note epoch must be applied FIRST, to make sure the correct event time is being used to construct the modulation functions hp.epoch = hp.epoch + self.P.tref hc.epoch = hc.epoch + self.P.tref if rosDebug: print(" Real h(t) before detector weighting, ", np.max(hp.data.data), np.max(hc.data.data)) hoft = lalsim.SimDetectorStrainREAL8TimeSeries( hp, hc, # beware, this MAY alter the series length?? self.P.phi, self.P.theta, self.P.psi, lalsim.DetectorPrefixToLALDetector(str(self.P.detector))) hoft = lal.CutREAL8TimeSeries( hoft, 0, hp.data.length) # force same length as before?? if rosDebug: print("Size before and after detector weighting ", hp.data.length, hoft.data.length) if rosDebug: print(" Real h_{IFO}(t) generated, pre-taper : max strain =", np.max(hoft.data.data)) if self.P.taper != lalsimutils.lsu_TAPER_NONE: # Taper if requested lalsim.SimInspiralREAL8WaveTaper(hoft.data, self.P.taper) if self.P.deltaF is not None: TDlen = int(1. / self.P.deltaF * 1. / self.P.deltaT) print("Size sanity check 2 ", int(1. / self.P.deltaF * 1. / self.P.deltaT), hoft.data.length) assert TDlen >= hoft.data.length npts = hoft.data.length hoft = lal.ResizeREAL8TimeSeries(hoft, 0, TDlen) # Zero out the last few data elements -- NOT always reliable for all architectures; SHOULD NOT BE NECESSARY hoft.data.data[npts:TDlen] = 0 if rosDebug: print(" Real h_{IFO}(t) generated : max strain =", np.max(hoft.data.data)) return hoft
def make_signal(self, waveform): """ Generate the signal seeen in this detector """ #print >> sys.stdout, "generating signal..." # --- Set up timing # index of the absolute maximum peak #idx = np.concatenate(np.argwhere(abs(waveform.hplus.data.data)>0))[0] idx = np.argmax(abs(waveform.hplus.data)) # Epoch = GPS start of time series. Want the peak time of the waveform # to be aligned to the geocenter, so set the epoch to the geocentric # peak time minus the time to the waveform peak. In other words: # (waveform epoch) = (geocentric peak time) - (# of seconds to peak) hplus_epoch = self.ext_params.geocent_peak_time - idx * waveform.hplus.delta_t hcross_epoch = self.ext_params.geocent_peak_time - idx * waveform.hcross.delta_t # XXX: create regular lal timeseries objects for this bit (may replace # with pycbc injection routines later) hplus = lal.CreateREAL8TimeSeries( 'hplus', hplus_epoch, 0, waveform.hplus.delta_t, lal.StrainUnit, int(waveform.hplus.duration / waveform.hplus.delta_t)) hplus.data.data = np.array(waveform.hplus.data) hcross = lal.CreateREAL8TimeSeries( 'hcross', hcross_epoch, 0, waveform.hcross.delta_t, lal.StrainUnit, int(waveform.hcross.duration / waveform.hcross.delta_t)) hcross.data.data = np.array(waveform.hcross.data) if self.taper is True: print >> sys.stderr, "Warning: tapering out inspiral (not a realistic strategy)" delay = 0.0e-3 idx = np.argmax(hplus.data.data) + \ np.ceil(delay/self.delta_t) hplus.data.data[0:idx] = 0.0 hcross.data.data[0:idx] = 0.0 lalsim.SimInspiralREAL8WaveTaper(hplus.data, lalsim.SIM_INSPIRAL_TAPER_START) lalsim.SimInspiralREAL8WaveTaper(hcross.data, lalsim.SIM_INSPIRAL_TAPER_START) # Scale for distance (waveforms extracted at 20 Mpc) hplus.data.data *= 20.0 / self.ext_params.distance hcross.data.data *= 20.0 / self.ext_params.distance tmp = lalsim.SimDetectorStrainREAL8TimeSeries( hplus, hcross, self.ext_params.ra, self.ext_params.dec, self.ext_params.polarization, self.det_site) # Pad the end so we have the same length signal and noise (useful for # snr and psds) sigdata = np.zeros(len(self.td_noise)) sigdata[:len(tmp.data.data)] = np.copy(tmp.data.data) # Project waveform onto these extrinsic parameters self.td_signal = \ pycbc.types.timeseries.TimeSeries(initial_array=sigdata, delta_t=tmp.deltaT, epoch=tmp.epoch) del tmp
# Construct expansion parameters Hlm = construct_Hlm(Ixx, Ixy, Ixz, Iyy, Iyz, Izz, l=2, m=m) # # Resample to uniform spacing at 16384 kHz # Hlm_real = interpolate(times, Hlm.real, target_times) Hlm_imag = interpolate(times, Hlm.imag, target_times) # Populate time series hplus_sim.data.data = Hlm_real hcross_sim.data.data = -1 * Hlm_imag # --- Apply Tapering Window (important for merger sims) lalsim.SimInspiralREAL8WaveTaper(hplus_sim.data, lalsim.SIM_INSPIRAL_TAPER_START) lalsim.SimInspiralREAL8WaveTaper(hcross_sim.data, lalsim.SIM_INSPIRAL_TAPER_START) # --- Write data to file f = open(filename, 'w') for j in range(hplus_sim.data.length): f.write( "%.16f %.16f %.16f\n" % (target_times[j], hplus_sim.data.data[j], hcross_sim.data.data[j])) f.close() # --- append to ini file inifile.writelines("2,{0} = {1}\n".format(m, filename)) inifile.close()
def _compute_waveform(self, df, f_final): # Time domain, so compute then FFT # need to compute dt from df, duration sample_rate = 2**np.ceil(np.log2(2 * f_final)) dt = 1. / sample_rate # Generate waveform in time domain hplus, hcross = lalsim.SimInspiralSpinTaylorT4( 0, # GW phase at reference freq (rad) 1, # tail gauge term (default = 1) dt, # sampling interval (s) self.m1 * lal.MSUN_SI, # mass of companion 1 (kg) self.m2 * lal.MSUN_SI, # mass of companion 2 (kg) self.bank.flow, # start GW frequency (Hz) self.bank. flow, # reference GW frequency at which phase is set (Hz) 1e6 * PC_SI, # distance of source (m) self.s1x, # initial value of S1x self.s1y, # initial value of S1y self.s1z, # initial value of S1z self.s2x, # initial value of S2x self.s2y, # initial value of S2y self.s2z, # initial value of S2z np.sin(self.inclination), # initial value of LNhatx 0, # initial value of LNhaty np.cos(self.inclination), # initial value of LNhatz np.cos(self.inclination), # initial value of E1x 0, # initial value of E1y -np.sin(self.inclination), # initial value of E1z 0, # tidal deformability of mass 1 0, # tidal deformability of mass 2 1, # phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) 1, # phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) 7, # twice PN spin order 0, # twice PN tidal order 7, # twice PN phase order 0 # twice PN amplitude order ) # project onto detector hoft = project_hplus_hcross(hplus, hcross, self.theta, self.phi, self.psi) # zero-pad up to 1/df N = ceil_pow_2(int(sample_rate / df)) hoft = lal.ResizeREAL8TimeSeries(hoft, 0, N) # taper lalsim.SimInspiralREAL8WaveTaper(hoft.data, lalsim.SIM_INSPIRAL_TAPER_STARTEND) # create vector to hold output and plan htilde = lal.CreateCOMPLEX16FrequencySeries("h(f)", hoft.epoch, hoft.f0, df, lal.HertzUnit, int(N / 2 + 1)) fftplan = lal.CreateForwardREAL8FFTPlan(N, 0) # do the fft lal.REAL8TimeFreqFFT(htilde, hoft, fftplan) return htilde