def _integrate_halo(fesc_res, mass_flux_res): photons_escaped = SimArray(fesc_res["I1"], "s**-1").in_units("yr**-1") # cum_photons_escaped = trapz(photons_escaped, fesc_res["lbtime"].in_units("yr")) cum_photons_escaped = fesc_res["tint_fesc_hist"][0] F, F_plus, F_minus = mass_flux_res["F"].transpose() F_plus = SimArray(F_plus, "Msol yr**-1") F_minus = SimArray(F_minus, "Msol yr**-1") if (len(F_plus) != len(photons_escaped)): return np.nan, np.nan lbtime = mass_flux_res["lbtime"] F_net_outflow = F_plus - np.abs(F_minus) if len(np.where(np.isnan(F_net_outflow))[0] > 0): return np.nan, np.nan ix = np.where(F_net_outflow < 0.) if len(ix[0] == 0): return cum_photons_escaped, lbtime[-1] else: time_outflow = [0] for i in ix[0]: if (i == 0): continue time_outflow.append(lbtime[i - 1]) time_spent = np.zeros(len(time_outflow) - 1) for i in range(len(time_spent)): time_spent[i] = time_outflow[i + 1] - time_outflow[i] return cum_photons_escaped, time_spent.mean()
def _annotate_nstar(ax, pp, **kwargs): from seren3.core.snapshot import NML nml = pp.snapshot.nml # Check whether the namelist is using lecacy blocks # (PHYSICS_PARAMS) or new blocks (SF_PARAMS) if NML.PHYSICS_PARAMS in nml: print("Using legacy namelist block (PHYSICS_PARAMS)") n_star = SimArray(nml[NML.PHYSICS_PARAMS]['n_star'], "cm**-3").in_units("m**-3") elif NML.SF_PARAMS in nml: n_star = SimArray(nml[NML.SF_PARAMS]['n_star'], "cm**-3").in_units("m**-3") ymin, ymax = ax.get_ylim() if pp.ymin is not None and pp.ymax is not None: ymin, ymax = (pp.ymin, pp.ymax) ax.vlines(x=np.log10(n_star), ymin=ymin, ymax=ymax, linestyle='--', color='k')
def amr_TJ(context, dset): ''' Computes densty dependent Jeans temperature floor ''' from seren3.core.snapshot import NML nH = dset["nH"] nml = context.nml # First, check whether using legacy (PHYSICS_PARAMS) or new # (SF_PARAMS) namelist block if NML.PHYSICS_PARAMS in nml: print("Using legacy namelist block (PHYSICS_PARAMS)") PHYSICS_PARAMS = nml[NML.PHYSICS_PARAMS] n_star = SimArray(PHYSICS_PARAMS['n_star'], "cm**-3").in_units(nH.units) T2_star = PHYSICS_PARAMS['T2_star'] g_star = PHYSICS_PARAMS.get('g_star', 2.0) elif NML.SF_PARAMS in nml: SF_PARAMS = nml[NML.SF_PARAMS] n_star = SimArray(SF_PARAMS['n_star'], "cm**-3").in_units(nH.units) T2_star = SF_PARAMS['T2_star'] g_star = SF_PARAMS.get('g_star', 2.0) return SimArray(T2_star * (nH / n_star) ** (g_star-1.0), "K")
def T_poly(log_nH): ''' Computes polytropic temperature ''' from seren3.core.snapshot import NML nbins = pp.nbins bins = np.linspace(log_nH.min(), log_nH.max(), nbins) nH = 10**bins nml = pp.snapshot.nml # Check whether using lecacy (PHYSICS_PARAMS) or new # (SF_PARAMS) namelist block if NML.PHYSICS_PARAMS in nml: print("Using legacy namelist block (PHYSICS_PARAMS)") PHYSICS_PARAMS = nml[NML.PHYSICS_PARAMS] n_star = SimArray(PHYSICS_PARAMS['n_star'], "cm**-3").in_units("m**-3") T2_star = PHYSICS_PARAMS['T2_star'] g_star = PHYSICS_PARAMS.get('g_star', 2.0) elif NML.SF_PARAMS in nml: SF_PARAMS = nml[NML.SF_PARAMS] n_star = SimArray(SF_PARAMS['n_star'], "cm**-3").in_units("m**-3") T2_star = SF_PARAMS['T2_star'] g_star = SF_PARAMS.get('g_star', 2.0) return T2_star * (nH / n_star)**(g_star - 1.0)
def mass_function(self, units='Msol h**-1', nbins=100, **kwargs): ''' Compute the halo mass function for the given catalogue ''' masses = [] for halo in self: #Mvir = halo['M200c'].in_units(units) Mvir = halo['Mvir'].in_units(units) masses.append(Mvir) mhist, mbin_edges = np.histogram(np.log10(masses), bins=nbins) mbinmps = np.zeros(len(mhist)) mbinsize = np.zeros(len(mhist)) for i in np.arange(len(mhist)): mbinmps[i] = np.mean([mbin_edges[i], mbin_edges[i + 1]]) mbinsize[i] = mbin_edges[i + 1] - mbin_edges[i] # Compute HMF from realization and plot # boxsize = self.base.boxsize.in_units("Mpc h**-1 a") boxsize = kwargs.pop("boxsize", self.base.boxsize).in_units("Mpc h**-1 a") hmf = self.base.array(mhist / (boxsize**3) / mbinsize, "Mpc**-3 h**3 a**-3") return SimArray(mbinmps, units), hmf, SimArray(mbinsize, units)
def amr_nHII(context, dset): ''' Neutral hydrogen number density ''' nHII = SimArray(dset["nH"] * dset["xHII"], dset["nH"].units) nHII.set_field_latex("n$_{\\mathrm{HII}}$") return nHII
def amr_xHI(context, dset): ''' Hydrogen neutral fraction ''' val = 1. - dset["xHII"] xHI = SimArray(val) xHI.set_field_latex("$\\mathrm{x}_{\\mathrm{HI}}$") return xHI
def part_age(context, dset, **kwargs): #return context.quantities.tform(dset['epoch'], **kwargs) ''' Return the formation (lookback) time in units of Gyr For formation time since the big bang (age), do age_simu - tform (also in units of Gyr) ''' nml = context.nml isCosmoSim = ('cosmo' in nml['RUN_PARAMS'] and nml['RUN_PARAMS']['cosmo'] == '.true.') verbose = kwargs.get("verbose", False) tform = dset['epoch'] output = None if verbose: print 'part_age isCosmoSim: ', isCosmoSim if not isCosmoSim: output = tform * context.info['unit_time'].express(context.C.Gyr) # age in Gyr else: cosmology = context.cosmo h0 = cosmology['h'] * 100 friedmann = context.friedmann axp_out = friedmann['axp_out'] # hexp_out = friedmann['hexp_out'] tau_out = friedmann['tau_out'] t_out = friedmann['t_out'] # age_tot = friedmann['age_tot'] # age_simu = friedmann['age_simu'] time_simu = friedmann['time_simu'] patch = kwargs.get('patch', context.patch) if verbose: print 'part_age: patch = ', patch if patch == 'rt': output = (time_simu - tform) / (h0 * 1e5 / 3.08e24) / (365. * 24. * 3600. * 1e9) else: ntable = len(axp_out) - 1 output = np.zeros(len(tform)) for j in range(0, len(tform) - 1): i = 1 while ((tau_out[i] > tform[j]) and (i < ntable)): i += 1 # Interpolate time time = t_out[i] * (tform[j] - tau_out[i - 1]) / (tau_out[i] - tau_out[i - 1]) + \ t_out[i - 1] * (tform[j] - tau_out[i]) / \ (tau_out[i - 1] - tau_out[i]) time = max( (time_simu - time) / (h0 * 1e5 / 3.08e24) / (365 * 24 * 3600 * 1e9), 0) output[j] = time # output[j] = (time_simu - time)*unit_t/(365 * 24 * 3600 * 1e9) result = SimArray(output, "Gyr") result.set_field_latex("$\\mathrm{Age}$") return result
def amr_T2(context, dset): ''' Gas Temperature in units of K/mu ''' mH = SimArray(context.C.mH) kB = SimArray(context.C.kB) T2 = (dset["P"]/dset["rho"] * (mH / kB)) T2.set_field_latex("T$_{2}$") return T2
def star_Nion_d(context, dset, dt=0., group=1): ''' Computes the number of ionisiing photons produced by a stellar population per solar mass per second ''' from seren3.array import SimArray from seren3.utils.sed import io from seren3.exceptions import NoParticlesException from seren3 import config # from seren3.analysis import interpolate from scipy.interpolate import interp2d verbose = config.get("general", "verbose") Z_sun = 0.02 # metallicity of the sun nGroups = context.info["nGroups"] if (verbose): print 'Computing Nion_d for photon group %i/%i' % (group, nGroups) nIons = context.info["nIons"] nPhotons_idx = 0 # index of photon number in SED # Load the SED table agebins, zbins, SEDs = io.read_seds_from_lists(context.path, nGroups, nIons) igroup = group - 1 fn = interp2d(zbins / Z_sun, agebins, SEDs[:, :, igroup, nPhotons_idx]) age = dset["age"].in_units("Gyr") Z = dset["metal"] / Z_sun # in units of solar metalicity # Which star particles should we keep if dt != 0.: age -= dt.in_units("Gyr") # keep = np.where( np.logical_and(age >= 0., age.in_units("Myr") <= 10.) ) keep = np.where(age >= 0.) age = age[keep] Z = Z[keep] if len(age) == 0: raise NoParticlesException("No particles with (age - dt) > 0", "star_Nion_d") # interpolate photon production rate from SED nStars = len(age) nPhotons = np.zeros(nStars) for i in xrange(nStars): nPhotons[i] = fn(Z[i], age[i]) # nPhotons = interpolate.interpolate2d(age, Z, agebins, zbins, SEDs[:,:,igroup,nPhotons_idx]) # Multiply by (SSP) escape fraction and return nml = context.nml NML_KEYS = nml.NML rt_esc_frac = float(nml[NML_KEYS.RT_PARAMS]['rt_esc_frac'].replace( 'd', 'e')) Nion_d = SimArray(rt_esc_frac * nPhotons, "s**-1 Msol**-1") Nion_d.set_field_latex("$\\dot{N_{\\mathrm{ion}}}$") return Nion_d
def amr_nHI(context, dset): ''' Neutral hydrogen number density ''' xHII = np.round( dset["xHII"], decimals=5 ) nHI = SimArray(dset["nH"] * (1. - xHII), dset["nH"].units) # nHI = SimArray(dset["nH"] * (1. - dset["xHII"]), dset["nH"].units) nHI.set_field_latex("n$_{\\mathrm{HI}}$") return nHI
def Tvir(self): ''' Returns the virial Temperature of the halo ''' mu = 0.59 # Okamoto 2008 mH = SimArray(self.base.C.mH) kB = SimArray(self.base.C.kB) Vc = self.Vc Tvir = 1. / 2. * (mu * mH / kB) * Vc**2 return self.base.array(Tvir, Tvir.units)
def rho_T_hist2d(snap, xo=None, yo=None, mass=None, den_field='nH', temp_field='T2', \ nbins=500, plot=False, ax=None, title=None, show=False, **kwargs): ''' Produces a mass weighted, 2D histogram of density vs temperature ''' from seren3.array import SimArray from seren3.utils.plot_utils import add_colorbar import numpy as np import matplotlib.pylab as plt if ax is None: fig = plt.figure(figsize=(12, 12)) ax = fig.add_subplot(111) if xo is None or yo is None or mass is None: dset = snap.g[den_field, temp_field, 'mass'].flatten() mass = dset["mass"].in_units("Msol") totmass = mass.sum() xo, yo = (dset[den_field], dset[temp_field]) h, xs, ys = hist2d(xo, yo, xlogrange=True, ylogrange=True, density=False, mass=mass, nbins=500) h /= totmass xs = SimArray(xs, dset[den_field].units) #xs.set_latex(dset[den_field].get_field_latex()) ys = SimArray(ys, dset[temp_field].units) #ys.set_latex(dset[temp_field].get_field_latex()) if plot: cmap = kwargs.get('cmap', 'coolwarm') p = plot_2dhist(h, xs, ys, den_field, temp_field, ax=ax, ret_im=True, cmap=cmap) p.set_clim(vmin=-8, vmax=-2) if title: plt.title(title) if show: plt.show() return h, xs, ys
def amr_TJ(context, dset): ''' Computes densty dependent Jeans temperature floor ''' from seren3.core.snapshot import NML nH = dset["nH"] nml = context.nml PHYSICS_PARAMS = nml[NML.PHYSICS_PARAMS] n_star = SimArray(PHYSICS_PARAMS['n_star'], "cm**-3").in_units(nH.units) T2_star = PHYSICS_PARAMS['T2_star'] g_star = PHYSICS_PARAMS.get('g_star', 2.0) return SimArray(T2_star * (nH / n_star)**(g_star - 1.0), "K")
def compute_sfr(age, mass, nbins=nbins, **kwargs): agerange = kwargs.pop('agerange', [age.min(), age.max()]) binnorm = SimArray(1e-9 * nbins / (agerange[1] - agerange[0]), "yr**-1") weights = mass * binnorm sfrhist, bin_edges = np.histogram(age, weights=weights, bins=nbins, range=agerange, **kwargs) binmps = np.zeros(len(sfrhist)) binsize = np.zeros(len(sfrhist)) for i in np.arange(len(sfrhist)): binmps[i] = np.mean([bin_edges[i], bin_edges[i + 1]]) binsize[i] = bin_edges[i + 1] - bin_edges[i] return SimArray(sfrhist, "Msol yr**-1"), SimArray(binmps, "Gyr"), SimArray(binsize, "Gyr")
def integrate_surface_flux(flux_map, r): ''' Integrates a healpix surface flux to compute the total net flux out of the sphere. r is the radius of the sphere in meters ''' import numpy as np import healpy as hp from scipy.integrate import trapz from seren3.array import SimArray if not ((isinstance(flux_map, SimArray) or isinstance(r, SimArray))): raise Exception("Must pass SimArrays") # Compute theta/phi npix = len(flux_map) nside = hp.npix2nside(npix) # theta, phi = hp.pix2ang(nside, range(npix)) theta, phi = hp.pix2ang(nside, range(npix)) r = r.in_units("kpc") # make sure r is in meters # Compute the integral # integrand = np.zeros(len(theta)) ix = theta.argsort() integrand = r**2 * np.sin(theta[ix]) * flux_map[ix] # for i in range(len(theta)): # th, ph = (theta[i], phi[i]) # integrand[i] = r**2 * np.sin(th) * flux_map[i] # mass_flux_radial function already deals with unit vev # integrand = integrand[:, None] + np.zeros(len(phi)) # 2D over theta and phi # I = trapz(trapz(integrand, phi), theta) I = trapz(integrand, theta[ix]) * 2. * np.pi return SimArray(I, "Msol yr**-1")
def process(self, dset): """Compute the profile of the specified data source """ # Prepare full profile histogram # profile = np.zeros(len(self.bin_bounds) - 1) profile = 0. bin_coords = self.bin_func(dset) # Compute profile for this batch dprofile = np.histogram( bin_coords, weights=self.profile_func(dset), bins=self.bin_bounds, normed=False)[0] if self.divide_by_counts: print "Dividing by bin counts" # Divide by counts counts = np.histogram( bin_coords, bins=self.bin_bounds, normed=False)[0] counts[counts == 0] = 1 dprofile = dprofile / counts profile += SimArray(dprofile, dset[self.field].units) # if average_over_dsets: # # Average out over number of dsets # return profile / float(len(source)) # else: # return profile return profile
def compute_bias_lc(ics, vbc): """ Calculate the bias to the density power spectrum assuming COHERENT vbc at z=1000. """ import os, time from seren3.array import SimArray # Compute size of grid and boxsize (for this patch) N = vbc.shape[0] boxsize = ics.boxsize.in_units("Mpc a h**-1") * (float(N) / float(ics.header.N)) # Compute vbc @ z=1000 z = ics.z zstart = 1000 rms = vbc_rms(vbc) rms_recom = rms * (1001. / z) # ps_vbc0 = run_cicsass_lc(boxsize, z, 0.) # ps_vbcrecom = run_cicsass_lc(boxsize, z, rms_recom) # Boxsize doesn't make a difference when calculating the power spectra ps_vbc0 = run_pyvbc(vbc=0.0, zstart=zstart, zend=z, dz=3) ps_vbcrecom = run_pyvbc(vbc=rms_recom, zstart=zstart, zend=z, dz=3) #CDM bias b_cdm = ps_vbcrecom[1] / ps_vbc0[1] # Baryon bias b_b = ps_vbcrecom[2] / ps_vbc0[2] # Wavenumber k_bias = SimArray(ps_vbcrecom[0] / ics.cosmo["h"], "h Mpc**-1") return k_bias, b_cdm, b_b
def rad_radial(sim, group): import numpy as np from pynbody.array import SimArray from seren3.utils import unit_vec_r, heaviside flux = [] units = None for i in 'xyz': #print i fi = sim.g["rad_%i_flux_%s" % (group, i)] flux.append(fi) units = fi.units flux = np.array(flux).T x, y, z = sim.g["pos"].T r = np.sqrt(x**2 + y**2 + z**2) # theta = sim.g["sg_theta"] # phi = sim.g["sg_az"] theta = np.arccos(z / r) phi = np.arctan2(y, x) flux_scalar = np.zeros(len(theta)) for i in range(len(theta)): th, ph = (theta[i], phi[i]) unit_r = unit_vec_r(th, ph) # Compute outward flux (should always be positive) flux_scalar[i] = np.dot(flux[i], unit_r)\ * heaviside(np.dot(flux[i], unit_r)) return SimArray(flux_scalar, units)
def sg_theta(sim): import numpy as np from pynbody.array import SimArray x, y, z = sim["pos"].transpose() r = np.sqrt(x**2 + y**2 + z**2) return SimArray(np.arccos(z / r))
def __init__(self, level_dir): with self._open_file(level_dir) as f: nn, dx, origin, cosmo = self.read_header(f) self.N = nn[0] self.nn = nn self.dx = dx self.origin = origin self.cosmo = cosmo self.dx *= self.cosmo['h'] # Mpccm/h self.dx = SimArray(self.dx, "Mpc a h**-1", snapshot=self) self.boxsize = SimArray(self.N * self.dx, self.dx.units, snapshot=self) # Mpccm/h self.cosmo['z'] = (1. / self.cosmo["aexp"]) - 1.
def mass_flux_radial(sim): import numpy as np from pynbody.array import SimArray from seren3.utils import unit_vec_r, heaviside flux = [] units = None for i in 'xyz': #print i fi = sim.g["mf%s" % i] flux.append(fi) units = fi.units flux = np.array(flux).T x, y, z = sim.g["pos"].T r = np.sqrt(x**2 + y**2 + z**2) # theta = sim.g["sg_theta"] # phi = sim.g["sg_az"] theta = np.arccos(z / r) phi = np.arctan2(y, x) mass_flux_scalar = np.zeros(len(theta)) for i in range(len(theta)): th, ph = (theta[i], phi[i]) unit_r = unit_vec_r(th, ph) mass_flux_scalar[i] = np.dot(flux[i], unit_r) return SimArray(mass_flux_scalar, units)
def amr_inflow_rate(context, dset, center=None, **kwargs): from seren3.utils import unit_vec_r, heaviside if (center is None): # Locate centre of mass if hasattr(context, "base"): if hasattr(context.base, "region"): center = context.base.region.center else: from seren3.utils import camera_utils center = camera_utils.find_center_of_mass(context) unit_l = context.array(context.info["unit_length"]) pos = dset["pos"].in_units(unit_l) - center x,y,z = pos.T # Cartesian -> spherical polars r = np.sqrt(x**2 + y**2 + z**2) theta = np.arccos(z / r) phi = np.arctan2(y, x) rho = dset["rho"] vel = dset["vel"] rho_u = (rho * vel.T).T mass_flux_scalar = np.zeros(len(theta)) for i in range(len(theta)): th, ph = (theta[i], phi[i]) unit_r = unit_vec_r(th, ph) mass_flux_scalar[i] = np.dot(rho_u[i], unit_r)\ * heaviside(np.dot(-rho_u[i], unit_r)) return SimArray( mass_flux_scalar, rho_u.units )
def bin_spherical(self, field, npoints, nbins, divide_by_counts=False, **kwargs): ''' Spherical binning function ''' from seren3.array import SimArray from seren3.utils.derived_utils import is_derived, get_derived_field from seren3.analysis.profile_binners import SphericalProfileBinner center = kwargs.pop("center", None) if center is None: if hasattr(self.base, "region"): center = self.base.region.center else: raise Exception("center not specified") # if not isinstance(center, SimArray): # raise Exception("Center must be a SimArray") radius = kwargs.pop("radius", None) if radius is None: if hasattr(self.base, "region"): radius = float(self.base.region.radius) else: raise Exception("radius not specified") # if not isinstance(radius, SimArray): # raise Exception("Radius must be a SimArray") profile_func = kwargs.pop("profile_func", None) if profile_func is None: if is_derived(self, field): fn = get_derived_field(self, field) profile_func = lambda dset: fn(self, dset) else: profile_func = lambda dset: dset[field] bin_bounds = np.linspace(0., radius, nbins) dset = None source = self[[field, "pos"]] if self.family == "amr": sphere = self.base.get_sphere(center, radius) points = sphere.random_points(npoints) dset = source.sample_points(points) else: dset = source.flatten() binner = SphericalProfileBinner(field, center, profile_func, bin_bounds, divide_by_counts) prof = binner.process(dset) prof_units = kwargs.pop("prof_units", None) if prof_units is not None: prof = prof.in_units(prof_units) r_units = kwargs.pop("r_units", "pc") r_bins = (bin_bounds[1:] + bin_bounds[:-1])/2. r_bins = SimArray(r_bins, self.info["unit_length"]).in_units(r_units) return prof, r_bins
def dt(self): ''' Time delay for photons to escape, assuming point source ''' rvir = self.rvir.in_units("m") rt_c = SimArray(self.base.info_rt["rt_c_frac"] * self.base.C.c) dt = rvir / rt_c return self.base.array(dt, dt.units)
def cs_rho_mean(fname): import pickle from seren3.array import SimArray data = pickle.load( open(fname, "rb") ) aexp = np.zeros(len(data)) cs = SimArray( np.zeros(len(data)), "m s**-1" ) rho_mean = SimArray( np.zeros(len(data)), "kg m**-3" ) for i in range(len(data)): res = data[i].result aexp[i] = res["aexp"] cs[i] = res["mw"].in_units(cs.units) rho_mean[i] = res["rho_mean"].in_units(rho_mean.units) return aexp, cs, rho_mean
def plot_filtering_mass(sims, labels, cols): from matplotlib import rcParams rcParams['axes.linewidth'] = 1.5 rcParams['xtick.labelsize'] = 14 rcParams['ytick.labelsize'] = 14 rcParams['axes.labelsize'] = 18 rcParams['xtick.major.pad'] = 10 rcParams['ytick.major.pad'] = 10 import matplotlib.pylab as plt from seren3.array import SimArray fig, ax = plt.subplots(figsize=(8,8)) sub_axes = plt.axes([.5, .5, .35, .35]) for sim, label, c in zip(sims, labels, cols): pickle_path = "%s/pickle/" % sim.path fname = "%s/cs_time_averaged_at_rho_mean.p" % pickle_path aexp, cs, rho_mean = cs_rho_mean(fname) kJ = jeans_scale(aexp, cs, rho_mean) kF = filtering_scale(aexp, kJ) kJ_fn = jeans_scale_interp_fn(aexp, kJ) kJ_interp = SimArray(10**kJ_fn(np.log10(aexp)), "m**-1") jeans_mass = (4.*np.pi/3.) * rho_mean * (np.pi * aexp / kJ_interp)**3 filtering_mass = (4.*np.pi/3.) * rho_mean * (np.pi * aexp / kF)**3 filtering_mass.convert_units("Msol") jeans_mass.convert_units("Msol") z = (1./aexp) - 1. ax.semilogy(z, filtering_mass, linewidth=2., label=label, color=c) ax.semilogy(z, jeans_mass, linewidth=2., color=c, linestyle="--") ix = np.where( np.logical_and(z >= 6, z <= 10) ) sub_axes.semilogy(z[ix], filtering_mass[ix], linewidth=2., color=c) sub_axes.semilogy(z[ix], jeans_mass[ix], linewidth=2., color=c, linestyle="--") ax.set_xlabel(r"$z$") ax.set_ylabel(r"M$_{F,\mathrm{J}}$ [M$_{\odot}$]") sub_axes.set_xlabel(r"$z$") sub_axes.set_ylabel(r"M$_{F,\mathrm{J}}$ [M$_{\odot}$]") # Shrink current axis's height by 10% on the bottom box = ax.get_position() ax.set_position([box.x0, box.y0 + box.height * 0.1, box.width, box.height * 0.9]) # Put a legend below current axis ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.125), frameon=False, ncol=2, prop={"size" : 16}) plt.show()
def Vc(self): ''' Returns the circular velocity of the halo ''' G = SimArray(self.base.C.G) M = self["mvir"].in_units("kg") Rvir = self["rvir"].in_units("m") Vc = np.sqrt((G * M) / Rvir) return self.base.array(Vc, Vc.units)
def _integrate_halo(fesc_res, mass_flux_res): photons_escaped = SimArray(fesc_res["I1"], "s**-1").in_units("yr**-1") cum_photons_escaped = trapz(photons_escaped, fesc_res["lbtime"].in_units("yr")) F, F_plus, F_minus = mass_flux_res["F"].transpose() F_plus = SimArray(F_plus, "Msol yr**-1") F_minus = SimArray(F_minus, "Msol yr**-1") if (len(F_plus) != len(photons_escaped)): return np.nan, np.nan cum_outflowed_mass = trapz(F_plus, mass_flux_res["lbtime"].in_units("yr")) cum_inflowed_mass = np.abs( trapz(F_minus, mass_flux_res["lbtime"].in_units("yr"))) # return cum_photons_escaped, cum_outflowed_mass - cum_inflowed_mass return cum_photons_escaped, cum_outflowed_mass
def jeans_scale(aexp, cs, rho): from seren3.array import SimArray from pymses.utils import constants as C if (not isinstance(cs, SimArray) or not isinstance(rho, SimArray)): raise Exception("cs and rho must be SimArrays") G = SimArray(C.G) kJ = ( (2. * np.pi * aexp)/cs ) * np.sqrt( (G * rho) / np.pi ) return kJ