LSS projected basics (#140)

* Move files

* Move files

* Add galactic to RA/dec

* Update sky maps

* Add projected fields

* Remove old import

* Quick update

* Add IO

* Add imports

* Update imports

* Add basic file
This commit is contained in:
Richard Stiskalek 2024-08-14 13:02:38 +02:00 committed by GitHub
parent 3b46f17ead
commit d578c71b83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 365 additions and 231 deletions

View file

@ -0,0 +1,274 @@
# 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.
"""
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 datetime import datetime
from gc import collect
from os.path import join
import numpy as np
from astropy import units as u
from astropy.coordinates import CartesianRepresentation, SkyCoord
from tqdm import tqdm
import csiborgtools
from csiborgtools import fprint
from csiborgtools.field import (field_enclosed_mass, particles_enclosed_mass,
particles_enclosed_momentum)
###############################################################################
# Read in information about the simulation #
###############################################################################
def t():
return datetime.now()
def get_reader(simname, paths, nsim):
"""Get the appropriate snapshot reader for the simulation."""
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 snapshot particles."""
fprint("reading coordinates and calculating radial distance.", verbose)
pos = reader.coordinates()
dtype = pos.dtype
pos -= boxsize / 2
dist = np.linalg.norm(pos, axis=1).astype(dtype)
collect()
if get_velocity:
fprint("reading velocities.", verbose)
vel = reader.velocities().astype(dtype)
vrad = np.sum(pos, vel, axis=1) / dist
del pos
collect()
fprint("reading masses.")
mass = reader.masses()
fprint("sorting arrays.")
indxs = np.argsort(dist)
dist = dist[indxs]
mass = mass[indxs]
if get_velocity:
vel = vel[indxs]
del indxs
collect()
if get_velocity:
return dist, mass, vel, vrad
return dist, mass
###############################################################################
# Main #
###############################################################################
def main_borg(args, folder):
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
boxsize = csiborgtools.simname2boxsize(args.simname)
nsims = paths.get_ics(args.simname)
distances = np.linspace(0, boxsize / 2, 101)
cumulative_mass = np.zeros((len(nsims), len(distances)))
cumulative_volume = np.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" or args.simname == "borg2_all":
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)
np.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 = np.linspace(0, boxsize / 2, 501)[1:]
# Initialize arrays to store the results
cumulative_mass = np.zeros((len(nsims), len(distances)))
mass135 = np.zeros(len(nsims))
masstot = np.zeros(len(nsims))
cumulative_vel_mono = np.zeros((len(nsims), len(distances)))
cumulative_velocity = np.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, vrad = get_particles(reader, boxsize, verbose=True)
# Calculate masses
cumulative_mass[i, :] = particles_enclosed_mass(rdist, mass, distances)
mass135[i] = particles_enclosed_mass(rdist, mass, [135])[0]
masstot[i] = np.sum(mass)
# Calculate monopole momentum
cumulative_vel_mono[i] = particles_enclosed_mass(
rdist, vrad * mass, distances)
# Calculate velocities
cumulative_velocity[i, ...] = particles_enclosed_momentum(
rdist, mass, vel, distances)
# Normalize the momentum to get velocity out of it.
for j in range(3):
cumulative_velocity[i, :, j] /= cumulative_mass[i, :]
cumulative_vel_mono[i, ...] /= cumulative_mass[i, ...]
# Finally save the output
fname = f"enclosed_mass_{args.simname}.npz"
fname = join(folder, fname)
np.savez(fname, enclosed_mass=cumulative_mass, mass135=mass135,
masstot=masstot, distances=distances,
cumulative_velocity=cumulative_velocity,
cumulative_velocity_mono=cumulative_vel_mono)
def main_from_field(args, folder):
"""Bulk flows in 3D fields"""
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
boxsize = csiborgtools.simname2boxsize(args.simname)
nsims = paths.get_ics(args.simname)
distances = np.linspace(0, boxsize / 2, 101)[1:]
cumulative_mass = np.zeros((len(nsims), len(distances)))
cumulative_volume = np.zeros((len(nsims), len(distances)))
cumulative_vel_mono = np.zeros((len(nsims), len(distances)))
cumulative_vel_x = np.zeros((len(nsims), len(distances)))
cumulative_vel_y = np.zeros_like(cumulative_vel_x)
cumulative_vel_z = np.zeros_like(cumulative_vel_x)
for i, nsim in enumerate(tqdm(nsims, desc="Simulations")):
if args.simname == "csiborg2X":
reader = csiborgtools.read.CSiBORG2XField(nsim, paths)
elif args.simname == "Carrick2015":
reader = csiborgtools.read.Carrick2015Field(paths)
elif args.simname == "Lilow2024":
reader = csiborgtools.read.Lilow2024Field(paths)
else:
raise ValueError(f"Unknown simname: `{args.simname}`.")
density_field = reader.density_field()
cumulative_mass[i, :], cumulative_volume[i, :] = field_enclosed_mass(
density_field, distances, boxsize, verbose=False)
del density_field
collect()
velocity_field = reader.velocity_field()
radial_velocity_field = csiborgtools.field.radial_velocity(
velocity_field, [0., 0., 0.])
cumulative_vel_mono[i, :], __ = field_enclosed_mass(
radial_velocity_field, distances, boxsize, verbose=False)
del radial_velocity_field
collect()
cumulative_vel_x[i, :], __ = field_enclosed_mass(
velocity_field[0], distances, boxsize, verbose=False)
cumulative_vel_y[i, :], __ = field_enclosed_mass(
velocity_field[1], distances, boxsize, verbose=False)
cumulative_vel_z[i, :], __ = field_enclosed_mass(
velocity_field[2], distances, boxsize, verbose=False)
del velocity_field
collect()
if args.simname in ["Carrick2015", "Lilow2024"]:
# Carrick+2015 and Lilow+2024 box is in galactic coordinates, so we
# need to convert the bulk flow vector to RA/dec Cartesian
# representation.
galactic_cartesian = CartesianRepresentation(
cumulative_vel_x, cumulative_vel_y, cumulative_vel_z,
unit=u.km/u.s)
galactic_coord = SkyCoord(galactic_cartesian, frame='galactic')
icrs_cartesian = galactic_coord.icrs.cartesian
cumulative_vel_x = icrs_cartesian.x.to(u.km/u.s).value
cumulative_vel_y = icrs_cartesian.y.to(u.km/u.s).value
cumulative_vel_z = icrs_cartesian.z.to(u.km/u.s).value
cumulative_vel = np.stack(
[cumulative_vel_x, cumulative_vel_y, cumulative_vel_z], axis=-1)
cumulative_vel /= cumulative_volume[..., None]
cumulative_vel_mono /= cumulative_volume
# Finally save the output
fname = f"enclosed_mass_{args.simname}.npz"
fname = join(folder, fname)
print(f"Saving to `{fname}`.")
np.savez(fname, enclosed_mass=cumulative_mass, distances=distances,
cumulative_velocity_mono=cumulative_vel_mono,
cumulative_velocity=cumulative_vel,
enclosed_volume=cumulative_volume)
###############################################################################
# Command line interface #
###############################################################################
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--simname", type=str, help="Simulation name.",
choices=["csiborg1", "csiborg2_main", "csiborg2_varysmall", "csiborg2_random", # noqa
"borg1", "borg2", "borg2_all", "csiborg2X", "Carrick2015", # noqa
"Lilow2024"]) # noqa
args = parser.parse_args()
folder = "/mnt/extraspace/rstiskalek/csiborg_postprocessing/field_shells"
if args.simname in ["csiborg2X", "Carrick2015", "Lilow2024"]:
main_from_field(args, folder)
elif "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}`.")

View file

@ -0,0 +1,21 @@
nthreads=1
memory=48
on_login=0
queue="berg"
env="/mnt/zfsusers/rstiskalek/csiborgtools/venv_csiborg/bin/python"
file="field_bulk.py"
simname=${1}
pythoncm="$env $file --simname $simname"
if [ $on_login -eq 1 ]; then
echo $pythoncm
$pythoncm
else
cm="addqueue -q $queue -n $nthreads -m $memory $pythoncm"
echo "Submitting:"
echo $cm
echo
eval $cm
fi

View file

@ -0,0 +1,420 @@
# Copyright (C) 2024 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.
"""
MPI script to interpolate the density and velocity fields along the line of
sight.
"""
from argparse import ArgumentParser
from datetime import datetime
from gc import collect
from os import makedirs, remove, rmdir
from os.path import exists, join
from warnings import warn
import csiborgtools
import numpy as np
from astropy import units as u
from astropy.coordinates import SkyCoord
from astropy.io import fits
from h5py import File
from mpi4py import MPI
from numba import jit
from taskmaster import work_delegation # noqa
from utils import get_nsims
###############################################################################
# I/O functions #
###############################################################################
def get_los(catalogue_name, simname, comm):
"""
Get the line of sight RA/dec coordinates for the given catalogue.
Parameters
----------
catalogue_name : str
Catalogue name.
simname : str
Simulation name.
comm : mpi4py.MPI.Comm
MPI communicator.
Returns
-------
pos : 2-dimensional array
RA/dec coordinates of the line of sight.
"""
if comm.Get_rank() == 0:
folder = "/mnt/extraspace/rstiskalek/catalogs"
if catalogue_name in ["LOSS", "Foundation", "SFI_gals",
"SFI_gals_masked", "SFI_groups", "2MTF",
"Pantheon+"]:
fpath = join(folder, "PV_compilation.hdf5")
with File(fpath, 'r') as f:
grp = f[catalogue_name]
RA = grp["RA"][:]
dec = grp["DEC"][:]
elif catalogue_name == "A2":
fpath = join(folder, "A2.h5")
with File(fpath, 'r') as f:
RA = f["RA"][:]
dec = f["DEC"][:]
elif "CB2_" in catalogue_name:
kind = catalogue_name.split("_")[-1]
fname = f"/mnt/extraspace/rstiskalek/catalogs/PV_mock_CB2_17417_{kind}.hdf5" # noqa
with File(fname, 'r') as f:
RA = f["RA"][:]
dec = f["DEC"][:]
elif catalogue_name == "UPGLADE":
fname = "/mnt/users/rstiskalek/csiborgtools/data/upglade_all_z0p05_new_PROCESSED.h5" # noqa
with File(fname, 'r') as f:
RA = f["RA"][:]
dec = f["DEC"][:]
else:
raise ValueError(f"Unknown field name: `{catalogue_name}`.")
if comm.Get_rank() == 0:
print(f"The dataset contains {len(RA)} objects.")
if simname in ["Carrick2015", "Lilow2024"]:
# The Carrick+2015 and Lilow+2024 are in galactic coordinates, so
# we need to convert the RA/dec to galactic coordinates.
c = SkyCoord(ra=RA*u.degree, dec=dec*u.degree, frame='icrs')
pos = np.vstack((c.galactic.l, c.galactic.b)).T
elif "CF4" in simname:
# CF4 fields are in supergalactic coordinates.
c = SkyCoord(ra=RA*u.degree, dec=dec*u.degree, frame='icrs')
pos = np.vstack((c.supergalactic.sgl, c.supergalactic.sgb)).T
else:
pos = np.vstack((RA, dec)).T
else:
pos = None
return comm.bcast(pos, root=0)
def get_field(simname, nsim, kind, MAS, grid):
"""
Get the field from the simulation.
Parameters
----------
simname : str
Simulation name.
nsim : int
IC realisation index.
kind : str
Field kind. Either `density` or `velocity`.
MAS : str
Mass assignment scheme.
grid : int
Grid resolution.
Returns
-------
field : n-dimensional array
"""
# Open the field reader.
if simname == "csiborg1":
field_reader = csiborgtools.read.CSiBORG1Field(nsim)
elif "csiborg2_" in simname:
simkind = simname.split("_")[-1]
field_reader = csiborgtools.read.CSiBORG2Field(nsim, simkind)
elif simname == "csiborg2X":
field_reader = csiborgtools.read.CSiBORG2XField(nsim)
elif simname == "Carrick2015":
folder = "/mnt/extraspace/rstiskalek/catalogs"
warn(f"Using local paths from `{folder}`.", RuntimeWarning)
if kind == "density":
fpath = join(folder, "twompp_density_carrick2015.npy")
return np.load(fpath).astype(np.float32)
elif kind == "velocity":
fpath = join(folder, "twompp_velocity_carrick2015.npy")
field = np.load(fpath).astype(np.float32)
# Because the Carrick+2015 data is in the following form:
# "The velocities are predicted peculiar velocities in the CMB
# frame in Galactic Cartesian coordinates, generated from the
# \(\delta_g^*\) field with \(\beta^* = 0.43\) and an external
# dipole \(V_\mathrm{ext} = [89,-131,17]\) (Carrick et al Table 3)
# has already been added.""
field[0] -= 89
field[1] -= -131
field[2] -= 17
field /= 0.43
return field
else:
raise ValueError(f"Unknown field kind: `{kind}`.")
elif simname == "CF4":
folder = "/mnt/extraspace/rstiskalek/catalogs/CF4"
warn(f"Using local paths from `{folder}`.", RuntimeWarning)
if kind == "density":
fpath = join(folder, f"CF4_new_128-z008_realization{nsim}_delta.fits") # noqa
elif kind == "velocity":
fpath = join(folder, f"CF4_new_128-z008_realization{nsim}_velocity.fits") # noqa
else:
raise ValueError(f"Unknown field kind: `{kind}`.")
field = fits.open(fpath)[0].data
# https://projets.ip2i.in2p3.fr//cosmicflows/ says to multiply by 52
if kind == "velocity":
field *= 52
return field.astype(np.float32)
elif simname == "Lilow2024":
folder = "/mnt/extraspace/rstiskalek/catalogs"
warn(f"Using local paths from `{folder}`.", RuntimeWarning)
if kind == "density":
fpath = join(folder, "Lilow2024_density.npy")
field = np.load(fpath)
elif kind == "velocity":
field = []
for p in ["x", "y", "z"]:
fpath = join(folder, f"Lilow2024_{p}Velocity.npy")
field.append(np.load(fpath).astype(np.float32))
field = np.stack(field)
return field.astype(np.float32)
else:
raise ValueError(f"Unknown simulation name: `{simname}`.")
# Read in the field.
if kind == "density":
field = field_reader.density_field(MAS=MAS, grid=grid)
elif kind == "velocity":
field = field_reader.velocity_field(MAS=MAS, grid=grid)
else:
raise ValueError(f"Unknown field kind: `{kind}`.")
return field
def combine_from_simulations(catalogue_name, simname, nsims, outfolder,
dumpfolder):
"""
Combine the results from individual simulations into a single file.
Parameters
----------
catalogue_name : str
Catalogue name.
simname : str
Simulation name.
nsims : list
List of IC realisations.
outfolder : str
Output folder.
dumpfolder : str
Dumping folder where the temporary files are stored.
Returns
-------
None
"""
fname_out = join(outfolder, f"los_{catalogue_name}_{simname}.hdf5")
print(f"Combining results from invidivual simulations to `{fname_out}`.")
if exists(fname_out):
remove(fname_out)
for nsim in nsims:
fname = join(dumpfolder, f"los_{simname}_{nsim}.hdf5")
with File(fname, 'r') as f, File(fname_out, 'a') as f_out:
f_out.create_dataset(f"rdist_{nsim}", data=f["rdist"][:])
f_out.create_dataset(f"density_{nsim}", data=f["density"][:])
f_out.create_dataset(f"velocity_{nsim}", data=f["velocity"][:])
f_out.create_dataset(f"rmax_{nsim}", data=f["rmax"][:])
# Remove the temporary file.
remove(fname)
# Remove the dumping folder.
rmdir(dumpfolder)
print("Finished combining results.")
###############################################################################
# Main interpolating function #
###############################################################################
@jit(nopython=True)
def find_index_of_first_nan(y):
for n in range(1, len(y)):
if np.isnan(y[n]):
return n
return None
def replace_nan_with_last_finite(x, y, apply_decay):
n = find_index_of_first_nan(y)
if n is None:
return y, x[-1]
y[n:] = y[n-1]
rmax = x[n-1]
if apply_decay:
# Optionally aply 1 / r decay
y[n:] *= rmax / x[n:]
return y, rmax
def interpolate_field(pos, simname, nsim, MAS, grid, dump_folder, rmax,
dr, smooth_scales, verbose=False):
"""
Interpolate the density and velocity fields along the line of sight.
Parameters
----------
pos : 2-dimensional array
RA/dec coordinates of the line of sight.
simname : str
Simulation name.
nsim : int
IC realisation index.
MAS : str
Mass assignment scheme.
grid : int
Grid resolution.
dump_folder : str
Folder where the temporary files are stored.
rmax : float
Maximum distance along the line of sight.
dr : float
Distance spacing along the line of sight.
smooth_scales : list
Smoothing scales.
Returns
-------
None
"""
boxsize = csiborgtools.simname2boxsize(simname)
fname_out = join(dump_folder, f"los_{simname}_{nsim}.hdf5")
# First do the density field.
if verbose:
print(f"Interpolating density field for IC realisation `{nsim}`.",
flush=True)
density = get_field(simname, nsim, "density", MAS, grid)
rdist, finterp = csiborgtools.field.evaluate_los(
density, sky_pos=pos, boxsize=boxsize, rmax=rmax, dr=dr,
smooth_scales=smooth_scales, verbose=verbose,
interpolation_method="linear")
rmax_density = np.full((len(pos), len(smooth_scales)), np.nan)
for i in range(len(pos)):
for j in range(len(smooth_scales)):
y, current_rmax = replace_nan_with_last_finite(rdist, finterp[i, :, j], False) # noqa
finterp[i, :, j] = y
if current_rmax is not None:
rmax_density[i, j] = current_rmax
print(f"Writing temporary file `{fname_out}`.")
with File(fname_out, 'w') as f:
f.create_dataset("rdist", data=rdist)
f.create_dataset("density", data=finterp)
del density, rdist, finterp
collect()
if verbose:
print(f"Interpolating velocity field for IC realisation `{nsim}`.",
flush=True)
velocity = get_field(simname, nsim, "velocity", MAS, grid)
rdist, finterp = csiborgtools.field.evaluate_los(
velocity[0], velocity[1], velocity[2],
sky_pos=pos, boxsize=boxsize, rmax=rmax, dr=dr,
smooth_scales=smooth_scales, verbose=verbose,
interpolation_method="linear")
rmax_velocity = np.full((3, len(pos), len(smooth_scales)), np.nan)
for k in range(3):
for i in range(len(pos)):
for j in range(len(smooth_scales)):
y, current_rmax = replace_nan_with_last_finite(rdist, finterp[k][i, :, j], True) # noqa
finterp[k][i, :, j] = y
if current_rmax is not None:
rmax_velocity[k, i, j] = current_rmax
rmax_velocity = np.min(rmax_velocity, axis=0)
rmax = np.minimum(rmax_density, rmax_velocity)
with File(fname_out, 'a') as f:
f.create_dataset("velocity", data=finterp)
f.create_dataset("rmax", data=rmax)
###############################################################################
# Command line interface #
###############################################################################
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--catalogue", type=str, help="Catalogue name.")
parser.add_argument("--nsims", type=int, nargs="+", default=None,
help="IC realisations. `-1` for all simulations.")
parser.add_argument("--simname", type=str, help="Simulation name.")
parser.add_argument("--MAS", type=str,
choices=["NGP", "CIC", "TSC", "PCS", "SPH"],
help="Mass assignment scheme.")
parser.add_argument("--grid", type=int, help="Grid resolution.")
args = parser.parse_args()
rmax = 300
dr = 0.5
smooth_scales = [0]
comm = MPI.COMM_WORLD
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
nsims = get_nsims(args, paths)
out_folder = "/mnt/extraspace/rstiskalek/csiborg_postprocessing/field_los"
# Create the dumping folder.
if comm.Get_rank() == 0:
dump_folder = join(out_folder,
f"temp_{str(datetime.now())}".replace(" ", "_"))
print(f"Creating folder `{dump_folder}`.")
makedirs(dump_folder)
else:
dump_folder = None
dump_folder = comm.bcast(dump_folder, root=0)
# Get the line of sight sky coordinates.
pos = get_los(args.catalogue, args.simname, comm)
def main(nsim):
interpolate_field(pos, args.simname, nsim, args.MAS, args.grid,
dump_folder, rmax, dr, smooth_scales,
verbose=comm.Get_size() == 1)
work_delegation(main, nsims, comm, master_verbose=True)
comm.Barrier()
if comm.Get_rank() == 0:
combine_from_simulations(args.catalogue, args.simname, nsims,
out_folder, dump_folder)
print("All finished!")

29
scripts/field_prop/field_los.sh Executable file
View file

@ -0,0 +1,29 @@
nthreads=1
memory=64
on_login=1
queue="berg"
env="/mnt/users/rstiskalek/csiborgtools/venv_csiborg/bin/python"
file="field_los.py"
nsims="-1"
MAS="SPH"
grid=1024
for simname in "CF4"; do
for catalogue in "Foundation"; do
pythoncm="$env $file --catalogue $catalogue --nsims $nsims --simname $simname --MAS $MAS --grid $grid"
if [ $on_login -eq 1 ]; then
echo $pythoncm
$pythoncm
else
cm="addqueue -q $queue -n $nthreads -m $memory $pythoncm"
echo "Submitting:"
echo $cm
echo
eval $cm
fi
sleep 0.05
done
done

View file

@ -0,0 +1,127 @@
# 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.
"""
A script to calculate the projected density field for a given simulation as a
sky map. The script is not parallelized in any way. The generated fields are
converted to galactic coordinates to match the CMB maps.
"""
from argparse import ArgumentParser
from os import remove
from os.path import exists, join
import csiborgtools
import numpy as np
from h5py import File
def get_field(simname, nsim, field_kind, MAS, grid):
"""Get the appropriate field reader for the simulation."""
if simname == "csiborg1":
reader = csiborgtools.read.CSiBORG1Field(nsim)
elif "csiborg2" in simname:
kind = simname.split("_")[-1]
reader = csiborgtools.read.CSiBORG2Field(nsim, kind)
elif simname == "csiborg2X":
reader = csiborgtools.read.CSiBORG2XField(nsim)
elif "quijote" in simname:
reader = csiborgtools.read.QuijoteField(nsim)
else:
raise ValueError(f"Unknown simname: `{simname}`.")
if field_kind == "density":
return reader.density_field(MAS, grid)
else:
raise ValueError(f"Unknown field kind: `{field_kind}`.")
def main(simname, nsims, field_kind, nside, dist_ranges, MAS, grid,
volume_weight, folder, normalize_to_overdensity=True):
boxsize = csiborgtools.simname2boxsize(simname)
Om0 = csiborgtools.simname2Omega_m(simname)
matter_density = Om0 * 277.53662724583074 # Msun / kpc^3
fname = join(folder, f"{simname}_{field_kind}.hdf5")
if volume_weight:
fname = fname.replace(".hdf5", "_volume_weighted.hdf5")
print(f"Writing to `{fname}`...")
if exists(fname):
remove(fname)
with File(fname, "w") as f:
f.create_dataset("dist_ranges", data=np.asarray(dist_ranges))
f.create_dataset("nsims", data=nsims)
# These are at first generated in RA/dec but we can assume it is galactic
# and convert it to RA/dec.
pixel_angpos = csiborgtools.field.nside2radec(nside)
RA, dec = csiborgtools.galactic_to_radec(*pixel_angpos.T)
pixel_angpos = np.vstack([RA, dec]).T
npix = len(pixel_angpos)
Rmax = np.asanyarray(dist_ranges).reshape(-1).max()
dr = 0.5 * boxsize / grid
print(f"{'R_max:':<20} {Rmax} Mpc / h", flush=True)
print(f"{'dr:':<20} {dr} Mpc / h", flush=True)
for nsim in nsims:
print(f"Interpolating at {npix} pixel for simulation {nsim}...",
flush=True)
field = get_field(simname, nsim, field_kind, MAS, grid)
rdist, finterp = csiborgtools.field.make_sky(
field, pixel_angpos, Rmax, dr, boxsize, return_full=True,
interpolation_method="linear")
with File(fname, "a") as f:
grp = f.create_group(f"nsim_{nsim}")
for n in range(len(dist_ranges)):
dmin, dmax = dist_ranges[n]
k_start = np.searchsorted(rdist, dmin)
k_end = np.searchsorted(rdist, dmax)
r = rdist[k_start:k_end + 1]
y = r**2 * finterp[:, k_start:k_end + 1]
skymap = np.trapz(y, r, axis=-1) / np.trapz(r**2, r)
if normalize_to_overdensity:
skymap /= matter_density
skymap -= 1
grp.create_dataset(f"dist_range_{n}", data=skymap)
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--simname", type=str, help="Simulation name.")
args = parser.parse_args()
fdir = "/mnt/extraspace/rstiskalek/csiborg_postprocessing/field_projected"
dx = 25
dist_ranges = [[0, n * dx] for n in range(1, 5)]
dist_ranges += [[n * dx, (n + 1) * dx] for n in range(0, 5)]
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
nsims = paths.get_ics(args.simname)
print(f"{'Num. sims:':<20} {len(nsims)}", flush=True)
MAS = "SPH"
grid = 1024
nside = 128
field_kind = "density"
volume_weight = True
main(args.simname, nsims, field_kind, nside, dist_ranges, MAS, grid,
volume_weight, fdir)

View file

@ -0,0 +1,26 @@
nthreads=1
memory=64
on_login=${1}
simname=${2}
queue="berg"
env="/mnt/users/rstiskalek/csiborgtools/venv_csiborg/bin/python"
file="field_projected.py"
if [ "$on_login" != "1" ] && [ "$on_login" != "0" ]
then
echo "'on_login' (1) must be either 0 or 1."
exit 1
fi
pythoncm="$env $file --simname $simname"
if [ $on_login -eq 1 ]; then
echo $pythoncm
$pythoncm
else
cm="addqueue -q $queue -n $nthreads -m $memory $pythoncm"
echo "Submitting:"
echo $cm
echo
eval $cm
fi

View file

@ -0,0 +1,349 @@
# 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.
"""MPI script to calculate the various fields."""
from argparse import ArgumentParser
from datetime import datetime
import numpy
from mpi4py import MPI
from taskmaster import work_delegation
import csiborgtools
from utils import get_nsims
###############################################################################
# Density field #
###############################################################################
def density_field(nsim, parser_args):
"""
Calculate and save the density field from the particle positions and
masses.
Parameters
----------
nsim : int
Simulation index.
parser_args : argparse.Namespace
Command line arguments.
Returns
-------
density_field : 3-dimensional array
"""
if parser_args.MAS == "SPH":
raise NotImplementedError("SPH is not implemented here. Use cosmotool")
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
nsnap = max(paths.get_snapshots(nsim, parser_args.simname))
# Read in the particle coordinates and masses
if parser_args.simname == "csiborg1":
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)
elif parser_args.simname == "quijote":
snapshot = csiborgtools.read.QuijoteSnapshot(nsim, nsnap, paths)
else:
raise RuntimeError(f"Unknown simulation name `{parser_args.simname}`.")
pos = snapshot.coordinates()
mass = snapshot.masses()
# Run the field generator
boxsize = csiborgtools.simname2boxsize(parser_args.simname)
gen = csiborgtools.field.DensityField(boxsize, parser_args.MAS)
field = gen(pos, mass, parser_args.grid)
fout = paths.field("density", parser_args.MAS, parser_args.grid,
nsim, parser_args.simname)
print(f"{datetime.now()}: saving output to `{fout}`.")
numpy.save(fout, field)
return field
###############################################################################
# Velocity field #
###############################################################################
def velocity_field(nsim, parser_args):
"""
Calculate and save the velocity field from the particle positions,
velocities and masses.
Parameters
----------
nsim : int
Simulation index.
parser_args : argparse.Namespace
Command line arguments.
Returns
-------
velocity_field : 4-dimensional array
"""
if parser_args.MAS == "SPH":
raise NotImplementedError("SPH is not implemented here. Use cosmotool")
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
nsnap = max(paths.get_snapshots(nsim, parser_args.simname))
if parser_args.simname == "csiborg1":
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)
elif parser_args.simname == "quijote":
snapshot = csiborgtools.read.QuijoteSnapshot(nsim, nsnap, paths)
else:
raise RuntimeError(f"Unknown simulation name `{parser_args.simname}`.")
pos = snapshot.coordinates()
vel = snapshot.velocities()
mass = snapshot.masses()
boxsize = csiborgtools.simname2boxsize(parser_args.simname)
gen = csiborgtools.field.VelocityField(boxsize, parser_args.MAS)
field = gen(pos, vel, mass, parser_args.grid)
fout = paths.field("velocity", parser_args.MAS, parser_args.grid,
nsim, parser_args.simname)
print(f"{datetime.now()}: saving output to `{fout}`.")
numpy.save(fout, field)
return field
###############################################################################
# Radial velocity field #
###############################################################################
def radvel_field(nsim, parser_args):
"""
Calculate and save the radial velocity field.
Parameters
----------
nsim : int
Simulation index.
parser_args : argparse.Namespace
Command line arguments.
Returns
-------
radvel_field : 3-dimensional array
"""
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
if parser_args.simname == "csiborg1":
field = csiborgtools.read.CSiBORG1Field(nsim, paths)
elif "csiborg2" in parser_args.simname:
kind = parser_args.simname.split("_")[-1]
field = csiborgtools.read.CSiBORG2Field(nsim, kind, paths)
elif parser_args.simname == "quijote":
field = csiborgtools.read.QuijoteField(nsim, paths)
else:
raise RuntimeError(f"Unknown simulation name `{parser_args.simname}`.")
vel = field.velocity_field(parser_args.MAS, parser_args.grid)
observer_velocity = csiborgtools.field.observer_peculiar_velocity(vel)
radvel = csiborgtools.field.radial_velocity(vel, observer_velocity)
fout = paths.field("radvel", parser_args.MAS, parser_args.grid,
nsim, parser_args.simname)
print(f"{datetime.now()}: saving output to `{fout}`.")
numpy.save(fout, radvel)
return field
def observer_peculiar_velocity(nsim, parser_args):
"""
Calculate the peculiar velocity of an observer in the centre of the box
for several hard-coded smoothing scales.
Parameters
----------
nsim : int
Simulation index.
parser_args : argparse.Namespace
Command line arguments.
Returns
-------
observer_vp : 4-dimensional array
"""
boxsize = csiborgtools.simname2boxsize(parser_args.simname)
# NOTE these values are hard-coded.
smooth_scales = numpy.array([0., 2.0, 4.0, 8.0, 16.])
smooth_scales /= boxsize
if parser_args.simname == "csiborg1":
field = csiborgtools.read.CSiBORG1Field(nsim, paths)
elif "csiborg2" in parser_args.simname:
kind = parser_args.simname.split("_")[-1]
field = csiborgtools.read.CSiBORG2Field(nsim, paths, kind)
elif parser_args.simname == "quijote":
field = csiborgtools.read.QuijoteField(nsim, paths)
else:
raise RuntimeError(f"Unknown simulation name `{parser_args.simname}`.")
vel = field.velocity_field(parser_args.MAS, parser_args.grid)
observer_vp = csiborgtools.field.observer_peculiar_velocity(
vel, smooth_scales)
fout = paths.observer_peculiar_velocity(parser_args.MAS, parser_args.grid,
nsim, parser_args.simname)
print(f"Saving to ... `{fout}`")
numpy.savez(fout, smooth_scales=smooth_scales, observer_vp=observer_vp)
return observer_vp
###############################################################################
# Command line interface #
###############################################################################
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--nsims", type=int, nargs="+", default=None,
help="IC realisations. `-1` for all simulations.")
parser.add_argument("--simname", type=str, help="Simulation name.")
parser.add_argument("--kind", type=str,
choices=["density", "velocity", "radvel", "observer_vp"], # noqa
help="What derived field to calculate?")
parser.add_argument("--MAS", type=str,
choices=["NGP", "CIC", "TSC", "PCS", "SPH"],
help="Mass assignment scheme.")
parser.add_argument("--grid", type=int, help="Grid resolution.")
parser_args = parser.parse_args()
comm = MPI.COMM_WORLD
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
nsims = get_nsims(parser_args, paths)
def main(nsim):
if parser_args.kind == "density":
density_field(nsim, parser_args)
elif parser_args.kind == "velocity":
velocity_field(nsim, parser_args)
elif parser_args.kind == "radvel":
radvel_field(nsim, parser_args)
elif parser_args.kind == "observer_vp":
observer_peculiar_velocity(nsim, parser_args)
else:
raise RuntimeError(f"Field {parser_args.kind} is not implemented.")
work_delegation(main, nsims, comm, master_verbose=True)
# def potential_field(nsim, parser_args, to_save=True):
# """
# Calculate the potential field in the CSiBORG simulation.
# """
# paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
# nsnap = max(paths.get_snapshots(nsim, "csiborg"))
# box = csiborgtools.read.CSiBORG1Box(nsnap, nsim, paths)
#
# if not parser_args.in_rsp:
# rho = numpy.load(paths.field(
# "density", parser_args.MAS, parser_args.grid, nsim,
# in_rsp=False))
# density_gen = csiborgtools.field.DensityField(box, parser_args.MAS)
# rho = density_gen.overdensity_field(rho)
#
# gen = csiborgtools.field.PotentialField(box, parser_args.MAS)
# field = gen(rho)
# else:
# field = numpy.load(paths.field(
# "potential", parser_args.MAS, parser_args.grid, nsim, False))
# radvel_field = numpy.load(paths.field(
# "radvel", parser_args.MAS, parser_args.grid, nsim, False))
#
# field = csiborgtools.field.field2rsp(field, radvel_field, box,
# parser_args.MAS)
#
# if to_save:
# fout = paths.field(parser_args.kind, parser_args.MAS,
# parser_args.grid,
# nsim, parser_args.in_rsp)
# print(f"{datetime.now()}: saving output to `{fout}`.")
# numpy.save(fout, field)
# return field
#
#
# #############################################################################
# # Environment classification #
# #############################################################################
#
#
# def environment_field(nsim, parser_args, to_save=True):
# """
# Calculate the environmental classification in the CSiBORG simulation.
# """
# paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
# nsnap = max(paths.get_snapshots(nsim, "csiborg"))
# box = csiborgtools.read.CSiBORG1Box(nsnap, nsim, paths)
#
# rho = numpy.load(paths.field(
# "density", parser_args.MAS, parser_args.grid, nsim, in_rsp=False))
# density_gen = csiborgtools.field.DensityField(box, parser_args.MAS)
# rho = density_gen.overdensity_field(rho)
#
# if parser_args.smooth_scale > 0.0:
# rho = csiborgtools.field.smoothen_field(
# rho, parser_args.smooth_scale, box.box2mpc(1.))
#
# gen = csiborgtools.field.TidalTensorField(box, parser_args.MAS)
# field = gen(rho)
#
# del rho
# collect()
#
# if parser_args.in_rsp:
# radvel_field = numpy.load(paths.field(
# "radvel", parser_args.MAS, parser_args.grid, nsim, False))
# args = (radvel_field, box, parser_args.MAS)
#
# field.T00 = csiborgtools.field.field2rsp(field.T00, *args)
# field.T11 = csiborgtools.field.field2rsp(field.T11, *args)
# field.T22 = csiborgtools.field.field2rsp(field.T22, *args)
# field.T01 = csiborgtools.field.field2rsp(field.T01, *args)
# field.T02 = csiborgtools.field.field2rsp(field.T02, *args)
# field.T12 = csiborgtools.field.field2rsp(field.T12, *args)
#
# del radvel_field
# collect()
#
# eigvals = gen.tensor_field_eigvals(field)
#
# del field
# collect()
#
# env = gen.eigvals_to_environment(eigvals)
#
# if to_save:
# fout = paths.field("environment", parser_args.MAS, parser_args.grid,
# nsim, parser_args.in_rsp,
# parser_args.smooth_scale)
# print(f"{datetime.now()}: saving output to `{fout}`.")
# numpy.save(fout, env)
# return env

View file

@ -0,0 +1,24 @@
nthreads=10
memory=12
on_login=${1}
queue="berg"
env="/mnt/zfsusers/rstiskalek/csiborgtools/venv_csiborg/bin/python"
file="field_prop.py"
kind="velocity"
simname="quijote"
nsims="-1"
MAS="PCS"
grid=256
pythoncm="$env $file --nsims $nsims --simname $simname --kind $kind --MAS $MAS --grid $grid"
if [ $on_login -eq 1 ]; then
echo $pythoncm
$pythoncm
else
cm="addqueue -q $queue -n $nthreads -m $memory $pythoncm"
echo "Submitting:"
echo $cm
echo
eval $cm
fi

View file

@ -0,0 +1,327 @@
# 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.
"""
Script to sample a CSiBORG field at galaxy positions and save the result.
Supports additional smoothing of the field as well.
"""
from argparse import ArgumentParser
from os.path import join
import csiborgtools
import numpy
from astropy.cosmology import FlatLambdaCDM
from h5py import File
from mpi4py import MPI
from taskmaster import work_delegation
from tqdm import tqdm
from numba import jit
from utils import get_nsims
@jit(nopython=True, fastmath=True, boundscheck=False)
def scatter_along_radial_direction(pos, scatter, boxsize):
"""
Scatter galaxy positions along the radial direction. Enforces that the
radial position is always on the same side of the box and that the galaxy
is still inside the box.
Parameters
----------
pos : 2-dimensional array
Galaxy positions in the form of (distance, RA, DEC).
scatter : float
Scatter to add to the radial positions of galaxies in same units as
`distance` (Mpc / h).
boxsize : float
Box size in `Mpc / h`.
"""
pos_new = numpy.copy(pos)
for i in range(len(pos)):
r0, ra, dec = pos[i]
# Convert to radians
ra *= numpy.pi / 180
dec *= numpy.pi / 180
# Convert to normalized Cartesian coordinates
xnorm = numpy.cos(dec) * numpy.cos(ra)
ynorm = numpy.cos(dec) * numpy.sin(ra)
znorm = numpy.sin(dec)
while True:
rnew = numpy.random.normal(r0, scatter)
if rnew < 0:
continue
xnew = rnew * xnorm + boxsize / 2
ynew = rnew * ynorm + boxsize / 2
znew = rnew * znorm + boxsize / 2
if 0 <= xnew < boxsize and 0 <= ynew < boxsize and 0 <= znew < boxsize: # noqa
pos_new[i, 0] = rnew
break
return pos_new
def open_galaxy_positions(survey_name, comm, scatter=None):
"""
Load the survey's galaxy positions , broadcasting them to all ranks.
Parameters
----------
survey_name : str
Name of the survey.
comm : mpi4py.MPI.Comm
MPI communicator.
scatter : float
Scatter to add to the radial positions of galaxies, supportted only in
TNG300-1.
Returns
-------
pos : 2-dimensional array
Galaxy positions in the form of (distance, RA, DEC).
"""
rank, size = comm.Get_rank(), comm.Get_size()
if rank == 0:
if survey_name == "SDSS":
survey = csiborgtools.SDSS()()
pos = numpy.vstack([survey["DIST"],
survey["RA"],
survey["DEC"]],
).T
pos = pos.astype(numpy.float32)
elif survey_name == "SDSSxALFALFA":
survey = csiborgtools.SDSSxALFALFA()()
pos = numpy.vstack([survey["DIST"],
survey["RA_1"],
survey["DEC_1"]],
).T
pos = pos.astype(numpy.float32)
elif survey_name == "GW170817":
samples = File("/mnt/extraspace/rstiskalek/GWLSS/H1L1V1-EXTRACT_POSTERIOR_GW170817-1187008600-400.hdf", 'r')["samples"] # noqa
cosmo = FlatLambdaCDM(H0=100, Om0=0.3175)
pos = numpy.vstack([
cosmo.comoving_distance(samples["redshift"][:]).value,
samples["ra"][:] * 180 / numpy.pi,
samples["dec"][:] * 180 / numpy.pi],
).T
elif survey_name == "TNG300-1":
with File("/mnt/extraspace/rstiskalek/TNG300-1/postprocessing/subhalo_catalogue_099.hdf5", 'r') as f: # noqa
pos = numpy.vstack([f["SubhaloPos"][:, 0],
f["SubhaloPos"][:, 1],
f["SubhaloPos"][:, 2]],
).T
boxsize = csiborgtools.simname2boxsize("TNG300-1")
pos -= boxsize / 2
pos = csiborgtools.cartesian_to_radec(pos)
if scatter is not None:
if scatter < 0:
raise ValueError("Scatter must be positive.")
if scatter > 0:
pos = scatter_along_radial_direction(pos, scatter,
boxsize)
else:
raise NotImplementedError(f"Survey `{survey_name}` not "
"implemented.")
else:
pos = None
comm.Barrier()
if size > 1:
pos = comm.bcast(pos, root=0)
return pos
def evaluate_field(field, pos, boxsize, smooth_scales, verbose=True):
"""
Evaluate the field at the given galaxy positions.
Parameters
----------
field : 3-dimensional array
Cartesian field to be evaluated.
pos : 2-dimensional array
Galaxy positions in the form of (distance, RA, DEC).
boxsize : float
Box size in `Mpc / h`.
smooth_scales : list
List of smoothing scales in `Mpc / h`.
verbose : bool
Verbosity flag.
Returns
-------
val : 2-dimensional array
Evaluated field.
"""
mpc2box = 1. / boxsize
val = numpy.full((pos.shape[0], len(smooth_scales)), numpy.nan,
dtype=field.dtype)
for i, scale in enumerate(tqdm(smooth_scales, desc="Smoothing",
disable=not verbose)):
if scale > 0:
field_smoothed = csiborgtools.field.smoothen_field(
field, scale * mpc2box, boxsize=1, make_copy=True)
else:
field_smoothed = numpy.copy(field)
val[:, i] = csiborgtools.field.evaluate_sky(
field_smoothed, pos=pos, mpc2box=mpc2box)
return val
def match_to_no_selection(val, parser_args):
"""
Match the shape of the evaluated field to the shape of the survey without
any masking. Missing values are filled with `numpy.nan`.
Parameters
----------
val : n-dimensional array
Evaluated field.
parser_args : argparse.Namespace
Command line arguments.
Returns
-------
n-dimensional array
"""
if parser_args.survey == "SDSS":
survey = csiborgtools.SDSS()()
elif parser_args.survey == "SDSSxALFALFA":
survey = csiborgtools.SDSSxALFALFA()()
else:
raise NotImplementedError(
f"Survey `{parser_args.survey}` not implemented for matching to no selection.") # noqa
return csiborgtools.read.match_array_to_no_masking(val, survey)
def main(nsim, parser_args, pos, verbose):
"""
Main function to load the field, interpolate (and smooth it) it and save
the results to the disk.
Parameters
----------
nsim : int
IC realisation.
parser_args : argparse.Namespace
Command line arguments.
pos : numpy.ndarray
Galaxy coordinates in the form of (distance, RA, DEC) where to evaluate
the field.
verbose : bool
Verbosity flag.
Returns
-------
None
"""
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
boxsize = csiborgtools.simname2boxsize(parser_args.simname)
# Get the appropriate field loader
if parser_args.simname == "csiborg1":
freader = csiborgtools.read.CSiBORG1Field(nsim)
elif "csiborg2" in parser_args.simname:
kind = parser_args.simname.split("_")[-1]
freader = csiborgtools.read.CSiBORG2Field(nsim, kind)
elif parser_args.simname == "TNG300-1":
freader = csiborgtools.read.TNG300_1Field()
else:
raise NotImplementedError(f"Simulation `{parser_args.simname}` is not supported.") # noqa
# Get the appropriate field
if parser_args.kind == "density":
field = freader.density_field(parser_args.MAS, parser_args.grid)
else:
raise NotImplementedError(f"Field `{parser_args.kind}` is not supported.") # noqa
val = evaluate_field(field, pos, boxsize, parser_args.smooth_scales,
verbose=verbose)
if parser_args.survey == "GW170817":
fout = join(
"/mnt/extraspace/rstiskalek/GWLSS/",
f"{parser_args.kind}_{parser_args.MAS}_{parser_args.grid}_{nsim}_H1L1V1-EXTRACT_POSTERIOR_GW170817-1187008600-400.npz") # noqa
else:
if parser_args.simname == "TNG300-1":
scatter = parser_args.scatter
else:
scatter = None
fout = paths.field_interpolated(
parser_args.survey, parser_args.simname, nsim, parser_args.kind,
parser_args.MAS, parser_args.grid, scatter)
# The survey above had some cuts, however for compatibility we want
# the same shape as the `uncut` survey
if parser_args.survey != "TNG300-1":
val = match_to_no_selection(val, parser_args)
if verbose:
print(f"Saving to ... `{fout}`.")
numpy.savez(fout, val=val, smooth_scales=parser_args.smooth_scales)
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--nsims", type=int, nargs="+", default=None,
help="IC realisations. If `-1` processes all.")
parser.add_argument("--simname", type=str, default="csiborg1",
choices=["csiborg1", "csiborg2_main", "csiborg2_random", "csiborg2_varysmall", "TNG300-1"], # noqa
help="Simulation name")
parser.add_argument("--survey", type=str, required=True,
choices=["SDSS", "SDSSxALFALFA", "GW170817", "TNG300-1"], # noqa
help="Galaxy survey")
parser.add_argument("--smooth_scales", type=float, nargs="+", default=None,
help="Smoothing scales in Mpc / h.")
parser.add_argument("--kind", type=str,
choices=["density", "rspdensity", "velocity", "radvel",
"potential"],
help="What field to interpolate.")
parser.add_argument("--MAS", type=str,
choices=["NGP", "CIC", "TSC", "PCS", "SPH"],
help="Mass assignment scheme.")
parser.add_argument("--grid", type=int, help="Grid resolution.")
parser.add_argument("--scatter", type=float, default=None,
help="Scatter to add to the radial positions of galaxies, supportted only in TNG300-1.") # noqa
args = parser.parse_args()
if args.simname == "TNG300-1" and args.survey != "TNG300-1":
raise ValueError("TNG300-1 simulation is only supported for TNG300-1 survey.") # noqa
paths = csiborgtools.read.Paths(**csiborgtools.paths_glamdring)
if args.simname == "TNG300-1":
nsims = [0]
else:
nsims = get_nsims(args, paths)
pos = open_galaxy_positions(args.survey, MPI.COMM_WORLD, args.scatter)
def _main(nsim):
main(nsim, args, pos, verbose=MPI.COMM_WORLD.Get_size() == 1)
work_delegation(_main, nsims, MPI.COMM_WORLD)

View file

@ -0,0 +1,29 @@
nthreads=11
memory=64
on_login=${1}
queue="berg"
env="/mnt/zfsusers/rstiskalek/csiborgtools/venv_csiborg/bin/python"
file="field_sample.py"
nsims="-1"
simname="csiborg1"
survey="SDSS"
smooth_scales="0 2 4 8 16"
kind="density"
MAS="SPH"
grid=1024
scatter=0
pythoncm="$env $file --nsims $nsims --simname $simname --survey $survey --smooth_scales $smooth_scales --kind $kind --MAS $MAS --grid $grid --scatter $scatter"
if [ $on_login -eq 1 ]; then
echo $pythoncm
$pythoncm
else
cm="addqueue -q $queue -n $nthreads -m $memory $pythoncm"
echo "Submitting:"
echo $cm
echo
eval $cm
fi