mirror of
https://github.com/Richard-Sti/csiborgtools.git
synced 2024-12-22 12:38:02 +00:00
CSiBORG FoF switch (#75)
* Add moving FoF membership files * add FoF membership path * Add notes where its PHEW * Add FoF catalogue path * Correct typo * Add more functionalities * Make work with halo IDs from FoF * Edit print statement * Fix copy bug * copy * Add FoF catalogue reading * Clean up script * Fix typo * Little edits * Fix naming convention * Rename key * Remove loading substructure particles * Rename CSiBORG Cat * Rename clumps cat * Rename cat * Remove misplaced import * Switch to halos * rm import * structfit of only halos * Add FoF halo reading * Add a short comment * Fix __getitem__ to work with int * Fix problems * Improve __getitem__ * Add more conversion * Fix indexing * Fix __getitem__ assertion * Fix numbers * Rename * Fix verbosity flags * Add full Quijote HMF option * Add plot of Quijote only * Add quijote full paths * Fix the fit_init script * Renam arg * Update .gitignore * add default argument name * Change default verbosity flag * Modernise script structure * Fix dictionary * Fix reading to include m200c * Modernise script * Add args
This commit is contained in:
parent
fcd1a6b321
commit
eb8d070fff
19 changed files with 659 additions and 466 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -23,3 +23,4 @@ scripts_plots/python.sh
|
|||
scripts_plots/submit.sh
|
||||
scripts_plots/*.out
|
||||
scripts_plots/*.sh
|
||||
notebooks/test.ipynb
|
||||
|
|
|
@ -24,7 +24,7 @@ from numba import jit
|
|||
from scipy.ndimage import gaussian_filter
|
||||
from tqdm import tqdm, trange
|
||||
|
||||
from ..read import load_parent_particles
|
||||
from ..read import load_halo_particles
|
||||
|
||||
BCKG_HALFSIZE = 475
|
||||
BOX_SIZE = 2048
|
||||
|
@ -36,7 +36,7 @@ BOX_SIZE = 2048
|
|||
|
||||
class RealisationsMatcher:
|
||||
"""
|
||||
A tool to match halos between IC realisations.
|
||||
A tool to match haloes between IC realisations.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -112,7 +112,7 @@ class RealisationsMatcher:
|
|||
"""
|
||||
return self._overlapper
|
||||
|
||||
def cross(self, cat0, catx, particles0, particlesx, clump_map0, clump_mapx,
|
||||
def cross(self, cat0, catx, particles0, particlesx, halo_map0, halo_mapx,
|
||||
delta_bckg, cache_size=10000, verbose=True):
|
||||
r"""
|
||||
Find all neighbours whose CM separation is less than `nmult` times the
|
||||
|
@ -122,9 +122,9 @@ class RealisationsMatcher:
|
|||
|
||||
Parameters
|
||||
----------
|
||||
cat0 : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
cat0 : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue of the reference simulation.
|
||||
catx : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
catx : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue of the cross simulation.
|
||||
particles0 : 2-dimensional array
|
||||
Array of particles in box units in the reference simulation.
|
||||
|
@ -132,13 +132,13 @@ class RealisationsMatcher:
|
|||
particlesx : 2-dimensional array
|
||||
Array of particles in box units in the cross simulation.
|
||||
The columns must be `x`, `y`, `z` and `M`.
|
||||
clump_map0 : 2-dimensional array
|
||||
Clump map of the reference simulation.
|
||||
clump_mapx : 2-dimensional array
|
||||
Clump map of the cross simulation.
|
||||
halo_map0 : 2-dimensional array
|
||||
Halo map of the reference simulation.
|
||||
halo_mapx : 2-dimensional array
|
||||
Halo map of the cross simulation.
|
||||
delta_bckg : 3-dimensional array
|
||||
Summed background density field of the reference and cross
|
||||
simulations calculated with particles assigned to halos at the
|
||||
simulations calculated with particles assigned to haloes at the
|
||||
final snapshot. Assumed to only be sampled in cells
|
||||
:math:`[512, 1536)^3`.
|
||||
cache_size : int, optional
|
||||
|
@ -174,15 +174,14 @@ class RealisationsMatcher:
|
|||
aratio = numpy.abs(numpy.log10(catx[p][indx] / cat0[p][i]))
|
||||
match_indxs[i] = match_indxs[i][aratio < self.dlogmass]
|
||||
|
||||
clid2map0 = {clid: i for i, clid in enumerate(clump_map0[:, 0])}
|
||||
clid2mapx = {clid: i for i, clid in enumerate(clump_mapx[:, 0])}
|
||||
hid2map0 = {hid: i for i, hid in enumerate(halo_map0[:, 0])}
|
||||
hid2mapx = {hid: i for i, hid in enumerate(halo_mapx[:, 0])}
|
||||
|
||||
# We will cache the halos from the cross simulation to speed up the I/O
|
||||
@lru_cache(maxsize=cache_size)
|
||||
def load_cached_halox(hid):
|
||||
return load_processed_halo(hid, particlesx, clump_mapx, clid2mapx,
|
||||
catx.clumps_cat, nshift=0,
|
||||
ncells=BOX_SIZE)
|
||||
return load_processed_halo(hid, particlesx, halo_mapx, hid2mapx,
|
||||
nshift=0, ncells=BOX_SIZE)
|
||||
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: calculating overlaps.", flush=True)
|
||||
|
@ -196,8 +195,7 @@ class RealisationsMatcher:
|
|||
# Next, we find this halo's particles, total mass, minimum and
|
||||
# maximum cells and convert positions to cells.
|
||||
pos0, mass0, totmass0, mins0, maxs0 = load_processed_halo(
|
||||
k0, particles0, clump_map0, clid2map0, cat0.clumps_cat,
|
||||
nshift=0, ncells=BOX_SIZE)
|
||||
k0, particles0, halo_map0, hid2map0, nshift=0, ncells=BOX_SIZE)
|
||||
|
||||
# We now loop over matches of this halo and calculate their
|
||||
# overlap, storing them in `_cross`.
|
||||
|
@ -221,8 +219,8 @@ class RealisationsMatcher:
|
|||
cross = numpy.asanyarray(cross, dtype=object)
|
||||
return match_indxs, cross
|
||||
|
||||
def smoothed_cross(self, cat0, catx, particles0, particlesx, clump_map0,
|
||||
clump_mapx, delta_bckg, match_indxs, smooth_kwargs,
|
||||
def smoothed_cross(self, cat0, catx, particles0, particlesx, halo_map0,
|
||||
halo_mapx, delta_bckg, match_indxs, smooth_kwargs,
|
||||
cache_size=10000, verbose=True):
|
||||
r"""
|
||||
Calculate the smoothed overlaps for pair previously identified via
|
||||
|
@ -230,9 +228,9 @@ class RealisationsMatcher:
|
|||
|
||||
Parameters
|
||||
----------
|
||||
cat0 : :py:class:`csiborgtools.read.ClumpsCatalogue`
|
||||
cat0 : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue of the reference simulation.
|
||||
catx : :py:class:`csiborgtools.read.ClumpsCatalogue`
|
||||
catx : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue of the cross simulation.
|
||||
particles0 : 2-dimensional array
|
||||
Array of particles in box units in the reference simulation.
|
||||
|
@ -240,10 +238,10 @@ class RealisationsMatcher:
|
|||
particlesx : 2-dimensional array
|
||||
Array of particles in box units in the cross simulation.
|
||||
The columns must be `x`, `y`, `z` and `M`.
|
||||
clump_map0 : 2-dimensional array
|
||||
Clump map of the reference simulation.
|
||||
clump_mapx : 2-dimensional array
|
||||
Clump map of the cross simulation.
|
||||
halo_map0 : 2-dimensional array
|
||||
Halo map of the reference simulation.
|
||||
halo_mapx : 2-dimensional array
|
||||
Halo map of the cross simulation.
|
||||
delta_bckg : 3-dimensional array
|
||||
Smoothed summed background density field of the reference and cross
|
||||
simulations calculated with particles assigned to halos at the
|
||||
|
@ -263,14 +261,13 @@ class RealisationsMatcher:
|
|||
overlaps : 1-dimensional array of arrays
|
||||
"""
|
||||
nshift = read_nshift(smooth_kwargs)
|
||||
clid2map0 = {clid: i for i, clid in enumerate(clump_map0[:, 0])}
|
||||
clid2mapx = {clid: i for i, clid in enumerate(clump_mapx[:, 0])}
|
||||
hid2map0 = {hid: i for i, hid in enumerate(halo_map0[:, 0])}
|
||||
hid2mapx = {hid: i for i, hid in enumerate(halo_mapx[:, 0])}
|
||||
|
||||
@lru_cache(maxsize=cache_size)
|
||||
def load_cached_halox(hid):
|
||||
return load_processed_halo(hid, particlesx, clump_mapx, clid2mapx,
|
||||
catx.clumps_cat, nshift=nshift,
|
||||
ncells=BOX_SIZE)
|
||||
return load_processed_halo(hid, particlesx, halo_mapx, hid2mapx,
|
||||
nshift=nshift, ncells=BOX_SIZE)
|
||||
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: calculating smoothed overlaps.",
|
||||
|
@ -279,8 +276,8 @@ class RealisationsMatcher:
|
|||
cross = [numpy.asanyarray([], dtype=numpy.float32)] * match_indxs.size
|
||||
for i, k0 in enumerate(tqdm(indxs) if verbose else indxs):
|
||||
pos0, mass0, __, mins0, maxs0 = load_processed_halo(
|
||||
k0, particles0, clump_map0, clid2map0, cat0.clumps_cat,
|
||||
nshift=nshift, ncells=BOX_SIZE)
|
||||
k0, particles0, halo_map0, hid2map0, nshift=nshift,
|
||||
ncells=BOX_SIZE)
|
||||
|
||||
# Now loop over the matches and calculate the smoothed overlap.
|
||||
_cross = numpy.full(match_indxs[i].size, numpy.nan, numpy.float32)
|
||||
|
@ -337,7 +334,7 @@ class ParticleOverlap:
|
|||
Gaussian smoothing.
|
||||
"""
|
||||
|
||||
def make_bckg_delta(self, particles, clump_map, clid2map, halo_cat,
|
||||
def make_bckg_delta(self, particles, halo_map, hid2map, halo_cat,
|
||||
delta=None, verbose=False):
|
||||
"""
|
||||
Calculate a NGP density field of particles belonging to halos of a
|
||||
|
@ -349,12 +346,12 @@ class ParticleOverlap:
|
|||
----------
|
||||
particles : 2-dimensional array
|
||||
Array of particles.
|
||||
clump_map : 2-dimensional array
|
||||
halo_map : 2-dimensional array
|
||||
Array containing start and end indices in the particle array
|
||||
corresponding to each clump.
|
||||
clid2map : dict
|
||||
Dictionary mapping clump IDs to `clump_map` array positions.
|
||||
halo_cat: :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
corresponding to each halo.
|
||||
hid2map : dict
|
||||
Dictionary mapping halo IDs to `halo_map` array positions.
|
||||
halo_cat: :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue.
|
||||
delta : 3-dimensional array, optional
|
||||
Array to store the density field in. If `None` a new array is
|
||||
|
@ -375,12 +372,9 @@ class ParticleOverlap:
|
|||
else:
|
||||
assert ((delta.shape == (ncells,) * 3)
|
||||
& (delta.dtype == numpy.float32))
|
||||
from tqdm import tqdm
|
||||
|
||||
clumps_cat = halo_cat.clumps_cat
|
||||
for hid in tqdm(halo_cat["index"]) if verbose else halo_cat["index"]:
|
||||
pos = load_parent_particles(hid, particles, clump_map, clid2map,
|
||||
clumps_cat)
|
||||
pos = load_halo_particles(hid, particles, halo_map, hid2map)
|
||||
if pos is None:
|
||||
continue
|
||||
|
||||
|
@ -396,8 +390,8 @@ class ParticleOverlap:
|
|||
def make_delta(self, pos, mass, mins=None, maxs=None, subbox=False,
|
||||
smooth_kwargs=None):
|
||||
"""
|
||||
Calculate a NGP density field of a halo on a cubic grid. Optionally can
|
||||
be smoothed with a Gaussian kernel.
|
||||
Calculate a NGP density field of a halo on a regular grid. Optionally
|
||||
can be smoothed with a Gaussian kernel.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -409,7 +403,7 @@ class ParticleOverlap:
|
|||
Minimun and maximum cell numbers along each dimension.
|
||||
subbox : bool, optional
|
||||
Whether to calculate the density field on a grid strictly enclosing
|
||||
the clump.
|
||||
the halo.
|
||||
smooth_kwargs : kwargs, optional
|
||||
Kwargs to be passed to :py:func:`scipy.ndimage.gaussian_filter`.
|
||||
If `None` no smoothing is applied.
|
||||
|
@ -458,10 +452,10 @@ class ParticleOverlap:
|
|||
mass2 : 1-dimensional array
|
||||
Particle masses of the second halo.
|
||||
mins1, maxs1 : 1-dimensional arrays of shape `(3,)`
|
||||
Minimun and maximum cell numbers along each dimension of `clump1`.
|
||||
Minimun and maximum cell numbers along each dimension of `halo1`.
|
||||
Optional.
|
||||
mins2, maxs2 : 1-dimensional arrays of shape `(3,)`
|
||||
Minimun and maximum cell numbers along each dimension of `clump2`.
|
||||
Minimun and maximum cell numbers along each dimension of `halo2`.
|
||||
Optional.
|
||||
smooth_kwargs : kwargs, optional
|
||||
Kwargs to be passed to :py:func:`scipy.ndimage.gaussian_filter`.
|
||||
|
@ -470,11 +464,11 @@ class ParticleOverlap:
|
|||
Returns
|
||||
-------
|
||||
delta1, delta2 : 3-dimensional arrays
|
||||
Density arrays of `clump1` and `clump2`, respectively.
|
||||
Density arrays of `halo1` and `halo2`, respectively.
|
||||
cellmins : len-3 tuple
|
||||
Tuple of left-most cell ID in the full box.
|
||||
nonzero : 2-dimensional array
|
||||
Indices where the lower mass clump has a non-zero density.
|
||||
Indices where the lower mass halo has a non-zero density.
|
||||
Calculated only if no smoothing is applied, otherwise `None`.
|
||||
"""
|
||||
nshift = read_nshift(smooth_kwargs)
|
||||
|
@ -509,7 +503,7 @@ class ParticleOverlap:
|
|||
delta1 = numpy.zeros(ncells, dtype=numpy.float32)
|
||||
delta2 = numpy.zeros(ncells, dtype=numpy.float32)
|
||||
|
||||
# If no smoothing figure out the nonzero indices of the smaller clump
|
||||
# If no smoothing figure out the nonzero indices of the smaller halo
|
||||
if smooth_kwargs is None:
|
||||
if pos1.shape[0] > pos2.shape[0]:
|
||||
fill_delta(delta1, xc1, yc1, zc1, *cellmins, mass1)
|
||||
|
@ -533,12 +527,12 @@ class ParticleOverlap:
|
|||
mins1=None, maxs1=None, mins2=None, maxs2=None,
|
||||
totmass1=None, totmass2=None, smooth_kwargs=None):
|
||||
"""
|
||||
Calculate overlap between `clump1` and `clump2`. See
|
||||
Calculate overlap between `halo1` and `halo2`. See
|
||||
`calculate_overlap(...)` for further information. Be careful so that
|
||||
the background density field is calculated with the same
|
||||
`smooth_kwargs`. If any smoothing is applied then loops over the full
|
||||
density fields, otherwise only over the non-zero cells of the lower
|
||||
mass clump.
|
||||
mass halo.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -558,13 +552,13 @@ class ParticleOverlap:
|
|||
final snapshot. Assumed to only be sampled in cells
|
||||
:math:`[512, 1536)^3`.
|
||||
mins1, maxs1 : 1-dimensional arrays of shape `(3,)`
|
||||
Minimun and maximum cell numbers along each dimension of `clump1`.
|
||||
Minimun and maximum cell numbers along each dimension of `halo1`.
|
||||
Optional.
|
||||
mins2, maxs2 : 1-dimensional arrays of shape `(3,)`
|
||||
Minimum and maximum cell numbers along each dimension of `clump2`,
|
||||
Minimum and maximum cell numbers along each dimension of `halo2`,
|
||||
optional.
|
||||
totmass1, totmass2 : floats, optional
|
||||
Total mass of `clump1` and `clump2`, respectively. Must be provided
|
||||
Total mass of `halo1` and `halo2`, respectively. Must be provided
|
||||
if `loop_nonzero` is `True`.
|
||||
smooth_kwargs : kwargs, optional
|
||||
Kwargs to be passed to :py:func:`scipy.ndimage.gaussian_filter`.
|
||||
|
@ -708,7 +702,7 @@ def get_halolims(pos, ncells, nshift=None):
|
|||
ncells : int
|
||||
Number of grid cells of the box along a single dimension.
|
||||
nshift : int, optional
|
||||
Lower and upper shift of the clump limits.
|
||||
Lower and upper shift of the halo limits.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
@ -754,7 +748,7 @@ def calculate_overlap(delta1, delta2, cellmins, delta_bckg):
|
|||
-------
|
||||
overlap : float
|
||||
"""
|
||||
totmass = 0.0 # Total mass of clump 1 and clump 2
|
||||
totmass = 0.0 # Total mass of halo 1 and halo 2
|
||||
intersect = 0.0 # Weighted intersecting mass
|
||||
i0, j0, k0 = cellmins # Unpack things
|
||||
bckg_size = 2 * BCKG_HALFSIZE
|
||||
|
@ -785,7 +779,7 @@ def calculate_overlap(delta1, delta2, cellmins, delta_bckg):
|
|||
def calculate_overlap_indxs(delta1, delta2, cellmins, delta_bckg, nonzero,
|
||||
mass1, mass2):
|
||||
r"""
|
||||
Overlap between two clumps whose density fields are evaluated on the
|
||||
Overlap between two haloes whose density fields are evaluated on the
|
||||
same grid and `nonzero1` enumerates the non-zero cells of `delta1. This is
|
||||
a JIT implementation, hence it is outside of the main class.
|
||||
|
||||
|
@ -802,10 +796,10 @@ def calculate_overlap_indxs(delta1, delta2, cellmins, delta_bckg, nonzero,
|
|||
calculated with particles assigned to halos at the final snapshot.
|
||||
Assumed to only be sampled in cells :math:`[512, 1536)^3`.
|
||||
nonzero : 2-dimensional array of shape `(n_cells, 3)`
|
||||
Indices of cells that are non-zero of the lower mass clump. Expected to
|
||||
Indices of cells that are non-zero of the lower mass halo. Expected to
|
||||
be precomputed from `fill_delta_indxs`.
|
||||
mass1, mass2 : floats, optional
|
||||
Total masses of the two clumps, respectively. Optional. If not provided
|
||||
Total masses of the two haloes, respectively. Optional. If not provided
|
||||
calculcated directly from the density field.
|
||||
|
||||
Returns
|
||||
|
@ -837,8 +831,7 @@ def calculate_overlap_indxs(delta1, delta2, cellmins, delta_bckg, nonzero,
|
|||
return intersect / (mass1 + mass2 - intersect)
|
||||
|
||||
|
||||
def load_processed_halo(hid, particles, clump_map, clid2map, clumps_cat,
|
||||
ncells, nshift):
|
||||
def load_processed_halo(hid, particles, halo_map, hid2map, ncells, nshift):
|
||||
"""
|
||||
Load a processed halo from the `.h5` file. This is to be wrapped by a
|
||||
cacher.
|
||||
|
@ -850,13 +843,11 @@ def load_processed_halo(hid, particles, clump_map, clid2map, clumps_cat,
|
|||
particles : 2-dimensional array
|
||||
Array of particles in box units. The columns must be `x`, `y`, `z`
|
||||
and `M`.
|
||||
clump_map : 2-dimensional array
|
||||
halo_map : 2-dimensional array
|
||||
Array containing start and end indices in the particle array
|
||||
corresponding to each clump.
|
||||
clid2map : dict
|
||||
Dictionary mapping clump IDs to `clump_map` array positions.
|
||||
clumps_cat : :py:class:`csiborgtools.read.ClumpsCatalogue`
|
||||
Clumps catalogue.
|
||||
corresponding to each halo.
|
||||
hid2map : dict
|
||||
Dictionary mapping halo IDs to `halo_map` array positions.
|
||||
ncells : int
|
||||
Number of cells in the original density field. Typically 2048.
|
||||
nshift : int
|
||||
|
@ -875,8 +866,7 @@ def load_processed_halo(hid, particles, clump_map, clid2map, clumps_cat,
|
|||
maxs : len-3 tuple
|
||||
Maximum cell indices of the halo.
|
||||
"""
|
||||
pos = load_parent_particles(hid, particles, clump_map, clid2map,
|
||||
clumps_cat)
|
||||
pos = load_halo_particles(hid, particles, halo_map, hid2map)
|
||||
pos, mass = pos[:, :3], pos[:, 3]
|
||||
pos = pos2cell(pos, ncells)
|
||||
totmass = numpy.sum(mass)
|
||||
|
@ -898,9 +888,9 @@ def radius_neighbours(knn, X, radiusX, radiusKNN, nmult=1.0,
|
|||
Array of shape `(n_samples, 3)`, where the latter axis represents
|
||||
`x`, `y` and `z`.
|
||||
radiusX: 1-dimensional array of shape `(n_samples, )`
|
||||
Patch radii corresponding to clumps in `X`.
|
||||
Patch radii corresponding to haloes in `X`.
|
||||
radiusKNN : 1-dimensional array
|
||||
Patch radii corresponding to clumps used to train `knn`.
|
||||
Patch radii corresponding to haloes used to train `knn`.
|
||||
nmult : float, optional
|
||||
Multiple of the sum of two radii below which to consider a match.
|
||||
enforce_int32 : bool, optional
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
from .box_units import CSiBORGBox, QuijoteBox # noqa
|
||||
from .halo_cat import (ClumpsCatalogue, HaloCatalogue, # noqa
|
||||
QuijoteHaloCatalogue, fiducial_observers)
|
||||
from .halo_cat import (CSiBORGHaloCatalogue, QuijoteHaloCatalogue, fiducial_observers) # noqa
|
||||
from .knn_summary import kNNCDFReader # noqa
|
||||
from .nearest_neighbour_summary import NearestNeighbourReader # noqa
|
||||
from .obs import (SDSS, MCXCClusters, PlanckClusters, TwoMPPGalaxies, # noqa
|
||||
|
@ -25,8 +24,8 @@ from .overlap_summary import (NPairsOverlap, PairOverlap, # noqa
|
|||
from .paths import Paths # noqa
|
||||
from .pk_summary import PKReader # noqa
|
||||
from .readsim import (MmainReader, ParticleReader, halfwidth_mask, # noqa
|
||||
load_clump_particles, load_parent_particles, read_initcm)
|
||||
load_halo_particles, read_initcm) # noqa
|
||||
from .tpcf_summary import TPCFReader # noqa
|
||||
from .utils import (M200_to_R200, cartesian_to_radec, # noqa
|
||||
cols_to_structured, radec_to_cartesian, read_h5,
|
||||
real2redshift)
|
||||
real2redshift) # noqa
|
||||
|
|
|
@ -26,11 +26,11 @@ from .readsim import ParticleReader
|
|||
# Map of CSiBORG unit conversions
|
||||
CONV_NAME = {
|
||||
"length": ["x", "y", "z", "peak_x", "peak_y", "peak_z", "Rs", "rmin",
|
||||
"rmax", "r200c", "r500c", "r200m", "x0", "y0", "z0",
|
||||
"rmax", "r200c", "r500c", "r200m", "r500m", "x0", "y0", "z0",
|
||||
"lagpatch_size"],
|
||||
"velocity": ["vx", "vy", "vz"],
|
||||
"mass": ["mass_cl", "totpartmass", "m200c", "m500c", "mass_mmain", "M",
|
||||
"m200m"],
|
||||
"m200m", "m500m"],
|
||||
"density": ["rho0"]}
|
||||
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
Simulation catalogues:
|
||||
- CSiBORG: halo and clump catalogue.
|
||||
- Quijote: halo catalogue.
|
||||
- CSiBORG: FoF halo catalogue.
|
||||
- Quijote: FoF halo catalogue.
|
||||
"""
|
||||
from abc import ABC, abstractproperty
|
||||
from copy import deepcopy
|
||||
|
@ -25,7 +25,6 @@ from math import floor
|
|||
from os.path import join
|
||||
|
||||
import numpy
|
||||
|
||||
from readfof import FoF_catalog
|
||||
from sklearn.neighbors import NearestNeighbors
|
||||
|
||||
|
@ -369,6 +368,9 @@ class BaseCatalogue(ABC):
|
|||
return self.data.dtype.names
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, (int, numpy.integer)):
|
||||
assert key >= 0
|
||||
return self.data[key]
|
||||
if key not in self.keys:
|
||||
raise KeyError(f"Key '{key}' not in catalogue.")
|
||||
return self.data[key]
|
||||
|
@ -377,111 +379,14 @@ class BaseCatalogue(ABC):
|
|||
return self.data.size
|
||||
|
||||
|
||||
###############################################################################
|
||||
# CSiBORG base catalogue #
|
||||
###############################################################################
|
||||
|
||||
|
||||
class BaseCSiBORG(BaseCatalogue):
|
||||
"""
|
||||
Base CSiBORG catalogue class.
|
||||
"""
|
||||
|
||||
@property
|
||||
def nsnap(self):
|
||||
return max(self.paths.get_snapshots(self.nsim))
|
||||
|
||||
@property
|
||||
def box(self):
|
||||
"""
|
||||
CSiBORG box object handling unit conversion.
|
||||
|
||||
Returns
|
||||
-------
|
||||
box : instance of :py:class:`csiborgtools.units.BaseBox`
|
||||
"""
|
||||
return CSiBORGBox(self.nsnap, self.nsim, self.paths)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# CSiBORG clumps catalogue #
|
||||
###############################################################################
|
||||
|
||||
|
||||
class ClumpsCatalogue(BaseCSiBORG):
|
||||
r"""
|
||||
Clumps catalogue, defined in the final snapshot.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
sim : int
|
||||
IC realisation index.
|
||||
paths : py:class`csiborgtools.read.Paths`
|
||||
Paths object.
|
||||
bounds : dict
|
||||
Parameter bounds to apply to the catalogue. The keys are the parameter
|
||||
names and the items are a len-2 tuple of (min, max) values. In case of
|
||||
no minimum or maximum, use `None`. For radial distance from the origin
|
||||
use `dist`.
|
||||
load_fitted : bool, optional
|
||||
Whether to load fitted quantities.
|
||||
rawdata : bool, optional
|
||||
Whether to return the raw data. In this case applies no cuts and
|
||||
transformations.
|
||||
"""
|
||||
|
||||
def __init__(self, nsim, paths, bounds={"dist": (0, 155.5 / 0.705)},
|
||||
load_fitted=True, rawdata=False):
|
||||
self.nsim = nsim
|
||||
self.paths = paths
|
||||
# Read in the clumps from the final snapshot
|
||||
partreader = ParticleReader(self.paths)
|
||||
cols = ["index", "parent", "x", "y", "z", "mass_cl"]
|
||||
self._data = partreader.read_clumps(self.nsnap, self.nsim, cols=cols)
|
||||
# Overwrite the parent with the ultimate parent
|
||||
mmain = numpy.load(self.paths.mmain(self.nsnap, self.nsim))
|
||||
self._data["parent"] = mmain["ultimate_parent"]
|
||||
|
||||
if load_fitted:
|
||||
fits = numpy.load(paths.structfit(self.nsnap, nsim, "clumps"))
|
||||
cols = [col for col in fits.dtype.names if col != "index"]
|
||||
X = [fits[col] for col in cols]
|
||||
self._data = add_columns(self._data, X, cols)
|
||||
|
||||
# If the raw data is not required, then start applying transformations
|
||||
# and cuts.
|
||||
if not rawdata:
|
||||
flip_cols(self._data, "x", "z")
|
||||
for p in ("x", "y", "z"):
|
||||
self._data[p] -= 0.5
|
||||
names = ["x", "y", "z", "mass_cl", "totpartmass", "rho0", "r200c",
|
||||
"r500c", "m200c", "m500c", "r200m", "m200m",
|
||||
"vx", "vy", "vz"]
|
||||
self._data = self.box.convert_from_box(self._data, names)
|
||||
if bounds is not None:
|
||||
self.apply_bounds(bounds)
|
||||
|
||||
@property
|
||||
def ismain(self):
|
||||
"""
|
||||
Whether the clump is a main halo.
|
||||
|
||||
Returns
|
||||
-------
|
||||
ismain : 1-dimensional array
|
||||
"""
|
||||
return self["index"] == self["parent"]
|
||||
|
||||
|
||||
###############################################################################
|
||||
# CSiBORG halo catalogue #
|
||||
###############################################################################
|
||||
|
||||
|
||||
class HaloCatalogue(BaseCSiBORG):
|
||||
class CSiBORGHaloCatalogue(BaseCatalogue):
|
||||
r"""
|
||||
Halo catalogue, i.e. parent halos with summed substructure, defined in the
|
||||
final snapshot.
|
||||
CSiBORG FoF halo catalogue.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -504,22 +409,17 @@ class HaloCatalogue(BaseCSiBORG):
|
|||
Whether to return the raw data. In this case applies no cuts and
|
||||
transformations.
|
||||
"""
|
||||
_clumps_cat = None
|
||||
|
||||
def __init__(self, nsim, paths, bounds={"dist": (0, 155.5 / 0.705)},
|
||||
with_lagpatch=True, load_fitted=True, load_initial=True,
|
||||
load_clumps_cat=False, rawdata=False):
|
||||
rawdata=False):
|
||||
self.nsim = nsim
|
||||
self.paths = paths
|
||||
# Read in the mmain catalogue of summed substructure
|
||||
mmain = numpy.load(self.paths.mmain(self.nsnap, self.nsim))
|
||||
self._data = mmain["mmain"]
|
||||
# We will also need the clumps catalogue
|
||||
if load_clumps_cat:
|
||||
self._clumps_cat = ClumpsCatalogue(nsim, paths, rawdata=True,
|
||||
load_fitted=False)
|
||||
reader = ParticleReader(paths)
|
||||
self._data = reader.read_fof_halos(self.nsim)
|
||||
|
||||
if load_fitted:
|
||||
fits = numpy.load(paths.structfit(self.nsnap, nsim, "halos"))
|
||||
fits = numpy.load(paths.structfit(self.nsnap, nsim))
|
||||
cols = [col for col in fits.dtype.names if col != "index"]
|
||||
X = [fits[col] for col in cols]
|
||||
self._data = add_columns(self._data, X, cols)
|
||||
|
@ -538,19 +438,25 @@ class HaloCatalogue(BaseCSiBORG):
|
|||
|
||||
self._data = add_columns(self._data, X, cols)
|
||||
|
||||
if not rawdata:
|
||||
if rawdata:
|
||||
for p in ('x', 'y', 'z'):
|
||||
self._data[p] = self.box.mpc2box(self._data[p]) + 0.5
|
||||
else:
|
||||
if with_lagpatch:
|
||||
self._data = self._data[numpy.isfinite(self["lagpatch_size"])]
|
||||
# Flip positions and convert from code units to cMpc. Convert M too
|
||||
flip_cols(self._data, "x", "z")
|
||||
for p in ("x", "y", "z"):
|
||||
self._data[p] -= 0.5
|
||||
names = ["x", "y", "z", "M", "totpartmass", "rho0", "r200c",
|
||||
"r500c", "m200c", "m500c", "r200m", "m200m",
|
||||
"vx", "vy", "vz"]
|
||||
self._data = self.box.convert_from_box(self._data, names)
|
||||
if load_fitted:
|
||||
flip_cols(self._data, "vx", "vz")
|
||||
names = ["totpartmass", "rho0", "r200c",
|
||||
"r500c", "m200c", "m500c", "r200m", "m200m",
|
||||
"r500m", "m500m", "vx", "vy", "vz"]
|
||||
self._data = self.box.convert_from_box(self._data, names)
|
||||
|
||||
if load_initial:
|
||||
flip_cols(self._data, "x0", "z0")
|
||||
for p in ("x0", "y0", "z0"):
|
||||
self._data[p] -= 0.5
|
||||
names = ["x0", "y0", "z0", "lagpatch_size"]
|
||||
self._data = self.box.convert_from_box(self._data, names)
|
||||
|
||||
|
@ -558,17 +464,19 @@ class HaloCatalogue(BaseCSiBORG):
|
|||
self.apply_bounds(bounds)
|
||||
|
||||
@property
|
||||
def clumps_cat(self):
|
||||
def nsnap(self):
|
||||
return max(self.paths.get_snapshots(self.nsim))
|
||||
|
||||
@property
|
||||
def box(self):
|
||||
"""
|
||||
The raw clumps catalogue.
|
||||
CSiBORG box object handling unit conversion.
|
||||
|
||||
Returns
|
||||
-------
|
||||
clumps_cat : :py:class:`csiborgtools.read.ClumpsCatalogue`
|
||||
box : instance of :py:class:`csiborgtools.units.BaseBox`
|
||||
"""
|
||||
if self._clumps_cat is None:
|
||||
raise ValueError("`clumps_cat` is not loaded.")
|
||||
return self._clumps_cat
|
||||
return CSiBORGBox(self.nsnap, self.nsim, self.paths)
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
@ -578,7 +486,7 @@ class HaloCatalogue(BaseCSiBORG):
|
|||
|
||||
class QuijoteHaloCatalogue(BaseCatalogue):
|
||||
"""
|
||||
Quijote halo catalogue.
|
||||
Quijote FoF halo catalogue.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
|
@ -32,9 +32,9 @@ class PairOverlap:
|
|||
|
||||
Parameters
|
||||
----------
|
||||
cat0 : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
cat0 : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue corresponding to the reference simulation.
|
||||
catx : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
catx : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue corresponding to the cross simulation.
|
||||
paths : py:class`csiborgtools.read.Paths`
|
||||
CSiBORG paths object.
|
||||
|
@ -58,9 +58,9 @@ class PairOverlap:
|
|||
|
||||
Parameters
|
||||
----------
|
||||
cat0 : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
cat0 : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue corresponding to the reference simulation.
|
||||
catx : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
catx : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Halo catalogue corresponding to the cross simulation.
|
||||
paths : py:class`csiborgtools.read.Paths`
|
||||
CSiBORG paths object.
|
||||
|
@ -557,9 +557,9 @@ class NPairsOverlap:
|
|||
|
||||
Parameters
|
||||
----------
|
||||
cat0 : :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
cat0 : :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
Single reference simulation halo catalogue.
|
||||
catxs : list of :py:class:`csiborgtools.read.HaloCatalogue`
|
||||
catxs : list of :py:class:`csiborgtools.read.CSiBORGHaloCatalogue`
|
||||
List of cross simulation halo catalogues.
|
||||
paths : py:class`csiborgtools.read.Paths`
|
||||
CSiBORG paths object.
|
||||
|
|
|
@ -186,6 +186,42 @@ class Paths:
|
|||
"""
|
||||
return join(self.borg_dir, "mcmc", f"mcmc_{nsim}.h5")
|
||||
|
||||
def fof_membership(self, nsim, sorted=False):
|
||||
"""
|
||||
Path to the file containing the FoF particle membership.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
sorted : bool, optional
|
||||
Whether to return path to the file that is sorted in the same
|
||||
order as the PHEW output.
|
||||
"""
|
||||
fdir = join(self.postdir, "FoF_membership", )
|
||||
if not isdir(fdir):
|
||||
mkdir(fdir)
|
||||
warn(f"Created directory `{fdir}`.", UserWarning, stacklevel=1)
|
||||
fout = join(fdir, f"fof_membership_{nsim}.npy")
|
||||
if sorted:
|
||||
fout = fout.replace(".npy", "_sorted.npy")
|
||||
return fout
|
||||
|
||||
def fof_cat(self, nsim):
|
||||
"""
|
||||
Path to the FoF halo catalogue file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
"""
|
||||
fdir = join(self.postdir, "FoF_membership", )
|
||||
if not isdir(fdir):
|
||||
mkdir(fdir)
|
||||
warn(f"Created directory `{fdir}`.", UserWarning, stacklevel=1)
|
||||
return join(fdir, f"halo_catalog_{nsim}_FOF.txt")
|
||||
|
||||
def mmain(self, nsnap, nsim):
|
||||
"""
|
||||
Path to the `mmain` CSiBORG files of summed substructure.
|
||||
|
@ -246,7 +282,7 @@ class Paths:
|
|||
-------
|
||||
ids : 1-dimensional array
|
||||
"""
|
||||
assert simname in ["csiborg", "quijote"]
|
||||
assert simname in ["csiborg", "quijote", "quijote_full"]
|
||||
if simname == "csiborg":
|
||||
files = glob(join(self.srcdir, "ramses_out*"))
|
||||
files = [f.split("/")[-1] for f in files] # Only file names
|
||||
|
@ -260,6 +296,7 @@ class Paths:
|
|||
pass
|
||||
return numpy.sort(ids)
|
||||
else:
|
||||
# TODO here later read this from the catalogues instead.
|
||||
return numpy.arange(100, dtype=int)
|
||||
|
||||
def ic_path(self, nsim, tonew=False):
|
||||
|
@ -323,7 +360,7 @@ class Paths:
|
|||
simpath = self.ic_path(nsim, tonew=tonew)
|
||||
return join(simpath, f"output_{str(nsnap).zfill(5)}")
|
||||
|
||||
def structfit(self, nsnap, nsim, kind):
|
||||
def structfit(self, nsnap, nsim):
|
||||
"""
|
||||
Path to the clump or halo catalogue from `fit_halos.py`. Only CSiBORG
|
||||
is supported.
|
||||
|
@ -334,19 +371,16 @@ class Paths:
|
|||
Snapshot index.
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
kind : str
|
||||
Type of catalogue. Can be either `clumps` or `halos`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
path : str
|
||||
"""
|
||||
assert kind in ["clumps", "halos"]
|
||||
fdir = join(self.postdir, "structfit")
|
||||
if not isdir(fdir):
|
||||
mkdir(fdir)
|
||||
warn(f"Created directory `{fdir}`.", UserWarning, stacklevel=1)
|
||||
fname = f"{kind}_out_{str(nsim).zfill(5)}_{str(nsnap).zfill(5)}.npy"
|
||||
fname = f"out_{str(nsim).zfill(5)}_{str(nsnap).zfill(5)}.npy"
|
||||
return join(fdir, fname)
|
||||
|
||||
def overlap(self, nsim0, nsimx, smoothed):
|
||||
|
@ -441,7 +475,7 @@ class Paths:
|
|||
Parameters
|
||||
----------
|
||||
simname : str
|
||||
Simulation name. Must be `csiborg` or `quijote`.
|
||||
Simulation name. Must be `csiborg`, `quijote` or `quijote_full`.
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ from .utils import cols_to_structured
|
|||
|
||||
class ParticleReader:
|
||||
"""
|
||||
Shortcut to read in particle files along with their corresponding clumps.
|
||||
Object to read in particle files along with their corresponding haloes.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -203,7 +203,7 @@ class ParticleReader:
|
|||
nsim : int
|
||||
IC realisation index.
|
||||
pars_extract : list of str
|
||||
Parameters to be extacted.
|
||||
Parameters to be extracted.
|
||||
return_structured : bool, optional
|
||||
Whether to return a structured array or a 2-dimensional array. If
|
||||
the latter, then the order of the columns is the same as the order
|
||||
|
@ -280,7 +280,7 @@ class ParticleReader:
|
|||
|
||||
def open_unbinding(self, nsnap, nsim, cpu):
|
||||
"""
|
||||
Open particle files to a given CSiBORG simulation. Note that to be
|
||||
Open particle files of a given CSiBORG simulation. Note that to be
|
||||
consistent CPU is incremented by 1.
|
||||
|
||||
Parameters
|
||||
|
@ -305,7 +305,8 @@ class ParticleReader:
|
|||
|
||||
def read_clumpid(self, nsnap, nsim, verbose=True):
|
||||
"""
|
||||
Read clump IDs of particles from unbinding files.
|
||||
Read PHEW clump IDs of particles from unbinding files. This halo finder
|
||||
was used when running the catalogue.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -332,14 +333,13 @@ class ParticleReader:
|
|||
j = nparts[cpu]
|
||||
ff = self.open_unbinding(nsnap, nsim, cpu)
|
||||
clumpid[i:i + j] = ff.read_ints()
|
||||
|
||||
ff.close()
|
||||
|
||||
return clumpid
|
||||
|
||||
def read_clumps(self, nsnap, nsim, cols=None):
|
||||
"""
|
||||
Read in a clump file `clump_xxXXX.dat`.
|
||||
Read in a PHEW clump file `clump_xxXXX.dat`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -387,6 +387,54 @@ class ParticleReader:
|
|||
out[col] = data[:, clump_cols[col][0]]
|
||||
return out
|
||||
|
||||
def read_fof_hids(self, nsim):
|
||||
"""
|
||||
Read in the FoF particle halo membership IDs that are sorted to match
|
||||
the PHEW output.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
|
||||
Returns
|
||||
-------
|
||||
hids : 1-dimensional array
|
||||
Halo IDs of particles.
|
||||
"""
|
||||
return numpy.load(self.paths.fof_membership(nsim, sorted=True))
|
||||
|
||||
def read_fof_halos(self, nsim):
|
||||
"""
|
||||
Read in the FoF halo catalogue.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
|
||||
Returns
|
||||
-------
|
||||
cat : structured array
|
||||
"""
|
||||
fpath = self.paths.fof_cat(nsim)
|
||||
hid = numpy.genfromtxt(fpath, usecols=0, dtype=numpy.int32)
|
||||
pos = numpy.genfromtxt(fpath, usecols=(1, 2, 3), dtype=numpy.float32)
|
||||
totmass = numpy.genfromtxt(fpath, usecols=4, dtype=numpy.float32)
|
||||
m200c = numpy.genfromtxt(fpath, usecols=5, dtype=numpy.float32)
|
||||
|
||||
dtype = {"names": ["index", "x", "y", "z", "fof_totpartmass",
|
||||
"fof_m200c"],
|
||||
"formats": [numpy.int32] + [numpy.float32] * 5}
|
||||
out = numpy.full(hid.size, numpy.nan, dtype=dtype)
|
||||
out["index"] = hid
|
||||
out["x"] = pos[:, 0]
|
||||
out["y"] = pos[:, 1]
|
||||
out["z"] = pos[:, 2]
|
||||
out["fof_totpartmass"] = totmass * 1e11
|
||||
out["fof_m200c"] = m200c * 1e11
|
||||
return out
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Summed substructure catalogue #
|
||||
|
@ -457,7 +505,7 @@ class MmainReader:
|
|||
"""
|
||||
Make the summed substructure catalogue for a final snapshot. Includes
|
||||
the position of the parent, the summed mass and the fraction of mass in
|
||||
substructure.
|
||||
substructure. Corresponds to the PHEW Halo finder.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -552,39 +600,10 @@ def halfwidth_mask(pos, hw):
|
|||
return numpy.all((0.5 - hw < pos) & (pos < 0.5 + hw), axis=1)
|
||||
|
||||
|
||||
def load_clump_particles(clid, particles, clump_map, clid2map):
|
||||
def load_halo_particles(hid, particles, halo_map, hid2map):
|
||||
"""
|
||||
Load a clump's particles from a particle array. If it is not there, i.e
|
||||
clump has no associated particles, return `None`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
clid : int
|
||||
Clump ID.
|
||||
particles : 2-dimensional array
|
||||
Array of particles.
|
||||
clump_map : 2-dimensional array
|
||||
Array containing start and end indices in the particle array
|
||||
corresponding to each clump.
|
||||
clid2map : dict
|
||||
Dictionary mapping clump IDs to `clump_map` array positions.
|
||||
|
||||
Returns
|
||||
-------
|
||||
clump_particles : 2-dimensional array
|
||||
Particle array of this clump.
|
||||
"""
|
||||
try:
|
||||
k0, kf = clump_map[clid2map[clid], 1:]
|
||||
return particles[k0:kf + 1, :]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
|
||||
def load_parent_particles(hid, particles, clump_map, clid2map, clumps_cat):
|
||||
"""
|
||||
Load a parent halo's particles from a particle array. If it is not there,
|
||||
return `None`.
|
||||
Load a halo's particles from a particle array. If it is not there, i.e
|
||||
halo has no associated particles, return `None`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -592,27 +611,19 @@ def load_parent_particles(hid, particles, clump_map, clid2map, clumps_cat):
|
|||
Halo ID.
|
||||
particles : 2-dimensional array
|
||||
Array of particles.
|
||||
clump_map : 2-dimensional array
|
||||
halo_map : 2-dimensional array
|
||||
Array containing start and end indices in the particle array
|
||||
corresponding to each clump.
|
||||
clid2map : dict
|
||||
Dictionary mapping clump IDs to `clump_map` array positions.
|
||||
clumps_cat : :py:class:`csiborgtools.read.ClumpsCatalogue`
|
||||
Clumps catalogue.
|
||||
corresponding to each halo.
|
||||
hid2map : dict
|
||||
Dictionary mapping halo IDs to `halo_map` array positions.
|
||||
|
||||
Returns
|
||||
-------
|
||||
halo : 2-dimensional array
|
||||
halo_particles : 2-dimensional array
|
||||
Particle array of this halo.
|
||||
"""
|
||||
clids = clumps_cat["index"][clumps_cat["parent"] == hid]
|
||||
# We first load the particles of each clump belonging to this parent
|
||||
# and then concatenate them for further analysis.
|
||||
clumps = []
|
||||
for clid in clids:
|
||||
parts = load_clump_particles(clid, particles, clump_map, clid2map)
|
||||
if parts is not None:
|
||||
clumps.append(parts)
|
||||
if len(clumps) == 0:
|
||||
try:
|
||||
k0, kf = halo_map[hid2map[hid], 1:]
|
||||
return particles[k0:kf + 1, :]
|
||||
except KeyError:
|
||||
return None
|
||||
return numpy.concatenate(clumps)
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
"matches = np.full(len(nsims), np.nan)\n",
|
||||
"\n",
|
||||
"for ii in trange(101):\n",
|
||||
" cat = csiborgtools.read.HaloCatalogue(nsims[ii], paths, minmass=('M', 1e13))\n",
|
||||
" cat = csiborgtools.read.CSiBORGHaloCatalogue(nsims[ii], paths, minmass=('M', 1e13))\n",
|
||||
" dist, ind = cat.angular_neighbours(Xclust, ang_radius=5, rad_tolerance=10)\n",
|
||||
" dist = dist[0]\n",
|
||||
" ind = ind[0]\n",
|
||||
|
|
|
@ -13,15 +13,17 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
A script to fit halos (concentration, ...). The particle array of each CSiBORG
|
||||
realisation must have been split in advance by `runsplit_halos`.
|
||||
A script to fit FoF halos (concentration, ...). The particle array of each
|
||||
CSiBORG realisation must have been processed in advance by `pre_dumppart.py`.
|
||||
"""
|
||||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
|
||||
import numpy
|
||||
from mpi4py import MPI
|
||||
from tqdm import tqdm
|
||||
from tqdm import trange
|
||||
|
||||
from utils import get_nsims
|
||||
|
||||
try:
|
||||
import csiborgtools
|
||||
|
@ -38,18 +40,13 @@ nproc = comm.Get_size()
|
|||
verbose = nproc == 1
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--kind", type=str, choices=["halos", "clumps"])
|
||||
parser.add_argument("--ics", type=int, nargs="+", default=None,
|
||||
parser.add_argument("--nsims", type=int, nargs="+", default=None,
|
||||
help="IC realisations. If `-1` processes all simulations.")
|
||||
args = parser.parse_args()
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
partreader = csiborgtools.read.ParticleReader(paths)
|
||||
nfwpost = csiborgtools.fits.NFWPosterior()
|
||||
|
||||
if args.ics is None or args.ics[0] == -1:
|
||||
ics = paths.get_ics("csiborg")
|
||||
else:
|
||||
ics = args.ics
|
||||
nsims = get_nsims(args, paths)
|
||||
|
||||
cols_collect = [
|
||||
("index", numpy.int32),
|
||||
|
@ -67,13 +64,12 @@ cols_collect = [
|
|||
("lambda200c", numpy.float32),
|
||||
("r200m", numpy.float32),
|
||||
("m200m", numpy.float32),
|
||||
("r500m", numpy.float32),
|
||||
("m500m", numpy.float32),
|
||||
]
|
||||
|
||||
|
||||
def fit_clump(particles, clump_info, box):
|
||||
"""
|
||||
Fit an object. Can be eithe a clump or a parent halo.
|
||||
"""
|
||||
def fit_halo(particles, clump_info, box):
|
||||
obj = csiborgtools.fits.Clump(particles, clump_info, box)
|
||||
|
||||
out = {}
|
||||
|
@ -82,16 +78,15 @@ def fit_clump(particles, clump_info, box):
|
|||
for i, v in enumerate(["vx", "vy", "vz"]):
|
||||
out[v] = numpy.average(obj.vel[:, i], weights=obj["M"])
|
||||
# Overdensity masses
|
||||
out["r200c"], out["m200c"] = obj.spherical_overdensity_mass(200,
|
||||
kind="crit")
|
||||
out["r500c"], out["m500c"] = obj.spherical_overdensity_mass(500,
|
||||
kind="crit")
|
||||
out["r200m"], out["m200m"] = obj.spherical_overdensity_mass(200,
|
||||
kind="matter")
|
||||
for n in [200, 500]:
|
||||
out[f"r{n}c"], out[f"m{n}c"] = obj.spherical_overdensity_mass(
|
||||
n, kind="crit", npart_min=10)
|
||||
out[f"r{n}m"], out[f"m{n}m"] = obj.spherical_overdensity_mass(
|
||||
n, kind="matter", npart_min=10)
|
||||
# NFW fit
|
||||
if out["npart"] > 10 and numpy.isfinite(out["r200c"]):
|
||||
Rs, rho0 = nfwpost.fit(obj)
|
||||
out["conc"] = Rs / out["r200c"]
|
||||
out["conc"] = out["r200c"] / Rs
|
||||
out["rho0"] = rho0
|
||||
# Spin within R200c
|
||||
if numpy.isfinite(out["r200c"]):
|
||||
|
@ -100,8 +95,8 @@ def fit_clump(particles, clump_info, box):
|
|||
|
||||
|
||||
# We MPI loop over all simulations.
|
||||
jobs = csiborgtools.fits.split_jobs(len(ics), nproc)[rank]
|
||||
for nsim in [ics[i] for i in jobs]:
|
||||
jobs = csiborgtools.fits.split_jobs(len(nsims), nproc)[rank]
|
||||
for nsim in [nsims[i] for i in jobs]:
|
||||
print(f"{datetime.now()}: rank {rank} calculating simulation `{nsim}`.",
|
||||
flush=True)
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
|
@ -110,49 +105,30 @@ for nsim in [ics[i] for i in jobs]:
|
|||
# Particle archive
|
||||
f = csiborgtools.read.read_h5(paths.particles(nsim))
|
||||
particles = f["particles"]
|
||||
clump_map = f["clumpmap"]
|
||||
clid2map = {clid: i for i, clid in enumerate(clump_map[:, 0])}
|
||||
clumps_cat = csiborgtools.read.ClumpsCatalogue(nsim, paths, rawdata=True,
|
||||
load_fitted=False)
|
||||
# We check whether we fit halos or clumps, will be indexing over different
|
||||
# iterators.
|
||||
if args.kind == "halos":
|
||||
ismain = clumps_cat.ismain
|
||||
else:
|
||||
ismain = numpy.ones(len(clumps_cat), dtype=bool)
|
||||
|
||||
halo_map = f["halomap"]
|
||||
hid2map = {clid: i for i, clid in enumerate(halo_map[:, 0])}
|
||||
cat = csiborgtools.read.CSiBORGHaloCatalogue(
|
||||
nsim, paths, with_lagpatch=False, load_initial=False, rawdata=True,
|
||||
load_fitted=False)
|
||||
# Even if we are calculating parent halo this index runs over all clumps.
|
||||
out = csiborgtools.read.cols_to_structured(len(clumps_cat), cols_collect)
|
||||
indxs = clumps_cat["index"]
|
||||
for i, clid in enumerate(tqdm(indxs)) if verbose else enumerate(indxs):
|
||||
clid = clumps_cat["index"][i]
|
||||
out["index"][i] = clid
|
||||
# If we are fitting halos and this clump is not a main, then continue.
|
||||
if args.kind == "halos" and not ismain[i]:
|
||||
continue
|
||||
|
||||
if args.kind == "halos":
|
||||
part = csiborgtools.read.load_parent_particles(
|
||||
clid, particles, clump_map, clid2map, clumps_cat)
|
||||
else:
|
||||
part = csiborgtools.read.load_clump_particles(clid, particles,
|
||||
clump_map, clid2map)
|
||||
out = csiborgtools.read.cols_to_structured(len(cat), cols_collect)
|
||||
indxs = cat["index"]
|
||||
for i in trange(len(cat)) if verbose else range(len(cat)):
|
||||
hid = cat["index"][i]
|
||||
out["index"][i] = hid
|
||||
|
||||
part = csiborgtools.read.load_halo_particles(hid, particles, halo_map,
|
||||
hid2map)
|
||||
# We fit the particles if there are any. If not we assign the index,
|
||||
# otherwise it would be NaN converted to integers (-2147483648) and
|
||||
# yield an error further down.
|
||||
if part is None:
|
||||
continue
|
||||
|
||||
_out = fit_clump(part, clumps_cat[i], box)
|
||||
_out = fit_halo(part, cat[i], box)
|
||||
for key in _out.keys():
|
||||
out[key][i] = _out[key]
|
||||
|
||||
# Finally, we save the results. If we were analysing main halos, then
|
||||
# remove array indices that do not correspond to parent halos.
|
||||
if args.kind == "halos":
|
||||
out = out[ismain]
|
||||
|
||||
fout = paths.structfit(nsnap, nsim, args.kind)
|
||||
fout = paths.structfit(nsnap, nsim)
|
||||
print(f"Saving to `{fout}`.", flush=True)
|
||||
numpy.save(fout, out)
|
||||
|
|
|
@ -58,7 +58,9 @@ def get_counts(nsim, bins, paths, parser_args):
|
|||
bounds = {"dist": (0, parser_args.Rmax)}
|
||||
|
||||
if simname == "csiborg":
|
||||
cat = csiborgtools.read.HaloCatalogue(nsim, paths, bounds=bounds)
|
||||
cat = csiborgtools.read.CSiBORGHaloCatalogue(
|
||||
nsim, paths, bounds=bounds, with_lagpatch=False,
|
||||
load_initial=False)
|
||||
logmass = numpy.log10(cat["totpartmass"])
|
||||
counts = csiborgtools.fits.number_counts(logmass, bins)
|
||||
elif simname == "quijote":
|
||||
|
@ -71,6 +73,12 @@ def get_counts(nsim, bins, paths, parser_args):
|
|||
cat = cat0.pick_fiducial_observer(nobs, rmax=parser_args.Rmax)
|
||||
logmass = numpy.log10(cat["group_mass"])
|
||||
counts[nobs, :] = csiborgtools.fits.number_counts(logmass, bins)
|
||||
elif simname == "quijote_full":
|
||||
cat = csiborgtools.read.QuijoteHaloCatalogue(nsim, paths, nsnap=4)
|
||||
logmass = numpy.log10(cat["group_mass"])
|
||||
counts = csiborgtools.fits.number_counts(logmass, bins)
|
||||
else:
|
||||
raise ValueError(f"Unknown simulation name `{simname}`.")
|
||||
|
||||
fout = paths.halo_counts(simname, nsim)
|
||||
if parser_args.verbose:
|
||||
|
@ -80,12 +88,15 @@ def get_counts(nsim, bins, paths, parser_args):
|
|||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--simname", type=str, choices=["csiborg", "quijote"],
|
||||
parser.add_argument("--simname", type=str,
|
||||
choices=["csiborg", "quijote", "quijote_full"],
|
||||
help="Simulation name")
|
||||
parser.add_argument("--nsims", type=int, nargs="+", default=None,
|
||||
help="Indices of simulations to cross. If `-1` processes all simulations.") # noqa
|
||||
parser.add_argument("--Rmax", type=float, default=155/0.705,
|
||||
help="High-resolution region radius")
|
||||
parser.add_argument("--bw", type=float, default=0.2,
|
||||
help="Bin width in dex")
|
||||
parser.add_argument("--verbose", type=lambda x: bool(strtobool(x)),
|
||||
default=False)
|
||||
|
||||
|
@ -96,7 +107,7 @@ if __name__ == "__main__":
|
|||
verbose = nproc == 1
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsims = get_nsims(parser_args, paths)
|
||||
bins = numpy.arange(11., 16., 0.2, dtype=numpy.float32)
|
||||
bins = numpy.arange(11., 16., parser_args.bw, dtype=numpy.float32)
|
||||
|
||||
def do_work(nsim):
|
||||
get_counts(nsim, bins, paths, parser_args)
|
||||
|
|
|
@ -24,6 +24,8 @@ import numpy
|
|||
from mpi4py import MPI
|
||||
from tqdm import tqdm
|
||||
|
||||
from utils import get_nsims
|
||||
|
||||
try:
|
||||
import csiborgtools
|
||||
except ModuleNotFoundError:
|
||||
|
@ -41,16 +43,16 @@ verbose = nproc == 1
|
|||
|
||||
# Argument parser
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--ics", type=int, nargs="+", default=None,
|
||||
parser.add_argument("--simname", type=str, default="csiborg",
|
||||
choices=["csiborg", "quijote"],
|
||||
help="Simulation name")
|
||||
parser.add_argument("--nsims", type=int, nargs="+", default=None,
|
||||
help="IC realisations. If `-1` processes all simulations.")
|
||||
args = parser.parse_args()
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
partreader = csiborgtools.read.ParticleReader(paths)
|
||||
|
||||
if args.ics is None or args.ics[0] == -1:
|
||||
ics = paths.get_ics("csiborg")
|
||||
else:
|
||||
ics = args.ics
|
||||
nsims = get_nsims(args, paths)
|
||||
|
||||
cols_collect = [("index", numpy.int32),
|
||||
("x", numpy.float32),
|
||||
|
@ -61,8 +63,8 @@ cols_collect = [("index", numpy.int32),
|
|||
|
||||
|
||||
# MPI loop over simulations
|
||||
jobs = csiborgtools.fits.split_jobs(len(ics), nproc)[rank]
|
||||
for nsim in [ics[i] for i in jobs]:
|
||||
jobs = csiborgtools.fits.split_jobs(len(nsims), nproc)[rank]
|
||||
for nsim in [nsims[i] for i in jobs]:
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
overlapper = csiborgtools.match.ParticleOverlap()
|
||||
print(f"{datetime.now()}: rank {rank} calculating simulation `{nsim}`.",
|
||||
|
@ -70,22 +72,18 @@ for nsim in [ics[i] for i in jobs]:
|
|||
|
||||
parts = csiborgtools.read.read_h5(paths.initmatch(nsim, "particles"))
|
||||
parts = parts['particles']
|
||||
clump_map = csiborgtools.read.read_h5(paths.particles(nsim))
|
||||
clump_map = clump_map["clumpmap"]
|
||||
clumps_cat = csiborgtools.read.ClumpsCatalogue(nsim, paths, rawdata=True,
|
||||
load_fitted=False)
|
||||
clid2map = {clid: i for i, clid in enumerate(clump_map[:, 0])}
|
||||
ismain = clumps_cat.ismain
|
||||
halo_map = csiborgtools.read.read_h5(paths.particles(nsim))
|
||||
halo_map = halo_map["halomap"]
|
||||
cat = csiborgtools.read.CSiBORGHaloCatalogue(
|
||||
nsim, paths, rawdata=True, load_fitted=False, load_initial=False)
|
||||
hid2map = {hid: i for i, hid in enumerate(halo_map[:, 0])}
|
||||
|
||||
out = csiborgtools.read.cols_to_structured(len(clumps_cat), cols_collect)
|
||||
indxs = clumps_cat["index"]
|
||||
for i, hid in enumerate(tqdm(indxs) if verbose else indxs):
|
||||
out = csiborgtools.read.cols_to_structured(len(cat), cols_collect)
|
||||
for i, hid in enumerate(tqdm(cat["index"]) if verbose else cat["index"]):
|
||||
out["index"][i] = hid
|
||||
if not ismain[i]:
|
||||
continue
|
||||
part = csiborgtools.read.load_halo_particles(hid, parts, halo_map,
|
||||
hid2map)
|
||||
|
||||
part = csiborgtools.read.load_parent_particles(hid, parts, clump_map,
|
||||
clid2map, clumps_cat)
|
||||
# Skip if the halo is too small.
|
||||
if part is None or part.size < 100:
|
||||
continue
|
||||
|
@ -101,7 +99,6 @@ for nsim in [ics[i] for i in jobs]:
|
|||
delta = overlapper.make_delta(part[:, :3], part[:, 3], subbox=True)
|
||||
out["lagpatch_ncells"][i] = csiborgtools.fits.delta2ncells(delta)
|
||||
|
||||
out = out[ismain]
|
||||
# Now save it
|
||||
fout = paths.initmatch(nsim, "fit")
|
||||
print(f"{datetime.now()}: dumping fits to .. `{fout}`.",
|
||||
|
|
|
@ -30,7 +30,7 @@ except ModuleNotFoundError:
|
|||
|
||||
|
||||
def pair_match(nsim0, nsimx, sigma, smoothen, verbose):
|
||||
from csiborgtools.read import HaloCatalogue, read_h5
|
||||
from csiborgtools.read import CSiBORGHaloCatalogue, read_h5
|
||||
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
smooth_kwargs = {"sigma": sigma, "mode": "constant", "cval": 0.0}
|
||||
|
@ -40,10 +40,10 @@ def pair_match(nsim0, nsimx, sigma, smoothen, verbose):
|
|||
# Load the raw catalogues (i.e. no selection) including the initial CM
|
||||
# positions and the particle archives.
|
||||
bounds = {"totpartmass": (1e12, None)}
|
||||
cat0 = HaloCatalogue(nsim0, paths, load_initial=True, bounds=bounds,
|
||||
with_lagpatch=True, load_clumps_cat=True)
|
||||
catx = HaloCatalogue(nsimx, paths, load_initial=True, bounds=bounds,
|
||||
with_lagpatch=True, load_clumps_cat=True)
|
||||
cat0 = CSiBORGHaloCatalogue(nsim0, paths, load_initial=True, bounds=bounds,
|
||||
with_lagpatch=True, load_clumps_cat=True)
|
||||
catx = CSiBORGHaloCatalogue(nsimx, paths, load_initial=True, bounds=bounds,
|
||||
with_lagpatch=True, load_clumps_cat=True)
|
||||
|
||||
clumpmap0 = read_h5(paths.particles(nsim0))["clumpmap"]
|
||||
parts0 = read_h5(paths.initmatch(nsim0, "particles"))["particles"]
|
||||
|
|
151
scripts/mv_fofmembership.py
Normal file
151
scripts/mv_fofmembership.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
# Copyright (C) 2022 Richard Stiskalek
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
Short script to move and change format of the CSiBORG FoF membership files
|
||||
calculated by Julien. Additionally, also orders the particles in the same way
|
||||
as the PHEW halo finder output.
|
||||
"""
|
||||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
from gc import collect
|
||||
from os.path import join
|
||||
from shutil import copy
|
||||
|
||||
import numpy
|
||||
from mpi4py import MPI
|
||||
from taskmaster import work_delegation
|
||||
from tqdm import trange
|
||||
|
||||
from utils import get_nsims
|
||||
|
||||
try:
|
||||
import csiborgtools
|
||||
except ModuleNotFoundError:
|
||||
import sys
|
||||
sys.path.append("../")
|
||||
import csiborgtools
|
||||
|
||||
|
||||
def copy_membership(nsim, verbose=True):
|
||||
"""
|
||||
Copy the FoF particle halo membership to the CSiBORG directory and write it
|
||||
as a NumPy array instead of a text file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
verbose : bool, optional
|
||||
Verbosity flag.
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
fpath = join("/mnt/extraspace/jeg/greenwhale/Constrained_Sims",
|
||||
f"sim_{nsim}/particle_membership_{nsim}_FOF.txt")
|
||||
if verbose:
|
||||
print(f"Loading from ... `{fpath}`.")
|
||||
data = numpy.genfromtxt(fpath, dtype=int)
|
||||
|
||||
fout = paths.fof_membership(nsim)
|
||||
if verbose:
|
||||
print(f"Saving to ... `{fout}`.")
|
||||
numpy.save(fout, data)
|
||||
|
||||
|
||||
def copy_catalogue(nsim, verbose=True):
|
||||
"""
|
||||
Move the FoF catalogue to the CSiBORG directory.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
verbose : bool, optional
|
||||
Verbosity flag.
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
source = join("/mnt/extraspace/jeg/greenwhale/Constrained_Sims",
|
||||
f"sim_{nsim}/halo_catalog_{nsim}_FOF.txt")
|
||||
dest = paths.fof_cat(nsim)
|
||||
if verbose:
|
||||
print("Copying`{}` to `{}`.".format(source, dest))
|
||||
copy(source, dest)
|
||||
|
||||
|
||||
def sort_fofid(nsim, verbose=True):
|
||||
"""
|
||||
Read the FoF particle halo membership and sort the halo IDs to the ordering
|
||||
of particles in the PHEW clump IDs.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
verbose : bool, optional
|
||||
Verbosity flag.
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
fpath = paths.fof_membership(nsim)
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: loading from ... `{fpath}`.")
|
||||
# Columns are halo ID, particle ID.
|
||||
fof = numpy.load(fpath)
|
||||
|
||||
reader = csiborgtools.read.ParticleReader(paths)
|
||||
pars_extract = ["x"] # Dummy variable
|
||||
__, pids = reader.read_particle(nsnap, nsim, pars_extract,
|
||||
return_structured=False, verbose=verbose)
|
||||
del __
|
||||
collect()
|
||||
|
||||
# Map the particle IDs in pids to their corresponding PHEW array index
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: mapping particle IDs to their indices.")
|
||||
pids_idx = {pid: i for i, pid in enumerate(pids)}
|
||||
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: mapping FoF HIDs to their array indices.")
|
||||
# Unassigned particle IDs are assigned a halo ID of 0. Same as PHEW.
|
||||
fof_hids = numpy.zeros(pids.size, dtype=numpy.int32)
|
||||
for i in trange(fof.shape[0]) if verbose else range(fof.shape[0]):
|
||||
hid, pid = fof[i]
|
||||
fof_hids[pids_idx[pid]] = hid
|
||||
|
||||
fout = paths.fof_membership(nsim, sorted=True)
|
||||
if verbose:
|
||||
print(f"Saving the sorted data to ... `{fout}`")
|
||||
numpy.save(fout, fof_hids)
|
||||
|
||||
|
||||
def main(nsim, verbose=True):
|
||||
copy_membership(nsim, verbose=verbose)
|
||||
copy_catalogue(nsim, verbose=verbose)
|
||||
sort_fofid(nsim, verbose=verbose)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--simname", type=str, default="csiborg",
|
||||
choices=["csiborg", "quijote"],
|
||||
help="Simulation name")
|
||||
parser.add_argument("--nsims", type=int, nargs="+", default=None,
|
||||
help="Indices of simulations to cross. If `-1` processes all simulations.") # noqa
|
||||
args = parser.parse_args()
|
||||
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsims = get_nsims(args, paths)
|
||||
comm = MPI.COMM_WORLD
|
||||
|
||||
work_delegation(main, nsims, comm)
|
|
@ -12,12 +12,12 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
Script to load in the simulation particles, load them by their clump ID and
|
||||
dump into a HDF5 file. Stores the first and last index of each clump in the
|
||||
Script to load in the simulation particles, sort them by their FoF halo ID and
|
||||
dump into a HDF5 file. Stores the first and last index of each halo in the
|
||||
particle array. This can be used for fast slicing of the array to acces
|
||||
particles of a single clump.
|
||||
"""
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
from gc import collect
|
||||
|
||||
|
@ -25,8 +25,11 @@ import h5py
|
|||
import numba
|
||||
import numpy
|
||||
from mpi4py import MPI
|
||||
from taskmaster import work_delegation
|
||||
from tqdm import trange
|
||||
|
||||
from utils import get_nsims
|
||||
|
||||
try:
|
||||
import csiborgtools
|
||||
except ModuleNotFoundError:
|
||||
|
@ -35,80 +38,79 @@ except ModuleNotFoundError:
|
|||
sys.path.append("../")
|
||||
import csiborgtools
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
# We set up the MPI
|
||||
comm = MPI.COMM_WORLD
|
||||
rank = comm.Get_rank()
|
||||
nproc = comm.Get_size()
|
||||
|
||||
# And next parse all the arguments and set up CSiBORG objects
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--ics", type=int, nargs="+", default=None,
|
||||
help="IC realisations. If `-1` processes all simulations.")
|
||||
args = parser.parse_args()
|
||||
|
||||
verbose = nproc == 1
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
partreader = csiborgtools.read.ParticleReader(paths)
|
||||
# Keep "ID" as the last column!
|
||||
pars_extract = ['x', 'y', 'z', 'vx', 'vy', 'vz', 'M', "ID"]
|
||||
|
||||
if args.ics is None or args.ics[0] == -1:
|
||||
ics = paths.get_ics("csiborg")
|
||||
else:
|
||||
ics = args.ics
|
||||
|
||||
|
||||
@numba.jit(nopython=True)
|
||||
def minmax_clump(clid, clump_ids, start_loop=0):
|
||||
def minmax_halo(hid, halo_ids, start_loop=0):
|
||||
"""
|
||||
Find the start and end index of a clump in a sorted array of clump IDs.
|
||||
Find the start and end index of a halo in a sorted array of halo IDs.
|
||||
This is much faster than using `numpy.where` and then `numpy.min` and
|
||||
`numpy.max`.
|
||||
"""
|
||||
start = None
|
||||
end = None
|
||||
|
||||
for i in range(start_loop, clump_ids.size):
|
||||
n = clump_ids[i]
|
||||
if n == clid:
|
||||
for i in range(start_loop, halo_ids.size):
|
||||
n = halo_ids[i]
|
||||
if n == hid:
|
||||
if start is None:
|
||||
start = i
|
||||
end = i
|
||||
elif n > clid:
|
||||
elif n > hid:
|
||||
break
|
||||
return start, end
|
||||
|
||||
|
||||
# MPI loop over individual simulations. We read in the particles from RAMSES
|
||||
# files and dump them to a HDF5 file.
|
||||
jobs = csiborgtools.fits.split_jobs(len(ics), nproc)[rank]
|
||||
for i in jobs:
|
||||
nsim = ics[i]
|
||||
def main(nsim, simname, verbose):
|
||||
"""
|
||||
Read in the snapshot particles, sort them by their FoF halo ID and dump
|
||||
into a HDF5 file. Stores the first and last index of each halo in the
|
||||
particle array for fast slicing of the array to acces particles of a single
|
||||
halo.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
simname : str
|
||||
Simulation name.
|
||||
verbose : bool
|
||||
Verbosity flag.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
partreader = csiborgtools.read.ParticleReader(paths)
|
||||
|
||||
if simname == "quijote":
|
||||
raise NotImplementedError("Not implemented for Quijote yet.")
|
||||
|
||||
# Keep "ID" as the last column!
|
||||
pars_extract = ['x', 'y', 'z', 'vx', 'vy', 'vz', 'M', "ID"]
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
fname = paths.particles(nsim)
|
||||
# We first read in the clump IDs of the particles and infer the sorting.
|
||||
# Right away we dump the clump IDs to a HDF5 file and clear up memory.
|
||||
print(f"{datetime.now()}: rank {rank} loading particles {nsim}.",
|
||||
flush=True)
|
||||
part_cids = partreader.read_clumpid(nsnap, nsim, verbose=verbose)
|
||||
sort_indxs = numpy.argsort(part_cids).astype(numpy.int32)
|
||||
part_cids = part_cids[sort_indxs]
|
||||
# We first read in the halo IDs of the particles and infer the sorting.
|
||||
# Right away we dump the halo IDs to a HDF5 file and clear up memory.
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: loading particles {nsim}.", flush=True)
|
||||
part_hids = partreader.read_fof_hids(nsim)
|
||||
sort_indxs = numpy.argsort(part_hids).astype(numpy.int32)
|
||||
part_hids = part_hids[sort_indxs]
|
||||
with h5py.File(fname, "w") as f:
|
||||
f.create_dataset("clump_ids", data=part_cids)
|
||||
f.create_dataset("halo_ids", data=part_hids)
|
||||
f.close()
|
||||
del part_cids
|
||||
del part_hids
|
||||
collect()
|
||||
|
||||
# Next we read in the particles and sort them by their clump ID.
|
||||
# Next we read in the particles and sort them by their halo ID.
|
||||
# We cannot directly read this as an unstructured array because the float32
|
||||
# precision is insufficient to capture the clump IDs.
|
||||
# precision is insufficient to capture the halo IDs.
|
||||
parts, pids = partreader.read_particle(
|
||||
nsnap, nsim, pars_extract, return_structured=False, verbose=verbose)
|
||||
# Now we in two steps save the particles and particle IDs.
|
||||
print(f"{datetime.now()}: rank {rank} dumping particles from {nsim}.",
|
||||
flush=True)
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: dumping particles from {nsim}.", flush=True)
|
||||
parts = parts[sort_indxs]
|
||||
pids = pids[sort_indxs]
|
||||
del sort_indxs
|
||||
|
@ -126,29 +128,48 @@ for i in jobs:
|
|||
del parts
|
||||
collect()
|
||||
|
||||
print(f"{datetime.now()}: rank {rank} creating clump mapping for {nsim}.",
|
||||
flush=True)
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: creating halo map for {nsim}.", flush=True)
|
||||
# Load clump IDs back to memory
|
||||
with h5py.File(fname, "r") as f:
|
||||
part_cids = f["clump_ids"][:]
|
||||
part_hids = f["halo_ids"][:]
|
||||
# We loop over the unique clump IDs.
|
||||
unique_clump_ids = numpy.unique(part_cids)
|
||||
clump_map = numpy.full((unique_clump_ids.size, 3), numpy.nan,
|
||||
dtype=numpy.int32)
|
||||
unique_halo_ids = numpy.unique(part_hids)
|
||||
halo_map = numpy.full((unique_halo_ids.size, 3), numpy.nan,
|
||||
dtype=numpy.int32)
|
||||
start_loop = 0
|
||||
niters = unique_clump_ids.size
|
||||
niters = unique_halo_ids.size
|
||||
for i in trange(niters) if verbose else range(niters):
|
||||
clid = unique_clump_ids[i]
|
||||
k0, kf = minmax_clump(clid, part_cids, start_loop=start_loop)
|
||||
clump_map[i, 0] = clid
|
||||
clump_map[i, 1] = k0
|
||||
clump_map[i, 2] = kf
|
||||
hid = unique_halo_ids[i]
|
||||
k0, kf = minmax_halo(hid, part_hids, start_loop=start_loop)
|
||||
halo_map[i, 0] = hid
|
||||
halo_map[i, 1] = k0
|
||||
halo_map[i, 2] = kf
|
||||
start_loop = kf
|
||||
|
||||
# We save the mapping to a HDF5 file
|
||||
with h5py.File(paths.particles(nsim), "r+") as f:
|
||||
f.create_dataset("clumpmap", data=clump_map)
|
||||
f.create_dataset("halomap", data=halo_map)
|
||||
f.close()
|
||||
|
||||
del part_cids
|
||||
del part_hids
|
||||
collect()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# And next parse all the arguments and set up CSiBORG objects
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--simname", type=str, default="csiborg",
|
||||
choices=["csiborg", "quijote"],
|
||||
help="Simulation name")
|
||||
parser.add_argument("--nsims", type=int, nargs="+", default=None,
|
||||
help="IC realisations. If `-1` processes all .")
|
||||
args = parser.parse_args()
|
||||
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsims = get_nsims(args, paths)
|
||||
|
||||
def _main(nsim, verbose=MPI.COMM_WORLD.nproc == 1):
|
||||
main(nsim, args.simname, verbose=verbose)
|
||||
|
||||
work_delegation(_main, nsims, MPI.COMM_WORLD)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
Script to sort the initial snapshot particles according to their final
|
||||
snapshot ordering, which is sorted by the clump IDs.
|
||||
snapshot ordering, which is sorted by the halo IDs.
|
||||
"""
|
||||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
|
@ -23,6 +23,9 @@ from gc import collect
|
|||
import h5py
|
||||
import numpy
|
||||
from mpi4py import MPI
|
||||
from taskmaster import work_delegation
|
||||
|
||||
from utils import get_nsims
|
||||
|
||||
try:
|
||||
import csiborgtools
|
||||
|
@ -33,42 +36,37 @@ except ModuleNotFoundError:
|
|||
import csiborgtools
|
||||
|
||||
|
||||
# Get MPI things
|
||||
comm = MPI.COMM_WORLD
|
||||
rank = comm.Get_rank()
|
||||
nproc = comm.Get_size()
|
||||
verbose = nproc == 1
|
||||
def _main(nsim, simname, verbose):
|
||||
"""
|
||||
Sort the initial snapshot particles according to their final snapshot
|
||||
ordering and dump them into a HDF5 file.
|
||||
|
||||
# Argument parser
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--ics", type=int, nargs="+", default=None,
|
||||
help="IC realisations. If `-1` processes all simulations.")
|
||||
args = parser.parse_args()
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
partreader = csiborgtools.read.ParticleReader(paths)
|
||||
# NOTE: ID has to be the last column.
|
||||
pars_extract = ["x", "y", "z", "M", "ID"]
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
simname : str
|
||||
Simulation name.
|
||||
verbose : bool
|
||||
Verbosity flag.
|
||||
"""
|
||||
if simname == "quijote":
|
||||
raise NotImplementedError("Quijote not implemented yet.")
|
||||
|
||||
if args.ics is None or args.ics[0] == -1:
|
||||
ics = paths.get_ics("csiborg")
|
||||
else:
|
||||
ics = args.ics
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
partreader = csiborgtools.read.ParticleReader(paths)
|
||||
|
||||
# We loop over simulations. Each simulation is then procesed with MPI, rank 0
|
||||
# loads the data and broadcasts it to other ranks.
|
||||
jobs = csiborgtools.fits.split_jobs(len(ics), nproc)[rank]
|
||||
for i in jobs:
|
||||
nsim = ics[i]
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
|
||||
print(f"{datetime.now()}: reading and processing simulation {nsim}.",
|
||||
flush=True)
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: reading and processing simulation {nsim}.",
|
||||
flush=True)
|
||||
# We first load the particle IDs in the final snapshot.
|
||||
pidf = csiborgtools.read.read_h5(paths.particles(nsim))
|
||||
pidf = pidf["particle_ids"]
|
||||
# Then we load the particles in the initil snapshot and make sure that
|
||||
# their particle IDs are sorted as in the final snapshot.
|
||||
# Again, because of precision this must be read as structured.
|
||||
# their particle IDs are sorted as in the final snapshot. Again, because of
|
||||
# precision this must be read as structured.
|
||||
# NOTE: ID has to be the last column.
|
||||
pars_extract = ["x", "y", "z", "M", "ID"]
|
||||
part0, pid0 = partreader.read_particle(
|
||||
1, nsim, pars_extract, return_structured=False, verbose=verbose)
|
||||
# First enforce them to already be sorted and then apply reverse
|
||||
|
@ -77,6 +75,26 @@ for i in jobs:
|
|||
del pid0
|
||||
collect()
|
||||
part0 = part0[numpy.argsort(numpy.argsort(pidf))]
|
||||
print(f"{datetime.now()}: dumping particles for {nsim}.", flush=True)
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: dumping particles for {nsim}.", flush=True)
|
||||
with h5py.File(paths.initmatch(nsim, "particles"), "w") as f:
|
||||
f.create_dataset("particles", data=part0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Argument parser
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--simname", type=str, default="csiborg",
|
||||
choices=["csiborg", "quijote"],
|
||||
help="Simulation name")
|
||||
parser.add_argument("--nsims", type=int, nargs="+", default=None,
|
||||
help="IC realisations. If `-1` processes all.")
|
||||
args = parser.parse_args()
|
||||
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsims = get_nsims(args, paths)
|
||||
|
||||
def main(nsim):
|
||||
_main(nsim, args.simname, MPI.COMM_WORLD.size == 1)
|
||||
|
||||
work_delegation(main, nsims, MPI.COMM_WORLD)
|
||||
|
|
|
@ -81,7 +81,7 @@ def read_single_catalogue(args, config, nsim, run, rmax, paths, nobs=None):
|
|||
|
||||
Returns
|
||||
-------
|
||||
cat : csiborgtools.read.HaloCatalogue or csiborgtools.read.QuijoteHaloCatalogue # noqa
|
||||
cat : csiborgtools.read.CSiBORGHaloCatalogue or csiborgtools.read.QuijoteHaloCatalogue # noqa
|
||||
Halo catalogue with selection criteria applied.
|
||||
"""
|
||||
selection = config.get(run, None)
|
||||
|
@ -89,7 +89,7 @@ def read_single_catalogue(args, config, nsim, run, rmax, paths, nobs=None):
|
|||
raise KeyError(f"No configuration for run {run}.")
|
||||
# We first read the full catalogue without applying any bounds.
|
||||
if args.simname == "csiborg":
|
||||
cat = csiborgtools.read.HaloCatalogue(nsim, paths)
|
||||
cat = csiborgtools.read.CSiBORGHaloCatalogue(nsim, paths)
|
||||
else:
|
||||
cat = csiborgtools.read.QuijoteHaloCatalogue(nsim, paths, nsnap=4)
|
||||
if nobs is not None:
|
||||
|
|
|
@ -46,11 +46,11 @@ def open_csiborg(nsim):
|
|||
|
||||
Returns
|
||||
-------
|
||||
cat : csiborgtools.read.HaloCatalogue
|
||||
cat : csiborgtools.read.CSiBORGHaloCatalogue
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
bounds = {"totpartmass": (None, None), "dist": (0, 155/0.705)}
|
||||
return csiborgtools.read.HaloCatalogue(nsim, paths, bounds=bounds)
|
||||
return csiborgtools.read.CSiBORGHaloCatalogue(nsim, paths, bounds=bounds)
|
||||
|
||||
|
||||
def open_quijote(nsim, nobs=None):
|
||||
|
@ -118,7 +118,7 @@ def plot_mass_vs_ncells(nsim, pdf=False):
|
|||
|
||||
def plot_hmf(pdf=False):
|
||||
"""
|
||||
Plot the (ultimate paretn) halo mass function of CSiBORG and Quijote.
|
||||
Plot the FoF halo mass function of CSiBORG and Quijote.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -132,7 +132,8 @@ def plot_hmf(pdf=False):
|
|||
print("Plotting the HMF...", flush=True)
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
|
||||
csiborg_nsims = paths.get_ics("csiborg")
|
||||
# csiborg_nsims = paths.get_ics("csiborg")
|
||||
csiborg_nsims = [7444]
|
||||
print("Loading CSiBORG halo counts.", flush=True)
|
||||
for i, nsim in enumerate(tqdm(csiborg_nsims)):
|
||||
data = numpy.load(paths.halo_counts("csiborg", nsim))
|
||||
|
@ -141,6 +142,8 @@ def plot_hmf(pdf=False):
|
|||
csiborg_counts = numpy.full((len(csiborg_nsims), len(bins) - 1),
|
||||
numpy.nan, dtype=numpy.float32)
|
||||
csiborg_counts[i, :] = data["counts"]
|
||||
print(data["counts"])
|
||||
print(csiborg_counts)
|
||||
csiborg_counts /= numpy.diff(bins).reshape(1, -1)
|
||||
|
||||
print("Loading Quijote halo counts.", flush=True)
|
||||
|
@ -211,6 +214,76 @@ def plot_hmf(pdf=False):
|
|||
plt.close()
|
||||
|
||||
|
||||
def plot_hmf_quijote_full(pdf=False):
|
||||
"""
|
||||
Plot the FoF halo mass function of Quijote full run.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pdf : bool, optional
|
||||
Whether to save the figure as a PDF file.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
print("Plotting the HMF...", flush=True)
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
|
||||
print("Loading Quijote halo counts.", flush=True)
|
||||
quijote_nsims = paths.get_ics("quijote")
|
||||
for i, nsim in enumerate(tqdm(quijote_nsims)):
|
||||
data = numpy.load(paths.halo_counts("quijote_full", nsim))
|
||||
if i == 0:
|
||||
bins = data["bins"]
|
||||
counts = numpy.full((len(quijote_nsims), len(bins) - 1), numpy.nan,
|
||||
dtype=numpy.float32)
|
||||
counts[i, :] = data["counts"]
|
||||
counts /= numpy.diff(bins).reshape(1, -1)
|
||||
counts /= 1000**3
|
||||
|
||||
x = 10**(0.5 * (bins[1:] + bins[:-1]))
|
||||
# Edit lower and upper limits
|
||||
counts[:, x < 10**(12.4)] = numpy.nan
|
||||
counts[:, x > 4e15] = numpy.nan
|
||||
|
||||
with plt.style.context(plt_utils.mplstyle):
|
||||
cols = plt.rcParams["axes.prop_cycle"].by_key()["color"]
|
||||
fig, ax = plt.subplots(nrows=2, sharex=True,
|
||||
figsize=(3.5, 2.625 * 1.25),
|
||||
gridspec_kw={"height_ratios": [1, 0.65]})
|
||||
fig.subplots_adjust(hspace=0, wspace=0)
|
||||
|
||||
# Upper panel data
|
||||
mean = numpy.mean(counts, axis=0)
|
||||
std = numpy.std(counts, axis=0)
|
||||
ax[0].plot(x, mean)
|
||||
ax[0].fill_between(x, mean - std, mean + std, alpha=0.5)
|
||||
# Lower panel data
|
||||
for i in range(counts.shape[0]):
|
||||
ax[1].plot(x, counts[i, :] / mean, c=cols[0])
|
||||
|
||||
# Labels and accesories
|
||||
ax[1].axhline(1, color="k", ls=plt.rcParams["lines.linestyle"],
|
||||
lw=0.5 * plt.rcParams["lines.linewidth"], zorder=0)
|
||||
ax[0].set_ylabel(r"$\frac{\mathrm{d}^2 n}{\mathrm{d}\log M_{\rm h} \mathrm{d} V}~[\mathrm{dex}^{-1} (\mathrm{Mpc / h})^{-3}]$", # noqa
|
||||
fontsize="small")
|
||||
ax[1].set_xlabel(r"$M_{\rm h}$ [$M_\odot$]")
|
||||
ax[1].set_ylabel(r"$\mathrm{HMF} / \langle \mathrm{HMF} \rangle$",
|
||||
fontsize="small")
|
||||
|
||||
ax[0].set_xscale("log")
|
||||
ax[0].set_yscale("log")
|
||||
ax[0].legend()
|
||||
|
||||
fig.tight_layout(h_pad=0, w_pad=0)
|
||||
for ext in ["png"] if pdf is False else ["png", "pdf"]:
|
||||
fout = join(plt_utils.fout, f"hmf_quijote_full.{ext}")
|
||||
print(f"Saving to `{fout}`.")
|
||||
fig.savefig(fout, dpi=plt_utils.dpi, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
def load_field(kind, nsim, grid, MAS, in_rsp=False, smooth_scale=None):
|
||||
r"""
|
||||
Load a single field.
|
||||
|
@ -516,7 +589,8 @@ def plot_sky_distribution(field, nsim, grid, nside, smooth_scale=None,
|
|||
if plot_halos is not None:
|
||||
bounds = {"dist": (dmin, dmax),
|
||||
"totpartmass": (plot_halos, None)}
|
||||
cat = csiborgtools.read.HaloCatalogue(nsim, paths, bounds=bounds)
|
||||
cat = csiborgtools.read.CSiBORGHaloCatalogue(nsim, paths,
|
||||
bounds=bounds)
|
||||
X = cat.position(cartesian=False)
|
||||
healpy.projscatter(numpy.deg2rad(X[:, 2] + 90),
|
||||
numpy.deg2rad(X[:, 1]),
|
||||
|
@ -560,6 +634,9 @@ if __name__ == "__main__":
|
|||
if False:
|
||||
plot_hmf(pdf=False)
|
||||
|
||||
if True:
|
||||
plot_hmf_quijote_full(pdf=False)
|
||||
|
||||
if False:
|
||||
kind = "overdensity"
|
||||
grid = 1024
|
||||
|
@ -567,7 +644,7 @@ if __name__ == "__main__":
|
|||
plot_groups=False, dmin=45, dmax=60,
|
||||
plot_halos=5e13, volume_weight=True)
|
||||
|
||||
if True:
|
||||
if False:
|
||||
kind = "overdensity"
|
||||
grid = 256
|
||||
smooth_scale = 0
|
||||
|
@ -589,4 +666,3 @@ if __name__ == "__main__":
|
|||
plt.tight_layout()
|
||||
plt.savefig("../plots/velocity_distribution.png", dpi=450,
|
||||
bbox_inches="tight")
|
||||
|
||||
|
|
|
@ -51,11 +51,11 @@ def open_cat(nsim):
|
|||
|
||||
Returns
|
||||
-------
|
||||
cat : csiborgtools.read.HaloCatalogue
|
||||
cat : csiborgtools.read.CSiBORGHaloCatalogue
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
bounds = {"totpartmass": (1e12, None)}
|
||||
return csiborgtools.read.HaloCatalogue(nsim, paths, bounds=bounds)
|
||||
return csiborgtools.read.CSiBORGHaloCatalogue(nsim, paths, bounds=bounds)
|
||||
|
||||
|
||||
def plot_mass_vs_pairoverlap(nsim0, nsimx):
|
||||
|
|
Loading…
Reference in a new issue