Exemple #1
0
 def project_wave(self, hp, hc, longitude, latitude, polarization):
     """Return the strain of a wave with given amplitudes and angles as
     measured by the detector.
     """
     h_lal = lalsimulation.SimDetectorStrainREAL8TimeSeries(
             hp.astype(np.float64).lal(), hc.astype(np.float64).lal(),
             longitude, latitude, polarization, self.frDetector)
     return TimeSeries(
             h_lal.data.data, delta_t=h_lal.deltaT, epoch=h_lal.epoch,
             dtype=np.float64, copy=False)
Exemple #2
0
def generate_for_detector(source, ifos, sample_rate, epoch, distance,
                          total_mass, ra, dec, psi):
    '''
    Generate an injection for a given waveform.
    Parameters
    ----------
    source : ``minke.Source`` object
       The source which should generate the waveform.
    ifos : list
       A list of interferometer initialisms, e.g. ['L1', 'H1']
    sample_rate : int
       The sample rate in hertz for the generated signal.
    epoch : str
       The epoch (start time) for the injection.
       Note that this should be provided as a string to prevent overflows.
    distance : float
       The distance for the injection, in megaparsecs.
    total_mass : float
       The total mass for the injected signal.
    ra : float
        The right ascension of the source, in radians.
    dec : float
        The declination of the source, in radians.
    psi : float
        The polarisation angle of the source, in radians. '''

    nr_waveform = source.datafile
    data = {}
    data['data'] = {}
    data['times'] = {}
    data['meta'] = {}
    data['epoch'] = epoch
    data['meta']['ra'] = ra
    data['meta']['dec'] = dec
    data['meta']['psi'] = psi
    data['meta']['distance'] = distance
    data['meta']['total_mass'] = total_mass
    data['meta']['sample rate'] = sample_rate
    data['meta']['waveform'] = nr_waveform

    for ifo in ifos:
        det = lalsimulation.DetectorPrefixToLALDetector(ifo)
        hp, hx = source._generate(half=True, epoch=epoch, rate=sample_rate)[:2]
        h_tot = lalsimulation.SimDetectorStrainREAL8TimeSeries(
            hp, hx, ra, dec, psi, det)
        data['data'][ifo] = h_tot.data.data.tolist()
        data['times'][ifo] = np.linspace(0,
                                         len(h_tot.data.data) * h_tot.deltaT,
                                         len(h_tot.data.data)).tolist()

    return data
Exemple #3
0
    def project_wave(self, hp, hc, longitude, latitude, polarization):
        """Return the strain of a waveform as measured by the detector.

        Apply the time shift for the given detector relative to the assumed
        geocentric frame and apply the antenna patterns to the plus and cross
        polarizations.

        """
        h_lal = lalsimulation.SimDetectorStrainREAL8TimeSeries(
                hp.astype(np.float64).lal(), hc.astype(np.float64).lal(),
                longitude, latitude, polarization, self.frDetector)
        return TimeSeries(
                h_lal.data.data, delta_t=h_lal.deltaT, epoch=h_lal.epoch,
                dtype=np.float64, copy=False)
Exemple #4
0
    def time_series(self, sampling_rate, detector=None):
        """
        Generate a time series at a given sampling_rate (Hz) for the waveform using a call to lalsimulation. If detector is None (default), return only the (h+, hx) tuple. Otherwise, apply the proper detector anntenna patterns and return the resultant series F+h+ + Fxhx.
        """

        hp, hx = lalburst.GenerateSimBurst(copy_sim_burst(self),
                                           1.0 / sampling_rate)

        if detector is None:
            return hp, hx

        detector = LAL_DETECTORS[detector]
        return lalsimulation.SimDetectorStrainREAL8TimeSeries(
            hp, hx, self.ra, self.dec, self.psi, detector)
Exemple #5
0
    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
Exemple #6
0
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)
Exemple #7
0
    def project_wave(self, hp, hc, ra, dec, polarization,
                     method='lal',
                     reference_time=None):
        """Return the strain of a waveform as measured by the detector.
        Apply the time shift for the given detector relative to the assumed
        geocentric frame and apply the antenna patterns to the plus and cross
        polarizations.

        Parameters
        ----------
        hp: pycbc.types.TimeSeries
            Plus polarization of the GW
        hc: pycbc.types.TimeSeries
            Cross polarization of the GW
        ra: float
            Right ascension of source location
        dec: float
            Declination of source location
        polarization: float
            Polarization angle of the source
        method: {'lal', 'constant', 'vary_polarization'}
            The method to use for projecting the polarizations into the
            detector frame. Default is 'lal'.
        reference_time: float, Optional
            The time to use as, a reference for some methods of projection.
            Used by 'constant' and 'vary_polarization' methods. Uses average
            time if not provided.
        """
        # The robust and most fefature rich method which includes
        # time changing antenna patterns and doppler shifts due to the
        # earth rotation and orbit
        if method == 'lal':
            import lalsimulation
            h_lal = lalsimulation.SimDetectorStrainREAL8TimeSeries(
                    hp.astype(np.float64).lal(), hc.astype(np.float64).lal(),
                    ra, dec, polarization, self.lal())
            ts = TimeSeries(
                    h_lal.data.data, delta_t=h_lal.deltaT, epoch=h_lal.epoch,
                    dtype=np.float64, copy=False)

        # 'constant' assume fixed orientation relative to source over the
        # duration of the signal, accurate for short duration signals
        # 'fixed_polarization' applies only time changing orientation
        # but no doppler corrections
        elif method in ['constant', 'vary_polarization']:
            if reference_time is not None:
                rtime = reference_time
            else:
                # In many cases, one should set the reference time if using
                # this method as we don't know where the signal is within
                # the given time series. If not provided, we'll choose
                # the midpoint time.
                rtime = (float(hp.end_time) + float(hp.start_time)) / 2.0

            if method == 'constant':
                time = rtime
            elif method == 'vary_polarization':
                if (not isinstance(hp, TimeSeries) or
                   not isinstance(hc, TimeSeries)):
                    raise TypeError('Waveform polarizations must be given'
                                    ' as time series for this method')

                # this is more granular than needed, may be optimized later
                # assume earth rotation in ~30 ms needed for earth ceneter
                # to detector is completely negligible.
                time = hp.sample_times.numpy()

            fp, fc = self.antenna_pattern(ra, dec, polarization, time)
            dt = self.time_delay_from_earth_center(ra, dec, rtime)
            ts = fp * hp + fc * hc
            ts.start_time = float(ts.start_time) + dt

        # add in only the correction for the time variance in the polarization
        # due to the earth's rotation, no doppler correction applied
        else:
            raise ValueError("Unkown projection method {}".format(method))
        return ts
Exemple #8
0
def get_WF_and_snr(inj, PSD, sample_rate, instrument="H1", plot_dir=None):
    "Given an injection row, it computes the WF and the SNR"
    #https://git.ligo.org/lscsoft/gstlal/-/blob/precession_hm-0.2/gstlal-inspiral/bin/gstlal_inspiral_injection_snr
    #PSD should be a lal PSD obj
    assert instrument in ["H1", "L1", "V1"]

    injtime = inj.time_geocent

    sample_rate = 16384.0

    approximant = lalsimulation.GetApproximantFromString(str(inj.waveform))
    f_min = inj.f_lower

    h_plus, h_cross = lalsimulation.SimInspiralTD(m1=inj.mass1 * lal.MSUN_SI,
                                                  m2=inj.mass2 * lal.MSUN_SI,
                                                  S1x=inj.spin1x,
                                                  S1y=inj.spin1y,
                                                  S1z=inj.spin1z,
                                                  S2x=inj.spin2x,
                                                  S2y=inj.spin2y,
                                                  S2z=inj.spin2z,
                                                  distance=inj.distance * 1e6 *
                                                  lal.PC_SI,
                                                  inclination=inj.inclination,
                                                  phiRef=inj.coa_phase,
                                                  longAscNodes=0.0,
                                                  eccentricity=0.0,
                                                  meanPerAno=0.0,
                                                  deltaT=1.0 / sample_rate,
                                                  f_min=f_min,
                                                  f_ref=0.0,
                                                  LALparams=None,
                                                  approximant=approximant)

    h_plus.epoch += injtime
    h_cross.epoch += injtime

    # Compute strain in the chosen detector.
    h = lalsimulation.SimDetectorStrainREAL8TimeSeries(
        h_plus, h_cross, inj.longitude, inj.latitude, inj.polarization,
        lalsimulation.DetectorPrefixToLALDetector(instrument))
    #Compute the SNR
    if PSD is not None:
        snr = lalsimulation.MeasureSNR(h, PSD, options.flow, options.fmax)
    else:
        snr = 0.

    if isinstance(plot_dir, str):
        plt.figure()
        plt.title(
            "(m1, m2, s1 (x,y,z), s2 (x,y,z), d_L) =\n {0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} {6:.2f} {7:.2f} {8:.2f} "
            .format(inj.mass1, inj.mass2, inj.spin1x, inj.spin1y, inj.spin1z,
                    inj.spin2x, inj.spin2y, inj.spin2z, inj.distance))
        plt.plot(
            np.linspace(0,
                        len(h_plus.data.data) / sample_rate,
                        len(h_plus.data.data)), h_plus.data.data)
        plt.savefig(plot_dir + '/inj_{}.png'.format(injtime))
        #plt.show()
        plt.close('all')

    return (h.data.data, snr)
Exemple #9
0
    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
Exemple #10
0
	# 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 )
elif h_wnb.data.length > needed_samps:
	h_wnb = lal.ResizeREAL8TimeSeries( h_wnb, h_wnb.data.length-needed_samps, needed_samps )

if h_sg.data.length < needed_samps:
	h_sg = lal.ResizeREAL8TimeSeries( h_sg, 0, needed_samps )
elif h_sg.data.length > needed_samps:
	h_sg = lal.ResizeREAL8TimeSeries( h_sg, h_sg.data.length-needed_samps, needed_samps )

hf_wnb = lal.CreateCOMPLEX16FrequencySeries(
									name = "m1",