cabinetry: Design and Steer Profile Likelihood Fits

0.6.0 · active · verified Thu Apr 16

cabinetry is a Python library designed for building and steering profile likelihood fits, particularly used in high-energy physics for statistical analysis. It currently stands at version 0.6.0 and maintains an active development cycle with regular patch and minor releases, often coinciding with updates to its core dependency, `pyhf`.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates the core workflow of cabinetry: defining a statistical model via a configuration, generating dummy data and sample histograms, building a `pyhf` workspace, performing a profile likelihood fit, and visualizing the results. The example generates in-memory histograms to ensure runnability without external files.

import cabinetry
import numpy as np
import pyhf
import os

# 1. Define configuration (simplified for quickstart)
# In a real scenario, this would likely be loaded from a YAML/JSON file
config = {
    "General": {
        "Measurement": "my_measurement",
        "POI": "Signal_norm",
        "Luminosity": 1.0
    },
    "Regions": [
        {
            "Name": "SR",
            "HistogramFolders": ["data/", "signal/", "background/"],
            "Variable": "m_yy",
            "Binning": [40, 50, 60, 70, 80, 90, 100]
        }
    ],
    "Samples": [
        {"Name": "Signal", "Observable": "m_yy", "Normalization": "Signal_norm"},
        {"Name": "Background", "Observable": "m_yy"}
    ],
    "Systematics": [
        {
            "Name": "lumi",
            "Type": "lumi",
            "Expression": "1.02"
        }
    ]
}

# 2. Create dummy data/histograms in memory
bins = config["Regions"][0]["Binning"]

data_hists = {
    "SR": np.array([5, 8, 12, 10, 7, 4])
}

sample_hists = [
    {
        "name": "Signal",
        "region": "SR",
        "nominal": np.array([2, 3, 4, 3, 2, 1]),
        "staterr": np.sqrt(np.array([2, 3, 4, 3, 2, 1])) # Placeholder for stat error
    },
    {
        "name": "Background",
        "region": "SR",
        "nominal": np.array([3, 5, 8, 7, 5, 3]),
        "staterr": np.sqrt(np.array([3, 5, 8, 7, 5, 3]))
    }
]

# Add systematic variation for "lumi"
for h in sample_hists:
    h["lumi_up"] = h["nominal"] * 1.02
    h["lumi_down"] = h["nominal"] * 0.98
    h["bins"] = bins # Add binning for plotting


# 3. Build workspace
ws = cabinetry.workspace.build(config, sample_hists, data_hists)
model, data = cabinetry.model_utils.model_and_data(ws)

# 4. Perform fit
fit_results = cabinetry.fit.fit(model, data)

# 5. Visualize results (optional)
plot_dir = "cabinetry_quickstart_plots"
os.makedirs(plot_dir, exist_ok=True)

cabinetry.visualize.data_mc(
    model, data, fit_results=fit_results, config=config, save_path=os.path.join(plot_dir, "data_mc_plot.pdf")
)
cabinetry.visualize.ranking(
    fit_results, save_path=os.path.join(plot_dir, "ranking_plot.pdf")
)

print("cabinetry quickstart complete. Plots saved to:", os.path.abspath(plot_dir))

view raw JSON →