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'])
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]
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
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
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))