From 116464413c9696a33e86d45b6b10db4ef29e5ccf Mon Sep 17 00:00:00 2001 From: Maximilian Linhoff Date: Tue, 22 Aug 2023 17:26:10 +0200 Subject: [PATCH] Address review comments --- pyirf/interpolation/__init__.py | 2 ++ pyirf/interpolation/base_extrapolators.py | 9 +++++---- pyirf/interpolation/base_interpolators.py | 13 ------------- pyirf/interpolation/moment_morph_interpolator.py | 9 ++++++++- .../interpolation/nearest_simplex_extrapolator.py | 5 +++-- pyirf/interpolation/quantile_interpolator.py | 3 ++- pyirf/interpolation/tests/test_utils.py | 12 ++++++++++++ pyirf/interpolation/utils.py | 14 ++++++++++++++ 8 files changed, 46 insertions(+), 21 deletions(-) diff --git a/pyirf/interpolation/__init__.py b/pyirf/interpolation/__init__.py index 47d71cb84..2863650b5 100644 --- a/pyirf/interpolation/__init__.py +++ b/pyirf/interpolation/__init__.py @@ -11,6 +11,7 @@ BaseInterpolator, DiscretePDFInterpolator, ParametrizedInterpolator, + PDFNormalization, ) from .component_estimators import ( BaseComponentEstimator, @@ -39,6 +40,7 @@ "BaseInterpolator", "BaseNearestNeighborSearcher", "BaseExtrapolator", + "PDFNormalization", "DiscretePDFExtrapolator", "ParametrizedExtrapolator", "DiscretePDFComponentEstimator", diff --git a/pyirf/interpolation/base_extrapolators.py b/pyirf/interpolation/base_extrapolators.py index d848009c4..28b3b38a8 100644 --- a/pyirf/interpolation/base_extrapolators.py +++ b/pyirf/interpolation/base_extrapolators.py @@ -89,16 +89,17 @@ def __init__(self, grid_points, bin_edges, binned_pdf, normalization=PDFNormaliz Parameters ---------- - grid_points: np.ndarray, shape=(n_points, n_dims) + grid_points : np.ndarray, shape=(n_points, n_dims) Grid points at which templates exist - bin_edges: np.ndarray, shape=(n_bins+1) + bin_edges : np.ndarray, shape=(n_bins+1) Edges of the data binning - binned_pdf: np.ndarray, shape=(n_points, ..., n_bins) + binned_pdf : np.ndarray, shape=(n_points, ..., n_bins) Content of each bin in bin_edges for each point in grid_points. First dimesion has to correspond to number of grid_points, last dimension has to correspond to number of bins for the quantity that should be extrapolated (e.g. the Migra axis for EDisp) - + normalization : PDFNormalization + How the PDF is normalized Note ---- diff --git a/pyirf/interpolation/base_interpolators.py b/pyirf/interpolation/base_interpolators.py index 99ecb44af..9f47f0c31 100644 --- a/pyirf/interpolation/base_interpolators.py +++ b/pyirf/interpolation/base_interpolators.py @@ -1,19 +1,16 @@ """Base classes for interpolators""" from abc import ABCMeta, abstractmethod import enum -import astropy.units as u import numpy as np from ..binning import bin_center -from ..utils import cone_solid_angle __all__ = [ "BaseInterpolator", "ParametrizedInterpolator", "DiscretePDFInterpolator", "PDFNormalization", - "get_bin_width", ] @@ -27,16 +24,6 @@ class PDFNormalization(enum.Enum): CONE_SOLID_ANGLE = enum.auto() -def get_bin_width(bin_edges, normalization): - if normalization is PDFNormalization.AREA: - return np.diff(bin_edges) - - if normalization is PDFNormalization.CONE_SOLID_ANGLE: - return np.diff(cone_solid_angle(bin_edges).to_value(u.sr)) - - raise ValueError(f"Invalid PDF normalization: {normalization}") - - class BaseInterpolator(metaclass=ABCMeta): """ Base class for all interpolators, only knowing grid-points, diff --git a/pyirf/interpolation/moment_morph_interpolator.py b/pyirf/interpolation/moment_morph_interpolator.py index e3f8520fe..f561e050d 100644 --- a/pyirf/interpolation/moment_morph_interpolator.py +++ b/pyirf/interpolation/moment_morph_interpolator.py @@ -2,7 +2,8 @@ from pyirf.binning import bin_center, calculate_bin_indices from scipy.spatial import Delaunay -from .base_interpolators import DiscretePDFInterpolator, PDFNormalization, get_bin_width +from .base_interpolators import DiscretePDFInterpolator, PDFNormalization +from .utils import get_bin_width __all__ = [ "MomentMorphInterpolator", @@ -19,6 +20,8 @@ def _estimate_mean_std(bin_edges, binned_pdf, normalization): Array of common bin-edges for binned_pdf binned_pdf: np.ndarray, shape=(N, ..., M) PDF values from which to compute mean and std + normalization : PDFNormalization + How the PDF is normalized Returns ------- @@ -189,6 +192,8 @@ def moment_morph_estimation(bin_edges, binned_pdf, coefficients, normalization): Array of bin-entries, actual coefficients: np.ndarray, shape=(N) Estimation coefficients for each entry in binned_pdf + normalization : PDFNormalization + How the PDF is normalized Returns ------- @@ -273,6 +278,8 @@ def __init__( the quantity that should be interpolated (e.g. the Migra axis for EDisp) has to be at axis specified by axis-keyword as well as having entries corresponding to the number of bins given through bin_edges keyword. + normalization : PDFNormalization + How the PDF is normalized Note ---- diff --git a/pyirf/interpolation/nearest_simplex_extrapolator.py b/pyirf/interpolation/nearest_simplex_extrapolator.py index c108766db..3dc8c7aa8 100644 --- a/pyirf/interpolation/nearest_simplex_extrapolator.py +++ b/pyirf/interpolation/nearest_simplex_extrapolator.py @@ -7,7 +7,6 @@ import numpy as np from scipy.spatial import Delaunay -from pyirf.interpolation.base_interpolators import get_bin_width from .base_extrapolators import DiscretePDFExtrapolator, ParametrizedExtrapolator, PDFNormalization from .moment_morph_interpolator import ( @@ -15,7 +14,7 @@ linesegment_1D_interpolation_coefficients, moment_morph_estimation, ) -from .utils import find_nearest_simplex +from .utils import find_nearest_simplex, get_bin_width __all__ = [ "MomentMorphNearestSimplexExtrapolator", @@ -145,6 +144,8 @@ def __init__(self, grid_points, bin_edges, binned_pdf, normalization=PDFNormaliz the quantity that should be interpolated (e.g. the Migra axis for EDisp) has to be at the last axis as well as having entries corresponding to the number of bins given through bin_edges keyword. + normalization : PDFNormalization + How the PDF is normalized Note ---- diff --git a/pyirf/interpolation/quantile_interpolator.py b/pyirf/interpolation/quantile_interpolator.py index bdc6c6d42..890624191 100644 --- a/pyirf/interpolation/quantile_interpolator.py +++ b/pyirf/interpolation/quantile_interpolator.py @@ -1,7 +1,8 @@ import numpy as np from scipy.interpolate import griddata, interp1d -from .base_interpolators import DiscretePDFInterpolator, PDFNormalization, get_bin_width +from .base_interpolators import DiscretePDFInterpolator, PDFNormalization +from .utils import get_bin_width __all__ = ["QuantileInterpolator"] diff --git a/pyirf/interpolation/tests/test_utils.py b/pyirf/interpolation/tests/test_utils.py index 60fe5f7df..cba06d6cf 100644 --- a/pyirf/interpolation/tests/test_utils.py +++ b/pyirf/interpolation/tests/test_utils.py @@ -147,3 +147,15 @@ def test_find_nearest_simplex(non_rect_grid): assert find_nearest_simplex(non_rect_grid, np.array([-10, -10])) == 0 assert find_nearest_simplex(non_rect_grid, np.array([10, 30])) == 1 assert find_nearest_simplex(non_rect_grid, np.array([20.00000000001, -10])) == 2 + + +def test_get_bin_width(): + from pyirf.interpolation.utils import get_bin_width + from pyirf.interpolation import PDFNormalization + + bins = np.array([0, 1, 3]) + np.testing.assert_allclose(get_bin_width(bins, PDFNormalization.AREA), [1, 2]) + + bins = np.array([0, np.pi / 3, np.pi / 2]) + width = get_bin_width(bins, PDFNormalization.CONE_SOLID_ANGLE) + np.testing.assert_allclose(width, [np.pi, np.pi]) diff --git a/pyirf/interpolation/utils.py b/pyirf/interpolation/utils.py index aa54ad100..5936ec63a 100644 --- a/pyirf/interpolation/utils.py +++ b/pyirf/interpolation/utils.py @@ -1,5 +1,19 @@ +import astropy.units as u import numpy as np +from ..utils import cone_solid_angle +from .base_interpolators import PDFNormalization + + +def get_bin_width(bin_edges, normalization): + if normalization is PDFNormalization.AREA: + return np.diff(bin_edges) + + if normalization is PDFNormalization.CONE_SOLID_ANGLE: + return np.diff(cone_solid_angle(bin_edges).to_value(u.sr)) + + raise ValueError(f"Invalid PDF normalization: {normalization}") + def plumb_point_dist(line, target): """