コード例 #1
0
ファイル: generator.py プロジェクト: calbooth/pycbc-1
def generator_mchirp_eta_to_mass1_mass2(generator):
    """Converts mchirp and eta in `current_params`, to mass1 and mass2.
    """
    mchirp = generator.current_params['mchirp']
    eta = generator.current_params['eta']
    m1, m2 = pnutils.mchirp_eta_to_mass1_mass2(mchirp, eta)
    generator.current_params['mass1'] = m1
    generator.current_params['mass2'] = m2
コード例 #2
0
ファイル: generator.py プロジェクト: sfairhur/pycbc
def generator_mchirp_eta_to_mass1_mass2(generator):
    """Converts mchirp and eta in `current_params`, to mass1 and mass2.
    """
    mchirp = generator.current_params['mchirp']
    eta = generator.current_params['eta']
    m1, m2 = pnutils.mchirp_eta_to_mass1_mass2(mchirp, eta)
    generator.current_params['mass1'] = m1
    generator.current_params['mass2'] = m2
コード例 #3
0
     'font.serif': ['palatino'],
     'savefig.dpi': 300
     })

#####

f_low = 15.
f_high = 2048.

# True NR parameters
nrs1 = +0.84984534
nrs2 = +0.84976985
nrmc = 29.57934177
nret = 0.22223058
nrmt = nrmc / nret**0.6
nrm1, nrm2 = mchirp_eta_to_mass1_mass2(nrmc, nret)
nrq = nrm1 / eta_mass1_to_mass2(nret, nrm1)

nrwav = UseNRinDA.nr_waveform(
    filename=
    '/home/prayush/research/cita-papers/SEOBtesting/Paper1/plots/InvestigateSimulations/d11.5-q8.5-sA_0_0_0_sB_0_0_0/rhOverM_CcePITT_Asymptotic_GeometricUnits.h5',
    time_length=8)
nrwav.rescale_to_totalmass(nrmt)
nrhp = TimeSeries(nrwav.rescaled_hp, epoch=0)
nrhc = TimeSeries(nrwav.rescaled_hc, epoch=0)
nrh_max_amp_t, _ = nrwav.get_amplitude_peak()

nrwav2 = UseNRinDA.nr_waveform(
    filename=
    '/home/prayush/research/cita-papers/SEOBtesting/Paper1/plots/InvestigateSimulations/d11.5-q8.5-sA_0_0_0_sB_0_0_0/rhOverM_Asymptotic_GeometricUnits.h5',
    time_length=8)
コード例 #4
0
ファイル: types.py プロジェクト: gwnrtools/gwnrtools
 def parameterbiases_vs_parameters(self,
                                   inkey=None,
                                   approx=None,
                                   chieff=False,
                                   total_mass=False):
     """
     Computes the relative/absolute differences between maximum-overlap
     parameters and those of the injections themselves. Default behavior
     is to return biases in 
     - chirp mass, 
     - eta, 
     - spin1, 
     - spin2, but
     the following input flags alter this : 
     - total_mass = true ==> instead of chirp mass, total mass diffs're returned
     """
     # {{{
     if chieff:
         from pycbc import pnutils
     else:
         print("Not using effective spin", file=sys.stdout)
     for kk in list(self.data.keys()):
         if inkey in kk:
             break
     for app in list(self.data[kk].keys()):
         if approx in app:
             break
     masses = np.array(list(self.data[inkey][app].keys()))
     masses.sort()
     ff = np.array([max(self.data[inkey][app][mm][:, -1]) for mm in masses])
     sig_mc = np.array([
         self.data[inkey][app][mm][np.where(
             self.data[inkey][app][mm][:, -1] ==
             max(self.data[inkey][app][mm][:, -1]))[0][0], -5]
         for mm in masses
     ])
     sig_et = np.array([
         self.data[inkey][app][mm][np.where(
             self.data[inkey][app][mm][:, -1] ==
             max(self.data[inkey][app][mm][:, -1]))[0][0], -4]
         for mm in masses
     ])
     if chieff:
         sig_m1, sig_m2 = pnutils.mchirp_eta_to_mass1_mass2(sig_mc, sig_et)
     if total_mass:
         sig_mt = sig_mc * sig_et**-0.6
     sig_s1 = np.array([
         self.data[inkey][app][mm][np.where(
             self.data[inkey][app][mm][:, -1] ==
             max(self.data[inkey][app][mm][:, -1]))[0][0], -3]
         for mm in masses
     ])
     sig_s2 = np.array([
         self.data[inkey][app][mm][np.where(
             self.data[inkey][app][mm][:, -1] ==
             max(self.data[inkey][app][mm][:, -1]))[0][0], -2]
         for mm in masses
     ])
     # NR parameters are fixed for a simulation, so they dont need to be
     # accumulated
     nr_et = self.data[inkey][app][mm][0, 1]
     nr_q = (1. + (1. - 4. * nr_et)**0.5 - 2. * nr_et) / (2. * nr_et)
     nr_q = np.ones(len(ff)) * nr_q  # Its constant
     nr_et = np.ones(len(ff)) * nr_et
     nr_mc = masses * nr_et**0.6
     if chieff:
         nr_m1, nr_m2 = pnutils.mchirp_eta_to_mass1_mass2(nr_mc, nr_et)
     nr_s1 = np.ones(len(ff)) * \
         self.data[inkey][app][mm][0, 2]  # Its constant
     nr_s2 = np.ones(len(ff)) * \
         self.data[inkey][app][mm][0, 3]  # Its constant
     #
     if chieff:
         # Compute PN effective spins
         #nr_seff = spins_to_PNeffective_spin(nr_m1, nr_m2, nr_s1, nr_s2)
         #sig_seff= spins_to_PNeffective_spin(sig_m1, sig_m2, sig_s1, sig_s2)
         nr_seff = spins_to_massweighted_spin(nr_m1, nr_m2, nr_s1, nr_s2)
         sig_seff = spins_to_massweighted_spin(sig_m1, sig_m2, sig_s1,
                                               sig_s2)
     #mc_diff = (nr_mc-sig_mc)/nr_mc
     #eta_diff = (nr_et-sig_et)/nr_et
     #
     # NB: here 'mc_diff' really can contain either mchirp or mtotal differences,
     # please do not pay attention to the nomenclature 'mc'
     if total_mass:
         mc_diff = (sig_mt - masses) / masses
     else:
         mc_diff = (sig_mc - nr_mc) / nr_mc
     eta_diff = (sig_et - nr_et) / nr_et
     # Handle spins specially for q = 1
     if 'q1' not in inkey:
         if chieff:
             s1_diff = sig_seff - nr_seff
         else:
             s1_diff = sig_s1 - nr_s1  # nr_s1-sig_s1
         s2_diff = sig_s2 - nr_s2  # nr_s2-sig_s2
     else:
         s1_diff, s2_diff = np.zeros(len(nr_s1)), np.zeros(len(nr_s2))
         s11d, s12d = sig_s1 - nr_s1, sig_s2 - nr_s1  # nr_s1 - sig_s1, nr_s1 - sig_s2
         s21d, s22d = sig_s1 - nr_s2, sig_s2 - nr_s2  # nr_s2 - sig_s1, nr_s2 - sig_s2
         s1122rms = (s11d**2 + s22d**2)**0.5
         s1221rms = (s12d**2 + s21d**2)**0.5
         mask = s1122rms < s1221rms
         s1_diff[mask] = s11d[mask]
         s2_diff[mask] = s22d[mask]
         mask = s1122rms >= s1221rms
         s1_diff[mask] = s12d[mask]
         s2_diff[mask] = s21d[mask]
         if chieff:
             s1_diff = sig_seff - nr_seff
     return masses, nr_q, nr_s1, nr_s2, mc_diff, eta_diff, s1_diff, s2_diff, ff
コード例 #5
0
def calculate_fitting_factor(m1, m2,
                             s1x=0, s1y=0, s1z=0,
                             s2x=0, s2y=0, s2z=0,
                             tc=0, phic=0,
                             ra=0, dec=0, polarization=0,
                             signal_approx='IMRPhenomD',
                             signal_file=None,
                             tmplt_approx='IMRPhenomC',
                             vary_masses_only=True,
                             vary_masses_and_aligned_spin_only=False,
                             chirp_mass_window=0.1,
                             effective_spin_window=0.5,
                             num_retries=4,
                             f_lower=15.0,
                             sample_rate=4096,
                             signal_duration=256,
                             psd_string='aLIGOZeroDetHighPower',
                             pso_swarm_size=500,
                             pso_omega=0.5,
                             pso_phip=0.5,
                             pso_phig=0.25,
                             pso_minfunc=1e-8,
                             verbose=True,
                             debug=False):
    """
Calculates the fitting factor for a signal of given physical
parameters, as modelled by a given signal approximant, against
templates of another approximant.

This function uses a particle swarm optimization to maximize
the overlaps between signal and templates. Algorithm parameters
are tunable, depending on how many dimensions we are optimizing
over.

IN PROGRESS: Adding facility to use "FromDataFile" waveforms
    """
    # {{{
    # 0) OPTION CHECKING
    if vary_masses_only:
        print("WARNING: Only component masses are allowed to be varied in templates. Setting the rest to signal values.")
    if vary_masses_and_aligned_spin_only:
        print("WARNING: Only component masses and spin components parallel to L allowed to be varied in templates. Setting the rest to signal values.")
    if vary_masses_only and vary_masses_and_aligned_spin_only:
        raise IOError(
            "Inconsistent options: vary_masses_only and vary_masses_and_aligned_spin_only")
    if (not vary_masses_only) and (not vary_masses_and_aligned_spin_only):
        print("WARNING: All mass and spin components varied in templates. Sky parameters still fixed to signal values.")

    # 1) GENERATE FILTERING META-PARAMETERS
    signal_duration = int(signal_duration)
    sample_rate = int(sample_rate)
    filter_N = signal_duration * sample_rate
    filter_n = filter_N / 2 + 1
    delta_t = 1./sample_rate
    delta_f = 1./signal_duration
    if verbose:
        print("signal_duration = %d, sample_rate = %d, filter_N = %d, filter_n = %d" % (
            signal_duration, sample_rate, filter_N, filter_n))
        print("deltaT = %f, deltaF = %f" % (delta_t, delta_f))
    # LIGO Noise PSD
    psd = from_string(psd_string, filter_n, delta_f, f_lower)

    # 2) GENERATE THE TARGET SIGNAL
    # PREPARATORY: Get the signal generator
    if signal_approx in pywf.fd_approximants():
        generator = pywfg.FDomainDetFrameGenerator(pywfg.FDomainCBCGenerator, 0,
                                                   variable_args=['mass1', 'mass2',
                                                                  'spin1x', 'spin1y', 'spin1z',
                                                                  'spin2x', 'spin2y', 'spin2z',
                                                                  'coa_phase',
                                                                  'tc', 'ra', 'dec', 'polarization'],
                                                   detectors=['H1'],
                                                   delta_f=delta_f, f_lower=f_lower,
                                                   approximant=signal_approx)
    elif signal_approx in pywf.td_approximants():
        generator = pywfg.TDomainDetFrameGenerator(pywfg.TDomainCBCGenerator, 0,
                                                   variable_args=['mass1', 'mass2',
                                                                  'spin1x', 'spin1y', 'spin1z',
                                                                  'spin2x', 'spin2y', 'spin2z',
                                                                  'coa_phase',
                                                                  'tc', 'ra', 'dec', 'polarization'],
                                                   detectors=['H1'],
                                                   delta_t=delta_t, f_lower=f_lower,
                                                   approximant=signal_approx)
    elif 'FromDataFile' in signal_approx:
        if os.path.getsize(signal_file) == 0:
            raise RuntimeError(
                " ERROR:...OOPS. Waveform file %s empty!!" % signal_file)
        try:
            _ = np.loadtxt(signal_file)
        except:
            raise RuntimeError(
                " WARNING: FAILURE READING DATA FROM %s.." % signal_file)

        waveform_params = lsctables.SimInspiral()
        waveform_params.latitude = 0
        waveform_params.longitude = 0
        waveform_params.polarization = 0
        waveform_params.spin1x = 0
        waveform_params.spin1y = 0
        waveform_params.spin1z = 0
        waveform_params.spin2x = 0
        waveform_params.spin2y = 0
        waveform_params.spin2z = 0
        # try:
        if True:
            if verbose:
                print(".. generating signal waveform ")
            signal_htilde, _params = get_waveform(signal_approx,
                                                  -1, -1, -1,
                                                  waveform_params,
                                                  f_lower,
                                                  sample_rate,
                                                  filter_N,
                                                  datafile=signal_file)
            print(".. generated signal waveform ")
            m1, m2, w_value, _ = _params
            waveform_params.mass1 = m1
            waveform_params.mass2 = m2
            signal_h = make_frequency_series(signal_htilde)
            signal_h = extend_waveform_FrequencySeries(signal_h, filter_n)
        # except: raise IOError("Approximant %s not found.." % signal_approx)
    else:
        raise IOError("Approximant %s not found.." % signal_approx)

    if verbose:
        print(
            "\nGenerating signal with masses = %3f, %.3f, spin1 = (%.3f, %.3f, %.3f), and  spin2 = (%.3f, %.3f, %.3f)" %
            (m1, m2, s1x, s1y, s1z, s2x, s2y, s2z))
        sys.stdout.flush()

    # Actually GENERATE THE SIGNAL
    if signal_approx in pywf.fd_approximants():
        signal = generator.generate_from_args(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z,
                                              phic, tc, ra, dec, polarization)
        signal_h = extend_waveform_FrequencySeries(signal['H1'], filter_n)
    elif signal_approx in pywf.td_approximants():
        signal = generator.generate_from_args(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z,
                                              phic, tc, ra, dec, polarization)
        signal_h = make_frequency_series(signal['H1'])
        signal_h = extend_waveform_FrequencySeries(signal_h, filter_n)
    elif 'FromDataFile' in signal_approx:
        pass
    else:
        raise IOError("Approximant %s not found.." % signal_approx)

    ###
    # NOW : Set up PSO calculation of the optimal overlap parameter set, i.e. \theta(FF)
    ###

    # 3) INITIALIZE THE WAVEFORM GENERATOR FOR TEMPLATES
    # We allow all intrinsic parameters to vary, and fix them to the signal
    # values, in case only masses or only mass+aligned-spin components are
    # requested to be varied. This fixing is done inside the objective function.
    if tmplt_approx in pywf.fd_approximants():
        generator_tmplt = pywfg.FDomainDetFrameGenerator(pywfg.FDomainCBCGenerator, 0,
                                                         variable_args=['mass1', 'mass2',
                                                                        'spin1x', 'spin1y', 'spin1z',
                                                                        'spin2x', 'spin2y', 'spin2z'
                                                                        ],
                                                         detectors=['H1'],
                                                         coa_phase=phic,
                                                         tc=tc, ra=ra, dec=dec, polarization=polarization,
                                                         delta_f=delta_f, f_lower=f_lower,
                                                         approximant=tmplt_approx)
    elif tmplt_approx in pywf.td_approximants():
        raise IOError(
            "Time-domain templates not supported yet (TDomainDetFrameGenerator doesn't exist)")
        generator_tmplt = pywfg.TDomainDetFrameGenerator(pywfg.TDomainCBCGenerator, 0,
                                                         variable_args=['mass1', 'mass2',
                                                                        'spin1x', 'spin1y', 'spin1z',
                                                                        'spin2x', 'spin2y', 'spin2z'
                                                                        ],
                                                         detectors=['H1'],
                                                         coa_phase=phic,
                                                         tc=tc, ra=ra, dec=dec, polarization=polarization,
                                                         delta_t=delta_t, f_lower=f_lower,
                                                         approximant=tmplt_approx)
    elif 'FromDataFile' in tmplt_approx:
        raise RuntimeError(
            "Using **templates** from data files is not implemented yet")
    else:
        raise IOError("Approximant %s not found.." % tmplt_approx)

    # 4) DEFINE AN OBJECTIVE FUNCTION FOR PSO TO MINIMIZE
    def objective_function_fitting_factor(x, *args):
        """
        This function is to be minimized if the fitting factor is to be found
        """
        objective_function_fitting_factor.counter += 1
        # 1) OBTAIN THE TEMPLATE PARAMETERS FROM X. ASSUME THAT ONLY
        # THOSE ARE PASSED THAT ARE NEEDED BY THE GENERATOR
        if len(x) == 2:
            m1, m2 = x
            if vary_masses_only:
                _s1x = _s1y = _s1z = _s2x = _s2y = _s2z = 0
            else:
                _s1x, _s1y, _s1z = s1x, s1y, s1z
                _s2x, _s2y, _s2z = s2x, s2y, s2z
        elif len(x) == 4:
            m1, m2, _s1z, _s2z = x
            if vary_masses_and_aligned_spin_only:
                _s1x = _s1y = _s2x = _s2y = 0
            else:
                _s1x, _s1y = s1x, s1y
                _s2x, _s2y = s2x, s2y
        elif len(x) == 8:
            m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z = x
        else:
            raise IOError(
                "No of vars %d not supported (should be 2 or 4 or 8)" % len(x))

        # 2) CHECK FOR CONSISTENCY
        if (_s1x**2 + _s1y**2 + _s1z**2) > s_max or (_s2x**2 + _s2y**2 + _s2z**2) > s_max:
            return 1e99

        # 2) ASSUME THAT
        signal_h, tmplt_generator = args
        tmplt = tmplt_generator.generate_from_args(
            m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z)
        tmplt_h = make_frequency_series(tmplt['H1'])

        if debug:
            print("IN FF Objective-> for parameters:",  m1,
                  m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z)
        if debug:
            print("IN FF Objective-> Length(tmplt) = %d, making it %d" %
                  (len(tmplt['H1']), filter_n))
        # NOTE: SEOBNRv4 has extra high frequency content, it seems..
        if 'SEOBNRv4_ROM' in tmplt_approx or 'SEOBNRv2_ROM' in tmplt_approx:
            tmplt_h = extend_waveform_FrequencySeries(
                tmplt_h, filter_n, force_fit=True)
        else:
            tmplt_h = extend_waveform_FrequencySeries(tmplt_h, filter_n)

        # 3) COMPUTE MATCH
        m, _ = match(signal_h, tmplt_h, psd=psd, low_frequency_cutoff=f_lower)

        if debug:
            print("MATCH IS %.6f for parameters:" %
                  m, m1, m2, _s1x, _s1y, _s1z, _s2x, _s2y, _s2z)

        retval = np.log10(1. - m)

        # We do not want PSO to go berserk, so we stop when FF = 0.999999
        if retval <= -6.0:
            retval = -6.0
        return retval
    objective_function_fitting_factor.counter = 0

    # 5) DEFINE A CONSTRAINT FUNCTION FOR PSO TO RESPECT
    def constraint_function_fitting_factor(x, *args):
        """
        This function implements constraints on the optimization of fitting
        factors:
        1) spin magnitudes on both holes should be <= 1

        """
        if len(x) == 2:
            m1, m2 = x
            s1x = s1y = s1z = s2x = s2y = s2z = 0
        elif len(x) == 4:
            m1, m2, s1z, s2z = x
            s1x = s1y = s2x = s2y = 0
        elif len(x) == 8:
            m1, m2, s1x, s1y, s1z, s2x, s2y, s2z = x
        # 1) Constraint on spin magnitudes
        s1_mag = (s1x**2 + s1y**2 + s1z**2)**0.5
        s2_mag = (s2x**2 + s2y**2 + s2z**2)**0.5
        ##
        if (s1_mag > s_max) or (s2_mag > s_max):
            return -1
        # 2) Constraint on effective spin
        s_eff = (s1z * m1 + s2z * m2) / (m1 + m2)
        ##
        if (s_eff > s_eff_max) or (s_eff < s_eff_min):
            return -1
        # FINALLY) DEFAULT
        return 1

    # 6) FINALLY, CALL THE PSO TO COMPUTE THE FITTING FACTOR
    # 6a) FIRST CONSTRUCT THE FIXED ARGUMENTS FOR THE PSO's OBJECTIVE FUNCTION
    pso_args = (signal_h, generator_tmplt)

    # 6b) NOW SET THE RANGE OF PARAMETERS TO BE PROBED
    mt = m1 + m2 * 1.0
    et = m1 * m2 / mt / mt
    mc = mt * et**0.6
    mc_min = mc * (1.0 - chirp_mass_window)
    mc_max = mc * (1.0 + chirp_mass_window)
    et_max = 0.25
    et_min = 10. / 121.  # Lets say we trust waveform models up to q = 10
    m1_max, _ = pnutils.mchirp_eta_to_mass1_mass2(mc_max, et_min)
    m1_min, _ = pnutils.mchirp_eta_to_mass1_mass2(mc_min, et_max)
    _,      m2_max = pnutils.mchirp_eta_to_mass1_mass2(mc_max, et_max)
    _,      m2_min = pnutils.mchirp_eta_to_mass1_mass2(mc_min, et_min)
    s_min = -0.99
    s_max = +0.99
    s_eff = (s1z * m1 + s2z * m2) / (m1 + m2)
    s_eff_min = s_eff - effective_spin_window
    s_eff_max = s_eff + effective_spin_window

    if verbose:
        print(m1, m2, mt, et, mc, mc_min, mc_max, et_min,
              et_max, m1_min, m1_max, m2_min, m2_max)

    if vary_masses_only:
        low_lim = [m1_min, m2_min]
        high_lim = [m1_max, m2_max]
    elif vary_masses_and_aligned_spin_only:
        low_lim = [m1_min, m2_min, s_min, s_min]
        high_lim = [m1_max, m2_max, s_max, s_max]
    else:
        low_lim = [m1_min, m2_min, s_min, s_min, s_min, s_min, s_min, s_min]
        high_lim = [m1_max, m2_max, s_max, s_max, s_max, s_max, s_max, s_max]
    #
    if verbose:
        print("\nSearching within limits:\n", low_lim, " and \n", high_lim)
        print("\nCalculating overlap now..")
        sys.stdout.flush()
    olap, idx = calculate_faithfulness(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z,
                                       tc=tc, phic=phic,
                                       ra=ra, dec=dec,
                                       polarization=polarization,
                                       signal_approx=signal_approx,
                                       signal_file=signal_file,
                                       tmplt_approx=tmplt_approx,
                                       tmplt_file=None,
                                       aligned_spin_tmplt_only=vary_masses_and_aligned_spin_only,
                                       non_spin_tmplt_only=vary_masses_only,
                                       f_lower=f_lower, sample_rate=sample_rate,
                                       signal_duration=signal_duration,
                                       verbose=verbose, debug=debug)
    #
    if verbose:
        print("Overlap with aligned_spin_tmplt_only = ", vary_masses_and_aligned_spin_only,
              " and non_spin_tmplt_only = ", vary_masses_only, ": ", olap, np.log10(
                  1. - olap))
        sys.stdout.flush()
    #
    idx = 1
    ff = 0.0
    while ff < olap:
        if idx and idx % 2 == 0:
            pso_minfunc *= 0.1
            pso_phig *= 1.1

        if idx > num_retries:
            print(
                "WARNING: Failed to improve on overlap in %d iterations. Set ff = olap now" % num_retries)
            ff = olap
            break

        if verbose:
            print("\nTry %d to compute fitting factor" % idx)
            sys.stdout.flush()
        params, ff = pso(objective_function_fitting_factor,
                         low_lim, high_lim,
                         f_ieqcons=constraint_function_fitting_factor,
                         args=pso_args,
                         swarmsize=pso_swarm_size,
                         omega=pso_omega,
                         phip=pso_phip,
                         phig=pso_phig,
                         minfunc=pso_minfunc,
                         maxiter=500,
                         debug=verbose)
        # Restore fitting factor from 1-ff
        ff = 1.0 - 10**ff
        if verbose:
            print("\nLoop will continue till %.12f < %.12f" % (ff, olap))
            sys.stdout.flush()
        idx += 1

    if verbose:
        print("optimization took %d objective func evals" %
              objective_function_fitting_factor.counter)
        sys.stdout.flush()
    #
    # 7) RETURN OPTIMIZED PARAMETERS
    return [params, olap, ff]
コード例 #6
0
ファイル: option_utils.py プロジェクト: AbhayMK/pycbc
def verify_mass_range_options(opts, parser, nonSpin=False):
    """
    Parses the metric calculation options given and verifies that they are
    correct.

    Parameters
    ----------
    opts : argparse.Values instance
        Result of parsing the input options with OptionParser
    parser : object
        The OptionParser instance.
    nonSpin : boolean, optional (default=False)
        If this is provided the spin-related options will not be checked.
    """
    if not opts.min_mass1:
        parser.error("Must supply --min-mass1")
    if not opts.min_mass2:
        parser.error("Must supply --min-mass2")
    if not opts.max_mass1:
        parser.error("Must supply --max-mass1")
    if not opts.max_mass2:
        parser.error("Must supply --max-mass2")
    # Mass1 must be the heavier!
    if opts.min_mass1 < opts.min_mass2:
        parser.error("min-mass1 cannot be less than min-mass2!")
    if opts.max_mass1 < opts.max_mass2:
        parser.error("max-mass1 cannot be less than max-mass2!")
    # If given are min/max total mass/chirp mass possible?
    if opts.min_total_mass:
        if opts.min_total_mass > opts.max_mass1 + opts.max_mass2:
            err_msg = "Supplied minimum total mass %f " %(opts.min_total_mass,)
            err_msg += "greater than the sum of the two max component masses "
            err_msg += " %f and %f." %(opts.max_mass1,opts.max_mass2)
    if opts.max_total_mass:
        if opts.max_total_mass < opts.min_mass1 + opts.min_mass2:
            err_msg = "Supplied maximum total mass %f " %(opts.max_total_mass,)
            err_msg += "smaller than the sum of the two min component masses "
            err_msg += " %f and %f." %(opts.min_mass1,opts.min_mass2)
            raise ValueError(err_msg)
    if opts.max_total_mass and opts.min_total_mass:
        if opts.max_total_mass < opts.min_total_mass:
            err_msg = "Min total mass must be larger than max total mass."
            raise ValueError(err_msg)

    # Assign min/max total mass from mass1, mass2 if not specified
    if (not opts.min_total_mass) or \
            ((opts.min_mass1 + opts.min_mass2) > opts.min_total_mass):
        opts.min_total_mass = opts.min_mass1 + opts.min_mass2
    if (not opts.max_total_mass) or \
            ((opts.max_mass1 + opts.max_mass2) < opts.max_total_mass):
        opts.max_total_mass = opts.max_mass1 + opts.max_mass2

    # It is vital that min and max total mass be set correctly.
    # This is becasue the heavily-used function get_random_mass will place
    # points first in total mass (to some power), and then in eta. If the total
    # mass limits are not well known ahead of time it will place unphysical
    # points and fail.
    # This test is a bit convoluted as we identify the maximum and minimum
    # possible total mass from chirp mass and/or eta restrictions.
    if opts.min_chirp_mass is not None:
        # Need to get the smallest possible min_tot_mass from this chirp mass
        # There are 4 possibilities for where the min_tot_mass is found on the
        # line of min_chirp_mass that interacts with the component mass limits.
        # Either it is found at max_m2, or at min_m1, or it starts on the equal
        # mass line within the parameter space, or it doesn't intersect
        # at all.
        # First let's get the masses at both of these possible points
        m1_at_max_m2 = pnutils.mchirp_mass1_to_mass2(opts.min_chirp_mass,
                                                     opts.max_mass2)
        if m1_at_max_m2 < opts.max_mass2:
            # Unphysical, remove
            m1_at_max_m2 = -1
        m2_at_min_m1 = pnutils.mchirp_mass1_to_mass2(opts.min_chirp_mass,
                                                      opts.min_mass1)
        if m2_at_min_m1 > opts.min_mass1:
            # Unphysical, remove
            m2_at_min_m1 = -1
        # Get the values on the equal mass line
        m1_at_equal_mass, m2_at_equal_mass = pnutils.mchirp_eta_to_mass1_mass2(
                                                     opts.min_chirp_mass, 0.25)

        # Are any of these possible?
        if m1_at_max_m2 <= opts.max_mass1 and m1_at_max_m2 >= opts.min_mass1:
            min_tot_mass = opts.max_mass2 + m1_at_max_m2
        elif m2_at_min_m1 <= opts.max_mass2 and m2_at_min_m1 >= opts.min_mass2:
            min_tot_mass = opts.min_mass1 + m2_at_min_m1
        elif m1_at_equal_mass <= opts.max_mass1 and \
                 m1_at_equal_mass >= opts.min_mass1 and \
                 m2_at_equal_mass <= opts.max_mass2 and \
                 m2_at_equal_mass >= opts.min_mass2:
            min_tot_mass = m1_at_equal_mass + m2_at_equal_mass
        # So either the restriction is low enough to be redundant, or is
        # removing all the parameter space
        elif m2_at_min_m1 < opts.min_mass2:
            # This is the redundant case, ignore
            min_tot_mass = opts.min_total_mass
        else:
            # And this is the bad case
            err_msg = "The minimum chirp mass provided is not possible given "
            err_msg += "restrictions on component masses."
            raise ValueError(err_msg)
        # Is there also an eta restriction?
        if opts.max_eta:
            # Get the value of m1,m2 at max_eta, min_chirp_mass
            max_eta_m1, max_eta_m2 = pnutils.mchirp_eta_to_mass1_mass2(
                                         opts.min_chirp_mass, opts.max_eta)
            max_eta_min_tot_mass = max_eta_m1 + max_eta_m2
            if max_eta_min_tot_mass > min_tot_mass:
                # Okay, eta does restrict this further. Still physical?
                min_tot_mass = max_eta_min_tot_mass
                if max_eta_m1 > opts.max_mass1:
                    err_msg = "The combination of component mass, chirp "
                    err_msg += "mass, eta and (possibly) total mass limits "
                    err_msg += "have precluded all systems."
                    raise ValueError(err_msg)
        # Update min_tot_mass if needed
        if min_tot_mass > opts.min_total_mass:
            opts.min_total_mass = float(min_tot_mass)

    # Then need to do max_chirp_mass and min_eta
    if opts.max_chirp_mass is not None:
        # Need to get the largest possible maxn_tot_mass from this chirp mass
        # There are 3 possibilities for where the max_tot_mass is found on the
        # line of max_chirp_mass that interacts with the component mass limits.
        # Either it is found at min_m2, or at max_m1, or it doesn't intersect
        # at all.
        # First let's get the masses at both of these possible points
        m1_at_min_m2 = pnutils.mchirp_mass1_to_mass2(opts.max_chirp_mass,
                                                     opts.min_mass2)
        m2_at_max_m1 = pnutils.mchirp_mass1_to_mass2(opts.max_chirp_mass,
                                                      opts.max_mass1)
        # Are either of these possible?
        if m1_at_min_m2 <= opts.max_mass1 and m1_at_min_m2 >= opts.min_mass1:
            max_tot_mass = opts.min_mass2 + m1_at_min_m2
        elif m2_at_max_m1 <= opts.max_mass2 and m2_at_max_m1 >= opts.min_mass2:
            max_tot_mass = opts.max_mass1 + m2_at_max_m1
        # So either the restriction is low enough to be redundant, or is
        # removing all the paramter space
        elif m2_at_max_m1 > opts.max_mass2:
            # This is the redundant case, ignore
            max_tot_mass = opts.max_total_mass
        else:
            # And this is the bad case
            err_msg = "The maximum chirp mass provided is not possible given "
            err_msg += "restrictions on component masses."
            raise ValueError(err_msg)
        # Is there also an eta restriction?
        if opts.min_eta:
            # Get the value of m1,m2 at max_eta, min_chirp_mass
            min_eta_m1, min_eta_m2 = pnutils.mchirp_eta_to_mass1_mass2(
                                         opts.max_chirp_mass, opts.min_eta)
            min_eta_max_tot_mass = min_eta_m1 + min_eta_m2
            if min_eta_max_tot_mass < max_tot_mass:
                # Okay, eta does restrict this further. Still physical?
                max_tot_mass = min_eta_max_tot_mass
                if min_eta_m1 < opts.min_mass1:
                    err_msg = "The combination of component mass, chirp "
                    err_msg += "mass, eta and (possibly) total mass limits "
                    err_msg += "have precluded all systems."
                    raise ValueError(err_msg)
        # Update min_tot_mass if needed
        if max_tot_mass < opts.max_total_mass:
            opts.max_total_mass = float(max_tot_mass)

    # Need to check max_eta alone for minimum and maximum mass
    if opts.max_eta:
        # Similar to above except this can affect both the minimum and maximum
        # total mass. Need to identify where the line of max_eta intersects
        # the parameter space, and if it affects mass restrictions.
        m1_at_min_m2 = pnutils.eta_mass1_to_mass2(opts.max_eta, opts.min_mass2,
                                                      return_mass_heavier=True)
        m2_at_min_m1 = pnutils.eta_mass1_to_mass2(opts.max_eta, opts.min_mass1,
                                                     return_mass_heavier=False)
        m1_at_max_m2 = pnutils.eta_mass1_to_mass2(opts.max_eta, opts.max_mass2,
                                                      return_mass_heavier=True)
        m2_at_max_m1 = pnutils.eta_mass1_to_mass2(opts.max_eta, opts.max_mass1,
                                                      return_mass_heavier=False)
        # Check for restrictions on the minimum total mass
        # Are either of these possible?
        if m1_at_min_m2 <= opts.max_mass1 and m1_at_min_m2 >= opts.min_mass1:
            min_tot_mass = opts.min_mass2 + m1_at_min_m2
        elif m2_at_min_m1 <= opts.max_mass2 and m2_at_min_m1 >= opts.min_mass2:
            # This case doesn't change the minimal total mass
            min_tot_mass = opts.min_total_mass
        # So either the restriction is low enough to be redundant, or is
        # removing all the paramter space
        elif m2_at_min_m1 > opts.max_mass2:
            # This is the redundant case, ignore
            min_tot_mass = opts.min_total_mass
        else:
            # And this is the bad case
            err_msg = "The maximum eta provided is not possible given "
            err_msg += "restrictions on component masses."
            raise ValueError(err_msg)
        # Update min_tot_mass if needed
        if min_tot_mass > opts.min_total_mass:
            opts.min_total_mass = float(min_tot_mass)

        # Check for restrictions on the maximum total mass
        # Are either of these possible?
        if m2_at_max_m1 <= opts.max_mass2 and m2_at_max_m1 >= opts.min_mass2:
            max_tot_mass = opts.max_mass1 + m2_at_max_m1
        elif m1_at_max_m2 <= opts.max_mass1 and m1_at_max_m2 >= opts.min_mass1:
            # This case doesn't change the maximal total mass
            max_tot_mass = opts.max_total_mass
        # So either the restriction is low enough to be redundant, or is
        # removing all the paramter space, the latter case is already tested
        else:
            # This is the redundant case, ignore
            max_tot_mass = opts.max_total_mass
        if max_tot_mass < opts.max_total_mass:
            opts.max_total_mass = float(max_tot_mass)

    # Need to check min_eta alone for maximum and minimum total mass
    if opts.min_eta:
        # Same as max_eta.
        # Need to identify where the line of max_eta intersects
        # the parameter space, and if it affects mass restrictions.
        m1_at_min_m2 = pnutils.eta_mass1_to_mass2(opts.min_eta, opts.min_mass2,
                                                      return_mass_heavier=True)
        m2_at_min_m1 = pnutils.eta_mass1_to_mass2(opts.min_eta, opts.min_mass1,
                                                     return_mass_heavier=False)
        m1_at_max_m2 = pnutils.eta_mass1_to_mass2(opts.min_eta, opts.max_mass2,
                                                      return_mass_heavier=True)
        m2_at_max_m1 = pnutils.eta_mass1_to_mass2(opts.min_eta, opts.max_mass1,
                                                      return_mass_heavier=False)

        # Check for restrictions on the maximum total mass
        # Are either of these possible?
        if m1_at_max_m2 <= opts.max_mass1 and m1_at_max_m2 >= opts.min_mass1:
            max_tot_mass = opts.max_mass2 + m1_at_max_m2

        elif m2_at_max_m1 <= opts.max_mass2 and m2_at_max_m1 >= opts.min_mass2:
            # This case doesn't affect the maximum total mass
            max_tot_mass = opts.max_total_mass
        # So either the restriction is low enough to be redundant, or is
        # removing all the paramter space
        elif m2_at_max_m1 < opts.min_mass2:
            # This is the redundant case, ignore
            max_tot_mass = opts.max_total_mass
        else:
            # And this is the bad case
            err_msg = "The minimum eta provided is not possible given "
            err_msg += "restrictions on component masses."
            raise ValueError(err_msg)
        # Update min_tot_mass if needed
        if max_tot_mass < opts.max_total_mass:
            opts.max_total_mass = float(max_tot_mass)

        # Check for restrictions on the minimum total mass
        # Are either of these possible?
        if m2_at_min_m1 <= opts.max_mass2 and m2_at_min_m1 >= opts.min_mass2:
            min_tot_mass = opts.min_mass1 + m2_at_min_m1
        elif m1_at_min_m2 <= opts.max_mass1 and m1_at_min_m2 >= opts.min_mass1:
            # This case doesn't change the maximal total mass
            min_tot_mass = opts.min_total_mass
        # So either the restriction is low enough to be redundant, or is
        # removing all the paramter space, which is tested above
        else:
            # This is the redundant case, ignore
            min_tot_mass = opts.min_total_mass
        if min_tot_mass > opts.min_total_mass:
            opts.min_total_mass = float(min_tot_mass)

    if opts.max_total_mass < opts.min_total_mass:
        err_msg = "After including restrictions on chirp mass, component mass, "
        err_msg += "eta and total mass, no physical systems are possible."
        raise ValueError(err_msg)

    if opts.max_eta and opts.min_eta:
        if opts.max_eta < opts.min_eta:
            parser.error("--max-eta must be larger than --min-eta.")
    if nonSpin:
        return

    if opts.max_ns_spin_mag is None:
        if opts.nsbh_flag:
            parser.error("Must supply --max_ns_spin_mag with --nsbh-flag")
        # Can ignore this if no NSs will be generated
        elif opts.min_mass2 < (opts.ns_bh_boundary_mass or
                massRangeParameters.default_nsbh_boundary_mass):
            parser.error("Must supply --max-ns-spin-mag for the chosen"
                         " value of --min_mass2")
        else:
            opts.max_ns_spin_mag = opts.max_bh_spin_mag
    if opts.max_bh_spin_mag is None:
        if opts.nsbh_flag:
            parser.error("Must supply --max_bh_spin_mag with --nsbh-flag")
        # Can ignore this if no BHs will be generated
        if opts.max_mass1 >= (opts.ns_bh_boundary_mass or
                massRangeParameters.default_nsbh_boundary_mass):
            parser.error("Must supply --max-bh-spin-mag for the chosen"
                         " value of --max_mass1")
        else:
            opts.max_bh_spin_mag = opts.max_ns_spin_mag
コード例 #7
0
    theta_a12[s] = sim['theta_a12']

    SeffdotL[s] = sim['SeffdotL']
    SeffcrossL[s] = sim['SeffcrossL']

    SdotL[s] = sim['theta_SdotL']
    theta_SdotL[s] = sim['theta_SdotL']


    for n in xrange(config.nsampls):

        chirp_masses[s,n] = masses[s,n] * sim['eta']**(3./5) 

    mass1, mass2 = \
            pnutils.mchirp_eta_to_mass1_mass2(np.median(chirp_masses[s,:]),
                    sim['eta'])
    chieff[s] = pnutils.phenomb_chi(mass1, mass2, sim['spin1z'],
            sim['spin2z'])

median_chirp_masses = np.median(chirp_masses, axis=1)
std_chirp_masses    = np.std(chirp_masses, axis=1)

matchsort = np.argsort(median_matches)
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Summary for %s"%args[0]
print ""
print "   * Highest (median) Match: %f +/- %f"%(median_matches[matchsort][-1],
        std_matches[matchsort][-1])
print "   * Waveform: %s"%(
        simulations_goodmatch[matchsort][-1]['wavefile'].split('/')[-1])
print "   * mass ratio: %f"%(mass_ratios[matchsort][-1])