Beispiel #1
0
def _lalsim_fd_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.SimInspiralChooseFDWaveform(
        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']), p['delta_f'], float(p['f_lower']),
        float(p['f_final']), float(p['f_ref']), lal_pars,
        _lalsim_enum[p['approximant']])

    hp = FrequencySeries(hp1.data.data[:], delta_f=hp1.deltaF, epoch=hp1.epoch)

    hc = FrequencySeries(hc1.data.data[:], delta_f=hc1.deltaF, epoch=hc1.epoch)
    #lal.DestroyDict(lal_pars)
    return hp, hc
Beispiel #2
0
def _check_lal_pars(p):
    """ Create a laldict object from the dictionary of waveform parameters

    Parameters
    ----------
    p: dictionary
        The dictionary of lalsimulation paramaters

    Returns
    -------
    laldict: LalDict
        The lal type dictionary to pass to the lalsimulation waveform functions.
    """
    lal_pars = lal.CreateDict()
    #nonGRparams can be straightforwardly added if needed, however they have to
    # be invoked one by one
    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.SimInspiralWaveformParamsInsertTidalLambda1(
            lal_pars, p['lambda1'])
    if p['lambda2']:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(
            lal_pars, p['lambda2'])
    if p['dquad_mon1']:
        lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1(
            lal_pars, p['dquad_mon1'])
    if p['dquad_mon2']:
        lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2(
            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'])
    return lal_pars
Beispiel #3
0
    def _compute_waveform(self, df, f_final):
        phi0 = 0  # This is a reference phase, and not an intrinsic parameter
        LALpars = lal.CreateDict()
        lalsim.SimInspiralWaveformParamsInsertPNAmplitudeOrder(LALpars, 0)
        lalsim.SimInspiralWaveformParamsInsertPNPhaseOrder(LALpars, 7)
        lalsim.SimInspiralWaveformParamsInsertPNSpinOrder(LALpars, 5)
        approx = lalsim.GetApproximantFromString(self.approx_name)
        hplus_fd, hcross_fd = lalsim.SimInspiralChooseFDWaveform(
            self.m1 * MSUN_SI, self.m2 * MSUN_SI, 0., 0., self.spin1z, 0., 0.,
            self.spin2z, 1.e6 * PC_SI, 0., phi0, 0., 0., 0., df, self.flow,
            f_final, self.flow, LALpars, approx)

        # Must set values greater than _get_f_final to 0
        act_f_max = self._get_f_final()
        f_max_idx = int(act_f_max / df + 0.999)
        hplus_fd.data.data[f_max_idx:] = 0

        return hplus_fd
Beispiel #4
0
def _check_lal_pars(p):
    """ Create a laldict object from the dictionary of waveform parameters

    Parameters
    ----------
    p: dictionary
        The dictionary of lalsimulation paramaters

    Returns
    -------
    laldict: LalDict
        The lal type dictionary to pass to the lalsimulation waveform functions.
    """
    lal_pars = lal.CreateDict()
    #nonGRparams can be straightforwardly added if needed, however they have to
    # be invoked one by one
    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'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1(lal_pars, p['lambda1'])
    if p['lambda2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(lal_pars, p['lambda2'])
    if p['lambda_octu1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarLambda1(lal_pars, p['lambda_octu1'])
    if p['lambda_octu2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarLambda2(lal_pars, p['lambda_octu2'])
    if p['quadfmode1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalQuadrupolarFMode1(lal_pars, p['quadfmode1'])
    if p['quadfmode2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalQuadrupolarFMode2(lal_pars, p['quadfmode2'])
    if p['octufmode1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarFMode1(lal_pars, p['octufmode1'])
    if p['octufmode2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarFMode2(lal_pars, p['octufmode2'])
    if p['dquad_mon1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1(lal_pars, p['dquad_mon1'])
    if p['dquad_mon2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2(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'])
    if p['mode_array'] is not None:
        ma = lalsimulation.SimInspiralCreateModeArray()
        for l,m in p['mode_array']:
            lalsimulation.SimInspiralModeArrayActivateMode(ma, l, m)
        lalsimulation.SimInspiralWaveformParamsInsertModeArray(lal_pars, ma)
    #TestingGR parameters:
    if p['dchi0'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi0(lal_pars,p['dchi0'])
    if p['dchi1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi1(lal_pars,p['dchi1'])
    if p['dchi2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi2(lal_pars,p['dchi2'])
    if p['dchi3'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi3(lal_pars,p['dchi3'])
    if p['dchi4'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi4(lal_pars,p['dchi4'])
    if p['dchi5'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi5(lal_pars,p['dchi5'])
    if p['dchi5l'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi5L(lal_pars,p['dchi5l'])
    if p['dchi6'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi6(lal_pars,p['dchi6'])
    if p['dchi6l'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi6L(lal_pars,p['dchi6l'])
    if p['dchi7'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi7(lal_pars,p['dchi7'])
    if p['dalpha1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha1(lal_pars,p['dalpha1'])
    if p['dalpha2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha2(lal_pars,p['dalpha2'])
    if p['dalpha3'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha3(lal_pars,p['dalpha3'])
    if p['dalpha4'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha4(lal_pars,p['dalpha4'])
    if p['dalpha5'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha5(lal_pars,p['dalpha5'])
    if p['dbeta1'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta1(lal_pars,p['dbeta1'])
    if p['dbeta2'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta2(lal_pars,p['dbeta2'])
    if p['dbeta3'] is not None:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta3(lal_pars,p['dbeta3'])
    return lal_pars
Beispiel #5
0
def spa_tmplt(**kwds):
    """ Generate a minimal TaylorF2 approximant with optimations for the sin/cos
    """
    # Pull out the input arguments
    f_lower = kwds['f_lower']
    delta_f = kwds['delta_f']
    distance = kwds['distance']
    mass1 = kwds['mass1']
    mass2 = kwds['mass2']
    s1z = kwds['spin1z']
    s2z = kwds['spin2z']
    phase_order = int(kwds['phase_order'])
    #amplitude_order = int(kwds['amplitude_order'])
    spin_order = int(kwds['spin_order'])

    if 'out' in kwds:
        out = kwds['out']
    else:
        out = None

    amp_factor = spa_amplitude_factor(mass1=mass1, mass2=mass2) / distance

    lal_pars = lal.CreateDict()
    if phase_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(
            lal_pars, phase_order)

    if spin_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder(
            lal_pars, spin_order)

    #Calculate the PN terms
    phasing = lalsimulation.SimInspiralTaylorF2AlignedPhasing(
        float(mass1), float(mass2), float(s1z), float(s2z), lal_pars)

    pfaN = phasing.v[0]
    pfa2 = phasing.v[2] / pfaN
    pfa3 = phasing.v[3] / pfaN
    pfa4 = phasing.v[4] / pfaN
    pfa5 = phasing.v[5] / pfaN
    pfa6 = (phasing.v[6] - phasing.vlogv[6] * log(4)) / pfaN
    pfa7 = phasing.v[7] / pfaN

    pfl5 = phasing.vlogv[5] / pfaN
    pfl6 = phasing.vlogv[6] / pfaN

    piM = lal.PI * (mass1 + mass2) * lal.MTSUN_SI

    kmin = int(f_lower / float(delta_f))

    vISCO = 1. / sqrt(6.)
    fISCO = vISCO * vISCO * vISCO / piM
    kmax = int(fISCO / delta_f)
    f_max = ceilpow2(fISCO)
    n = int(f_max / delta_f) + 1

    if not out:
        htilde = FrequencySeries(zeros(n, dtype=numpy.complex64),
                                 delta_f=delta_f,
                                 copy=False)
    else:
        if type(out) is not Array:
            raise TypeError("Output must be an instance of Array")
        if len(out) < kmax:
            kmax = len(out)
        if out.dtype != complex64:
            raise TypeError("Output array is the wrong dtype")
        htilde = FrequencySeries(out, delta_f=delta_f, copy=False)

    spa_tmplt_engine(htilde[kmin:kmax], kmin, phase_order, delta_f, piM, pfaN,
                     pfa2, pfa3, pfa4, pfa5, pfl5, pfa6, pfl6, pfa7,
                     amp_factor)
    return htilde
Beispiel #6
0
def _base_lal_cbc_fd_waveform(
        frequency_array, mass_1, mass_2, luminosity_distance, theta_jn, phase,
        a_1=0.0, a_2=0.0, tilt_1=0.0, tilt_2=0.0, phi_12=0.0, phi_jl=0.0,
        lambda_1=0.0, lambda_2=0.0, eccentricity=0.0, **waveform_kwargs):
    """ Generate a cbc waveform model using lalsimulation

    Parameters
    ==========
    frequency_array: array_like
        The frequencies at which we want to calculate the strain
    mass_1: float
        The mass of the heavier object in solar masses
    mass_2: float
        The mass of the lighter object in solar masses
    luminosity_distance: float
        The luminosity distance in megaparsec
    a_1: float
        Dimensionless primary spin magnitude
    tilt_1: float
        Primary tilt angle
    phi_12: float
        Azimuthal angle between the component spins
    a_2: float
        Dimensionless secondary spin magnitude
    tilt_2: float
        Secondary tilt angle
    phi_jl: float
        Azimuthal angle between the total and orbital angular momenta
    theta_jn: float
        Orbital inclination
    phase: float
        The phase at coalescence
    eccentricity: float
        Binary eccentricity
    lambda_1: float
        Tidal deformability of the more massive object
    lambda_2: float
        Tidal deformability of the less massive object
    kwargs: dict
        Optional keyword arguments

    Returns
    =======
    dict: A dictionary with the plus and cross polarisation strain modes
    """
    import lal
    import lalsimulation as lalsim

    waveform_approximant = waveform_kwargs['waveform_approximant']
    reference_frequency = waveform_kwargs['reference_frequency']
    minimum_frequency = waveform_kwargs['minimum_frequency']
    maximum_frequency = waveform_kwargs['maximum_frequency']
    catch_waveform_errors = waveform_kwargs['catch_waveform_errors']
    pn_spin_order = waveform_kwargs['pn_spin_order']
    pn_tidal_order = waveform_kwargs['pn_tidal_order']
    pn_phase_order = waveform_kwargs['pn_phase_order']
    pn_amplitude_order = waveform_kwargs['pn_amplitude_order']
    waveform_dictionary = waveform_kwargs.get(
        'lal_waveform_dictionary', lal.CreateDict()
    )

    approximant = lalsim_GetApproximantFromString(waveform_approximant)

    if pn_amplitude_order != 0:
        start_frequency = lalsim.SimInspiralfLow2fStart(
            minimum_frequency, int(pn_amplitude_order), approximant)
    else:
        start_frequency = minimum_frequency

    delta_frequency = frequency_array[1] - frequency_array[0]

    frequency_bounds = ((frequency_array >= minimum_frequency) *
                        (frequency_array <= maximum_frequency))

    luminosity_distance = luminosity_distance * 1e6 * utils.parsec
    mass_1 = mass_1 * utils.solar_mass
    mass_2 = mass_2 * utils.solar_mass

    iota, spin_1x, spin_1y, spin_1z, spin_2x, spin_2y, spin_2z = bilby_to_lalsimulation_spins(
        theta_jn=theta_jn, phi_jl=phi_jl, tilt_1=tilt_1, tilt_2=tilt_2,
        phi_12=phi_12, a_1=a_1, a_2=a_2, mass_1=mass_1, mass_2=mass_2,
        reference_frequency=reference_frequency, phase=phase)

    longitude_ascending_nodes = 0.0
    mean_per_ano = 0.0

    lalsim.SimInspiralWaveformParamsInsertPNSpinOrder(
        waveform_dictionary, int(pn_spin_order))
    lalsim.SimInspiralWaveformParamsInsertPNTidalOrder(
        waveform_dictionary, int(pn_tidal_order))
    lalsim.SimInspiralWaveformParamsInsertPNPhaseOrder(
        waveform_dictionary, int(pn_phase_order))
    lalsim.SimInspiralWaveformParamsInsertPNAmplitudeOrder(
        waveform_dictionary, int(pn_amplitude_order))
    lalsim_SimInspiralWaveformParamsInsertTidalLambda1(
        waveform_dictionary, lambda_1)
    lalsim_SimInspiralWaveformParamsInsertTidalLambda2(
        waveform_dictionary, lambda_2)

    for key, value in waveform_kwargs.items():
        func = getattr(lalsim, "SimInspiralWaveformParamsInsert" + key, None)
        if func is not None:
            func(waveform_dictionary, value)

    if waveform_kwargs.get('numerical_relativity_file', None) is not None:
        lalsim.SimInspiralWaveformParamsInsertNumRelData(
            waveform_dictionary, waveform_kwargs['numerical_relativity_file'])

    if ('mode_array' in waveform_kwargs) and waveform_kwargs['mode_array'] is not None:
        mode_array = waveform_kwargs['mode_array']
        mode_array_lal = lalsim.SimInspiralCreateModeArray()
        for mode in mode_array:
            lalsim.SimInspiralModeArrayActivateMode(mode_array_lal, mode[0], mode[1])
        lalsim.SimInspiralWaveformParamsInsertModeArray(waveform_dictionary, mode_array_lal)

    if lalsim.SimInspiralImplementedFDApproximants(approximant):
        wf_func = lalsim_SimInspiralChooseFDWaveform
    else:
        wf_func = lalsim_SimInspiralFD
    try:
        hplus, hcross = wf_func(
            mass_1, mass_2, spin_1x, spin_1y, spin_1z, spin_2x, spin_2y,
            spin_2z, luminosity_distance, iota, phase,
            longitude_ascending_nodes, eccentricity, mean_per_ano, delta_frequency,
            start_frequency, maximum_frequency, reference_frequency,
            waveform_dictionary, approximant)
    except Exception as e:
        if not catch_waveform_errors:
            raise
        else:
            EDOM = (e.args[0] == 'Internal function call failed: Input domain error')
            if EDOM:
                failed_parameters = dict(mass_1=mass_1, mass_2=mass_2,
                                         spin_1=(spin_1x, spin_2y, spin_1z),
                                         spin_2=(spin_2x, spin_2y, spin_2z),
                                         luminosity_distance=luminosity_distance,
                                         iota=iota, phase=phase,
                                         eccentricity=eccentricity,
                                         start_frequency=start_frequency)
                logger.warning("Evaluating the waveform failed with error: {}\n".format(e) +
                               "The parameters were {}\n".format(failed_parameters) +
                               "Likelihood will be set to -inf.")
                return None
            else:
                raise

    h_plus = np.zeros_like(frequency_array, dtype=complex)
    h_cross = np.zeros_like(frequency_array, dtype=complex)

    if len(hplus.data.data) > len(frequency_array):
        logger.debug("LALsim waveform longer than bilby's `frequency_array`" +
                     "({} vs {}), ".format(len(hplus.data.data), len(frequency_array)) +
                     "probably because padded with zeros up to the next power of two length." +
                     " Truncating lalsim array.")
        h_plus = hplus.data.data[:len(h_plus)]
        h_cross = hcross.data.data[:len(h_cross)]
    else:
        h_plus[:len(hplus.data.data)] = hplus.data.data
        h_cross[:len(hcross.data.data)] = hcross.data.data

    h_plus *= frequency_bounds
    h_cross *= frequency_bounds

    if wf_func == lalsim_SimInspiralFD:
        dt = 1 / hplus.deltaF + (hplus.epoch.gpsSeconds + hplus.epoch.gpsNanoSeconds * 1e-9)
        time_shift = np.exp(-1j * 2 * np.pi * dt * frequency_array[frequency_bounds])
        h_plus[frequency_bounds] *= time_shift
        h_cross[frequency_bounds] *= time_shift

    return dict(plus=h_plus, cross=h_cross)
Beispiel #7
0
def _base_waveform_frequency_sequence(frequency_array, mass_1, mass_2,
                                      luminosity_distance, a_1, tilt_1, phi_12,
                                      a_2, tilt_2, lambda_1, lambda_2, phi_jl,
                                      theta_jn, phase, **waveform_kwargs):
    """ Generate a cbc waveform model on specified frequency samples

    Parameters
    ----------
    frequency_array: np.array
        This input is ignored
    mass_1: float
        The mass of the heavier object in solar masses
    mass_2: float
        The mass of the lighter object in solar masses
    luminosity_distance: float
        The luminosity distance in megaparsec
    a_1: float
        Dimensionless primary spin magnitude
    tilt_1: float
        Primary tilt angle
    phi_12: float
    a_2: float
        Dimensionless secondary spin magnitude
    tilt_2: float
        Secondary tilt angle
    phi_jl: float
    theta_jn: float
        Orbital inclination
    phase: float
        The phase at coalescence
    waveform_kwargs: dict
        Optional keyword arguments

    Returns
    -------
    waveform_polarizations: dict
        Dict containing plus and cross modes evaluated at the linear and
        quadratic frequency nodes.
    """
    from lal import CreateDict
    import lalsimulation as lalsim

    frequencies = waveform_kwargs['frequencies']
    reference_frequency = waveform_kwargs['reference_frequency']
    approximant = lalsim_GetApproximantFromString(
        waveform_kwargs['waveform_approximant'])
    catch_waveform_errors = waveform_kwargs['catch_waveform_errors']
    pn_spin_order = waveform_kwargs['pn_spin_order']
    pn_tidal_order = waveform_kwargs['pn_tidal_order']
    pn_phase_order = waveform_kwargs['pn_phase_order']
    pn_amplitude_order = waveform_kwargs['pn_amplitude_order']
    waveform_dictionary = waveform_kwargs.get('lal_waveform_dictionary',
                                              CreateDict())

    lalsim.SimInspiralWaveformParamsInsertPNSpinOrder(waveform_dictionary,
                                                      int(pn_spin_order))
    lalsim.SimInspiralWaveformParamsInsertPNTidalOrder(waveform_dictionary,
                                                       int(pn_tidal_order))
    lalsim.SimInspiralWaveformParamsInsertPNPhaseOrder(waveform_dictionary,
                                                       int(pn_phase_order))
    lalsim.SimInspiralWaveformParamsInsertPNAmplitudeOrder(
        waveform_dictionary, int(pn_amplitude_order))
    lalsim_SimInspiralWaveformParamsInsertTidalLambda1(waveform_dictionary,
                                                       lambda_1)
    lalsim_SimInspiralWaveformParamsInsertTidalLambda2(waveform_dictionary,
                                                       lambda_2)

    for key, value in waveform_kwargs.items():
        func = getattr(lalsim, "SimInspiralWaveformParamsInsert" + key, None)
        if func is not None:
            func(waveform_dictionary, value)

    if waveform_kwargs.get('numerical_relativity_file', None) is not None:
        lalsim.SimInspiralWaveformParamsInsertNumRelData(
            waveform_dictionary, waveform_kwargs['numerical_relativity_file'])

    if ('mode_array'
            in waveform_kwargs) and waveform_kwargs['mode_array'] is not None:
        mode_array = waveform_kwargs['mode_array']
        mode_array_lal = lalsim.SimInspiralCreateModeArray()
        for mode in mode_array:
            lalsim.SimInspiralModeArrayActivateMode(mode_array_lal, mode[0],
                                                    mode[1])
        lalsim.SimInspiralWaveformParamsInsertModeArray(
            waveform_dictionary, mode_array_lal)

    luminosity_distance = luminosity_distance * 1e6 * utils.parsec
    mass_1 = mass_1 * utils.solar_mass
    mass_2 = mass_2 * utils.solar_mass

    iota, spin_1x, spin_1y, spin_1z, spin_2x, spin_2y, spin_2z = bilby_to_lalsimulation_spins(
        theta_jn=theta_jn,
        phi_jl=phi_jl,
        tilt_1=tilt_1,
        tilt_2=tilt_2,
        phi_12=phi_12,
        a_1=a_1,
        a_2=a_2,
        mass_1=mass_1,
        mass_2=mass_2,
        reference_frequency=reference_frequency,
        phase=phase)

    try:
        h_plus, h_cross = lalsim_SimInspiralChooseFDWaveformSequence(
            phase, mass_1, mass_2, spin_1x, spin_1y, spin_1z, spin_2x, spin_2y,
            spin_2z, reference_frequency, luminosity_distance, iota,
            waveform_dictionary, approximant, frequencies)
    except Exception as e:
        if not catch_waveform_errors:
            raise
        else:
            EDOM = (e.args[0] ==
                    'Internal function call failed: Input domain error')
            if EDOM:
                failed_parameters = dict(
                    mass_1=mass_1,
                    mass_2=mass_2,
                    spin_1=(spin_1x, spin_2y, spin_1z),
                    spin_2=(spin_2x, spin_2y, spin_2z),
                    luminosity_distance=luminosity_distance,
                    iota=iota,
                    phase=phase)
                logger.warning(
                    "Evaluating the waveform failed with error: {}\n".format(e)
                    + "The parameters were {}\n".format(failed_parameters) +
                    "Likelihood will be set to -inf.")
                return None
            else:
                raise

    return dict(plus=h_plus.data.data, cross=h_cross.data.data)
Beispiel #8
0
def _check_lal_pars(p):
    """ Create a laldict object from the dictionary of waveform parameters

    Parameters
    ----------
    p: dictionary
        The dictionary of lalsimulation paramaters

    Returns
    -------
    laldict: LalDict
        The lal type dictionary to pass to the lalsimulation waveform functions.
    """
    lal_pars = lal.CreateDict()
    #nonGRparams can be straightforwardly added if needed, however they have to
    # be invoked one by one
    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.SimInspiralWaveformParamsInsertTidalLambda1(
            lal_pars, p['lambda1'])
    if p['lambda2']:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(
            lal_pars, p['lambda2'])
    if p['dquad_mon1']:
        lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1(
            lal_pars, p['dquad_mon1'])
    if p['dquad_mon2']:
        lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2(
            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'])
################################################################################################
#####-------------------------------------Non-GR params-----------------------------------######
################################################################################################
# Phi:
    if 'phi1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRPhi1(
            lal_pars, float(p['phi1']))
    if 'phi2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRPhi2(
            lal_pars, float(p['phi2']))
    if 'phi3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRPhi3(
            lal_pars, float(p['phi3']))
    if 'phi4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRPhi4(
            lal_pars, float(p['phi4']))
# dChi:
    if 'dchi0' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi0(
            lal_pars, float(p['dchi0']))
    if 'dchi1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi1(
            lal_pars, float(p['dchi1']))
    if 'dchi2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi2(
            lal_pars, float(p['dchi2']))
    if 'dchi3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi3(
            lal_pars, float(p['dchi3']))
    if 'dchi4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi4(
            lal_pars, float(p['dchi4']))
    if 'dchi5' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi5(
            lal_pars, float(p['dchi5']))
    if 'dchi5L' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi5L(
            lal_pars, float(p['dchi5L']))
    if 'dchi6' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi6(
            lal_pars, float(p['dchi7']))
    if 'dchi6L' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi6L(
            lal_pars, float(p['dchi6L']))
    if 'dchi7' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi7(
            lal_pars, float(p['dchi7']))
# dXi:
    if 'dxi1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDXi1(
            lal_pars, float(p['dxi1']))
    if 'dxi2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDXi2(
            lal_pars, float(p['dxi2']))
    if 'dxi3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDXi3(
            lal_pars, float(p['dxi3']))
    if 'dxi4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDXi4(
            lal_pars, float(p['dxi4']))
    if 'dxi5' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDXi5(
            lal_pars, float(p['dxi5']))
    if 'dxi6' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDXi6(
            lal_pars, float(p['dxi6']))
# Sigma:
    if 'dsigma1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDSigma1(
            lal_pars, float(p['dsigma1']))
    if 'dsigma2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDSigma2(
            lal_pars, float(p['dsigma2']))
    if 'dsigma3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDSigma3(
            lal_pars, float(p['dsigma3']))
    if 'dsigma4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDSigma4(
            lal_pars, float(p['dsigma4']))
# Alpha:
    if 'dalpha1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha1(
            lal_pars, float(p['dalpha1']))
    if 'dalpha2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha2(
            lal_pars, float(p['dalpha2']))
    if 'dalpha3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha3(
            lal_pars, float(p['dalpha3']))
    if 'dalpha4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha4(
            lal_pars, float(p['dalpha4']))
    if 'dalpha5' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha5(
            lal_pars, float(p['dalpha5']))
# Beta:
    if 'dbeta1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta1(
            lal_pars, float(p['dbeta1']))
    if 'dbeta2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta2(
            lal_pars, float(p['dbeta2']))
    if 'dbeta3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta3(
            lal_pars, float(p['dbeta3']))
# Alpha PPE:
    if 'alphaPPE' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE(
            lal_pars, float(p['alphaPPE']))
    if 'alphaPPE0' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE0(
            lal_pars, float(p['alphaPPE0']))
    if 'alphaPPE1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE1(
            lal_pars, float(p['alphaPPE1']))
    if 'alphaPPE2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE2(
            lal_pars, float(p['alphaPPE2']))
    if 'alphaPPE3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE3(
            lal_pars, float(p['alphaPPE3']))
    if 'alphaPPE4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE4(
            lal_pars, float(p['alphaPPE4']))
    if 'alphaPPE5' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRAlphaPPE5(
            lal_pars, float(p['alphaPPE5']))


# Beta PPE:
    if 'betaPPE' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE(
            lal_pars, float(p['betaPPE']))
    if 'betaPPE0' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE0(
            lal_pars, float(p['betaPPE0']))
    if 'betaPPE1' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE1(
            lal_pars, float(p['betaPPE1']))
    if 'betaPPE2' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE2(
            lal_pars, float(p['betaPPE2']))
    if 'betaPPE3' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE3(
            lal_pars, float(p['betaPPE3']))
    if 'betaPPE4' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE4(
            lal_pars, float(p['betaPPE4']))
    if 'betaPPE5' in p:
        lalsimulation.SimInspiralWaveformParamsInsertNonGRBetaPPE5(
            lal_pars, float(p['betaPPE5']))

    return lal_pars
Beispiel #9
0
def _base_lal_cbc_fd_waveform(frequency_array,
                              mass_1,
                              mass_2,
                              luminosity_distance,
                              theta_jn,
                              phase,
                              a_1=0.0,
                              a_2=0.0,
                              tilt_1=0.0,
                              tilt_2=0.0,
                              phi_12=0.0,
                              phi_jl=0.0,
                              lambda_1=0.0,
                              lambda_2=0.0,
                              eccentricity=0.0,
                              **waveform_kwargs):
    """ Generate a cbc waveform model using lalsimulation

    Parameters
    ----------
    frequency_array: array_like
        The frequencies at which we want to calculate the strain
    mass_1: float
        The mass of the heavier object in solar masses
    mass_2: float
        The mass of the lighter object in solar masses
    luminosity_distance: float
        The luminosity distance in megaparsec
    a_1: float
        Dimensionless primary spin magnitude
    tilt_1: float
        Primary tilt angle
    phi_12: float
        Azimuthal angle between the component spins
    a_2: float
        Dimensionless secondary spin magnitude
    tilt_2: float
        Secondary tilt angle
    phi_jl: float
        Azimuthal angle between the total and orbital angular momenta
    theta_jn: float
        Orbital inclination
    phase: float
        The phase at coalescence
    eccentricity: float
        Binary eccentricity
    lambda_1: float
        Tidal deformability of the more massive object
    lambda_2: float
        Tidal deformability of the less massive object
    kwargs: dict
        Optional keyword arguments

    Returns
    -------
    dict: A dictionary with the plus and cross polarisation strain modes
    """
    waveform_approximant = waveform_kwargs['waveform_approximant']
    reference_frequency = waveform_kwargs['reference_frequency']
    minimum_frequency = waveform_kwargs['minimum_frequency']
    maximum_frequency = waveform_kwargs['maximum_frequency']
    catch_waveform_errors = waveform_kwargs['catch_waveform_errors']
    pn_spin_order = waveform_kwargs['pn_spin_order']
    pn_tidal_order = waveform_kwargs['pn_tidal_order']
    pn_phase_order = waveform_kwargs['pn_phase_order']
    pn_amplitude_order = waveform_kwargs['pn_amplitude_order']

    approximant = lalsim_GetApproximantFromString(waveform_approximant)

    if pn_amplitude_order != 0:
        start_frequency = lalsim.SimInspiralfLow2fStart(
            minimum_frequency, int(pn_amplitude_order), approximant)
    else:
        start_frequency = minimum_frequency

    delta_frequency = frequency_array[1] - frequency_array[0]

    frequency_bounds = ((frequency_array >= minimum_frequency) *
                        (frequency_array <= maximum_frequency))

    luminosity_distance = luminosity_distance * 1e6 * utils.parsec
    mass_1 = mass_1 * utils.solar_mass
    mass_2 = mass_2 * utils.solar_mass

    iota, spin_1x, spin_1y, spin_1z, spin_2x, spin_2y, spin_2z = bilby_to_lalsimulation_spins(
        theta_jn=theta_jn,
        phi_jl=phi_jl,
        tilt_1=tilt_1,
        tilt_2=tilt_2,
        phi_12=phi_12,
        a_1=a_1,
        a_2=a_2,
        mass_1=mass_1,
        mass_2=mass_2,
        reference_frequency=reference_frequency,
        phase=phase)

    longitude_ascending_nodes = 0.0
    mean_per_ano = 0.0

    waveform_dictionary = lal.CreateDict()
    lalsim.SimInspiralWaveformParamsInsertPNSpinOrder(waveform_dictionary,
                                                      int(pn_spin_order))
    lalsim.SimInspiralWaveformParamsInsertPNTidalOrder(waveform_dictionary,
                                                       int(pn_tidal_order))
    lalsim.SimInspiralWaveformParamsInsertPNPhaseOrder(waveform_dictionary,
                                                       int(pn_phase_order))
    lalsim.SimInspiralWaveformParamsInsertPNAmplitudeOrder(
        waveform_dictionary, int(pn_amplitude_order))
    lalsim_SimInspiralWaveformParamsInsertTidalLambda1(waveform_dictionary,
                                                       lambda_1)
    lalsim_SimInspiralWaveformParamsInsertTidalLambda2(waveform_dictionary,
                                                       lambda_2)

    if 'modearray' in waveform_kwargs:
        modearray = waveform_kwargs['modearray']
        mode_array = lalsim.SimInspiralCreateModeArray()
        for mode in modearray:
            lalsim.SimInspiralModeArrayActivateMode(mode_array, mode[0],
                                                    mode[1])
        lalsim.SimInspiralWaveformParamsInsertModeArray(
            waveform_dictionary, mode_array)

    if lalsim.SimInspiralImplementedFDApproximants(approximant):
        wf_func = lalsim_SimInspiralChooseFDWaveform
    else:
        wf_func = lalsim_SimInspiralFD
    try:
        hplus, hcross = wf_func(mass_1, mass_2, spin_1x, spin_1y, spin_1z,
                                spin_2x, spin_2y, spin_2z, luminosity_distance,
                                iota, phase, longitude_ascending_nodes,
                                eccentricity, mean_per_ano, delta_frequency,
                                start_frequency, maximum_frequency,
                                reference_frequency, waveform_dictionary,
                                approximant)
    except Exception as e:
        if not catch_waveform_errors:
            raise
        else:
            EDOM = (e.args[0] ==
                    'Internal function call failed: Input domain error')
            if EDOM:
                failed_parameters = dict(
                    mass_1=mass_1,
                    mass_2=mass_2,
                    spin_1=(spin_1x, spin_2y, spin_1z),
                    spin_2=(spin_2x, spin_2y, spin_2z),
                    luminosity_distance=luminosity_distance,
                    iota=iota,
                    phase=phase,
                    eccentricity=eccentricity,
                    start_frequency=start_frequency)
                logger.warning(
                    "Evaluating the waveform failed with error: {}\n".format(e)
                    + "The parameters were {}\n".format(failed_parameters) +
                    "Likelihood will be set to -inf.")
                return None
            else:
                raise

    h_plus = np.zeros_like(frequency_array, dtype=np.complex)
    h_cross = np.zeros_like(frequency_array, dtype=np.complex)

    if len(hplus.data.data) > len(frequency_array):
        raise ValueError("Waveform longer than frequency array")

    h_plus[:len(hplus.data.data)] = hplus.data.data
    h_cross[:len(hcross.data.data)] = hcross.data.data

    h_plus *= frequency_bounds
    h_cross *= frequency_bounds

    return dict(plus=h_plus, cross=h_cross)
Beispiel #10
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)
Beispiel #11
0
def lalsim_fd_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,
                       quad1=None,
                       quad2=None,
                       **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'])
    # Add spin-induced quadrupole terms. Default is universal relations.
    # dQuadMon1 = quad1 - 1
    # dQuadMon2 = quad2 - 1
    if quad1 == None:
        quad1 = taylorf2.quad_of_lambda_fit(p['lambda1'])
    if quad2 == None:
        quad2 = taylorf2.quad_of_lambda_fit(p['lambda2'])
    lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1(
        lal_pars, quad1 - 1.0)
    lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2(
        lal_pars, quad2 - 1.0)
    print quad1, quad2
    print 'dQuadMon1 =', lalsimulation.SimInspiralWaveformParamsLookupdQuadMon1(
        lal_pars)
    print 'dQuadMon2 =', lalsimulation.SimInspiralWaveformParamsLookupdQuadMon2(
        lal_pars)

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

    hp, hc = lalsimulation.SimInspiralChooseFDWaveform(
        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_f']), float(p['f_min']), float(p['f_max']),
        float(f_ref), lal_pars, lal_approx)

    # Extract data from lalsimulation's structures
    # The first data point in hp.data.data corresponds to f=0 not f=f_min
    fs = hp.deltaF * np.arange(hp.data.length)
    return wave.Waveform.from_hp_hc(fs, hp.data.data, hc.data.data)