{"id":13689048,"url":"https://github.com/scikit-hep/pyhf","last_synced_at":"2025-05-15T00:08:46.452Z","repository":{"id":37270152,"uuid":"118789569","full_name":"scikit-hep/pyhf","owner":"scikit-hep","description":"pure-Python HistFactory implementation with tensors and autodiff","archived":false,"fork":false,"pushed_at":"2025-05-05T19:14:11.000Z","size":58659,"stargazers_count":288,"open_issues_count":449,"forks_count":87,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-14T03:25:22.178Z","etag":null,"topics":["asymptotic-formulas","closember","cls","frequentist-statistics","hep","hep-ex","high-energy-physics","histfactory","jax","numpy","python","pytorch","scientific-computations","scikit-hep","scipy","statistical-inference","statistics","tensorflow"],"latest_commit_sha":null,"homepage":"https://pyhf.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scikit-hep.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":"docs/governance/ROADMAP.rst","roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":".zenodo.json"}},"created_at":"2018-01-24T16:14:39.000Z","updated_at":"2025-05-07T17:42:03.000Z","dependencies_parsed_at":"2024-01-16T07:23:00.485Z","dependency_job_id":"6f40d1c3-e65a-42b5-833f-5a68e732a0e8","html_url":"https://github.com/scikit-hep/pyhf","commit_stats":{"total_commits":1421,"total_committers":37,"mean_commits":38.4054054054054,"dds":"0.45320197044334976","last_synced_commit":"eb44f8c78537517d4515bc6d04feac0361b1e58e"},"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-hep%2Fpyhf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-hep%2Fpyhf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-hep%2Fpyhf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scikit-hep%2Fpyhf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scikit-hep","download_url":"https://codeload.github.com/scikit-hep/pyhf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254249204,"owners_count":22039029,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asymptotic-formulas","closember","cls","frequentist-statistics","hep","hep-ex","high-energy-physics","histfactory","jax","numpy","python","pytorch","scientific-computations","scikit-hep","scipy","statistical-inference","statistics","tensorflow"],"created_at":"2024-08-02T15:01:32.038Z","updated_at":"2025-05-15T00:08:41.443Z","avatar_url":"https://github.com/scikit-hep.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":".. image:: https://raw.githubusercontent.com/scikit-hep/pyhf/main/docs/_static/img/pyhf-logo.svg\n   :alt: pyhf logo\n   :width: 320\n   :align: center\n\npure-python fitting/limit-setting/interval estimation HistFactory-style\n=======================================================================\n\n|GitHub Project| |DOI| |JOSS DOI| |Scikit-HEP| |NSF Award Number IRIS-HEP v1| |NSF Award Number IRIS-HEP v2| |NumFOCUS Affiliated Project|\n\n|Docs from latest| |Docs from main| |Jupyter Book tutorial| |Binder|\n\n|PyPI version| |Conda-forge version| |Supported Python versions| |Docker Hub pyhf| |Docker Hub pyhf CUDA|\n\n|Code Coverage| |CodeFactor| |pre-commit.ci Status| |Code style: black|\n\n|GitHub Actions Status: CI| |GitHub Actions Status: Docs| |GitHub Actions Status: Publish|\n|GitHub Actions Status: Docker|\n\nThe HistFactory p.d.f. template\n[`CERN-OPEN-2012-016 \u003chttps://cds.cern.ch/record/1456844\u003e`__] is per-se\nindependent of its implementation in ROOT and sometimes, it’s useful to\nbe able to run statistical analysis outside of ROOT, RooFit, RooStats\nframework.\n\nThis repo is a pure-python implementation of that statistical model for\nmulti-bin histogram-based analysis and its interval estimation is based\non the asymptotic formulas of “Asymptotic formulae for likelihood-based\ntests of new physics”\n[`arXiv:1007.1727 \u003chttps://arxiv.org/abs/1007.1727\u003e`__]. The aim is also\nto support modern computational graph libraries such as PyTorch and\nTensorFlow in order to make use of features such as autodifferentiation\nand GPU acceleration.\n\n..\n  Comment: JupyterLite segment goes here in docs\n\nUser Guide\n----------\n\nFor an in depth walkthrough of usage of the latest release of ``pyhf`` visit the |pyhf tutorial|_.\n\n.. |pyhf tutorial| replace:: ``pyhf`` tutorial\n.. _pyhf tutorial: https://pyhf.github.io/pyhf-tutorial/\n\nHello World\n-----------\n\nThis is how you use the ``pyhf`` Python API to build a statistical model and run basic inference:\n\n.. code:: pycon\n\n   \u003e\u003e\u003e import pyhf\n   \u003e\u003e\u003e pyhf.set_backend(\"numpy\")\n   \u003e\u003e\u003e model = pyhf.simplemodels.uncorrelated_background(\n   ...     signal=[12.0, 11.0], bkg=[50.0, 52.0], bkg_uncertainty=[3.0, 7.0]\n   ... )\n   \u003e\u003e\u003e data = [51, 48] + model.config.auxdata\n   \u003e\u003e\u003e test_mu = 1.0\n   \u003e\u003e\u003e CLs_obs, CLs_exp = pyhf.infer.hypotest(\n   ...     test_mu, data, model, test_stat=\"qtilde\", return_expected=True\n   ... )\n   \u003e\u003e\u003e print(f\"Observed: {CLs_obs:.8f}, Expected: {CLs_exp:.8f}\")\n   Observed: 0.05251497, Expected: 0.06445321\n\nAlternatively the statistical model and observational data can be read from its serialized JSON representation (see next section).\n\n.. code:: pycon\n\n   \u003e\u003e\u003e import pyhf\n   \u003e\u003e\u003e import requests\n   \u003e\u003e\u003e pyhf.set_backend(\"numpy\")\n   \u003e\u003e\u003e url = \"https://raw.githubusercontent.com/scikit-hep/pyhf/main/docs/examples/json/2-bin_1-channel.json\"\n   \u003e\u003e\u003e wspace = pyhf.Workspace(requests.get(url).json())\n   \u003e\u003e\u003e model = wspace.model()\n   \u003e\u003e\u003e data = wspace.data(model)\n   \u003e\u003e\u003e test_mu = 1.0\n   \u003e\u003e\u003e CLs_obs, CLs_exp = pyhf.infer.hypotest(\n   ...     test_mu, data, model, test_stat=\"qtilde\", return_expected=True\n   ... )\n   \u003e\u003e\u003e print(f\"Observed: {CLs_obs:.8f}, Expected: {CLs_exp:.8f}\")\n   Observed: 0.35998409, Expected: 0.35998409\n\n\nFinally, you can also use the command line interface that ``pyhf`` provides\n\n.. code:: bash\n\n   $ cat \u003c\u003c EOF  | tee likelihood.json | pyhf cls\n   {\n       \"channels\": [\n           { \"name\": \"singlechannel\",\n             \"samples\": [\n               { \"name\": \"signal\",\n                 \"data\": [12.0, 11.0],\n                 \"modifiers\": [ { \"name\": \"mu\", \"type\": \"normfactor\", \"data\": null} ]\n               },\n               { \"name\": \"background\",\n                 \"data\": [50.0, 52.0],\n                 \"modifiers\": [ {\"name\": \"uncorr_bkguncrt\", \"type\": \"shapesys\", \"data\": [3.0, 7.0]} ]\n               }\n             ]\n           }\n       ],\n       \"observations\": [\n           { \"name\": \"singlechannel\", \"data\": [51.0, 48.0] }\n       ],\n       \"measurements\": [\n           { \"name\": \"Measurement\", \"config\": {\"poi\": \"mu\", \"parameters\": []} }\n       ],\n       \"version\": \"1.0.0\"\n   }\n   EOF\n\nwhich should produce the following JSON output:\n\n.. code:: json\n\n   {\n      \"CLs_exp\": [\n         0.0026062609501074576,\n         0.01382005356161206,\n         0.06445320535890459,\n         0.23525643861460702,\n         0.573036205919389\n      ],\n      \"CLs_obs\": 0.05251497423736956\n   }\n\nWhat does it support\n--------------------\n\nImplemented variations:\n  - ☑ HistoSys\n  - ☑ OverallSys\n  - ☑ ShapeSys\n  - ☑ NormFactor\n  - ☑ Multiple Channels\n  - ☑ Import from XML + ROOT via `uproot \u003chttps://github.com/scikit-hep/uproot4\u003e`__\n  - ☑ ShapeFactor\n  - ☑ StatError\n  - ☑ Lumi Uncertainty\n  - ☑ Non-asymptotic calculators\n\nComputational Backends:\n  - ☑ NumPy\n  - ☑ PyTorch\n  - ☑ TensorFlow\n  - ☑ JAX\n\nOptimizers:\n  - ☑ SciPy (``scipy.optimize``)\n  - ☑ MINUIT (``iminuit``)\n\nAll backends can be used in combination with all optimizers.\nCustom user backends and optimizers can be used as well.\n\nTodo\n----\n\n-  ☐ StatConfig\n\nresults obtained from this package are validated against output computed\nfrom HistFactory workspaces\n\nA one bin example\n-----------------\n\n.. code:: python\n\n   import pyhf\n   import numpy as np\n   import matplotlib.pyplot as plt\n   from pyhf.contrib.viz import brazil\n\n   pyhf.set_backend(\"numpy\")\n   model = pyhf.simplemodels.uncorrelated_background(\n       signal=[10.0], bkg=[50.0], bkg_uncertainty=[7.0]\n   )\n   data = [55.0] + model.config.auxdata\n\n   poi_vals = np.linspace(0, 5, 41)\n   results = [\n       pyhf.infer.hypotest(\n           test_poi, data, model, test_stat=\"qtilde\", return_expected_set=True\n       )\n       for test_poi in poi_vals\n   ]\n\n   fig, ax = plt.subplots()\n   fig.set_size_inches(7, 5)\n   brazil.plot_results(poi_vals, results, ax=ax)\n   fig.show()\n\n**pyhf**\n\n.. image:: https://raw.githubusercontent.com/scikit-hep/pyhf/main/docs/_static/img/README_1bin_example.png\n   :alt: manual\n   :width: 500\n   :align: center\n\n**ROOT**\n\n.. image:: https://raw.githubusercontent.com/scikit-hep/pyhf/main/docs/_static/img/hfh_1bin_55_50_7.png\n   :alt: manual\n   :width: 500\n   :align: center\n\nA two bin example\n-----------------\n\n.. code:: python\n\n   import pyhf\n   import numpy as np\n   import matplotlib.pyplot as plt\n   from pyhf.contrib.viz import brazil\n\n   pyhf.set_backend(\"numpy\")\n   model = pyhf.simplemodels.uncorrelated_background(\n       signal=[30.0, 45.0], bkg=[100.0, 150.0], bkg_uncertainty=[15.0, 20.0]\n   )\n   data = [100.0, 145.0] + model.config.auxdata\n\n   poi_vals = np.linspace(0, 5, 41)\n   results = [\n       pyhf.infer.hypotest(\n           test_poi, data, model, test_stat=\"qtilde\", return_expected_set=True\n       )\n       for test_poi in poi_vals\n   ]\n\n   fig, ax = plt.subplots()\n   fig.set_size_inches(7, 5)\n   brazil.plot_results(poi_vals, results, ax=ax)\n   fig.show()\n\n\n**pyhf**\n\n.. image:: https://raw.githubusercontent.com/scikit-hep/pyhf/main/docs/_static/img/README_2bin_example.png\n   :alt: manual\n   :width: 500\n   :align: center\n\n**ROOT**\n\n.. image:: https://raw.githubusercontent.com/scikit-hep/pyhf/main/docs/_static/img/hfh_2_bin_100.0_145.0_100.0_150.0_15.0_20.0_30.0_45.0.png\n   :alt: manual\n   :width: 500\n   :align: center\n\nInstallation\n------------\n\nTo install ``pyhf`` from PyPI with the NumPy backend run\n\n.. code:: bash\n\n   python -m pip install pyhf\n\nand to install ``pyhf`` with all additional backends run\n\n.. code:: bash\n\n   python -m pip install pyhf[backends]\n\nor a subset of the options.\n\nTo uninstall run\n\n.. code:: bash\n\n   python -m pip uninstall pyhf\n\nDocumentation\n-------------\n\nFor model specification, API reference, examples, and answers to FAQs visit the |pyhf documentation|_.\n\n.. |pyhf documentation| replace:: ``pyhf`` documentation\n.. _pyhf documentation: https://pyhf.readthedocs.io/\n\nQuestions\n---------\n\nIf you have a question about the use of ``pyhf`` not covered in `the\ndocumentation \u003chttps://pyhf.readthedocs.io/\u003e`__, please ask a question\non the `GitHub Discussions \u003chttps://github.com/scikit-hep/pyhf/discussions\u003e`__.\n\nIf you believe you have found a bug in ``pyhf``, please report it in the\n`GitHub\nIssues \u003chttps://github.com/scikit-hep/pyhf/issues/new?template=Bug-Report.md\u0026labels=bug\u0026title=Bug+Report+:+Title+Here\u003e`__.\nIf you're interested in getting updates from the ``pyhf`` dev team and release\nannouncements you can join the |pyhf-announcements mailing list|_.\n\n.. |pyhf-announcements mailing list| replace:: ``pyhf-announcements`` mailing list\n.. _pyhf-announcements mailing list: https://groups.google.com/group/pyhf-announcements/subscribe\n\nCitation\n--------\n\nAs noted in `Use and Citations \u003chttps://scikit-hep.org/pyhf/citations.html\u003e`__,\nthe preferred BibTeX entry for citation of ``pyhf`` includes both the\n`Zenodo \u003chttps://zenodo.org/\u003e`__ archive and the\n`JOSS \u003chttps://joss.theoj.org/\u003e`__ paper:\n\n.. code:: bibtex\n\n   @software{pyhf,\n     author = {Lukas Heinrich and Matthew Feickert and Giordon Stark},\n     title = \"{pyhf: v0.7.6}\",\n     version = {0.7.6},\n     doi = {10.5281/zenodo.1169739},\n     url = {https://doi.org/10.5281/zenodo.1169739},\n     note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.6}\n   }\n\n   @article{pyhf_joss,\n     doi = {10.21105/joss.02823},\n     url = {https://doi.org/10.21105/joss.02823},\n     year = {2021},\n     publisher = {The Open Journal},\n     volume = {6},\n     number = {58},\n     pages = {2823},\n     author = {Lukas Heinrich and Matthew Feickert and Giordon Stark and Kyle Cranmer},\n     title = {pyhf: pure-Python implementation of HistFactory statistical models},\n     journal = {Journal of Open Source Software}\n   }\n\nAuthors\n-------\n\n``pyhf`` is openly developed by Lukas Heinrich, Matthew Feickert, and Giordon Stark.\n\nPlease check the `contribution statistics for a list of\ncontributors \u003chttps://github.com/scikit-hep/pyhf/graphs/contributors\u003e`__.\n\nMilestones\n----------\n\n- 2022-09-12: 2000 GitHub issues and pull requests. (See PR `#2000 \u003chttps://github.com/scikit-hep/pyhf/pull/2000\u003e`__)\n- 2021-12-09: 1000 commits to the project. (See PR `#1710 \u003chttps://github.com/scikit-hep/pyhf/pull/1710\u003e`__)\n- 2020-07-28: 1000 GitHub issues and pull requests. (See PR `#1000 \u003chttps://github.com/scikit-hep/pyhf/pull/1000\u003e`__)\n\nAcknowledgements\n----------------\n\nMatthew Feickert has received support to work on ``pyhf`` provided by NSF\ncooperative agreements `OAC-1836650 \u003chttps://nsf.gov/awardsearch/showAward?AWD_ID=1836650\u003e`__\nand `PHY-2323298 \u003chttps://nsf.gov/awardsearch/showAward?AWD_ID=2323298\u003e`__ (IRIS-HEP)\nand grant `OAC-1450377 \u003chttps://www.nsf.gov/awardsearch/showAward?AWD_ID=1450377\u003e`__ (DIANA/HEP).\n\n``pyhf`` is a `NumFOCUS Affiliated Project \u003chttps://numfocus.org/sponsored-projects/affiliated-projects\u003e`__.\n\n.. |GitHub Project| image:: https://img.shields.io/badge/GitHub--blue?style=social\u0026logo=GitHub\n   :target: https://github.com/scikit-hep/pyhf\n.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.1169739.svg\n   :target: https://doi.org/10.5281/zenodo.1169739\n.. |JOSS DOI| image:: https://joss.theoj.org/papers/10.21105/joss.02823/status.svg\n   :target: https://doi.org/10.21105/joss.02823\n.. |Scikit-HEP| image:: https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg\n   :target: https://scikit-hep.org/\n.. |NSF Award Number IRIS-HEP v1| image:: https://img.shields.io/badge/NSF-1836650-blue.svg\n   :target: https://nsf.gov/awardsearch/showAward?AWD_ID=1836650\n.. |NSF Award Number IRIS-HEP v2| image:: https://img.shields.io/badge/NSF-2323298-blue.svg\n   :target: https://nsf.gov/awardsearch/showAward?AWD_ID=2323298\n.. |NumFOCUS Affiliated Project| image:: https://img.shields.io/badge/NumFOCUS-Affiliated%20Project-orange.svg?style=flat\u0026colorA=E1523D\u0026colorB=007D8A\n   :target: https://numfocus.org/sponsored-projects/affiliated-projects\n.. |Docs from latest| image:: https://img.shields.io/badge/docs-v0.7.6-blue.svg\n   :target: https://pyhf.readthedocs.io/\n.. |Docs from main| image:: https://img.shields.io/badge/docs-main-blue.svg\n   :target: https://scikit-hep.github.io/pyhf\n.. |Jupyter Book tutorial| image:: https://jupyterbook.org/_images/badge.svg\n   :target: https://pyhf.github.io/pyhf-tutorial/\n.. |Binder| image:: https://mybinder.org/badge_logo.svg\n   :target: https://mybinder.org/v2/gh/scikit-hep/pyhf/main?labpath=docs%2Fexamples%2Fnotebooks%2Fbinderexample%2FStatisticalAnalysis.ipynb\n\n.. |PyPI version| image:: https://badge.fury.io/py/pyhf.svg\n   :target: https://badge.fury.io/py/pyhf\n.. |Conda-forge version| image:: https://img.shields.io/conda/vn/conda-forge/pyhf.svg\n   :target: https://prefix.dev/channels/conda-forge/packages/pyhf\n.. |Supported Python versions| image:: https://img.shields.io/pypi/pyversions/pyhf.svg\n   :target: https://pypi.org/project/pyhf/\n.. |Docker Hub pyhf| image:: https://img.shields.io/badge/pyhf-v0.7.6-blue?logo=Docker\n   :target: https://hub.docker.com/r/pyhf/pyhf/tags\n.. |Docker Hub pyhf CUDA| image:: https://img.shields.io/badge/pyhf-CUDA-blue?logo=Docker\n   :target: https://hub.docker.com/r/pyhf/cuda/tags\n\n.. |Code Coverage| image:: https://codecov.io/gh/scikit-hep/pyhf/graph/badge.svg?branch=main\n   :target: https://codecov.io/gh/scikit-hep/pyhf?branch=main\n.. |CodeFactor| image:: https://www.codefactor.io/repository/github/scikit-hep/pyhf/badge\n   :target: https://www.codefactor.io/repository/github/scikit-hep/pyhf\n.. |pre-commit.ci Status| image:: https://results.pre-commit.ci/badge/github/scikit-hep/pyhf/main.svg\n  :target: https://results.pre-commit.ci/latest/github/scikit-hep/pyhf/main\n  :alt: pre-commit.ci status\n.. |Code style: black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n   :target: https://github.com/psf/black\n\n.. |GitHub Actions Status: CI| image:: https://github.com/scikit-hep/pyhf/actions/workflows/ci.yml/badge.svg\n   :target: https://github.com/scikit-hep/pyhf/actions/workflows/ci.yml?query=branch%3Amain\n.. |GitHub Actions Status: Docs| image:: https://github.com/scikit-hep/pyhf/actions/workflows/docs.yml/badge.svg\n   :target: https://github.com/scikit-hep/pyhf/actions/workflows/docs.yml?query=branch%3Amain\n.. |GitHub Actions Status: Publish| image:: https://github.com/scikit-hep/pyhf/actions/workflows/publish-package.yml/badge.svg\n   :target: https://github.com/scikit-hep/pyhf/actions/workflows/publish-package.yml?query=branch%3Amain\n.. |GitHub Actions Status: Docker| image:: https://github.com/scikit-hep/pyhf/actions/workflows/docker.yml/badge.svg\n   :target: https://github.com/scikit-hep/pyhf/actions/workflows/docker.yml?query=branch%3Amain\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscikit-hep%2Fpyhf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscikit-hep%2Fpyhf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscikit-hep%2Fpyhf/lists"}