Exemple #1
0
def update_params_norm_hoff(P, IP, param_names, vals, verbose=False):
    """
    Update the values of 1 or more member of P and recompute norm_hoff(P).

    Inputs:
        - P: A ChooseWaveformParams object
        - IP: An InnerProduct object
        - param_names: An array of strings of parameters to be updated.
            e.g. [ 'm1', 'm2', 'incl' ]
        - vals: update P to have these parameter values. Must be array-like
            with same length as param_names, ordered the same way
    Outputs:
        - A COMPLEX16FrequencySeries, same as norm_hoff(P, IP)
    """
    special_params = []
    special_vals = []
    assert len(param_names) == len(vals)
    for i, val in enumerate(vals):
        if hasattr(P, param_names[i]):  # Update an attribute of P...
            setattr(P, param_names[i], val)
        else:  # Either an incorrect param name, or a special case...
            special_params.append(param_names[i])
            special_vals.append(val)

    # Check allowed special cases of params not in P, e.g. Mc and eta
    if special_params == ['Mc', 'eta']:
        m1, m2 = lsu.m1m2(special_vals[0], lsu.sanitize_eta(
            special_vals[1]))  # m1,m2 = m1m2(Mc,eta)
        setattr(P, 'm1', m1)
        setattr(P, 'm2', m2)
    elif special_params == ['eta', 'Mc']:
        m1, m2 = lsu.m1m2(lsu.sanitize_eta(special_vals[1]), special_vals[0])
        setattr(P, 'm1', m1)
        setattr(P, 'm2', m2)
    elif special_params == ['Mc']:
        eta = lsu.sanitize_eta(lsu.symRatio(P.m1, P.m2))
        m1, m2 = lsu.m1m2(special_vals[0], eta)
        setattr(P, 'm1', m1)
        setattr(P, 'm2', m2)
    elif special_params == ['eta']:
        Mc = lsu.mchirp(P.m1, P.m2)
        m1, m2 = lsu.m1m2(Mc, lsu.sanitize_eta(special_vals[0]))
        setattr(P, 'm1', m1)
        setattr(P, 'm2', m2)
    elif special_params != []:
        print(special_params)
        raise Exception

    if verbose == True:  # for debugging - make sure params change properly
        P.print_params()
    return lsu.norm_hoff(P, IP)
Exemple #2
0
def extract_combination_from_LI(samples_LI, p):
    """
    extract_combination_from_LI
      - reads in known columns from posterior samples
      - for selected known combinations not always available, it will compute them from standard quantities
    Unike version in ConstructIntrinsicPosterior, this code does not rely on ChooseWaveformParams to perform coordinate changes...
    """
    if p in samples_LI.dtype.names:  # e.g., we have precomputed it
        return samples_LI[p]
    if p in remap_ILE_2_LI.keys():
        if remap_ILE_2_LI[p] in samples_LI.dtype.names:
            return samples_LI[remap_ILE_2_LI[p]]
    # Return cartesian components of spin1, spin2.  NOTE: I may already populate these quantities in 'Add important quantities'
    if (p == 'chi_eff' or p == 'xi') and 'a1z' in samples_LI.dtype.names:
        m1 = samples_LI['m1']
        m2 = samples_LI['m2']
        a1z = samples_LI['a1z']
        a2z = samples_LI['a2z']
        return (m1 * a1z + m2 * a2z) / (m1 + m2)
    if p == 'chiz_plus':
        print(" Transforming ")
        if 'a1z' in samples_LI.dtype.names:
            return (samples_LI['a1z'] + samples_LI['a2z']) / 2.
        if 'theta1' in samples_LI.dtype.names:
            return (samples_LI['a1'] * np.cos(samples_LI['theta1']) +
                    samples_LI['a2'] * np.cos(samples_LI['theta2'])) / 2.
#        return (samples_LI['a1']+ samples_LI['a2'])/2.
    if p == 'chiz_minus':
        print(" Transforming ")
        if 'a1z' in samples_LI.dtype.names:
            return (samples_LI['a1z'] - samples_LI['a2z']) / 2.
        if 'theta1' in samples_LI.dtype.names:
            return (samples_LI['a1'] * np.cos(samples_LI['theta1']) -
                    samples_LI['a2'] * np.cos(samples_LI['theta2'])) / 2.
#        return (samples_LI['a1']- samples_LI['a2'])/2.
    if 'theta1' in samples_LI.dtype.names:
        if p == 's1x':
            return samples_LI["a1"] * np.sin(samples_LI['theta1']) * np.cos(
                samples_LI['phi1'])
        if p == 's1y':
            return samples_LI["a1"] * np.sin(samples_LI['theta1']) * np.sin(
                samples_LI['phi1'])
        if p == 's2x':
            return samples_LI["a2"] * np.sin(samples_LI['theta2']) * np.cos(
                samples_LI['phi2'])
        if p == 's2y':
            return samples_LI["a2"] * np.sin(samples_LI['theta2']) * np.sin(
                samples_LI['phi2'])
        if p == 'chi1_perp':
            return samples_LI["a1"] * np.sin(samples_LI['theta1'])
        if p == 'chi2_perp':
            return samples_LI["a2"] * np.sin(samples_LI['theta2'])
    elif 'tilt1' in samples_LI.dtype.names:
        if p == 'chi1_perp':
            return samples_LI["a1"] * np.sin(samples_LI['tilt1'])
        if p == 'chi2_perp':
            return samples_LI["a2"] * np.sin(samples_LI['tilt2'])
    else:  # aligned
        if p == 'chi1_perp':
            return np.zeros(len(samples_LI["m1"]))
        if p == 'chi2_perp':
            return np.zeros(len(samples_LI["m1"]))

    if 'lambdat' in samples_LI.dtype.names:  # LI does sampling in these tidal coordinates
        lambda1, lambda2 = lalsimutils.tidal_lambda_from_tilde(
            samples_LI["m1"], samples_LI["m2"], samples_LI["lambdat"],
            samples_LI["dlambdat"])
        if p == "lambda1":
            return lambda1
        if p == "lambda2":
            return lambda2
    if p == 'delta' or p == 'delta_mc':
        return (samples_LI['m1'] - samples_LI['m2']) / (
            (samples_LI['m1'] + samples_LI['m2']))
    # Return cartesian components of Lhat
    if p == 'product(sin_beta,sin_phiJL)':
        return np.sin(samples_LI[remap_ILE_2_LI['beta']]) * np.sin(
            samples_LI['phi_jl'])
    if p == 'product(sin_beta,cos_phiJL)':
        return np.sin(samples_LI[remap_ILE_2_LI['beta']]) * np.cos(
            samples_LI['phi_jl'])

    if p == 'mc':
        m1v = samples["m1"]
        m2v = samples["m2"]
        return lalsimutils.mchirp(m1v, m2v)
    if p == 'eta':
        m1v = samples["m1"]
        m2v = samples["m2"]
        return lalsimutils.symRatio(m1v, m2v)

    # Backup : access lambdat if not present
    if (p == 'lambdat'
            or p == 'dlambdat') and 'lambda1' in samples.dtype.names:
        Lt, dLt = lalsimutils.tidal_lambda_tilde(samples['m1'], samples['m2'],
                                                 samples['lambda1'],
                                                 samples['lambda2'])
        if p == 'lambdat':
            return Lt
        if p == 'dlambdat':
            return dLt

    if p == "q" and 'm1' in samples.dtype.names:
        return samples["m2"] / samples["m1"]

    print(" No access for parameter ", p, " in ", samples.dtype.names)
    return np.zeros(len(samples_LI['m1']))  # to avoid causing a hard failure
Exemple #3
0
            npts_out = np.sum(indx_ok)
            new_samples = np.recarray((npts_out, ), dtype=samples.dtype)
            for name in samples.dtype.names:
                new_samples[name] = samples[name][indx_ok]
            samples = new_samples
#    samples = np.recarray(samples.T,names=field_names,dtype=field_formats) #,formats=field_formats)
# If no record names
# Add mtotal, q,
        samples = add_field(samples, [('mtotal', float)])
        samples["mtotal"] = samples["m1"] + samples["m2"]
        samples = add_field(samples, [('q', float)])
        samples["q"] = samples["m2"] / samples["m1"]
        samples = add_field(samples, [('mc', float)])
        samples["mc"] = lalsimutils.mchirp(samples["m1"], samples["m2"])
        samples = add_field(samples, [('eta', float)])
        samples["eta"] = lalsimutils.symRatio(samples["m1"], samples["m2"])
        samples = add_field(samples, [('chi_eff', float)])
        samples["chi_eff"] = (samples["m1"] * samples["a1z"] + samples["m2"] *
                              samples["a2z"]) / (samples["mtotal"])
        chi1_perp = np.sqrt(samples['a1x'] * samples["a1x"] +
                            samples['a1y']**2)
        chi2_perp = np.sqrt(samples['a2x']**2 + samples['a2y']**2)
        samples = add_field(samples, [('chi1_perp', float)])
        samples['chi1_perp'] = chi1_perp
        samples = add_field(samples, [('chi2_perp', float)])
        samples['chi2_perp'] = chi2_perp

        if ('lambda1' in samples.dtype.names):
            Lt, dLt = lalsimutils.tidal_lambda_tilde(samples['m1'],
                                                     samples['m2'],
                                                     samples['lambda1'],
Exemple #4
0
def calc_eta(red_data):
    return lalsimutils.symRatio(red_data[:, 1], red_data[:, 2])
Exemple #5
0
def find_effective_Fisher_region(P, IP, target_match, param_names,
                                 param_bounds):
    """
    Example Usage:
        find_effective_Fisher_region(P, IP, 0.9, ['Mc', 'eta'], [[mchirp(P.m1,P.m2)-lal.LAL_MSUN_SI,mchirp(P.m1,P.m2)+lal.LAL_MSUN_SI], [0.05, 0.25]])
    Arguments:
        - P: a ChooseWaveformParams object describing a target signal
        - IP: An inner product class to compute overlaps.
                Should have deltaF and length consistent with P
        - target_match: find parameter variation where overlap is target_match.
                Should be a real number in [0,1]
        - param_names: array of string names for members of P to vary.
                Should have length N for N params to be varied
                e.g. ['Mc', 'eta']
        - param_bounds: array of max variations of each param in param_names
                Should be an Nx2 array for N params to be varied
    
    Returns:
        Array of boundaries of a hypercube meant to encompass region where
                match is >= target_match.
                e.g. [ [3.12,3.16] , [0.12, 0.18] ]

    N.B. Only checks variations along parameter axes. If params are correlated,
    may get better matches off-axis, and the hypercube won't fully encompass
    region where target_match is achieved. Therefore, allow a generous
    safety factor in your value of 'target_match'.
    """
    TOL = 1.e-3  # Don't need to be very precise for this...
    Nparams = len(param_names)
    assert len(param_bounds) == Nparams
    param_cube = []
    hfSIG = lsu.norm_hoff(P, IP)
    for i, param in enumerate(param_names):
        PT = P.copy()
        if param == 'Mc':
            param_peak = lsu.mchirp(P.m1, P.m2)
        elif param == 'eta':
            param_peak = lsu.symRatio(P.m1, P.m2)
        else:
            param_peak = getattr(P, param)
        func = lambda x: update_params_ip(hfSIG, PT, IP, [param], [x]
                                          ) - target_match
        try:
            min_param = brentq(func, param_peak, param_bounds[i][0], xtol=TOL)
        except ValueError:
            print("\nWarning! Value", param_bounds[i][0], "of", param,\
                    "did not bound target match", target_match, ". Using",\
                    param_bounds[i][0], "as the lower bound of", param,\
                    "range for the effective Fisher region.\n")
            min_param = param_bounds[i][0]
        try:
            max_param = brentq(func, param_peak, param_bounds[i][1], xtol=TOL)
        except ValueError:
            print("\nWarning! Value", param_bounds[i][1], "of", param,\
                    "did not bound target match", target_match, ". Using",\
                    param_bounds[i][1], "as the upper bound of", param,\
                    "range for the effective Fisher region.\n")
            max_param = param_bounds[i][1]
        param_cube.append([min_param, max_param])

    return param_cube