From 2eb13e861aff27436f91afd18d9b08e8ca67fb92 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 23 Oct 2023 09:54:37 -0500 Subject: [PATCH 01/62] docs: Add general use citation from differentiable vertex fitting paper (#2355) * Add general citation from 'Differentiable Vertex Fitting for Jet Flavour Tagging'. - c.f. https://inspirehep.net/literature/2712691 --- docs/bib/general_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/general_citations.bib b/docs/bib/general_citations.bib index 69f91c1373..068c66a582 100644 --- a/docs/bib/general_citations.bib +++ b/docs/bib/general_citations.bib @@ -1,3 +1,15 @@ +% 2023-10-19 +@article{Smith:2023ssh, + author = "Smith, Rachel E. C. and Ochoa, In\^es and In\'acio, R\'uben and Shoemaker, Jonathan and Kagan, Michael", + title = "{Differentiable Vertex Fitting for Jet Flavour Tagging}", + eprint = "2310.12804", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + month = "10", + year = "2023", + journal = "" +} + % 2023-09-25 @inproceedings{Feickert:2023ajm, author = "Feickert, Matthew and Katz, Daniel S. and Neubauer, Mark S. and Sexton-Kennedy, Elizabeth and Stewart, Graeme A.", From ff19a15e1ae5fab4f3c6eb1982aa669de75a6a8b Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 23 Oct 2023 12:24:16 -0500 Subject: [PATCH 02/62] docs: Add use citation from observable sim gen ML paper (#2356) * Add use citation from 'Systematic Evaluation of Generative Machine Learning Capability to Simulate Distributions of Observables at the Large Hadron Collider'. - c.f. https://inspirehep.net/literature/2710627 --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 2d795f6304..1bb8fe3465 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2023-10-13 +@article{Gavranovic:2023oam, + author = "Gavranovi\v{c}, Jan and Ker\v{s}evan, Borut Paul", + title = "{Systematic Evaluation of Generative Machine Learning Capability to Simulate Distributions of Observables at the Large Hadron Collider}", + eprint = "2310.08994", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + month = "10", + year = "2023", + journal = "" +} + % 2023-10-11 @article{MicroBooNE:2023icy, author = "{MicroBooNE Collaboration}", From 50936682671edf814a8fe47a3ec661c914aed15a Mon Sep 17 00:00:00 2001 From: Alexander Held <45009355+alexander-held@users.noreply.github.com> Date: Mon, 23 Oct 2023 23:57:01 +0200 Subject: [PATCH 03/62] docs: Add award number for second phase of IRIS-HEP (#2354) * Add badge and funding acknowledgement for NSF cooperative agreement PHY-2323298 award for IRIS-HEP v2. - c.f. https://www.nsf.gov/awardsearch/showAward?AWD_ID=2323298 --- README.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index b536b9a08c..cf10370fdd 100644 --- a/README.rst +++ b/README.rst @@ -6,7 +6,7 @@ pure-python fitting/limit-setting/interval estimation HistFactory-style ======================================================================= -|GitHub Project| |DOI| |JOSS DOI| |Scikit-HEP| |NSF Award Number| |NumFOCUS Affiliated Project| +|GitHub Project| |DOI| |JOSS DOI| |Scikit-HEP| |NSF Award Number IRIS-HEP v1| |NSF Award Number IRIS-HEP v2| |NumFOCUS Affiliated Project| |Docs from latest| |Docs from main| |Jupyter Book tutorial| |Binder| @@ -348,7 +348,8 @@ Acknowledgements ---------------- Matthew Feickert has received support to work on ``pyhf`` provided by NSF -cooperative agreement `OAC-1836650 `__ (IRIS-HEP) +cooperative agreements `OAC-1836650 `__ +and `PHY-2323298 `__ (IRIS-HEP) and grant `OAC-1450377 `__ (DIANA/HEP). ``pyhf`` is a `NumFOCUS Affiliated Project `__. @@ -361,8 +362,10 @@ and grant `OAC-1450377 Date: Tue, 24 Oct 2023 15:35:17 -0700 Subject: [PATCH 04/62] fix: Remove os-dependent pieces of schema validation (#2357) * Use pathlib to build the stem for the schema to use (version + type of schema). - c.f. https://github.com/python/cpython/issues/65238 --- src/pyhf/schema/validator.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pyhf/schema/validator.py b/src/pyhf/schema/validator.py index 1fbc36c686..2540a3d002 100644 --- a/src/pyhf/schema/validator.py +++ b/src/pyhf/schema/validator.py @@ -1,4 +1,5 @@ import numbers +from pathlib import Path from typing import Mapping, Union import jsonschema @@ -70,12 +71,15 @@ def validate( version = version or variables.SCHEMA_VERSION - schema = load_schema(f'{version}/{schema_name}') + schema = load_schema(str(Path(version).joinpath(schema_name))) - # note: trailing slash needed for RefResolver to resolve correctly + # note: trailing slash needed for RefResolver to resolve correctly and by + # design, pathlib strips trailing slashes. See ref below: + # * https://bugs.python.org/issue21039 + # * https://github.com/python/cpython/issues/65238 resolver = jsonschema.RefResolver( - base_uri=f"file://{variables.schemas}/{version}/", - referrer=f"{schema_name}", + base_uri=f"{Path(variables.schemas).joinpath(version).as_uri()}/", + referrer=schema_name, store=variables.SCHEMA_CACHE, ) From 188b7a0015444e534c3ccefc07158aed2319b84b Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Wed, 25 Oct 2023 23:58:39 -0500 Subject: [PATCH 05/62] ci: Add simplified CI for Windows (#2363) * Add simplfied CI workflow for Windows. - Runs on nighly schedule and with workflow dispatch. * Add operating system PyPI trove classifier as support is added for Windows. --- .github/workflows/ci-windows.yml | 46 ++++++++++++++++++++++++++++++++ pyproject.toml | 1 + 2 files changed, 47 insertions(+) create mode 100644 .github/workflows/ci-windows.yml diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml new file mode 100644 index 0000000000..2aab9607f3 --- /dev/null +++ b/.github/workflows/ci-windows.yml @@ -0,0 +1,46 @@ +name: CI on Windows + +on: + # Run daily at 1:23 UTC + schedule: + - cron: '23 1 * * *' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest] + python-version: ['3.9', '3.10', '3.11'] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools wheel + python -m pip install --upgrade '.[test]' + + - name: List installed Python packages + run: python -m pip list + + - name: Test with pytest and coverage + # FIXME: ignore tests/test_scripts.py as runner breaks on Windows currently + run: | + coverage run --module pytest --ignore tests/test_scripts.py --ignore tests/contrib --ignore tests/benchmarks --ignore tests/test_notebooks.py + + - name: Coverage report for core project + run: | + coverage report + coverage xml diff --git a/pyproject.toml b/pyproject.toml index 1e50c697ce..fcbdeff0bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,7 @@ classifiers = [ "Environment :: WebAssembly :: Emscripten", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.8", From 9c5581d033be57eb31bb1794b0e2e1d88162855f Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 26 Oct 2023 12:06:19 -0500 Subject: [PATCH 06/62] docs: Update citations references with journal pubs through 2023-10 (#2367) * Update use citations references to include their journal publication information. - 'Vector-like lepton searches at a muon collider in the context of the 4321 model*'. https://doi.org/10.1088/1674-1137/ace5a7 - 'Potential of the Julia Programming Language for High Energy Physics Computing'. https://doi.org/10.1007/s41781-023-00104-x --- docs/bib/general_citations.bib | 13 ++++++++----- docs/bib/use_citations.bib | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/bib/general_citations.bib b/docs/bib/general_citations.bib index 068c66a582..3c66d739bf 100644 --- a/docs/bib/general_citations.bib +++ b/docs/bib/general_citations.bib @@ -36,14 +36,17 @@ @article{Kagan:2023gxz % 2023-06-06 @article{Eschle:2023ikn, - author = "Eschle, J. and others", - title = "{Potential of the Julia programming language for high energy physics computing}", + author = "Eschle, Jonas and others", + title = "{Potential of the Julia Programming Language for High Energy Physics Computing}", eprint = "2306.03675", archivePrefix = "arXiv", primaryClass = "hep-ph", - month = "6", - year = "2023", - journal = "" + doi = "10.1007/s41781-023-00104-x", + journal = "Comput. Softw. Big Sci.", + volume = "7", + number = "1", + pages = "10", + year = "2023" } % 2023-02-02 diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 1bb8fe3465..6967fca619 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -159,13 +159,16 @@ @article{Shadura:2023zks % 2023-04-04 @article{Guo:2023jkz, author = "Guo, Qilong and Gao, Leyun and Mao, Yajun and Li, Qiang", - title = "{Search for vector-like leptons at a Muon Collider}", + title = "{Vector-like lepton searches at a muon collider in the context of the 4321 model*}", eprint = "2304.01885", archivePrefix = "arXiv", primaryClass = "hep-ph", - month = "4", - year = "2023", - journal = "" + doi = "10.1088/1674-1137/ace5a7", + journal = "Chin. Phys. C", + volume = "47", + number = "10", + pages = "103106", + year = "2023" } % 2023-02-24 From 205c04ad4f668686584474b8e47fe55b2851d5f4 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 26 Oct 2023 13:02:24 -0500 Subject: [PATCH 07/62] =?UTF-8?q?docs:=20Bump=20version:=200.7.4=20?= =?UTF-8?q?=E2=86=92=200.7.5=20(#2370)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Forward port the version bump information from release v0.7.5 on the release/v0.7.x branch. --- .zenodo.json | 6 +++--- CITATION.cff | 8 ++++---- README.rst | 10 +++++----- codemeta.json | 2 +- docs/lite/jupyterlite.py | 2 +- src/pyhf/data/citation.bib | 6 +++--- src/pyhf/utils.py | 2 +- tbump.toml | 4 ++-- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index e1ede5548b..59380cbf28 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,8 +1,8 @@ { "description": "pure-Python HistFactory implementation with tensors and autodiff", "license": "Apache-2.0", - "title": "scikit-hep/pyhf: v0.7.4", - "version": "v0.7.4", + "title": "scikit-hep/pyhf: v0.7.5", + "version": "v0.7.5", "upload_type": "software", "creators": [ { @@ -36,7 +36,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/scikit-hep/pyhf/tree/v0.7.4", + "identifier": "https://github.com/scikit-hep/pyhf/tree/v0.7.5", "relation": "isSupplementTo" } ] diff --git a/CITATION.cff b/CITATION.cff index 32128c124b..85f9f5b8ba 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,11 +14,11 @@ authors: given-names: "Giordon" orcid: "https://orcid.org/0000-0001-6616-3433" affiliation: "SCIPP, University of California, Santa Cruz" -title: "pyhf: v0.7.4" -version: 0.7.4 +title: "pyhf: v0.7.5" +version: 0.7.5 doi: 10.5281/zenodo.1169739 -repository-code: "https://github.com/scikit-hep/pyhf/releases/tag/v0.7.4" -url: "https://pyhf.readthedocs.io/en/v0.7.4/" +repository-code: "https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5" +url: "https://pyhf.readthedocs.io/en/v0.7.5/" keywords: - python - physics diff --git a/README.rst b/README.rst index cf10370fdd..ba0f5199ff 100644 --- a/README.rst +++ b/README.rst @@ -309,11 +309,11 @@ the preferred BibTeX entry for citation of ``pyhf`` includes both the @software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, - title = "{pyhf: v0.7.4}", - version = {0.7.4}, + title = "{pyhf: v0.7.5}", + version = {0.7.5}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, - note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.4} + note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5} } @article{pyhf_joss, @@ -368,7 +368,7 @@ and grant `OAC-1450377 =3.0.0"]) +await piplite.install(["pyhf==0.7.5", "matplotlib>=3.0.0"]) # %matplotlib inline import pyhf diff --git a/src/pyhf/data/citation.bib b/src/pyhf/data/citation.bib index ea49d8f090..1c38a90abd 100644 --- a/src/pyhf/data/citation.bib +++ b/src/pyhf/data/citation.bib @@ -1,10 +1,10 @@ @software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, - title = "{pyhf: v0.7.4}", - version = {0.7.4}, + title = "{pyhf: v0.7.5}", + version = {0.7.5}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, - note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.4} + note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5} } @article{pyhf_joss, diff --git a/src/pyhf/utils.py b/src/pyhf/utils.py index 45f3d89f3e..859f887913 100644 --- a/src/pyhf/utils.py +++ b/src/pyhf/utils.py @@ -111,7 +111,7 @@ def citation(oneline=False): >>> import pyhf >>> pyhf.utils.citation(oneline=True) - '@software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, title = "{pyhf: v0.7.4}", version = {0.7.4}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.4}}@article{pyhf_joss, doi = {10.21105/joss.02823}, url = {https://doi.org/10.21105/joss.02823}, year = {2021}, publisher = {The Open Journal}, volume = {6}, number = {58}, pages = {2823}, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark and Kyle Cranmer}, title = {pyhf: pure-Python implementation of HistFactory statistical models}, journal = {Journal of Open Source Software}}' + '@software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, title = "{pyhf: v0.7.5}", version = {0.7.5}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5}}@article{pyhf_joss, doi = {10.21105/joss.02823}, url = {https://doi.org/10.21105/joss.02823}, year = {2021}, publisher = {The Open Journal}, volume = {6}, number = {58}, pages = {2823}, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark and Kyle Cranmer}, title = {pyhf: pure-Python implementation of HistFactory statistical models}, journal = {Journal of Open Source Software}}' Keyword Args: oneline (:obj:`bool`): Whether to provide citation with new lines (default) or as a one-liner. diff --git a/tbump.toml b/tbump.toml index 34a0361310..5f1c14c46f 100644 --- a/tbump.toml +++ b/tbump.toml @@ -1,7 +1,7 @@ github_url = "https://github.com/scikit-hep/pyhf/" [version] -current = "0.7.4" +current = "0.7.5" # Example of a semver regexp. # Make sure this matches current_version before @@ -19,7 +19,7 @@ regex = ''' [git] # The current version will get updated when tbump is run -message_template = "Bump version: 0.7.4 → {new_version}" +message_template = "Bump version: 0.7.5 → {new_version}" tag_template = "v{new_version}" # For each file to patch, add a [[file]] config From 6a347f4be87ece5fd14b726acd99efca3b5cc7f4 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 26 Oct 2023 13:55:42 -0500 Subject: [PATCH 08/62] docs: Add v0.7.5 release notes (#2371) * Forward port PR #2362 from release/v0.7.x to main. * Add release notes for pyhf v0.7.5. --- docs/release-notes.rst | 1 + docs/release-notes/v0.7.5.rst | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 docs/release-notes/v0.7.5.rst diff --git a/docs/release-notes.rst b/docs/release-notes.rst index c11d6c2019..0bdc291dfb 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -2,6 +2,7 @@ Release Notes ============= +.. include:: release-notes/v0.7.5.rst .. include:: release-notes/v0.7.4.rst .. include:: release-notes/v0.7.3.rst .. include:: release-notes/v0.7.2.rst diff --git a/docs/release-notes/v0.7.5.rst b/docs/release-notes/v0.7.5.rst new file mode 100644 index 0000000000..6687a55370 --- /dev/null +++ b/docs/release-notes/v0.7.5.rst @@ -0,0 +1,14 @@ +|release v0.7.5|_ +================= + +This is a patch release from ``v0.7.4`` → ``v0.7.5``. + +Fixes +----- + +* Remove operating system dependent components of schema validation to allow for + validation on Windows. + (PR :pr:`2357`) + +.. |release v0.7.5| replace:: ``v0.7.5`` +.. _`release v0.7.5`: https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5 From 78d9cc229fd853bfb91601d7372b4b297213181b Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 2 Nov 2023 02:10:17 -0500 Subject: [PATCH 09/62] build: Remove installation of backends from 'test' extra (#2373) * Remove the 'all' extra from the 'test' extra installs and add 'all' to the 'develop' extra. * Add the 'all' extra to all install commands that also install the 'test' extra. --- .github/workflows/ci-windows.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/dependencies-head.yml | 12 ++++++------ .github/workflows/lower-bound-requirements.yml | 2 +- .github/workflows/notebooks.yml | 2 +- noxfile.py | 6 +++--- pyproject.toml | 3 +-- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml index 2aab9607f3..bd26b06053 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -30,7 +30,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip install --upgrade '.[test]' + python -m pip install --upgrade '.[all,test]' - name: List installed Python packages run: python -m pip list diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81324f2884..1f61c5fb95 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip install --upgrade .[test] + python -m pip install --upgrade ".[all,test]" - name: List installed Python packages run: python -m pip list diff --git a/.github/workflows/dependencies-head.yml b/.github/workflows/dependencies-head.yml index ab2e8e8de2..a213e2052c 100644 --- a/.github/workflows/dependencies-head.yml +++ b/.github/workflows/dependencies-head.yml @@ -30,7 +30,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir --quiet install --upgrade --pre .[test] + python -m pip --no-cache-dir --quiet install --upgrade --pre ".[all,test]" python -m pip list - name: List release candidates, alpha, and beta releases @@ -62,7 +62,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir --quiet install --upgrade .[test] + python -m pip --no-cache-dir --quiet install --upgrade ".[all,test]" python -m pip uninstall --yes scipy python -m pip install --upgrade --index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple scipy python -m pip list @@ -88,7 +88,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir --quiet install --upgrade .[test] + python -m pip --no-cache-dir --quiet install --upgrade ".[all,test]" python -m pip uninstall --yes iminuit python -m pip install --upgrade cython python -m pip install --upgrade git+https://github.com/scikit-hep/iminuit.git @@ -114,7 +114,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir --quiet install --upgrade .[test] + python -m pip --no-cache-dir --quiet install --upgrade ".[all,test]" python -m pip uninstall --yes uproot python -m pip install --upgrade git+https://github.com/scikit-hep/uproot5.git python -m pip list @@ -141,7 +141,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir --quiet install --upgrade .[test] + python -m pip --no-cache-dir --quiet install --upgrade ".[all,test]" python -m pip uninstall --yes matplotlib # Need to use --extra-index-url as dependencies aren't on scientific-python-nightly-wheels package index. # Need to use --pre as dev releases will need priority over stable releases. @@ -176,7 +176,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir --quiet install --upgrade .[test] + python -m pip --no-cache-dir --quiet install --upgrade ".[all,test]" python -m pip uninstall --yes pytest python -m pip install --upgrade git+https://github.com/pytest-dev/pytest.git python -m pip list diff --git a/.github/workflows/lower-bound-requirements.yml b/.github/workflows/lower-bound-requirements.yml index 27e9a9cf4c..69f0937e8f 100644 --- a/.github/workflows/lower-bound-requirements.yml +++ b/.github/workflows/lower-bound-requirements.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies and force lowest bound run: | python -m pip install --upgrade pip setuptools wheel - python -m pip --no-cache-dir install --constraint tests/constraints.txt .[test] + python -m pip --no-cache-dir install --constraint tests/constraints.txt ".[all,test]" - name: List installed Python packages run: python -m pip list diff --git a/.github/workflows/notebooks.yml b/.github/workflows/notebooks.yml index 47c6acaff0..bc4c817efe 100644 --- a/.github/workflows/notebooks.yml +++ b/.github/workflows/notebooks.yml @@ -30,7 +30,7 @@ jobs: run: | python -m pip install --upgrade pip setuptools wheel # FIXME: c.f. https://github.com/scikit-hep/pyhf/issues/2104 - python -m pip install --upgrade .[test] 'jupyter-client<8.0.0' + python -m pip install --upgrade ".[all,test]" 'jupyter-client<8.0.0' - name: List installed Python packages run: python -m pip list diff --git a/noxfile.py b/noxfile.py index ba75fae440..8104dbd28b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -35,7 +35,7 @@ def tests(session): $ nox --session tests --python 3.11 -- tests/test_tensor.py # run specific tests $ nox --session tests --python 3.11 -- coverage # run with coverage but slower """ - session.install("--upgrade", "--editable", ".[test]") + session.install("--upgrade", "--editable", ".[all,test]") session.install("--upgrade", "pytest") # Allow tests to be run with coverage @@ -107,7 +107,7 @@ def regenerate(session): """ Regenerate Matplotlib images. """ - session.install("--upgrade", "--editable", ".[test]") + session.install("--upgrade", "--editable", ".[all,test]") session.install("--upgrade", "pytest", "matplotlib") if not sys.platform.startswith("linux"): session.error( @@ -182,7 +182,7 @@ def notebooks(session: nox.Session): """ Run the notebook tests. """ - session.install("--upgrade", "--editable", ".[test]") + session.install("--upgrade", "--editable", ".[all,test]") session.run( "pytest", "--override-ini", diff --git a/pyproject.toml b/pyproject.toml index fcbdeff0bc..916d9b2d07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,6 @@ all = ["pyhf[backends,xmlio,contrib,shellcomplete]"] # Developer extras test = [ - "pyhf[all]", "scikit-hep-testdata>=0.4.11", "pytest>=6.0", "coverage[toml]>=6.0.0", @@ -121,7 +120,7 @@ docs = [ "ipython!=8.7.0", # c.f. https://github.com/scikit-hep/pyhf/pull/2068 ] develop = [ - "pyhf[test,docs]", + "pyhf[all,test,docs]", "tbump>=6.7.0", "pre-commit", "nox", From aa22be90fe938d3dbf61845e1e9ee25da13c2004 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 2 Nov 2023 10:46:06 -0500 Subject: [PATCH 10/62] docs: Add use citation from single resonant top paper (#2375) * Add use citation from 'New Physics in Single Resonant Top Quarks'. - c.f. https://inspirehep.net/literature/2716269 --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 6967fca619..e725a32040 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2023-10-31 +@article{Tong:2023lms, + author = "Tong, Shelley and Corcoran, James and Fieg, Max and Fenton, Michael and Whiteson, Daniel", + title = "{New Physics in Single Resonant Top Quarks}", + eprint = "2311.00121", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + month = "10", + year = "2023", + journal = "" +} + % 2023-10-13 @article{Gavranovic:2023oam, author = "Gavranovi\v{c}, Jan and Ker\v{s}evan, Borut Paul", From 899d1fd63158953df224a4b7af39b7d25a5a4647 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Sat, 4 Nov 2023 02:08:55 -0500 Subject: [PATCH 11/62] fix: Access jax.config from jax (#2376) * As of jax and jaxlib v0.4.20 accessing jax.config from the jax.config submodule is deprecated and it should be accessed from the jax top level API instead. ``` >>> from jax.config import config :1: DeprecationWarning: Accessing jax.config via the jax.config submodule is deprecated ``` --- src/pyhf/tensor/jax_backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyhf/tensor/jax_backend.py b/src/pyhf/tensor/jax_backend.py index 6ae53b7bec..61a14084c3 100644 --- a/src/pyhf/tensor/jax_backend.py +++ b/src/pyhf/tensor/jax_backend.py @@ -1,4 +1,4 @@ -from jax.config import config +from jax import config config.update('jax_enable_x64', True) From 43a84a477a93df640faea5c0526dc3abeead9759 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:47:45 -0600 Subject: [PATCH 12/62] chore: [pre-commit.ci] pre-commit autoupdate (#2378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pre-commit hooks: - github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0 - github.com/astral-sh/ruff-pre-commit: v0.0.292 → v0.1.4 - github.com/psf/black-pre-commit-mirror: 23.9.1 → 23.10.1 - github.com/pre-commit/mirrors-mypy: v1.5.1 → v1.6.1 * Exclude tests/constraints.txt from requirements-txt-fixer. --- .pre-commit-config.yaml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1087037b32..bcb8d65591 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -22,18 +22,19 @@ repos: - id: name-tests-test args: ["--pytest-test-first"] - id: requirements-txt-fixer + exclude: tests/constraints.txt - id: trailing-whitespace # exclude generated files exclude: ^validation/|\.dtd$|\.xml$ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.0.292" + rev: "v0.1.4" hooks: - id: ruff args: ["--fix", "--show-fixes"] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.9.1 + rev: 23.10.1 hooks: - id: black-jupyter @@ -41,10 +42,10 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==23.7.0] + additional_dependencies: [black==23.10.1] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.1 + rev: v1.6.1 # check the oldest and newest supported Pythons hooks: - &mypy @@ -62,7 +63,7 @@ repos: rev: 1.7.0 hooks: - id: nbqa-ruff - additional_dependencies: [ruff==0.0.292] + additional_dependencies: [ruff==v0.1.4] args: ["--extend-ignore=F821,F401,F841,F811"] - repo: https://github.com/codespell-project/codespell From ba5543b647ef417888b6516890e5ea686f4c9e98 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 17 Nov 2023 02:12:11 -0600 Subject: [PATCH 13/62] fix: Add filterwarnings ignore for Pytorch virtualized device UserWarning (#2380) * Add an ignore to filterwarnings to avoid PyTorch virtualized device UserWarning on virtualized Apple hardware. > UserWarning: Skipping device Apple Paravirtual device that does not > support Metal 2.0. - c.f. https://github.com/pytorch/pytorch/pull/111576 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 916d9b2d07..adcb9d4d5f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -216,6 +216,7 @@ filterwarnings = [ "ignore:module 'sre_constants' is deprecated:DeprecationWarning", # tensorflow v2.12.0+ for Python 3.11+ "ignore:ml_dtypes.float8_e4m3b11 is deprecated.", #FIXME: Can remove when jaxlib>=0.4.12 "ignore:jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the:DeprecationWarning", # Issue #2139 + "ignore:Skipping device Apple Paravirtual device that does not support Metal 2.0:UserWarning", # Can't fix given hardware/virtualized device ] [tool.coverage.run] From f04796f13aa8dd29be2875c5c38e2f8ee86f628d Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 17 Nov 2023 08:35:34 -0600 Subject: [PATCH 14/62] chore: Use Ruff lint config (#2381) * Use the Ruff lint config option as recommended in the Scientific Python Development Guide. - RF202: Use (new) lint config section. - c.f. https://learn.scientific-python.org/development/guides/style/#ruff --- pyproject.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index adcb9d4d5f..8161145a15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -284,25 +284,27 @@ module = [ ignore_errors = true [tool.ruff] +src = ["src"] +line-length = 88 + +[tool.ruff.lint] select = [ "E", "F", "W", # flake8 "UP", # pyupgrade "RUF", # Ruff-specific "TID", # flake8-tidy-imports ] -line-length = 88 ignore = [ "E402", "E501", "RUF001", # String contains ambiguous unicode character "RUF005", # unpack-instead-of-concatenating-to-collection-literal ] -src = ["src"] typing-modules = ["pyhf.typing"] unfixable = [ "F841", # Removes unused variables ] flake8-tidy-imports.ban-relative-imports = "all" -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "docs/lite/jupyterlite.py" = ["F401", "F704"] From 156bd115b7c5f80830f620a0039a275401a14200 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 17 Nov 2023 14:29:58 -0600 Subject: [PATCH 15/62] chore: Add pre-commit/pygrep-hooks to pre-commit hooks (#2382) * Impliment repo-review PC170: Uses PyGrep hooks (only needed if RST present). - c.f. https://learn.scientific-python.org/development/guides/style/#PC170 --- .pre-commit-config.yaml | 7 +++++++ docs/index.rst | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bcb8d65591..637aa35b22 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,6 +27,13 @@ repos: # exclude generated files exclude: ^validation/|\.dtd$|\.xml$ +- repo: https://github.com/pre-commit/pygrep-hooks + rev: "v1.10.0" + hooks: + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal + - repo: https://github.com/astral-sh/ruff-pre-commit rev: "v0.1.4" hooks: diff --git a/docs/index.rst b/docs/index.rst index 278abc2447..fbb5bf9925 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,7 @@ .. pyhf documentation master file, created by sphinx-quickstart on Fri Feb 9 11:58:49 2018. You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. + contain the root ``toctree`` directive. .. toctree:: :hidden: From f78442a5934c510032a4b61a2c1f736e01866cc7 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 17 Nov 2023 15:47:59 -0500 Subject: [PATCH 16/62] chore: Use native Ruff Jupyter support (#2383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove github.com/nbQA-dev/nbQA in favor of native Ruff Jupyter support. * Add support for python, pyi, jupyter types to black-jupyter hook. * Update github.com/astral-sh/ruff-pre-commit: v0.1.4 → v0.1.6. --- .pre-commit-config.yaml | 10 ++-------- pyproject.toml | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 637aa35b22..ae20e15066 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,7 +35,7 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.4" + rev: "v0.1.6" hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -44,6 +44,7 @@ repos: rev: 23.10.1 hooks: - id: black-jupyter + types_or: [python, pyi, jupyter] - repo: https://github.com/adamchainz/blacken-docs rev: 1.16.0 @@ -66,13 +67,6 @@ repos: name: mypy with Python 3.11 args: ["--python-version=3.11"] -- repo: https://github.com/nbQA-dev/nbQA - rev: 1.7.0 - hooks: - - id: nbqa-ruff - additional_dependencies: [ruff==v0.1.4] - args: ["--extend-ignore=F821,F401,F841,F811"] - - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: diff --git a/pyproject.toml b/pyproject.toml index 8161145a15..e2a17df696 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -308,3 +308,4 @@ flake8-tidy-imports.ban-relative-imports = "all" [tool.ruff.lint.per-file-ignores] "docs/lite/jupyterlite.py" = ["F401", "F704"] +"**.ipynb" = ["F821", "F401", "F841", "F811", "E703"] From a1a31f17967740c93244f5d9ad17aea1fbef6be3 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 21 Nov 2023 17:34:47 -0600 Subject: [PATCH 17/62] test: Use tmp_path pytest fixture over tmpdir (#2384) * Use `tmp_path` over `tmpdir`. * Use pathlib.Path functions now that paths and not files are being used. - Remove use of `.strpath`. - Update from `.join` to `.joinpath`. - For `json.loads` update from `.read` to `.read_text`. - For `json.load` update to use `.open`. - Update from `.write` to `.write_text` for patches. - Update from `.mkdir` to creating the path and then calling `.mkdir`. --- tests/conftest.py | 2 +- tests/contrib/test_contrib_utils.py | 66 +++--- tests/test_examples.py | 2 +- tests/test_infer.py | 22 +- tests/test_notebooks.py | 4 +- tests/test_scripts.py | 343 ++++++++++++++-------------- 6 files changed, 223 insertions(+), 216 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 2f969e3444..ad2d9d7cba 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -167,6 +167,6 @@ def datadir(tmp_path, request): dir_util.copy_tree(test_dir, str(tmp_path)) # shutil is nicer, but doesn't work: https://bugs.python.org/issue20849 # Once pyhf is Python 3.8+ only then the below can be used. - # shutil.copytree(test_dir, tmpdir) + # shutil.copytree(test_dir, tmp_path) return tmp_path diff --git a/tests/contrib/test_contrib_utils.py b/tests/contrib/test_contrib_utils.py index 5a0b69261b..4af73adf2d 100644 --- a/tests/contrib/test_contrib_utils.py +++ b/tests/contrib/test_contrib_utils.py @@ -1,6 +1,5 @@ import tarfile import zipfile -from pathlib import Path from shutil import rmtree import pytest @@ -10,70 +9,69 @@ @pytest.fixture(scope="function") -def tarfile_path(tmpdir): - with open( - tmpdir.join("test_file.txt").strpath, "w", encoding="utf-8" - ) as write_file: +def tarfile_path(tmp_path): + with open(tmp_path.joinpath("test_file.txt"), "w", encoding="utf-8") as write_file: write_file.write("test file") with tarfile.open( - tmpdir.join("test_tar.tar.gz").strpath, mode="w:gz", encoding="utf-8" + tmp_path.joinpath("test_tar.tar.gz"), mode="w:gz", encoding="utf-8" ) as archive: - archive.add(tmpdir.join("test_file.txt").strpath) - return Path(tmpdir.join("test_tar.tar.gz").strpath) + archive.add(tmp_path.joinpath("test_file.txt")) + return tmp_path.joinpath("test_tar.tar.gz") @pytest.fixture(scope="function") -def tarfile_uncompressed_path(tmpdir): - with open( - tmpdir.join("test_file.txt").strpath, "w", encoding="utf-8" - ) as write_file: +def tarfile_uncompressed_path(tmp_path): + with open(tmp_path.joinpath("test_file.txt"), "w", encoding="utf-8") as write_file: write_file.write("test file") with tarfile.open( - tmpdir.join("test_tar.tar").strpath, mode="w", encoding="utf-8" + tmp_path.joinpath("test_tar.tar"), mode="w", encoding="utf-8" ) as archive: - archive.add(tmpdir.join("test_file.txt").strpath) - return Path(tmpdir.join("test_tar.tar").strpath) + archive.add(tmp_path.joinpath("test_file.txt")) + return tmp_path.joinpath("test_tar.tar") @pytest.fixture(scope="function") -def zipfile_path(tmpdir): - with open( - tmpdir.join("test_file.txt").strpath, "w", encoding="utf-8" - ) as write_file: +def zipfile_path(tmp_path): + with open(tmp_path.joinpath("test_file.txt"), "w", encoding="utf-8") as write_file: write_file.write("test file") - with zipfile.ZipFile(tmpdir.join("test_zip.zip").strpath, "w") as archive: - archive.write(tmpdir.join("test_file.txt").strpath) - return Path(tmpdir.join("test_zip.zip").strpath) + with zipfile.ZipFile(tmp_path.joinpath("test_zip.zip"), "w") as archive: + archive.write(tmp_path.joinpath("test_file.txt")) + return tmp_path.joinpath("test_zip.zip") -def test_download_untrusted_archive_host(tmpdir, requests_mock): +def test_download_untrusted_archive_host(tmp_path, requests_mock): archive_url = "https://www.pyhfthisdoesnotexist.org" requests_mock.get(archive_url) with pytest.raises(InvalidArchiveHost): - download(archive_url, tmpdir.join("likelihoods").strpath) + download(archive_url, tmp_path.joinpath("likelihoods")) -def test_download_invalid_archive(tmpdir, requests_mock): +def test_download_invalid_archive(tmp_path, requests_mock): archive_url = "https://www.hepdata.net/record/resource/1408476?view=true" requests_mock.get(archive_url, status_code=404) with pytest.raises(InvalidArchive): - download(archive_url, tmpdir.join("likelihoods").strpath) + download(archive_url, tmp_path.joinpath("likelihoods")) -def test_download_compress(tmpdir, requests_mock): +def test_download_compress(tmp_path, requests_mock): archive_url = "https://www.hepdata.net/record/resource/1408476?view=true" requests_mock.get(archive_url) - download(archive_url, tmpdir.join("likelihoods").strpath, compress=True) + download(archive_url, tmp_path.joinpath("likelihoods"), compress=True) def test_download_archive_type( - tmpdir, mocker, requests_mock, tarfile_path, tarfile_uncompressed_path, zipfile_path + tmp_path, + mocker, + requests_mock, + tarfile_path, + tarfile_uncompressed_path, + zipfile_path, ): archive_url = "https://www.hepdata.net/record/resource/1408476?view=true" - output_directory = tmpdir.join("likelihoods").strpath + output_directory = tmp_path.joinpath("likelihoods") # Give BytesIO a tarfile requests_mock.get(archive_url, content=open(tarfile_path, "rb").read()) download(archive_url, output_directory) @@ -86,7 +84,7 @@ def test_download_archive_type( requests_mock.get(archive_url, content=open(zipfile_path, "rb").read()) # Run without and with existing output_directory to cover both # cases of the shutil.rmtree logic - rmtree(Path(output_directory)) + rmtree(output_directory) download(archive_url, output_directory) # without download(archive_url, output_directory) # with @@ -97,13 +95,13 @@ def test_download_archive_type( download(archive_url, output_directory) -def test_download_archive_force(tmpdir, requests_mock, tarfile_path): +def test_download_archive_force(tmp_path, requests_mock, tarfile_path): archive_url = "https://www.cern.ch/record/resource/123456789" requests_mock.get( archive_url, content=open(tarfile_path, "rb").read(), status_code=200 ) with pytest.raises(InvalidArchiveHost): - download(archive_url, tmpdir.join("likelihoods").strpath, force=False) + download(archive_url, tmp_path.joinpath("likelihoods"), force=False) - download(archive_url, tmpdir.join("likelihoods").strpath, force=True) + download(archive_url, tmp_path.joinpath("likelihoods"), force=True) diff --git a/tests/test_examples.py b/tests/test_examples.py index 9d4c2a1e1c..fa545726ec 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,7 +1,7 @@ import shlex -def test_2bin_1channel(tmpdir, script_runner): +def test_2bin_1channel(tmp_path, script_runner): command = f"pyhf inspect {'docs/examples/json/2-bin_1-channel.json':s}" ret = script_runner.run(shlex.split(command)) assert ret.success diff --git a/tests/test_infer.py b/tests/test_infer.py index f6a5bc6e92..0ccd072b94 100644 --- a/tests/test_infer.py +++ b/tests/test_infer.py @@ -23,7 +23,7 @@ def check_uniform_type(in_list): ) -def test_toms748_scan(tmpdir, hypotest_args): +def test_toms748_scan(tmp_path, hypotest_args): """ Test the upper limit toms748 scan returns the correct structure and values """ @@ -166,7 +166,7 @@ def test_upper_limit_with_kwargs(hypotest_args): ) -def test_mle_fit_default(tmpdir, hypotest_args): +def test_mle_fit_default(tmp_path, hypotest_args): """ Check that the default return structure of pyhf.infer.mle.fit is as expected """ @@ -180,7 +180,7 @@ def test_mle_fit_default(tmpdir, hypotest_args): assert pyhf.tensorlib.shape(result) == (model.config.npars,) -def test_mle_fit_return_fitted_val(tmpdir, hypotest_args): +def test_mle_fit_return_fitted_val(tmp_path, hypotest_args): """ Check that the return structure of pyhf.infer.mle.fit with the return_fitted_val keyword arg is as expected @@ -196,7 +196,7 @@ def test_mle_fit_return_fitted_val(tmpdir, hypotest_args): assert pyhf.tensorlib.shape(result[1]) == () -def test_hypotest_default(tmpdir, hypotest_args): +def test_hypotest_default(tmp_path, hypotest_args): """ Check that the default return structure of pyhf.infer.hypotest is as expected """ @@ -209,7 +209,7 @@ def test_hypotest_default(tmpdir, hypotest_args): assert isinstance(result, type(tb.astensor(result))) -def test_hypotest_poi_outofbounds(tmpdir, hypotest_args): +def test_hypotest_poi_outofbounds(tmp_path, hypotest_args): """ Check that the fit errors for POI outside of parameter bounds """ @@ -226,7 +226,7 @@ def test_hypotest_poi_outofbounds(tmpdir, hypotest_args): @pytest.mark.parametrize('test_stat', ['q0', 'q', 'qtilde']) -def test_hypotest_return_tail_probs(tmpdir, hypotest_args, test_stat): +def test_hypotest_return_tail_probs(tmp_path, hypotest_args, test_stat): """ Check that the return structure of pyhf.infer.hypotest with the return_tail_probs keyword arg is as expected @@ -243,7 +243,7 @@ def test_hypotest_return_tail_probs(tmpdir, hypotest_args, test_stat): @pytest.mark.parametrize('test_stat', ['q0', 'q', 'qtilde']) -def test_hypotest_return_expected(tmpdir, hypotest_args, test_stat): +def test_hypotest_return_expected(tmp_path, hypotest_args, test_stat): """ Check that the return structure of pyhf.infer.hypotest with the addition of the return_expected keyword arg is as expected @@ -265,7 +265,7 @@ def test_hypotest_return_expected(tmpdir, hypotest_args, test_stat): @pytest.mark.parametrize('test_stat', ['q0', 'q', 'qtilde']) -def test_hypotest_return_expected_set(tmpdir, hypotest_args, test_stat): +def test_hypotest_return_expected_set(tmp_path, hypotest_args, test_stat): """ Check that the return structure of pyhf.infer.hypotest with the addition of the return_expected_set keyword arg is as expected @@ -300,7 +300,7 @@ def test_hypotest_return_expected_set(tmpdir, hypotest_args, test_stat): @pytest.mark.parametrize('return_expected', [True, False]) @pytest.mark.parametrize('return_expected_set', [True, False]) def test_hypotest_return_calculator( - tmpdir, + tmp_path, hypotest_args, calctype, kwargs, @@ -491,7 +491,7 @@ def test_significance_to_pvalue_roundtrip(backend): assert np.allclose(sigma, back_to_sigma, atol=0, rtol=rtol) -def test_emperical_distribution(tmpdir, hypotest_args): +def test_emperical_distribution(tmp_path, hypotest_args): """ Check that the empirical distribution of the test statistic gives expected results @@ -537,7 +537,7 @@ def test_emperical_distribution(tmpdir, hypotest_args): ) -def test_toy_calculator(tmpdir, hypotest_args): +def test_toy_calculator(tmp_path, hypotest_args): """ Check that the toy calculator is performing as expected """ diff --git a/tests/test_notebooks.py b/tests/test_notebooks.py index 07b978c2ff..bc005f2201 100644 --- a/tests/test_notebooks.py +++ b/tests/test_notebooks.py @@ -11,8 +11,8 @@ @pytest.fixture() -def common_kwargs(tmpdir): - outputnb = tmpdir.join('output.ipynb') +def common_kwargs(tmp_path): + outputnb = tmp_path.joinpath('output.ipynb') return { 'output_path': str(outputnb), 'kernel_name': f'python{sys.version_info.major}', diff --git a/tests/test_scripts.py b/tests/test_scripts.py index 0dd88e9b8a..9d00814c8e 100644 --- a/tests/test_scripts.py +++ b/tests/test_scripts.py @@ -5,7 +5,6 @@ import tarfile import time from importlib import import_module, reload -from pathlib import Path from unittest import mock import pytest @@ -15,16 +14,14 @@ @pytest.fixture(scope="function") -def tarfile_path(tmpdir): - with open( - tmpdir.join("test_file.txt").strpath, "w", encoding="utf-8" - ) as write_file: +def tarfile_path(tmp_path): + with open(tmp_path.joinpath("test_file.txt"), "w", encoding="utf-8") as write_file: write_file.write("test file") with tarfile.open( - tmpdir.join("test_tar.tar.gz").strpath, mode="w:gz", encoding="utf-8" + tmp_path.joinpath("test_tar.tar.gz"), mode="w:gz", encoding="utf-8" ) as archive: - archive.add(tmpdir.join("test_file.txt").strpath) - return Path(tmpdir.join("test_tar.tar.gz").strpath) + archive.add(tmp_path.joinpath("test_file.txt")) + return tmp_path.joinpath("test_tar.tar.gz") def test_version(script_runner): @@ -57,29 +54,29 @@ def test_citation(script_runner, flag): # see test_import.py for the same (detailed) test -def test_import_prepHistFactory(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_import_prepHistFactory(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) assert ret.success assert ret.stdout == '' assert ret.stderr == '' - parsed_xml = json.loads(temp.read()) + parsed_xml = json.loads(temp.read_text()) spec = {'channels': parsed_xml['channels']} pyhf.schema.validate(spec, 'model.json') -def test_import_prepHistFactory_withProgress(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_import_prepHistFactory_withProgress(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) assert ret.success assert ret.stdout == '' assert ret.stderr != '' -def test_import_prepHistFactory_stdout(tmpdir, script_runner): +def test_import_prepHistFactory_stdout(tmp_path, script_runner): command = 'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/' ret = script_runner.run(shlex.split(command)) assert ret.success @@ -89,12 +86,12 @@ def test_import_prepHistFactory_stdout(tmpdir, script_runner): assert d -def test_import_prepHistFactory_and_fit(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f"pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}" +def test_import_prepHistFactory_and_fit(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f"pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}" ret = script_runner.run(shlex.split(command)) - command = f"pyhf fit {temp.strpath:s}" + command = f"pyhf fit {temp}" ret = script_runner.run(shlex.split(command)) assert ret.success @@ -109,7 +106,7 @@ def test_import_prepHistFactory_and_fit(tmpdir, script_runner): "LogNormExample", "ConstExample", ]: - command = f"pyhf fit {temp.strpath:s} --value --measurement {measurement:s}" + command = f"pyhf fit {temp} --value --measurement {measurement:s}" ret = script_runner.run(shlex.split(command)) assert ret.success @@ -118,22 +115,22 @@ def test_import_prepHistFactory_and_fit(tmpdir, script_runner): assert "mle_parameters" in ret_json assert "twice_nll" in ret_json - tmp_out = tmpdir.join(f"{measurement:s}_output.json") + tmp_out = tmp_path.joinpath(f"{measurement:s}_output.json") # make sure output file works too - command += f" --output-file {tmp_out.strpath:s}" + command += f" --output-file {tmp_out}" ret = script_runner.run(shlex.split(command)) assert ret.success - ret_json = json.load(tmp_out) + ret_json = json.load(tmp_out.open()) assert "mle_parameters" in ret_json assert "twice_nll" in ret_json -def test_import_prepHistFactory_and_cls(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_import_prepHistFactory_and_cls(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) - command = f'pyhf cls {temp.strpath:s}' + command = f'pyhf cls {temp}' ret = script_runner.run(shlex.split(command)) assert ret.success @@ -148,7 +145,7 @@ def test_import_prepHistFactory_and_cls(tmpdir, script_runner): 'LogNormExample', 'ConstExample', ]: - command = f'pyhf cls {temp.strpath:s} --measurement {measurement:s}' + command = f'pyhf cls {temp} --measurement {measurement:s}' ret = script_runner.run(shlex.split(command)) assert ret.success @@ -157,37 +154,37 @@ def test_import_prepHistFactory_and_cls(tmpdir, script_runner): assert 'CLs_obs' in d assert 'CLs_exp' in d - tmp_out = tmpdir.join(f'{measurement:s}_output.json') + tmp_out = tmp_path.joinpath(f'{measurement:s}_output.json') # make sure output file works too - command += f' --output-file {tmp_out.strpath:s}' + command += f' --output-file {tmp_out}' ret = script_runner.run(shlex.split(command)) assert ret.success - d = json.load(tmp_out) + d = json.load(tmp_out.open()) assert 'CLs_obs' in d assert 'CLs_exp' in d -def test_import_usingMounts(datadir, tmpdir, script_runner): +def test_import_usingMounts(datadir, tmp_path, script_runner): data = datadir.joinpath("xmlimport_absolutePaths") - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json --hide-progress -v {data}:/absolute/path/to -v {data}:/another/absolute/path/to --output-file {temp.strpath:s} {data.joinpath("config/example.xml")}' + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json --hide-progress -v {data}:/absolute/path/to -v {data}:/another/absolute/path/to --output-file {temp} {data.joinpath("config/example.xml")}' ret = script_runner.run(shlex.split(command)) assert ret.success assert ret.stdout == '' assert ret.stderr == '' - parsed_xml = json.loads(temp.read()) + parsed_xml = json.loads(temp.read_text()) spec = {'channels': parsed_xml['channels']} pyhf.schema.validate(spec, 'model.json') -def test_import_usingMounts_badDelimitedPaths(datadir, tmpdir, script_runner): +def test_import_usingMounts_badDelimitedPaths(datadir, tmp_path, script_runner): data = datadir.joinpath("xmlimport_absolutePaths") - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json --hide-progress -v {data}::/absolute/path/to -v {data}/another/absolute/path/to --output-file {temp.strpath:s} {data.joinpath("config/example.xml")}' + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json --hide-progress -v {data}::/absolute/path/to -v {data}/another/absolute/path/to --output-file {temp} {data.joinpath("config/example.xml")}' ret = script_runner.run(shlex.split(command)) assert not ret.success @@ -196,12 +193,12 @@ def test_import_usingMounts_badDelimitedPaths(datadir, tmpdir, script_runner): @pytest.mark.parametrize("backend", ["numpy", "tensorflow", "pytorch", "jax"]) -def test_fit_backend_option(tmpdir, script_runner, backend): - temp = tmpdir.join("parsed_output.json") - command = f"pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}" +def test_fit_backend_option(tmp_path, script_runner, backend): + temp = tmp_path.joinpath("parsed_output.json") + command = f"pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}" ret = script_runner.run(shlex.split(command)) - command = f"pyhf fit --backend {backend:s} {temp.strpath:s}" + command = f"pyhf fit --backend {backend:s} {temp}" ret = script_runner.run(shlex.split(command)) assert ret.success @@ -211,12 +208,12 @@ def test_fit_backend_option(tmpdir, script_runner, backend): @pytest.mark.parametrize("backend", ["numpy", "tensorflow", "pytorch", "jax"]) -def test_cls_backend_option(tmpdir, script_runner, backend): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_cls_backend_option(tmp_path, script_runner, backend): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) - command = f'pyhf cls --backend {backend:s} {temp.strpath:s}' + command = f'pyhf cls --backend {backend:s} {temp}' ret = script_runner.run(shlex.split(command)) assert ret.success @@ -226,86 +223,98 @@ def test_cls_backend_option(tmpdir, script_runner, backend): assert 'CLs_exp' in d -def test_import_and_export(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_import_and_export(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) - command = f"pyhf json2xml {temp.strpath:s} --output-dir {tmpdir.mkdir('output').strpath:s}" + output_dir_path = tmp_path / "output" + output_dir_path.mkdir() + + command = f"pyhf json2xml {temp} --output-dir {output_dir_path}" ret = script_runner.run(shlex.split(command)) assert ret.success -def test_patch(tmpdir, script_runner): - patch = tmpdir.join('patch.json') +def test_patch(tmp_path, script_runner): + patch = tmp_path.joinpath('patch.json') - patch.write( + patch.write_text( ''' [{"op": "replace", "path": "/channels/0/samples/0/data", "value": [5,6]}] ''' ) - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) - command = f'pyhf cls {temp.strpath:s} --patch {patch.strpath:s}' + command = f'pyhf cls {temp} --patch {patch}' ret = script_runner.run(shlex.split(command)) assert ret.success - command = f"pyhf json2xml {temp.strpath:s} --output-dir {tmpdir.mkdir('output_1').strpath:s} --patch {patch.strpath:s}" + output_dir_path = tmp_path / "output_1" + output_dir_path.mkdir(exist_ok=True) + + command = f"pyhf json2xml {temp} --output-dir {output_dir_path} --patch {patch}" ret = script_runner.run(shlex.split(command)) assert ret.success - command = f'pyhf cls {temp.strpath:s} --patch -' + command = f'pyhf cls {temp} --patch -' - ret = script_runner.run(shlex.split(command), stdin=patch) + ret = script_runner.run(shlex.split(command), stdin=patch.open()) assert ret.success - command = f"pyhf json2xml {temp.strpath:s} --output-dir {tmpdir.mkdir('output_2').strpath:s} --patch -" - ret = script_runner.run(shlex.split(command), stdin=patch) + output_dir_path = tmp_path / "output_2" + output_dir_path.mkdir(exist_ok=True) + + command = f"pyhf json2xml {temp} --output-dir {output_dir_path} --patch -" + ret = script_runner.run(shlex.split(command), stdin=patch.open()) assert ret.success -def test_patch_fail(tmpdir, script_runner): - patch = tmpdir.join('patch.json') +def test_patch_fail(tmp_path, script_runner): + patch = tmp_path.joinpath('patch.json') - patch.write('''not,json''') + patch.write_text('''not,json''') - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) - command = f'pyhf cls {temp.strpath:s} --patch {patch.strpath:s}' + command = f'pyhf cls {temp} --patch {patch}' ret = script_runner.run(shlex.split(command)) assert not ret.success - command = f"pyhf json2xml {temp.strpath:s} --output-dir {tmpdir.mkdir('output').strpath:s} --patch {patch.strpath:s}" + output_dir_path = tmp_path / "output" + output_dir_path.mkdir() + + command = f"pyhf json2xml {temp} --output-dir {output_dir_path} --patch {patch}" ret = script_runner.run(shlex.split(command)) assert not ret.success -def test_bad_measurement_name(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_bad_measurement_name(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) - command = f'pyhf cls {temp.strpath:s} --measurement "a-fake-measurement-name"' + command = f'pyhf cls {temp} --measurement "a-fake-measurement-name"' ret = script_runner.run(shlex.split(command)) assert not ret.success # assert 'no measurement by name' in ret.stderr # numpy swallows the log.error() here, dunno why -def test_testpoi(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_testpoi(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) pois = [1.0, 0.5, 0.001] results_exp = [] results_obs = [] for test_poi in pois: - command = f'pyhf cls {temp.strpath:s} --test-poi {test_poi:f}' + command = f'pyhf cls {temp} --test-poi {test_poi:f}' ret = script_runner.run(shlex.split(command)) assert ret.success @@ -331,13 +340,13 @@ def test_testpoi(tmpdir, script_runner): @pytest.mark.parametrize( "opts,success", [(["maxiter=1000"], True), (["maxiter=1"], False)] ) -def test_fit_optimizer(tmpdir, script_runner, optimizer, opts, success): - temp = tmpdir.join("parsed_output.json") - command = f"pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}" +def test_fit_optimizer(tmp_path, script_runner, optimizer, opts, success): + temp = tmp_path.joinpath("parsed_output.json") + command = f"pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}" ret = script_runner.run(shlex.split(command)) optconf = " ".join(f"--optconf {opt}" for opt in opts) - command = f"pyhf fit --optimizer {optimizer} {optconf} {temp.strpath}" + command = f"pyhf fit --optimizer {optimizer} {optconf} {temp}" ret = script_runner.run(shlex.split(command)) assert ret.success == success @@ -347,39 +356,39 @@ def test_fit_optimizer(tmpdir, script_runner, optimizer, opts, success): @pytest.mark.parametrize( 'opts,success', [(['maxiter=1000'], True), (['maxiter=1'], False)] ) -def test_cls_optimizer(tmpdir, script_runner, optimizer, opts, success): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s}' +def test_cls_optimizer(tmp_path, script_runner, optimizer, opts, success): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp}' ret = script_runner.run(shlex.split(command)) optconf = " ".join(f"--optconf {opt}" for opt in opts) - command = f'pyhf cls {temp.strpath} --optimizer {optimizer} {optconf}' + command = f'pyhf cls {temp} --optimizer {optimizer} {optconf}' ret = script_runner.run(shlex.split(command)) assert ret.success == success -def test_inspect(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_inspect(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - command = f'pyhf inspect {temp.strpath:s}' + command = f'pyhf inspect {temp}' ret = script_runner.run(shlex.split(command)) assert ret.success -def test_inspect_outfile(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_inspect_outfile(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - tempout = tmpdir.join("inspect_output.json") - command = f'pyhf inspect {temp.strpath:s} --output-file {tempout.strpath:s}' + tempout = tmp_path.joinpath("inspect_output.json") + command = f'pyhf inspect {temp} --output-file {tempout}' ret = script_runner.run(shlex.split(command)) assert ret.success - summary = json.loads(tempout.read()) + summary = json.loads(tempout.read_text()) assert [ 'channels', 'measurements', @@ -396,65 +405,63 @@ def test_inspect_outfile(tmpdir, script_runner): assert len(summary['systematics']) == 6 -def test_prune(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_prune(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - command = ( - f"pyhf prune -m staterror_channel1 --measurement GammaExample {temp.strpath:s}" - ) + command = f"pyhf prune -m staterror_channel1 --measurement GammaExample {temp}" ret = script_runner.run(shlex.split(command)) assert ret.success -def test_prune_outfile(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_prune_outfile(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - tempout = tmpdir.join("prune_output.json") - command = f'pyhf prune -m staterror_channel1 --measurement GammaExample {temp.strpath:s} --output-file {tempout.strpath:s}' + tempout = tmp_path.joinpath("prune_output.json") + command = f'pyhf prune -m staterror_channel1 --measurement GammaExample {temp} --output-file {tempout}' ret = script_runner.run(shlex.split(command)) assert ret.success - spec = json.loads(temp.read()) + spec = json.loads(temp.read_text()) ws = pyhf.Workspace(spec) assert 'GammaExample' in ws.measurement_names assert 'staterror_channel1' in ws.model().config.parameters - pruned_spec = json.loads(tempout.read()) + pruned_spec = json.loads(tempout.read_text()) pruned_ws = pyhf.Workspace(pruned_spec) assert 'GammaExample' not in pruned_ws.measurement_names assert 'staterror_channel1' not in pruned_ws.model().config.parameters -def test_rename(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_rename(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - command = f'pyhf rename -m staterror_channel1 staterror_channelone --measurement GammaExample GamEx {temp.strpath:s}' + command = f'pyhf rename -m staterror_channel1 staterror_channelone --measurement GammaExample GamEx {temp}' ret = script_runner.run(shlex.split(command)) assert ret.success -def test_rename_outfile(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_rename_outfile(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - tempout = tmpdir.join("rename_output.json") - command = f'pyhf rename -m staterror_channel1 staterror_channelone --measurement GammaExample GamEx {temp.strpath:s} --output-file {tempout.strpath:s}' + tempout = tmp_path.joinpath("rename_output.json") + command = f'pyhf rename -m staterror_channel1 staterror_channelone --measurement GammaExample GamEx {temp} --output-file {tempout}' ret = script_runner.run(shlex.split(command)) assert ret.success - spec = json.loads(temp.read()) + spec = json.loads(temp.read_text()) ws = pyhf.Workspace(spec) assert 'GammaExample' in ws.measurement_names assert 'GamEx' not in ws.measurement_names assert 'staterror_channel1' in ws.model().config.parameters assert 'staterror_channelone' not in ws.model().config.parameters - renamed_spec = json.loads(tempout.read()) + renamed_spec = json.loads(tempout.read_text()) renamed_ws = pyhf.Workspace(renamed_spec) assert 'GammaExample' not in renamed_ws.measurement_names assert 'GamEx' in renamed_ws.measurement_names @@ -462,10 +469,10 @@ def test_rename_outfile(tmpdir, script_runner): assert 'staterror_channelone' in renamed_ws.model().config.parameters -def test_combine(tmpdir, script_runner): - temp_1 = tmpdir.join("parsed_output.json") - temp_2 = tmpdir.join("renamed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp_1.strpath:s} --hide-progress' +def test_combine(tmp_path, script_runner): + temp_1 = tmp_path.joinpath("parsed_output.json") + temp_2 = tmp_path.joinpath("renamed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp_1} --hide-progress' ret = script_runner.run(shlex.split(command)) rename_channels = {'channel1': 'channel2'} @@ -482,18 +489,18 @@ def test_combine(tmpdir, script_runner): _opts_measurements = ''.join( ' --measurement ' + ' '.join(item) for item in rename_measurements.items() ) - command = f"pyhf rename {temp_1.strpath:s} {_opts_channels:s} {_opts_measurements:s} --output-file {temp_2.strpath:s}" + command = f"pyhf rename {temp_1} {_opts_channels:s} {_opts_measurements:s} --output-file {temp_2}" ret = script_runner.run(shlex.split(command)) - command = f'pyhf combine {temp_1.strpath:s} {temp_2.strpath:s}' + command = f'pyhf combine {temp_1} {temp_2}' ret = script_runner.run(shlex.split(command)) assert ret.success -def test_combine_outfile(tmpdir, script_runner): - temp_1 = tmpdir.join("parsed_output.json") - temp_2 = tmpdir.join("renamed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp_1.strpath:s} --hide-progress' +def test_combine_outfile(tmp_path, script_runner): + temp_1 = tmp_path.joinpath("parsed_output.json") + temp_2 = tmp_path.joinpath("renamed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp_1} --hide-progress' ret = script_runner.run(shlex.split(command)) rename_channels = {'channel1': 'channel2'} @@ -510,35 +517,33 @@ def test_combine_outfile(tmpdir, script_runner): _opts_measurements = ''.join( ' --measurement ' + ' '.join(item) for item in rename_measurements.items() ) - command = f"pyhf rename {temp_1.strpath:s} {_opts_channels:s} {_opts_measurements:s} --output-file {temp_2.strpath:s}" + command = f"pyhf rename {temp_1} {_opts_channels:s} {_opts_measurements:s} --output-file {temp_2}" ret = script_runner.run(shlex.split(command)) - tempout = tmpdir.join("combined_output.json") - command = f'pyhf combine {temp_1.strpath:s} {temp_2.strpath:s} --output-file {tempout.strpath:s}' + tempout = tmp_path.joinpath("combined_output.json") + command = f'pyhf combine {temp_1} {temp_2} --output-file {tempout}' ret = script_runner.run(shlex.split(command)) assert ret.success - combined_spec = json.loads(tempout.read()) + combined_spec = json.loads(tempout.read_text()) combined_ws = pyhf.Workspace(combined_spec) assert combined_ws.channels == ['channel1', 'channel2'] assert len(combined_ws.measurement_names) == 8 -def test_combine_merge_channels(tmpdir, script_runner): - temp_1 = tmpdir.join("parsed_output.json") - temp_2 = tmpdir.join("renamed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp_1.strpath} --hide-progress' +def test_combine_merge_channels(tmp_path, script_runner): + temp_1 = tmp_path.joinpath("parsed_output.json") + temp_2 = tmp_path.joinpath("renamed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp_1} --hide-progress' ret = script_runner.run(shlex.split(command)) assert ret.success - command = ( - f'pyhf prune {temp_1.strpath} --sample signal --output-file {temp_2.strpath}' - ) + command = f'pyhf prune {temp_1} --sample signal --output-file {temp_2}' ret = script_runner.run(shlex.split(command)) assert ret.success - command = f'pyhf combine --merge-channels --join "left outer" {temp_1.strpath} {temp_2.strpath}' + command = f'pyhf combine --merge-channels --join "left outer" {temp_1} {temp_2}' ret = script_runner.run(shlex.split(command)) assert ret.success @@ -547,17 +552,19 @@ def test_combine_merge_channels(tmpdir, script_runner): @pytest.mark.parametrize( 'algorithms', [['md5'], ['sha256'], ['sha256', 'md5'], ['sha256', 'md5']] ) -def test_workspace_digest(tmpdir, script_runner, algorithms, do_json): +def test_workspace_digest(tmp_path, script_runner, algorithms, do_json): results = { 'md5': '7de8930ff37e5a4f6a31da11bda7813f', 'sha256': '6d416ee67a40460499ea2ef596fb1e682a563d7df06e690018a211d35238aecc', } - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath} --hide-progress' + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - command = f"pyhf digest {temp.strpath} -a {' -a '.join(algorithms)}{' -j' if do_json else ''}" + command = ( + f"pyhf digest {temp} -a {' -a '.join(algorithms)}{' -j' if do_json else ''}" + ) ret = script_runner.run(shlex.split(command)) assert ret.success assert all(algorithm in ret.stdout for algorithm in algorithms) @@ -588,21 +595,23 @@ def test_workspace_digest(tmpdir, script_runner, algorithms, do_json): "https://doi.org/10.17182/hepdata.89408.v1/r2", ], ) -def test_patchset_download(tmpdir, script_runner, requests_mock, tarfile_path, archive): +def test_patchset_download( + tmp_path, script_runner, requests_mock, tarfile_path, archive +): requests_mock.get(archive, content=open(tarfile_path, "rb").read()) - command = f'pyhf contrib download {archive} {tmpdir.join("likelihoods").strpath}' + command = f'pyhf contrib download {archive} {tmp_path.joinpath("likelihoods")}' ret = script_runner.run(shlex.split(command)) assert ret.success # Run with all optional flags - command = f'pyhf contrib download --verbose --force {archive} {tmpdir.join("likelihoods").strpath}' + command = f'pyhf contrib download --verbose --force {archive} {tmp_path.joinpath("likelihoods")}' ret = script_runner.run(shlex.split(command)) assert ret.success requests_mock.get( "https://www.pyhfthisdoesnotexist.org/record/resource/1234567", status_code=200 ) - command = f'pyhf contrib download --verbose https://www.pyhfthisdoesnotexist.org/record/resource/1234567 {tmpdir.join("likelihoods").strpath}' + command = f'pyhf contrib download --verbose https://www.pyhfthisdoesnotexist.org/record/resource/1234567 {tmp_path.joinpath("likelihoods")}' ret = script_runner.run(shlex.split(command)) assert not ret.success assert ( @@ -614,7 +623,7 @@ def test_patchset_download(tmpdir, script_runner, requests_mock, tarfile_path, a requests_mock.get( "https://httpstat.us/404/record/resource/1234567", status_code=404 ) - command = f'pyhf contrib download --verbose --force https://httpstat.us/404/record/resource/1234567 {tmpdir.join("likelihoods").strpath}' + command = f'pyhf contrib download --verbose --force https://httpstat.us/404/record/resource/1234567 {tmp_path.joinpath("likelihoods")}' ret = script_runner.run(shlex.split(command)) assert not ret.success assert "gives a response code of 404" in ret.stderr @@ -686,11 +695,11 @@ def test_patchset_inspect(datadir, script_runner): @pytest.mark.parametrize('output_file', [False, True]) @pytest.mark.parametrize('with_metadata', [False, True]) -def test_patchset_extract(datadir, tmpdir, script_runner, output_file, with_metadata): - temp = tmpdir.join("extracted_output.json") +def test_patchset_extract(datadir, tmp_path, script_runner, output_file, with_metadata): + temp = tmp_path.joinpath("extracted_output.json") command = f'pyhf patchset extract {datadir.joinpath("example_patchset.json")} --name patch_channel1_signal_syst1' if output_file: - command += f" --output-file {temp.strpath}" + command += f" --output-file {temp}" if with_metadata: command += " --with-metadata" @@ -698,7 +707,7 @@ def test_patchset_extract(datadir, tmpdir, script_runner, output_file, with_meta assert ret.success if output_file: - extracted_output = json.loads(temp.read()) + extracted_output = json.loads(temp.read_text()) else: extracted_output = json.loads(ret.stdout) if with_metadata: @@ -721,17 +730,17 @@ def test_patchset_verify(datadir, script_runner): @pytest.mark.parametrize('output_file', [False, True]) -def test_patchset_apply(datadir, tmpdir, script_runner, output_file): - temp = tmpdir.join("patched_output.json") +def test_patchset_apply(datadir, tmp_path, script_runner, output_file): + temp = tmp_path.joinpath("patched_output.json") command = f'pyhf patchset apply {datadir.joinpath("example_bkgonly.json")} {datadir.joinpath("example_patchset.json")} --name patch_channel1_signal_syst1' if output_file: - command += f" --output-file {temp.strpath}" + command += f" --output-file {temp}" ret = script_runner.run(shlex.split(command)) assert ret.success if output_file: - extracted_output = json.loads(temp.read()) + extracted_output = json.loads(temp.read_text()) else: extracted_output = json.loads(ret.stdout) assert extracted_output['channels'][0]['samples'][0]['modifiers'][0]['data'] == { @@ -740,24 +749,24 @@ def test_patchset_apply(datadir, tmpdir, script_runner, output_file): } -def test_sort(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_sort(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - command = f'pyhf sort {temp.strpath}' + command = f'pyhf sort {temp}' ret = script_runner.run(shlex.split(command)) assert ret.success -def test_sort_outfile(tmpdir, script_runner): - temp = tmpdir.join("parsed_output.json") - command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp.strpath:s} --hide-progress' +def test_sort_outfile(tmp_path, script_runner): + temp = tmp_path.joinpath("parsed_output.json") + command = f'pyhf xml2json validation/xmlimport_input/config/example.xml --basedir validation/xmlimport_input/ --output-file {temp} --hide-progress' ret = script_runner.run(shlex.split(command)) - tempout = tmpdir.join("sort_output.json") - command = f'pyhf sort {temp.strpath} --output-file {tempout.strpath}' + tempout = tmp_path.joinpath("sort_output.json") + command = f'pyhf sort {temp} --output-file {tempout}' ret = script_runner.run(shlex.split(command)) assert ret.success From d3b1cdbcba46618358a9b2d5207757be742e5cdc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 09:29:53 +0100 Subject: [PATCH 18/62] build(deps): bump pypa/gh-action-pypi-publish from 1.8.10 to 1.8.11 (#2389) Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.8.10 to 1.8.11. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.10...v1.8.11) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/publish-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 187391b1a3..795f34bf72 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -132,13 +132,13 @@ jobs: if: >- (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository == 'scikit-hep/pyhf') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true' && github.repository == 'scikit-hep/pyhf') - uses: pypa/gh-action-pypi-publish@v1.8.10 + uses: pypa/gh-action-pypi-publish@v1.8.11 with: repository-url: https://test.pypi.org/legacy/ print-hash: true - name: Publish distribution 📦 to PyPI if: github.event_name == 'release' && github.event.action == 'published' && github.repository == 'scikit-hep/pyhf' - uses: pypa/gh-action-pypi-publish@v1.8.10 + uses: pypa/gh-action-pypi-publish@v1.8.11 with: print-hash: true From fcc5d48a0144df56902d1bdba3d8389482d6ea7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:14:00 +0100 Subject: [PATCH 19/62] build(deps): bump actions/configure-pages from 3 to 4 (#2387) Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 3 to 4. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index aa744303f6..7f6dd497ad 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -113,7 +113,7 @@ jobs: steps: - name: Setup Pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v4 - name: Deploy to GitHub Pages id: deployment From 8b722c79ce59c873a50f6434190646225983b584 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:46:09 +0100 Subject: [PATCH 20/62] build(deps): bump actions/deploy-pages from 2 to 3 (#2388) Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 2 to 3. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7f6dd497ad..78da096c11 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -117,4 +117,4 @@ jobs: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v3 From b4fec1c35b840508fb9adcfbecedfe0f0e69cb47 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:07:16 +0100 Subject: [PATCH 21/62] chore: [pre-commit.ci] pre-commit autoupdate (#2386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pre-commit hooks: - github.com/psf/black-pre-commit-mirror: 23.10.1 → 23.11.0 - github.com/pre-commit/mirrors-mypy: v1.6.1 → v1.7.1 --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ae20e15066..a5bea1a3c8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: args: ["--fix", "--show-fixes"] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.10.1 + rev: 23.11.0 hooks: - id: black-jupyter types_or: [python, pyi, jupyter] @@ -50,10 +50,10 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==23.10.1] + additional_dependencies: [black==23.11.0] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.1 + rev: v1.7.1 # check the oldest and newest supported Pythons hooks: - &mypy From 4d215a78cc7278299ff552b147c1ff589fee4e18 Mon Sep 17 00:00:00 2001 From: Lorenz Gaertner Date: Thu, 7 Dec 2023 14:57:30 +0100 Subject: [PATCH 22/62] feat: Allow skipping of validation when combining workspaces (#2385) * Add validate arg to workspace.combine to allow for optionally skipping workspace validation during. Default is to validate. * Add test for validate arg being used. * Add Lorenz Gaertner to contributors list. --- docs/contributors.rst | 1 + src/pyhf/workspace.py | 7 +++++-- tests/test_workspace.py | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/contributors.rst b/docs/contributors.rst index c2d0b0a698..d29fd0974b 100644 --- a/docs/contributors.rst +++ b/docs/contributors.rst @@ -33,3 +33,4 @@ Contributors include: - Beojan Stanislaus - Daniel Werner - Jonas Rembser +- Lorenz Gaertner diff --git a/src/pyhf/workspace.py b/src/pyhf/workspace.py index 00abcf77f4..7ce0bc486d 100644 --- a/src/pyhf/workspace.py +++ b/src/pyhf/workspace.py @@ -706,7 +706,9 @@ def rename(self, modifiers=None, samples=None, channels=None, measurements=None) ) @classmethod - def combine(cls, left, right, join='none', merge_channels=False): + def combine( + cls, left, right, join='none', merge_channels=False, validate: bool = True + ): """ Return a new workspace specification that is the combination of the two workspaces. @@ -733,6 +735,7 @@ def combine(cls, left, right, join='none', merge_channels=False): right (~pyhf.workspace.Workspace): Another workspace join (:obj:`str`): How to join the two workspaces. Pick from "none", "outer", "left outer", or "right outer". merge_channels (:obj:`bool`): Whether or not to merge channels when performing the combine. This is only done with "outer", "left outer", and "right outer" options. + validate (:obj:`bool`): Whether to validate against a JSON schema. Returns: ~pyhf.workspace.Workspace: A new combined workspace object @@ -770,7 +773,7 @@ def combine(cls, left, right, join='none', merge_channels=False): 'observations': new_observations, 'version': new_version, } - return cls(newspec) + return cls(newspec, validate=validate) @classmethod def sorted(cls, workspace): diff --git a/tests/test_workspace.py b/tests/test_workspace.py index 55ee0df046..e966d6c3f1 100644 --- a/tests/test_workspace.py +++ b/tests/test_workspace.py @@ -791,6 +791,28 @@ def test_combine_workspace(workspace_factory, join): ) +@pytest.mark.parametrize("join", pyhf.Workspace.valid_joins) +def test_combine_workspace_without_validation(mocker, workspace_factory, join): + ws = workspace_factory() + new_ws = ws.rename( + channels={channel: f"renamed_{channel}" for channel in ws.channels}, + samples={sample: f"renamed_{sample}" for sample in ws.samples}, + modifiers={ + modifier: f"renamed_{modifier}" + for modifier, _ in ws.modifiers + if modifier != "lumi" + }, + measurements={ + measurement: f"renamed_{measurement}" + for measurement in ws.measurement_names + }, + ) + + mocker.patch("pyhf.schema.validate") + pyhf.Workspace.combine(ws, new_ws, join=join, validate=False) + assert pyhf.schema.validate.called is False + + def test_workspace_equality(workspace_factory): ws = workspace_factory() ws_other = workspace_factory() From 079356c65d0cbd614a1e17f0c4f85b0ba24a0354 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 8 Dec 2023 00:50:37 +0100 Subject: [PATCH 23/62] docs: Add November 2023 use and general citations (#2392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add use citation from 'Hadronic Mono-W′ Probes of Dark Matter at Colliders'. - c.f. https://inspirehep.net/literature/2725449 * Add use citation from 'Light New Physics in B→K(∗)νν¯?'. - c.f. https://inspirehep.net/literature/2725980 * Add general citation from 'Monojets reveal overlapping excesses for light compressed higgsinos'. - c.f. https://inspirehep.net/literature/2727900 --- docs/bib/general_citations.bib | 12 ++++++++++++ docs/bib/use_citations.bib | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/docs/bib/general_citations.bib b/docs/bib/general_citations.bib index 3c66d739bf..adb743ada3 100644 --- a/docs/bib/general_citations.bib +++ b/docs/bib/general_citations.bib @@ -1,3 +1,15 @@ +% 2023-11-28 +@article{Agin:2023yoq, + author = "Agin, Diyar and Fuks, Benjamin and Goodsell, Mark D. and Murphy, Taylor", + title = "{Monojets reveal overlapping excesses for light compressed higgsinos}", + eprint = "2311.17149", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + month = "11", + year = "2023", + journal = "" +} + % 2023-10-19 @article{Smith:2023ssh, author = "Smith, Rachel E. C. and Ochoa, In\^es and In\'acio, R\'uben and Shoemaker, Jonathan and Kagan, Michael", diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index e725a32040..5747713e52 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,29 @@ +% 2023-11-24 +@article{Altmannshofer:2023hkn, + author = "Altmannshofer, Wolfgang and Crivellin, Andreas and Haigh, Huw and Inguglia, Gianluca and Martin Camalich, Jorge", + title = "{Light New Physics in $B\to K^{(*)}\nu\bar\nu$?}", + eprint = "2311.14629", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + reportNumber = "PSI-PR-23-46, ZU-TH 77/23", + month = "11", + year = "2023", + journal = "" +} + +% 2023-11-22 +@article{Holder:2023jbt, + author = "Holder, Ryan and Reddick, John and Cremonesi, Matteo and Berry, Doug and Cheng, Kun and Low, Matthew and Tait, Tim M. P. and Whiteson, Daniel", + title = "{Hadronic Mono-$W'$ Probes of Dark Matter at Colliders}", + eprint = "2311.13578", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + reportNumber = "FERMILAB-PUB-23-764-PPD", + month = "11", + year = "2023", + journal = "" +} + % 2023-10-31 @article{Tong:2023lms, author = "Tong, Shelley and Corcoran, James and Fieg, Max and Fenton, Michael and Whiteson, Daniel", From ef7eb33b69f49b25ab6e69e710bd7f5864da6135 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 8 Dec 2023 01:13:13 +0100 Subject: [PATCH 24/62] =?UTF-8?q?docs:=20Add=20use=20citation=20from=20Bel?= =?UTF-8?q?le=20II=20evidence=20for=20B+=E2=86=92K+=CE=BD=CE=BD=C2=AF=20de?= =?UTF-8?q?cays=20paper=20(#2393)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add use citation from 'Evidence for B+→K+νν¯ Decays'. - c.f. https://inspirehep.net/literature/2725943 - Congratulations to the Belle II collaboration on this excellent result! --- docs/bib/use_citations.bib | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 5747713e52..f79f0b53cb 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -11,6 +11,19 @@ @article{Altmannshofer:2023hkn journal = "" } +% 2023-11-24 +@article{Belle-II:2023esi, + author = "Belle II Collaboration", + title = "{Evidence for $B^{+}\to K^{+}\nu\bar{\nu}$ Decays}", + eprint = "2311.14647", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + reportNumber = "Belle II Preprint 2023-017, KEK Preprint 2023-35", + month = "11", + year = "2023", + journal = "" +} + % 2023-11-22 @article{Holder:2023jbt, author = "Holder, Ryan and Reddick, John and Cremonesi, Matteo and Berry, Doug and Cheng, Kun and Low, Matthew and Tait, Tim M. P. and Whiteson, Daniel", From 1191f6676002b26bbd751c1b8e116400baaed25e Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 8 Dec 2023 02:50:54 +0100 Subject: [PATCH 25/62] =?UTF-8?q?docs:=20Add=20use=20citation=20from=20ATL?= =?UTF-8?q?AS=20axion-like=20search=20in=20H->aa->4=CE=B3=20paper=20(#2394?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add use citation from 'Search for short- and long-lived axion-like particles in H→aa→4γ decays with the ATLAS experiment at the LHC'. - ATLAS paper: HDBS-2019-19 - c.f. https://inspirehep.net/literature/2731621 --- docs/bib/use_citations.bib | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index f79f0b53cb..34f672007e 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,16 @@ +% 2023-12-06 +@article{ATLAS:2023ian, + author = "{ATLAS Collaboration}", + title = "{Search for short- and long-lived axion-like particles in $H\rightarrow a a \rightarrow 4\gamma$ decays with the ATLAS experiment at the LHC}", + eprint = "2312.03306", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + reportNumber = "CERN-EP-2023-202", + month = "12", + year = "2023", + journal = "" +} + % 2023-11-24 @article{Altmannshofer:2023hkn, author = "Altmannshofer, Wolfgang and Crivellin, Andreas and Haigh, Huw and Inguglia, Gianluca and Martin Camalich, Jorge", From 6cd2de4bfe0e82e3121e8bea07840c5783413127 Mon Sep 17 00:00:00 2001 From: Lorenz Gaertner Date: Fri, 8 Dec 2023 11:48:56 +0100 Subject: [PATCH 26/62] feat: Improve warnings for qmu and qmu_tilde for the set POI bounds (#2390) * Add information to the user in the warning that provides them with the higher level pyhf.infer APIs kwarg to set the correct test statistic. --- src/pyhf/infer/test_statistics.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pyhf/infer/test_statistics.py b/src/pyhf/infer/test_statistics.py index 3af773d42c..cf11e09c86 100644 --- a/src/pyhf/infer/test_statistics.py +++ b/src/pyhf/infer/test_statistics.py @@ -134,7 +134,8 @@ def qmu(mu, data, pdf, init_pars, par_bounds, fixed_params, return_fitted_pars=F if par_bounds[pdf.config.poi_index][0] == 0: log.warning( 'qmu test statistic used for fit configuration with POI bounded at zero.\n' - + 'Use the qmu_tilde test statistic (pyhf.infer.test_statistics.qmu_tilde) instead.' + + 'Use the qmu_tilde test statistic (pyhf.infer.test_statistics.qmu_tilde) instead.\n' + + 'If you called this from pyhf.infer.mle or pyhf.infer.hypotest, set test_stat="qtilde".' ) return _qmu_like( mu, @@ -229,7 +230,8 @@ def qmu_tilde( if par_bounds[pdf.config.poi_index][0] != 0: log.warning( 'qmu_tilde test statistic used for fit configuration with POI not bounded at zero.\n' - + 'Use the qmu test statistic (pyhf.infer.test_statistics.qmu) instead.' + + 'Use the qmu test statistic (pyhf.infer.test_statistics.qmu) instead.\n' + + 'If you called this from pyhf.infer.mle or pyhf.infer.hypotest, set test_stat="q".' ) return _qmu_like( mu, From cb8359013debbe0c36c5d7df759af45f0b1c1b2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:55:15 +0100 Subject: [PATCH 27/62] build(deps): bump actions/setup-python from 4 to 5 (#2400) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/bump-version.yml | 2 +- .github/workflows/ci-windows.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/dependencies-head.yml | 12 ++++++------ .github/workflows/docs.yml | 2 +- .github/workflows/lower-bound-requirements.yml | 2 +- .github/workflows/notebooks.yml | 2 +- .github/workflows/publish-package.yml | 2 +- .github/workflows/release_tests.yml | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 607db63612..3f4d4cb074 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -198,7 +198,7 @@ jobs: - name: Set up Python 3.11 if: success() - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml index bd26b06053..d2d7f3c792 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f61c5fb95..857804bb2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/dependencies-head.yml b/.github/workflows/dependencies-head.yml index a213e2052c..fc5e16c1f3 100644 --- a/.github/workflows/dependencies-head.yml +++ b/.github/workflows/dependencies-head.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -53,7 +53,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -82,7 +82,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -108,7 +108,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -134,7 +134,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -170,7 +170,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 78da096c11..47cd419425 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -22,7 +22,7 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' diff --git a/.github/workflows/lower-bound-requirements.yml b/.github/workflows/lower-bound-requirements.yml index 69f0937e8f..96b5c6a3d8 100644 --- a/.github/workflows/lower-bound-requirements.yml +++ b/.github/workflows/lower-bound-requirements.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/notebooks.yml b/.github/workflows/notebooks.yml index bc4c817efe..e961de6f56 100644 --- a/.github/workflows/notebooks.yml +++ b/.github/workflows/notebooks.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 795f34bf72..fac33a96ce 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -37,7 +37,7 @@ jobs: fetch-depth: 0 - name: Set up Python 3.11 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' diff --git a/.github/workflows/release_tests.yml b/.github/workflows/release_tests.yml index 7fbbe46828..85034114c9 100644 --- a/.github/workflows/release_tests.yml +++ b/.github/workflows/release_tests.yml @@ -27,7 +27,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From 836c7ae3c13f4ea85d6073ce3b40a6dce6656ba2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 00:45:18 -0600 Subject: [PATCH 28/62] build(deps): bump github/codeql-action from 2 to 3 (#2405) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8319caaeb3..7d680f58d3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,7 +26,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: python # If you wish to specify custom queries, you can do so here or in a config file. @@ -35,4 +35,4 @@ jobs: # queries: ./path/to/local/query, your-org/your-repo/queries@main - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From 9a0d285f0e8c95abff949cb892606721f830f6ab Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 19 Dec 2023 01:39:58 -0600 Subject: [PATCH 29/62] docs: Add use citation from right-handed charged gauge bosons paper (#2406) * Add use citation from 'A novel search strategy for right-handed charged gauge bosons at the Large Hadron Collider'. - c.f. https://inspirehep.net/literature/2737265 --- docs/bib/use_citations.bib | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 34f672007e..792a993753 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,16 @@ +% 2023-12-13 +@article{Frank:2023epx, + author = "Frank, Mariana and Fuks, Benjamin and Jueid, Adil and Moretti, Stefano and Ozdal, Ozer", + title = "{A novel search strategy for right-handed charged gauge bosons at the Large Hadron Collider}", + eprint = "2312.08521", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + reportNumber = "CTPU-PTC-23-43", + month = "12", + year = "2023", + journal = "" +} + % 2023-12-06 @article{ATLAS:2023ian, author = "{ATLAS Collaboration}", From 6cbdeb051bd82b9303acd7d9df56a78245c7aa2c Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 22 Dec 2023 03:21:57 -0600 Subject: [PATCH 30/62] docs: Add use citation from HH at HL-LHC paper (#2407) * Add use citation from 'Double Higgs production at the HL-LHC: probing a loop-enhanced model with kinematical distributions'. - c.f. https://inspirehep.net/literature/2739283 --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 792a993753..999f13a6aa 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2023-12-20 +@article{DaRold:2023hst, + author = "Da Rold, Leandro and Epele, Manuel and Medina, Anibal D. and Mileo, Nicol\'as I. and Szynkman, Alejandro", + title = "{Double Higgs production at the HL-LHC: probing a loop-enhanced model with kinematical distributions}", + eprint = "2312.13149", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + month = "12", + year = "2023", + journal = "" +} + % 2023-12-13 @article{Frank:2023epx, author = "Frank, Mariana and Fuks, Benjamin and Jueid, Adil and Moretti, Stefano and Ozdal, Ozer", From 81d858ccb0880c5b98dd3f69662e279da863a83d Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 22 Dec 2023 03:41:37 -0600 Subject: [PATCH 31/62] docs: Add use citation from dark-trident MicroBooNE paper (#2408) * Add use citation from 'First search for dark-trident processes using the MicroBooNE detector'. - c.f. https://inspirehep.net/literature/2739832 --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 999f13a6aa..dde3ab948e 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2023-12-21 +@article{MicroBooNE:2023sds, + author = "{MicroBooNE Collaboration}", + title = "{First search for dark-trident processes using the MicroBooNE detector}", + eprint = "2312.13945", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + month = "12", + year = "2023", + journal = "" +} + % 2023-12-20 @article{DaRold:2023hst, author = "Da Rold, Leandro and Epele, Manuel and Medina, Anibal D. and Mileo, Nicol\'as I. and Szynkman, Alejandro", From 0b1a379bbf4762db5a137002370f2bea560c4bcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 10:35:05 -0600 Subject: [PATCH 32/62] build(deps): bump actions/download-artifact from 3 to 4 (#2403) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index fac33a96ce..2f5b418cd6 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -118,7 +118,7 @@ jobs: steps: - name: Download distribution artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: dist-artifact path: dist From ccb7984b8a4311d3f79d89a7d095b953a520a710 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:20:16 -0600 Subject: [PATCH 33/62] build(deps): bump actions/upload-artifact from 3 to 4 (#2404) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/publish-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 2f5b418cd6..c45d90d53e 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -98,7 +98,7 @@ jobs: run: python -m zipfile --list dist/pyhf-*.whl - name: Upload distribution artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: dist-artifact path: dist From 2fa2c94ef38be57890ee1a7e7dd4716860df9e46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:46:10 -0600 Subject: [PATCH 34/62] build(deps): bump actions/upload-pages-artifact from 2 to 3 (#2410) Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 47cd419425..8580daabe6 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -91,7 +91,7 @@ jobs: done - name: Upload artifact - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 with: path: 'docs/_build/html' From bc79c8cc2d61ad2e1c428a06e49f0d7e3b98c5dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 15:01:41 -0600 Subject: [PATCH 35/62] build(deps): bump actions/deploy-pages from 3 to 4 (#2409) Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 3 to 4. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8580daabe6..5af25f1632 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -117,4 +117,4 @@ jobs: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v3 + uses: actions/deploy-pages@v4 From 45517d59bfedf8820c990c50e56fd4cae149fb0a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 15:18:34 -0600 Subject: [PATCH 36/62] chore: [pre-commit.ci] pre-commit autoupdate (#2412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pre-commit hooks: - github.com/astral-sh/ruff-pre-commit: v0.1.6 → v0.1.9 - github.com/psf/black-pre-commit-mirror: 23.11.0 → 23.12.1 - github.com/pre-commit/mirrors-mypy: v1.7.1 → v1.8.0 --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a5bea1a3c8..92d2a4223b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,13 +35,13 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.6" + rev: "v0.1.9" hooks: - id: ruff args: ["--fix", "--show-fixes"] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.11.0 + rev: 23.12.1 hooks: - id: black-jupyter types_or: [python, pyi, jupyter] @@ -50,10 +50,10 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==23.11.0] + additional_dependencies: [black==23.12.1] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.1 + rev: v1.8.0 # check the oldest and newest supported Pythons hooks: - &mypy From 970cd118738508ede7d2793954697bb0198425ef Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 4 Jan 2024 15:46:49 -0600 Subject: [PATCH 37/62] ci: Group dependabot updates (#2413) * Group dependabot updates to reduce the number of PRs. - c.f. sp-repo-review GH212: Require GHA update grouping https://learn.scientific-python.org/development/guides/gha-basic/#GH212 --- .github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ced1d704d0..93c21d076c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,10 @@ updates: directory: "/" schedule: interval: "weekly" + groups: + actions: + patterns: + - "*" labels: - "github-actions" - "dependencies" From 4fdd6d6c3fb3783be9985e568c9b98d53bedbdd0 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 4 Jan 2024 23:17:14 +0100 Subject: [PATCH 38/62] fix: Correct variable assignment for limit band artists (#2411) * Assign the one and two sigma band artists to the correct objects. - Amends PR https://github.com/scikit-hep/pyhf/pull/1377 --- src/pyhf/contrib/viz/brazil.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyhf/contrib/viz/brazil.py b/src/pyhf/contrib/viz/brazil.py index a8955f20eb..ad39a7648d 100644 --- a/src/pyhf/contrib/viz/brazil.py +++ b/src/pyhf/contrib/viz/brazil.py @@ -129,14 +129,14 @@ def plot_brazil_band(test_pois, cls_obs, cls_exp, test_size, ax, **kwargs): label=None if idx != 2 else r"$\mathrm{CL}_{s,\mathrm{exp}}$", ) cls_exp_lines.append(_cls_exp_line) - one_sigma_band = ax.fill_between( + two_sigma_band = ax.fill_between( test_pois, cls_exp[0], cls_exp[-1], facecolor="yellow", label=r"$\pm2\sigma$ $\mathrm{CL}_{s,\mathrm{exp}}$", ) - two_sigma_band = ax.fill_between( + one_sigma_band = ax.fill_between( test_pois, cls_exp[1], cls_exp[-2], From 03b7286e49b528e34a6ce25ce6d6f0eb42fd4f3f Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 4 Jan 2024 16:39:54 -0600 Subject: [PATCH 39/62] chore: Remove Mypy 'show_error_codes' as now default (#2414) * sp-repo-review MY102: Mypy show_error_codes deprecated Must not have show_error_codes. Use hide_error_codes instead (since Mypy v0.990). --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e2a17df696..9b653a5646 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -237,7 +237,6 @@ files = "src" python_version = "3.11" warn_unused_configs = true strict = true -show_error_codes = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] warn_unreachable = true From 1d4a3b2d425da21ee51e48c1a47a7343b62027dd Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 4 Jan 2024 17:07:51 -0600 Subject: [PATCH 40/62] docs: Add use citation from global LHC constraints SModelS paper (#2415) * Add use citation from 'Global LHC constraints on electroweak-inos with SModelS v2.3'. - c.f. https://inspirehep.net/literature/2741235 --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index dde3ab948e..81d2a21317 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2023-12-27 +@article{Altakach:2023tsd, + author = "Altakach, Mohammad Mahdi and Kraml, Sabine and Lessa, Andre and Narasimha, Sahana and Pascal, Timoth\'ee and Reymermier, Th\'eo and Waltenberger, Wolfgang", + title = "{Global LHC constraints on electroweak-inos with SModelS v2.3}", + eprint = "2312.16635", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + month = "12", + year = "2023", + journal = "" +} + % 2023-12-21 @article{MicroBooNE:2023sds, author = "{MicroBooNE Collaboration}", From 865faa8773387db655dce238c43cc803bbf07a12 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 4 Jan 2024 17:29:48 -0600 Subject: [PATCH 41/62] docs: Add use citation from ML for columnar HEP paper (#2416) * Add use citation from 'Machine Learning for Columnar High Energy Physics Analysis'. - c.f. https://inspirehep.net/literature/2743013 * First citation from 2024! --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 81d2a21317..7cb717ffe5 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2024-01-03 +@article{Kauffman:2024bov, + author = "Kauffman, Elliott and Held, Alexander and Shadura, Oksana", + title = "{Machine Learning for Columnar High Energy Physics Analysis}", + eprint = "2401.01802", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + month = "1", + year = "2024", + journal = "" +} + % 2023-12-27 @article{Altakach:2023tsd, author = "Altakach, Mohammad Mahdi and Kraml, Sabine and Lessa, Andre and Narasimha, Sahana and Pascal, Timoth\'ee and Reymermier, Th\'eo and Waltenberger, Wolfgang", From 4ec2cc2f252416fadb52e81fe850338eb31373bf Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 4 Jan 2024 18:00:24 -0600 Subject: [PATCH 42/62] docs: Update GitHub Actions workflow status badge URLs (#2417) * The previous URLs are starting to break and so the current web API URLs for the status badges is used. --- README.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index ba0f5199ff..dcb81360d0 100644 --- a/README.rst +++ b/README.rst @@ -398,11 +398,11 @@ and grant `OAC-1450377 Date: Thu, 4 Jan 2024 21:31:04 -0600 Subject: [PATCH 43/62] docs: Update citations references with journal pubs through 2023-12 (#2418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add use citation from 'Search for a Heavy Neutrino in \ensuremath{\tau} Decays at Belle'. - c.f. https://inspirehep.net/literature/2616299 * Add use citation from 'Probing electroweak phase transition in the singlet Standard Model via bbγγ and 4l channels'. - c.f. https://inspirehep.net/literature/2639009 * Update use citations references to include their journal publication information. - 'SModelS v2.3: enabling global likelihood analyses'. https://doi.org/10.21468/SciPostPhys.15.5.185 - 'Boosting dark matter searches at muon colliders with machine learning: The mono-Higgs channel as a case study'. https://doi.org/10.1093/ptep/ptad144 --- docs/bib/use_citations.bib | 54 +++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 7cb717ffe5..6755ec4530 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -163,20 +163,24 @@ @inproceedings{Feickert:2023hhr % 2023-09-20 @article{Belfkir:2023vpo, author = "Belfkir, Mohamed and Jueid, Adil and Nasri, Salah", - title = "{Boosting dark matter searches at muon colliders with Machine Learning: the mono-Higgs channel as a case study}", + title = "{Boosting dark matter searches at muon colliders with machine learning: The mono-Higgs channel as a case study}", eprint = "2309.11241", archivePrefix = "arXiv", primaryClass = "hep-ph", reportNumber = "CTPU-PTC-23-37", - month = "9", - year = "2023", - journal = "" + doi = "10.1093/ptep/ptad144", + journal = "Progress of Theoretical and Experimental Physics", + volume = "2023", + number = "12", + pages = "123B03", + month = "12", + year = "2023" } % 2023-09-04 @article{Fenton:2023ikr, author = "Fenton, Michael James and Shmakov, Alexander and Okawa, Hideki and Li, Yuji and Hsiao, Ko-Yang and Hsu, Shih-Chieh and Whiteson, Daniel and Baldi, Pierre", - title = "{Extended Symmetry Preserving Attention Networks for LHC Analysis}", + title = "{Reconstruction of Unstable Heavy Particles Using Deep Symmetry-Preserving Attention Networks}", eprint = "2309.01886", archivePrefix = "arXiv", primaryClass = "hep-ex", @@ -227,9 +231,11 @@ @article{MahdiAltakach:2023bdn eprint = "2306.17676", archivePrefix = "arXiv", primaryClass = "hep-ph", - month = "6", - year = "2023", - journal = "" + doi = "10.21468/SciPostPhys.15.5.185", + journal = "SciPost Phys.", + volume = "15", + pages = "185", + year = "2023" } % 2023-06-19 @@ -296,6 +302,20 @@ @article{Guo:2023jkz year = "2023" } +% 2023-03-07 +@article{Zhang:2023jvh, + author = "Zhang, Wenxing and Li, Hao-Lin and Liu, Kun and Ramsey-Musolf, Michael J. and Zeng, Yonghao and Arunasalam, Suntharan", + title = "{Probing electroweak phase transition in the singlet Standard Model via bb\ensuremath{\gamma}\ensuremath{\gamma} and 4l channels}", + eprint = "2303.03612", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + doi = "10.1007/JHEP12(2023)018", + journal = "JHEP", + volume = "12", + pages = "018", + year = "2023" +} + % 2023-02-24 @article{Behera:2023eeo, author = "Behera, Subhasish and Hageluken, Manuel and Schott, Matthias", @@ -352,6 +372,22 @@ @article{Berger:2023bat year = "2023" } +% 2022-12-20 +@article{Belle:2022tfo, + author = "Belle Collaboration", + title = "{Search for a Heavy Neutrino in \ensuremath{\tau} Decays at Belle}", + eprint = "2212.10095", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + reportNumber = "Belle Preprint 2022-27, KEK Preprint 2022-36", + doi = "10.1103/PhysRevLett.131.211802", + journal = "Phys. Rev. Lett.", + volume = "131", + number = "21", + pages = "211802", + year = "2023" +} + % 2022-12-06 @article{Belle-II:2022yaw, author = "Belle II Collaboration", @@ -460,7 +496,7 @@ @article{Belle:2022gbl eprint = "2207.07476", archivePrefix = "arXiv", primaryClass = "hep-ex", - reportNumber = "BELLE-CONF-2201", + reportNumber = "BELLE-CONF-2201, Belle Preprint 2023-13, KEK Preprint 2023-17", month = "7", year = "2022", journal = "" From f2ce224b3cff087a2651fbc3948437eb87f19556 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 5 Jan 2024 08:42:32 -0600 Subject: [PATCH 44/62] docs: Correct fixed_params type to tuple or list (#2420) * `fixed_params` is an iterable that is of type tuple or list. Though operations on it may support tensor types, not all operations will necessarily be supported and so the docs should not list it as being a tensor. --- src/pyhf/infer/__init__.py | 4 ++-- src/pyhf/infer/calculators.py | 12 ++++++------ src/pyhf/infer/mle.py | 8 ++++---- src/pyhf/infer/test_statistics.py | 20 ++++++++++---------- src/pyhf/infer/utils.py | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/pyhf/infer/__init__.py b/src/pyhf/infer/__init__.py index 5aaaf2c1c6..dc5531cd93 100644 --- a/src/pyhf/infer/__init__.py +++ b/src/pyhf/infer/__init__.py @@ -61,8 +61,8 @@ def hypotest( par_bounds (:obj:`tensor`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`tensor` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. calctype (:obj:`str`): The calculator to create. Choose either 'asymptotics' (default) or 'toybased'. return_tail_probs (:obj:`bool`): Bool for returning :math:`\mathrm{CL}_{s+b}` and :math:`\mathrm{CL}_{b}` return_expected (:obj:`bool`): Bool for returning :math:`\mathrm{CL}_{\mathrm{exp}}` diff --git a/src/pyhf/infer/calculators.py b/src/pyhf/infer/calculators.py index ed9642e085..1889dec0c7 100644 --- a/src/pyhf/infer/calculators.py +++ b/src/pyhf/infer/calculators.py @@ -61,8 +61,8 @@ def generate_asimov_data( par_bounds (:obj:`tensor`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`tensor` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. return_fitted_pars (:obj:`bool`): Return the best-fit parameter values for the given ``asimov_mu``. @@ -241,8 +241,8 @@ def __init__( par_bounds (:obj:`tensor`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`tensor` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. test_stat (:obj:`str`): The test statistic to use as a numerical summary of the data: ``'qtilde'``, ``'q'``, or ``'q0'``. @@ -685,8 +685,8 @@ def __init__( par_bounds (:obj:`tensor`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`tensor` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. test_stat (:obj:`str`): The test statistic to use as a numerical summary of the data: ``'qtilde'``, ``'q'``, or ``'q0'``. diff --git a/src/pyhf/infer/mle.py b/src/pyhf/infer/mle.py index fffff84131..61559b0ed0 100644 --- a/src/pyhf/infer/mle.py +++ b/src/pyhf/infer/mle.py @@ -106,8 +106,8 @@ def fit(data, pdf, init_pars=None, par_bounds=None, fixed_params=None, **kwargs) par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. kwargs: Keyword arguments passed through to the optimizer API Returns: @@ -180,8 +180,8 @@ def fixed_poi_fit( par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. kwargs: Keyword arguments passed through to the optimizer API Returns: diff --git a/src/pyhf/infer/test_statistics.py b/src/pyhf/infer/test_statistics.py index cf11e09c86..97b6babe79 100644 --- a/src/pyhf/infer/test_statistics.py +++ b/src/pyhf/infer/test_statistics.py @@ -112,8 +112,8 @@ def qmu(mu, data, pdf, init_pars, par_bounds, fixed_params, return_fitted_pars=F par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. return_fitted_pars (:obj:`bool`): Return the best-fit parameter tensors the fixed-POI and unconstrained fits have converged on (i.e. :math:`\mu, \hat{\hat{\theta}}` and :math:`\hat{\mu}, \hat{\theta}`) @@ -207,8 +207,8 @@ def qmu_tilde( par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. return_fitted_pars (:obj:`bool`): Return the best-fit parameter tensors the fixed-POI and unconstrained fits have converged on (i.e. :math:`\mu, \hat{\hat{\theta}}` and :math:`\hat{\mu}, \hat{\theta}`) @@ -290,8 +290,8 @@ def tmu(mu, data, pdf, init_pars, par_bounds, fixed_params, return_fitted_pars=F par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. return_fitted_pars (:obj:`bool`): Return the best-fit parameter tensors the fixed-POI and unconstrained fits have converged on (i.e. :math:`\mu, \hat{\hat{\theta}}` and :math:`\hat{\mu}, \hat{\theta}`) @@ -380,8 +380,8 @@ def tmu_tilde( par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. return_fitted_pars (:obj:`bool`): Return the best-fit parameter tensors the fixed-POI and unconstrained fits have converged on (i.e. :math:`\mu, \hat{\hat{\theta}}` and :math:`\hat{\mu}, \hat{\theta}`) @@ -458,8 +458,8 @@ def q0(mu, data, pdf, init_pars, par_bounds, fixed_params, return_fitted_pars=Fa par_bounds (:obj:`list` of :obj:`list`/:obj:`tuple`): The extrema of values the model parameters are allowed to reach in the fit. The shape should be ``(n, 2)`` for ``n`` model parameters. - fixed_params (:obj:`list` of :obj:`bool`): The flag to set a parameter constant to its starting - value during minimization. + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): The flag to set a parameter + constant to its starting value during minimization. return_fitted_pars (:obj:`bool`): Return the best-fit parameter tensors the fixed-POI and unconstrained fits have converged on (i.e. :math:`\mu, \hat{\hat{\theta}}` and :math:`\hat{\mu}, \hat{\theta}`) diff --git a/src/pyhf/infer/utils.py b/src/pyhf/infer/utils.py index 1131b01de9..a9eeefac49 100644 --- a/src/pyhf/infer/utils.py +++ b/src/pyhf/infer/utils.py @@ -22,7 +22,7 @@ def all_pois_floating(pdf, fixed_params): Args: pdf (~pyhf.pdf.Model): The statistical model adhering to the schema ``model.json``. - fixed_params (:obj:`list` or `tensor` of :obj:`bool`): Array of + fixed_params (:obj:`tuple` or :obj:`list` of :obj:`bool`): Array of :obj:`bool` indicating if model parameters are fixed. Returns: From 8be3e90b9987d4791ca2bce8b93287ce096655c0 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 5 Jan 2024 12:41:03 -0600 Subject: [PATCH 45/62] =?UTF-8?q?docs:=20Bump=20version:=200.7.5=20?= =?UTF-8?q?=E2=86=92=200.7.6=20(#2433)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Forward port the version bump information from release v0.7.6 on the release/v0.7.x branch. --- .zenodo.json | 6 +++--- CITATION.cff | 8 ++++---- README.rst | 10 +++++----- codemeta.json | 2 +- docs/lite/jupyterlite.py | 2 +- src/pyhf/data/citation.bib | 6 +++--- src/pyhf/utils.py | 2 +- tbump.toml | 4 ++-- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 59380cbf28..4d85eb20fb 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,8 +1,8 @@ { "description": "pure-Python HistFactory implementation with tensors and autodiff", "license": "Apache-2.0", - "title": "scikit-hep/pyhf: v0.7.5", - "version": "v0.7.5", + "title": "scikit-hep/pyhf: v0.7.6", + "version": "v0.7.6", "upload_type": "software", "creators": [ { @@ -36,7 +36,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/scikit-hep/pyhf/tree/v0.7.5", + "identifier": "https://github.com/scikit-hep/pyhf/tree/v0.7.6", "relation": "isSupplementTo" } ] diff --git a/CITATION.cff b/CITATION.cff index 85f9f5b8ba..14b1444bb7 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,11 +14,11 @@ authors: given-names: "Giordon" orcid: "https://orcid.org/0000-0001-6616-3433" affiliation: "SCIPP, University of California, Santa Cruz" -title: "pyhf: v0.7.5" -version: 0.7.5 +title: "pyhf: v0.7.6" +version: 0.7.6 doi: 10.5281/zenodo.1169739 -repository-code: "https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5" -url: "https://pyhf.readthedocs.io/en/v0.7.5/" +repository-code: "https://github.com/scikit-hep/pyhf/releases/tag/v0.7.6" +url: "https://pyhf.readthedocs.io/en/v0.7.6/" keywords: - python - physics diff --git a/README.rst b/README.rst index dcb81360d0..eda8612ae8 100644 --- a/README.rst +++ b/README.rst @@ -309,11 +309,11 @@ the preferred BibTeX entry for citation of ``pyhf`` includes both the @software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, - title = "{pyhf: v0.7.5}", - version = {0.7.5}, + title = "{pyhf: v0.7.6}", + version = {0.7.6}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, - note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5} + note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.6} } @article{pyhf_joss, @@ -368,7 +368,7 @@ and grant `OAC-1450377 =3.0.0"]) +await piplite.install(["pyhf==0.7.6", "matplotlib>=3.0.0"]) # %matplotlib inline import pyhf diff --git a/src/pyhf/data/citation.bib b/src/pyhf/data/citation.bib index 1c38a90abd..48348f61b0 100644 --- a/src/pyhf/data/citation.bib +++ b/src/pyhf/data/citation.bib @@ -1,10 +1,10 @@ @software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, - title = "{pyhf: v0.7.5}", - version = {0.7.5}, + title = "{pyhf: v0.7.6}", + version = {0.7.6}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, - note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5} + note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.6} } @article{pyhf_joss, diff --git a/src/pyhf/utils.py b/src/pyhf/utils.py index 859f887913..c9ad5d0185 100644 --- a/src/pyhf/utils.py +++ b/src/pyhf/utils.py @@ -111,7 +111,7 @@ def citation(oneline=False): >>> import pyhf >>> pyhf.utils.citation(oneline=True) - '@software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, title = "{pyhf: v0.7.5}", version = {0.7.5}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.5}}@article{pyhf_joss, doi = {10.21105/joss.02823}, url = {https://doi.org/10.21105/joss.02823}, year = {2021}, publisher = {The Open Journal}, volume = {6}, number = {58}, pages = {2823}, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark and Kyle Cranmer}, title = {pyhf: pure-Python implementation of HistFactory statistical models}, journal = {Journal of Open Source Software}}' + '@software{pyhf, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark}, title = "{pyhf: v0.7.6}", version = {0.7.6}, doi = {10.5281/zenodo.1169739}, url = {https://doi.org/10.5281/zenodo.1169739}, note = {https://github.com/scikit-hep/pyhf/releases/tag/v0.7.6}}@article{pyhf_joss, doi = {10.21105/joss.02823}, url = {https://doi.org/10.21105/joss.02823}, year = {2021}, publisher = {The Open Journal}, volume = {6}, number = {58}, pages = {2823}, author = {Lukas Heinrich and Matthew Feickert and Giordon Stark and Kyle Cranmer}, title = {pyhf: pure-Python implementation of HistFactory statistical models}, journal = {Journal of Open Source Software}}' Keyword Args: oneline (:obj:`bool`): Whether to provide citation with new lines (default) or as a one-liner. diff --git a/tbump.toml b/tbump.toml index 5f1c14c46f..edc6fa00e6 100644 --- a/tbump.toml +++ b/tbump.toml @@ -1,7 +1,7 @@ github_url = "https://github.com/scikit-hep/pyhf/" [version] -current = "0.7.5" +current = "0.7.6" # Example of a semver regexp. # Make sure this matches current_version before @@ -19,7 +19,7 @@ regex = ''' [git] # The current version will get updated when tbump is run -message_template = "Bump version: 0.7.5 → {new_version}" +message_template = "Bump version: 0.7.6 → {new_version}" tag_template = "v{new_version}" # For each file to patch, add a [[file]] config From 273c772b0d14d2e5fe61e6e326c9f792df1d64ec Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 5 Jan 2024 13:10:14 -0600 Subject: [PATCH 46/62] docs: Add v0.7.6 release notes (#2434) * Forward port PR #2430 and #2432 from release/v0.7.x to main. * Add release notes for pyhf v0.7.6. --- docs/release-notes.rst | 1 + docs/release-notes/v0.7.6.rst | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 docs/release-notes/v0.7.6.rst diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 0bdc291dfb..720321de7e 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -2,6 +2,7 @@ Release Notes ============= +.. include:: release-notes/v0.7.6.rst .. include:: release-notes/v0.7.5.rst .. include:: release-notes/v0.7.4.rst .. include:: release-notes/v0.7.3.rst diff --git a/docs/release-notes/v0.7.6.rst b/docs/release-notes/v0.7.6.rst new file mode 100644 index 0000000000..35ced6792e --- /dev/null +++ b/docs/release-notes/v0.7.6.rst @@ -0,0 +1,32 @@ +|release v0.7.6|_ +================= + +This is a patch release from ``v0.7.5`` → ``v0.7.6``. + +Fixes +----- + +* For the JAX backend access ``jax.config`` from the ``jax`` top level API to + avoid support issues with ``jax`` and ``jaxlib`` ``v0.4.20+``. + (PR :pr:`2376`) +* Add information in the warnings for :func:`pyhf.infer.test_statistics.qmu` and + :func:`pyhf.infer.test_statistics.qmu_tilde` that provides users with the + higher level ``pyhf.infer`` APIs ``kwarg`` to set the correct test statistic. + (PR :pr:`2390`) +* Correct the variable assignment for the one-sigma and two-sigma limit band + artists in :func:`pyhf.contrib.viz.brazil.plot_brazil_band` to match the + stated return structure. + (PR :pr:`2411`) +* In the ``pyhf.infer`` module, correct the ``fixed_params`` type in the docs + to be to :obj:`tuple` or :obj:`list`. + (PR :pr:`2420`) + +Contributors +------------ + +``v0.7.6`` benefited from contributions from: + +* Lorenz Gaertner + +.. |release v0.7.6| replace:: ``v0.7.6`` +.. _`release v0.7.6`: https://github.com/scikit-hep/pyhf/releases/tag/v0.7.6 From c7b2f2df4699cc6193d6d4a4b8a277f574fcd643 Mon Sep 17 00:00:00 2001 From: Alexander Held <45009355+alexander-held@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:06:20 +0100 Subject: [PATCH 47/62] docs: Add use citation from AGC CHEP 2023 proceedings (#2435) * Add use citation from 'Physics analysis for the HL-LHC: concepts and pipelines in practice with the Analysis Grand Challenge'. - c.f. https://inspirehep.net/literature/2743608 --- docs/bib/use_citations.bib | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 6755ec4530..42ac672bdb 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -1,3 +1,15 @@ +% 2024-01-05 +@article{Held:2024gwj, + author = "Held, Alexander and Kauffman, Elliott and Shadura, Oksana and Wightman, Andrew", + title = "{Physics analysis for the HL-LHC: concepts and pipelines in practice with the Analysis Grand Challenge}", + eprint = "2401.02766", + archivePrefix = "arXiv", + primaryClass = "hep-ex", + month = "1", + year = "2024", + journal = "" +} + % 2024-01-03 @article{Kauffman:2024bov, author = "Kauffman, Elliott and Held, Alexander and Shadura, Oksana", From 5b632519838f6ad2c73a8c8f8b53a09c1d8c678b Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 8 Jan 2024 23:21:04 -0600 Subject: [PATCH 48/62] docs: Add use citation from inert triplet model paper (#2436) * Add use citation from 'Probing Inert Triplet Model at a multi-TeV muon collider via vector boson fusion with forward muon tagging'. - c.f. https://inspirehep.net/literature/2743639 --- docs/bib/use_citations.bib | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/bib/use_citations.bib b/docs/bib/use_citations.bib index 42ac672bdb..b569eab851 100644 --- a/docs/bib/use_citations.bib +++ b/docs/bib/use_citations.bib @@ -10,6 +10,19 @@ @article{Held:2024gwj journal = "" } +% 2024-01-05 +@article{Bandyopadhyay:2024plc, + author = "Bandyopadhyay, Priyotosh and Parashar, Snehashis and Sen, Chandrima and Song, Jeonghyeon", + title = "{Probing Inert Triplet Model at a multi-TeV muon collider via vector boson fusion with forward muon tagging}", + eprint = "2401.02697", + archivePrefix = "arXiv", + primaryClass = "hep-ph", + reportNumber = "IITH-PH-0002/23, KIAS-P23063", + month = "1", + year = "2024", + journal = "" +} + % 2024-01-03 @article{Kauffman:2024bov, author = "Kauffman, Elliott and Held, Alexander and Shadura, Oksana", From fc5e83018d2a2c98156e5073a6e630793a1edd55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:42:23 -0600 Subject: [PATCH 49/62] build(deps): bump the actions group with 1 update (#2443) * Bumps the actions group with 1 update: [codecov/codecov-action](https://github.com/codecov/codecov-action). Updates `codecov/codecov-action` from 3 to 4 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3...v4) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... * Add required token secret. Signed-off-by: dependabot[bot] Co-authored-by: Matthew Feickert --- .github/workflows/ci.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 857804bb2a..b3e1b3fa25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,10 +66,12 @@ jobs: if: >- github.event_name != 'schedule' && matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: + fail_ci_if_error: true files: ./coverage.xml flags: unittests-${{ matrix.python-version }} + token: ${{ secrets.CODECOV_TOKEN }} - name: Test Contrib module with pytest run: | @@ -82,10 +84,12 @@ jobs: - name: Report contrib coverage with Codecov if: github.event_name != 'schedule' && matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: + fail_ci_if_error: true files: ./coverage.xml flags: contrib + token: ${{ secrets.CODECOV_TOKEN }} - name: Test docstring examples with doctest if: matrix.python-version == '3.11' @@ -99,10 +103,12 @@ jobs: - name: Report doctest coverage with Codecov if: github.event_name != 'schedule' && matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: + fail_ci_if_error: true files: doctest-coverage.xml flags: doctest + token: ${{ secrets.CODECOV_TOKEN }} - name: Run benchmarks if: github.event_name == 'schedule' && matrix.python-version == '3.11' From 975ee43b71b2aa20664d47de47b5ddb79fc891b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 01:38:10 -0600 Subject: [PATCH 50/62] build(deps): bump the actions group with 1 update (#2446) Bumps the actions group with 1 update: [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish). Updates `pypa/gh-action-pypi-publish` from 1.8.11 to 1.8.12 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.11...v1.8.12) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/publish-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index c45d90d53e..38af3dfd7e 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -132,13 +132,13 @@ jobs: if: >- (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository == 'scikit-hep/pyhf') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true' && github.repository == 'scikit-hep/pyhf') - uses: pypa/gh-action-pypi-publish@v1.8.11 + uses: pypa/gh-action-pypi-publish@v1.8.12 with: repository-url: https://test.pypi.org/legacy/ print-hash: true - name: Publish distribution 📦 to PyPI if: github.event_name == 'release' && github.event.action == 'published' && github.repository == 'scikit-hep/pyhf' - uses: pypa/gh-action-pypi-publish@v1.8.11 + uses: pypa/gh-action-pypi-publish@v1.8.12 with: print-hash: true From af5d9521b1a3f1e307ecef2c23d9a418994394b9 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Sat, 9 Mar 2024 01:45:13 -0600 Subject: [PATCH 51/62] build: Disallow TensorFlow v2.16.1 (#2448) * tensorflow v2.16.1 breaks tensorflow-probability at import time with the Keras v3.0 API breaking change. Until Keras v3.0 is adopted in tensorflow-probability, tensorflow v2.16.1+ can't be used. - c.f. https://github.com/tensorflow/probability/issues/1795 * Note that Apple silicon machines should revert to installing 'tensorflow' instead of 'tensorflow-macos' for tensorflow v2.16.1+. * Note that macos x86 builds of tensorflow will be deprecated and no longer released from tensorflow v2.17.0+. --- pyproject.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9b653a5646..a3be808496 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,9 +67,11 @@ Homepage = "https://github.com/scikit-hep/pyhf" [project.optional-dependencies] shellcomplete = ["click_completion"] +# TODO: Use 'tensorflow' for all platform_machine for tensorflow v2.16.x+ +# NOTE: macos x86 support is deprecated from tensorflow v2.17.0 onwards. tensorflow = [ - "tensorflow>=2.7.0; platform_machine != 'arm64'", # c.f. PR #1962 - "tensorflow-macos>=2.7.0; platform_machine == 'arm64' and platform_system == 'Darwin'", # c.f. PR #2119 + "tensorflow>=2.7.0,!=2.16.1; platform_machine != 'arm64'", # c.f. PR #1962, #2448 + "tensorflow-macos>=2.7.0,!=2.16.1; platform_machine == 'arm64' and platform_system == 'Darwin'", # c.f. PR #2119, #2448 "tensorflow-probability>=0.11.0", # c.f. PR #1657 ] torch = ["torch>=1.10.0"] # c.f. PR #1657 From c09738d5ad94379065a02560f4a06019008aeb45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 18:28:04 -0500 Subject: [PATCH 52/62] build(deps): bump the actions group with 1 update (#2451) Bumps the actions group with 1 update: [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish). Updates `pypa/gh-action-pypi-publish` from 1.8.12 to 1.8.14 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.8.12...v1.8.14) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/publish-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 38af3dfd7e..786f410998 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -132,13 +132,13 @@ jobs: if: >- (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && github.repository == 'scikit-hep/pyhf') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true' && github.repository == 'scikit-hep/pyhf') - uses: pypa/gh-action-pypi-publish@v1.8.12 + uses: pypa/gh-action-pypi-publish@v1.8.14 with: repository-url: https://test.pypi.org/legacy/ print-hash: true - name: Publish distribution 📦 to PyPI if: github.event_name == 'release' && github.event.action == 'published' && github.repository == 'scikit-hep/pyhf' - uses: pypa/gh-action-pypi-publish@v1.8.12 + uses: pypa/gh-action-pypi-publish@v1.8.14 with: print-hash: true From be2fde2056298b4cf01a947842f0643aae845504 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 12 Mar 2024 16:01:02 -0500 Subject: [PATCH 53/62] ci: Add Apple silicon macOS to CI (#2447) * Add Apple M1 runner to tests using 'macos-14' for the 'runs-on' key. - c.f. https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/ * Lower the tolerance for tests/test_calculator.py to reach agreement between amd64 and arm64. * Skip doctest evaluation for arm64. --- .github/workflows/ci.yml | 8 ++++++-- tests/test_calculator.py | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3e1b3fa25..218b0ebc55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,9 @@ jobs: include: - os: macos-latest python-version: '3.11' + # Apple silicon runner + - os: macos-14 + python-version: '3.11' steps: - uses: actions/checkout@v4 @@ -92,11 +95,12 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Test docstring examples with doctest - if: matrix.python-version == '3.11' + # TODO: Don't currently try to match amd64 and arm64 floating point for docs, but will in the future. + if: matrix.python-version == '3.11' && matrix.os != 'macos-14' run: coverage run --data-file=.coverage-doctest --module pytest src/ README.rst - name: Coverage report for doctest only - if: matrix.python-version == '3.11' + if: matrix.python-version == '3.11' && matrix.os != 'macos-14' run: | coverage report --data-file=.coverage-doctest coverage xml --data-file=.coverage-doctest -o doctest-coverage.xml diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 97b5fa4e3d..973d1e27bc 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -84,6 +84,7 @@ def test_asymptotic_calculator_has_fitted_pars(test_stat): assert pytest.approx([1.0, 1.0], rel=rtol) == pyhf.tensorlib.tolist( fitted_pars.free_fit_to_data ) + # lower tolerance for amd64 and arm64 to agree assert pytest.approx( - [7.6470499e-05, 1.4997178], rel=rtol + [7.6470499e-05, 1.4997178], rel=1e-3 ) == pyhf.tensorlib.tolist(fitted_pars.free_fit_to_asimov) From adddb0797c564a0158a8e2e69a58ee1f98604bf7 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Tue, 12 Mar 2024 16:39:24 -0500 Subject: [PATCH 54/62] build: Determine tensorflow-probability requirements from python version (#2452) * Split the requirements for the 'tensorflow' extra into two different conditional groups by python_version. - Starting with tensorflow v2.16.1, multiple changes were made that simplifies the installation of tensorflow across platform_machine and Keras v3.0 was adopted. - tensorflow-probability did _not_ adopt Keras v3.0, but instead requires tf-keras. Starting in tensorflow-probability v0.24.0 the 'tensorflow-probability[tf]' extra was added which includes all the required dependencies to be able to use tensorflow-probability with tensorflow v2.15+. - tensorflow v2.16.1 and tensorflow-probability v0.24.0 support Python 3.9+, so for Python 3.8 support the 'tensorflow' requirements need to use the previous more verbose conditionals. * Reverts PR https://github.com/scikit-hep/pyhf/pull/2448 --- pyproject.toml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a3be808496..fbc4f47d4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,12 +67,18 @@ Homepage = "https://github.com/scikit-hep/pyhf" [project.optional-dependencies] shellcomplete = ["click_completion"] -# TODO: Use 'tensorflow' for all platform_machine for tensorflow v2.16.x+ +# TODO: 'tensorflow' supports all platform_machine for tensorflow v2.16.1+ +# but TensorFlow only supports python_version 3.8 up through tensorflow v2.13.1. +# So until Python 3.8 support is dropped, split requirments on python_version +# before and after 3.9. # NOTE: macos x86 support is deprecated from tensorflow v2.17.0 onwards. tensorflow = [ - "tensorflow>=2.7.0,!=2.16.1; platform_machine != 'arm64'", # c.f. PR #1962, #2448 - "tensorflow-macos>=2.7.0,!=2.16.1; platform_machine == 'arm64' and platform_system == 'Darwin'", # c.f. PR #2119, #2448 - "tensorflow-probability>=0.11.0", # c.f. PR #1657 + # python == 3.8 + "tensorflow>=2.7.0; python_version < '3.9' and platform_machine != 'arm64'", # c.f. PR #1962, #2452 + "tensorflow-macos>=2.7.0; python_version < '3.9' and platform_machine == 'arm64' and platform_system == 'Darwin'", # c.f. PR #2119, #2452 + "tensorflow-probability>=0.11.0; python_version < '3.9'", # c.f. PR #1657, #2452 + # python >= 3.9 + "tensorflow-probability[tf]>=0.24.0; python_version >= '3.9'" # c.f. PR #2452 ] torch = ["torch>=1.10.0"] # c.f. PR #1657 jax = [ From 50f107609b2fd0f2f6085ac760708b73e244eb25 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 15 Mar 2024 14:38:28 -0500 Subject: [PATCH 55/62] feat: Use Python 3.12+ tarfile data extraction filter (#2455) * In Python 3.12 extraction filters are added and will become default in Python 3.14. To start using them for when Python 3.12 support is added, and to guard against a Python 3.14 DeprecationWarning, use the data extraction filter for extracting tarfiles in pyhf.contrib.utils.download. - c.f. https://docs.python.org/3.12/library/tarfile.html#extraction-filters --- src/pyhf/contrib/utils.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pyhf/contrib/utils.py b/src/pyhf/contrib/utils.py index 02c9ffb5f2..7fa9550242 100644 --- a/src/pyhf/contrib/utils.py +++ b/src/pyhf/contrib/utils.py @@ -91,7 +91,12 @@ def download(archive_url, output_directory, force=False, compress=False): with tarfile.open( mode="r:*", fileobj=BytesIO(response.content) ) as archive: - archive.extractall(output_directory) + # TODO: Simplify after pyhf is Python 3.12+ only + # c.f. https://docs.python.org/3.12/library/tarfile.html#extraction-filters + if hasattr(tarfile, "data_filter"): + archive.extractall(output_directory, filter="data") + else: + archive.extractall(output_directory) except tarfile.ReadError: if not zipfile.is_zipfile(BytesIO(response.content)): raise exceptions.InvalidArchive( From a0d94b9e92fd1211b6d15a6c04aac9d01a3a0065 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Wed, 20 Mar 2024 03:58:10 -0500 Subject: [PATCH 56/62] fix: Test xml.etree.ElementTree.Element truth value by 'is not None' (#2459) * In Python 3.14 testing the truth value of an xml.etree.ElementTree.Element is deprecated and will raise an exception. As of Python 3.12 this behavior will raise a DeprecationWarning: ``` DeprecationWarning: Testing an element's truth value will raise an exception in future versions. Use specific 'len(elem)' or 'elem is not None' test instead. ``` To avoid this, determine the truth element by using the 'elem is not None' method. - c.f. https://docs.python.org/3.12/library/xml.etree.elementtree.html#element-objects --- src/pyhf/writexml.py | 2 +- tests/test_export.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyhf/writexml.py b/src/pyhf/writexml.py index 8d3ecd3ca3..ff7aac800b 100644 --- a/src/pyhf/writexml.py +++ b/src/pyhf/writexml.py @@ -56,7 +56,7 @@ def _export_root_histogram(hist_name, data): # https://stackoverflow.com/a/4590052 def indent(elem, level=0): i = "\n" + level * " " - if elem: + if elem is not None: if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): diff --git a/tests/test_export.py b/tests/test_export.py index bba0aa224e..5c1ebed6e2 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -447,7 +447,7 @@ def test_integer_data(datadir, mocker): mocker.patch("pyhf.writexml._ROOT_DATA_FILE") channel = pyhf.writexml.build_channel(spec, channel_spec, {}) - assert channel + assert channel is not None @pytest.mark.parametrize( From dd4a243588a79aedde84b4fe43a4570d84b8a6ec Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Wed, 20 Mar 2024 12:48:40 -0500 Subject: [PATCH 57/62] ci: Add Python 3.12 to testing to CI as default (#2460) * Add Python 3.12 to testing in CI. * Default to using Python 3.12 in GitHub Actions where possible. * Add ignore of DeprecationWarning for protobuf * Add Python 3.12 trove classifier to PyPI metadata. --- .github/workflows/bump-version.yml | 4 ++-- .github/workflows/ci-windows.yml | 2 +- .github/workflows/ci.yml | 16 ++++++++-------- .github/workflows/dependencies-head.yml | 12 ++++++------ .github/workflows/docs.yml | 2 +- .github/workflows/notebooks.yml | 2 +- .github/workflows/publish-package.yml | 4 ++-- .github/workflows/release_tests.yml | 4 ++-- pyproject.toml | 4 +++- 9 files changed, 26 insertions(+), 24 deletions(-) diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 3f4d4cb074..8083fa8a43 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -196,11 +196,11 @@ jobs: echo "steps.script.outputs.old_tag=v${current_tag}" echo "old_tag=v${current_tag}" >> $GITHUB_OUTPUT - - name: Set up Python 3.11 + - name: Set up Python 3.12 if: success() uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - name: Install Python dependencies run: | diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml index d2d7f3c792..c9f3e8e68b 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [windows-latest] - python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 218b0ebc55..65d7e656dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,13 +27,13 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] include: - os: macos-latest - python-version: '3.11' + python-version: '3.12' # Apple silicon runner - os: macos-14 - python-version: '3.11' + python-version: '3.12' steps: - uses: actions/checkout@v4 @@ -86,7 +86,7 @@ jobs: coverage xml - name: Report contrib coverage with Codecov - if: github.event_name != 'schedule' && matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' + if: github.event_name != 'schedule' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v4 with: fail_ci_if_error: true @@ -96,17 +96,17 @@ jobs: - name: Test docstring examples with doctest # TODO: Don't currently try to match amd64 and arm64 floating point for docs, but will in the future. - if: matrix.python-version == '3.11' && matrix.os != 'macos-14' + if: matrix.python-version == '3.12' && matrix.os != 'macos-14' run: coverage run --data-file=.coverage-doctest --module pytest src/ README.rst - name: Coverage report for doctest only - if: matrix.python-version == '3.11' && matrix.os != 'macos-14' + if: matrix.python-version == '3.12' && matrix.os != 'macos-14' run: | coverage report --data-file=.coverage-doctest coverage xml --data-file=.coverage-doctest -o doctest-coverage.xml - name: Report doctest coverage with Codecov - if: github.event_name != 'schedule' && matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' + if: github.event_name != 'schedule' && matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v4 with: fail_ci_if_error: true @@ -115,6 +115,6 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Run benchmarks - if: github.event_name == 'schedule' && matrix.python-version == '3.11' + if: github.event_name == 'schedule' && matrix.python-version == '3.12' run: | pytest --benchmark-sort=mean tests/benchmarks/test_benchmark.py diff --git a/.github/workflows/dependencies-head.yml b/.github/workflows/dependencies-head.yml index fc5e16c1f3..1e4651251f 100644 --- a/.github/workflows/dependencies-head.yml +++ b/.github/workflows/dependencies-head.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 @@ -47,7 +47,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 @@ -77,7 +77,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 @@ -103,7 +103,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 @@ -128,7 +128,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 @@ -165,7 +165,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5af25f1632..f040b74ccc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - name: Install Python dependencies run: | diff --git a/.github/workflows/notebooks.yml b/.github/workflows/notebooks.yml index e961de6f56..7ab2b048f8 100644 --- a/.github/workflows/notebooks.yml +++ b/.github/workflows/notebooks.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.11'] + python-version: ['3.12'] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 786f410998..cd5d4a9ba7 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -36,10 +36,10 @@ jobs: with: fetch-depth: 0 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.12' - name: Install python-build and twine run: | diff --git a/.github/workflows/release_tests.yml b/.github/workflows/release_tests.yml index 85034114c9..b149d22d11 100644 --- a/.github/workflows/release_tests.yml +++ b/.github/workflows/release_tests.yml @@ -18,10 +18,10 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] include: - os: macos-latest - python-version: '3.11' + python-version: '3.12' steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index fbc4f47d4d..6383e1b6b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Physics", @@ -106,7 +107,7 @@ test = [ "pytest-mpl", "ipympl>=0.3.0", "pydocstyle", - "papermill~=2.3.4", + "papermill~=2.5.0", "scrapbook~=0.5.0", "jupyter", "graphviz", @@ -225,6 +226,7 @@ filterwarnings = [ "ignore:ml_dtypes.float8_e4m3b11 is deprecated.", #FIXME: Can remove when jaxlib>=0.4.12 "ignore:jsonschema.RefResolver is deprecated as of v4.18.0, in favor of the:DeprecationWarning", # Issue #2139 "ignore:Skipping device Apple Paravirtual device that does not support Metal 2.0:UserWarning", # Can't fix given hardware/virtualized device + 'ignore:Type google._upb._message.[A-Z]+ uses PyType_Spec with a metaclass that has custom:DeprecationWarning', # protobuf via tensorflow ] [tool.coverage.run] From db67210ec76007db1a5b6818644fe721662d5249 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Wed, 20 Mar 2024 13:06:03 -0500 Subject: [PATCH 58/62] chore: Update services and docs to Python 3.12 as default (#2461) * Update to using Python 3.12 in linting and validation tools. * Update Binder runtime Python to Python 3.12. * Update Dockerfile base image to python:3.12-slim-bullseye. * Update the docs to advocate using Python 3.12 for development. --- .pre-commit-config.yaml | 4 ++-- .readthedocs.yaml | 2 +- binder/runtime.txt | 2 +- codemeta.json | 1 + docker/Dockerfile | 2 +- docs/development.rst | 6 +++--- noxfile.py | 12 ++++++------ pyproject.toml | 2 +- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 92d2a4223b..047103c327 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -64,8 +64,8 @@ repos: ['numpy', 'types-tqdm', 'click', 'types-jsonpatch', 'types-pyyaml', 'types-jsonschema', 'importlib_metadata', 'packaging'] args: ["--python-version=3.8"] - <<: *mypy - name: mypy with Python 3.11 - args: ["--python-version=3.11"] + name: mypy with Python 3.12 + args: ["--python-version=3.12"] - repo: https://github.com/codespell-project/codespell rev: v2.2.6 diff --git a/.readthedocs.yaml b/.readthedocs.yaml index bdab4e8207..bd5f4ea9cd 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.11" + python: "3.12" apt_packages: - curl - jq diff --git a/binder/runtime.txt b/binder/runtime.txt index 67ebc4e9a6..d2aca3a7e1 100644 --- a/binder/runtime.txt +++ b/binder/runtime.txt @@ -1 +1 @@ -python-3.11 +python-3.12 diff --git a/codemeta.json b/codemeta.json index 67ffefec40..1b9ca9c817 100644 --- a/codemeta.json +++ b/codemeta.json @@ -50,6 +50,7 @@ "runtimePlatform": [ "Python 3", "Python 3 Only", + "Python 3.12", "Python 3.11", "Python 3.10", "Python 3.8", diff --git a/docker/Dockerfile b/docker/Dockerfile index 50c2f31e95..154d279e35 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -ARG BASE_IMAGE=python:3.11-slim-bullseye +ARG BASE_IMAGE=python:3.12-slim-bullseye # hadolint ignore=DL3006 FROM ${BASE_IMAGE} as base diff --git a/docs/development.rst b/docs/development.rst index 324b8110bf..fa6149a8a9 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -97,7 +97,7 @@ contrib module, or notebooks, and so instead to test the core codebase a develop .. code-block:: console - nox --session tests --python 3.11 + nox --session tests --python 3.12 Contrib module matplotlib image tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -107,7 +107,7 @@ To run the visualization tests for the ``contrib`` module with the ``pytest-mpl` .. code-block:: console - nox --session tests --python 3.11 -- contrib + nox --session tests --python 3.12 -- contrib If the image files need to be regenerated, run the tests with the ``--mpl-generate-path=tests/contrib/baseline`` option or just run @@ -141,7 +141,7 @@ or pass ``coverage`` as a positional argument to the ``nox`` ``tests`` session .. code-block:: console - nox --session tests --python 3.11 -- coverage + nox --session tests --python 3.12 -- coverage Coverage Report ^^^^^^^^^^^^^^^ diff --git a/noxfile.py b/noxfile.py index 8104dbd28b..1828383486 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,10 +4,10 @@ import nox -ALL_PYTHONS = ["3.8", "3.9", "3.10", "3.11"] +ALL_PYTHONS = ["3.8", "3.9", "3.10", "3.11", "3.12"] # Default sessions to run if no session handles are passed -nox.options.sessions = ["lint", "tests-3.11"] +nox.options.sessions = ["lint", "tests-3.12"] DIR = Path(__file__).parent.resolve() @@ -30,10 +30,10 @@ def tests(session): Examples: - $ nox --session tests --python 3.11 - $ nox --session tests --python 3.11 -- contrib # run the contrib module tests - $ nox --session tests --python 3.11 -- tests/test_tensor.py # run specific tests - $ nox --session tests --python 3.11 -- coverage # run with coverage but slower + $ nox --session tests --python 3.12 + $ nox --session tests --python 3.12 -- contrib # run the contrib module tests + $ nox --session tests --python 3.12 -- tests/test_tensor.py # run specific tests + $ nox --session tests --python 3.12 -- coverage # run with coverage but slower """ session.install("--upgrade", "--editable", ".[all,test]") session.install("--upgrade", "pytest") diff --git a/pyproject.toml b/pyproject.toml index 6383e1b6b7..f113ca1fed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -244,7 +244,7 @@ exclude_also = [ [tool.mypy] files = "src" -python_version = "3.11" +python_version = "3.12" warn_unused_configs = true strict = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] From 428c9e1ae4927f612b4d98da96923e0208339c6c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 15:28:02 -0500 Subject: [PATCH 59/62] chore: [pre-commit.ci] pre-commit autoupdate (#2442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pre-commit hooks: - github.com/astral-sh/ruff-pre-commit: v0.1.9 → v0.3.3 - github.com/psf/black-pre-commit-mirror: 23.12.1 → 24.3.0 - github.com/pre-commit/mirrors-mypy: v1.8.0 → v1.9.0 * Apply pre-commit changes. * Apply ruff fixes to 'RUF017 Avoid quadratic list summation' to src/pyhf/workspace.py with '--unsafe-fixes' option. - c.f. https://docs.astral.sh/ruff/rules/quadratic-list-summation/ Co-authored-by: Matthew Feickert --- .pre-commit-config.yaml | 8 ++++---- docs/examples/notebooks/ImpactPlot.ipynb | 8 +++++--- src/pyhf/cli/__init__.py | 1 + src/pyhf/cli/cli.py | 1 + src/pyhf/cli/complete.py | 1 + src/pyhf/cli/infer.py | 1 + src/pyhf/cli/patchset.py | 1 + src/pyhf/cli/rootio.py | 1 + src/pyhf/cli/spec.py | 9 ++++++--- src/pyhf/contrib/cli.py | 1 + src/pyhf/contrib/viz/brazil.py | 1 + src/pyhf/infer/calculators.py | 1 + src/pyhf/infer/intervals/__init__.py | 1 + src/pyhf/infer/intervals/upper_limits.py | 1 + src/pyhf/infer/mle.py | 1 + src/pyhf/interpolators/code0.py | 1 + src/pyhf/interpolators/code1.py | 1 + src/pyhf/interpolators/code2.py | 1 + src/pyhf/interpolators/code4.py | 1 + src/pyhf/interpolators/code4p.py | 1 + src/pyhf/modifiers/shapesys.py | 6 +++--- src/pyhf/modifiers/staterror.py | 15 +++++++++------ src/pyhf/optimize/common.py | 1 + src/pyhf/optimize/mixins.py | 1 + src/pyhf/optimize/opt_minuit.py | 1 + src/pyhf/optimize/opt_scipy.py | 1 + src/pyhf/optimize/opt_tflow.py | 1 + src/pyhf/parameters/paramview.py | 8 +++++--- src/pyhf/patchset.py | 1 + src/pyhf/probability.py | 1 + src/pyhf/schema/__init__.py | 1 + src/pyhf/tensor/numpy_backend.py | 1 + src/pyhf/tensor/pytorch_backend.py | 1 + src/pyhf/tensor/tensorflow_backend.py | 1 + src/pyhf/typing.py | 9 +++------ src/pyhf/workspace.py | 7 +++++-- tests/test_interpolate.py | 4 +--- 37 files changed, 69 insertions(+), 33 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 047103c327..5d204da540 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,13 +35,13 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.1.9" + rev: "v0.3.3" hooks: - id: ruff args: ["--fix", "--show-fixes"] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.1 + rev: 24.3.0 hooks: - id: black-jupyter types_or: [python, pyi, jupyter] @@ -50,10 +50,10 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==23.12.1] + additional_dependencies: [black==24.3.0] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.8.0 + rev: v1.9.0 # check the oldest and newest supported Pythons hooks: - &mypy diff --git a/docs/examples/notebooks/ImpactPlot.ipynb b/docs/examples/notebooks/ImpactPlot.ipynb index aa045c124f..3a3fdd9019 100644 --- a/docs/examples/notebooks/ImpactPlot.ipynb +++ b/docs/examples/notebooks/ImpactPlot.ipynb @@ -172,9 +172,11 @@ " model, _, b, e = fitresults()\n", " widths = pyhf.tensorlib.concatenate(\n", " [\n", - " model.config.param_set(k).width()\n", - " if model.config.param_set(k).constrained\n", - " else [None] * model.config.param_set(k).n_parameters\n", + " (\n", + " model.config.param_set(k).width()\n", + " if model.config.param_set(k).constrained\n", + " else [None] * model.config.param_set(k).n_parameters\n", + " )\n", " for k, v in model.config.par_map.items()\n", " ]\n", " )\n", diff --git a/src/pyhf/cli/__init__.py b/src/pyhf/cli/__init__.py index 0d65039661..ed53c296af 100644 --- a/src/pyhf/cli/__init__.py +++ b/src/pyhf/cli/__init__.py @@ -1,4 +1,5 @@ """The pyhf command line interface.""" + from pyhf.cli.cli import pyhf as cli from pyhf.cli.rootio import cli as rootio from pyhf.cli.spec import cli as spec diff --git a/src/pyhf/cli/cli.py b/src/pyhf/cli/cli.py index a1a486fe54..cd458a6329 100644 --- a/src/pyhf/cli/cli.py +++ b/src/pyhf/cli/cli.py @@ -1,4 +1,5 @@ """The pyhf Command Line Interface.""" + import logging import click diff --git a/src/pyhf/cli/complete.py b/src/pyhf/cli/complete.py index 58fda5604f..c39e6e9784 100644 --- a/src/pyhf/cli/complete.py +++ b/src/pyhf/cli/complete.py @@ -1,4 +1,5 @@ '''Shell completions for pyhf.''' + import click try: diff --git a/src/pyhf/cli/infer.py b/src/pyhf/cli/infer.py index a877469efc..f2b0dce107 100644 --- a/src/pyhf/cli/infer.py +++ b/src/pyhf/cli/infer.py @@ -1,4 +1,5 @@ """The inference CLI group.""" + import logging import click diff --git a/src/pyhf/cli/patchset.py b/src/pyhf/cli/patchset.py index 75bdb56887..4d31d4963d 100644 --- a/src/pyhf/cli/patchset.py +++ b/src/pyhf/cli/patchset.py @@ -1,4 +1,5 @@ """The pyhf spec CLI subcommand.""" + import logging import click diff --git a/src/pyhf/cli/rootio.py b/src/pyhf/cli/rootio.py index 95d8872a84..c5d5840762 100644 --- a/src/pyhf/cli/rootio.py +++ b/src/pyhf/cli/rootio.py @@ -1,4 +1,5 @@ """CLI subapps to handle conversion from ROOT.""" + import logging import click diff --git a/src/pyhf/cli/spec.py b/src/pyhf/cli/spec.py index 9772558169..08fdd73d94 100644 --- a/src/pyhf/cli/spec.py +++ b/src/pyhf/cli/spec.py @@ -1,4 +1,5 @@ """The pyhf spec CLI subcommand.""" + import logging import click @@ -149,9 +150,11 @@ def inspect(workspace, output_file, measurement): ('(*) ' if measurement_name == default_measurement['name'] else '') + measurement_name, measurement_poi, - ','.join(measurement_parameters) - if measurement_parameters - else '(none)', + ( + ','.join(measurement_parameters) + if measurement_parameters + else '(none)' + ), ) ) diff --git a/src/pyhf/contrib/cli.py b/src/pyhf/contrib/cli.py index eaf2bb7e23..5bba47e4d4 100644 --- a/src/pyhf/contrib/cli.py +++ b/src/pyhf/contrib/cli.py @@ -1,4 +1,5 @@ """CLI for functionality that will get migrated out eventually.""" + import logging import click from pathlib import Path diff --git a/src/pyhf/contrib/viz/brazil.py b/src/pyhf/contrib/viz/brazil.py index ad39a7648d..18b25d87bd 100644 --- a/src/pyhf/contrib/viz/brazil.py +++ b/src/pyhf/contrib/viz/brazil.py @@ -1,4 +1,5 @@ """Brazil Band Plots.""" + from collections import namedtuple import matplotlib.pyplot as plt diff --git a/src/pyhf/infer/calculators.py b/src/pyhf/infer/calculators.py index 1889dec0c7..f9922c6d89 100644 --- a/src/pyhf/infer/calculators.py +++ b/src/pyhf/infer/calculators.py @@ -7,6 +7,7 @@ Using the calculators hypothesis tests can then be performed. """ + from pyhf.infer.mle import fixed_poi_fit from pyhf import get_backend from pyhf.infer import utils diff --git a/src/pyhf/infer/intervals/__init__.py b/src/pyhf/infer/intervals/__init__.py index 0f2f928cdd..2acdfd3165 100644 --- a/src/pyhf/infer/intervals/__init__.py +++ b/src/pyhf/infer/intervals/__init__.py @@ -1,4 +1,5 @@ """Interval estimation""" + import pyhf.infer.intervals.upper_limits __all__ = ["upper_limits.upper_limit"] diff --git a/src/pyhf/infer/intervals/upper_limits.py b/src/pyhf/infer/intervals/upper_limits.py index 6fbc27e6b3..601189cdbb 100644 --- a/src/pyhf/infer/intervals/upper_limits.py +++ b/src/pyhf/infer/intervals/upper_limits.py @@ -1,4 +1,5 @@ """Interval estimation""" + import numpy as np from scipy.optimize import toms748 diff --git a/src/pyhf/infer/mle.py b/src/pyhf/infer/mle.py index 61559b0ed0..c269eb47c8 100644 --- a/src/pyhf/infer/mle.py +++ b/src/pyhf/infer/mle.py @@ -1,4 +1,5 @@ """Module for Maximum Likelihood Estimation.""" + from pyhf import get_backend from pyhf.exceptions import UnspecifiedPOI diff --git a/src/pyhf/interpolators/code0.py b/src/pyhf/interpolators/code0.py index ff972d506b..52d87fefba 100644 --- a/src/pyhf/interpolators/code0.py +++ b/src/pyhf/interpolators/code0.py @@ -1,4 +1,5 @@ """Piecewise-linear Interpolation. (Code 0).""" + import logging import pyhf from pyhf.tensor.manager import get_backend diff --git a/src/pyhf/interpolators/code1.py b/src/pyhf/interpolators/code1.py index f5bbe71ff0..a9fa41c011 100644 --- a/src/pyhf/interpolators/code1.py +++ b/src/pyhf/interpolators/code1.py @@ -1,4 +1,5 @@ """Piecewise-Exponential Interpolation (Code 1).""" + import logging import math import pyhf diff --git a/src/pyhf/interpolators/code2.py b/src/pyhf/interpolators/code2.py index ed305c44da..8dff3278e7 100644 --- a/src/pyhf/interpolators/code2.py +++ b/src/pyhf/interpolators/code2.py @@ -1,4 +1,5 @@ """Quadratic Interpolation (Code 2).""" + import logging import pyhf from pyhf.tensor.manager import get_backend diff --git a/src/pyhf/interpolators/code4.py b/src/pyhf/interpolators/code4.py index a120bdf295..0290d0c52d 100644 --- a/src/pyhf/interpolators/code4.py +++ b/src/pyhf/interpolators/code4.py @@ -1,4 +1,5 @@ """Polynomial Interpolation (Code 4).""" + import logging import math import pyhf diff --git a/src/pyhf/interpolators/code4p.py b/src/pyhf/interpolators/code4p.py index ec8b63afa7..8841eb0dd0 100644 --- a/src/pyhf/interpolators/code4p.py +++ b/src/pyhf/interpolators/code4p.py @@ -1,4 +1,5 @@ """Piecewise-Linear + Polynomial Interpolation (Code 4p).""" + import logging import pyhf from pyhf.tensor.manager import get_backend diff --git a/src/pyhf/modifiers/shapesys.py b/src/pyhf/modifiers/shapesys.py index 39740e4cf8..c18ac90149 100644 --- a/src/pyhf/modifiers/shapesys.py +++ b/src/pyhf/modifiers/shapesys.py @@ -165,9 +165,9 @@ def _reindex_access_field(self, pdfconfig): sample_mask = self._shapesys_mask[syst_index][singular_sample_index][0] access_field_for_syst_and_batch[sample_mask] = selection - self._access_field[ - syst_index, batch_index - ] = access_field_for_syst_and_batch + self._access_field[syst_index, batch_index] = ( + access_field_for_syst_and_batch + ) def _precompute(self): tensorlib, _ = get_backend() diff --git a/src/pyhf/modifiers/staterror.py b/src/pyhf/modifiers/staterror.py index 919811c9fe..a6d6d499c5 100644 --- a/src/pyhf/modifiers/staterror.py +++ b/src/pyhf/modifiers/staterror.py @@ -92,9 +92,12 @@ def finalize(self): relerrs = default_backend.sum( [ [ - (modifier_data['data']['uncrt'][binnr] / nomsall[binnr]) ** 2 - if nomsall[binnr] > 0 - else 0.0 + ( + (modifier_data['data']['uncrt'][binnr] / nomsall[binnr]) + ** 2 + if nomsall[binnr] > 0 + else 0.0 + ) for binnr in range(len(modifier_data['data']['nom_data'])) ] for modifier_data in self.builder_data[modname].values() @@ -184,9 +187,9 @@ def _reindex_access_field(self, pdfconfig): sample_mask = self._staterror_mask[syst_index][singular_sample_index][0] access_field_for_syst_and_batch[sample_mask] = selection - self._access_field[ - syst_index, batch_index - ] = access_field_for_syst_and_batch + self._access_field[syst_index, batch_index] = ( + access_field_for_syst_and_batch + ) def _precompute(self): if not self.param_viewer.index_selection: diff --git a/src/pyhf/optimize/common.py b/src/pyhf/optimize/common.py index 61eeafd889..2049939159 100644 --- a/src/pyhf/optimize/common.py +++ b/src/pyhf/optimize/common.py @@ -1,4 +1,5 @@ """Common Backend Shim to prepare minimization for optimizer.""" + from pyhf.tensor.manager import get_backend from pyhf.tensor.common import _TensorViewer diff --git a/src/pyhf/optimize/mixins.py b/src/pyhf/optimize/mixins.py index c0e689c512..19e150f069 100644 --- a/src/pyhf/optimize/mixins.py +++ b/src/pyhf/optimize/mixins.py @@ -1,4 +1,5 @@ """Helper Classes for use of automatic differentiation.""" + import logging import numpy as np diff --git a/src/pyhf/optimize/opt_minuit.py b/src/pyhf/optimize/opt_minuit.py index 01424e8ca7..4f1edb3dca 100644 --- a/src/pyhf/optimize/opt_minuit.py +++ b/src/pyhf/optimize/opt_minuit.py @@ -1,4 +1,5 @@ """Minuit Optimizer Class.""" + from pyhf import exceptions from pyhf.optimize.mixins import OptimizerMixin import scipy diff --git a/src/pyhf/optimize/opt_scipy.py b/src/pyhf/optimize/opt_scipy.py index f334c36ad7..68c64bafe3 100644 --- a/src/pyhf/optimize/opt_scipy.py +++ b/src/pyhf/optimize/opt_scipy.py @@ -1,4 +1,5 @@ """SciPy Optimizer Class.""" + from pyhf import exceptions from pyhf.optimize.mixins import OptimizerMixin import scipy diff --git a/src/pyhf/optimize/opt_tflow.py b/src/pyhf/optimize/opt_tflow.py index fd2965fb3e..178bc332ac 100644 --- a/src/pyhf/optimize/opt_tflow.py +++ b/src/pyhf/optimize/opt_tflow.py @@ -1,4 +1,5 @@ """Tensorflow Backend Function Shim.""" + from pyhf import get_backend import tensorflow as tf diff --git a/src/pyhf/parameters/paramview.py b/src/pyhf/parameters/paramview.py index cac057f8b5..0238832747 100644 --- a/src/pyhf/parameters/paramview.py +++ b/src/pyhf/parameters/paramview.py @@ -44,9 +44,11 @@ def extract_index_access(baseviewer, subviewer, indices): # the transpose is here so that modifier code doesn't have to do it indices_concatenated = tensorlib.astensor( - tensorlib.einsum('ij->ji', stitched) - if len(tensorlib.shape(stitched)) > 1 - else stitched, + ( + tensorlib.einsum('ij->ji', stitched) + if len(tensorlib.shape(stitched)) > 1 + else stitched + ), dtype='int', ) return index_selection, stitched, indices_concatenated diff --git a/src/pyhf/patchset.py b/src/pyhf/patchset.py index b72118835b..86acaef693 100644 --- a/src/pyhf/patchset.py +++ b/src/pyhf/patchset.py @@ -1,6 +1,7 @@ """ pyhf patchset provides a user-friendly interface for interacting with patchsets. """ + import logging import jsonpatch from pyhf import exceptions diff --git a/src/pyhf/probability.py b/src/pyhf/probability.py index 7851127ae3..0cc0330272 100644 --- a/src/pyhf/probability.py +++ b/src/pyhf/probability.py @@ -1,4 +1,5 @@ """The probability density function module.""" + from pyhf import get_backend __all__ = ["Independent", "Normal", "Poisson", "Simultaneous"] diff --git a/src/pyhf/schema/__init__.py b/src/pyhf/schema/__init__.py index 61bb01c78e..0c08f018b2 100644 --- a/src/pyhf/schema/__init__.py +++ b/src/pyhf/schema/__init__.py @@ -1,6 +1,7 @@ """ See :class:`~pyhf.schema.Schema` for documentation. """ + import pathlib import sys from pyhf.schema.loader import load_schema diff --git a/src/pyhf/tensor/numpy_backend.py b/src/pyhf/tensor/numpy_backend.py index 4623ea5797..8e019a7ec9 100644 --- a/src/pyhf/tensor/numpy_backend.py +++ b/src/pyhf/tensor/numpy_backend.py @@ -1,4 +1,5 @@ """NumPy Tensor Library Module.""" + from __future__ import annotations import logging diff --git a/src/pyhf/tensor/pytorch_backend.py b/src/pyhf/tensor/pytorch_backend.py index fb0cd4ad52..c962c864f9 100644 --- a/src/pyhf/tensor/pytorch_backend.py +++ b/src/pyhf/tensor/pytorch_backend.py @@ -1,4 +1,5 @@ """PyTorch Tensor Library Module.""" + import torch import torch.autograd from torch.distributions.utils import broadcast_all diff --git a/src/pyhf/tensor/tensorflow_backend.py b/src/pyhf/tensor/tensorflow_backend.py index 1e51a2a885..a36fa9206f 100644 --- a/src/pyhf/tensor/tensorflow_backend.py +++ b/src/pyhf/tensor/tensorflow_backend.py @@ -1,4 +1,5 @@ """Tensorflow Tensor Library Module.""" + import logging import tensorflow as tf import tensorflow_probability as tfp diff --git a/src/pyhf/typing.py b/src/pyhf/typing.py index f012e3af22..19802e3da7 100644 --- a/src/pyhf/typing.py +++ b/src/pyhf/typing.py @@ -150,8 +150,7 @@ class TensorBackend(Protocol): precision: str default_do_grad: bool - def _setup(self) -> None: - ... + def _setup(self) -> None: ... class Optimizer(Protocol): @@ -159,8 +158,6 @@ class Optimizer(Protocol): class PDF(Protocol): - def sample(self, sample_shape: Shape) -> Any: - ... + def sample(self, sample_shape: Shape) -> Any: ... - def log_prob(self, value: Any) -> Any: - ... + def log_prob(self, value: Any) -> Any: ... diff --git a/src/pyhf/workspace.py b/src/pyhf/workspace.py index 7ce0bc486d..08b285d25e 100644 --- a/src/pyhf/workspace.py +++ b/src/pyhf/workspace.py @@ -5,6 +5,7 @@ * the observed data (optional) * fit configurations ("measurements") """ + from __future__ import annotations import collections @@ -17,6 +18,8 @@ from pyhf import exceptions, schema from pyhf.mixins import _ChannelSummaryMixin from pyhf.pdf import Model +import functools +import operator log = logging.getLogger(__name__) @@ -464,8 +467,8 @@ def data(self, model, include_auxdata=True): """ try: - observed_data = sum( - (self.observations[c] for c in model.config.channels), [] + observed_data = functools.reduce( + operator.iadd, (self.observations[c] for c in model.config.channels), [] ) except KeyError: log.error( diff --git a/tests/test_interpolate.py b/tests/test_interpolate.py index ef8e382b66..52b5830f12 100644 --- a/tests/test_interpolate.py +++ b/tests/test_interpolate.py @@ -178,9 +178,7 @@ def test_code0_validation(backend, do_tensorized_calc): def test_code1_validation(backend, do_tensorized_calc): histogramssets = [[[[0.9], [1.0], [1.1]]]] alphasets = pyhf.tensorlib.astensor([[-2, -1, 0, 1, 2]]) - expected = pyhf.tensorlib.astensor( - [[[[0.9**2], [0.9], [1.0], [1.1], [1.1**2]]]] - ) + expected = pyhf.tensorlib.astensor([[[[0.9**2], [0.9], [1.0], [1.1], [1.1**2]]]]) interpolator = pyhf.interpolators.get(1, do_tensorized_calc=do_tensorized_calc)( histogramssets, subscribe=False From 39db83b8df8d3bd6c52b974332a1833727c8fa07 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Fri, 22 Mar 2024 10:36:53 -0500 Subject: [PATCH 60/62] fix: Use str object for jupyterlite-sphinx jupyterlite_dir config (#2458) * To avoid warning WARNING: The config value `jupyterlite_dir` has type `PosixPath`, defaults to `str`. use a str for the jupyterlite-sphinx v0.13.0+ jupyterlite_dir config option. * Update jupyterlite-sphinx lower bound to v0.13.1 in 'docs' extra. * Amends PR https://github.com/scikit-hep/pyhf/pull/2300 --- docs/conf.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 06ead2b2a7..60ab7b974d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -531,5 +531,5 @@ def setup(app): linkcheck_retries = 50 # JupyterLite configuration -# Use Path as jupyterlite-sphinx expects PosixPath -jupyterlite_dir = Path("lite") +# jupyterlite-sphinx v0.13.0+ expects str +jupyterlite_dir = str(Path("lite")) diff --git a/pyproject.toml b/pyproject.toml index f113ca1fed..034be5f52f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -123,7 +123,7 @@ docs = [ "ipywidgets", "sphinx-issues", "sphinx-copybutton>=0.3.2,!=0.5.1", - "jupyterlite-sphinx>=0.8.0", + "jupyterlite-sphinx>=0.13.1", # c.f. https://github.com/scikit-hep/pyhf/pull/2458 "jupyterlite-pyodide-kernel>=0.0.7", "jupytext>=1.14.0", "ipython!=8.7.0", # c.f. https://github.com/scikit-hep/pyhf/pull/2068 From 1420112bb2f2047a07899dc7f8d046202f1ce5a3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:57:06 +0200 Subject: [PATCH 61/62] chore: [pre-commit.ci] pre-commit autoupdate (#2464) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pre-commit hooks: - github.com/astral-sh/ruff-pre-commit: v0.3.3 → v0.3.5 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5d204da540..0a69bd27a6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,7 +35,7 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.3.3" + rev: "v0.3.5" hooks: - id: ruff args: ["--fix", "--show-fixes"] From 64ab2646b836ae69404929b7e2b7ba04fb87d492 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 09:28:29 +0200 Subject: [PATCH 62/62] build(deps): bump the actions group with 1 update (#2465) Bumps the actions group with 1 update: [actions/configure-pages](https://github.com/actions/configure-pages). Updates `actions/configure-pages` from 4 to 5 - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f040b74ccc..155100d0ed 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -113,7 +113,7 @@ jobs: steps: - name: Setup Pages - uses: actions/configure-pages@v4 + uses: actions/configure-pages@v5 - name: Deploy to GitHub Pages id: deployment