Source code for slsim.Util.ParamDistributions.kext_gext_distributions
import h5py
import numpy as np
import os
import warnings
[docs]
class LineOfSightDistribution:
"""Class to read the joint and no nonlinear distributions from the H5
files.
From the H5 files, the class can retrieve kappa and gamma values
from the H5 files based on the source and lens redshifts for the
resample of external convergence and shear.
"""
correction_data = None
no_nonlinear_correction_data = None
def __init__(self, nonlinear_correction_path=None, no_correction_path=None):
"""Initialize the Data Reader. Load data into class variables if not
already loaded.
:param nonlinear_correction_path: Path to the
'joint_distributions.h5' file.
:param no_correction_path: Path to the
'kg_distributions_nolos.h5' file.
"""
current_script_path = os.path.abspath(__file__)
current_directory = os.path.dirname(current_script_path)
parent_directory = os.path.dirname(current_directory)
parent_parent = os.path.dirname(os.path.dirname(parent_directory))
if nonlinear_correction_path is None:
file_path_joint = os.path.join(
parent_parent, "data/glass/joint_distributions.h5"
)
if os.path.exists(file_path_joint):
nonlinear_correction_path = file_path_joint
else:
nonlinear_correction_path = None
if no_correction_path is None:
file_path_no_nonlinear = os.path.join(
parent_parent, "data/glass/no_nonlinear_distributions.h5"
)
if os.path.exists(file_path_no_nonlinear):
no_correction_path = file_path_no_nonlinear
else:
no_correction_path = None
if (
LineOfSightDistribution.correction_data is None
and nonlinear_correction_path is not None
):
LineOfSightDistribution.correction_data = self._load_data(
nonlinear_correction_path
)
elif nonlinear_correction_path is None:
LineOfSightDistribution.correction_data = None
if (
LineOfSightDistribution.no_nonlinear_correction_data is None
and no_correction_path is not None
):
LineOfSightDistribution.no_nonlinear_correction_data = self._load_data(
no_correction_path
)
elif no_correction_path is None:
LineOfSightDistribution.no_nonlinear_correction_data = None
@staticmethod
def _load_data(file_path):
"""Load data from an H5 file into memory.
:param file_path: Path to the H5 file.
:return: Dictionary of datasets.
"""
data = {}
with h5py.File(file_path, "r") as h5_file:
for dataset_name in h5_file:
data[dataset_name] = h5_file[dataset_name][()]
return data
@staticmethod
def _round_to_nearest_0_1(value):
"""Round the value to the nearest 0.1.
:param value: A floating point number.
:return: Rounded number to the nearest 0.1.
"""
if value > 4.9:
return 4.9
if value < 0.1:
return 0.1
return round(value * 10) / 10
[docs]
def get_kappa_gamma(self, z_source, z_lens, use_nonlinear_correction=False):
"""Retrieve kappa and gamma values from the loaded data based on source
and lens redshifts.
:param z_source: Source redshift (zs).
:param z_lens: Lens redshift (zd).
:param use_nonlinear_correction: Boolean to use the nonlinear
correction data.
:return: Tuple of gamma and kappa values.
"""
if z_source <= z_lens:
return 0.0, 0.0
z_source_rounded = self._round_to_nearest_0_1(z_source)
z_lens_rounded = self._round_to_nearest_0_1(z_lens)
if z_lens_rounded == z_source_rounded:
z_lens_rounded = z_lens_rounded - 0.1
z_lens_rounded = round(z_lens_rounded, 1)
# todoļ¼ make z_lens_rounded == z_source_rounded worked in file
dataset_name = (
f"zs_{z_source_rounded}_zd_{z_lens_rounded}"
if (use_nonlinear_correction)
else f"zs_{z_source_rounded}"
)
data = (
LineOfSightDistribution.correction_data
if use_nonlinear_correction
else LineOfSightDistribution.no_nonlinear_correction_data
)
if data is None:
warnings.warn("No file found, provide 0 instead.")
return 0.0, 0.0
if dataset_name in data:
gamma = np.random.choice(data[dataset_name][:, 1])
kappa = np.random.choice(data[dataset_name][:, 0])
return gamma, kappa
else:
raise ValueError(
f"No data found for zs={z_source_rounded} and zd={z_lens_rounded}."
)