Exemple #1
0
    def __init__(self,
                 mass_1,
                 mass_2,
                 chi_1,
                 chi_2,
                 luminosity_distance,
                 lambda_1=0,
                 lambda_2=0):
        self.mass_1 = mass_1
        self.mass_2 = mass_2
        self.chi_1 = chi_1
        self.chi_2 = chi_2
        self.total_mass = mass_1 + mass_2
        self.symmetric_mass_ratio = mass_1 * mass_2 / self.total_mass**2

        self.lambda_1 = float(lambda_1)
        self.lambda_2 = float(lambda_2)
        self.param_dict = CreateDict()
        ls.SimInspiralWaveformParamsInsertTidalLambda1(self.param_dict,
                                                       self.lambda_1)
        ls.SimInspiralWaveformParamsInsertTidalLambda2(self.param_dict,
                                                       self.lambda_2)
        ls.SimInspiralSetQuadMonParamsFromLambdas(self.param_dict)

        self.luminosity_distance = luminosity_distance * MEGA_PARSEC_SI
Exemple #2
0
    def phase(self, frequency_array, phi_c=0):
        orbital_speed = (np.pi * self.total_mass * SOLAR_RADIUS_IN_S *
                         frequency_array)**(1 / 3)
        phase_coefficients = ls.SimInspiralTaylorF2AlignedPhasing(
            self.mass_1, self.mass_2, self.chi_1, self.chi_2, CreateDict())
        phasing = xp.zeros_like(orbital_speed)
        cumulative_power_frequency = orbital_speed**-5
        for ii in range(len(phase_coefficients.v)):
            phasing += phase_coefficients.v[ii] * cumulative_power_frequency
            phasing += (phase_coefficients.vlogv[ii] *
                        cumulative_power_frequency * xp.log(orbital_speed))
            cumulative_power_frequency *= orbital_speed

        phasing -= 2 * phi_c + np.pi / 4
        phasing = phasing % (2 * np.pi)

        return phasing
Exemple #3
0
def _base_roq_waveform(
        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_arguments):
    """
    See https://git.ligo.org/lscsoft/lalsuite/blob/master/lalsimulation/src/LALSimInspiral.c#L1460

    Parameters
    ==========
    frequency_array: np.array
        This input is ignored for the roq source model
    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 arguments
    ===================
    Non-sampled extra data used in the source model calculation
    frequency_nodes_linear: np.array
    frequency_nodes_quadratic: np.array
    reference_frequency: float
    approximant: str

    Note: for the frequency_nodes_linear and frequency_nodes_quadratic arguments,
    if using data from https://git.ligo.org/lscsoft/ROQ_data, this should be
    loaded as `np.load(filename).T`.

    Returns
    =======
    waveform_polarizations: dict
        Dict containing plus and cross modes evaluated at the linear and
        quadratic frequency nodes.
    """
    from lal import CreateDict
    frequency_nodes_linear = waveform_arguments['frequency_nodes_linear']
    frequency_nodes_quadratic = waveform_arguments['frequency_nodes_quadratic']
    reference_frequency = waveform_arguments['reference_frequency']
    approximant = lalsim_GetApproximantFromString(
        waveform_arguments['waveform_approximant'])

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

    waveform_dictionary = CreateDict()
    lalsim_SimInspiralWaveformParamsInsertTidalLambda1(
        waveform_dictionary, lambda_1)
    lalsim_SimInspiralWaveformParamsInsertTidalLambda2(
        waveform_dictionary, lambda_2)

    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)

    h_linear_plus, h_linear_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, frequency_nodes_linear)

    waveform_dictionary = CreateDict()
    lalsim_SimInspiralWaveformParamsInsertTidalLambda1(
        waveform_dictionary, lambda_1)
    lalsim_SimInspiralWaveformParamsInsertTidalLambda2(
        waveform_dictionary, lambda_2)

    h_quadratic_plus, h_quadratic_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, frequency_nodes_quadratic)

    waveform_polarizations = dict()
    waveform_polarizations['linear'] = dict(
        plus=h_linear_plus.data.data, cross=h_linear_cross.data.data)
    waveform_polarizations['quadratic'] = dict(
        plus=h_quadratic_plus.data.data, cross=h_quadratic_cross.data.data)

    return waveform_polarizations
Exemple #4
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)
Exemple #5
0
def get_chirp_params_new(mass1, mass2, spin1z, spin2z, f0, order):
    """
    Take a set of masses and spins and convert to the various lambda
    coordinates that describe the orbital phase. Accepted PN orders are:
    {}
 
    Parameters
    ----------
    mass1 : float or array
        Mass1 of input(s).
    mass2 : float or array
        Mass2 of input(s).
    spin1z : float or array
        Parallel spin component(s) of body 1.
    spin2z : float or array
        Parallel spin component(s) of body 2.
    f0 : float
        This is an arbitrary scaling factor introduced to avoid the potential
        for numerical overflow when calculating this. Generally the default
        value (70) is safe here. **IMPORTANT, if you want to calculate the
        ethinca metric components later this MUST be set equal to f_low.**
        This value must also be used consistently (ie. don't change its value
        when calling different functions!).
    order : string
        The Post-Newtonian order that is used to translate from masses and
        spins to the lambda_i coordinate system. Valid orders given above.

    Returns
    --------
    lambdas : list of floats or numpy.arrays
        The lambda coordinates for the input system(s)
    """

    # Determine whether array or single value input
    sngl_inp = False
    try:
        num_points = len(mass1)
    except TypeError:
        sngl_inp = True
        # If you care about speed, you aren't calling this function one entry
        # at a time.
        mass1 = numpy.array([mass1])
        mass2 = numpy.array([mass2])
        spin1z = numpy.array([spin1z])
        spin2z = numpy.array([spin2z])
        num_points = 1
    lal_pars = CreateDict()
    phasing_vs = numpy.zeros([num_points, 13])
    phasing_vlogvs = numpy.zeros([num_points, 13])
    phasing_vlogvsqs = numpy.zeros([num_points, 13])
    for i in xrange(num_points):
        phasing = lalsimulation.SimInspiralTaylorF2AlignedPhasing(
                            mass1[i], mass2[i], spin1z[i], spin2z[i], lal_pars)
        phasing_vs[i] = phasing.v
        phasing_vlogvs[i] = phasing.vlogv
        phasing_vlogvsqs[i] = phasing.vlogvsq

    pmf = PI * (mass1 + mass2)*MTSUN_SI * f0
    pmf13 = pmf**(1./3.)

    mapping = generate_inverse_mapping(order)
    lambdas = []
    lambda_str = '^Lambda([0-9]+)'
    loglambda_str = '^LogLambda([0-9]+)'
    logloglambda_str = '^LogLogLambda([0-9]+'
    for idx in xrange(len(mapping.keys())):
        # RE magic engage!
        rematch = re.match(lambda_str, mapping[idx])
        if rematch:
            pn_order = int(rematch.groups()[0])
            lambdas.append(phasing_vs[:,pn_order] * pmf13**(-5+pn_order))
            continue
        rematch = re.match(loglambda_str, mapping[idx])
        if rematch:
            pn_order = int(rematch.groups()[0])
            lambdas.append(phasing_vlogvs[:,pn_order] * pmf13**(-5+pn_order))
            continue
        rematch = re.match(logloglambda_str, mapping[idx])
        if rematch:
            pn_order = int(rematch.groups()[0])
            lambdas.append(phasing_vlogvsqs[:,pn_order] * pmf13**(-5+pn_order))
            continue
        err_msg = "Failed to parse " +  mapping[idx]
        raise ValueError(err_msg)

    if sngl_inp:
        return [l[0] for l in lambdas]
    else:
        return lambdas