mirror of
https://github.com/Richard-Sti/csiborgtools.git
synced 2024-12-22 07:28:02 +00:00
Add better diagnostics & plotting (#67)
* Add caching functions * Add limts * Add new mass runs * Update .gitignore * Edit which CDFs are loaded * Stop saving cross hindxs * Change dist to half precision * New nearest path * Add neighbour counting * Add neighbour kwargs * Update work in progress * Add new counting * Add how dist is built * Collect dist to 1 file * Update reading routine * Delete Quijote files * Remove file * Back to float32 * Fix bugs * Rename utils * Remove neighbuor kwargs * Rename file * Fix bug * Rename plt utils * Change where nghb kwargs from * line length * Remove old notebooks * Move survey * Add white space * Update TODO * Update CDF calculation * Update temporarily plotting * Merge branch 'add_diagnostics' of github.com:Richard-Sti/csiborgtools into add_diagnostics * Start adding documentation to plotting * Remove comments * Better code documentation * Some work on tidal tensor * Better plotting * Add comment * Remove nb * Remove comment * Add documentation * Update plotting * Update submission * Update KL vs KS plots * Update the plotting routine * Update plotting * Update plotting routines
This commit is contained in:
parent
004d9629a2
commit
ccbbbd24b4
20 changed files with 1075 additions and 32121 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -22,3 +22,4 @@ scripts_test/
|
|||
scripts_plots/python.sh
|
||||
scripts_plots/submit.sh
|
||||
scripts_plots/*.out
|
||||
scripts_plots/*.sh
|
||||
|
|
|
@ -19,3 +19,26 @@ paths_glamdring = {"srcdir": "/mnt/extraspace/hdesmond/",
|
|||
"postdir": "/mnt/extraspace/rstiskalek/CSiBORG/",
|
||||
"quijote_dir": "/mnt/extraspace/rstiskalek/Quijote",
|
||||
}
|
||||
|
||||
|
||||
neighbour_kwargs = {"rmax_radial": 155 / 0.705,
|
||||
"nbins_radial": 50,
|
||||
"rmax_neighbour": 100.,
|
||||
"nbins_neighbour": 150,
|
||||
"paths_kind": paths_glamdring}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Surveys #
|
||||
###############################################################################
|
||||
|
||||
class SDSS:
|
||||
@staticmethod
|
||||
def steps(cls):
|
||||
return [(lambda x: cls[x], ("IN_DR7_LSS",)),
|
||||
(lambda x: cls[x] < 17.6, ("ELPETRO_APPMAG_r", )),
|
||||
(lambda x: cls[x] < 155, ("DIST", ))
|
||||
]
|
||||
|
||||
def __call__(self):
|
||||
return read.SDSS(h=1, sel_steps=self.steps)
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
Density field and cross-correlation calculations.
|
||||
|
||||
TODO:
|
||||
- [ ] Project the velocity field along the line of sight.
|
||||
"""
|
||||
from abc import ABC
|
||||
|
||||
|
@ -370,9 +367,9 @@ class TidalTensorField(BaseField):
|
|||
box : :py:class:`csiborgtools.read.CSiBORGBox`
|
||||
The simulation box information and transformations.
|
||||
MAS : str
|
||||
Mass assignment scheme. Options are Options are: 'NGP' (nearest grid
|
||||
point), 'CIC' (cloud-in-cell), 'TSC' (triangular-shape cloud), 'PCS'
|
||||
(piecewise cubic spline).
|
||||
Mass assignment scheme used to calculate the density field. Options
|
||||
are: 'NGP' (nearest grid point), 'CIC' (cloud-in-cell), 'TSC'
|
||||
(triangular-shape cloud), 'PCS' (piecewise cubic spline).
|
||||
"""
|
||||
def __init__(self, box, MAS):
|
||||
self.box = box
|
||||
|
@ -384,8 +381,6 @@ class TidalTensorField(BaseField):
|
|||
Calculate eigenvalues of the tidal tensor field, sorted in increasing
|
||||
order.
|
||||
|
||||
TODO: evaluate this on a grid instead.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tidal_tensor : :py:class:`MAS_library.tidal_tensor`
|
||||
|
@ -396,20 +391,14 @@ class TidalTensorField(BaseField):
|
|||
-------
|
||||
eigvals : 3-dimensional array of shape `(grid, grid, grid)`
|
||||
"""
|
||||
n_samples = tidal_tensor.T00.size
|
||||
# We create a array and then calculate the eigenvalues.
|
||||
Teval = numpy.full((n_samples, 3, 3), numpy.nan, dtype=numpy.float32)
|
||||
Teval[:, 0, 0] = tidal_tensor.T00
|
||||
Teval[:, 0, 1] = tidal_tensor.T01
|
||||
Teval[:, 0, 2] = tidal_tensor.T02
|
||||
Teval[:, 1, 1] = tidal_tensor.T11
|
||||
Teval[:, 1, 2] = tidal_tensor.T12
|
||||
Teval[:, 2, 2] = tidal_tensor.T22
|
||||
# TODO needs to be checked further
|
||||
grid = tidal_tensor.T00.shape[0]
|
||||
eigvals = numpy.full((grid, grid, grid, 3), numpy.nan,
|
||||
dtype=numpy.float32)
|
||||
dummy = numpy.full((3, 3), numpy.nan, dtype=numpy.float32)
|
||||
|
||||
eigvals = numpy.full((n_samples, 3), numpy.nan, dtype=numpy.float32)
|
||||
for i in range(n_samples):
|
||||
eigvals[i, :] = numpy.linalg.eigvalsh(Teval[i, ...], 'U')
|
||||
eigvals[i, :] = numpy.sort(eigvals[i, :])
|
||||
# FILL IN THESER ARGUMENTS
|
||||
tidal_tensor_to_eigenvalues(eigvals, dummy, ...)
|
||||
|
||||
return eigvals
|
||||
|
||||
|
@ -430,3 +419,23 @@ class TidalTensorField(BaseField):
|
|||
"""
|
||||
return MASL.tidal_tensor(overdensity_field, self.box._omega_m,
|
||||
self.box._aexp, self.MAS)
|
||||
|
||||
|
||||
@jit(nopython=True)
|
||||
def tidal_tensor_to_eigenvalues(eigvals, dummy, T00, T01, T02, T11, T12, T22):
|
||||
"""
|
||||
TODO: needs to be checked further.
|
||||
"""
|
||||
grid = T00.shape[0]
|
||||
for i in range(grid):
|
||||
for j in range(grid):
|
||||
for k in range(grid):
|
||||
dummy[0, 0] = T00[i, j, k]
|
||||
dummy[0, 1] = T01[i, j, k]
|
||||
dummy[0, 2] = T02[i, j, k]
|
||||
dummy[1, 1] = T11[i, j, k]
|
||||
dummy[1, 2] = T12[i, j, k]
|
||||
dummy[2, 2] = T22[i, j, k]
|
||||
eigvals[i, j, k, :] = numpy.linalg.eigvalsh(dummy, 'U')
|
||||
eigvals[i, j, k, :] = numpy.sort(eigvals[i, j, k, :])
|
||||
return eigvals
|
||||
|
|
|
@ -260,7 +260,6 @@ def fill_outside(field, fill_value, rmax, boxsize):
|
|||
N = imax
|
||||
# Squared radial distance from the center of the box in box units.
|
||||
rmax_box2 = (N * rmax / boxsize)**2
|
||||
# print("Box ", rmax_box2)
|
||||
|
||||
for i in range(N):
|
||||
idist2 = (i - 0.5 * (N - 1))**2
|
||||
|
@ -268,7 +267,6 @@ def fill_outside(field, fill_value, rmax, boxsize):
|
|||
jdist2 = (j - 0.5 * (N - 1))**2
|
||||
for k in range(N):
|
||||
kdist2 = (k - 0.5 * (N - 1))**2
|
||||
# print(idist2 + jdist2 + kdist2 > rmax_box2)
|
||||
if idist2 + jdist2 + kdist2 > rmax_box2:
|
||||
field[i, j, k] = fill_value
|
||||
return field
|
||||
|
|
|
@ -58,7 +58,6 @@ class BaseStructure(ABC):
|
|||
|
||||
@info.setter
|
||||
def info(self, info):
|
||||
# TODO turn this into a structured array and add some checks
|
||||
self._info = info
|
||||
|
||||
@property
|
||||
|
|
|
@ -19,10 +19,11 @@ the final snapshot.
|
|||
from math import floor
|
||||
|
||||
import numpy
|
||||
from numba import jit
|
||||
from scipy.integrate import quad
|
||||
from scipy.integrate import cumulative_trapezoid, quad
|
||||
from scipy.interpolate import interp1d
|
||||
from scipy.stats import gaussian_kde, kstest
|
||||
|
||||
from numba import jit
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
|
@ -205,54 +206,57 @@ class NearestNeighbourReader:
|
|||
Archive with keys `ndist`, `rdist`, `mass`, `cross_hindxs``
|
||||
"""
|
||||
assert simname in ["csiborg", "quijote"]
|
||||
fpath = self.paths.cross_nearest(simname, run, nsim, nobs)
|
||||
fpath = self.paths.cross_nearest(simname, run, "dist", nsim, nobs)
|
||||
return numpy.load(fpath)
|
||||
|
||||
def build_dist(self, simname, run, kind, verbose=True):
|
||||
def count_neighbour(self, out, ndist, rdist):
|
||||
"""
|
||||
Build the a PDF or a CDF for the nearest neighbour distribution.
|
||||
Counts the binned number of neighbour for each halo as a funtion of its
|
||||
radial distance from the centre of the high-resolution region.
|
||||
Count the number of neighbours for each halo as a function of its
|
||||
radial distance.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
simname : str
|
||||
Simulation name. Must be either `csiborg` or `quijote`.
|
||||
run : str
|
||||
Run name.
|
||||
kind : str
|
||||
Distribution kind. Either `pdf` or `cdf`.
|
||||
verbose : bool, optional
|
||||
Verbosity flag.
|
||||
out : 2-dimensional array of shape `(nbins_radial, nbins_neighbour)`
|
||||
Output array to write to. Results are added to this array.
|
||||
ndist : 2-dimensional array of shape `(nhalos, ncross_simulations)`
|
||||
Distance of each halo to its nearest neighbour from a cross
|
||||
simulation.
|
||||
rdist : 1-dimensional array of shape `(nhalos, )`
|
||||
Distance of each halo to the centre of the high-resolution region.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : 2-dimensional array of shape `(nbins_radial, nbins_neighbour)`
|
||||
"""
|
||||
return count_neighbour(out, ndist, rdist, self.radial_bin_edges,
|
||||
self.rmax_neighbour, self.nbins_neighbour)
|
||||
|
||||
def build_dist(self, counts, kind):
|
||||
"""
|
||||
Build the a PDF or a CDF for the nearest neighbour distribution from
|
||||
binned counts as a function of radial distance from the centre of the
|
||||
high-resolution region.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
counts : 2-dimensional array of shape `(nbins_radial, nbins_neighbour)`
|
||||
Binned counts of the number of neighbours as a function of
|
||||
radial distance.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dist : 2-dimensional array of shape `(nbins_radial, nbins_neighbour)`
|
||||
"""
|
||||
assert simname in ["csiborg", "quijote"]
|
||||
assert kind in ["pdf", "cdf"]
|
||||
rbin_edges = self.radial_bin_edges
|
||||
# We first bin the distances as a function of each reference halo
|
||||
# radial distance and then its nearest neighbour distance.
|
||||
fpaths = self.paths.cross_nearest(simname, run)
|
||||
if simname == "quijote":
|
||||
fpaths = fpaths
|
||||
out = numpy.zeros((self.nbins_radial, self.nbins_neighbour),
|
||||
dtype=numpy.float32)
|
||||
for fpath in tqdm(fpaths) if verbose else fpaths:
|
||||
data = numpy.load(fpath)
|
||||
out = count_neighbour(
|
||||
out, data["ndist"], data["rdist"], rbin_edges,
|
||||
self.rmax_neighbour, self.nbins_neighbour)
|
||||
|
||||
if kind == "pdf":
|
||||
neighbour_bin_edges = self.neighbour_bin_edges
|
||||
dx = neighbour_bin_edges[1] - neighbour_bin_edges[0]
|
||||
out /= numpy.sum(dx * out, axis=1).reshape(-1, 1)
|
||||
counts /= numpy.sum(dx * counts, axis=1).reshape(-1, 1)
|
||||
else:
|
||||
out = numpy.cumsum(out, axis=1, out=out)
|
||||
out /= out[:, -1].reshape(-1, 1)
|
||||
return out
|
||||
x = self.bin_centres("neighbour")
|
||||
counts = cumulative_trapezoid(counts, x, axis=1, initial=0)
|
||||
counts /= counts[:, -1].reshape(-1, 1)
|
||||
return counts
|
||||
|
||||
def kl_divergence(self, simname, run, nsim, pdf, nobs=None, verbose=True):
|
||||
r"""
|
||||
|
|
|
@ -410,7 +410,7 @@ class Paths:
|
|||
fname = f"halo_counts_{simname}_{str(nsim).zfill(5)}.npz"
|
||||
return join(fdir, fname)
|
||||
|
||||
def cross_nearest(self, simname, run, nsim=None, nobs=None):
|
||||
def cross_nearest(self, simname, run, kind, nsim=None, nobs=None):
|
||||
"""
|
||||
Path to the files containing distance from a halo in a reference
|
||||
simulation to the nearest halo from a cross simulation.
|
||||
|
@ -421,6 +421,9 @@ class Paths:
|
|||
Simulation name. Must be one of: `csiborg`, `quijote`.
|
||||
run : str
|
||||
Run name.
|
||||
kind : str
|
||||
Whether raw distances or counts in bins. Must be one of `dist`,
|
||||
`bin_dist` or `tot_counts`.
|
||||
nsim : int, optional
|
||||
IC realisation index.
|
||||
nobs : int, optional
|
||||
|
@ -431,6 +434,7 @@ class Paths:
|
|||
path : str
|
||||
"""
|
||||
assert simname in ["csiborg", "quijote"]
|
||||
assert kind in ["dist", "bin_dist", "tot_counts"]
|
||||
fdir = join(self.postdir, "nearest_neighbour")
|
||||
if not isdir(fdir):
|
||||
makedirs(fdir)
|
||||
|
@ -440,9 +444,9 @@ class Paths:
|
|||
nsim = str(nsim).zfill(5)
|
||||
else:
|
||||
nsim = self.quijote_fiducial_nsim(nsim, nobs)
|
||||
return join(fdir, f"{simname}_nn_{nsim}_{run}.npz")
|
||||
return join(fdir, f"{simname}_nn_{kind}_{nsim}_{run}.npz")
|
||||
|
||||
files = glob(join(fdir, f"{simname}_nn_*"))
|
||||
files = glob(join(fdir, f"{simname}_nn_{kind}_*"))
|
||||
run = "_" + run
|
||||
return [f for f in files if run in f]
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ class PKReader:
|
|||
Output precision. By default `numpy.float32`.
|
||||
"""
|
||||
def __init__(self, ics, hw, fskel=None, dtype=numpy.float32):
|
||||
self.ics= ics
|
||||
self.ics = ics
|
||||
self.hw = hw
|
||||
if fskel is None:
|
||||
fskel = "/mnt/extraspace/rstiskalek/csiborg/crosspk/out_{}_{}_{}.p"
|
||||
|
|
12419
notebooks/fits.ipynb
12419
notebooks/fits.ipynb
File diff suppressed because one or more lines are too long
12560
notebooks/matching.ipynb
12560
notebooks/matching.ipynb
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -19,12 +19,14 @@ MPI parallelized over the reference simulations.
|
|||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
from distutils.util import strtobool
|
||||
from os import remove
|
||||
|
||||
import numpy
|
||||
import yaml
|
||||
from mpi4py import MPI
|
||||
|
||||
from taskmaster import work_delegation
|
||||
from tqdm import trange
|
||||
|
||||
from utils import open_catalogues
|
||||
|
||||
try:
|
||||
|
@ -36,7 +38,7 @@ except ModuleNotFoundError:
|
|||
import csiborgtools
|
||||
|
||||
|
||||
def find_neighbour(args, nsim, cats, paths, comm):
|
||||
def find_neighbour(args, nsim, cats, paths, comm, save_kind):
|
||||
"""
|
||||
Find the nearest neighbour of each halo in the given catalogue.
|
||||
|
||||
|
@ -53,23 +55,78 @@ def find_neighbour(args, nsim, cats, paths, comm):
|
|||
Paths object.
|
||||
comm : mpi4py.MPI.Comm
|
||||
MPI communicator.
|
||||
save_kind : str
|
||||
Kind of data to save. Must be either `dist` or `bin_dist`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
assert save_kind in ["dist", "bin_dist"]
|
||||
ndist, cross_hindxs = csiborgtools.match.find_neighbour(nsim, cats)
|
||||
|
||||
mass_key = "totpartmass" if args.simname == "csiborg" else "group_mass"
|
||||
cat0 = cats[nsim]
|
||||
mass = cat0[mass_key]
|
||||
rdist = cat0.radial_distance(in_initial=False)
|
||||
|
||||
fout = paths.cross_nearest(args.simname, args.run, nsim)
|
||||
# Distance is saved optionally, whereas binned distance is always saved.
|
||||
if save_kind == "dist":
|
||||
out = {"ndist": ndist,
|
||||
"cross_hindxs": cross_hindxs,
|
||||
"mass": cat0[mass_key],
|
||||
"ref_hindxs": cat0["index"],
|
||||
"rdist": rdist}
|
||||
fout = paths.cross_nearest(args.simname, args.run, "dist", nsim)
|
||||
if args.verbose:
|
||||
print(f"Rank {comm.Get_rank()} writing to `{fout}`.", flush=True)
|
||||
numpy.savez(fout, **out)
|
||||
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
reader = csiborgtools.read.NearestNeighbourReader(
|
||||
paths=paths, **csiborgtools.neighbour_kwargs)
|
||||
counts = numpy.zeros((reader.nbins_radial, reader.nbins_neighbour),
|
||||
dtype=numpy.float32)
|
||||
counts = reader.count_neighbour(counts, ndist, rdist)
|
||||
out = {"counts": counts}
|
||||
fout = paths.cross_nearest(args.simname, args.run, "bin_dist", nsim)
|
||||
if args.verbose:
|
||||
print(f"Rank {comm.Get_rank()} writing to `{fout}`.", flush=True)
|
||||
numpy.savez(fout, ndist=ndist, cross_hindxs=cross_hindxs, mass=mass,
|
||||
ref_hindxs=cat0["index"], rdist=rdist)
|
||||
numpy.savez(fout, **out)
|
||||
|
||||
|
||||
def collect_dist(args, paths):
|
||||
"""
|
||||
Collect the binned nearest neighbour distances into a single file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
args : argparse.Namespace
|
||||
Command line arguments.
|
||||
paths : csiborgtools.paths.Paths
|
||||
Paths object.
|
||||
|
||||
Returns
|
||||
-------
|
||||
"""
|
||||
fnames = paths.cross_nearest(args.simname, args.run, "bin_dist")
|
||||
|
||||
if args.verbose:
|
||||
print("Collecting counts into a single file.", flush=True)
|
||||
|
||||
for i in trange(len(fnames)) if args.verbose else range(len(fnames)):
|
||||
fname = fnames[i]
|
||||
data = numpy.load(fname)
|
||||
if i == 0:
|
||||
out = data["counts"]
|
||||
else:
|
||||
out += data["counts"]
|
||||
|
||||
remove(fname)
|
||||
|
||||
fout = paths.cross_nearest(args.simname, args.run, "tot_counts",
|
||||
nsim=0, nobs=0)
|
||||
if args.verbose:
|
||||
print(f"Writing the summed counts to `{fout}`.", flush=True)
|
||||
numpy.savez(fout, tot_counts=out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -87,16 +144,23 @@ if __name__ == "__main__":
|
|||
with open("./match_finsnap.yml", "r") as file:
|
||||
config = yaml.safe_load(file)
|
||||
|
||||
if args.simname == "csiborg":
|
||||
save_kind = "dist"
|
||||
else:
|
||||
save_kind = "bin_dist"
|
||||
|
||||
comm = MPI.COMM_WORLD
|
||||
rank = comm.Get_rank()
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
cats = open_catalogues(args, config, paths, comm)
|
||||
|
||||
def do_work(nsim):
|
||||
return find_neighbour(args, nsim, cats, paths, comm)
|
||||
return find_neighbour(args, nsim, cats, paths, comm, save_kind)
|
||||
|
||||
work_delegation(do_work, list(cats.keys()), comm,
|
||||
master_verbose=args.verbose)
|
||||
|
||||
comm.Barrier()
|
||||
if comm.Get_rank() == 0:
|
||||
if rank == 0:
|
||||
collect_dist(args, paths)
|
||||
print(f"{datetime.now()}: all finished. Quitting.")
|
||||
|
|
|
@ -18,20 +18,77 @@ nbins_marks: 10
|
|||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 1.e+12
|
||||
max: 1.e+13
|
||||
min: 12.4
|
||||
max: 12.8
|
||||
islog: true
|
||||
|
||||
"mass002":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 1.e+13
|
||||
max: 1.e+14
|
||||
min: 12.6
|
||||
max: 13.0
|
||||
islog: true
|
||||
|
||||
"mass003":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 1.e+14
|
||||
min: 12.8
|
||||
max: 13.2
|
||||
islog: true
|
||||
|
||||
"mass004":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 13.0
|
||||
max: 13.4
|
||||
islog: true
|
||||
|
||||
"mass005":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 13.2
|
||||
max: 13.6
|
||||
islog: true
|
||||
|
||||
"mass006":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 13.4
|
||||
max: 13.8
|
||||
islog: true
|
||||
|
||||
"mass007":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 13.6
|
||||
max: 14.0
|
||||
islog: true
|
||||
|
||||
"mass008":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 13.8
|
||||
max: 14.2
|
||||
islog: true
|
||||
|
||||
"mass009":
|
||||
primary:
|
||||
name:
|
||||
- totpartmass
|
||||
- group_mass
|
||||
min: 14.0
|
||||
islog: true
|
|
@ -106,8 +106,12 @@ def read_single_catalogue(args, config, nsim, run, rmax, paths, nobs=None):
|
|||
pname = _name
|
||||
if pname is None:
|
||||
raise KeyError(f"Invalid names `{sel['name']}`.")
|
||||
|
||||
cat.apply_bounds({pname: (sel.get("min", None), sel.get("max", None))})
|
||||
xmin = sel.get("min", None)
|
||||
xmax = sel.get("max", None)
|
||||
if sel.get("islog", False):
|
||||
xmin = 10**xmin if xmin is not None else None
|
||||
xmax = 10**xmax if xmax is not None else None
|
||||
cat.apply_bounds({pname: (xmin, xmax)})
|
||||
|
||||
# Now the secondary selection bounds. If needed transfrom the secondary
|
||||
# property before applying the bounds.
|
||||
|
|
|
@ -21,7 +21,7 @@ import numpy
|
|||
import healpy
|
||||
|
||||
import scienceplots # noqa
|
||||
import utils
|
||||
import plt_utils
|
||||
from cache_to_disk import cache_to_disk, delete_disk_caches_for_function # noqa
|
||||
from tqdm import tqdm
|
||||
|
||||
|
@ -35,7 +35,16 @@ except ModuleNotFoundError:
|
|||
|
||||
def open_csiborg(nsim):
|
||||
"""
|
||||
Open a CSiBORG halo catalogue.
|
||||
Open a CSiBORG halo catalogue. Applies mass and distance selection.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
Simulation index.
|
||||
|
||||
Returns
|
||||
-------
|
||||
cat : csiborgtools.read.HaloCatalogue
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
bounds = {"totpartmass": (None, None), "dist": (0, 155/0.705)}
|
||||
|
@ -43,6 +52,20 @@ def open_csiborg(nsim):
|
|||
|
||||
|
||||
def open_quijote(nsim, nobs=None):
|
||||
"""
|
||||
Open a Quijote halo catalogue. Applies mass and distance selection.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
Simulation index.
|
||||
nobs : int, optional
|
||||
Fiducial observer index.
|
||||
|
||||
Returns
|
||||
-------
|
||||
cat : csiborgtools.read.QuijoteHaloCatalogue
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
cat = csiborgtools.read.QuijoteHaloCatalogue(nsim, paths, nsnap=4)
|
||||
if nobs is not None:
|
||||
|
@ -51,10 +74,24 @@ def open_quijote(nsim, nobs=None):
|
|||
|
||||
|
||||
def plot_mass_vs_ncells(nsim, pdf=False):
|
||||
"""
|
||||
Plot the halo mass vs. number of occupied cells in the initial snapshot.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
Simulation index.
|
||||
pdf : bool, optional
|
||||
Whether to save the figure as a PDF file.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
cat = open_csiborg(nsim)
|
||||
mpart = 4.38304044e+09
|
||||
|
||||
with plt.style.context(utils.mplstyle):
|
||||
with plt.style.context(plt_utils.mplstyle):
|
||||
plt.figure()
|
||||
plt.scatter(cat["totpartmass"], cat["lagpatch_ncells"], s=0.25,
|
||||
rasterized=True)
|
||||
|
@ -66,9 +103,9 @@ def plot_mass_vs_ncells(nsim, pdf=False):
|
|||
plt.ylabel(r"$N_{\rm cells}$")
|
||||
|
||||
for ext in ["png"] if pdf is False else ["png", "pdf"]:
|
||||
fout = join(utils.fout, f"init_mass_vs_ncells_{nsim}.{ext}")
|
||||
fout = join(plt_utils.fout, f"init_mass_vs_ncells_{nsim}.{ext}")
|
||||
print(f"Saving to `{fout}`.")
|
||||
plt.savefig(fout, dpi=utils.dpi, bbox_inches="tight")
|
||||
plt.savefig(fout, dpi=plt_utils.dpi, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
|
@ -77,13 +114,19 @@ def plot_mass_vs_ncells(nsim, pdf=False):
|
|||
###############################################################################
|
||||
|
||||
|
||||
def process_counts(counts):
|
||||
mean = numpy.mean(counts, axis=0)
|
||||
std = numpy.std(counts, axis=0)
|
||||
return mean, std
|
||||
|
||||
|
||||
def plot_hmf(pdf=False):
|
||||
"""
|
||||
Plot the (ultimate paretn) halo mass function of CSiBORG and Quijote.
|
||||
|
||||
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)
|
||||
|
||||
|
@ -114,35 +157,39 @@ def plot_hmf(pdf=False):
|
|||
x = 10**(0.5 * (bins[1:] + bins[:-1]))
|
||||
# Edit lower limits
|
||||
csiborg_counts[:, x < 1e12] = numpy.nan
|
||||
quijote_counts[:, x < 8e12] = numpy.nan
|
||||
quijote_counts[:, x < 10**(12.4)] = numpy.nan
|
||||
# Edit upper limits
|
||||
csiborg_counts[:, x > 4e15] = numpy.nan
|
||||
quijote_counts[:, x > 4e15] = numpy.nan
|
||||
|
||||
with plt.style.context(utils.mplstyle):
|
||||
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)
|
||||
|
||||
mean_csiborg, std_csiborg = process_counts(csiborg_counts)
|
||||
# Upper panel data
|
||||
mean_csiborg = numpy.mean(csiborg_counts, axis=0)
|
||||
std_csiborg = numpy.std(csiborg_counts, axis=0)
|
||||
ax[0].plot(x, mean_csiborg, label="CSiBORG")
|
||||
ax[0].fill_between(x, mean_csiborg - std_csiborg,
|
||||
mean_csiborg + std_csiborg, alpha=0.5)
|
||||
|
||||
mean_quijote, std_quijote = process_counts(quijote_counts)
|
||||
mean_quijote = numpy.mean(quijote_counts, axis=0)
|
||||
std_quijote = numpy.std(quijote_counts, axis=0)
|
||||
ax[0].plot(x, mean_quijote, label="Quijote")
|
||||
ax[0].fill_between(x, mean_quijote - std_quijote,
|
||||
mean_quijote + std_quijote, alpha=0.5)
|
||||
|
||||
# Lower panel data
|
||||
log_y = numpy.log10(mean_csiborg / mean_quijote)
|
||||
err = numpy.sqrt((std_csiborg / mean_csiborg / numpy.log(10))**2
|
||||
+ (std_quijote / mean_quijote / numpy.log(10))**2)
|
||||
|
||||
ax[1].plot(x, 10**log_y, c=cols[2])
|
||||
ax[1].fill_between(x, 10**(log_y - err), 10**(log_y + err), alpha=0.5,
|
||||
color=cols[2])
|
||||
|
||||
# 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} n}{\mathrm{d}\log M_{\rm h}}~\mathrm{dex}^{-1}$") # noqa
|
||||
|
@ -156,14 +203,33 @@ def plot_hmf(pdf=False):
|
|||
|
||||
fig.tight_layout(h_pad=0, w_pad=0)
|
||||
for ext in ["png"] if pdf is False else ["png", "pdf"]:
|
||||
fout = join(utils.fout, f"hmf_comparison.{ext}")
|
||||
fout = join(plt_utils.fout, f"hmf_comparison.{ext}")
|
||||
print(f"Saving to `{fout}`.")
|
||||
fig.savefig(fout, dpi=utils.dpi, bbox_inches="tight")
|
||||
fig.savefig(fout, dpi=plt_utils.dpi, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
@cache_to_disk(7)
|
||||
def load_field(kind, nsim, grid, MAS, in_rsp=False):
|
||||
"""
|
||||
Load a single field.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
kind : str
|
||||
Field kind.
|
||||
nsim : int
|
||||
Simulation index.
|
||||
grid : int
|
||||
Grid size.
|
||||
MAS : str
|
||||
Mass assignment scheme.
|
||||
in_rsp : bool, optional
|
||||
Whether to load the field in redshift space.
|
||||
|
||||
Returns
|
||||
-------
|
||||
field : n-dimensional array
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
return numpy.load(paths.field(kind, MAS, grid, nsim, in_rsp=in_rsp))
|
||||
|
||||
|
@ -175,6 +241,30 @@ def load_field(kind, nsim, grid, MAS, in_rsp=False):
|
|||
|
||||
def plot_projected_field(kind, nsim, grid, in_rsp, MAS="PCS",
|
||||
highres_only=True, pdf=False):
|
||||
"""
|
||||
Plot the mean projected field.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
kind : str
|
||||
Field kind.
|
||||
nsim : int
|
||||
Simulation index.
|
||||
grid : int
|
||||
Grid size.
|
||||
in_rsp : bool
|
||||
Whether to load the field in redshift space.
|
||||
MAS : str, optional
|
||||
Mass assignment scheme.
|
||||
highres_only : bool, optional
|
||||
Whether to only plot the high-resolution region.
|
||||
pdf : bool, optional
|
||||
Whether to save the figure as a PDF.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
print(f"Plotting projected field `{kind}`. ", flush=True)
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
|
@ -190,14 +280,12 @@ def plot_projected_field(kind, nsim, grid, in_rsp, MAS="PCS",
|
|||
if highres_only:
|
||||
csiborgtools.field.fill_outside(field, numpy.nan, rmax=155.5,
|
||||
boxsize=677.7)
|
||||
# start = field.shape[0] // 4
|
||||
start = round(field.shape[0] * 0.27)
|
||||
end = round(field.shape[0] * 0.73)
|
||||
# end = field.shape[0] - start
|
||||
field = field[start:end, start:end, start:end]
|
||||
|
||||
labels = [r"$y-z$", r"$x-z$", r"$x-y$"]
|
||||
with plt.style.context(utils.mplstyle):
|
||||
with plt.style.context(plt_utils.mplstyle):
|
||||
fig, ax = plt.subplots(figsize=(3.5 * 2, 2.625), ncols=3, sharey=True,
|
||||
sharex=True)
|
||||
fig.subplots_adjust(hspace=0, wspace=0)
|
||||
|
@ -216,9 +304,10 @@ def plot_projected_field(kind, nsim, grid, in_rsp, MAS="PCS",
|
|||
|
||||
fig.tight_layout(h_pad=0, w_pad=0)
|
||||
for ext in ["png"] if pdf is False else ["png", "pdf"]:
|
||||
fout = join(utils.fout, f"field_{kind}_{nsim}_rsp{in_rsp}.{ext}")
|
||||
fout = join(plt_utils.fout,
|
||||
f"field_{kind}_{nsim}_rsp{in_rsp}.{ext}")
|
||||
print(f"Saving to `{fout}`.")
|
||||
fig.savefig(fout, dpi=utils.dpi, bbox_inches="tight")
|
||||
fig.savefig(fout, dpi=plt_utils.dpi, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
###############################################################################
|
||||
|
@ -227,6 +316,20 @@ def plot_projected_field(kind, nsim, grid, in_rsp, MAS="PCS",
|
|||
|
||||
|
||||
def get_sky_label(kind, volume_weight):
|
||||
"""
|
||||
Get the sky label for a given field kind.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
kind : str
|
||||
Field kind.
|
||||
volume_weight : bool
|
||||
Whether to volume weight the field.
|
||||
|
||||
Returns
|
||||
-------
|
||||
label : str
|
||||
"""
|
||||
if volume_weight:
|
||||
if kind == "density":
|
||||
label = r"$\log \int_{0}^{R} r^2 \rho(r, \mathrm{RA}, \mathrm{dec}) \mathrm{d} r$" # noqa
|
||||
|
@ -255,8 +358,38 @@ def get_sky_label(kind, volume_weight):
|
|||
def plot_sky_distribution(kind, nsim, grid, nside, MAS="PCS", plot_groups=True,
|
||||
dmin=0, dmax=220, plot_halos=None,
|
||||
volume_weight=True, pdf=False):
|
||||
"""
|
||||
NOTE: add distance for groups.
|
||||
r"""
|
||||
Plot the sky distribution of a given field kind on the sky along with halos
|
||||
and selected observations.
|
||||
|
||||
TODO
|
||||
----
|
||||
- Add distance for groups.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
field : str
|
||||
Field kind.
|
||||
nsim : int
|
||||
Simulation index.
|
||||
grid : int
|
||||
Grid size.
|
||||
nside : int
|
||||
Healpix nside of the sky projection.
|
||||
MAS : str, optional
|
||||
Mass assignment scheme.
|
||||
plot_groups : bool, optional
|
||||
Whether to plot the 2M++ groups.
|
||||
dmin : float, optional
|
||||
Minimum projection distance in :math:`\mathrm{Mpc}/h`.
|
||||
dmax : float, optional
|
||||
Maximum projection distance in :math:`\mathrm{Mpc}/h`.
|
||||
plot_halos : list, optional
|
||||
Minimum halo mass to plot in :math:`M_\odot`.
|
||||
volume_weight : bool, optional
|
||||
Whether to volume weight the field.
|
||||
pdf : bool, optional
|
||||
Whether to save the figure as a pdf.
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
nsnap = max(paths.get_snapshots(nsim))
|
||||
|
@ -274,7 +407,7 @@ def plot_sky_distribution(kind, nsim, grid, nside, MAS="PCS", plot_groups=True,
|
|||
out = csiborgtools.field.make_sky(field, angpos=angpos, dist=dist, box=box,
|
||||
volume_weight=volume_weight)
|
||||
|
||||
with plt.style.context(utils.mplstyle):
|
||||
with plt.style.context(plt_utils.mplstyle):
|
||||
label = get_sky_label(kind, volume_weight)
|
||||
if kind in ["density", "overdensity"]:
|
||||
out = numpy.log10(out)
|
||||
|
@ -299,9 +432,9 @@ def plot_sky_distribution(kind, nsim, grid, nside, MAS="PCS", plot_groups=True,
|
|||
plt.legend(markerscale=10)
|
||||
|
||||
for ext in ["png"] if pdf is False else ["png", "pdf"]:
|
||||
fout = join(utils.fout, f"sky_{kind}_{nsim}_from_{dmin}_to_{dmax}_vol{volume_weight}.{ext}") # noqa
|
||||
fout = join(plt_utils.fout, f"sky_{kind}_{nsim}_from_{dmin}_to_{dmax}_vol{volume_weight}.{ext}") # noqa
|
||||
print(f"Saving to `{fout}`.")
|
||||
plt.savefig(fout, dpi=utils.dpi, bbox_inches="tight")
|
||||
plt.savefig(fout, dpi=plt_utils.dpi, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
|
@ -321,12 +454,19 @@ if __name__ == "__main__":
|
|||
print(f"Cleaning cache for function {func}.")
|
||||
delete_disk_caches_for_function(func)
|
||||
|
||||
# plot_mass_vs_occupancy(7444)
|
||||
# plot_mass_vs_normcells(7444 + 24 * 4, pdf=False)
|
||||
# plot_mass_vs_ncells(7444, pdf=True)
|
||||
# plot_hmf(pdf=True)
|
||||
# plot_sky_distribution("radvel", 7444, 256, nside=64,
|
||||
# plot_groups=False, dmin=50, dmax=100,
|
||||
# plot_halos=5e13, volume_weight=False)
|
||||
if False:
|
||||
plot_mass_vs_ncells(7444, pdf=False)
|
||||
|
||||
plot_projected_field("potential", 7444, 256, in_rsp=True)
|
||||
if False:
|
||||
plot_hmf(pdf=False)
|
||||
|
||||
if False:
|
||||
plot_sky_distribution("radvel", 7444, 256, nside=64,
|
||||
plot_groups=False, dmin=50, dmax=100,
|
||||
plot_halos=5e13, volume_weight=False)
|
||||
|
||||
if True:
|
||||
plot_projected_field("overdensity", 7444, 1024, in_rsp=True,
|
||||
highres_only=False)
|
||||
plot_projected_field("overdensity", 7444, 1024, in_rsp=False,
|
||||
highres_only=False)
|
||||
|
|
|
@ -19,7 +19,7 @@ import matplotlib.pyplot as plt
|
|||
import numpy
|
||||
|
||||
import scienceplots # noqa
|
||||
import utils
|
||||
import plt_utils
|
||||
|
||||
try:
|
||||
import csiborgtools
|
||||
|
@ -40,7 +40,7 @@ def plot_knn(runname):
|
|||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
reader = csiborgtools.read.kNNCDFReader(paths)
|
||||
|
||||
with plt.style.context(utils.mplstyle):
|
||||
with plt.style.context(plt_utils.mplstyle):
|
||||
plt.figure()
|
||||
|
||||
# Quijote kNN
|
||||
|
@ -92,9 +92,9 @@ def plot_knn(runname):
|
|||
plt.ylabel(r"$P(k | V = 4 \pi r^3 / 3)$")
|
||||
|
||||
for ext in ["png"]:
|
||||
fout = join(utils.fout, f"knn_{runname}.{ext}")
|
||||
fout = join(plt_utils.fout, f"knn_{runname}.{ext}")
|
||||
print("Saving to `{fout}`.".format(fout=fout))
|
||||
plt.savefig(fout, dpi=utils.dpi, bbox_inches="tight")
|
||||
plt.savefig(fout, dpi=plt_utils.dpi, bbox_inches="tight")
|
||||
plt.close()
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue