From 97a851a3d5cfac2814d20014100ef01932e67cfc Mon Sep 17 00:00:00 2001 From: "Jack Y. Araz" Date: Wed, 29 Jan 2025 10:14:45 -0500 Subject: [PATCH] allow for negative poi in UL calculation --- src/spey/base/hypotest_base.py | 80 +++++++++++---------- src/spey/hypothesis_testing/upper_limits.py | 3 +- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/spey/base/hypotest_base.py b/src/spey/base/hypotest_base.py index 163f450..5fbac08 100644 --- a/src/spey/base/hypotest_base.py +++ b/src/spey/base/hypotest_base.py @@ -840,42 +840,38 @@ def poi_upper_limit( low_init: Optional[float] = 1.0, hig_init: Optional[float] = 1.0, expected_pvalue: Literal["nominal", "1sigma", "2sigma"] = "nominal", + allow_negative_signal: bool = False, maxiter: int = 10000, optimiser_arguments: Optional[Dict[str, Any]] = None, ) -> Union[float, List[float]]: r""" - Compute the upper limit for the parameter of interest i.e. :math:`\mu`. - - .. note:: - - This function uses ``"qtilde"`` test statistic which means signal values are always - assumed to be positive i.e. :math:`\hat\mu>0`. + Compute the upper limit for the parameter of interest (POI), denoted as :math:`\mu`. Args: - expected (~spey.ExpectationType): Sets which values the fitting algorithm should focus and - p-values to be computed. - - * :obj:`~spey.ExpectationType.observed`: Computes the p-values with via post-fit - prescriotion which means that the experimental data will be assumed to be the truth - (default). - * :obj:`~spey.ExpectationType.aposteriori`: Computes the expected p-values with via - post-fit prescriotion which means that the experimental data will be assumed to be - the truth. - * :obj:`~spey.ExpectationType.apriori`: Computes the expected p-values with via pre-fit - prescription which means that the SM will be assumed to be the truth. - - confidence_level (``float``, default ``0.95``): Determines the confidence level of the upper - limit i.e. the value of :math:`1-CL_s`. It needs to be between ``[0,1]``. - low_init (``Optional[float]``, default ``1.0``): Lower limit for the search algorithm to start - If ``None`` it the lower limit will be determined by :math:`\hat\mu + 1.5\sigma_{\hat\mu}`. + expected (:obj:`~spey.ExpectationType`, default :obj:`~spey.ExpectationType.observed`): + Specifies the type of expectation for the fitting algorithm and p-value computation. + + * :obj:`~spey.ExpectationType.observed`: Computes p-values using post-fit prescription, + assuming experimental data as the truth (default). + * :obj:`~spey.ExpectationType.aposteriori`: Computes expected p-values using post-fit + prescription, assuming experimental data as the truth. + * :obj:`~spey.ExpectationType.apriori`: Computes expected p-values using pre-fit + prescription, assuming the Standard Model (SM) as the truth. + + confidence_level (``float``, default ``0.95``): Confidence level for the upper limit, + representing :math:`1 - CL_s`. Must be between 0 and 1. Default is 0.95. + low_init (``Optional[float]``, default ``1.0``): Initial lower limit for the search + algorithm. If `None`, it is determined by :math:`\hat\mu + 1.5\sigma_{\hat\mu}`. + Default is 1.0. .. note:: :math:`\sigma_{\hat\mu}` is determined via :func:`~spey.base.hypotest_base.HypothesisTestingBase.sigma_mu` function. - hig_init (``Optional[float]``, default ``1.0``): Upper limit for the search algorithm to start - If ``None`` it the upper limit will be determined by :math:`\hat\mu + 2.5\sigma_{\hat\mu}`. + hig_init (``Optional[float]``, default ``1.0``): Initial upper limit for the search + algorithm. If `None`, it is determined by :math:`\hat\mu + 2.5\sigma_{\hat\mu}`. + Default is 1.0. .. note:: @@ -884,30 +880,36 @@ def poi_upper_limit( expected_pvalue (``Literal["nominal", "1sigma", "2sigma"]``, default ``"nominal"``): In case of :obj:`~spey.ExpectationType.aposteriori` and :obj:`~spey.ExpectationType.apriori` - expectation, gives the choice to find excluded upper limit for statistical deviations as well. + expectation, specifies the type of expected p-value for upper limit calculation. - * ``"nominal"``: only find the upper limit for the central p-value. Returns a single value. - * ``"1sigma"``: find the upper limit for central p-value and :math:`1\sigma` fluctuation from - background. Returns 3 values. - * ``"2sigma"``: find the upper limit for central p-value and :math:`1\sigma` and - :math:`2\sigma` fluctuation from background. Returns 5 values. + * ``"nominal"``: Computes the upper limit for the central p-value. Returns a single value. + * ``"1sigma"``: Computes the upper limit for the central p-value and :math:`1\sigma` + fluctuation from background. Returns 3 values. + * ``"2sigma"``: Computes the upper limit for the central p-value and :math:`1\sigma` + and :math:`2\sigma` fluctuation from background. Returns 5 values. .. note:: For ``expected=spey.ExpectationType.observed``, ``expected_pvalue`` argument will be overwritten to ``"nominal"``. - maxiter (``int``, default ``10000``): Maximum iteration limit for the optimiser. - optimiser_arguments (``Dict``, default ``None``): Arguments for optimiser that is used - to compute likelihood and its maximum. + allow_negative_signal (``bool``, default ``True``): Allows for negative signal values, + changing the computation of the test statistic. Default is False. + maxiter (``int``, default ``10000``): Maximum number of iterations for the optimiser. + Default is 10000. + optimiser_arguments (``Dict``, default ``None``): Additional arguments for the optimiser + used to compute the likelihood and its maximum. Default is None. Returns: ``Union[float, List[float]]``: - In case of nominal values it returns a single value for the upper limit. In case of - ``expected_pvalue="1sigma"`` or ``expected_pvalue="2sigma"`` it will return a list of - multiple upper limit values for fluctuations as well as the central value. The - output order is :math:`-2\sigma` value, :math:`-1\sigma` value, central value, - :math:`1\sigma` and :math:`2\sigma` value. + + - A single value representing the upper limit for the nominal case. + - A list of values representing the upper limits for the central value and statistical + deviations (for "1sigma" and "2sigma" cases). The order is: :math:`-2\sigma`, + :math:`-1\sigma`, central value, :math:`1\sigma`, :math:`2\sigma`. + + Raises: + AssertionError: If the confidence level is not between 0 and 1. """ assert ( 0.0 <= confidence_level <= 1.0 @@ -953,7 +955,7 @@ def poi_upper_limit( asimov_logpdf=logpdf_asimov, expected=expected, confidence_level=confidence_level, - allow_negative_signal=False, + allow_negative_signal=allow_negative_signal, low_init=low_init, hig_init=hig_init, expected_pvalue=expected_pvalue, diff --git a/src/spey/hypothesis_testing/upper_limits.py b/src/spey/hypothesis_testing/upper_limits.py index db8073d..dd3d751 100644 --- a/src/spey/hypothesis_testing/upper_limits.py +++ b/src/spey/hypothesis_testing/upper_limits.py @@ -142,7 +142,8 @@ def find_poi_upper_limit( confidence_level (``float``, default ``0.95``): Determines the confidence level of the upper limit i.e. the value of :math:`1-CL_s`. It needs to be between ``[0,1]``. - allow_negative_signal (``bool``, default ``True``): _description_ + allow_negative_signal (``bool``, default ``True``): allow for negative signal values. This will + change the computation of the test statistic. low_init (``float``, default ``None``): Lower limit for the search algorithm to start hig_init (``float``, default ``None``): Upper limit for the search algorithm to start expected_pvalue (``Text``, default ``"nominal"``): In case of :obj:`~spey.ExpectationType.aposteriori`