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.7

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.7
File Size Uploaded
bsm_scanner-0.1.7.tar.gz 20.8 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for bsm-scanner 0.1.7
File
bsm_scanner-0.1.7-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
bsm_scanner-0.1.7-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
bsm_scanner-0.1.7-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.7-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
bsm_scanner-0.1.7-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
bsm_scanner-0.1.7-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
bsm_scanner-0.1.7-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.7-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.7.tar.gz

Download URL bsm_scanner-0.1.7.tar.gz
Size 20.8 MB
Tags Source
SHA-256 checksum
How to use checksums
7d06bd1027f0ea7e687a71106351a4ffee051be8465885a39edd2f07f3afc92e
BLAKE2b-256 checksum
How to use checksums
cca291e862bd051e16ffcde307c5951f49105aef3bc5ea69e94113d2f123a393
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 646.2 kB
Tags CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
9057f28ff88f419a80876edaee9766bf377aea333db4b50355e5b819275b914f
BLAKE2b-256 checksum
How to use checksums
09886fd5f5ca973b0cedb8613eae3dff3abce8a93aeb057ede11dea1397e17a0
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp313-cp313-macosx_11_0_arm64.whl
Size 465.6 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
be24c25e4e2b18fd5cf8fb3f1b87e0642c511cc07fb8e50d8cd2e28a6f5d0e7f
BLAKE2b-256 checksum
How to use checksums
9b1704330e497587a7f95068519171484006443ae084080cb83e0001e674a192
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 646.1 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
dee8d7820d465d45659e7d2aedd4bf2318c8ad855a8e00153768d487c27aabcf
BLAKE2b-256 checksum
How to use checksums
121b2bf0cc954ea64a9caf8016ba348720f4a225ec0176928f88a337ec24dbb3
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp312-cp312-macosx_11_0_arm64.whl
Size 465.5 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
559f3f6289b45f11d0404232b8a721190ea8c331c3edf1dcdbdfa1be10924d26
BLAKE2b-256 checksum
How to use checksums
bb535dc7396dbcbc00181df0ec3d0c30b5d7965596cacce1381d9a3a3a6570df
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 642.4 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
209949507f6dbf3e2830a739a8b68e174f566094c41004468140f8378306f7cf
BLAKE2b-256 checksum
How to use checksums
106dd1ed94306baf14b7dbd9c651de38b68c70d77e8bdc6b232528f42fa4d7ec
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp311-cp311-macosx_11_0_arm64.whl
Size 463.9 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c88abd2976e03fd644e7c795611b5217b22112ca6cc16a3319a00cf306f25619
BLAKE2b-256 checksum
How to use checksums
8f4264ff113264bd95b405e643f6542ea8a135308345eadd8f0e669d572ce747
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 641.5 kB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
014ec18c92d9bb8870b68af018ad5267222a7abd73a780c900138e966463f21a
BLAKE2b-256 checksum
How to use checksums
3ed0fe9e3d6bbc6a1e5e33b1adb99954f57275af4abc948fc39201d49d6b6caf
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 3, 2026.

Transparency log

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

Download URL bsm_scanner-0.1.7-cp310-cp310-macosx_11_0_arm64.whl
Size 462.5 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
1cb26a1f601bae573c13e18e27b420765cde06697bfc9b2af44c1f15c8272bf8
BLAKE2b-256 checksum
How to use checksums
aafe0ad6b2490fa7f3b32423a174b325a812af9f5c0df4d1a910a89ed07dc68b
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 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

9 release files

0.1.8

9 release files

This release

0.1.7 This release

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