def damped_chirp_tmplt(det_data, int_params, ext_params): """ Build a template for the detector in det_data from the intrinsic and extrinsic parameteres in int_params and ext_params """ # # Compute polarisations for damped chirp # # _, hp = damped_chirp(int_params.tmplt_len, # int_params.Amp, int_params.f0, int_params.tau, int_params.df) # # _, hc = damped_chirp(int_params.tmplt_len, # int_params.Amp, int_params.f0, int_params.tau, int_params.df, # phi0=90.0) # Get the epoch for the start of the time series epoch = ext_params.geocent_peak_time # - \ #np.argmax(hp)*det_data.td_response.delta_t # XXX: why don't we need to subtract this bit...? Q = 2.0 * np.pi * int_params.tau * int_params.f0 hp, hc = lalsim.SimBurstChirplet(Q, int_params.f0, int_params.df, int_params.Amp, 0, 0, 1.0 / 16384) hp.data.data[0:hp.data.length / 2] = 0.0 hc.data.data[0:hp.data.length / 2] = 0.0 hplus = lal.CreateREAL8TimeSeries('hplus', epoch, 0, det_data.td_noise.delta_t, lal.StrainUnit, hp.data.length) hplus.data.data = np.copy(hp.data.data) del hp hcross = lal.CreateREAL8TimeSeries('hcross', epoch, 0, det_data.td_noise.delta_t, lal.StrainUnit, hc.data.length) hcross.data.data = np.copy(hc.data.data) del hc # try: # time_delay = lal.TimeDelayFromEarthCenter(det_data.det_site.location, # ext_params.ra, ext_params.dec, ext_params.geocent_peak_time) # except RuntimeError: # time_delay = lal.TimeDelayFromEarthCenter(det_data.det_site.location, # ext_params.ra, ext_params.dec, -1e4) # --- Put the polarisations into LAL TimeSeries # hplus = lal.CreateREAL8TimeSeries('hplus', epoch, 0, # det_data.td_noise.delta_t, lal.StrainUnit, len(hp)) # hplus.data.data=np.copy(hp) # del hp # # hcross = lal.CreateREAL8TimeSeries('hcross', epoch, 0, # det_data.td_noise.delta_t, lal.StrainUnit, len(hc)) # hcross.data.data=np.copy(hc) # del hc # # Project polarisations down to detector # tmplt = lalsim.SimDetectorStrainREAL8TimeSeries(hplus, hcross, ext_params.ra, ext_params.dec, ext_params.polarization, det_data.det_site) del hplus, hcross # Scale for distance (waveforms extracted at 20 Mpc) tmplt.data.data *= 20.0 / ext_params.distance # # Finally make this the same size as the data (useful for fitting) # #lal.ResizeREAL8TimeSeries(tmplt, 0, len(det_data.td_response.data)) no_noise = lal.CreateREAL8TimeSeries( 'blah', det_data.td_noise.start_time, 0, det_data.td_noise.delta_t, lal.StrainUnit, int(det_data.td_noise.duration / det_data.td_noise.delta_t)) no_noise.data.data = np.zeros( int(det_data.td_noise.duration / det_data.td_noise.delta_t)) tmplt = lal.AddREAL8TimeSeries(no_noise, tmplt) return pycbc.types.timeseries.TimeSeries(\ initial_array=np.copy(tmplt.data.data), delta_t=tmplt.deltaT, epoch=tmplt.epoch)
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 add_signal_to_noise(self): """ Sum the noise and the signal to get the 'measured' strain in the detector """ # noise noise = lal.CreateREAL8TimeSeries( 'blah', self.epoch, 0, self.td_noise.delta_t, lal.StrainUnit, int(self.td_noise.duration / self.td_noise.delta_t)) noise.data.data = self.td_noise.data # signal signal = lal.CreateREAL8TimeSeries( 'blah', self.ext_params.geocent_peak_time, 0, self.td_signal.delta_t, lal.StrainUnit, int(self.td_signal.duration / self.td_signal.delta_t)) signal.data.data = self.td_signal.data win = lal.CreateTukeyREAL8Window(len(signal.data.data), 0.1) win.data.data[len(signal.data.data):] = 1.0 #signal.data.data *= win.data.data # --- Scale to a target snr print '---' if self.target_snr is not None: tmp_sig = pycbc.types.TimeSeries(signal.data.data, delta_t=self.td_signal.delta_t) current_snr = pycbc.filter.sigma(tmp_sig, psd=self.psd, low_frequency_cutoff=self.f_low, high_frequency_cutoff=0.5 / self.delta_t) signal.data.data *= self.target_snr / current_snr # ---- # sum noise_plus_signal = lal.AddREAL8TimeSeries(noise, signal) self.td_response = \ pycbc.types.timeseries.TimeSeries(\ initial_array=np.copy(noise_plus_signal.data.data), delta_t=noise_plus_signal.deltaT, epoch=noise_plus_signal.epoch) # Finally, zero-pad the signal vector to have the same length as the actual data # vector no_noise = lal.CreateREAL8TimeSeries( 'blah', self.epoch, 0, self.td_noise.delta_t, lal.StrainUnit, int(self.td_noise.duration / self.td_noise.delta_t)) no_noise.data.data = np.zeros(\ int(self.td_noise.duration / self.td_noise.delta_t)) signal = lal.AddREAL8TimeSeries(no_noise, signal) self.td_signal = \ pycbc.types.timeseries.TimeSeries(initial_array=np.copy(signal.data.data), delta_t=signal.deltaT, epoch=noise_plus_signal.epoch) del noise, signal, noise_plus_signal