Skip to main content

Statistical inference steps for high-energy physics analyses with JAX.

Project description

everwillow logo

everwillow is a statistical inference library for high-energy physics built on JAX pytrees and optimistix optimizers. It provides tools for fitting, profiling, and hypothesis testing with flexible parameter handling and parameter bounds via transformations. It works with any JAX-based statistical model.

Installation

pip install everwillow

or with uv:

uv add everwillow

From source:

git clone https://github.com/MoAly98/everwillow.git
cd everwillow
uv sync

Example

A Poisson counting experiment: define a model, fit it, compute CLs p-values, and find a 95% CL upper limit — both with asymptotic formulas and toys.

import jax
import jax.numpy as jnp

import everwillow as ew
import everwillow.statelib as sl
from everwillow.hypotest.calculators import AsymptoticCalculator, HypoTestCalculator
from everwillow.hypotest.distributions import (
    QTildeAsymptotic,
    SimpleEmpiricalDistribution,
)
from everwillow.hypotest.test_statistics import QTilde
from everwillow.hypotest.toys import ToyGenerator
from everwillow.hypotest.upper_limit import upper_limit, upper_limit_toys

jax.config.update("jax_enable_x64", True)

# --- Model ---

signal, background = 10.0, 5.0


def nll(params, observation):
    mu = params["mu"]
    expected = mu * signal + background
    return expected - observation["n"] * jnp.log(expected)


def predict(params_state):
    mu = params_state.to_pytree()["mu"]
    return {"n": mu * signal + background}


params = sl.State.from_pytree({"mu": 1.0})
observed = {"n": 12.0}

# --- Fit ---

result = ew.fit(nll_fn=nll, params=params, observation=observed)
print(result.params.to_pytree())
# {'mu': Array(0.7, dtype=float64)}

# --- Asymptotic hypothesis test ---

calc = AsymptoticCalculator(
    nll_fn=nll,
    params=params,
    observation=observed,
    poi_key="mu",
    predict_fn=predict,
    test_statistic=QTilde(),
    distribution=QTildeAsymptotic(),
)
result = calc.test(1.0)
print(f"CLs: {calc.cls(result):.4f}")
# CLs: 0.2140


def cls_objective(poi):
    return calc.cls(calc.test(poi))


limit = upper_limit(cls_objective, bounds=(0.0, 5.0), level=0.05)
print(f"95% CL upper limit (asymptotic): {float(limit):.4f}")
# 95% CL upper limit (asymptotic): 1.3673

# --- Toy-based upper limit ---

toy_gen = ToyGenerator(test_statistic=QTilde(), ntoys=5000)


def cls_from_toys(poi, key):
    """Generate toys and compute CLs at a given POI value."""
    toys = toy_gen.generate(
        nll,
        params,
        observed,
        "mu",
        poi_null=poi,
        poi_alt=0.0,
        key=key,
        predict_fn=predict,
    )
    dist = SimpleEmpiricalDistribution.from_toys(toys)
    toy_calc = HypoTestCalculator(
        nll_fn=nll,
        params=params,
        observation=observed,
        poi_key="mu",
        test_statistic=QTilde(),
        distribution=dist,
    )
    return toy_calc.cls(toy_calc.test(poi))


toy_limit = upper_limit_toys(
    cls_from_toys, bounds=(0.0, 5.0), key=jax.random.key(0), tol=0.01
)
print(f"95% CL upper limit (toys): {float(toy_limit):.4f}")

Documentation

Contributing

We welcome contributions! See CONTRIBUTING.md for setup and workflow.

License

everwillow is distributed under the BSD-3-Clause License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

everwillow-0.1.2.tar.gz (349.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

everwillow-0.1.2-py3-none-any.whl (54.0 kB view details)

Uploaded Python 3

File details

Details for the file everwillow-0.1.2.tar.gz.

File metadata

  • Download URL: everwillow-0.1.2.tar.gz
  • Upload date:
  • Size: 349.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for everwillow-0.1.2.tar.gz
Algorithm Hash digest
SHA256 44340de1dc112409e80db5bddd6918ed7a7be52b9f961d5c1a89090d8bdda0bc
MD5 6f197ec8abb46b11282ba0bb9493d007
BLAKE2b-256 624dda23e2aaee4722cfa44b557ba363770f2f32db94a27ec70d5b9c6736370a

See more details on using hashes here.

Provenance

The following attestation bundles were made for everwillow-0.1.2.tar.gz:

Publisher: cd.yml on MoAly98/everwillow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file everwillow-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: everwillow-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 54.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for everwillow-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 51347ecaf4819b4ee4174081069b5879910f90c59b52e8a8c3cd8b5ca99b5d37
MD5 d461aa6156a7d46e05537c5c7d061d65
BLAKE2b-256 8d37ba781d87836f70639d78da9aca75168e0341604e8557965301ce144ae455

See more details on using hashes here.

Provenance

The following attestation bundles were made for everwillow-0.1.2-py3-none-any.whl:

Publisher: cd.yml on MoAly98/everwillow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page