{"id":7567,"library":"pyhf","title":"pyhf - Pure-Python HistFactory","description":"pyhf is a pure-Python implementation of the HistFactory statistical model for binned data analysis, widely used in particle physics. It leverages modern tensor libraries like NumPy, TensorFlow, PyTorch, and JAX with automatic differentiation for efficient and scalable statistical inference. The current version is 0.7.6, and it follows a regular release cadence with patch releases addressing fixes and minor improvements, and minor versions introducing new features and sometimes API changes.","status":"active","version":"0.7.6","language":"en","source_language":"en","source_url":"https://github.com/scikit-hep/pyhf","tags":["physics","statistics","histfactory","autodiff","HEP","machine learning","data analysis"],"install":[{"cmd":"pip install pyhf","lang":"bash","label":"Base installation"},{"cmd":"pip install 'pyhf[tensorflow]'","lang":"bash","label":"With TensorFlow backend"},{"cmd":"pip install 'pyhf[torch]'","lang":"bash","label":"With PyTorch backend"},{"cmd":"pip install 'pyhf[jax]' 'jaxlib'","lang":"bash","label":"With JAX backend (requires jaxlib separately)"},{"cmd":"pip install 'pyhf[full]'","lang":"bash","label":"With all backends and extra features"}],"dependencies":[{"reason":"Core tensor library","package":"numpy","optional":false},{"reason":"Core scientific computing library","package":"scipy","optional":false},{"reason":"Optional backend for tensor operations and autodiff","package":"tensorflow","optional":true},{"reason":"Optional backend for tensor operations and autodiff","package":"torch","optional":true},{"reason":"Optional backend for tensor operations and autodiff","package":"jax","optional":true},{"reason":"Required for JAX backend, often needs specific installation based on hardware","package":"jaxlib","optional":true},{"reason":"Optional backend for optimization routines via iminuit","package":"mminuit","optional":true}],"imports":[{"symbol":"pyhf","correct":"import pyhf"},{"note":"pyhf.set_backend is a global configuration function and is intended to be called via the pyhf module directly to ensure proper initialization of the backend context.","wrong":"from pyhf import set_backend; set_backend(\"numpy\")","symbol":"set_backend","correct":"import pyhf\npyhf.set_backend(\"numpy\")"},{"symbol":"Model","correct":"import pyhf\nmodel = pyhf.Model(...)"},{"symbol":"fit","correct":"import pyhf\nresult = pyhf.infer.mle.fit(...)"},{"note":"The `test_statistics` module and related functions were moved under `pyhf.infer` in v0.6.0 for better organization.","wrong":"mu_test_stat = pyhf.test_statistics.qmu(...)","symbol":"qmu","correct":"import pyhf\nmu_test_stat = pyhf.infer.test_statistics.qmu(...)"}],"quickstart":{"code":"import pyhf\nimport json\n\n# Define a simple workspace (example adapted from pyhf documentation)\nworkspace_data = {\n  \"channels\": [\n    {\n      \"name\": \"singlechannel\",\n      \"samples\": [\n        {\n          \"name\": \"signal\",\n          \"data\": [12.0],\n          \"modifiers\": [\n            {\"name\": \"mu\", \"type\": \"normfactor\", \"data\": None},\n            {\"name\": \"lumi\", \"type\": \"lumi\", \"data\": {\"correlated\": True, \"nom_data\": 1.0, \"rel_data\": 0.1}}\n          ]\n        },\n        {\n          \"name\": \"background\",\n          \"data\": [100.0],\n          \"modifiers\": [\n            {\"name\": \"lumi\", \"type\": \"lumi\", \"data\": {\"correlated\": True, \"nom_data\": 1.0, \"rel_data\": 0.1}},\n            {\"name\": \"bkg_norm\", \"type\": \"normfactor\", \"data\": None}\n          ]\n        }\n      ]\n    }\n  ],\n  \"observations\": [\n    {\n      \"name\": \"singlechannel\",\n      \"data\": [120.0],\n      \"modifier_data\": [\n        {\"name\": \"lumi\", \"type\": \"lumi\", \"data\": 1.0}\n      ]\n    }\n  ]\n}\n\n# Set the backend (e.g., 'numpy', 'tensorflow', 'torch', or 'jax')\npyhf.set_backend(\"numpy\")\n\n# Create a model from the workspace data\nworkspace = pyhf.Workspace(workspace_data)\nmodel = workspace.model(modifier_settings={'lumi': {'type': 'lumi', 'decorrelate': False}})\n\n# Prepare data and initial parameters for the fit\n# The model's data method handles observation and auxiliary data.\nactual_data = model.data(workspace.data)\ninit_pars = model.config.suggested_init()\nfixed_pars = model.config.suggested_fixed()\nbounds = model.config.suggested_bounds()\n\n# Perform Maximum Likelihood Estimation (MLE)\n# This fits the model to the data to find the best-fit parameters.\nfit_results = pyhf.infer.mle.fit(\n    data=actual_data,\n    pdf=model,\n    init_pars=init_pars,\n    fixed_params=fixed_pars,\n    par_bounds=bounds\n)\n\nprint(f\"Fitted parameters: {fit_results[0]}\")\nprint(f\"Parameter uncertainties: {fit_results[1]}\")\n\n# Example for hypothesis testing: fixing 'mu' (signal strength) to 0 (background-only hypothesis)\nmu_index = model.config.modifier_index('mu') # Get index of the 'mu' parameter\n\nbkg_only_init_pars = list(init_pars) # Create a mutable copy\nbkg_only_init_pars[mu_index] = 0.0 # Set mu to 0\n\nbkg_only_fixed_params = list(fixed_pars) # Create a mutable copy\nbkg_only_fixed_params[mu_index] = True # Fix mu at 0\n\nbkg_only_fit_results = pyhf.infer.mle.fit(\n    data=actual_data,\n    pdf=model,\n    init_pars=bkg_only_init_pars,\n    fixed_params=bkg_only_fixed_params,\n    par_bounds=bounds\n)\nprint(f\"Fitted parameters (mu=0 fixed): {bkg_only_fit_results[0]}\")","lang":"python","description":"This quickstart demonstrates how to define a simple HistFactory workspace, set a backend, create a pyhf model, and perform a basic maximum likelihood fit to extract best-fit parameters and their uncertainties. It also shows how to set and fix specific parameters for hypothesis testing."},"warnings":[{"fix":"Consult the pyhf v0.7.0 release notes and official documentation's migration guides. Pay close attention to changes in `pyhf.Workspace` and `pyhf.Model` constructors.","message":"Version 0.7.0 introduced significant API breaking changes, impacting workspace definition, model creation, and inference calls. Code written for versions prior to 0.7.0 will likely require updates.","severity":"breaking","affected_versions":"<0.7.0"},{"fix":"Upgrade pyhf to version 0.7.3 or newer, which internally replaces `np.product` with `np.prod` to ensure compatibility.","message":"If using NumPy versions 1.25.0 or higher, the `np.product` function is deprecated. pyhf versions prior to 0.7.3 might raise deprecation warnings or errors related to this.","severity":"gotcha","affected_versions":"<0.7.3"},{"fix":"Upgrade pyhf to version 0.7.6 or newer, which incorporates the fix to access `jax.config` from the top-level API, ensuring compatibility.","message":"When using the JAX backend with `jax` and `jaxlib` versions 0.4.20+, direct access to `jax.config` from nested modules within pyhf could lead to support issues. It must be accessed from the top-level `jax` API.","severity":"gotcha","affected_versions":"0.4.20+"},{"fix":"Upgrade pyhf to version 0.7.4 or newer to resolve this subtle bug and improve stability when changing backends or modifying callbacks.","message":"Older pyhf versions (<0.7.4) could exhibit non-deterministic bugs related to accessing dead weakrefs while iterating over callbacks, particularly around `pyhf.set_backend` events, leading to crashes.","severity":"gotcha","affected_versions":"<0.7.4"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install the desired backend using the extra syntax, e.g., `pip install 'pyhf[tensorflow]'`. Alternatively, explicitly set a different backend like `pyhf.set_backend('numpy')` if it's installed.","cause":"An optional backend (TensorFlow, PyTorch, or JAX) was not installed, but pyhf attempted to use it or it was explicitly set as the backend.","error":"ModuleNotFoundError: No module named 'tensorflow' (or 'torch' or 'jax')"},{"fix":"Upgrade pyhf to version 0.7.3 or newer: `pip install --upgrade pyhf`. This version updates pyhf's internal usage of `np.product` to `np.prod`.","cause":"You are using a pyhf version older than 0.7.3 with NumPy version 1.25.0 or newer. `np.product` was deprecated in NumPy 1.25.0.","error":"AttributeError: module 'numpy' has no attribute 'product'"},{"fix":"Review your workspace definition against the official HistFactory schema and pyhf's documentation. Ensure all required fields (e.g., 'channels', 'observations', 'samples') are present and correctly formatted, and that data types match expectations.","cause":"The provided JSON or XML workspace definition does not conform to the HistFactory schema expected by pyhf, often due to missing required fields or incorrect data types.","error":"pyhf.exceptions.InvalidWorkspace: Schema validation failed:"},{"fix":"Ensure that all tensor operations use the functions provided by `pyhf.tensorlib` and that arrays are consistently managed within the chosen backend. Avoid direct mixing of `numpy.array` with JAX or PyTorch tensors without explicit conversion functions.","cause":"This (or similar `TypeError` for other backends like `torch.Tensor`) often occurs when mixing array types from different backends (e.g., passing a JAX array to a NumPy-expecting function) or attempting operations not supported by the current backend's tensor type.","error":"TypeError: 'jax.Array' object cannot be interpreted as an integer"}]}