Skip to main content

BSMScanner

bsm-scanner is a framework for fast parameter scans of Beyond-the-Standard-Model physics models. You describe a model in YAML -- parameters, constants, derived quantities, matrices, observables, theory checks, likelihoods -- and the framework compiles it into a dependency graph, evaluates it in a compiled C++ core, and drives a parameter scan over it.

It is built around a sharp split:

  • Python owns model definition, validation, graph construction, scan orchestration, and result loading.
  • C++ owns hot-loop point evaluation, typed caching, matrix algebra, diagonalization, and likelihood accumulation.
  • Optional Fortran for isolated numerical kernels or external scanner bridges.

Your model lives in your own directory, not inside the framework. You write YAML, optionally import the reusable physics blocks the package ships (shared constants, neutrino/quark observable definitions, oscillation data tables), and run.

Installation

pip install bsm-scanner

While the package is only published to TestPyPI (a real PyPI release is not out yet), dependencies have to come from the real index instead, since TestPyPI does not mirror them:

pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ bsm-scanner

CI publishes prebuilt wheels via cibuildwheel for:

Platform Architecture Python
macOS arm64 (Apple Silicon) 3.10 - 3.13
Linux x86_64, glibc >= 2.28 (manylinux_2_28) 3.10 - 3.13

On a matching machine, installation needs nothing beyond pip. Eigen3 -- the only native dependency besides pybind11 -- is header-only, so it is only needed while building the C++ extension, not at install or runtime; nothing links against it once compiled. The Linux wheels are also passed through auditwheel repair as part of the build, which fails the build outright (rather than shipping a broken wheel) if the compiled extension ends up depending on any shared library outside the manylinux_2_28 baseline. So on either platform above, there is nothing to separately install for Eigen3, CMake, or a C++ compiler.

Outside that matrix -- Windows, Linux aarch64, macOS x86_64 (Intel), musllinux (Alpine), or a Python version other than 3.10-3.13 -- pip install silently falls back to building from the source distribution instead, which needs everything in Prerequisites below already installed on your machine, and will fail with a CMake not found or Eigen3 was not found error otherwise.

From source

Clone the repository, install the Prerequisites below, then see Build.

Quickstart

Start from a working template rather than an empty file:

pip install bsm-scanner
bsm-scanner new-model mymodel
bsm-scanner run --model mymodel/model.yaml --run-dir mymodel/runs/first

That creates a small, complete, runnable model you can edit. It runs immediately, so you always have a working baseline to modify.

Model syntax

A model is one or more YAML files under a schema with a fixed set of top-level sections -- parameters, constants, functions, derived_scalars, derived_complex, matrices, diagonalizations, observables, theory_checks, likelihoods, outputs, and scan. A trimmed real example (from models/minimal_bl/model.yaml, a gauged B-L benchmark):

metadata:
  name: minimal_bl_gauge
  version: 0.1.0

parameters:
- {name: gBL, value_type: real, scan: true, lower: 0.001, upper: 1.0, default: 0.1, prior: log}
- {name: vBL, value_type: real, scan: true, lower: 1000.0, upper: 100000.0, default: 70000.0, prior: log}

constants:
- {name: v_sm, value: 246.22}

derived_scalars:
- {name: MZp, value_type: real, expression: "2.0*gBL*vBL"}

observables:
- {name: MZprime, value_type: real, expression: MZp}

theory_checks:
- {name: positive_masses, condition: "MZp > 0", fatal: true, message: MZp must be positive.}

likelihoods:
- {name: lep_contact_bound, kind: hard_cut, observable: MZprime, lower: 7000.0, upper: 1.0e9}

outputs:
  save: [MZprime]

scan:
  engine: serial_random
  save_every: 100
  seed: 11064462
  settings: {objective: nll, max_evaluations: 2000}

The Python layer validates these sections, resolves dependencies, rejects cycles, expands reusable analytic functions, and lowers the active subgraph into a compact plan that the C++ core evaluates point by point. Matrices carry metadata (type, role, diagonalize: true) that triggers automatic diagonalization -- see docs/matrix_diagonalization.md and docs/core_model_split.md.

Reusable physics blocks

The framework ships a library of model-independent building blocks -- constants, neutrino/quark observable definitions, oscillation data tables. Reference them with the core: prefix, which resolves to wherever the package is installed, so your model works no matter which directory it lives in:

imports:
  - core:constants/physics_constants.yaml
  - core:neutrino/observables_common.yaml
  - core:neutrino/observables_normal.yaml
  - my_parameters.yaml       # your own files stay relative
  - my_matrices.yaml
bsm-scanner core list                                    # every shipped block
bsm-scanner core show core:quark/quark_mass_ratios.yaml   # what a block defines
bsm-scanner core path                                     # where they live

See docs/authoring_models.md for the full authoring guide, including what each shipped block provides and the division between what belongs in the reusable core versus in your own model.

Python API

from pathlib import Path

from bsm_scanner import compile_model, load_model, run_scan

model = load_model("models/minimal_bl/model.yaml")
compiled = compile_model(model, build_backend=True)
results = run_scan(model, compiled, run_directory=Path("runs/minimal_bl_example"))
print(results.summary)

The example launcher uses the same path:

python examples/minimal_bl/run_scan.py --run-dir examples/minimal_bl/runs/example_scan

Core Concepts

  • ModelDefinition: validated user-facing representation of a model.
  • ModelGraph: named dependency graph over parameters, derived quantities, matrices, diagonalizations, observables, theory checks, likelihoods, and outputs.
  • CompiledModelSpec: Python-lowered plan that contains bytecode-like expression programs plus typed node metadata.
  • CompiledModel: immutable C++ evaluation object safe to reuse across many scan points and threads.
  • PointResult: structured result for one point, including outputs, likelihood terms, total likelihood, flags, and invalid-point diagnostics.

Prerequisites

These are only needed for a from-source build -- i.e. cloning this repository, or installing on a platform/Python version outside the prebuilt-wheel matrix above.

  • Python >= 3.10

  • A C++20 compiler (tested with GCC >= 11 and Apple Clang)

  • CMake >= 3.20

  • Eigen3 >= 3.4 -- a system dependency, not vendored. Install it first:

    brew install eigen              # macOS
    sudo apt-get install libeigen3-dev   # Debian/Ubuntu
    conda install -c conda-forge eigen   # conda
    

    CMakeLists.txt also looks under /usr/include, /usr/local/include, and /opt/homebrew/include directly, or you can point it at a specific install with -DEigen3_DIR=/path/to/eigen/share/eigen3/cmake.

Build

Python packaging is driven by scikit-build-core, with CMake building the C++ extension. The root build discovers plugin sources under src/plugins/*.cpp automatically and includes any plugin-local CMake fragments under cmake/plugins/*.cmake, so new backend integrations do not require editing the framework CMakeLists.txt.

pip install -e .

To configure without the optional Diver or Fortran layers:

cmake -S . -B build
cmake --build build -j

To build the native Diver bridge:

CMAKE_ARGS="-DBSM_SCANNER_BUILD_DIVER=ON -DBSM_SCANNER_DIVER_ROOT=/path/to/Diver" \
pip install -e .[dev]

To enable the SciPy differential-evolution reference backend:

python -m pip install -e '.[de]'

Command Line

The installable package exposes a small CLI:

bsm-scanner --help
bsm-scanner --version
python -m bsm_scanner --help
bsm-scanner new-model mymodel
bsm-scanner core list

A lightweight installed smoke example is available without any model file:

bsm-scanner run --example quadratic --run-dir runs/quadratic-smoke

Full physics scans use model-local YAML files, for example:

bsm-scanner run --model models/scotogenic_ma/model_no.yaml --run-dir runs/scotogenic-no

Models that request the external diver engine still require a Diver-enabled native build.

Available scan engines:

  • serial_random
  • diver
  • de_scipy
  • adaptive_diver
  • basin_scan

de_scipy is a reference backend built on scipy.optimize.differential_evolution. It exists to validate the framework's DE engine contract and to provide a comparison baseline.

adaptive_diver is the native model-agnostic adaptive Differential Evolution engine. It uses the same evaluator/objective pipeline as the other engines, supports final-population diagnostics, and can optionally refine elite points with SciPy local minimizers.

basin_scan explores broadly first, clusters the surviving valid points, builds a focused sub-box around each cluster, and runs adaptive_diver inside each box. It is the strongest strategy on benchmarks with a sparse, clustered valid region (see docs/published_benchmark_validation.md), and the weakest on benchmarks where the valid region is a broad, degenerate plateau -- engine choice should follow the shape of the likelihood, not a fixed default.

An optional statistics layer can also post-process completed scan outputs into plot-ready CSV and JSON artifacts. It is configured through a top-level statistics: block, writes under run_directory/statistics, and intentionally does not generate plots inside the framework.

scan.settings is reserved for actual runner controls such as maxgen, population_size, and objective. Unknown keys are rejected instead of being silently echoed into metadata.

Core Reusable YAML

The core tree is for framework-owned YAML that is still declarative rather than hardcoded into the evaluator. It centralizes:

  • shared physics constants
  • ordering-aware neutrino observable blocks
  • CKM observable and construction blocks
  • core/common observable wiring that depends only on declared matrix roles and automatic diagonalization

Models are expected to keep their own:

  • parameters
  • analytic matrix definitions
  • scan settings
  • likelihood blocks and dataset choices
  • plugins or custom likelihood terms when they are genuinely model-specific

models/scotogenic_ma is a full-scale example of this split, and models/minimal_bl the simplest single-file case. See docs/core_model_split.md for the full rationale.

Remote Sync And Build

To sync this workspace to a remote build host and build it there, set the destination first:

export REMOTE_HOST=user@host
export REMOTE_DIR=/path/on/remote/BSMScanner

./scripts/sync_to_remote.sh
./scripts/build_on_remote.sh

Both variables are required; the scripts exit with a message if either is unset.

Benchmark Models

models/ includes exactly the seven published benchmark models used in a companion methodology study comparing the four scan engines at matched budget:

  • scotogenic_ma -- radiative (one-loop) neutrino mass with dark matter
  • minimal_bl -- gauged U(1)_B-L with a seesaw and a Z'
  • two_higgs_doublet -- CP-conserving two-Higgs-doublet model
  • smeft_wilson -- SMEFT, Warsaw basis, 10 Wilson coefficients
  • zprime_simplified -- Z' simplified dark matter (LHC DM Forum benchmark)
  • leptoquark_brw -- Buchmuller-Ruckl-Wyler scalar leptoquark
  • alp_effective -- axion-like-particle effective couplings

Each ships as a standalone model directory under models/<name>/ with a matching runnable example under examples/<name>/. See docs/published_benchmark_validation.md for what is validated formula-by-formula against the cited reference versus what remains a simplified analytic proxy for each benchmark.

Tutorial notebooks (one per published benchmark model, pre-executed) are under notebooks/ -- see notebooks/README.md.

Repository Layout

BSMScanner/
├── CMakeLists.txt
├── pyproject.toml
├── CHANGELOG.md
├── README.md
├── docs/                    # one file per subsystem -- see Documentation below
├── core/                    # reusable, model-independent YAML (core: prefix)
│   ├── constants/
│   └── neutrino/
├── examples/                # small runnable end-to-end examples, one per model
│   └── <name>/
│       ├── model.yaml
│       └── run_scan.py
├── models/                  # standalone model directories (see Benchmark Models)
│   └── <name>/
│       ├── model.yaml
│       ├── parameters.yaml
│       ├── constraints/
│       └── outputs.yaml
├── fortran/
│   └── kernels/
├── include/
│   └── bsm/core/            # C++ evaluation core headers
├── python/
│   └── bsm_scanner/         # Python package: api, compiler, model, scan
├── src/
│   ├── constraints.cpp
│   ├── evaluator.cpp
│   ├── plugins/             # backend plugins, auto-discovered at build time
│   └── scan/
├── notebooks/                # pre-executed tutorial notebooks
│   └── README.md
└── tests/                    # pytest suite
    └── fixtures/

Documentation

Metadata

Release files for bsm-scanner 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bsm-scanner 0.1.8
File Size Uploaded
bsm_scanner-0.1.8.tar.gz 20.8 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for bsm-scanner 0.1.8
File
bsm_scanner-0.1.8-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
bsm_scanner-0.1.8-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
bsm_scanner-0.1.8-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
bsm_scanner-0.1.8-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
bsm_scanner-0.1.8-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
bsm_scanner-0.1.8-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
bsm_scanner-0.1.8-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
bsm_scanner-0.1.8-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 25.2 MB

Release files / bsm_scanner-0.1.8.tar.gz

Download URL bsm_scanner-0.1.8.tar.gz
Size 20.8 MB
Tags Source
SHA-256 checksum
How to use checksums
c8e8aa10b2c4e51d5c9d03aa9a2ee330ffa89de432afe2cb8f6924fab2ea1361
BLAKE2b-256 checksum
How to use checksums
55e489971bd8dbf7f9df42183e9b66a72a72c69177aa9f08ecfc544431c92702
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL bsm_scanner-0.1.8-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 646.5 kB
Tags CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
248890c78c016dd367f2f0464b335c3ba9277b9a236d02e60e8c9065c0619c04
BLAKE2b-256 checksum
How to use checksums
a6a98101700f92169f75539bac73a36fe4966940e3646dc6cbed771729011f71
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp313-cp313-macosx_11_0_arm64.whl

Download URL bsm_scanner-0.1.8-cp313-cp313-macosx_11_0_arm64.whl
Size 465.9 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7cf44e0190c3ab0cb397295ccadb4220f2d5c5b6506e24162a80e9e095a00922
BLAKE2b-256 checksum
How to use checksums
dffb9bf16fce2f4aaafdfacf18e9cb7432268155fa440e8ce869ce9a4c123dbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL bsm_scanner-0.1.8-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 646.4 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
02481728bb0dfde1b5a2e38724bb4be31895f40dd35b346e28802b5f272e6fa5
BLAKE2b-256 checksum
How to use checksums
2f0bf55d58f6d92efa42043e378b6838756ea2612fcc5dcc10f94d302cd29aa7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp312-cp312-macosx_11_0_arm64.whl

Download URL bsm_scanner-0.1.8-cp312-cp312-macosx_11_0_arm64.whl
Size 465.8 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ac5bac0b0906a01ce0e4af72f54a4b5860eaf471839f54eddf5b5a2ff8ee7f07
BLAKE2b-256 checksum
How to use checksums
16862d97ca49d9ff0b60079bda1faec43bd5a8bce0e1ad57c34658a1401b30c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL bsm_scanner-0.1.8-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 642.7 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
91f03fa61964825e385080133441b2edd078966264040650980d3d34ea33f6f2
BLAKE2b-256 checksum
How to use checksums
bc4d4df126149d1dcac8e0a4514576f92e47aa29677c427eacfb84aec5943729
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp311-cp311-macosx_11_0_arm64.whl

Download URL bsm_scanner-0.1.8-cp311-cp311-macosx_11_0_arm64.whl
Size 464.2 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d02d5ab54af2a8ea7c4bffaeb0f07a9c30af4df701bf70cbdfc3a027efbe123d
BLAKE2b-256 checksum
How to use checksums
eaa0127c0dc13810129c11b9c87476f4ce62e1f9993bdc4092634c9ff7d0247a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL bsm_scanner-0.1.8-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 641.8 kB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
0d07130e8e038c34e3a46139061e343380492d590808d173219fd2c2b83111f5
BLAKE2b-256 checksum
How to use checksums
018078f5348505af0efb06773d46ff80d925aedb59c4006372a00e665bbe9298
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / bsm_scanner-0.1.8-cp310-cp310-macosx_11_0_arm64.whl

Download URL bsm_scanner-0.1.8-cp310-cp310-macosx_11_0_arm64.whl
Size 462.8 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2e6dd72ce5eca3808c15421445a22d621982a60010549ad2a6585f6291355449
BLAKE2b-256 checksum
How to use checksums
a6d6bb97f5e2aa9b750563fab3b1477d578603f43cd4ffcac239772345f09c7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

9 release files

This release

0.1.8 This release

9 release files

0.1.7

9 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page