def profile_check(c): a = [1E12, 1E13, 1E14] for k in range(0, 3): x0 = a[k] cosmology.setCosmology('planck100',\ {'flat': True, 'H0': 67.3, 'Om0': 0.315, 'Ob0': 0.049, 'sigma8': 0.81, 'ns': 0.95}) p_nfw = profile_nfw.NFWProfile(M=x0, c=3.5, z=0, mdef='vir') r = np.logspace(-4, 3.5, 1000) rho = p_nfw.density(r) ##这里的r表示rs #plt.loglog(r, rho) plt.loglog(10**(-3) * r, 10**9 * rho, ls='--') #plt.xlabel(r'$kpc/h$') #plt.ylabel(r'$h^2M_\odot/kpc^3$') plt.xlabel(r'$Mpc/h$') plt.ylabel(r'$h^2M_\odot/Mpc^3$') #plt.savefig(r'$rho-r$',dpi=600) return
def _convert_m_vmax(self,mass,v_max,z): """ Convert from mass and v_max to profile amplitude and concentration for an NFW Args: mass (float): Mass of the NFW in units of M_sun/h v_max (float): v_max of the NFW in units of km/s z (float): The redshift of the NFW Returns, ((float,float,float,float)): A tuple containing the concentration of the NFW, the amplitude of the NFW in units of M_sun*h^2/kpc^3, and the scale radius in units of Mpc/h. """ # Create our f function def f(x): return np.log(1+x)-x/(1+x) rho_overd = mass_so.densityThreshold(z,'vir') # Create our v_max function def v_max_dif(c,mass,v_max): if c < 1: return 100 r_vir = (mass/(4*np.pi/3*rho_overd))**(1/3) # In kpc/h v_max_calc = np.sqrt(self.__class__.G_TRADITIONAL * mass / r_vir * f( self.__class__.XMAX)/f(c)*c/self.__class__.XMAX) return v_max_calc-v_max c = root_scalar(v_max_dif,args=(mass,v_max),x0=6,x1=10).root # Use colossus to convert to the amplitude and scale radius. rho, r_s = profile_nfw.NFWProfile.fundamentalParameters(M=mass,c=c,z=z, mdef='vir') v_vir = profile_nfw.NFWProfile(M=mass,c=c,z=z, mdef='vir').circularVelocity(c*r_s) # Divide the scale radius by 1000 to convert it to Mpc/h from kpc/h r_s /= 1000 r_vir = r_s * c return c, rho, r_s, v_vir, r_vir
set_model = apcy.Planck15.clone(H0=67.74, Om0=0.311) input_cosm_model(get_model=set_model) cosmos_param() z0 = 0.50 v_m = 200 Mh0 = 14 c0 = 5 R_0 = np.logspace(0, 3.5, 100) sigma_m = sigmam(R_0, Mh0, z0, c0) sigma_c = sigmac(R_0, Mh0, z0, c0) p_nfw = profile_nfw.NFWProfile(M=1E14, c=c0, z=z0, mdef='200m') p_Sigma = p_nfw.surfaceDensity(R_0) print(p_Sigma / sigma_m) p_nfw_c = profile_nfw.NFWProfile(M=1E14, c=c0, z=z0, mdef='200c') p_Sigma_c = p_nfw_c.surfaceDensity(R_0) print(p_Sigma_c / sigma_c) rho_c, rho_m = rhom_set(z0) c_rho_c = cosmos.rho_c(z0) c_rho_m = cosmos.rho_m(z0) print(c_rho_c / rho_c) print(c_rho_m / rho_m)
sigma_crit = (constants.c**2 / (4 * np.pi * constants.G) * d_s / ( d_l * d_ls)).to(u.solMass / u.kpc**2).value ds = np.zeros((len(log_mvir), len(rp))) kappa = np.zeros((len(log_mvir), len(rp))) # %% for i, mvir in enumerate(10**log_mvir): w = dn[i] / np.sum(dn) if w == 0: continue profile = profile_nfw.NFWProfile( M=mvir, c=concentration(mvir, 'vir', z_l, model='diemer19'), z=z_l, mdef='vir') for j in range(len(rp)): rp_phys = 1000 * rp[j] / (1 + z_l) # phys. in kpc/h ds[i, j] = profile.surfaceDensity(rp_phys) / (1 + z_l)**2 kappa[i, j] = profile.surfaceDensity(rp_phys) / sigma_crit # %% alpha_s = 2.0 fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
idxp1 = np.sum(cat.Npart[:idx]) idxp2 = idxp1 + cat.Npart[idx] plt.scatter(pos[idxp1:idxp2][:, 0], pos[idxp1:idxp2][:, 1], s=0.1) plt.show() plt.scatter(pos[idxp1:idxp2][:, 0], pos[idxp1:idxp2][:, 2], s=0.1) plt.show() plt.scatter(pos[idxp1:idxp2][:, 1], pos[idxp1:idxp2][:, 2], s=0.1) plt.show() # Getting Radius r = ((pos[idxp1:idxp2] - cat.pos[idx])**2).sum(axis=1)**0.5 rhist = np.geomspace(r.min(), r.max(), 10) mhist, aux = np.histogram(r, bins=rhist) mhist = mp * mhist mhist = np.cumsum(mhist) mhist = np.append([0], mhist) profile = profile_nfw.NFWProfile(M=cat.Mass[idx], mdef='200c', z=0.0, c=4.0) fit = profile.fit(rhist * 1e3, mhist, 'M') c = concentration.concentration(cat.Mass, '200c', 0.0, model='bhattacharya13') print(c[idx], rDelta[idx] * 1e3 / fit['x'][1]) plt.plot(rhist, fit['q_fit']) plt.plot(rhist, mhist) plt.show()
for i in range(300): print(conc.dtype, rdelta.dtype, r.dtype, theta.dtype, phi.dtype) NFWx.random_nfw(npart, conc, rdelta, r, theta, phi) #r = randomr(conc[0], n=npart[0]) # Getting Radius R = r rhist = np.linspace(R.min(), R.max()) mhist, aux = np.histogram(R, bins=rhist) mhist = mp * mhist mhist = np.cumsum(mhist) mhist = np.append([0], mhist) #\+ np.sum(r<=rhist.min()) * 1e10 profile = profile_nfw.NFWProfile(M=mpart, mdef='200c', z=0.0, c=conc[0]) mfid = profile.enclosedMass(rhist * 1e3) print(profile.enclosedMass(rdelta * 1e3) / mpart) #plt.plot(rhist, mhist) #plt.plot(rhist, mfid) #plt.show() fit = profile.fit(rhist * 1e3, mhist, 'M') prec_dict[nparti] += [conc / (rdelta * 1e3 / fit['x'][1])] plt.plot(rhist, mhist) plt.plot(rhist, fit['q_fit']) plt.show() plt.hist(np.array(prec_dict[nparti]).flatten(), bins=30) plt.show()
def DStheo(theta, args): """ Computes de theoretical :math:`\Delta\Sigma_{NFW}` profile for a given mass :math:`m_{200}`, z and cosmology. Parameters ---------- theta: tuple Parameters for the mcmc args: dict Contains the cosmology and other mean values computed from the data Returns ------- ds: np.array The thoretical :math:`\Delta\Sigma_{NFW}` profile Notes ----- The parameters for the NFW function are the mass :math:`m_{200}` and the concentration :math:`c_{200}`. However, in this anlysis, we use the Duffy et al. (2008) concetration-mass relation to get the profile only as a function of the mass. See: https://github.com/joergdietrich/NFW for more details on the NFW function. """ runtype = args['runtype'] runconfig = args['runconfig'] if runtype == 'data': if runconfig == 'Full': m200, pcc, Am, B0, Rs = theta #M200c [Msun] elif runconfig == 'OnlyM': m200 = theta[0] elif runconfig == 'FixAm': m200, pcc, B0, Rs = theta elif runtype == 'cal': m200 = theta[0] elif runtype == 'calsys': if runconfig == 'Full': m200, pcc, Am, B0, Rs = theta #M200c [Msun] h = args['h'] z_mean = args['z_mean'] R = args['R'] #in physical [Mpc] cosmo = args['cosmo'] #astropy cosmology object cmodel = args[ 'cmodel'] #diemer18 (obs.: lastest version of Colossus renamed to diemer19) twohalo = args['twohalo'] factor2h = args['factor2h'] #boolean, if True multiply 2-halo term by h cosmodict = args['cosmodict'] omega_m = cosmodict['om'] sigma_crit_inv = args['Sigma_crit_inv'] #Setting up the cosmology for Colossus params = { 'flat': True, 'H0': cosmodict['h'] * 100., 'Om0': cosmodict['om'], 'Ob0': cosmodict['ob'], 'sigma8': cosmodict['sigma8'], 'ns': cosmodict['ns'] } cosmology.addCosmology('myCosmo', params) cosmoc = cosmology.setCosmology('myCosmo') cmodel = cmodel c200c = concentration.concentration( m200 * h, '200c', z_mean, model=cmodel, conversion_profile='nfw') #m200c_in is [Msun/h], m200c_out is [Msun/h] nfw = NFW(m200, c200c, z_mean, cosmology=cosmo, overdensity_type='critical') #input mass should be in [Msun] #For DeltaSigma calculation, data and sim, the radius has to be in physical [Mpc] if runtype == 'cal': ds = (nfw.delta_sigma(R).value ) / 1.e12 #DeltaSigma is in units of physical [M_sun/Mpc^2] #This two-halo part was not used in the analysis, the compuation is too slow if twohalo: #Adding the 2-halo term b = bias.haloBias(m200 * h, z_mean, '200c', model='tinker10') #mass_in is [Msun/h] outer_term_xi = profile_outer.OuterTermCorrelationFunction( z=z_mean, bias=b) p_nfw = profile_nfw.NFWProfile( M=m200 * h, c=c200c, z=z_mean, mdef='200c', outer_terms=[outer_term_xi]) #mass_in is [Msun/h] #Radius in physical kpc/h two_nfw0 = p_nfw.deltaSigmaOuter((R * 1e3) * h, interpolate=True, interpolate_surface_density=False, min_r_interpolate=1.e-6 * h, max_r_integrate=2.e5 * h, max_r_interpolate=2.e5 * h) two_nfw1 = two_nfw0 / 1.e6 #in physical [h Msun/pc^2] if factor2h: two_nfw = h * (two_nfw1 * h ) #something like physical [Msun/(h pc^2)] else: two_nfw = ( two_nfw1 * h ) #in physical [Msun/pc^2] #This should be the right one ds_model = ds + two_nfw #NFW + 2-halo in physical [Msun/pc^2] if factor2h=False else: ds_model = ds return ds_model #physical [M_sun/pc^2] if runtype == 'data' or runtype == 'calsys': ds = ( nfw.delta_sigma(R).value ) / 1.e12 #units of h Msun/pc^2 physical (but h=1, so actually is M_sun/pc^2) sigma = (nfw.sigma(R).value) / 1.e12 # Computing miscetering correction from data m200p = m200 z = np.array([z_mean]) if runtype == 'data': cluster = ClusterEnsemble(z, cosmology=FlatLambdaCDM(H0=100, Om0=0.3), cm='Diemer18', cmval=c200c) misc_off = 0.1326 #here in [Mpc], since h=1 elif runtype == 'calsys': cluster = ClusterEnsemble(z, cosmology=FlatLambdaCDM(H0=h * 100, Om0=omega_m), cm='Diemer18', cmval=c200c) misc_off = 0.1326 / h #input needs to be in units of [Mpc] if np.shape(m200p) == (1, 1): m200p = np.reshape(m200p, (1, )) try: cluster.m200 = m200p #M200c [Msun] except TypeError: cluster.m200 = np.array([m200p]) rbins = R # in physical [Mpc] offsets = np.ones(cluster.z.shape[0]) * misc_off cluster.calc_nfw(rbins, offsets=offsets) #NFW with offset dsigma_offset = cluster.deltasigma_nfw.mean( axis=0) #physical [M_sun/pc^2], but if h=1 is [h M_sun/pc**2] DSmisc = dsigma_offset.value #physical [Msun/pc^2] sigma_offset = cluster.sigma_nfw.mean( axis=0) #physical [M_sun/pc**2], but if h=1 is [h M_sun/pc**2] Smisc = sigma_offset.value #physical [Msun/pc^2] if runconfig == 'OnlyM': pcc = 0.75 B0 = 0.50 Rs = 2.00 #The final model full_Sigma = pcc * sigma + (1 - pcc) * Smisc full_model = pcc * ds + (1 - pcc) * DSmisc if runconfig == 'Full': full_model *= Am #shear+photo-z bias correction elif runconfig == 'OnlyM' or 'FixAm': full_model = full_model #Note: R (rbins) and Rs are in physical [Mpc], need to be comoving [Mpc/h] boost_model = ct.boostfactors.boost_nfw_at_R(rbins * h * (1 + z_mean), B0, Rs * h * (1 + z_mean)) full_model /= boost_model #boost-factor full_model /= (1 - full_Sigma * sigma_crit_inv) #Reduced shear return full_model # in physical [M_sun/pc^2]