示例#1
0
def setup_analytical_cluster(simulation, i=0):
    """ Set up an analytical cluster given sampled parameters of the halo.
        In Toycluster we have two haloes: halo[0] and halo[1].

        Toycluster runtime output is piped to runToycluster.log.
        This output is then parsed by `Toycluster2RuntimeOutputParser' class
        and saved in the `NumericalCluster' instance `simulation' class
        variable `toyclusterlog'.

        toyclusterlog has a 2D dict halosetup, where
        halosetup[0][...] gives the specific halo properties of halo0
    """

    # Caution: parms[0] is number density! Caution: use unitsless numbers!
    rho0 = simulation.toyclusterlog.halosetup[i]['rho0gas_cgs']
    ne0 = convert.rho_to_ne(rho0.value_in(units.g / units.cm**3),
                            simulation.toyclusterlog.systemat['z'])
    rc = simulation.toyclusterlog.halosetup[i]['rc']
    R200 = simulation.toyclusterlog.halosetup[i]['R200']
    Mass_in_DM = simulation.toyclusterlog.halosetup[i]['Mass_in_DM']
    a = simulation.toyclusterlog.halosetup[i]['a_hernquist']

    # print "rho0          :", rho0
    # print "ne0           :", ne0
    # print "rc            :", rc
    # print "R200          :", R200
    # print "Mass_in_DM    :", Mass_in_DM
    # print "a             :", a

    parms = (ne0, rc.value_in(units.kpc), R200.value_in(units.kpc))
    dm_parms = (Mass_in_DM, a)

    return AnalyticalCluster(parms,
                             dm_parms,
                             z=simulation.toyclusterlog.systemat['z'])
示例#2
0
def compton_y(r, Rmax, rho_gas, M_tot):
    """ SZ 1980 adopted by Donnert (2014; eq. 16)

        CAUTION: constants used in this function are in cgs. Make sure that the
        rho_gas, M_tot and r are all in cgs units!!

        @param Rmax   : maximum value in integration, float, [cm]
        @param rho_gas: callable gas density profile, function pointer
        @param M_tot  : callable total mass profile, function pointer
        @return       : compton-y parameter """

    print "Does not work yet"
    return

    m_e = const.m_e.to(u.g).value
    kB = const.k_B.to(u.erg / u.K).value
    sT = const.sigma_T.cgs.value
    c = const.c.cgs.value
    fac = sT * kB * 4 * numpy.pi / m_e / p2(c)

    y = scipy.integrate.quad(
        lambda t: fac * p2(t) * convert.rho_to_ne(rho_gas(t)) *
        hydrostatic_temperature(t, Rmax, rho_gas, M_tot), 0, Rmax)
    return y[0]
示例#3
0
def total_gravitating_mass(c,
                           cNFW=None,
                           bf=0.17,
                           RCUT_R200_RATIO=None,
                           verbose=False,
                           debug=False):
    """ Find total gravitating mass under assumption of fixed baryon fraction
        at the virial radius (seventeen percent) r200.
        The problem is implicit and solved by root-finding (bisection).
        @param c   : ObservedCluster
        @param cNFW: Concentration parameter. If given, cNFW is a free parameter
                     instead of using the Duffy+ 2008 relation for c(M200, z)
        @param bf  : Baryon fraction. Default 17% within R200.
        @param RCUT_R200_RATIO
                   : rcut = RCUT_R200_RATIO * r200 to cut-off betamodel and NFW
        @return    : Dictionary of best-fit halo properties. """

    # Set bestfit betamodel parameters
    ne0, rho0, beta, rc = c.ne0, c.rho0, c.beta, c.rc
    rc *= convert.kpc2cm

    # Find r200 such that rho200 / rho_crit == 200 (True by definition)
    lower = 10 * convert.kpc2cm
    upper = 4000 * convert.kpc2cm

    # bisection method
    epsilon = 0.001
    while upper / lower > 1 + epsilon:
        # bisection
        r200 = (lower + upper) / 2.

        # bf = 0.17  # Critical assumption: bf == 0.17 at r200 (Planelles+ 2013)

        if RCUT_R200_RATIO is None:
            rcut = None
        else:
            rcut = r200 * RCUT_R200_RATIO
        Mgas200 = profiles.gas_mass_betamodel(r200, rho0, beta, rc, rcut)
        Mdm200 = Mgas200 * (1 / bf - 1)

        M200 = Mgas200 + Mdm200

        if not cNFW: cNFW = profiles.cNFW(M200)
        rs = r200 / cNFW

        rho0_dm = Mdm200 / profiles.dm_mass_nfw(r200, 1, rs)
        """ Now rho_average(r200)/rhocrit should equal 200.
                If not? Try different r200"""
        rho200_over_rhocrit = (
            M200 / (4. / 3 * numpy.pi * p3(r200))) / c.cc.rho_crit()
        if debug:
            print "Lower                  = {0:3.1f}".format(lower *
                                                             convert.cm2kpc)
            print "r200                   = {0:3.1f}".format(r200 *
                                                             convert.cm2kpc)
            print "Upper                  = {0:3.1f}".format(upper *
                                                             convert.cm2kpc)
            print "Ratio                  = {0:.1f}".format(
                rho200_over_rhocrit / 200)
            print

        # bisection
        if rho200_over_rhocrit < 200:
            upper = r200
        if rho200_over_rhocrit > 200:
            lower = r200

    # r200, thus M200 found
    halo = dict()
    halo["r200"] = r200 * convert.cm2kpc
    halo["rcut"] = rcut * convert.cm2kpc if rcut is not None else None
    halo["rho200_over_rhocrit"] = rho200_over_rhocrit
    halo["bf200"] = Mgas200 / (Mdm200 + Mgas200)
    halo["rho0"] = rho0
    halo["ne0"] = convert.rho_to_ne(rho0)
    halo["rc"] = rc * convert.cm2kpc
    halo["beta"] = beta
    halo["Mgas200"] = Mgas200 * convert.g2msun
    halo["Mdm200"] = Mdm200 * convert.g2msun
    halo["M200"] = M200 * convert.g2msun
    halo["cNFW"] = cNFW
    halo["rs"] = rs * convert.cm2kpc
    halo["rho0_dm"] = rho0_dm
    halo["ne0_dm"] = convert.rho_to_ne(rho0_dm)

    return halo
示例#4
0
def make_all_plots(run, snap, i, replot=False):
    print "Generating plots for:", snap

    fname = snap.split('/')[-1]
    snapnr = fname.split('_')[-1]
    if run.IC_only:
        snapnr += "00-ICOnly"

    mass_filename = run.outdir + "{0}-mass-{1}.png".format(
        run.timestamp, snapnr)
    density_filename = run.outdir + "{0}-density-{1}.png".format(
        run.timestamp, snapnr)
    temperature_filename = run.outdir + "{0}-temperature-{1}.png".format(
        run.timestamp, snapnr)

    if (os.path.isfile(mass_filename) and os.path.exists(mass_filename)
            and os.path.isfile(density_filename) \
            and os.path.exists(density_filename)) \
            and not replot:
        print "Plots exist. Skipping", snap
        return

    numerical = NumericalCluster(
        icdir=run.icdir,
        snapdir=run.snapdir,
        logfile="runToycluster.log",
        icfile="IC_single_0" if run.IC_only else "snapshot_" + snapnr,
        verbose=False)
    """ TODO: can use cluster.py setup_analytical_cluster
              to obtain AnalyticalCluster from NumericalCluster"""
    # Caution: parms[0] is number density! Caution: use unitsless numbers!
    ne0 = convert.rho_to_ne(numerical.rho0gas.value_in(units.g / units.cm**3),
                            numerical.z)
    parms = (ne0, numerical.rc.value_in(units.kpc),
             numerical.R200.value_in(units.kpc), float(numerical.beta))
    # TODO: not use this, but if doing so then use halo0_sampling...
    dm_parms = (numerical.Mass_in_DM, numerical.a)

    analytical = AnalyticalCluster(parms,
                                   dm_parms,
                                   z=numerical.z,
                                   free_beta=True)

    # 295 for WC6, 50 for Cubic Spline kernel
    numerical.get_gas_mass_via_density(DESNNGB=50 if arguments.IC_only else 50)
    numerical.get_dm_mass_via_number_density(log_binning=True)
    numerical.set_dm_density()

    plot_individual_cluster_density(numerical, analytical, run.observed)
    # pyplot.title("Time = {0:1.2f} Gyr".format(i*run.TimeBetSnapshot), y=1.03)
    if arguments.save:
        pyplot.savefig(density_filename)
        pyplot.close()

    pyplot.show()
    # plot_individual_cluster_mass(numerical, analytical)
    # pyplot.title("Time = {0:1.2f} Gyr".format(i*run.TimeBetSnapshot), y=1.03)
    # if arguments.save:
    #     pyplot.savefig(mass_filename)
    #     pyplot.close()

    # plot_individual_cluster_temperature(numerical, analytical)
    # pyplot.title("Time = {0:1.2f} Gyr".format(i*run.TimeBetSnapshot), y=1.03)
    # if arguments.save:
    #     pyplot.savefig(temperature_filename)
    #     pyplot.close()
    # else:
    #     pyplot.show()

    # break
    print "Done with snapshot:  ", snap
示例#5
0
 def gas_number_density(self, r=None):
     return (convert.rho_to_ne(
         self.gas_density(r).value_in(units.g / units.cm**3), self.z) |
             (1 / units.cm**3))