mirror of
https://github.com/Richard-Sti/csiborgtools_public.git
synced 2025-05-13 14:11:11 +00:00
Overlap fixing and more (#107)
* Update README * Update density field reader * Update name of SDSSxALFAFA * Fix quick bug * Add little fixes * Update README * Put back fit_init * Add paths to initial snapshots * Add export * Remove some choices * Edit README * Add Jens' comments * Organize imports * Rename snapshot * Add additional print statement * Add paths to initial snapshots * Add masses to the initial files * Add normalization * Edit README * Update README * Fix bug in CSiBORG1 so that does not read fof_00001 * Edit README * Edit README * Overwrite comments * Add paths to init lag * Fix Quijote path * Add lagpatch * Edit submits * Update README * Fix numpy int problem * Update README * Add a flag to keep the snapshots open when fitting * Add a flag to keep snapshots open * Comment out some path issue * Keep snapshots open * Access directly snasphot * Add lagpatch for CSiBORG2 * Add treatment of x-z coordinates flipping * Add radial velocity field loader * Update README * Add lagpatch to Quijote * Fix typo * Add setter * Fix typo * Update README * Add output halo cat as ASCII * Add import * Add halo plot * Update README * Add evaluating field at radial distanfe * Add field shell evaluation * Add enclosed mass computation * Add BORG2 import * Add BORG boxsize * Add BORG paths * Edit run * Add BORG2 overdensity field * Add bulk flow clauclation * Update README * Add new plots * Add nbs * Edit paper * Update plotting * Fix overlap paths to contain simname * Add normalization of positions * Add default paths to CSiBORG1 * Add overlap path simname * Fix little things * Add CSiBORG2 catalogue * Update README * Add import * Add TNG density field constructor * Add TNG density * Add draft of calculating BORG ACL * Fix bug * Add ACL of enclosed density * Add nmean acl * Add galaxy bias calculation * Add BORG acl notebook * Add enclosed mass calculation * Add TNG300-1 dir * Add TNG300 and BORG1 dir * Update nb
This commit is contained in:
parent
0984191dc8
commit
9e4b34f579
30 changed files with 10037 additions and 248 deletions
|
@ -53,10 +53,10 @@ def density_field(nsim, parser_args):
|
|||
|
||||
# Read in the particle coordinates and masses
|
||||
if parser_args.simname == "csiborg1":
|
||||
snapshot = csiborgtools.read.CSIBORG1Snapshot(nsim, nsnap, paths)
|
||||
snapshot = csiborgtools.read.CSiBORG1Snapshot(nsim, nsnap, paths)
|
||||
elif "csiborg2" in parser_args.simname:
|
||||
kind = parser_args.simname.split("_")[-1]
|
||||
snapshot = csiborgtools.read.CSIBORG2Snapshot(nsim, nsnap, paths, kind)
|
||||
snapshot = csiborgtools.read.CSiBORG2Snapshot(nsim, nsnap, paths, kind)
|
||||
elif parser_args.simname == "quijote":
|
||||
snapshot = csiborgtools.read.QuijoteSnapshot(nsim, nsnap, paths)
|
||||
else:
|
||||
|
@ -106,10 +106,10 @@ def velocity_field(nsim, parser_args):
|
|||
nsnap = max(paths.get_snapshots(nsim, parser_args.simname))
|
||||
|
||||
if parser_args.simname == "csiborg1":
|
||||
snapshot = csiborgtools.read.CSIBORG1Snapshot(nsim, nsnap, paths)
|
||||
snapshot = csiborgtools.read.CSiBORG1Snapshot(nsim, nsnap, paths)
|
||||
elif "csiborg2" in parser_args.simname:
|
||||
kind = parser_args.simname.split("_")[-1]
|
||||
snapshot = csiborgtools.read.CSIBORG2Snapshot(nsim, nsnap, kind, paths)
|
||||
snapshot = csiborgtools.read.CSiBORG2Snapshot(nsim, nsnap, kind, paths)
|
||||
elif parser_args.simname == "quijote":
|
||||
snapshot = csiborgtools.read.QuijoteSnapshot(nsim, nsnap, paths)
|
||||
else:
|
||||
|
|
94
scripts/field_shells.py
Normal file
94
scripts/field_shells.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
|
||||
# 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.
|
||||
"""
|
||||
NOTE: This script is pretty dodgy.
|
||||
|
||||
A script to calculate the mean and standard deviation of a field at different
|
||||
distances from the center of the box such that at each distance the field is
|
||||
evaluated at uniformly-spaced points on a sphere.
|
||||
|
||||
The script is not parallelized in any way but it should not take very long, the
|
||||
main bottleneck is reading the data from disk.
|
||||
"""
|
||||
from argparse import ArgumentParser
|
||||
from os.path import join
|
||||
|
||||
import csiborgtools
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
def main(args):
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
boxsize = csiborgtools.simname2boxsize(args.simname)
|
||||
distances = numpy.linspace(0, boxsize / 2, 101)[1:]
|
||||
nsims = paths.get_ics(args.simname)
|
||||
folder = "/mnt/extraspace/rstiskalek/csiborg_postprocessing/field_shells"
|
||||
|
||||
mus = numpy.zeros((len(nsims), len(distances)))
|
||||
stds = numpy.zeros((len(nsims), len(distances)))
|
||||
for i, nsim in enumerate(tqdm(nsims, desc="Simulations")):
|
||||
# Get the correct field loader
|
||||
if args.simname == "csiborg1":
|
||||
reader = csiborgtools.read.CSiBORG1Field(nsim, paths)
|
||||
elif "csiborg2" in args.simname:
|
||||
kind = args.simname.split("_")[-1]
|
||||
reader = csiborgtools.read.CSiBORG2Field(nsim, kind, paths)
|
||||
elif args.simname == "borg2":
|
||||
reader = csiborgtools.read.BORG2Field(nsim, paths)
|
||||
else:
|
||||
raise ValueError(f"Unknown simname: `{args.simname}`.")
|
||||
|
||||
# Get the field
|
||||
if args.field == "density":
|
||||
field = reader.density_field(args.MAS, args.grid)
|
||||
elif args.field == "overdensity":
|
||||
if args.simname == "borg2":
|
||||
field = reader.overdensity_field()
|
||||
else:
|
||||
field = reader.density_field(args.MAS, args.grid)
|
||||
csiborgtools.field.overdensity_field(field, make_copy=False)
|
||||
elif args.field == "radvel":
|
||||
field = reader.radial_velocity_field(args.MAS, args.grid)
|
||||
else:
|
||||
raise ValueError(f"Unknown field: `{args.field}`.")
|
||||
|
||||
# Evaluate this field at different distances
|
||||
vals = [csiborgtools.field.field_at_distance(field, distance, boxsize)
|
||||
for distance in distances]
|
||||
|
||||
# Calculate the mean and standard deviation
|
||||
mus[i, :] = [numpy.mean(val) for val in vals]
|
||||
stds[i, :] = [numpy.std(val) for val in vals]
|
||||
|
||||
# Finally save the output
|
||||
fname = f"{args.simname}_{args.field}_{args.MAS}_{args.grid}.npz"
|
||||
fname = join(folder, fname)
|
||||
numpy.savez(fname, mean=mus, std=stds, distances=distances)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--field", type=str, help="Field type.",
|
||||
choices=["density", "overdensity", "radvel"])
|
||||
parser.add_argument("--simname", type=str, help="Simulation name.",
|
||||
choices=["csiborg1", "csiborg2_main", "csiborg2_varysmall", "csiborg2_random", "borg2"]) # noqa
|
||||
parser.add_argument("--MAS", type=str, help="Mass assignment scheme.",
|
||||
choices=["NGP", "CIC", "TSC", "PCS", "SPH"])
|
||||
parser.add_argument("--grid", type=int, help="Grid size.")
|
||||
args = parser.parse_args()
|
||||
|
||||
main(args)
|
128
scripts/fit_init.py
Normal file
128
scripts/fit_init.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
# 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.
|
||||
"""
|
||||
Script to calculate the particle centre of mass and Lagrangian patch size in
|
||||
the initial snapshot. The initial snapshot particles are read from the sorted
|
||||
files.
|
||||
"""
|
||||
from argparse import ArgumentParser
|
||||
from datetime import datetime
|
||||
|
||||
import csiborgtools
|
||||
import numpy
|
||||
from mpi4py import MPI
|
||||
from taskmaster import work_delegation
|
||||
from tqdm import tqdm
|
||||
|
||||
from utils import get_nsims
|
||||
|
||||
|
||||
def _main(nsim, simname, verbose):
|
||||
"""
|
||||
Calculate and save the Lagrangian halo centre of mass and Lagrangian patch
|
||||
size in the initial snapshot.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsim : int
|
||||
IC realisation index.
|
||||
simname : str
|
||||
Simulation name.
|
||||
verbose : bool
|
||||
Verbosity flag.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
cols = [("index", numpy.int32),
|
||||
("x", numpy.float32),
|
||||
("y", numpy.float32),
|
||||
("z", numpy.float32),
|
||||
("lagpatch_size", numpy.float32),
|
||||
("lagpatch_ncells", numpy.int32),]
|
||||
|
||||
if simname == "csiborg1":
|
||||
snap = csiborgtools.read.CSiBORG1Snapshot(nsim, 1, paths,
|
||||
keep_snapshot_open=True)
|
||||
cat = csiborgtools.read.CSiBORG1Catalogue(nsim, paths, snapshot=snap)
|
||||
fout = f"/mnt/extraspace/rstiskalek/csiborg1/chain_{nsim}/initial_lagpatch.npy" # noqa
|
||||
elif "csiborg2" in simname:
|
||||
kind = simname.split("_")[-1]
|
||||
snap = csiborgtools.read.CSiBORG2Snapshot(nsim, 0, kind, paths,
|
||||
keep_snapshot_open=True)
|
||||
cat = csiborgtools.read.CSiBORG2Catalogue(nsim, 99, kind, paths,
|
||||
snapshot=snap)
|
||||
fout = f"/mnt/extraspace/rstiskalek/csiborg2_{kind}/catalogues/initial_lagpatch_{nsim}.npy" # noqa
|
||||
elif simname == "quijote":
|
||||
snap = csiborgtools.read.QuijoteSnapshot(nsim, "ICs", paths,
|
||||
keep_snapshot_open=True)
|
||||
cat = csiborgtools.read.QuijoteHaloCatalogue(nsim, paths,
|
||||
snapshot=snap)
|
||||
fout = f"/mnt/extraspace/rstiskalek/quijote/fiducial_processed/chain_{nsim}/initial_lagpatch.npy" # noqa
|
||||
else:
|
||||
raise ValueError(f"Unknown simulation name `{simname}`.")
|
||||
|
||||
boxsize = csiborgtools.simname2boxsize(simname)
|
||||
|
||||
# Initialise the overlapper.
|
||||
if simname == "csiborg" or "csiborg2" in simname:
|
||||
kwargs = {"box_size": 2048, "bckg_halfsize": 512}
|
||||
else:
|
||||
kwargs = {"box_size": 512, "bckg_halfsize": 256}
|
||||
overlapper = csiborgtools.match.ParticleOverlap(**kwargs)
|
||||
|
||||
out = csiborgtools.read.cols_to_structured(len(cat), cols)
|
||||
for i, hid in enumerate(tqdm(cat["index"]) if verbose else cat["index"]):
|
||||
out["index"][i] = hid
|
||||
|
||||
pos = snap.halo_coordinates(hid)
|
||||
mass = snap.halo_masses(hid)
|
||||
|
||||
# Calculate the centre of mass and the Lagrangian patch size.
|
||||
cm = csiborgtools.center_of_mass(pos, mass, boxsize=boxsize)
|
||||
distances = csiborgtools.periodic_distance(pos, cm, boxsize=boxsize)
|
||||
out["x"][i], out["y"][i], out["z"][i] = cm
|
||||
out["lagpatch_size"][i] = numpy.percentile(distances, 99)
|
||||
|
||||
pos /= boxsize # need to normalize the positions to be [0, 1).
|
||||
# Calculate the number of cells with > 0 density.
|
||||
delta = overlapper.make_delta(pos, mass, subbox=True)
|
||||
out["lagpatch_ncells"][i] = csiborgtools.delta2ncells(delta)
|
||||
|
||||
# Now save it
|
||||
if verbose:
|
||||
print(f"{datetime.now()}: dumping fits to .. `{fout}`.", flush=True)
|
||||
with open(fout, "wb") as f:
|
||||
numpy.save(f, out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--simname", type=str,
|
||||
choices=["csiborg1", "csiborg2_main", "csiborg2_random", "csiborg2_varysmall", "quijote"], # noqa
|
||||
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)
|
376
scripts/mass_enclosed.py
Normal file
376
scripts/mass_enclosed.py
Normal file
|
@ -0,0 +1,376 @@
|
|||
# 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 calculate the enclosed mass or bulk flow at different distances
|
||||
from the center of the box directly from the particles. Note that the velocity
|
||||
of an observer is not being subtracted from the bulk flow.
|
||||
|
||||
The script is not parallelized in any way but it should not take very long, the
|
||||
main bottleneck is reading the data from disk.
|
||||
"""
|
||||
from argparse import ArgumentParser
|
||||
from os.path import join
|
||||
from gc import collect
|
||||
|
||||
import csiborgtools
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
from numba import jit
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Read in information about the simulation #
|
||||
###############################################################################
|
||||
|
||||
|
||||
def t():
|
||||
return datetime.now()
|
||||
|
||||
|
||||
def get_reader(simname, paths, nsim):
|
||||
"""
|
||||
Get the appropriate snaspshot reader for the simulation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
simname : str
|
||||
Name of the simulation.
|
||||
paths : csiborgtools.read.Paths
|
||||
Paths object.
|
||||
nsim : int
|
||||
Simulation index.
|
||||
|
||||
Returns
|
||||
-------
|
||||
reader : instance of csiborgtools.read.BaseSnapshot
|
||||
Snapshot reader.
|
||||
"""
|
||||
if simname == "csiborg1":
|
||||
nsnap = max(paths.get_snapshots(nsim, simname))
|
||||
reader = csiborgtools.read.CSiBORG1Snapshot(nsim, nsnap, paths,
|
||||
flip_xz=True)
|
||||
elif "csiborg2" in simname:
|
||||
kind = simname.split("_")[-1]
|
||||
reader = csiborgtools.read.CSiBORG2Snapshot(nsim, 99, kind, paths,
|
||||
flip_xz=True)
|
||||
else:
|
||||
raise ValueError(f"Unknown simname: `{simname}`.")
|
||||
|
||||
return reader
|
||||
|
||||
|
||||
def get_particles(reader, boxsize, get_velocity=True, verbose=True):
|
||||
"""
|
||||
Get the distance of particles from the center of the box and their masses.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
reader : instance of csiborgtools.read.BaseSnapshot
|
||||
Snapshot reader.
|
||||
boxsize : float
|
||||
Box size in Mpc / h.
|
||||
get_velocity : bool, optional
|
||||
Whether to also return the velocity of particles.
|
||||
verbose : bool
|
||||
Verbosity flag.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dist : 1-dimensional array
|
||||
Distance of particles from the center of the box.
|
||||
mass : 1-dimensional array
|
||||
Mass of particles.
|
||||
vel : 2-dimensional array, optional
|
||||
Velocity of particles.
|
||||
"""
|
||||
if verbose:
|
||||
print(f"{t()},: reading coordinates and calculating radial distance.")
|
||||
pos = reader.coordinates()
|
||||
dtype = pos.dtype
|
||||
pos -= boxsize / 2
|
||||
dist = numpy.linalg.norm(pos, axis=1).astype(dtype)
|
||||
del pos
|
||||
collect()
|
||||
|
||||
if verbose:
|
||||
print(f"{t()}: reading masses.")
|
||||
mass = reader.masses()
|
||||
|
||||
if get_velocity:
|
||||
if verbose:
|
||||
print(f"{t()}: reading velocities.")
|
||||
vel = reader.velocities().astype(dtype)
|
||||
|
||||
if verbose:
|
||||
print(f"{t()}: sorting arrays.")
|
||||
indxs = numpy.argsort(dist)
|
||||
dist = dist[indxs]
|
||||
mass = mass[indxs]
|
||||
if get_velocity:
|
||||
vel = vel[indxs]
|
||||
|
||||
del indxs
|
||||
collect()
|
||||
|
||||
if get_velocity:
|
||||
return dist, mass, vel
|
||||
|
||||
return dist, mass
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Calculate the enclosed mass at each distance #
|
||||
###############################################################################
|
||||
|
||||
|
||||
@jit(nopython=True, boundscheck=False)
|
||||
def _enclosed_mass(rdist, mass, rmax, start_index):
|
||||
enclosed_mass = 0.
|
||||
|
||||
for i in range(start_index, len(rdist)):
|
||||
if rdist[i] <= rmax:
|
||||
enclosed_mass += mass[i]
|
||||
else:
|
||||
break
|
||||
|
||||
return enclosed_mass, i
|
||||
|
||||
|
||||
def enclosed_mass(rdist, mass, distances):
|
||||
"""
|
||||
Calculate the enclosed mass at each distance.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rdist : 1-dimensional array
|
||||
Distance of particles from the center of the box.
|
||||
mass : 1-dimensional array
|
||||
Mass of particles.
|
||||
distances : 1-dimensional array
|
||||
Distances at which to calculate the enclosed mass.
|
||||
|
||||
Returns
|
||||
-------
|
||||
enclosed_mass : 1-dimensional array
|
||||
Enclosed mass at each distance.
|
||||
"""
|
||||
enclosed_mass = numpy.full_like(distances, 0.)
|
||||
start_index = 0
|
||||
for i, dist in enumerate(distances):
|
||||
if i > 0:
|
||||
enclosed_mass[i] += enclosed_mass[i - 1]
|
||||
|
||||
m, start_index = _enclosed_mass(rdist, mass, dist, start_index)
|
||||
enclosed_mass[i] += m
|
||||
|
||||
return enclosed_mass
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Calculate enclosed mass from a density field #
|
||||
###############################################################################
|
||||
|
||||
|
||||
@jit(nopython=True)
|
||||
def _cell_rdist(i, j, k, Ncells, boxsize):
|
||||
"""Radial distance of the center of a cell from the center of the box."""
|
||||
xi = boxsize / Ncells * (i + 0.5) - boxsize / 2
|
||||
yi = boxsize / Ncells * (j + 0.5) - boxsize / 2
|
||||
zi = boxsize / Ncells * (k + 0.5) - boxsize / 2
|
||||
|
||||
return (xi**2 + yi**2 + zi**2)**0.5
|
||||
|
||||
|
||||
@jit(nopython=True, boundscheck=False)
|
||||
def _field_enclosed_mass(field, rmax, boxsize):
|
||||
Ncells = field.shape[0]
|
||||
cell_volume = (1000 * boxsize / Ncells)**3
|
||||
|
||||
mass = 0.
|
||||
volume = 0.
|
||||
for i in range(Ncells):
|
||||
for j in range(Ncells):
|
||||
for k in range(Ncells):
|
||||
if _cell_rdist(i, j, k, Ncells, boxsize) < rmax:
|
||||
mass += field[i, j, k]
|
||||
volume += 1.
|
||||
|
||||
return mass * cell_volume, volume * cell_volume
|
||||
|
||||
|
||||
def field_enclosed_mass(field, distances, boxsize):
|
||||
"""
|
||||
Calculate the approximate enclosed mass within a given radius from a
|
||||
density field.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
field : 3-dimensional array
|
||||
Density field in units of `h^2 Msun / kpc^3`.
|
||||
rmax : 1-dimensional array
|
||||
Radii to calculate the enclosed mass at in `Mpc / h`.
|
||||
boxsize : float
|
||||
Box size in `Mpc / h`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
enclosed_mass : 1-dimensional array
|
||||
Enclosed mass at each distance.
|
||||
enclosed_volume : 1-dimensional array
|
||||
Enclosed grid-like volume at each distance.
|
||||
"""
|
||||
enclosed_mass = numpy.zeros_like(distances)
|
||||
enclosed_volume = numpy.zeros_like(distances)
|
||||
for i, dist in enumerate(distances):
|
||||
enclosed_mass[i], enclosed_volume[i] = _field_enclosed_mass(
|
||||
field, dist, boxsize)
|
||||
|
||||
return enclosed_mass, enclosed_volume
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Calculate the enclosed momentum at each distance #
|
||||
###############################################################################
|
||||
|
||||
|
||||
@jit(nopython=True, boundscheck=False)
|
||||
def _enclosed_momentum(rdist, mass, vel, rmax, start_index):
|
||||
bulk_momentum = numpy.zeros(3, dtype=rdist.dtype)
|
||||
|
||||
for i in range(start_index, len(rdist)):
|
||||
if rdist[i] <= rmax:
|
||||
bulk_momentum += mass[i] * vel[i]
|
||||
else:
|
||||
break
|
||||
|
||||
return bulk_momentum, i
|
||||
|
||||
|
||||
def enclosed_momentum(rdist, mass, vel, distances):
|
||||
"""
|
||||
Calculate the enclosed momentum at each distance.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rdist : 1-dimensional array
|
||||
Distance of particles from the center of the box.
|
||||
mass : 1-dimensional array
|
||||
Mass of particles.
|
||||
vel : 2-dimensional array
|
||||
Velocity of particles.
|
||||
distances : 1-dimensional array
|
||||
Distances at which to calculate the enclosed momentum.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bulk_momentum : 2-dimensional array
|
||||
Enclosed momentum at each distance.
|
||||
"""
|
||||
bulk_momentum = numpy.zeros((len(distances), 3))
|
||||
start_index = 0
|
||||
for i, dist in enumerate(distances):
|
||||
if i > 0:
|
||||
bulk_momentum[i] += bulk_momentum[i - 1]
|
||||
|
||||
v, start_index = _enclosed_momentum(rdist, mass, vel, dist,
|
||||
start_index)
|
||||
bulk_momentum[i] += v
|
||||
|
||||
return bulk_momentum
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Main & command line interface #
|
||||
###############################################################################
|
||||
|
||||
|
||||
def main_borg(args, folder):
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
boxsize = csiborgtools.simname2boxsize(args.simname)
|
||||
nsims = paths.get_ics(args.simname)
|
||||
distances = numpy.linspace(0, boxsize / 2, 101)[1:]
|
||||
|
||||
cumulative_mass = numpy.zeros((len(nsims), len(distances)))
|
||||
cumulative_volume = numpy.zeros((len(nsims), len(distances)))
|
||||
for i, nsim in enumerate(tqdm(nsims, desc="Simulations")):
|
||||
if args.simname == "borg1":
|
||||
reader = csiborgtools.read.BORG1Field(nsim)
|
||||
field = reader.density_field()
|
||||
elif args.simname == "borg2":
|
||||
reader = csiborgtools.read.BORG2Field(nsim)
|
||||
field = reader.density_field()
|
||||
else:
|
||||
raise ValueError(f"Unknown simname: `{args.simname}`.")
|
||||
|
||||
cumulative_mass[i, :], cumulative_volume[i, :] = field_enclosed_mass(
|
||||
field, distances, boxsize)
|
||||
|
||||
# Finally save the output
|
||||
fname = f"enclosed_mass_{args.simname}.npz"
|
||||
fname = join(folder, fname)
|
||||
numpy.savez(fname, enclosed_mass=cumulative_mass, distances=distances,
|
||||
enclosed_volume=cumulative_volume)
|
||||
|
||||
|
||||
def main_csiborg(args, folder):
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
boxsize = csiborgtools.simname2boxsize(args.simname)
|
||||
nsims = paths.get_ics(args.simname)
|
||||
distances = numpy.linspace(0, boxsize / 2, 101)[1:]
|
||||
|
||||
# Initialize arrays to store the results
|
||||
cumulative_mass = numpy.zeros((len(nsims), len(distances)))
|
||||
mass135 = numpy.zeros(len(nsims))
|
||||
masstot = numpy.zeros(len(nsims))
|
||||
cumulative_velocity = numpy.zeros((len(nsims), len(distances), 3))
|
||||
|
||||
for i, nsim in enumerate(tqdm(nsims, desc="Simulations")):
|
||||
reader = get_reader(args.simname, paths, nsim)
|
||||
rdist, mass, vel = get_particles(reader, boxsize, verbose=False)
|
||||
|
||||
# Calculate masses
|
||||
cumulative_mass[i, :] = enclosed_mass(rdist, mass, distances)
|
||||
mass135[i] = enclosed_mass(rdist, mass, [135])[0]
|
||||
masstot[i] = numpy.sum(mass)
|
||||
|
||||
# Calculate velocities
|
||||
cumulative_velocity[i, ...] = enclosed_momentum(
|
||||
rdist, mass, vel, distances)
|
||||
for j in range(3): # Normalize the momentum to get velocity out of it.
|
||||
cumulative_velocity[i, :, j] /= cumulative_mass[i, :]
|
||||
|
||||
# Finally save the output
|
||||
fname = f"enclosed_mass_{args.simname}.npz"
|
||||
fname = join(folder, fname)
|
||||
numpy.savez(fname, enclosed_mass=cumulative_mass, mass135=mass135,
|
||||
masstot=masstot, distances=distances,
|
||||
cumulative_velocity=cumulative_velocity)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("--simname", type=str, help="Simulation name.",
|
||||
choices=["csiborg1", "csiborg2_main", "csiborg2_varysmall", "csiborg2_random", "borg1", "borg2"]) # noqa
|
||||
args = parser.parse_args()
|
||||
|
||||
folder = "/mnt/extraspace/rstiskalek/csiborg_postprocessing/field_shells"
|
||||
if "csiborg" in args.simname:
|
||||
main_csiborg(args, folder)
|
||||
elif "borg" in args.simname:
|
||||
main_borg(args, folder)
|
||||
else:
|
||||
raise ValueError(f"Unknown simname: `{args.simname}`.")
|
|
@ -97,32 +97,54 @@ def pair_match(nsim0, nsimx, simname, min_logmass, sigma, verbose):
|
|||
"""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
smooth_kwargs = {"sigma": sigma, "mode": "constant", "cval": 0}
|
||||
bounds = {"lagpatch_size": (0, None)}
|
||||
bounds = {"lagpatch_radius": (0, None)}
|
||||
|
||||
if simname == "csiborg1":
|
||||
overlapper_kwargs = {"box_size": 2048, "bckg_halfsize": 512}
|
||||
bounds |= {"dist": (0, 150), "totmass": (10**min_logmass, None)}
|
||||
bounds |= {"dist": (0, 135), "totmass": (10**min_logmass, None)}
|
||||
|
||||
snap0 = csiborgtools.read.CSIBORG1Snapshot(nsim0, 0)
|
||||
cat0 = csiborgtools.read.CSiBORG1Catalogue(nsim0, snapshot=snap0,
|
||||
bounds=bounds)
|
||||
# Reference simulation.
|
||||
snap0 = csiborgtools.read.CSiBORG1Snapshot(
|
||||
nsim0, 1, keep_snapshot_open=True)
|
||||
cat0 = csiborgtools.read.CSiBORG1Catalogue(
|
||||
nsim0, snapshot=snap0, bounds=bounds)
|
||||
|
||||
snapx = csiborgtools.read.CSIBORG1Snapshot(nsimx, 0)
|
||||
catx = csiborgtools.read.CSiBORGCatalogue(nsimx, snapshot=snapx,
|
||||
bounds=bounds)
|
||||
# Cross simulation.
|
||||
snapx = csiborgtools.read.CSiBORG1Snapshot(
|
||||
nsimx, 1, keep_snapshot_open=True)
|
||||
catx = csiborgtools.read.CSiBORG1Catalogue(
|
||||
nsimx, snapshot=snapx, bounds=bounds)
|
||||
elif "csiborg2" in simname:
|
||||
raise RuntimeError("CSiBORG2 currently not implemented..")
|
||||
kind = simname.split("_")[-1]
|
||||
overlapper_kwargs = {"box_size": 2048, "bckg_halfsize": 512}
|
||||
bounds |= {"dist": (0, 135), "totmass": (10**min_logmass, None)}
|
||||
|
||||
# Reference simulation.
|
||||
snap0 = csiborgtools.read.CSiBORG2Snapshot(
|
||||
nsim0, 99, kind, keep_snapshot_open=True)
|
||||
cat0 = csiborgtools.read.CSiBORG2Catalogue(
|
||||
nsim0, 99, kind, snapshot=snap0, bounds=bounds)
|
||||
|
||||
# Cross simulation.
|
||||
snapx = csiborgtools.read.CSiBORG2Snapshot(
|
||||
nsimx, 99, kind, keep_snapshot_open=True)
|
||||
catx = csiborgtools.read.CSiBORG2Catalogue(
|
||||
nsimx, 99, kind, snapshot=snapx, bounds=bounds)
|
||||
elif simname == "quijote":
|
||||
overlapper_kwargs = {"box_size": 512, "bckg_halfsize": 256}
|
||||
bounds |= {"totmass": (10**min_logmass, None)}
|
||||
|
||||
snap0 = csiborgtools.read.QuijoteSnapshot(nsim0, "ICs")
|
||||
cat0 = csiborgtools.read.QuijoteCatalogue(nsim0, snapshot=snap0,
|
||||
bounds=bounds)
|
||||
# Reference simulation.
|
||||
snap0 = csiborgtools.read.QuijoteSnapshot(
|
||||
nsim0, "ICs", keep_snapshot_open=True)
|
||||
cat0 = csiborgtools.read.QuijoteCatalogue(
|
||||
nsim0, snapshot=snap0, bounds=bounds)
|
||||
|
||||
snapx = csiborgtools.read.QuijoteSnapshot(nsimx, "ICs")
|
||||
catx = csiborgtools.read.QuijoteCatalogue(nsimx, snapshot=snapx,
|
||||
bounds=bounds)
|
||||
# Cross simulation.
|
||||
snapx = csiborgtools.read.QuijoteSnapshot(
|
||||
nsimx, "ICs", keep_snapshot_open=True)
|
||||
catx = csiborgtools.read.QuijoteCatalogue(
|
||||
nsimx, snapshot=snapx, bounds=bounds)
|
||||
else:
|
||||
raise ValueError(f"Unknown simulation name: `{simname}`.")
|
||||
|
||||
|
|
76
scripts/output_halocatalogue.py
Normal file
76
scripts/output_halocatalogue.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Copyright (C) 2023 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.
|
||||
"""
|
||||
Quick script to output either halo positions and masses or positions of
|
||||
galaxies in a survey as an ASCII file.
|
||||
"""
|
||||
from os.path import join
|
||||
|
||||
import csiborgtools
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
|
||||
DIR_OUT = "/mnt/extraspace/rstiskalek/csiborg_postprocessing/ascii_positions"
|
||||
|
||||
|
||||
def process_simulation(simname):
|
||||
"""Watch out about the distinction between real and redshift space."""
|
||||
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
|
||||
if "csiborg2" in simname:
|
||||
nsims = paths.get_ics(simname)
|
||||
kind = simname.split("_")[-1]
|
||||
|
||||
for nsim in tqdm(nsims, desc="Looping over simulations"):
|
||||
cat = csiborgtools.read.CSiBORG2Catalogue(nsim, 99, kind, paths)
|
||||
pos = cat["cartesian_pos"]
|
||||
mass = cat["totmass"]
|
||||
# Stack positions and masses
|
||||
x = numpy.hstack([pos, mass.reshape(-1, 1)])
|
||||
|
||||
# Save to a file
|
||||
fname = join(DIR_OUT, f"halos_real_{simname}_{nsim}.txt")
|
||||
numpy.savetxt(fname, x)
|
||||
else:
|
||||
raise RuntimeError("Simulation not implemented..")
|
||||
|
||||
|
||||
def process_survey(survey_name, boxsize):
|
||||
"""Watch out about the distance definition."""
|
||||
if survey_name == "SDSS":
|
||||
survey = csiborgtools.SDSS()()
|
||||
dist, ra, dec = survey["DIST"], survey["RA"], survey["DEC"]
|
||||
elif survey_name == "SDSSxALFALFA":
|
||||
survey = csiborgtools.SDSSxALFALFA()()
|
||||
dist, ra, dec = survey["DIST"], survey["RA_1"], survey["DEC_1"]
|
||||
else:
|
||||
raise RuntimeError("Survey not implemented..")
|
||||
|
||||
# Convert to Cartesian coordinates
|
||||
X = numpy.vstack([dist, ra, dec]).T
|
||||
X = csiborgtools.radec_to_cartesian(X)
|
||||
|
||||
# Center the coordinates in the box
|
||||
X += boxsize / 2
|
||||
|
||||
fname = join(DIR_OUT, f"survey_{survey_name}.txt")
|
||||
numpy.savetxt(fname, X)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# process_simulation("csiborg2_main")
|
||||
|
||||
boxsize = 676.6
|
||||
for survey in ["SDSS", "SDSSxALFALFA"]:
|
||||
process_survey(survey, boxsize)
|
|
@ -68,7 +68,7 @@ def read_single_catalogue(args, config, nsim, run, rmax, paths, nobs=None):
|
|||
|
||||
Returns
|
||||
-------
|
||||
`csiborgtools.read.CSiBORGHaloCatalogue` or `csiborgtools.read.QuijoteHaloCatalogue` # noqa
|
||||
instance of `csiborgtools.read.BaseCatalogue`
|
||||
"""
|
||||
selection = config.get(run, None)
|
||||
if selection is None:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue