Remove halo fitting. (#83)

* Rename file

* Remove old content

* Remove halo fit

* Completely remove fits

* Add utils here

* Account for renaming
This commit is contained in:
Richard Stiskalek 2023-08-07 11:33:27 +02:00 committed by GitHub
parent ff395af148
commit f4a7cb0d16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 148 additions and 718 deletions

View file

@ -1,153 +0,0 @@
# 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.
"""
A script to fit FoF halos (concentration, ...). The CSiBORG particle array of
each realisation must have been processed in advance by `pre_dumppart.py`.
Quijote is not supported yet
"""
from argparse import ArgumentParser
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 fit_halo(particles, box):
"""
Fit a single halo from the particle array. Only halos with more than 100
particles are fitted.
Parameters
----------
particles : 2-dimensional array of shape `(n_particles, 3)`
Particle array. The columns must be `x`, `y`, `z`, `vx`, `vy`, `vz`,
`M`.
box : object derived from :py:class`csiborgtools.read.BaseBox`
Box object.
Returns
-------
out : dict
"""
halo = csiborgtools.fits.Halo(particles, box)
out = {}
out["npart"] = len(halo)
out["totpartmass"] = numpy.sum(halo["M"])
for i, v in enumerate(["vx", "vy", "vz"]):
out[v] = numpy.average(halo.vel[:, i], weights=halo["M"])
if out["npart"] < 100:
return out
cm, dist = halo.center_of_mass()
m200c, r200c = halo.spherical_overdensity_mass(dist, 200)
angmom = halo.angular_momentum(dist, cm, r200c)
out["m200c"] = m200c
out["r200c"] = r200c
out["lambda200c"] = halo.lambda_bullock(angmom, m200c, r200c)
out["conc"] = halo.nfw_concentration(dist, r200c)
return out
def _main(nsim, simname, verbose):
"""
Fit the FoF halos.
Parameters
----------
nsim : int
IC realisation index.
simname : str
Simulation name.
verbose : bool
Verbosity flag.
"""
cols = [("index", numpy.int32),
("npart", numpy.int32),
("totpartmass", numpy.float32),
("vx", numpy.float32),
("vy", numpy.float32),
("vz", numpy.float32),
("conc", numpy.float32),
("r200c", numpy.float32),
("m200c", numpy.float32),
("lambda200c", numpy.float32),]
nsnap = max(paths.get_snapshots(nsim, simname))
if simname == "csiborg":
box = csiborgtools.read.CSiBORGBox(nsnap, nsim, paths)
cat = csiborgtools.read.CSiBORGHaloCatalogue(
nsim, paths, bounds=None, load_fitted=False, load_initial=False)
else:
box = csiborgtools.read.QuijoteBox(nsnap, nsim, paths)
cat = csiborgtools.read.QuijoteHaloCatalogue(
nsim, paths, nsnap, bounds=None, load_fitted=False,
load_initial=False)
# Particle archive
f = csiborgtools.read.read_h5(paths.particles(nsim, simname))
particles = f["particles"]
halo_map = f["halomap"]
hid2map = {hid: i for i, hid in enumerate(halo_map[:, 0])}
out = csiborgtools.read.cols_to_structured(len(cat), cols)
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)
# Skip if no particles.
if part is None:
continue
_out = fit_halo(part, box)
for key in _out.keys():
out[key][i] = _out.get(key, numpy.nan)
fout = paths.structfit(nsnap, nsim, simname)
if verbose:
print(f"Saving to `{fout}`.", flush=True)
numpy.save(fout, out)
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--simname", type=str, default="csiborg",
choices=["csiborg", "quijote", "quijote_full"],
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.Get_size() == 1)
work_delegation(main, nsims, MPI.COMM_WORLD)

View file

@ -61,7 +61,7 @@ def get_counts(nsim, bins, paths, parser_args):
cat = csiborgtools.read.CSiBORGHaloCatalogue(
nsim, paths, bounds=bounds, load_fitted=False, load_initial=False)
logmass = numpy.log10(cat["fof_totpartmass"])
counts = csiborgtools.fits.number_counts(logmass, bins)
counts = csiborgtools.number_counts(logmass, bins)
elif simname == "quijote":
cat0 = csiborgtools.read.QuijoteHaloCatalogue(
nsim, paths, nsnap=4, load_fitted=False, load_initial=False)
@ -72,12 +72,12 @@ def get_counts(nsim, bins, paths, parser_args):
for nobs in range(nmax):
cat = cat0.pick_fiducial_observer(nobs, rmax=parser_args.Rmax)
logmass = numpy.log10(cat["group_mass"])
counts[nobs, :] = csiborgtools.fits.number_counts(logmass, bins)
counts[nobs, :] = csiborgtools.number_counts(logmass, bins)
elif simname == "quijote_full":
cat = csiborgtools.read.QuijoteHaloCatalogue(
nsim, paths, nsnap=4, load_fitted=False, load_initial=False)
logmass = numpy.log10(cat["group_mass"])
counts = csiborgtools.fits.number_counts(logmass, bins)
counts = csiborgtools.number_counts(logmass, bins)
else:
raise ValueError(f"Unknown simulation name `{simname}`.")

View file

@ -91,14 +91,14 @@ def _main(nsim, simname, verbose):
pos, mass = part[:, :3], part[:, 3]
# Calculate the centre of mass and the Lagrangian patch size.
cm = csiborgtools.fits.center_of_mass(pos, mass, boxsize=1.0)
distances = csiborgtools.fits.periodic_distance(pos, cm, boxsize=1.0)
cm = csiborgtools.center_of_mass(pos, mass, boxsize=1.0)
distances = csiborgtools.periodic_distance(pos, cm, boxsize=1.0)
out["x"][i], out["y"][i], out["z"][i] = cm
out["lagpatch_size"][i] = numpy.percentile(distances, 99)
# Calculate the number of cells with > 0 density.
delta = overlapper.make_delta(pos, mass, subbox=True)
out["lagpatch_ncells"][i] = csiborgtools.fits.delta2ncells(delta)
out["lagpatch_ncells"][i] = csiborgtools.delta2ncells(delta)
# Now save it
fout = paths.initmatch(nsim, simname, "fit")