示例#1
0
def gen_test_data(spin1x, approximant, mode_array):
    """
    compute the difference between two waveforms
    and compare to expected value
    """
    lalparams = lal.CreateDict()

    if (mode_array != None):
        ModeArray = lalsimulation.SimInspiralCreateModeArray()
        for mode in mode_array:
            lalsimulation.SimInspiralModeArrayActivateMode(
                ModeArray, mode[0], mode[1])
        lalsimulation.SimInspiralWaveformParamsInsertModeArray(
            lalparams, ModeArray)

    common_pars = dict(m1=50 * lal.MSUN_SI,
                       m2=30 * lal.MSUN_SI,
                       s1x=spin1x,
                       s1y=0.,
                       s1z=0.,
                       s2x=0.,
                       s2y=0.,
                       s2z=0.,
                       distance=1,
                       inclination=np.pi / 3.,
                       phiRef=0.,
                       longAscNodes=0.,
                       eccentricity=0.,
                       meanPerAno=0.,
                       deltaT=1. / 4096.,
                       f_min=30.,
                       f_ref=30.,
                       params=lalparams,
                       approximant=approximant)

    pars1 = common_pars.copy()

    pars2 = common_pars.copy()
    pars2.update({"inclination": 0.17})
    pars2.update({"phiRef": 0.5})

    hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(**pars1)
    hp2, hc2 = lalsimulation.SimInspiralChooseTDWaveform(**pars2)

    # compute amp and phase
    hp1_amp, hp1_phase = get_amp_phase(hp1.data.data)
    hc1_amp, hc1_phase = get_amp_phase(hc1.data.data)

    hp2_amp, hp2_phase = get_amp_phase(hp2.data.data)
    hc2_amp, hc2_phase = get_amp_phase(hc2.data.data)

    hp_amp_diff = sum_sqr_diff(hp1_amp, hp2_amp)
    hp_phase_diff = sum_sqr_diff(hp1_phase, hp2_phase)

    hc_amp_diff = sum_sqr_diff(hc1_amp, hc2_amp)
    hc_phase_diff = sum_sqr_diff(hc1_phase, hc2_phase)

    return hp_amp_diff, hp_phase_diff, hc_amp_diff, hc_phase_diff
示例#2
0
def tmplttime(f0, m1, m2, j1, j2, approx):
    dt = 1.0 / 16384.0
    approximant = lalsim.GetApproximantFromString(approx)
    hp, hc = lalsim.SimInspiralChooseTDWaveform(phiRef=0,
                                                deltaT=dt,
                                                m1=m1,
                                                m2=m2,
                                                s1x=0,
                                                s1y=0,
                                                s1z=j1,
                                                s2x=0,
                                                s2y=0,
                                                s2z=j2,
                                                f_min=f0,
                                                f_ref=0,
                                                r=1,
                                                i=0,
                                                lambda1=0,
                                                lambda2=0,
                                                waveFlags=None,
                                                nonGRparams=None,
                                                amplitudeO=0,
                                                phaseO=0,
                                                approximant=approximant)
    h = numpy.array(hp.data.data, dtype=complex)
    h += 1j * numpy.array(hc.data.data, dtype=complex)
    try:
        n = list(abs(h)).index(0)
    except ValueError:
        n = len(h)
    return n * hp.deltaT
示例#3
0
def get_SEOBNRv2_WF(q, M, chi1, chi2, f_start, deltaT=1. / (4096 * 4.)):
    m1 = q * M / (1 + q)
    m2 = M / (1 + q)
    hp, hc = lalsim.SimInspiralChooseTDWaveform(  #where is its definition and documentation????
        m1 * lalsim.lal.MSUN_SI,  #m1
        m2 * lalsim.lal.MSUN_SI,  #m2
        0.,
        0.,
        chi1,  #spin vector 1
        0.,
        0.,
        chi2,  #spin vector 2
        1e6 * lalsim.lal.PC_SI,  #distance to source
        0.,  #inclination
        0.,  #phi
        0.,  #longAscNodes
        0.,  #eccentricity
        0.,  #meanPerAno
        deltaT,  # time incremental step
        f_start,  # lowest value of freq
        f_start,  #some reference value of freq (??)
        lal.CreateDict(),  #some lal dictionary
        lalsim.SimInspiralGetApproximantFromString(
            'SpinTaylorT4')  #approx method for the model
    )
    h_p, h_c = hp.data.data, hc.data.data
    times = np.linspace(0, len(h_c) * deltaT, len(h_c))
    ph = np.unwrap(np.angle(h_p + 1j * h_c))
    omega_22 = (ph[2] - ph[0]) / (2 * deltaT)
    print("FREQUENCY of THE WF (NP): ", omega_22, omega_22 / (2 * np.pi))
    t_max = times[np.argmax(np.abs(h_p + 1j * h_c))]
    times = times - t_max
    return times, h_p + 1j * h_c
示例#4
0
def _lalsim_td_waveform(**p):
    lal_pars = lal.CreateDict()
    if p['phase_order'] != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(
            lal_pars, int(p['phase_order']))
    if p['amplitude_order'] != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder(
            lal_pars, int(p['amplitude_order']))
    if p['spin_order'] != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder(
            lal_pars, int(p['spin_order']))
    if p['tidal_order'] != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidalOrder(
            lal_pars, p['tidal_order'])
    if p['eccentricity_order'] != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNEccentricityOrder(
            lal_pars, p['eccentricity_order'])
    if p['lambda1']:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidalLambda1(
            lal_pars, p['lambda1'])
    if p['lambda2']:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidalLambda2(
            lal_pars, p['lambda2'])
    if p['dquad_mon1']:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidaldQuadMon1(
            lal_pars, p['dquad_mon1'])
    if p['dquad_mon2']:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidaldQuadMon2(
            lal_pars, p['dquad_mon2'])
    if p['numrel_data']:
        lalsimulation.SimInspiralWaveformParamsInsertNumRelData(
            lal_pars, str(p['numrel_data']))
    if p['modes_choice']:
        lalsimulation.SimInspiralWaveformParamsInsertModesChoice(
            lal_pars, p['modes_choice'])
    if p['frame_axis']:
        lalsimulation.SimInspiralWaveformParamsInsertFrameAxis(
            lal_pars, p['frame_axis'])
    if p['side_bands']:
        lalsimulation.SimInspiralWaveformParamsInsertSideband(
            lal_pars, p['side_bands'])
    #nonGRparams can be straightforwardly added if needed, however they have to
    # be invoked one by one
    hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(
        float(pnutils.solar_mass_to_kg(p['mass1'])),
        float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']),
        float(p['spin1y']), float(p['spin1z']), float(p['spin2x']),
        float(p['spin2y']), float(p['spin2z']),
        pnutils.megaparsecs_to_meters(float(p['distance'])),
        float(p['inclination']), float(p['coa_phase']),
        float(p['long_asc_nodes']), float(p['eccentricity']),
        float(p['mean_per_ano']), float(p['delta_t']), float(p['f_lower']),
        float(p['f_ref']), lal_pars, _lalsim_enum[p['approximant']])
    #lal.DestroyDict(lal_pars)

    hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch)
    hc = TimeSeries(hc1.data.data[:], delta_t=hc1.deltaT, epoch=hc1.epoch)

    return hp, hc
示例#5
0
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
示例#6
0
    def __init__(self, mass1, mass2, S, f_low, approximant, amplitude_order,
                 phase_order):
        """Create a TaylorF2 signal model with the given masses, PSD function
        S(f), PN amplitude order, and low-frequency cutoff."""

        if approximant == lalsimulation.TaylorF2:
            # Frequency-domain post-Newtonian inspiral waveform.
            h, _ = lalsimulation.SimInspiralChooseFDWaveform(
                0, 1, 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, 0, approximant)

            # Find indices of first and last nonzero samples.
            nonzero = np.nonzero(h.data.data)[0]
            first_nonzero = nonzero[0]
            last_nonzero = nonzero[-1]
        elif approximant == lalsimulation.TaylorT4:
            # Time-domain post-Newtonian inspiral waveform.
            hplus, hcross = lalsimulation.SimInspiralChooseTDWaveform(
                0, 1 / 4096, 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)

            hplus.data.data += hcross.data.data
            hplus.data.data /= np.sqrt(2)

            h = lal.CreateCOMPLEX16FrequencySeries(
                None, lal.LIGOTimeGPS(0), 0, 0, lal.lalDimensionlessUnit,
                len(hplus.data.data) // 2 + 1)
            plan = CreateForwardREAL8FFTPlan(len(hplus.data.data), 0)
            lal.REAL8TimeFreqFFT(h, hplus, plan)

            f = h.f0 + len(h.data.data) * h.deltaF
            first_nonzero = long(np.floor((f_low - h.f0) / h.deltaF))
            last_nonzero = long(np.ceil((2048 - h.f0) / h.deltaF))
            last_nonzero = min(last_nonzero, len(h.data.data) - 1)
        else:
            raise ValueError("unrecognized approximant")

        # Frequency sample points
        self.dw = 2 * np.pi * h.deltaF
        f = h.f0 + h.deltaF * np.arange(first_nonzero, last_nonzero + 1)
        self.w = 2 * np.pi * f

        # Throw away leading and trailing zeros.
        h = h.data.data[first_nonzero:last_nonzero + 1]

        self.denom_integrand = 4 / (2 * np.pi) * (np.square(h.real) +
                                                  np.square(h.imag)) / S(f)
        self.den = np.trapz(self.denom_integrand, dx=self.dw)
示例#7
0
def _lalsim_td_waveform(**p):
    hp, hc = lalsimulation.SimInspiralChooseTDWaveform(
        float(p['phi0']), float(p['delta_t']),
        float(solar_mass_to_kg(p['mass1'])),
        float(solar_mass_to_kg(p['mass2'])), float(p['spin1x']),
        float(p['spin1y']), float(p['spin1z']), float(p['spin2x']),
        float(p['spin2y']), float(p['spin2z']), float(p['f_lower']), 0,
        parsecs_to_meters(float(p['distance'])),
        float(p['inclination']), 0, 0, None, None, int(p['amplitude_order']),
        int(p['phase_order']), _lalsim_enum[p['approximant']])

    hp = TimeSeries(hp.data.data, delta_t=hp.deltaT, epoch=hp.epoch)
    hc = TimeSeries(hc.data.data, delta_t=hc.deltaT, epoch=hc.epoch)

    return hp, hc
示例#8
0
def _lalsim_td_waveform(**p):
    fail_tolerant_waveform_generation
    lal_pars = _check_lal_pars(p)
    #nonGRparams can be straightforwardly added if needed, however they have to
    # be invoked one by one
    try:
        hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(
               float(pnutils.solar_mass_to_kg(p['mass1'])),
               float(pnutils.solar_mass_to_kg(p['mass2'])),
               float(p['spin1x']), float(p['spin1y']), float(p['spin1z']),
               float(p['spin2x']), float(p['spin2y']), float(p['spin2z']),
               pnutils.megaparsecs_to_meters(float(p['distance'])),
               float(p['inclination']), float(p['coa_phase']),
               float(p['long_asc_nodes']), float(p['eccentricity']), float(p['mean_per_ano']),
               float(p['delta_t']), float(p['f_lower']), float(p['f_ref']),
               lal_pars,
               _lalsim_enum[p['approximant']])
    except RuntimeError:
        if not fail_tolerant_waveform_generation:
            raise
        # For some cases failure modes can occur. Here we add waveform-specific
        # instructions to try to work with waveforms that are known to fail.
        if 'SEOBNRv3' in p['approximant']:
            # Try doubling the sample time and redoing.
            # Don't want to get stuck in a loop though!
            if 'delta_t_orig' not in p:
                p['delta_t_orig'] = p['delta_t']
            p['delta_t'] = p['delta_t'] / 2.
            if p['delta_t_orig'] / p['delta_t'] > 9:
                raise
            hp, hc = _lalsim_td_waveform(**p)
            p['delta_t'] = p['delta_t_orig']
            hp = resample_to_delta_t(hp, hp.delta_t*2)
            hc = resample_to_delta_t(hc, hc.delta_t*2)
            return hp, hc
        raise

    #lal.DestroyDict(lal_pars)

    hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch)
    hc = TimeSeries(hc1.data.data[:], delta_t=hc1.deltaT, epoch=hc1.epoch)

    return hp, hc
示例#9
0
def _lalsim_td_waveform(**p):
    flags = lalsimulation.SimInspiralCreateWaveformFlags()
    lalsimulation.SimInspiralSetSpinOrder(flags, p['spin_order'])
    lalsimulation.SimInspiralSetTidalOrder(flags, p['tidal_order'])

    ###########
    def rulog2(val):
        return 2.0**numpy.ceil(numpy.log2(float(val)))

    f_final = rulog2(seobnrrom_final_frequency(**p))
    f_nyq = 0.5 / p['delta_t']
    if f_final > f_nyq:
        print 'Final frequecny {0} is greater than given nyquist frequecny {1}'.format(
            f_final, f_nyq)
        p['delta_t'] = 0.5 / f_final

    ##########

    if p['numrel_data']:
        lalsimulation.SimInspiralSetNumrelData(flags, str(p['numrel_data']))

    hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(
        float(p['coa_phase']), float(p['delta_t']),
        float(pnutils.solar_mass_to_kg(p['mass1'])),
        float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']),
        float(p['spin1y']), float(p['spin1z']), float(p['spin2x']),
        float(p['spin2y']), float(p['spin2z']), float(p['f_lower']),
        float(p['f_ref']), pnutils.megaparsecs_to_meters(float(p['distance'])),
        float(p['inclination']), float(p['lambda1']),
        float(p['lambda2']), flags, None, int(p['amplitude_order']),
        int(p['phase_order']), _lalsim_enum[p['approximant']])

    hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch)
    hc = TimeSeries(hc1.data.data[:], delta_t=hc1.deltaT, epoch=hc1.epoch)

    if f_final > f_nyq:
        p['delta_t'] = 0.5 / f_nyq
        print "Need to resample at delta_t {0}".format(p['delta_t'])
        hp = resample_to_delta_t(hp, p['delta_t'])
        hc = resample_to_delta_t(hc, p['delta_t'])

    return hp, hc
示例#10
0
def _lalsim_td_waveform(**p):
    flags = lalsimulation.SimInspiralCreateWaveformFlags()
    lalsimulation.SimInspiralSetSpinOrder(flags, p['spin_order'])
    lalsimulation.SimInspiralSetTidalOrder(flags, p['tidal_order'])

    hp, hc = lalsimulation.SimInspiralChooseTDWaveform(
        float(p['coa_phase']), float(p['delta_t']),
        float(pnutils.solar_mass_to_kg(p['mass1'])),
        float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']),
        float(p['spin1y']), float(p['spin1z']), float(p['spin2x']),
        float(p['spin2y']), float(p['spin2z']), float(p['f_lower']),
        float(p['f_ref']), pnutils.megaparsecs_to_meters(float(p['distance'])),
        float(p['inclination']), float(p['lambda1']),
        float(p['lambda2']), flags, None, int(p['amplitude_order']),
        int(p['phase_order']), _lalsim_enum[p['approximant']])

    hp = TimeSeries(hp.data.data[:] * 1, delta_t=hp.deltaT, epoch=hp.epoch)
    hc = TimeSeries(hc.data.data[:] * 1, delta_t=hc.deltaT, epoch=hc.epoch)

    return hp, hc
示例#11
0
def _lalsim_td_waveform(**p):
    lal_pars = _check_lal_pars(p)
    #nonGRparams can be straightforwardly added if needed, however they have to
    # be invoked one by one
    hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(
        float(pnutils.solar_mass_to_kg(p['mass1'])),
        float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']),
        float(p['spin1y']), float(p['spin1z']), float(p['spin2x']),
        float(p['spin2y']), float(p['spin2z']),
        pnutils.megaparsecs_to_meters(float(p['distance'])),
        float(p['inclination']), float(p['coa_phase']),
        float(p['long_asc_nodes']), float(p['eccentricity']),
        float(p['mean_per_ano']), float(p['delta_t']), float(p['f_lower']),
        float(p['f_ref']), lal_pars, _lalsim_enum[p['approximant']])
    #lal.DestroyDict(lal_pars)

    hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch)
    hc = TimeSeries(hc1.data.data[:], delta_t=hc1.deltaT, epoch=hc1.epoch)

    return hp, hc
示例#12
0
def generate_LAL_waveform(approximant, q, chiA0, chiB0, dt, M, \
    dist_mpc, f_low, f_ref, inclination=0, phi_ref=0., ellMax=None, \
    single_mode=None):

    distance = dist_mpc * 1.0e6 * PC_SI
    approxTag = lalsim.SimInspiralGetApproximantFromString(approximant)

    # component masses of the binary
    m1_kg = M * MSUN_SI * q / (1. + q)
    m2_kg = M * MSUN_SI / (1. + q)

    if single_mode is not None and ellMax is not None:
        raise Exception("Specify only one of single_mode or ellMax")

    dictParams = lal.CreateDict()
    # If ellMax, load all modes with ell<=ellMax
    if ellMax is not None:
        ma = lalsim.SimInspiralCreateModeArray()
        for ell in range(2, ellMax + 1):
            lalsim.SimInspiralModeArrayActivateAllModesAtL(ma, ell)
        lalsim.SimInspiralWaveformParamsInsertModeArray(dictParams, ma)
    elif single_mode is not None:
        # If a single_mode is given, load only that mode (l,m) and (l,-m)
        dictParams = set_single_mode(dictParams, single_mode[0],
                                     single_mode[1])

    hp, hc = lalsim.SimInspiralChooseTDWaveform(\
        m1_kg, m2_kg, chiA0[0], chiA0[1], chiA0[2], \
        chiB0[0], chiB0[1], chiB0[2], \
        distance, inclination, phi_ref, 0, 0, 0,\
        dt, f_low, f_ref, dictParams, approxTag)

    h = np.array(hp.data.data - 1.j * hc.data.data)
    t = dt * np.arange(len(h))

    return t, h
示例#13
0
    def time_domain_oscillatory(self,
                                delta_t=None,
                                modes=None,
                                inc=None,
                                phase=None):
        """
        Get the mode decomposition of the waveform approximant.

        Since the waveforms we consider only contain content about the
        ell=|m|=2 modes.
        We can therefore evaluate the waveform for a face-on system, where
        only the (2, 2) mode is non-zero.

        Parameters
        ----------
        delta_t: float, optional
            Time step for waveform.
        modes: list, optional
            List of modes to try to generate.
        inc: float, optional
            Inclination of the source, if None, the spherical harmonic modes
            will be returned.
        phase: float, optional
            Phase at coalescence of the source, if None, the spherical harmonic
            modes will be returned.

        Returns
        -------
        h_lm: dict
            Spin-weighted spherical harmonic decomposed waveform.
        times: np.array
            Times on which waveform is evaluated.
        """
        if self.h_lm is None:
            if modes is None:
                modes = self.available_modes
            else:
                modes = modes

            if not set(modes).issubset(self.available_modes):
                print('Requested {} unavailable modes'.format(' '.join(
                    set(modes).difference(self.available_modes))))
                modes = list(set(modes).union(self.available_modes))
                print('Using modes {}'.format(' '.join(modes)))

            fmin, fRef = 20, 20
            theta = 0.0
            phi = 0.0
            longAscNodes = 0.0
            eccentricity = 0.0
            meanPerAno = 0.0
            approx = lalsim.GetApproximantFromString(self.name)
            WFdict = None

            if delta_t is None:
                delta_t = 0.1 * (self.m1_SI + self.m2_SI) * utils.GG /\
                    utils.CC ** 3
            else:
                delta_t = delta_t

            hplus, hcross = lalsim.SimInspiralChooseTDWaveform(
                self.m1_SI, self.m2_SI, self.S1[0], self.S1[1], self.S1[2],
                self.S2[0], self.S2[1], self.S2[2], self.distance_SI, theta,
                phi, longAscNodes, eccentricity, meanPerAno, delta_t, fmin,
                fRef, WFdict, approx)

            h = hplus.data.data - 1j * hcross.data.data

            h_22 = h / harmonics.sYlm(-2, 2, 2, theta, phi)

            times = np.linspace(0, delta_t * len(h), len(h))
            times -= times[np.argmax(abs(h_22))]

            h_lm = {(2, 2): h_22, (2, -2): np.conjugate(h_22)}

        else:
            h_lm = self.h_lm
            times = self.times

        if inc is None or phase is None:
            return h_lm, times
        else:
            return combine_modes(h_lm, inc, phase), times
示例#14
0
def gen_test_data():
    """
    compute the difference between two waveforms
    and compare to expected value
    """

    common_pars = dict(m1=50 * lal.MSUN_SI,
                       m2=30 * lal.MSUN_SI,
                       s1x=0,
                       s1y=0,
                       s1z=-0.45,
                       s2x=0,
                       s2y=0,
                       s2z=0.98,
                       distance=1,
                       inclination=0.,
                       phiRef=0.,
                       longAscNodes=0.,
                       eccentricity=0.,
                       meanPerAno=0.,
                       deltaT=1. / 4096.,
                       f_min=30.,
                       f_ref=30.,
                       params=None,
                       approximant=lalsimulation.TEOBResumS)

    pars1 = common_pars.copy()
    pars2 = common_pars.copy()
    pars2.update({"m2": 20. * lal.MSUN_SI})

    hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(**pars1)
    hp2, hc2 = lalsimulation.SimInspiralChooseTDWaveform(**pars2)

    # compute amp and phase
    hp1_amp, hp1_phase = get_amp_phase(hp1.data.data)
    hc1_amp, hc1_phase = get_amp_phase(hc1.data.data)

    hp2_amp, hp2_phase = get_amp_phase(hp2.data.data)
    hc2_amp, hc2_phase = get_amp_phase(hc2.data.data)

    npeak1 = np.argmax(hp1_amp)
    npeak2 = np.argmax(hp2_amp)
    ni = min(npeak1, npeak2)
    no = min(hp1.data.length - npeak1, hp2.data.length - npeak2)

    # Truncate and align waveforms in place w.r.t. peak
    hp1_amp = hp1_amp[npeak1 - ni:npeak1 + no]
    hc1_amp = hc1_amp[npeak1 - ni:npeak1 + no]
    hp2_amp = hp2_amp[npeak2 - ni:npeak2 + no]
    hc2_amp = hc2_amp[npeak2 - ni:npeak2 + no]
    hp1_phase = hp1_phase[npeak1 - ni:npeak1 + no]
    hc1_phase = hc1_phase[npeak1 - ni:npeak1 + no]
    hp2_phase = hp2_phase[npeak2 - ni:npeak2 + no]
    hc2_phase = hc2_phase[npeak2 - ni:npeak2 + no]

    hp_amp_diff = sum_sqr_diff(hp1_amp, hp2_amp)
    hp_phase_diff = sum_sqr_diff(hp1_phase, hp2_phase)

    hc_amp_diff = sum_sqr_diff(hc1_amp, hc2_amp)
    hc_phase_diff = sum_sqr_diff(hc1_phase, hc2_phase)

    # since we want to compare decimals, we return the above quantities as 0.xxxxx..
    # by dividing them for their order of magnitude +1
    return hp_amp_diff / 1e6, hp_phase_diff / 1e3, hc_amp_diff / 1e6, hc_phase_diff / 1e3
示例#15
0
def gen_bbh(fs, T_obs, psd, isnr=1.0, det='H1', beta=[0.8, 1.0], par=None):
    """
    generates a BBH timedomain signal
    """
    N = T_obs * fs  # the total number of time samples
    dt = 1 / fs  # the sampling time (sec)
    f_low = 12.0  # lowest frequency of waveform (Hz)
    amplitude_order = 0
    phase_order = 7
    approximant = lalsimulation.IMRPhenomD
    dist = 1e6 * lal.PC_SI  # put it as 1 MPc

    # make waveform
    # loop until we have a long enough waveform - slowly reduce flow as needed
    flag = False
    while not flag:
        hp, hc = lalsimulation.SimInspiralChooseTDWaveform(
            par.m1 * lal.MSUN_SI, par.m2 * lal.MSUN_SI, 0, 0, 0, 0, 0,
            0, dist, par.iota, 0, 0, 0, 0, 1 / fs, f_low, f_low,
            lal.CreateDict(), approximant)
        flag = True if hp.data.length > 2 * N else False
        f_low -= 1  # decrease by 1 Hz each time
    hp = hp.data.data
    hc = hc.data.data

    # compute reference idx
    ref_idx = np.argmax(hp**2 + hc**2)

    # make signal - apply antenna and shifts
    ht_shift, hp_shift, hc_shift = make_bbh(hp, hc, fs, par.ra, par.dec,
                                            par.psi, det)

    # place signal into timeseries - including shift
    ts = np.zeros(N)
    hp = np.zeros(N)
    hc = np.zeros(N)
    ht_temp = ht_shift[int(ref_idx - par.idx):]
    hp_temp = hp_shift[int(ref_idx - par.idx):]
    hc_temp = hc_shift[int(ref_idx - par.idx):]
    if len(ht_temp) < N:
        ts[:len(ht_temp)] = ht_temp
        hp[:len(ht_temp)] = hp_temp
        hc[:len(ht_temp)] = hc_temp
    else:
        ts = ht_temp[:N]
        hp = hp_temp[:N]
        hc = hc_temp[:N]

    # the start index of the central region
    sidx = int(0.5 * fs * T_obs * (safe - 1.0) / safe)

    # apply aggressive window to cut out signal in central region
    # window is non-flat for 1/8 of desired Tobs
    # the window has dropped to 50% at the Tobs boundaries
    win = np.zeros(N)
    tempwin = tukey(int((16.0 / 15.0) * N / safe), alpha=1.0 / 8.0)
    win[int((N - tempwin.size) / 2):int((N - tempwin.size) / 2) +
        tempwin.size] = tempwin
    ts *= win
    hp *= win
    hc *= win

    # compute SNR of pre-whitened data
    intsnr = get_snr(ts, T_obs, fs, psd.data.data, par.fmin)

    # normalise the waveform using either integrated or peak SNR
    intsnr = np.array(intsnr)
    scale = isnr / intsnr
    ts *= scale
    hp *= scale
    hc *= scale
    intsnr *= scale
    print '{}: computed the network SNR = {}'.format(time.asctime(), isnr)

    return ts, hp, hc
示例#16
0
def generate_waveform(m1,
                      m2,
                      s1=0.,
                      s2=0.,
                      d=1.,
                      iota=0.,
                      phi_0=0.,
                      t_coal=0.4,
                      t_step=5e-5,
                      f_min=None,
                      t_min=None,
                      verbose=False,
                      approx="SEOBNRv2_opt"):
    """
generate_waveform
=================
	Wrapper to lalsimulation.SimInspiralChooseTDWaveform() to generate a single waveform. Wave is not preprocessed.
	Input:
		m1,m2,s1,s2,d,iota,phi_0	orbital parameters
		t_coal						approximate time to coalescence in reduced grid (ignored if f_min or t_min is set)
		t_step						EOB integration time to be given to lal
		f_min						starting frequency in Hz (if None, it will be determined by t_coal; ignored if t_min is set)
		t_min						starting time in s (if None, t_coal will be returned)
		verbose						whether to print messages for each wave...
	Output:
		times (D,)	times at which wave is evaluated
		h_p (N,D)	plus polarization of the wave
		h_c (N,D)	cross polarization of the wave
	"""
    import lal
    import lalsimulation as lalsim
    q = m1 / m2
    mtot = (m1 + m2)  #*lal.MTSUN_SI
    mc = (m1 * m2)**(3. / 5.) / (m1 + m2)**(1. / 5.)
    mc /= 1.21  #M_c / 1.21 M_sun

    if t_min is not None:
        f_min = .8 * ((151 * (t_min / mtot)**(-3. / 8.) *
                       (((1 + q)**2) / q)**(3. / 8.)) / mtot)

    if f_min is None:
        f_min = .9 * ((151 * (t_coal)**(-3. / 8.) *
                       (((1 + q)**2) / q)**(3. / 8.)) / mtot)

    if verbose:
        print("Generating wave @: ", m1, m2, s1, s2, d, iota, phi_0)

    hp, hc = lalsim.SimInspiralChooseTDWaveform(  #where is its definition and documentation????
        m1 * lalsim.lal.MSUN_SI,  #m1
        m2 * lalsim.lal.MSUN_SI,  #m2
        0.,
        0.,
        s1,  #spin vector 1
        0.,
        0.,
        s2,  #spin vector 2
        d * 1e6 * lalsim.lal.PC_SI,  #distance to source
        iota,  #inclination
        phi_0,  #phi
        0.,  #longAscNodes
        0.,  #eccentricity
        0.,  #meanPerAno
        t_step,  # time incremental step
        f_min,  # lowest value of freq
        f_min,  #some reference value of freq (??)
        lal.CreateDict(),  #some lal dictionary
        lalsim.GetApproximantFromString(approx)  #approx method for the model
    )
    h_p, h_c = hp.data.data, hc.data.data
    amp = np.sqrt(h_p**2 + h_c**2)
    #(indices, ) = np.where(amp!=0) #trimming zeros of amplitude
    #h_p = h_p[indices]
    #h_c = h_c[indices]

    times = np.linspace(0.0, h_p.shape[0] * t_step,
                        h_p.shape[0])  #time actually
    t_m = times[np.argmax(amp)]
    times = times - t_m

    if t_min is not None:
        arg = np.argmin(np.abs(times + t_min))
    else:
        arg = 0

    return times[arg:], h_p[arg:], h_c[arg:]
示例#17
0
def create_dataset_TD(N_data,
                      N_grid,
                      filename=None,
                      t_coal=0.5,
                      q_range=(1., 5.),
                      m2_range=None,
                      s1_range=(-0.8, 0.8),
                      s2_range=(-0.8, 0.8),
                      t_step=1e-5,
                      approximant="SEOBNRv2_opt",
                      alpha=0.35,
                      path_TEOBResumS=None):
    """
create_dataset_TD
=================
	Create a dataset for training a ML model to fit GW waveforms in time domain.
	The dataset consists in 3 parameters theta=(q, spin1z, spin2z) associated to the waveform computed in frequency domain for a grid of N_grid points in the range given by the user.
	More specifically, data are stored in 3 vectors:
		theta_vector	vector holding source parameters q, spin1, spin2
		amp_vector		vector holding amplitudes for each source evaluated at some N_grid equally spaced points
		ph_vector		vector holding phase for each source evaluated at some N_grid equally spaced points
	This routine add N_data data to filename if one is specified (if file is not empty it must contain data with the same N_grid); otherwise the datasets are returned as np vectors. 
	All the waves are evaluated at a constant distance of 1Mpc. Values of q and m2 as well as spins are drawn randomly in the range given by the user: it holds m1 = q *m2 M_sun.
	The waveforms are computed with a time step t_step; starting from a frequency f_min (set by the routine according to t_coal and m_tot). Waves are given in a rescaled time grid (i.e. t/m_tot) with N_grid points: t=0 occurs when at time of maximum amplitude. A higher density of grid points is placed in the post merger phase.
	Dataset can be generated either with a lal method (the approximant should be specified by the approximant keyword) either with an implementation of TEOBResumS (in this case a path to a local installation of TEOBResumS should be provided). If lal is used, lalsuite package shall be installed (note that lalsuite is not a prerequisite for mlgw)
	Dataset can be loaded with load_dataset.
	Input:
		N_data				size of dataset
		N_grid				number of grid points to evaluate
		filename			name of the file to save dataset in (If is None, nothing is saved on a file)
		t_coal				time to coalescence to start computation from (measured in reduced grid)
		q_range				tuple with range for random q values. if single value, q is kept fixed at that value
		m2_range			tuple with range for random m2 values. if single value, m2 is kept fixed at that value. If None, m2 will be chosen s.t. m_tot = m1+m2 = 20. M_sun
		spin_mag_max_1		tuple with range for random spin #1 values. if single value, s1 is kept fixed at that value
		spin_mag_max_2		tuple with range for random spin #1 values. if single value, s2 is kept fixed at that value
		t_step				time step to generate the wave with
		approximant			string for the approximant model to be used (in lal convention; to be used only if lal ought to be used)
		alpha				distorsion factor for time grid. (In range (0,1], when it's close to 0, more grid points are around merger)
		path_TEOBResumS		path to a local installation of TEOBResumS with routine 'EOBRun_module' (if given, it overwrites the aprroximant entry)
	Output:
		if filename is given
			None
		if filename is not given
			theta_vector (N_data,3)		vector holding ordered set of parameters used to generate amp_dataset and ph_dataset
			amp_dataset (N_data,N_grid)	dataset with amplitudes
			ph_dataset (N_data,N_grid)	dataset with phases
			times (N_grid,)				vector holding times at which waves are evaluated (t=0 is the time of maximum amplitude)
	"""
    d = 1.
    inclination = 0.  #np.pi/2.

    if path_TEOBResumS is not None:
        approximant = "TEOBResumS"

    if approximant == "TEOBResumS":
        #see https://bitbucket.org/eob_ihes/teobresums/src/development/ for the implementation of TEOBResumS
        try:
            import sys
            sys.path.append(
                path_TEOBResumS)  #path to local installation of TEOBResumS
            import EOBRun_module
        except:
            raise RuntimeError(
                "No valid imput source for module 'EOBRun_module' for TEOBResumS. Unable to continue."
            )
    else:
        try:
            import lal
            import lalsimulation as lalsim
        except:
            raise RuntimeError(
                "Impossible to load lalsimulation: try pip install lalsuite")
        LALpars = lal.CreateDict()
        approx = lalsim.SimInspiralGetApproximantFromString(approximant)

        #checking if N_grid is fine
    if not isinstance(N_grid, int):
        raise TypeError("N_grid is " + str(type(N_grid)) +
                        "! Expected to be a int.")

    if isinstance(m2_range, tuple):
        D_theta = 4  #m2 must be included as a feature
    else:
        D_theta = 3

        #creating time_grid
    t_end = 5.2e-4  #estimated maximum time for ringdown: WF will be killed after that time
    #t_end = 6e-5 #ONLY FOR mode = 3 (very ugly here...)
    time_grid = np.linspace(-np.power(np.abs(t_coal), alpha),
                            np.power(t_end, alpha), N_grid)
    time_grid = np.multiply(np.sign(time_grid),
                            np.power(np.abs(time_grid), 1. / alpha))

    #adding 0 to time grid
    index_0 = np.argmin(np.abs(time_grid))
    time_grid[index_0] = 0.  #0 is alway set in the grid

    #setting t_coal_freq for generating a waves
    if np.abs(t_coal) < 0.05:
        t_coal_freq = 0.05
    else:
        t_coal_freq = np.abs(t_coal)

    if filename is not None:  #doing header if file is empty - nothing otherwise
        if not os.path.isfile(
                filename
        ):  #file doesn't exist: must be created with proper header
            filebuff = open(filename, 'w')
            print("New file ", filename, " created")
            freq_header = np.concatenate((np.zeros(
                (3, )), time_grid, time_grid))
            freq_header = np.reshape(freq_header, (1, len(freq_header)))
            np.savetxt(filebuff,
                       freq_header,
                       header="# row: theta " + str(D_theta) + " | amp (1," +
                       str(N_grid) + ")| ph (1," + str(N_grid) +
                       ")\n# N_grid = " + str(N_grid) + " | t_coal =" +
                       str(t_coal) + " | t_step =" + str(t_step) +
                       " | q_range = " + str(q_range) + " | m2_range = " +
                       str(m2_range) + " | s1_range = " + str(s1_range) +
                       " | s2_range = " + str(s2_range),
                       newline='\n')
        else:
            filebuff = open(filename, 'a')

    if filename is None:
        amp_dataset = np.zeros(
            (N_data, N_grid))  #allocating storage for returning data
        ph_dataset = np.zeros((N_data, N_grid))
        theta_vector = np.zeros((N_data, D_theta))

    for i in range(N_data):  #loop on data to be created
        if i % 50 == 0 and i != 0:
            #if i%1 == 0 and i != 0: #debug
            print("Generated WF ", i)

            #setting value for data
        if isinstance(m2_range, tuple):
            m2 = np.random.uniform(m2_range[0], m2_range[1])
        elif m2_range is not None:
            m2 = float(m2_range)
        if isinstance(q_range, tuple):
            q = np.random.uniform(q_range[0], q_range[1])
        else:
            q = float(q_range)
        if isinstance(s1_range, tuple):
            spin1z = np.random.uniform(s1_range[0], s1_range[1])
        else:
            spin1z = float(s1_range)
        if isinstance(s2_range, tuple):
            spin2z = np.random.uniform(s2_range[0], s2_range[1])
        else:
            spin2z = float(s2_range)

        if m2_range is None:
            m2 = 20. / (1 + q)
            m1 = q * m2
        else:
            m1 = q * m2

            #computing f_min
        f_min = .9 * ((151 * (t_coal_freq)**(-3. / 8.) *
                       (((1 + q)**2) / q)**(3. / 8.)) / (m1 + m2))
        #in () there is the right scaling formula for frequency in order to get always the right reduced time
        #this should be multiplied by a prefactor (~1) for dealing with some small variation due to spins

        #getting the wave
        if approximant != "TEOBResumS":  #using lal to create WFs
            hptilde, hctilde = lalsim.SimInspiralChooseTDWaveform(  #where is its definition and documentation????
                m1 * lalsim.lal.MSUN_SI,  #m1
                m2 * lalsim.lal.MSUN_SI,  #m2
                0.,
                0.,
                spin1z,  #spin vector 1
                0.,
                0.,
                spin2z,  #spin vector 2
                d * 1e6 * lalsim.lal.PC_SI,  #distance to source
                inclination,  #inclination
                0.,  #phi ref
                0.,  #longAscNodes
                0.,  #eccentricity
                0.,  #meanPerAno
                t_step,  # time incremental step
                f_min,  # lowest value of time
                f_min,  #some reference value of time (??)
                lal.CreateDict(),  #some lal dictionary
                approx  #approx method for the model
            )
            #print(f_min, t_step)#debug
            #print(m1,m2, spin1z,spin2z) #debug

            h_p, h_c = np.array(hptilde.data.data), np.array(
                hctilde.data.data)  #complex waveform
            time_full = np.linspace(
                0.0, hptilde.data.length * t_step,
                hptilde.data.length)  #time grid at which wave is computed

        if approximant == "TEOBResumS":  #using TEOBResumS
            mode = 1
            pars = {
                'M': m1 + m2,
                'q': m1 / m2,
                'Lambda1': 0.,
                'Lambda2': 0.,
                'chi1': spin1z,
                'chi2': spin2z,
                'domain': 0,  # TD
                'arg_out': 0,  # Output hlm/hflm. Default = 0
                'use_mode_lm':
                [mode],  # List of modes to use/output through EOBRunPy
                'srate_interp':
                1. / t_step,  # srate at which to interpolate. Default = 4096.
                'use_geometric_units':
                0,  # Output quantities in geometric units. Default = 1
                'initial_frequency':
                f_min,  # in Hz if use_geometric_units = 0, else in geometric units
                'interp_uniform_grid':
                2,  # Interpolate mode by mode on a uniform grid. Default = 0 (no interpolation)
                'distance': d,
                'inclination': inclination,
                #'nqc':2, #{"no", "auto", "manual"}
                #'nqc_coefs_flx': 2, # {"none", "nrfit_nospin20160209", "fit_spin_202002", "fromfile"}
                #'nqc_coefs_hlm':0
            }
            if mode != 1:
                warnings.warn("Using non dominant mode " + str(mode))
            time_full, h_p, h_c = EOBRun_module.EOBRunPy(pars)

        if isinstance(m2_range, tuple):
            temp_theta = [m1, m2, spin1z, spin2z]
        else:
            temp_theta = [m1 / m2, spin1z, spin2z]

        temp_amp = np.sqrt(np.square(h_p) + np.square(h_c))
        temp_ph = np.unwrap(np.arctan2(h_c, h_p))

        time_full = (time_full - time_full[np.argmax(temp_amp)]) / (
            m1 + m2)  #grid is scaled to standard grid
        #setting waves to the chosen std grid
        temp_amp = np.interp(time_grid, time_full, temp_amp)
        temp_ph = np.interp(time_grid, time_full, temp_ph)

        #here you need to decide what is better
        #temp_ph = temp_ph - temp_ph[0] #all phases are shifted by a constant to make every wave start with 0 phase
        id0 = np.where(time_grid == 0)[0]
        temp_ph = temp_ph - temp_ph[
            id0]  #all phases are shifted by a constant to make every wave start with 0 phase at t=0 (i.e. at maximum amplitude)

        #removing spourious gaps (if present) (do I need it??)
        (index, ) = np.where(
            temp_amp / np.max(temp_amp) <
            1e-10)  #there should be a way to choose the right threshold...
        if len(index) > 0:
            #print("Wave killed")
            temp_amp[index] = 0  #temp_amp[index[0]-1]
            temp_ph[index] = temp_ph[index[0] - 1]

        if filename is None:
            amp_dataset[
                i, :] = temp_amp  #putting waveform in the dataset to return
            ph_dataset[i, :] = temp_ph  #phase
            theta_vector[i, :] = temp_theta

        if filename is not None:  #saving to file
            to_save = np.concatenate((temp_theta, temp_amp, temp_ph))
            to_save = np.reshape(to_save, (1, len(to_save)))
            np.savetxt(filebuff, to_save)

    if filename is None:
        return theta_vector, amp_dataset.real, ph_dataset.real, time_grid
    else:
        filebuff.close()
        return None
示例#18
0
# add what we need
p = default_args
p['mass1']=10.
p['mass2']=10.
p['delta_t'] = 1./4096
p['f_lower'] = 40.
p['approximant']='IMRPhenomD'
lal_pars = _check_lal_pars(p)

# make the waveform
hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(
                float(pnutils.solar_mass_to_kg(p['mass1'])),
                float(pnutils.solar_mass_to_kg(p['mass2'])),
                float(p['spin1x']), float(p['spin1y']), float(p['spin1z']),
                float(p['spin2x']), float(p['spin2y']), float(p['spin2z']),
                pnutils.megaparsecs_to_meters(float(p['distance'])),
                float(p['inclination']), float(p['coa_phase']),
                float(p['long_asc_nodes']), float(p['eccentricity']), float(p['mean_per_ano']),
                float(p['delta_t']), float(p['f_lower']), float(p['f_ref']),
                lal_pars,
                _lalsim_enum[p['approximant']])

hp = TimeSeries(hp1.data.data[:], delta_t=hp1.deltaT, epoch=hp1.epoch)
'''
p['dchi0'] = 1
lal_pars = _check_lal_pars(p)
sp1, sc1 = lalsimulation.SimInspiralChooseTDWaveform(
                float(pnutils.solar_mass_to_kg(p['mass1'])),
                float(pnutils.solar_mass_to_kg(p['mass2'])),
                float(p['spin1x']), float(p['spin1y']), float(p['spin1z']),
                float(p['spin2x']), float(p['spin2y']), float(p['spin2z']),
示例#19
0
def generate_waveform(m1, m2, s1=0.):
    q = m1 / m2
    mtot = (m1 + m2)  #*lal.MTSUN_SI
    mc = (m1 * m2)**(3. / 5.) / (m1 + m2)**(1. / 5.)
    mc /= 1.21  #M_c / 1.21 M_sun
    print(m1, m2, mc, mtot)
    print(mc**(-5. / 8.) * mtot**(-3. / 8.),
          (((1 + q)**2) / q)**(3. / 8.) / mtot)

    #	f_min = 134 * mc **(-5./8.)*(1.2)**(-3./8.) * mtot**(-3.8)
    f_min = .9 * ((151 * (.25)**(-3. / 8.) *
                   (((1 + q)**2) / q)**(3. / 8.)) / mtot)
    #in () there is the right scaling formula for frequency in order to get always the right reduced time
    #it should be multiplied by a prefactor for dealing with some small variation in spin
    #sounds like a good choice... and also it is able to reduce erorrs in phase reconstruction
    print(f_min)

    hptilde, hctilde = lalsim.SimInspiralChooseTDWaveform(  #where is its definition and documentation????
        m1 * lalsim.lal.MSUN_SI,  #m1
        m2 * lalsim.lal.MSUN_SI,  #m2
        0.,
        0.,
        s1,  #spin vector 1
        0.,
        0.,
        0.,  #spin vector 2
        1. * 1e6 * lalsim.lal.PC_SI,  #distance to source
        0.,  #inclination
        0.,  #phi ref
        0.,  #longAscNodes
        0.,  #eccentricity
        0.,  #meanPerAno
        5e-5,  # time incremental step
        f_min,  # lowest value of freq
        f_min,  #some reference value of freq (??)
        lal.CreateDict(),  #some lal dictionary
        #		lalsim.GetApproximantFromString('IMRPHenomPv2') #approx method for the model
        lalsim.GetApproximantFromString('SEOBNRv2_opt'
                                        )  #approx method for the model
    )

    h = (hptilde.data.data + 1j * hctilde.data.data)
    (indices, ) = np.where(np.abs(h) != 0)  #trimming zeros of amplitude
    h = h[indices]

    time_full = np.linspace(0.0, h.shape[0] * 5e-5, h.shape[0])  #time actually
    t_m = time_full[np.argmax(np.abs(h))]
    time_full = time_full - t_m  #[-???,??]

    #building a proper time grid
    split_point = -0.01
    time = np.hstack(
        (np.linspace(time_full[0], split_point,
                     3000), np.linspace(split_point, time_full[-1], 1500)))
    #time = time_full

    #time_pos = np.logspace(np.log10(1e-2), np.log10(np.max(time_full)), 1000)
    #time_neg = np.flip(-np.logspace(np.log10(1e-2), np.log10(-np.min(time_full)), 4000))
    #time = np.hstack((time_neg,time_pos))

    #print("time neg/pos: ",time_neg,time_pos)
    #print(time_full, time)

    #time = np.linspace(hptilde.data.length*0.9, hptilde.data.length, hptilde.data.length*.1) #time actually
    rescaled_time = time / mtot
    amp = np.abs(h)
    ph = np.unwrap(np.angle(h))
    amp = np.interp(time, time_full, amp)
    ph = np.interp(time, time_full, ph)
    ph = ph - ph[
        0]  #is it fine to shift waves at will?? Can I do this or am I losing some physical informations?? (this is the purpose of phi_ref!!!!)

    h = amp * np.exp(1j * ph)
    #	return  time, rescaled_time, h
    return time, rescaled_time, amp, ph
def spin_tidal_eob(m1,
                   m2,
                   s1z,
                   s2z,
                   lambda1,
                   lambda2,
                   f_min,
                   delta_t=1.0 / 16384.0,
                   distance=1.0,
                   inclination=0.0,
                   approximant='SEOBNRv4T',
                   verbose=True):
    """EOB waveform with aligned spin and tidal interactions. 
    l=3 tidal interaction and l=2,3 f-mode calculated with universal relations.
    
    Parameters
    ----------
    approximant : 'TEOBv2' or 'TEOBv4' or the new names 'SEOBNRv2T' or 'SEOBNRv4T'.
        Based on the inspiral model given by 'SEOBNRv2' or 'SEOBNRv4'.
    
    Returns
    -------
    Waveform object
    """
    # print m1, m2, s1z, s2z, lambda1, lambda2, f_min, delta_t, distance, inclination
    f_ref = 0.
    phiRef = 0.

    # Must have aligned spin
    s1x, s1y, s2x, s2y = 0., 0., 0., 0.

    # Eccentricity is not part of the model
    longAscNodes = 0.
    eccentricity = 0.
    meanPerAno = 0.

    # Set the EOB approximant
    if (approximant not in ['TEOBv2', 'TEOBv4', 'SEOBNRv2T', 'SEOBNRv4T']):
        raise Exception, "Approximant must be 'TEOBv2' or 'TEOBv4' or 'SEOBNRv2T' or 'SEOBNRv4T'."
    lal_approx = LS.GetApproximantFromString(approximant)

    # Insert matter parameters
    lal_params = lal.CreateDict()
    LS.SimInspiralWaveformParamsInsertTidalLambda1(lal_params, lambda1)
    LS.SimInspiralWaveformParamsInsertTidalLambda2(lal_params, lambda2)

    if verbose:
        ap = LS.GetStringFromApproximant(lal_approx)
        L2A = LS.SimInspiralWaveformParamsLookupTidalLambda1(lal_params)
        L2B = LS.SimInspiralWaveformParamsLookupTidalLambda2(lal_params)
        L3A = LS.SimInspiralWaveformParamsLookupTidalOctupolarLambda1(
            lal_params)
        L3B = LS.SimInspiralWaveformParamsLookupTidalOctupolarLambda2(
            lal_params)
        w2A = LS.SimInspiralWaveformParamsLookupTidalQuadrupolarFMode1(
            lal_params)
        w2B = LS.SimInspiralWaveformParamsLookupTidalQuadrupolarFMode2(
            lal_params)
        w3A = LS.SimInspiralWaveformParamsLookupTidalOctupolarFMode1(
            lal_params)
        w3B = LS.SimInspiralWaveformParamsLookupTidalOctupolarFMode2(
            lal_params)
        print 'Approximant: ' + str(ap)
        print 'm1={:.2f}, m2={:.2f}'.format(m1, m2)
        print 's1z={:.2f}, s2z={:.2f}'.format(s1z, s2z)
        print 'delta_t={:.6f}, 1/delta_t={:.5}, f_min={:.2f}'.format(
            delta_t, 1. / delta_t, f_min)
        print 'L2A, L2B, L3A, L3B, w2A, w2B, w3A, w3B:'
        print '{:.1f}, {:.1f}, {:.1f}, {:.1f}, {:.4f}, {:.4f}, {:.4f}, {:.4f}'.format(
            L2A, L2B, L3A, L3B, w2A, w2B, w3A, w3B)
        sys.stdout.flush()

    # Evaluate waveform
    hp, hc = LS.SimInspiralChooseTDWaveform(m1 * lal.MSUN_SI, m2 * lal.MSUN_SI,
                                            s1x, s1y, s1z, s2x, s2y, s2z,
                                            distance * lal.PC_SI, inclination,
                                            phiRef, longAscNodes, eccentricity,
                                            meanPerAno, delta_t, f_min, f_ref,
                                            lal_params, lal_approx)

    # Extract time array from lalsimulation's structures
    tstart = hp.epoch.gpsSeconds + hp.epoch.gpsNanoSeconds * 1.0e-9
    ts = tstart + hp.deltaT * np.arange(hp.data.length)

    return ts, hp.data.data, hc.data.data
        phi = sim_inspiral.coa_phase
        psi = sim_inspiral.polarization
        end_time = lal.LIGOTimeGPS(sim_inspiral.geocent_end_time, sim_inspiral.geocent_end_time_ns)
        epoch = end_time - 256 # GPS start time of data
        gmst = lal.GreenwichMeanSiderealTime(end_time)
        approximant, amplitude_order, phase_order = timing.get_approximant_and_orders_from_string(sim_inspiral.waveform)
        if approximant != lalsimulation.TaylorT4:
            raise ValueError("unrecognized approximant")

        # Generate injection
        hplus, hcross = lalsimulation.SimInspiralChooseTDWaveform(
            phi, 1 / sample_rate,
            mass1 * lal.MSUN_SI, mass2 * lal.MSUN_SI,
            spin1x, spin1y, spin1z, spin2x, spin2y, spin2z,
            f_low, f_low,
            DL * 1e6 * lal.PC_SI,
            inc, 0, 0,
            None, None,
            amplitude_order,
            phase_order,
            approximant)
        hplus.epoch += end_time
        hcross.epoch += end_time

    # Realize detector noise and add injection
    data = [inject(hplus, hcross, ifo, psd) for ifo, psd in zip(opts.detector, psds)]

    net_snr, sngl_inspirals = max(detect_net_snr_and_sngls(opts.detector, data, horizons, templates) for templates, horizons in zip(template_bank, horizons_bank))

    # If too few triggers were found, then skip this event.
    if len(sngl_inspirals) < opts.min_triggers:
示例#22
0
def create_dataset_TD(N_data, N_grid, modes, basefilename,  t_coal = 0.5, q_range = (1.,5.), m2_range = None, s1_range = (-0.8,0.8), s2_range = (-0.8,0.8), t_step = 1e-5, alpha = 0.35, approximant = "SEOBNRv2_opt", path_TEOBResumS = None):
	"""
create_dataset_TD
=================
	Create datasets for training a ML model to fit GW modes in time domain. Each dataset is saved in a different file (basefilename.mode).
	The dataset consists in 3 parameters theta=(q, spin1z, spin2z) associated to the modes computed in time domain for a grid of N_grid points in the range given by the user.
	More specifically, data are stored in 3 vectors:
		theta_vector	vector holding source parameters q, spin1, spin2
		amp_vector		vector holding amplitudes for each source evaluated at some discrete grid points
		ph_vector		vector holding phase for each source evaluated at some discrete grid points
	This routine add N_data data to filename if one is specified (if file is not empty it must contain data with the same N_grid); otherwise the datasets are returned as np vectors. 
	Values of q and m2 as well as spins are drawn randomly in the range given by the user: it holds m1 = q *m2 M_sun.
	The waveforms are computed with a time step t_step; starting from a time in reduced grid tau min (s/M_Sun). Waves are given in a rescaled time grid (i.e. t/m_tot) with N_grid points: t=0 occurs when the 22 mode has a peak. A higher density of grid points is placed close to the merger.
	Dataset is generated either with an implementation of TEOBResumS (a path to a local installation of TEOBResumS should be provided) either with SEOBNRv4HM (lalsuite installation required). It can be given an TD lal approximant with no HM; in this case, only the 22 mode can be generated.
	Datasets can be loaded with load_dataset.
	Input:
		N_data				size of dataset
		N_grid				number of grid points to evaluate
		modes []			list of modes (each a (l,m) tuple) to generate and fill the dataset with				
		basefilename		basename of the file to save dataset in (each dataset is saved in basefilename.lm)
		t_coal				time to coalescence to start computation from (measured in reduced grid)
		q_range				tuple with range for random q values. if single value, q is kept fixed at that value
		m2_range			tuple with range for random m2 values. if single value, m2 is kept fixed at that value. If None, m2 will be chosen s.t. m_tot = m1+m2 = 20. M_sun
		spin_mag_max_1		tuple with range for random spin #1 values. if single value, s1 is kept fixed at that value
		spin_mag_max_2		tuple with range for random spin #1 values. if single value, s2 is kept fixed at that value
		t_step				time step to generate the wave with
		approximant			string for the approximant model to be used (in lal convention; to be used only if lal is to be used)
		alpha				distorsion factor for time grid. (In range (0,1], when it's close to 0, more grid points are around merger)
		approximant			lal approximant to be used for generating the modes, or "TEOBResumS" (in the latter case a local installation must be provided by the argument path_TEOBResumS) 
		path_TEOBResumS		path to a local installation of TEOBResumS with routine 'EOBRun_module' (if given, it overwrites the aproximant entry)
	"""
		#imports
	if path_TEOBResumS is not None:
		approximant = "TEOBResumS"

	if isinstance(modes,tuple):
		modes = [modes]
	if not isinstance(modes,list):
		raise TypeError("Wrong kind of mode {} given. Expected a list [(l,m)]".format(modes))

	if approximant == "TEOBResumS":
		#see https://bitbucket.org/eob_ihes/teobresums/src/development/ for the implementation of TEOBResumS
		try:
			import sys
			sys.path.append(path_TEOBResumS) #path to local installation of TEOBResumS
			import EOBRun_module
		except:
			raise RuntimeError("No valid imput source for module 'EOBRun_module' for TEOBResumS. Unable to continue.")
	else:
		try:
			import lal
			import lalsimulation as lalsim
		except:
			raise RuntimeError("Impossible to load lalsimulation: try pip install lalsuite")
		LALpars = lal.CreateDict()
		approx = lalsim.SimInspiralGetApproximantFromString(approximant)
		prefactor = 4.7864188273360336e-20 # G/c^2*(M_sun/Mpc)

			#checking that all is good with modes
		if approximant == "SEOBNRv4HM":
			for mode in modes:
				if mode not in [(2,2),(2,1), (3,3), (4,4), (5,5)]:
					raise ValueError("Currently SEOBNRv4HM approximants do not implement the chosen HM")
		else:
			if modes != [(2,2)]:
				raise ValueError("The chosen lal approximant does not implement HMs")

		

		#checking if N_grid is fine
	if not isinstance(N_grid, int):
		raise TypeError("N_grid is "+str(type(N_grid))+"! Expected to be a int.")

	if isinstance(m2_range, tuple):
		D_theta = 4 #m2 must be included as a feature
	else:
		D_theta = 3

		######setting the time grid
	time_grid_list = []
	t_end_list = []
	if approximant == "TEOBResumS":
		modes_to_k = lambda modes:[int(x[0]*(x[0]-1)/2 + x[1]-2) for x in modes] # [(l,m)] -> [k]
		k_modes = modes_to_k(modes)
			#setting a list of time grids
		for mode in modes:
				#ugly setting of t_end in TEOBResumS: required to kill bad features after merger
			if mode == (2,2):
				t_end = 5.2e-4 #estimated maximum time for ringdown: WF will be killed after that time
			elif mode == (2,1) or mode == (3,3): #special treatment for 21 and 33
				t_end = 1e-6
			else:
				t_end = 3e-5 #for other modes
			t_end_list.append(t_end)
	else:
		for mode in modes:
			t_end_list.append(5.2e-4)

	print("Generating modes: "+str(modes))

		#creating time_grid
	for i,mode in enumerate(modes):
		time_grid = np.linspace(-np.power(np.abs(t_coal), alpha), np.power(t_end_list[i], alpha), N_grid)
		time_grid = np.multiply( np.sign(time_grid) , np.power(np.abs(time_grid), 1./alpha))

			#adding 0 to time grid
		index_0 = np.argmin(np.abs(time_grid))
		time_grid[index_0] = 0. #0 is alway set in the grid

		time_grid_list.append(time_grid)

		#setting t_coal_freq for generating a waves
	if np.abs(t_coal) < 0.05:
		t_coal_freq = 0.05
	else:
		t_coal_freq = np.abs(t_coal)


		#####create a list of buffer to save the WFs
	buff_list = []
	for i, mode in enumerate(modes):
		filename = basefilename+'.'+str(mode[0])+str(mode[1])
		if not os.path.isfile(filename): #file doesn't exist: must be created with proper header
			filebuff = open(filename,'w')
			print("New file ", filename, " created")
			time_header = np.concatenate((np.zeros((3,)), time_grid_list[i], time_grid_list[i]) )[None,:]
			np.savetxt(filebuff, time_header, header = "#Mode:"+ str(mode[0])+str(mode[1]) +"\n# row: theta "+str(D_theta)+" | amp (None,"+str(N_grid)+")| ph (None,"+str(N_grid)+")\n# N_grid = "+str(N_grid)+" | t_coal ="+str(t_coal)+" | t_step ="+str(t_step)+" | q_range = "+str(q_range)+" | m2_range = "+str(m2_range)+" | s1_range = "+str(s1_range)+" | s2_range = "+str(s2_range), newline = '\n')
		else:
			filebuff = open(filename,'a')
		buff_list.append(filebuff)

		#####creating WFs
	for n_WF in range(N_data): 
			#setting value for data
		if isinstance(m2_range, tuple):
			m2 = np.random.uniform(m2_range[0],m2_range[1])
		elif m2_range is not None:
			m2 = float(m2_range)
		if isinstance(q_range, tuple):
			q = np.random.uniform(q_range[0],q_range[1])
		else:
			q = float(q_range)
		if isinstance(s1_range, tuple):
			spin1z = np.random.uniform(s1_range[0],s1_range[1])
		else:
			spin1z = float(s1_range)
		if isinstance(s2_range, tuple):
			spin2z = np.random.uniform(s2_range[0],s2_range[1])
		else:
			spin2z = float(s2_range)

		if m2_range is None:
			m2 = 20. / (1+q)
			m1 = q * m2
		else:
			m1 = q* m2
		nu = np.divide(q, np.square(1+q)) #symmetric mass ratio

			#computing f_min
		f_min = .9* ((151*(t_coal_freq)**(-3./8.) * (((1+q)**2)/q)**(3./8.))/(m1+m2))
		 #in () there is the right scaling formula for frequency in order to get always the right reduced time
		 #this should be multiplied by a prefactor (~1) for dealing with some small variation due to spins

		if isinstance(m2_range, tuple):
			temp_theta = [m1, m2, spin1z, spin2z]		
		else:
			temp_theta = [m1/m2, spin1z, spin2z]

			#getting the wave
			#output of the if:
				#amp_list, ph_list (same order as in modes)
				#time_full, argpeak
		amp_list, ph_list = [None for i in range(len(modes))],[None for i in range(len(modes))]
		if approximant == "TEOBResumS": #using TEOBResumS
			pars = {
				'M'                  : m1+m2,
				'q'                  : m1/m2,
				'Lambda1'            : 0.,
				'Lambda2'            : 0.,     
				'chi1'               : spin1z,
				'chi2'               : spin2z,
				'domain'             : 0,      # TD
				'arg_out'            : 1,      # Output hlm/hflm. Default = 0
				'use_mode_lm'        : list(set(k_modes + [1])),      # List of modes to use/output through EOBRunPy (added 22 mode in case there isn't)
				#'srate_interp'       : 1./t_step,  # srate at which to interpolate. Default = 4096.
				'use_geometric_units': 0,      # Output quantities in geometric units. Default = 1
				'initial_frequency'  : f_min,   # in Hz if use_geometric_units = 0, else in geometric units
				'interp_uniform_grid': 0,      # Interpolate mode by mode on a uniform grid. Default = 0 (no interpolation)
				'distance': 1.,
				'inclination':0.,
			}
			time_full, h_p, h_c, hlm = EOBRun_module.EOBRunPy(pars)
			for i, k_mode in enumerate(k_modes):
				temp_amp = hlm[str(k_mode)][0]*nu #TEOBResumS has weird conventions on the modes
				temp_ph = hlm[str(k_mode)][1]
				amp_list[i] = temp_amp
				ph_list[i] = temp_ph
			argpeak = locate_peak(hlm['1'][0]*nu) #aligned at the peak of the 22

		elif approximant == "SEOBNRv4HM": #using SEOBNRv4HM
			nqcCoeffsInput=lal.CreateREAL8Vector(10)
			sp, dyn, dynHi = lalsim.SimIMRSpinAlignedEOBModes(t_step, m1*lal.MSUN_SI, m2*lal.MSUN_SI, f_min, 1e6*lal.PC_SI, spin1z, spin2z,41, 0., 0., 0.,0.,0.,0.,0.,0.,1.,1.,nqcCoeffsInput, 0)
			amp_prefactor = prefactor*(m1+m2)/1. # G/c^2 (M / d_L)
			while sp is not None:
				lm = (sp.l, sp.m)
				if lm not in modes: #skipping a non-necessary mode
					continue
				else: #computing index and saving the mode
					i = modes.index(lm)
					hlm = sp.mode.data.data #complex mode vector
					temp_amp = np.abs(hlm)/ amp_prefactor / nu #scaling with the convention of SEOB
					temp_ph = np.unwrap(np.angle(hlm))
					amp_list[i] = temp_amp
					ph_list[i] = temp_ph

				if (sp.l, sp.m) == (2,2): #get grid
					amp_22 = np.abs(sp.mode.data.data) #amp of 22 mode (for time grid alignment)
					time_full = np.linspace(0.0, sp.mode.data.length*t_step, sp.mode.data.length) #time grid at which wave is computed
					argpeak = locate_peak(amp_22) #aligned at the peak of the 22
				sp = sp.next

		else: #another lal approximant (only 22 mode)
			hp, hc = lalsim.SimInspiralChooseTDWaveform( #where is its definition and documentation????
				m1*lalsim.lal.MSUN_SI, #m1
				m2*lalsim.lal.MSUN_SI, #m2
				0., 0., spin1z, #spin vector 1
				0., 0., spin2z, #spin vector 2
				1e6*lalsim.lal.PC_SI, #distance to source
				0., #inclination
				0., #phi
				0., #longAscNodes
				0., #eccentricity
				0., #meanPerAno
				t_step, # time incremental step
				f_min, # lowest value of freq
				f_min, #some reference value of freq (??)
				LALpars, #some lal dictionary
				approx #approx method for the model
			)
			h_p, h_c =  hp.data.data, hc.data.data
			time_full = np.linspace(0.0, hp.data.length*t_step, hp.data.length) #time grid at which wave is computed
			amp_prefactor = prefactor*(m1+m2)/1. # G/c^2 (M / d_L)
			temp_amp = np.sqrt(np.square(h_p)+np.square(h_c)) / amp_prefactor / (4*np.sqrt(5/(64*np.pi)))
			temp_ph = np.unwrap(np.arctan2(h_c,h_p))
			amp_list = [temp_amp]
			ph_list = [temp_ph]
			argpeak = locate_peak(temp_amp) #aligned at the peak of the 22

			#setting time grid
		t_peak = time_full[argpeak]
		time_full = (time_full - t_peak)/(m1+m2) #grid is scaled to standard grid

			#computing waves to the chosen std grid and saving to file
		for i in range(len(amp_list)):
			temp_amp, temp_ph = amp_list[i], ph_list[i]
			#print(temp_amp.shape, time_full.shape, time_grid_list[i].shape)
			temp_amp = np.interp(time_grid_list[i], time_full, temp_amp)
			temp_ph = np.interp(time_grid_list[i], time_full, temp_ph)
			temp_ph = temp_ph - temp_ph[0] #all phases are shifted by a constant to make sure every wave has 0 phase at beginning of grid

			to_save = np.concatenate((temp_theta, temp_amp, temp_ph))[None,:] #(1,D)
			np.savetxt(buff_list[i], to_save)

			#user communication
		if n_WF%100 == 0 and n_WF != 0:
		#if n_WF%1 == 0 and n_WF != 0: #debug
			print("Generated WF ", n_WF)

	if filename is None:
		return theta_vector, amp_dataset.real, ph_dataset.real, time_grid
	else:
		filebuff.close()
		return None
t_step = 5e-5
f_min = 20.0

for inclination in np.linspace(-np.pi / 2, np.pi / 2, 10):

    hptilde, hctilde = lalsim.SimInspiralChooseTDWaveform(  #where is its definition and documentation????
        m1 * lalsim.lal.MSUN_SI,  #m1
        m2 * lalsim.lal.MSUN_SI,  #m2
        0.,
        0.,
        spin1z,  #spin vector 1
        0.,
        0.,
        spin2z,  #spin vector 2
        d * 1e6 * lalsim.lal.PC_SI,  #distance to source
        inclination,  #inclination
        0.,  #phi ref
        0.,  #longAscNodes
        0.,  #eccentricity
        0.,  #meanPerAno
        t_step,  # time incremental step
        f_min,  # lowest value of time
        f_min,  #some reference value of time (??)
        lal.CreateDict(),  #some lal dictionary
        lalsim.GetApproximantFromString(
            'SEOBNRv2_opt')  #approx method for the model
    )
    times = t_step * np.linspace(0.0, len(hptilde.data.data),
                                 len(hptilde.data.data))
    times -= times[np.argmax(hptilde.data.data**2 + hctilde.data.data**2)]

    theta = np.column_stack((m1 / m2, spin1z, spin2z))
示例#24
0
def lalsim_td_waveform(long_asc_nodes=0.0,
                       eccentricity=0.0,
                       mean_per_ano=0.0,
                       phi_ref=0.0,
                       f_ref=None,
                       phase_order=-1,
                       amplitude_order=-1,
                       spin_order=-1,
                       tidal_order=-1,
                       **p):
    """Wrapper for lalsimulation.SimInspiralChooseTDWaveform.
    Simplified version of pycbc.waveform.get_td_waveform wrapper.

    Parameters
    ----------
    f_ref : Reference frequency (?For setting phi_ref? Not sure.) Defaults to f_min.
    phi_ref : Reference phase (?at f_ref?).

    Returns
    -------
    h : Waveform
    """
    if f_ref == None:
        f_ref = p['f_min']

    # Set extra arguments in the lal Dict structure
    lal_pars = lal.CreateDict()
    if phase_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(
            lal_pars, int(phase_order))
    if amplitude_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder(
            lal_pars, int(amplitude_order))
    if spin_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder(
            lal_pars, int(spin_order))
    if tidal_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidalOrder(
            lal_pars, int(tidal_order))
    if p['lambda1']:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1(
            lal_pars, p['lambda1'])
    if p['lambda2']:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(
            lal_pars, p['lambda2'])

    # Set Approximant (C enum structure) corresponding to approximant string
    lal_approx = lalsimulation.GetApproximantFromString(p['approximant'])

    hp, hc = lalsimulation.SimInspiralChooseTDWaveform(
        float(MSUN_SI * p['mass1']), float(MSUN_SI * p['mass2']),
        float(p['spin1x']), float(p['spin1y']), float(p['spin1z']),
        float(p['spin2x']), float(p['spin2y']), float(p['spin2z']),
        float(MPC_SI * p['distance']), float(p['inclination']), float(phi_ref),
        float(long_asc_nodes), float(eccentricity), float(mean_per_ano),
        float(p['delta_t']), float(p['f_min']), float(f_ref), lal_pars,
        lal_approx)

    # Extract data from lalsimulation's structures
    tstart = hp.epoch.gpsSeconds + hp.epoch.gpsNanoSeconds * 1.0e-9
    xs = tstart + hp.deltaT * np.arange(hp.data.length)
    return wave.Waveform.from_hp_hc(xs, hp.data.data, hc.data.data)
示例#25
0
def gen_bbh(fs,T_obs,psds,isnr=1.0,dets=['H1']):
    """
    generates a BBH timedomain signal
    """
    N = T_obs * fs      # the total number of time samples
    dt = 1 / fs             # the sampling time (sec)
    f_low = 12.0            # lowest frequency of waveform (Hz)
    amplitude_order = 0
    phase_order = 7
    approximant = lalsimulation.IMRPhenomD
    ndet = len(dets)    # number of detectors

    # define distribution params
    m_min = 5.0         # rest frame component masses
    M_max = 100.0       # rest frame total mass
    log_m_max = np.log(M_max - m_min)
    dist = 1e6*lal.PC_SI  # put it as 1 MPc

    flag = False
    while not flag:
        m12 = np.exp(np.log(m_min) + np.random.uniform(0,1,2)*(log_m_max-np.log(m_min)))
        flag = True if (np.sum(m12)<M_max) and (np.all(m12>m_min)) and (m12[0]>=m12[1]) else False
    eta = m12[0]*m12[1]/(m12[0]+m12[1])**2
    mc = np.sum(m12)*eta**(3.0/5.0)
    print '{}: selected bbh masses = {},{} (chirp mass = {})'.format(time.asctime(),m12[0],m12[1],mc)

    # generate iota
    iota = np.arccos(-1.0 + 2.0*np.random.rand())
    print '{}: selected bbh cos(inclination) = {}'.format(time.asctime(),np.cos(iota))    

    # generate polarisation angle 
    psi = 2.0*np.pi*np.random.rand()
    print '{}: selected bbh polarisation = {}'.format(time.asctime(),psi)   

    # make waveform
    # loop until we have a long enough waveform - slowly reduce flow is needed
    flag = False
    while not flag:
        hp, hc = lalsimulation.SimInspiralChooseTDWaveform(
                    m12[0] * lal.MSUN_SI, m12[1] * lal.MSUN_SI,
                    0, 0, 0, 0, 0, 0,
                    dist,
                    iota, 0, 0,
                    0, 0,
                    1 / fs, 
                    f_low,f_low,
                    lal.CreateDict(),
                    approximant)
        flag = True if hp.data.length>2*N else False
        f_low -= 1       # decrease by 1 Hz each time
    hp = hp.data.data
    hc = hc.data.data

    # pick sky position - uniform on the 2-sphere
    ra = 2.0*np.pi*np.random.rand()   
    dec = np.arcsin(-1.0 + 2.0*np.random.rand())
    print '{}: selected bbh sky position = {},{}'.format(time.asctime(),ra,dec)

    # pick new random max amplitude sample location - within mid 20% region
    # and slide waveform to that location
    idx = int(np.random.randint(int(4.0*N/10.0),int(6.0*N/10.0),1)[0])
    print '{}: selected bbh peak amplitude time = {}'.format(time.asctime(),dt*idx)

    # define point of max amplitude
    ref_idx = int(np.argmax(hp**2 + hc**2))

    # loop over detectors
    ts = np.zeros((ndet,N))
    intsnr = []
    j = 0
    for det,psd in zip(dets,psds):

        # make signal - apply antenna and shifts
        ht_temp = make_bbh(hp,hc,fs,ra,dec,psi,det)
    
        # place signal into timeseries - including shift
        x_temp = np.zeros(N)
        temp = ht_temp[int(ref_idx-idx):]
        if len(temp)<N:
            x_temp[:len(temp)] = temp
        else:
            x_temp = temp[:N]        

        # compute SNR of pre-whitened data
        intsnr.append(get_snr(x_temp,T_obs,fs,psd.data.data))

        # don't whiten the data
        ts[j,:] = x_temp

        j += 1

    hpc_temp = np.zeros((2,N))
    temp_hp = hp[int(ref_idx-idx):]
    temp_hc = hc[int(ref_idx-idx):]
    if len(temp_hp)<N:
        hpc_temp[0,:len(temp)] = temp_hp
        hpc_temp[1,:len(temp)] = temp_hc
    else:
        hpc_temp[0,:] = temp_hp[:N]
        hpc_temp[1,:] = temp_hc[:N]

    # normalise the waveform using either integrated or peak SNR
    intsnr = np.array(intsnr)
    scale = isnr/np.sqrt(np.sum(intsnr**2))
    ts = scale*ts
    intsnr *= scale
    SNR = np.sqrt(np.sum(intsnr**2))
    print '{}: computed the network SNR = {}'.format(time.asctime(),SNR)

    # store params
    par = bbhparams(mc,m12[0],m12[1],ra,dec,np.cos(iota),psi,idx*dt,intsnr,SNR)

    return ts, par, hpc_temp
示例#26
0
def make_tidal_waveform(approx='TaylorT4',
                        rate=4096,
                        Lambda1=None,
                        Lambda2=None,
                        mass1=1.4,
                        mass2=1.3,
                        inclination=0,
                        distance=100,
                        eccentricity=0,
                        meanPerAno=0,
                        phiRef=0,
                        f_min=30,
                        f_ref=0,
                        longAscNodes=0,
                        s1x=0,
                        s1y=0,
                        s1z=0,
                        s2x=0,
                        s2y=0,
                        s2z=0,
                        eos=None,
                        save=False):
    # Sanity check
    if (Lambda1 is None) and (Lambda2 is None) and (eos is None):
        # Assuming Lambdas to be zero is not provided
        print("Assuming tidal deformability is zero")
        print(
            "Use arguments Lambda1=, and Lambda2= to provide deformabilities")
        Lambda1 = 0.0
        Lambda2 = 0.0
    if eos:
        if Lambda1 or Lambda2:
            print(
                "Warning: Both eos and Lambda1 and/or Lambda2 has been provided"
            )
            print("Ignoring Lambdas in favor of the eos")
        e = lalsim.SimNeutronStarEOSByName(eos)
        fam = lalsim.CreateSimNeutronStarFamily(e)
        max_mass = lalsim.SimNeutronStarMaximumMass(fam) / lal.MSUN_SI
        assert mass1 < max_mass, "mass1 greater than maximum mass allowed for the neutron star"
        assert mass2 < max_mass, "mass2 greater than the maximum mass allowed for the neutron star"
        r1 = lalsim.SimNeutronStarRadius(mass1 * lal.MSUN_SI, fam)
        k1 = lalsim.SimNeutronStarLoveNumberK2(mass1 * lal.MSUN_SI, fam)

        r2 = lalsim.SimNeutronStarRadius(mass2 * lal.MSUN_SI, fam)
        k2 = lalsim.SimNeutronStarLoveNumberK2(mass2 * lal.MSUN_SI, fam)
        c2 = mass2 * lal.MRSUN_SI / r2
        c1 = mass1 * lal.MRSUN_SI / r1

        Lambda1 = (2 / 3) * k1 / (c1**5)
        Lambda2 = (2 / 3) * k2 / (c2**5)

    mass1 = mass1 * lal.MSUN_SI
    mass2 = mass2 * lal.MSUN_SI
    distance = distance * 1e6 * lal.PC_SI
    deltaT = 1.0 / rate
    approximant = lalsim.GetApproximantFromString(approx)
    lal_pars = lal.CreateDict()
    lalsim.SimInspiralWaveformParamsInsertTidalLambda1(lal_pars, Lambda1)
    lalsim.SimInspiralWaveformParamsInsertTidalLambda2(lal_pars, Lambda2)
    hp, hc = lalsim.SimInspiralChooseTDWaveform(mass1,
                                                mass2,
                                                s1x=s1x,
                                                s1y=s1y,
                                                s1z=s1z,
                                                s2x=s2x,
                                                s2y=s2y,
                                                s2z=s2z,
                                                distance=distance,
                                                inclination=inclination,
                                                phiRef=phiRef,
                                                longAscNodes=longAscNodes,
                                                eccentricity=eccentricity,
                                                meanPerAno=meanPerAno,
                                                deltaT=deltaT,
                                                f_min=f_min,
                                                f_ref=f_ref,
                                                params=lal_pars,
                                                approximant=approximant)
    if save:
        plus_data = hp.data.data
        cross_data = hc.data.data
        tstart_p = hp.epoch.gpsSeconds + hp.epoch.gpsNanoSeconds * 1e-9
        tstart_c = hc.epoch.gpsSeconds + hc.epoch.gpsNanoSeconds * 1e-9
        tp = np.arange(tstart_p, 0, hp.deltaT)
        tp = tp[:len(hp.data.data)]
        tc = np.arange(tstart_c, 0, hc.deltaT)
        tc = tc[:len(hc.data.data)]
        output_plus = np.vstack((tp, plus_data)).T
        output_cross = np.vstack((tc, cross_data)).T

        np.savetxt("plus_polarization_data.txt", output_plus, fmt="%f\t%e")
        np.savetxt("cross_polarization_data.txt", output_cross, fmt="%f\t%e")

    return (hp, hc)
示例#27
0
dt = 1. / sampling_rate
flow = 20
fref = 20
LALpars = lal.CreateDict()
approx = lalsim.SimInspiralGetApproximantFromString('SEOBNRv2')

hp, hc = lalsim.SimInspiralChooseTDWaveform(
    m1 * lalsim.lal.MSUN_SI,
    m2 * lalsim.lal.MSUN_SI,
    spin1x,
    spin1y,
    spin1z,
    spin2x,
    spin2y,
    spin2z,
    d * 1e6 * lalsim.lal.PC_SI,
    inclination,
    phi0,
    0,  #longAscNodes
    0,  #eccentricity
    0,  #meanPerAno
    dt,
    flow,
    fref,
    LALpars,
    approx)
times = dt * np.array(range(len(hp.data.data)))

plt.figure()
plt.plot(times, hp.data.data, label='Plus polarisation')
plt.plot(times, hc.data.data, label='Cross polarisation')
plt.xlabel('time (s)')