Density Profiles
Density Profile Estimation
We have added density profile estimation capabilities. We contend ourselves with spherically averaged density profiles, which are thus defined with respect to the halocentric radius
where \((x,y,z)\) are the coordinates of a point cloud particle in some coordinate system centered on either the center of mass or the mode of the cloud. The density profile describes the radial mass distribution of the points in the cloud, e.g. in units of \(M_{\odot}h^2/(\mathrm{Mpc})^3\) in the above plot.
To estimate density profiles with CosmicProfiles, we first instantiate a DensProfsGadget
object called cprofiles
via:
from cosmic_profiles import DensShapeProfsGadget, updateInUnitSystem, updateOutUnitSystem
# Parameters
updateInUnitSystem(length_in_cm = 'Mpc/h', mass_in_g = 'E+10Msun', velocity_in_cm_per_s = 1e5, little_h = 0.6774)
updateOutUnitSystem(length_in_cm = 'Mpc/h', mass_in_g = 'Msun', velocity_in_cm_per_s = 1e5, little_h = 0.6774)
SNAP_DEST = "/path/to/snapdir_035"
GROUP_DEST = "/path/to/groups_035"
SNAP = '035'
OBJ_TYPE = 'dm'
VIZ_DEST = "./viz" # folder will be created if not present
CAT_DEST = "./cat"
RVIR_OR_R200 = 'R200'
MIN_NUMBER_PTCS = 200
CENTER = 'mode'
# Instantiate object
cprofiles = DensShapeProfsGadget(SNAP_DEST, GROUP_DEST, OBJ_TYPE, SNAP, VIZ_DEST, CAT_DEST, RVIR_OR_R200, MIN_NUMBER_PTCS, CENTER)
with arguments explained in the Data Structures section. Now we can simply invoke the command:
dens_profs_db = cprofiles.estDensProfs(r_over_r200, obj_numbers = np.arange(10), direct_binning = True, spherical = True, katz_config = default_katz_config),
where the float array dens_profs_db
of shape \((N_{\text{pass}}, N_r)\) contains the estimated density profiles. The obj_numbers
argument expects a list of integers indicating for which objects to estimate the density profile. In the example above, only the first 10 objects that have sufficient resolution will be considered, i.e. \(N_{\text{pass}}=10\), also see Shape Estimation section. \((N_{\text{pass}}, N_r)\) further assumes that the float array that specifies for which unitless spherical radii r_over_r200
the local density should be calculated, has shape \(N_r\). Specifying radial bins with equal spacing in logarithmic space \(\log (\delta r/r_{200}) = \mathrm{const}\) is common practice, e.g. r_over_r200 = np.logspace(-1.5,0,70)
.
As the naming suggests, with direct_binning = True
we estimate density profiles using a direct-binning approach, i.e. brute-force binning of particles into spherical shells and subsequent counting. The user also has the liberty to invoke an ellipsoidal shell-based density profile estimation algorithm by setting the boolean spherical = False
. See Gonzalez et al. 2022 for an application of the ellipsoidal shell-based density profile estimation technique.
Note
If spherical = False
, the user then also has the discretion to set the configuration parameters katz_config
for the Katz algorithm, explained in the Shape Estimation section.
On the other hand, with direct_binning = False
, we perform a kernel-based density profile estimation, cf. Reed et al. 2005. Kernel-based approaches allow estimation of profiles without excessive particle noise.
Density Profile Fitting
Apart from estimating density profiles using the direct-binning or the kernel-based approach, this package supports density profile fitting assuming a certain density profile model. Four different density profile models can be invoked. First, the NFW-profile (Navarro et al.) defined by
Secondly, the Hernquist profile (Hernquist 1990) given by
Thirdly, the Einasto profile (Einasto 1965) defined by an additional parameter \(\alpha\) via
Finally, the \(\alpha \beta \gamma\) density profile (Zhao 1996) is a generalization of the Navarro-Frank-White (NFW) halo density profile with the parametrization
To fit density profiles according to model method
, a dictionary whose profile
field can be either nfw
, hernquist
, einasto
or alpha_beta_gamma
, invoke the method:
method = {'profile': 'einasto', 'alpha': 0.18, 'min_method': 'Powell'}
best_fits = cprofiles.fitDensProfs(dens_profs, r_over_r200, method, obj_numbers = np.arange(10)).
This will fit the density profiles using a modified Powell algorithm (default). To switch to either ‘Nelder-Mead’, ‘L-BFGS-B’, ‘TNC’, ‘SLSQP’, ‘Powell’ or the ‘trust-constr’ minimization method, the min_method
field needs to be specified accordingly.
The first argument dens_profs
to fitDensProfs()
is an array of shape \((N_{\text{pass}}, N_r)\) containing the density profile estimates defined at normalized radii r_over_r200
. The last argument method = {'profile': 'einasto', 'alpha': 0.18, 'min_method': 'Powell'}
is a dictionary. The profile
field is 1 of 4 possible strings corresponding to the density profile model, i.e. either nfw
, hernquist
, einasto
or alpha_beta_gamma
.
If a parameter should be kept fixed during the fitting procedure, it needs to be supplied in the method
dict. In the example above, the alpha
parameter of the Einasto profile is fixed to 0.18
(giving approximately an NFW-profile).
The returned structured numpy array best_fits
will store the best-fit results and its fields can be accessed by dictionary-like semantics, e.g. rho_s = best_fits['rho_s']
(of shape \((N_{\text{pass}},)\)) will contain the density normalization of the best-fit profiles, r_s = best_fits['r_s']
the scale radius etc. If method = 'alpha_beta_gamma'
, then alpha = best_fits['alpha']
will contain the best-fit values for alpha
etc.
Once density profiles have been fit, concentrations of objects can be calculated, defined as
with \(r_s\) the characteristic or scale radius of the corresponding density profile model. To this end, invoke:
cs = cprofiles.estConcentrations(dens_profs, r_over_r200, method, obj_numbers = np.arange(10)),
which will return a float array cs
of shape (\(N_{\text{pass}},\)).
The density profiles, for instance dens_profs_db
, and their fits can be visualized using:
cprofiles.plotDensProfs(dens_profs_db, r_over_r200, dens_profs_fit, r_over_r200_fit, method, nb_bins = 2, obj_numbers = np.arange(10))
where dens_profs_fit
and r_over_r200_fit
refer to those estimated density profile values that the user would like the fitting operation to be carried out over, e.g. dens_profs_fit = dens_profs_db[:,25:]
and r_over_r200_fit = r_over_r200[25:]
to discard the values that correspond to deep layers of halos/galaxies/objects. Typically, the gravitational softening scale times some factor and / or information from the local relaxation timescale is used to estimate the inner convergence radius.
For guidance on choosing the inner convergence radius see e.g. Navarro et al 2010 or Ludlow et al 2019.