def lal(self): """ Returns a LAL Object that contains this data """ lal_data = None if type(self._data) is not _numpy.ndarray: raise TypeError("Cannot return lal type from the GPU") elif self._data.dtype == _numpy.float32: lal_data = _lal.CreateREAL4TimeSeries("", self._epoch, 0, self.delta_t, _lal.lalSecondUnit, len(self)) elif self._data.dtype == _numpy.float64: lal_data = _lal.CreateREAL8TimeSeries("", self._epoch, 0, self.delta_t, _lal.lalSecondUnit, len(self)) elif self._data.dtype == _numpy.complex64: lal_data = _lal.CreateCOMPLEX8TimeSeries("", self._epoch, 0, self.delta_t, _lal.lalSecondUnit, len(self)) elif self._data.dtype == _numpy.complex128: lal_data = _lal.CreateCOMPLEX16TimeSeries("", self._epoch, 0, self.delta_t, _lal.lalSecondUnit, len(self)) lal_data.data.data[:] = self._data return lal_data
def lal(self): """Produces a LAL time series object equivalent to self. Returns ------- lal_data : {lal.*TimeSeries} LAL time series object containing the same data as self. The actual type depends on the sample's dtype. If the epoch of self is 'None', the epoch of the returned LAL object will be LIGOTimeGPS(0,0); otherwise, the same as that of self. Raises ------ TypeError If time series is stored in GPU memory. """ lal_data = None ep = self._epoch if self._data.dtype == _numpy.float32: lal_data = _lal.CreateREAL4TimeSeries("",ep,0,self.delta_t,_lal.SecondUnit,len(self)) elif self._data.dtype == _numpy.float64: lal_data = _lal.CreateREAL8TimeSeries("",ep,0,self.delta_t,_lal.SecondUnit,len(self)) elif self._data.dtype == _numpy.complex64: lal_data = _lal.CreateCOMPLEX8TimeSeries("",ep,0,self.delta_t,_lal.SecondUnit,len(self)) elif self._data.dtype == _numpy.complex128: lal_data = _lal.CreateCOMPLEX16TimeSeries("",ep,0,self.delta_t,_lal.SecondUnit,len(self)) lal_data.data.data[:] = self.numpy() return lal_data
def matched_filter_real(template, psd): fdfilter = matched_filter_real_fd(template, psd) tdfilter = lal.CreateREAL8TimeSeries(None, lal.LIGOTimeGPS(0), 0, 0, lal.DimensionlessUnit, 2 * (len(fdfilter.data.data) - 1)) plan = CreateReverseREAL8FFTPlan(len(tdfilter.data.data), 0) lal.REAL8FreqTimeFFT(tdfilter, fdfilter, plan) return tdfilter
def generate_template(mass1, mass2, S, f_low, sample_rate, template_duration, approximant, amplitude_order, phase_order): template_length = sample_rate * template_duration if approximant == lalsimulation.TaylorF2: zf, _ = lalsimulation.SimInspiralChooseFDWaveform( 0, 1 / template_duration, mass1 * lal.LAL_MSUN_SI, mass2 * lal.LAL_MSUN_SI, 0, 0, 0, 0, 0, 0, f_low, 0, 1e6 * lal.LAL_PC_SI, 0, 0, 0, None, None, amplitude_order, phase_order, approximant) lal.ResizeCOMPLEX16FrequencySeries(zf, 0, template_length // 2 + 1) # Generate over-whitened template psd = lal.CreateREAL8FrequencySeries(None, zf.epoch, zf.f0, zf.deltaF, lal.lalDimensionlessUnit, len(zf.data.data)) psd.data.data = S(abscissa(psd)) zW = matched_filter_spa(zf, psd) elif approximant == lalsimulation.TaylorT4: hplus, hcross = lalsimulation.SimInspiralChooseTDWaveform( 0, 1 / sample_rate, mass1 * lal.LAL_MSUN_SI, mass2 * lal.LAL_MSUN_SI, 0, 0, 0, 0, 0, 0, f_low, f_low, 1e6 * lal.LAL_PC_SI, 0, 0, 0, None, None, amplitude_order, phase_order, approximant) ht = lal.CreateREAL8TimeSeries(None, lal.LIGOTimeGPS(-template_duration), hplus.f0, hplus.deltaT, hplus.sampleUnits, template_length) hf = lal.CreateCOMPLEX16FrequencySeries(None, lal.LIGOTimeGPS(0), 0, 0, lal.lalDimensionlessUnit, template_length // 2 + 1) plan = CreateForwardREAL8FFTPlan(template_length, 0) ht.data.data[:-len(hplus.data.data)] = 0 ht.data.data[-len(hplus.data.data):] = hplus.data.data lal.REAL8TimeFreqFFT(hf, ht, plan) psd = lal.CreateREAL8FrequencySeries(None, hf.epoch, hf.f0, hf.deltaF, lal.lalDimensionlessUnit, len(hf.data.data)) psd.data.data = S(abscissa(psd)) zWreal = matched_filter_real(hf, psd) ht.data.data[:-len(hcross.data.data)] = 0 ht.data.data[-len(hcross.data.data):] = hcross.data.data lal.REAL8TimeFreqFFT(hf, ht, plan) zWimag = matched_filter_real(hf, psd) zW = lal.CreateCOMPLEX16TimeSeries(None, zWreal.epoch, zWreal.f0, zWreal.deltaT, zWreal.sampleUnits, len(zWreal.data.data)) zW.data.data = zWreal.data.data + zWimag.data.data * 1j else: raise ValueError("unrecognized approximant") return zW.data.data[::-1].conj() * np.sqrt( 2) * template_duration / sample_rate / 2
def __init__(self, n): """ Initialize. n is the size, in samples, of the templates to be processed. This is used to pre-allocate work space. """ self.n = n self.fwdplan = lal.CreateForwardREAL8FFTPlan(n, 1) self.revplan = lal.CreateReverseCOMPLEX16FFTPlan(n, 1) self.in_fseries = lalfft.prepare_fseries_for_real8tseries( lal.CreateREAL8TimeSeries(deltaT=1.0, length=n))
def to_lal_timeseries(self): """ Output the time series strain data as a LAL TimeSeries object. """ laldata = lal.CreateREAL8TimeSeries("", lal.LIGOTimeGPS(self.start_time), 0., (1. / self.sampling_frequency), lal.SecondUnit, len(self.time_domain_strain)) laldata.data.data[:] = self.time_domain_strain return laldata
def get_sfts(self, fmax, Tsft, noise_sqrt_Sh=0, noise_seed=0, window=None, window_param=0): """ Generate SFTs [2] containing strain time series of a continuous-wave signal. @param fmax: maximum SFT frequency, in Hz @param Tsft: length of each SFT, in seconds; should divide evenly into @b Tdata @param noise_sqrt_Sh: if >0, add Gaussian noise with square-root single-sided power spectral density given by this value, in Hz^(-1/2) @param noise_seed: use this need for the random number generator used to create noise @param window: if not None, window the time series before performing the FFT, using the named window function; see XLALCreateNamedREAL8Window() @param window_param: parameter for the window function given by @b window, if needed @return (@b sft, @b i, @b N), where: @b sft = SFT; @b i = SFT file index, starting from zero; @b N = number of SFTs This is a Python generator function and so should be called as follows: ~~~ S = CWSimulator(...) for sft, i, N in S.get_sfts(...): ... ~~~ [2] https://dcc.ligo.org/LIGO-T040164/public """ # create timestamps for generating one SFT per time series sft_ts = lalpulsar.CreateTimestampVector(1) sft_ts.deltaT = Tsft # generate strain time series in blocks of length 'Tsft' sft_h = None sft_fs = 2 * fmax for t, h, i, N in self.get_strain_blocks(sft_fs, Tsft, noise_sqrt_Sh=noise_sqrt_Sh, noise_seed=noise_seed): # create and initialise REAL8TimeSeries to write to SFT files if sft_h is None: sft_name = self.__site.frDetector.prefix sft_h = lal.CreateREAL8TimeSeries(sft_name, t, 0, 1.0 / sft_fs, lal.DimensionlessUnit, len(h)) sft_h.epoch = t sft_h.data.data = h # create SFT, possibly with windowing sft_ts.data[0] = t sft_vect = lalpulsar.MakeSFTsFromREAL8TimeSeries(sft_h, sft_ts, window, window_param) # yield current SFT yield sft_vect.data[0], i, N
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 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 frequency_series(self, deltaF, detector=None, fwdplan=None): """ Generate a frequency series at a given frequency bin spacing deltaF (Hz) for the waveform using a call to lalsimulation. The function time_series is called first to generate the waveform in the time domain. If detector is None (default), return only hf with no antenna patterns applied. Otherwise, apply the proper detector anntenna patterns and return the resultant series hf = FFT[F+h+ + Fxhx]. """ # FIXME: This is overkill for BTLWNB, and won't work entirely for # cosmic strings sampling_rate = 4 * (self.frequency + (self.bandwidth or 0)) sampling_rate = 2**(int(math.log(sampling_rate, 2) + 1)) self.__get_fwdplan(sampling_rate, deltaF) if detector is not None: h = self.time_series(sampling_rate, detector) else: hp, hx = self.time_series(sampling_rate, detector) h = lal.CreateREAL8TimeSeries(name="TD signal", epoch=hp.epoch, f0=0, deltaT=hp.deltaT, sampleUnits=lal.DimensionlessUnit, length=hp.data.length) h.data.data = hp.data.data + hx.data.data # zero pad needed_samps = int(sampling_rate / deltaF) prevlen = h.data.length if h.data.length < needed_samps: h = lal.ResizeREAL8TimeSeries(h, 0, needed_samps) elif h.data.length > needed_samps: h = lal.ResizeREAL8TimeSeries(h, h.data.length - needed_samps, needed_samps) # adjust heterodyne frequency to match flow hf = lal.CreateCOMPLEX16FrequencySeries( name="FD signal", epoch=h.epoch, f0=0, deltaF=deltaF, sampleUnits=lal.DimensionlessUnit, length=int(h.data.length / 2 + 1)) # Forward FFT lal.REAL8TimeFreqFFT(hf, h, self._fwdplan) return hf
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 colored_noise(epoch, duration, sample_rate, psd): """Generate a REAL8TimeSeries containing duration seconds of colored Gaussian noise at the given sample rate, with the start time given by epoch. psd should be an instance of REAL8FrequencySeries containing a discretely sample power spectrum with f0=0, deltaF=1/duration, and a length of ((duration * sample_rate) // 2 + 1) samples. """ data_length = duration * sample_rate plan = CreateReverseREAL8FFTPlan(data_length, 0) x = lal.CreateREAL8TimeSeries( None, lal.LIGOTimeGPS(0), 0, 0, lal.DimensionlessUnit, data_length) xf = lal.CreateCOMPLEX16FrequencySeries( None, epoch, 0, 1 / duration, lal.DimensionlessUnit, data_length // 2 + 1) white_noise = (np.random.randn(len(xf.data.data)) + np.random.randn(len(xf.data.data)) * 1j) # On line 1288 of lal's AverageSpectrum.c, in the code comments for # XLALWhitenCOMPLEX8FrequencySeries, it says that according to the LAL # conventions a whitened frequency series should consist of bins whose # real and imaginary parts each have a variance of 1/2. white_noise /= np.sqrt(2) # The factor of sqrt(2 * psd.deltaF) comes from the value of 'norm' on # line 1362 of AverageSpectrum.c. xf.data.data = white_noise * np.sqrt(psd.data.data / (2 * psd.deltaF)) # Detrend the data: no DC component. xf.data.data[0] = 0 # Return to time domain. lal.REAL8FreqTimeFFT(x, xf, plan) # Copy over metadata. x.epoch = epoch x.sampleUnits = lal.StrainUnit # Done. return x
def _make_series(self, array, epoch, row_number): """For internal use only.""" para = { "name": "%s_%d_%d" % (self.instrument, self.bank_number, row_number), "epoch": epoch, "deltaT": self.deltaT, "f0": 0, "sampleUnits": lal.DimensionlessUnit, "length": len(array) } if array.dtype == numpy.float32: tseries = lal.CreateREAL4TimeSeries(**para) elif array.dtype == numpy.float64: tseries = lal.CreateREAL8TimeSeries(**para) elif array.dtype == numpy.complex64: tseries = lal.CreateCOMPLEX8TimeSeries(**para) elif array.dtype == numpy.complex128: tseries = lal.CreateCOMPLEX16TimeSeries(**para) else: raise ValueError("unsupported type : %s " % array.dtype) tseries.data.data = array return tseries
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 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 __init__(self, gps_t0, T, wf, gps_tref_wf, dt_wf, phi_0, psi, alpha, delta, det_name, earth_ephem_file="earth00-19-DE405.dat.gz", sun_ephem_file="sun00-19-DE405.dat.gz"): """ Initialise a continuous-wave signal simulator. @param gps_t0: start time of signal, in GPS seconds @param T: total duration of signal, in seconds @param wf: function which computes signal phase and amplitudes as functions of time: @b dphi, @b aplus, @b across = @b wf(dt), where: @b dt = time since reference time @b gps_tref_wf; @b dphi = phase of signal at time @b dt relative to reference time @b gps_tref_wf, in radians; @b aplus = strain amplitude of plus polarisation at time @b dt; @b across = strain amplitude of cross polarisation at time @b dt @param gps_tref_wf: reference time for signal phase, in GPS seconds @param dt_wf: sampling time of the function @c wf; this need only be small enough to ensure that @c dphi, @c aplus, and @c across are smoothly interpolated, and does not need to make the desired sampling frequency of the output strain time series @param phi_0: initial phase of the gravitational-wave signal at @b gps_t0, in radians @param psi: polarisation angle of the gravitational-wave source, in radians @param alpha: right ascension of the gravitational-wave source, in radians @param delta: declination of the gravitational-wave source, in radians @param det_name: name of the gravitational-wave detector to simulate a response for; e.g. @c "H1" for LIGO Hanford, @c "L1" for LIGO Livingston, @c "V1" for Virgo @param earth_ephem_file: name of file to load Earth ephemeris from @param sun_ephem_file: name of file to load Sun ephemeris from """ # store arguments self.__gps_t0 = gps_t0 self.__T = T # parse detector name try: _, self.__det_index = lalpulsar.GetCWDetectorPrefix(det_name) assert (self.__det_index >= 0) except: raise ValueError("Invalid detector name det_name='%s'" % det_name) # load Earth and Sun ephemerides self.__ephemerides = lalpulsar.InitBarycenter(earth_ephem_file, sun_ephem_file) # start signal time series 'T_pad_wf' before/after output strain time series # to add sufficient padding for maximum Doppler modulation time shifts, otherwise # lalpulsar.PulsarSimulateCoherentGW() will output zeros without complaint (unless # you run with LAL_DEBUG_LEVEL=warning) T_pad_wf = 2.0 * lal.AU_SI / lal.C_SI gps_t0_wf = gps_t0 - T_pad_wf N_wf = int(math.ceil(float(T + 2 * T_pad_wf) / float(dt_wf))) # create REAL8TimeSeries to store signal phase self.__phi = lal.CreateREAL8TimeSeries("phi", gps_t0_wf, 0, dt_wf, lal.DimensionlessUnit, N_wf) # create REAL4TimeVectorSeries to store signal amplitudes # - LAL provides no creator function for this type, so must be done manually self.__a = lal.REAL4TimeVectorSeries() self.__a.name = "a+,ax" self.__a.epoch = gps_t0_wf self.__a.deltaT = dt_wf self.__a.f0 = 0 self.__a.sampleUnits = lal.StrainUnit self.__a.data = lal.CreateREAL4VectorSequence(N_wf, 2) # call wf() to fill time series of signal phase and amplitudes dt = float(gps_t0_wf - gps_tref_wf) for i in xrange(0, N_wf): dphi, aplus, across = wf(dt) self.__phi.data.data[i] = phi_0 + dphi self.__a.data.data[i][0] = aplus self.__a.data.data[i][1] = across dt += dt_wf # create and initialise PulsarCoherentGW struct self.__waveform = lalpulsar.PulsarCoherentGW() self.__waveform.position.system = lal.COORDINATESYSTEM_EQUATORIAL self.__waveform.position.longitude = alpha self.__waveform.position.latitude = delta self.__waveform.psi = psi self.__waveform.phi = self.__phi self.__waveform.a = self.__a # create and initialise PulsarDetectorResponse struct self.__detector = lalpulsar.PulsarDetectorResponse() self.__detector.site = lal.CachedDetectors[self.__det_index] self.__detector.ephemerides = self.__ephemerides
def write_sft_files(self, fmax, T_sft, comment, out_dir=".", window=None, window_param=0): """ Write SFT files [2] containing strain time series of a continuous-wave signal. @param fmax: maximum SFT frequency, in Hz @param T_sft: length of each SFT, in seconds; should divide evenly into @b T @param comment: SFT file name comment, may only contain A-Z, a-z, 0-9, _, +, # characters @param out_dir: output directory to write SFT files into @param window: if not None, window the time series before performing the FFT, using the named window function; see XLALCreateNamedREAL8Window() @param window_param: parameter for the window function given by @b window, if needed @return (@b file, @b i, @b N), where: @b file = name of SFT file just written; @b i = SFT file index, starting from zero; @b N = number of SFT files This is a Python generator function and so should be called as follows: ~~~ S = CWSimulator(...) for t, h, i, N in S.write_sft_files(...): ... ~~~ [2] https://dcc.ligo.org/LIGO-T040164/public """ # check for valid SFT filename comment (see LIGO-T040164) valid_comment = re.compile(r'^[A-Za-z0-9_+#]+$') if not valid_comment.match(comment): raise ValueError( "SFT file comment='%s' may only contain A-Z, a-z, 0-9, _, +, # characters" % comment) # create timestamps for generating one SFT per time series sft_ts = lalpulsar.CreateTimestampVector(1) sft_ts.deltaT = T_sft # generate strain time series in blocks of length 'T_sft' sft_h = None sft_fs = 2 * fmax for t, h, i, N in self.get_strain_blocks(sft_fs, T_sft): # create and initialise REAL8TimeSeries to write to SFT files if sft_h is None: sft_name = lal.CachedDetectors[ self.__det_index].frDetector.prefix sft_h = lal.CreateREAL8TimeSeries(sft_name, t, 0, 1.0 / sft_fs, lal.DimensionlessUnit, len(h)) sft_h.epoch = t sft_h.data.data = h # create SFT, possibly with windowing sft_ts.data[0] = t sft_vect = lalpulsar.MakeSFTsFromREAL8TimeSeries( sft_h, sft_ts, window, window_param) # create standard SFT file name (see LIGO-T040164) sft_desc = 'simCW_%s' % comment sft_name = lalpulsar.GetOfficialName4MergedSFTs(sft_vect, sft_desc) sft_path = os.path.join(out_dir, sft_name) # write SFT lalpulsar.WriteSFTVector2NamedFile(sft_vect, sft_path, self.__origin_str) # yield current file name for e.g. printing progress yield sft_path, i, N
def analyze_event(P_list, indx_event, data_dict, psd_dict, fmax, opts, inv_spec_trunc_Q=inv_spec_trunc_Q, T_spec=T_spec): nEvals = 0 P = P_list[indx_event] # Precompute t_window = 0.15 rholms_intp, cross_terms, cross_terms_V, rholms, rest = factored_likelihood.PrecomputeLikelihoodTerms( fiducial_epoch, t_window, P, data_dict, psd_dict, opts.l_max, fmax, False, inv_spec_trunc_Q, T_spec, NR_group=NR_template_group, NR_param=NR_template_param, use_external_EOB=opts.use_external_EOB, nr_lookup=opts.nr_lookup, nr_lookup_valid_groups=opts.nr_lookup_group, perturbative_extraction=opts.nr_perturbative_extraction, use_provided_strain=opts.nr_use_provided_strain, hybrid_use=opts.nr_hybrid_use, hybrid_method=opts.nr_hybrid_method, ROM_group=opts.rom_group, ROM_param=opts.rom_param, ROM_use_basis=opts.rom_use_basis, verbose=opts.verbose, quiet=not opts.verbose, ROM_limit_basis_size=opts.rom_limit_basis_size_to, no_memory=opts.no_memory, skip_interpolation=opts.vectorized) # Only allocate the FFT plans ONCE ifo0 = psd_dict.keys()[0] npts = data_dict[ifo0].data.length print(" Allocating FFT forward, reverse plans ", npts) fwdplan = lal.CreateForwardREAL8FFTPlan(npts, 0) revplan = lal.CreateReverseREAL8FFTPlan(npts, 0) for ifo in psd_dict: # Plot PSDs plt.figure(99) # PSD figure) fvals = psd_dict[ifo].f0 + np.arange( psd_dict[ifo].data.length) * psd_dict[ifo].deltaF plt.plot(fvals, np.log10(np.sqrt(psd_dict[ifo].data.data)), label=ifo) plt.figure(88) plt.plot(fvals, fvals**(-14. / 6.) / psd_dict[ifo].data.data) plt.figure(1) # Plot inverse spectrum filters # - see lalsimutils code for inv_spec_trunc_Q , copied verbatim plt.figure(98) IP_here = lalsimutils.ComplexOverlap(P.fmin, fmax, 1. / 2 / P.deltaT, P.deltaF, psd_dict[ifo], False, inv_spec_trunc_Q, T_spec) WFD = lal.CreateCOMPLEX16FrequencySeries('FD root inv. spec.', lal.LIGOTimeGPS(0.), 0., IP_here.deltaF, lal.DimensionlessUnit, IP_here.len1side) WTD = lal.CreateREAL8TimeSeries('TD root inv. spec.', lal.LIGOTimeGPS(0.), 0., IP_here.deltaT, lal.DimensionlessUnit, IP_here.len2side) print(ifo, IP_here.len2side) # if not(fwdplan is None): WFD.data.data[:] = np.sqrt(IP_here.weights) # W_FD is 1/sqrt(S_n(f)) WFD.data.data[0] = WFD.data.data[-1] = 0. # zero 0, f_Nyq bins lal.REAL8FreqTimeFFT(WTD, WFD, revplan) # IFFT to TD tvals = IP_here.deltaT * np.arange(IP_here.len2side) plt.plot(tvals, np.log10(np.abs(WTD.data.data)), label=ifo) # Plot Q's plt.figure(1) plt.clf() for mode in rholms[ifo]: Q_here = rholms[ifo][mode] tvals = lalsimutils.evaluate_tvals(Q_here) - P.tref plt.plot(tvals, np.abs(Q_here.data.data), label=ifo + str(mode[0]) + "," + str(mode[1])) plt.legend() plt.xlabel("t (s)") plt.xlim(-0.1, 0.1) plt.xlabel("$Q_{lm}$") plt.title(ifo) plt.savefig(ifo + "_Q.png") plt.figure(99) plt.legend() plt.xlabel("f(Hz)") plt.ylabel(r'$\sqrt{S_h}$') plt.ylim(-24, -21) plt.savefig("PSD_plots.png") plt.xlim(5, 800) plt.savefig("PSD_plots_detail.png") plt.xlim(10, 400) plt.ylim(-23.5, -22) plt.savefig("PSD_plots_detail_fine.png") plt.figure(98) plt.legend() plt.xlabel("t (s)") plt.savefig("PSD_inv_plots.png") plt.figure(88) plt.legend() plt.xlabel("f (Hz)") plt.ylabel(r'$(S_h f^{15/6})^{-1}$') plt.savefig("PSD_weight_f.png")
def __init__(self, tref, tstart, Tdata, waveform, dt_wf, phi0, psi, alpha, delta, det_name, earth_ephem_file="earth00-40-DE405.dat.gz", sun_ephem_file="sun00-40-DE405.dat.gz", tref_at_det=False, extra_comment=None): """ Initialise a continuous-wave signal simulator. @param tref: reference time of signal phase at Solar System barycentre, in GPS seconds (but see @b tref_at_det) @param tstart: start time of signal, in GPS seconds @param Tdata: total duration of signal, in seconds @param waveform: function which computes signal phase and amplitudes as functions of time: @b dphi, @b aplus, @b across = @b waveform(dt), where: @b dt = time since reference time @b tref; @b dphi = phase of signal at time @b dt relative to reference time @b tref, in radians; @b aplus = strain amplitude of plus polarisation at time @b dt; @b across = strain amplitude of cross polarisation at time @b dt @param dt_wf: sampling time of the function @c waveform; this need only be small enough to ensure that @c dphi, @c aplus, and @c across are smoothly interpolated, and does not need to make the desired sampling frequency of the output strain time series @param phi0: initial phase of the gravitational-wave signal at @b tstart, in radians @param psi: polarisation angle of the gravitational-wave source, in radians @param alpha: right ascension of the gravitational-wave source, in radians @param delta: declination of the gravitational-wave source, in radians @param det_name: name of the gravitational-wave detector to simulate a response for; e.g. @c "H1" for LIGO Hanford, @c "L1" for LIGO Livingston, @c "V1" for Virgo @param earth_ephem_file: name of file to load Earth ephemeris from @param sun_ephem_file: name of file to load Sun ephemeris from @param tref_at_det: default False; if True, shift reference time @b tref so that @b dt = 0 is @b tref in @e detector frame instead of Solar System barycentre frame, useful if e.g. one wants to turn on signal only for @b dt > 0, one can use @b tref as the turn-on time @param extra_comment: additional text to add to comment string in frame/SFT headers (not filenames), e.g. for wrapper script commandlines """ self.__origin_str = "Generated by %s, %s-%s (%s)" % (__file__, git_version.id, git_version.status, git_version.date) if extra_comment: self.__origin_str += ", "+extra_comment # store arguments self.__tstart = tstart self.__Tdata = Tdata # parse detector name try: _, self.__site_index = lalpulsar.FindCWDetector(det_name, True) assert(self.__site_index >= 0) except: raise ValueError("Invalid detector name det_name='%s'" % det_name) self.__site = lal.CachedDetectors[self.__site_index] # load Earth and Sun ephemerides self.__ephemerides = lalpulsar.InitBarycenter(earth_ephem_file, sun_ephem_file) if tref_at_det: # calculate barycentric delay at reference time bary_state = lalpulsar.EarthState() bary_input = lalpulsar.BarycenterInput() bary_emit = lalpulsar.EmissionTime() bary_input.tgps = tref bary_input.site = self.__site for i in range(0, 3): bary_input.site.location[i] /= lal.C_SI bary_input.alpha = alpha bary_input.delta = delta bary_input.dInv = 0.0 lalpulsar.BarycenterEarth(bary_state, bary_input.tgps, self.__ephemerides) lalpulsar.Barycenter(bary_emit, bary_input, bary_state) # adjust reference time so that dt = 0 is tref in detector frame tref += bary_emit.deltaT # start signal time series 'Tpad_wf' before/after output strain time series # add sufficient padding to signal for maximum Doppler modulation time shifts, otherwise # lalpulsar.PulsarSimulateCoherentGW() will output zeros without complaint (unless # you run with LAL_DEBUG_LEVEL=warning) Tpad_wf = 2.0 * lal.AU_SI / lal.C_SI tstart_wf = tstart - Tpad_wf Nwf = int(math.ceil(float(Tdata + 2*Tpad_wf) / float(dt_wf))) # create REAL8TimeSeries to store signal phase self.__phi = lal.CreateREAL8TimeSeries("phi", tstart_wf, 0, dt_wf, lal.DimensionlessUnit, Nwf) # create REAL4TimeVectorSeries to store signal amplitudes # - LAL provides no creator function for this type, so must be done manually self.__a = lal.REAL4TimeVectorSeries() self.__a.name = "a+,ax" self.__a.epoch = tstart_wf self.__a.deltaT = dt_wf self.__a.f0 = 0 self.__a.sampleUnits = lal.StrainUnit self.__a.data = lal.CreateREAL4VectorSequence(Nwf, 2) # call waveform() to fill time series of signal phase and amplitudes dt = float(tstart_wf - tref) for i in range(0, Nwf): dphi, aplus, across = waveform(dt) self.__phi.data.data[i] = phi0 + dphi self.__a.data.data[i][0] = aplus self.__a.data.data[i][1] = across dt += dt_wf # create and initialise PulsarCoherentGW struct self.__wf = lalpulsar.PulsarCoherentGW() self.__wf.position.system = lal.COORDINATESYSTEM_EQUATORIAL self.__wf.position.longitude = alpha self.__wf.position.latitude = delta self.__wf.psi = psi self.__wf.phi = self.__phi self.__wf.a = self.__a # create and initialise PulsarDetectorResponse struct self.__detector = lalpulsar.PulsarDetectorResponse() self.__detector.site = self.__site self.__detector.ephemerides = self.__ephemerides
# Generate signal hoft = lalsimutils.hoft( P ) # include translation of source, but NOT interpolation onto regular time grid # zero pad to be opts.seglen long, if necessary if opts.seglen / hoft.deltaT > hoft.data.length: TDlenGoal = int(opts.seglen / hoft.deltaT) hoft = lal.ResizeREAL8TimeSeries(hoft, 0, TDlenGoal) # zero pad some more on either side, to make sure the segment covers start to stop if opts.start and hoft.epoch > opts.start: nToAddBefore = int((float(hoft.epoch) - opts.start) / hoft.deltaT) # hoft.epoch - nToAddBefore*hoft.deltaT # this is close to the epoch, but not quite ... we are adjusting it to be within 1 time sample print(nToAddBefore, hoft.data.length) ht = lal.CreateREAL8TimeSeries("Template h(t)", opts.start, 0, hoft.deltaT, lalsimutils.lsu_DimensionlessUnit, hoft.data.length + nToAddBefore) ht.data.data = np.zeros(ht.data.length) # clear ht.data.data[nToAddBefore:nToAddBefore + hoft.data.length] = hoft.data.data hoft = ht if opts.stop and hoft.epoch + hoft.data.length * hoft.deltaT < opts.stop: nToAddAtEnd = int( (-(hoft.epoch + hoft.data.length * hoft.deltaT) + opts.stop) / hoft.deltaT) print("Padding end ", nToAddAtEnd, hoft.data.length) hoft = lal.ResizeREAL8TimeSeries(hoft, 0, int(hoft.data.length + nToAddAtEnd)) # Import background data, if needed, and add it if not (opts.background_cache is None or opts.background_channel is None
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
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
sim_time = np.arange(0, duration, 1.0 / sample_rate) SI = 0 if SI: extraction_distance_SI = lal.LAL_PC_SI * 1e6 * dist geom_fac = lal.LAL_MRSUN_SI / extraction_distance_SI else: geom_fac = 1.0 sim_time /= lal.LAL_MTSUN_SI # # Allocate storage for simulation data # Idotdot = np.zeros((3, 3), float) hplus_sim = lal.CreateREAL8TimeSeries('hplus', lal.LIGOTimeGPS(), 0.0, 1. / sample_rate, lal.lalStrainUnit, int(duration * sample_rate)) hcross_sim = lal.CreateREAL8TimeSeries('hcross', lal.LIGOTimeGPS(), 0.0, 1. / sample_rate, lal.lalStrainUnit, int(duration * sample_rate)) # Get index middle of series startidx = np.floor(0.5 * duration * sample_rate) # Loop over harmonics for m in [-2, -1, 0, 1, 2]: if len(args) == 2: filename = args[1] + "_l2m%d.asc" % m elif len(args) == 1:
print "check choice of deltaF, might need to adjust:" print wnb_deltaF, sg_deltaF, deltaF # our fft will be easier if we zero pad (or truncate if we have too much) needed_samps = int(2.0*fnyq/deltaF) # to have enough resolution if opts.hrss_det is not True: # compute h(t) = h+(t) + hx(t) h_wnb = wnb_hp.data.data + wnb_hx.data.data h_sg = sg_hp.data.data + sg_hx.data.data # make lal time series to set numpy arrays equal to lal_h_wnb = lal.CreateREAL8TimeSeries(name = "lal_wnb", epoch = wnb_hp.epoch, f0=0, deltaT = deltaT, sampleUnits = lal.lalDimensionlessUnit, length = len(wnb_hp.data.data+wnb_hx.data.data)) lal_h_sg = lal.CreateREAL8TimeSeries(name = "lal_sg", epoch = sg_hp.epoch, f0=0, deltaT =deltaT, sampleUnits = lal.lalDimensionlessUnit, length = len(sg_hp.data.data+sg_hx.data.data)) #h_wnb = lal_h_wnb h_wnb = lal_h_wnb h_sg = lal_h_sg else: # use lal version of h: h(t) = F+ h+(t) + Fx hx(t) h_wnb = lalsimulation.SimDetectorStrainREAL8TimeSeries( wnb_hp, wnb_hx, sim_burst_table.ra, sim_burst_table.dec, sim_burst_table.psi, det ) h_sg = lalsimulation.SimDetectorStrainREAL8TimeSeries( sg_hp, sg_hx, sim_burst_table.ra, sim_burst_table.dec, sim_burst_table.psi, det ) # resize if necessary for FFT if h_wnb.data.length < needed_samps: h_wnb = lal.ResizeREAL8TimeSeries( h_wnb, 0, needed_samps )
def write_frame_files(self, fs, T_frame, comment, out_dir="."): """ Write frame files [1] containing strain time series of a continuous-wave signal. The strain time series is written as double-precision post-processed data (ProcData) channel named <tt><detector>:SIMCW-STRAIN</tt>, where <tt><detector></tt> is the 2-character detector prefix (e.g. <tt>H1</tt> for LIGO Hanford, <tt>L1</tt> for LIGO Livingston, <tt>V1</tt> for Virgo). @param fs: sampling frequency of strain time series, in Hz @param T_frame: length of each frame, in seconds; should divide evenly into @b T @param comment: frame file name comment, may only contain A-Z, a-z, 0-9, _, +, # characters @param out_dir: output directory to write frame files into @return (@b file, @b i, @b N), where: @b file = name of frame file just written; @b i = frame file index, starting from zero; @b N = number of frame files This is a Python generator function and so should be called as follows: ~~~ S = CWSimulator(...) for t, h, i, N in S.write_frame_files(...): ... ~~~ [1] https://dcc.ligo.org/LIGO-T970130/public """ try: import lalframe except ImportError: raise ImportError("SWIG wrappings of LALFrame cannot be imported") # check for valid frame filename comment (see LIGO-T010150) valid_comment = re.compile(r'^[A-Za-z0-9_+#]+$') if not valid_comment.match(comment): raise ValueError( "Frame file comment='%s' may only contain A-Z, a-z, 0-9, _, +, # characters" % comment) # generate strain time series in blocks of length 'T_frame' frame_h = None for t, h, i, N in self.get_strain_blocks(fs, T_frame): # create and initialise REAL8TimeSeries to write to frame files if frame_h is None: frame_h_channel = '%s:SIMCW-STRAIN' % lal.CachedDetectors[ self.__det_index].frDetector.prefix frame_h = lal.CreateREAL8TimeSeries(frame_h_channel, t, 0, 1.0 / fs, lal.DimensionlessUnit, len(h)) frame_h.epoch = t frame_h.data.data = h # create standard frame file name (see LIGO-T010150) frame_src = lal.CachedDetectors[ self.__det_index].frDetector.prefix[0] frame_desc = 'simCW_%s' % comment frame_t0 = int(t.gpsSeconds) frame_T = int(math.ceil(float(t + T_frame)) - math.floor(float(t))) frame_name = '%s-%s-%u-%u.gwf' % (frame_src, frame_desc, frame_t0, frame_T) frame_path = os.path.join(out_dir, frame_name) # create frame frame_det_bits = 2 * self.__det_index frame = lalframe.FrameNew(t, T_frame, "simCW", -1, i, frame_det_bits) # add strain time series to frame lalframe.FrameAddREAL8TimeSeriesProcData(frame, frame_h) # add history lalframe.FrameAddFrHistory(frame, "origin", self.__origin_str) # write frame lalframe.FrameWrite(frame, frame_path) # yield current file name for e.g. printing progress yield frame_path, i, N
del mem4 lal.CheckMemoryLeaks() print("PASSED memory allocation") else: print("skipped memory allocation") # check object parent tracking print("checking object parent tracking ...") a = lal.gsl_vector(3) a.data = [1.1, 2.2, 3.3] b = a.data assert (not b.flags['OWNDATA']) assert ((b == [1.1, 2.2, 3.3]).all()) del a assert ((b == [1.1, 2.2, 3.3]).all()) ts = lal.CreateREAL8TimeSeries("test", lal.LIGOTimeGPS(0), 0, 0.1, lal.DimensionlessUnit, 10) ts.data.data = list(range(0, 10)) for i in range(0, 7): v = ts.data assert ((v.data == list(range(0, 10))).all()) del ts assert ((v.data == list(range(0, 10))).all()) del v lal.CheckMemoryLeaks() print("PASSED object parent tracking") # check equal return/first argument type handling print("checking equal return/first argument type handling") sv = lal.CreateStringVector("1") assert (sv.length == 1) lal.AppendString2Vector(sv, "2")
Iyz /= massMpc Izz /= massMpc times /= lal.MTSUN_SI ###################################################################### # # # Construct expansion parameters and write to ascii in NINJA format # # # ###################################################################### target_times = np.arange(0, times[-1], 1. / sample_rate) # putting the data in laltimeseries allows us to use lalsim tapering functions hplus_sim = lal.CreateREAL8TimeSeries('hplus', lal.LIGOTimeGPS(), 0.0, 1. / sample_rate, lal.StrainUnit, len(target_times)) hcross_sim = lal.CreateREAL8TimeSeries('hcross', lal.LIGOTimeGPS(), 0.0, 1. / sample_rate, lal.StrainUnit, len(target_times)) # # Construct an ini file for further processing with NINJA-type tools # inifile = open(waveformlabel + ".ini", 'w') # XXX: hard-coding the mass-ratio and mass-scale here. We can add these as # arguments later if desired. Mass ratio is irrelevant for general matter # waveforms, but is needed by the existing ninja codes headerstr = """mass-ratio = {0}