prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  pass calculator options through `pyhf.infer.upperlimit` (toys)
  # Description
  
  Currently there's no easy way to pass custom options to upperlimit so it'll always acll asymptotics
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/pyhf/infer/intervals.py`
  Content:
  ```
  1 """Interval estimation"""
  2 from pyhf.infer import hypotest
  3 from pyhf import get_backend
  4 import numpy as np
  5 
  6 __all__ = ["upperlimit"]
  7 
  8 
  9 def __dir__():
  10     return __all__
  11 
  12 
  13 def _interp(x, xp, fp):
  14     tb, _ = get_backend()
  15     return tb.astensor(np.interp(x, xp.tolist(), fp.tolist()))
  16 
  17 
  18 def upperlimit(data, model, scan, level=0.05, return_results=False):
  19     """
  20     Calculate an upper limit interval ``(0, poi_up)`` for a single
  21     Parameter of Interest (POI) using a fixed scan through POI-space.
  22 
  23     Example:
  24         >>> import numpy as np
  25         >>> import pyhf
  26         >>> pyhf.set_backend("numpy")
  27         >>> model = pyhf.simplemodels.uncorrelated_background(
  28         ...     signal=[12.0, 11.0], bkg=[50.0, 52.0], bkg_uncertainty=[3.0, 7.0]
  29         ... )
  30         >>> observations = [51, 48]
  31         >>> data = pyhf.tensorlib.astensor(observations + model.config.auxdata)
  32         >>> scan = np.linspace(0, 5, 21)
  33         >>> obs_limit, exp_limits, (scan, results) = pyhf.infer.intervals.upperlimit(
  34         ...     data, model, scan, return_results=True
  35         ... )
  36         >>> obs_limit
  37         array(1.01764089)
  38         >>> exp_limits
  39         [array(0.59576921), array(0.76169166), array(1.08504773), array(1.50170482), array(2.06654952)]
  40 
  41     Args:
  42         data (:obj:`tensor`): The observed data.
  43         model (~pyhf.pdf.Model): The statistical model adhering to the schema ``model.json``.
  44         scan (:obj:`iterable`): Iterable of POI values.
  45         level (:obj:`float`): The threshold value to evaluate the interpolated results at.
  46         return_results (:obj:`bool`): Whether to return the per-point results.
  47 
  48     Returns:
  49         Tuple of Tensors:
  50 
  51             - Tensor: The observed upper limit on the POI.
  52             - Tensor: The expected upper limits on the POI.
  53             - Tuple of Tensors: The given ``scan`` along with the
  54               :class:`~pyhf.infer.hypotest` results at each test POI.
  55               Only returned when ``return_results`` is ``True``.
  56     """
  57     tb, _ = get_backend()
  58     results = [
  59         hypotest(mu, data, model, test_stat="qtilde", return_expected_set=True)
  60         for mu in scan
  61     ]
  62     obs = tb.astensor([[r[0]] for r in results])
  63     exp = tb.astensor([[r[1][idx] for idx in range(5)] for r in results])
  64 
  65     result_arrary = tb.concatenate([obs, exp], axis=1).T
  66 
  67     # observed limit and the (0, +-1, +-2)sigma expected limits
  68     limits = [_interp(level, result_arrary[idx][::-1], scan[::-1]) for idx in range(6)]
  69     obs_limit, exp_limits = limits[0], limits[1:]
  70 
  71     if return_results:
  72         return obs_limit, exp_limits, (scan, results)
  73     return obs_limit, exp_limits
  74
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/pyhf/infer/intervals.py b/src/pyhf/infer/intervals.py
  --- a/src/pyhf/infer/intervals.py
  +++ b/src/pyhf/infer/intervals.py
  @@ -15,7 +15,7 @@
       return tb.astensor(np.interp(x, xp.tolist(), fp.tolist()))
   
   
  -def upperlimit(data, model, scan, level=0.05, return_results=False):
  +def upperlimit(data, model, scan, level=0.05, return_results=False, **hypotest_kwargs):
       """
       Calculate an upper limit interval ``(0, poi_up)`` for a single
       Parameter of Interest (POI) using a fixed scan through POI-space.
  @@ -44,6 +44,8 @@
           scan (:obj:`iterable`): Iterable of POI values.
           level (:obj:`float`): The threshold value to evaluate the interpolated results at.
           return_results (:obj:`bool`): Whether to return the per-point results.
  +        hypotest_kwargs (:obj:`string`): Kwargs for the calls to
  +         :class:`~pyhf.infer.hypotest` to configure the fits.
   
       Returns:
           Tuple of Tensors:
  @@ -56,7 +58,7 @@
       """
       tb, _ = get_backend()
       results = [
  -        hypotest(mu, data, model, test_stat="qtilde", return_expected_set=True)
  +        hypotest(mu, data, model, return_expected_set=True, **hypotest_kwargs)
           for mu in scan
       ]
       obs = tb.astensor([[r[0]] for r in results])
  
verification_info: {"golden_diff": "diff --git a/src/pyhf/infer/intervals.py b/src/pyhf/infer/intervals.py\n--- a/src/pyhf/infer/intervals.py\n+++ b/src/pyhf/infer/intervals.py\n@@ -15,7 +15,7 @@\n     return tb.astensor(np.interp(x, xp.tolist(), fp.tolist()))\n \n \n-def upperlimit(data, model, scan, level=0.05, return_results=False):\n+def upperlimit(data, model, scan, level=0.05, return_results=False, **hypotest_kwargs):\n     \"\"\"\n     Calculate an upper limit interval ``(0, poi_up)`` for a single\n     Parameter of Interest (POI) using a fixed scan through POI-space.\n@@ -44,6 +44,8 @@\n         scan (:obj:`iterable`): Iterable of POI values.\n         level (:obj:`float`): The threshold value to evaluate the interpolated results at.\n         return_results (:obj:`bool`): Whether to return the per-point results.\n+        hypotest_kwargs (:obj:`string`): Kwargs for the calls to\n+         :class:`~pyhf.infer.hypotest` to configure the fits.\n \n     Returns:\n         Tuple of Tensors:\n@@ -56,7 +58,7 @@\n     \"\"\"\n     tb, _ = get_backend()\n     results = [\n-        hypotest(mu, data, model, test_stat=\"qtilde\", return_expected_set=True)\n+        hypotest(mu, data, model, return_expected_set=True, **hypotest_kwargs)\n         for mu in scan\n     ]\n     obs = tb.astensor([[r[0]] for r in results])\n", "issue": "pass calculator options through `pyhf.infer.upperlimit` (toys)\n# Description\r\n\r\nCurrently there's no easy way to pass custom options to upperlimit so it'll always acll asymptotics\n", "before_files": [{"content": "\"\"\"Interval estimation\"\"\"\nfrom pyhf.infer import hypotest\nfrom pyhf import get_backend\nimport numpy as np\n\n__all__ = [\"upperlimit\"]\n\n\ndef __dir__():\n    return __all__\n\n\ndef _interp(x, xp, fp):\n    tb, _ = get_backend()\n    return tb.astensor(np.interp(x, xp.tolist(), fp.tolist()))\n\n\ndef upperlimit(data, model, scan, level=0.05, return_results=False):\n    \"\"\"\n    Calculate an upper limit interval ``(0, poi_up)`` for a single\n    Parameter of Interest (POI) using a fixed scan through POI-space.\n\n    Example:\n        >>> import numpy as np\n        >>> import pyhf\n        >>> pyhf.set_backend(\"numpy\")\n        >>> model = pyhf.simplemodels.uncorrelated_background(\n        ...     signal=[12.0, 11.0], bkg=[50.0, 52.0], bkg_uncertainty=[3.0, 7.0]\n        ... )\n        >>> observations = [51, 48]\n        >>> data = pyhf.tensorlib.astensor(observations + model.config.auxdata)\n        >>> scan = np.linspace(0, 5, 21)\n        >>> obs_limit, exp_limits, (scan, results) = pyhf.infer.intervals.upperlimit(\n        ...     data, model, scan, return_results=True\n        ... )\n        >>> obs_limit\n        array(1.01764089)\n        >>> exp_limits\n        [array(0.59576921), array(0.76169166), array(1.08504773), array(1.50170482), array(2.06654952)]\n\n    Args:\n        data (:obj:`tensor`): The observed data.\n        model (~pyhf.pdf.Model): The statistical model adhering to the schema ``model.json``.\n        scan (:obj:`iterable`): Iterable of POI values.\n        level (:obj:`float`): The threshold value to evaluate the interpolated results at.\n        return_results (:obj:`bool`): Whether to return the per-point results.\n\n    Returns:\n        Tuple of Tensors:\n\n            - Tensor: The observed upper limit on the POI.\n            - Tensor: The expected upper limits on the POI.\n            - Tuple of Tensors: The given ``scan`` along with the\n              :class:`~pyhf.infer.hypotest` results at each test POI.\n              Only returned when ``return_results`` is ``True``.\n    \"\"\"\n    tb, _ = get_backend()\n    results = [\n        hypotest(mu, data, model, test_stat=\"qtilde\", return_expected_set=True)\n        for mu in scan\n    ]\n    obs = tb.astensor([[r[0]] for r in results])\n    exp = tb.astensor([[r[1][idx] for idx in range(5)] for r in results])\n\n    result_arrary = tb.concatenate([obs, exp], axis=1).T\n\n    # observed limit and the (0, +-1, +-2)sigma expected limits\n    limits = [_interp(level, result_arrary[idx][::-1], scan[::-1]) for idx in range(6)]\n    obs_limit, exp_limits = limits[0], limits[1:]\n\n    if return_results:\n        return obs_limit, exp_limits, (scan, results)\n    return obs_limit, exp_limits\n", "path": "src/pyhf/infer/intervals.py"}], "after_files": [{"content": "\"\"\"Interval estimation\"\"\"\nfrom pyhf.infer import hypotest\nfrom pyhf import get_backend\nimport numpy as np\n\n__all__ = [\"upperlimit\"]\n\n\ndef __dir__():\n    return __all__\n\n\ndef _interp(x, xp, fp):\n    tb, _ = get_backend()\n    return tb.astensor(np.interp(x, xp.tolist(), fp.tolist()))\n\n\ndef upperlimit(data, model, scan, level=0.05, return_results=False, **hypotest_kwargs):\n    \"\"\"\n    Calculate an upper limit interval ``(0, poi_up)`` for a single\n    Parameter of Interest (POI) using a fixed scan through POI-space.\n\n    Example:\n        >>> import numpy as np\n        >>> import pyhf\n        >>> pyhf.set_backend(\"numpy\")\n        >>> model = pyhf.simplemodels.uncorrelated_background(\n        ...     signal=[12.0, 11.0], bkg=[50.0, 52.0], bkg_uncertainty=[3.0, 7.0]\n        ... )\n        >>> observations = [51, 48]\n        >>> data = pyhf.tensorlib.astensor(observations + model.config.auxdata)\n        >>> scan = np.linspace(0, 5, 21)\n        >>> obs_limit, exp_limits, (scan, results) = pyhf.infer.intervals.upperlimit(\n        ...     data, model, scan, return_results=True\n        ... )\n        >>> obs_limit\n        array(1.01764089)\n        >>> exp_limits\n        [array(0.59576921), array(0.76169166), array(1.08504773), array(1.50170482), array(2.06654952)]\n\n    Args:\n        data (:obj:`tensor`): The observed data.\n        model (~pyhf.pdf.Model): The statistical model adhering to the schema ``model.json``.\n        scan (:obj:`iterable`): Iterable of POI values.\n        level (:obj:`float`): The threshold value to evaluate the interpolated results at.\n        return_results (:obj:`bool`): Whether to return the per-point results.\n        hypotest_kwargs (:obj:`string`): Kwargs for the calls to\n         :class:`~pyhf.infer.hypotest` to configure the fits.\n\n    Returns:\n        Tuple of Tensors:\n\n            - Tensor: The observed upper limit on the POI.\n            - Tensor: The expected upper limits on the POI.\n            - Tuple of Tensors: The given ``scan`` along with the\n              :class:`~pyhf.infer.hypotest` results at each test POI.\n              Only returned when ``return_results`` is ``True``.\n    \"\"\"\n    tb, _ = get_backend()\n    results = [\n        hypotest(mu, data, model, return_expected_set=True, **hypotest_kwargs)\n        for mu in scan\n    ]\n    obs = tb.astensor([[r[0]] for r in results])\n    exp = tb.astensor([[r[1][idx] for idx in range(5)] for r in results])\n\n    result_arrary = tb.concatenate([obs, exp], axis=1).T\n\n    # observed limit and the (0, +-1, +-2)sigma expected limits\n    limits = [_interp(level, result_arrary[idx][::-1], scan[::-1]) for idx in range(6)]\n    obs_limit, exp_limits = limits[0], limits[1:]\n\n    if return_results:\n        return obs_limit, exp_limits, (scan, results)\n    return obs_limit, exp_limits\n", "path": "src/pyhf/infer/intervals.py"}]}