nrcats
A stable, unified Python interface to public numerical-relativity (NR) binary black-hole waveform catalogs — for LVK analyses, waveform modeling, and cross-catalog comparison.
Install Quick start View on GitHub
What it does
nrcats serves three overlapping communities with one API:
- LIGO-Virgo-KAGRA analyses — reliable, PyCBC-compatible waveform time series and source-parameter dicts for parameter estimation, injection studies, and template bank construction, with consistent physical units (masses in M☉, distances in Mpc, epoch at the (2,2) peak) across all backends
- Waveform modeling — consistent loading, physical scaling, and frame-alignment tools
(Wigner D-matrix rotations,
f_lowerextraction, time/phase alignment) for calibrating and validating EOB, phenomenological, and surrogate models against any NR catalog - Cross-catalog studies — noise-weighted mismatch computation maximized over time and phase shifts, \(SO(3)\) rotations, and BMS supertranslations, for quantifying NR waveform accuracy across codes
All catalog backends expose an identical interface (defined by
CatalogBase), so analysis code written against one catalog works
against all others without modification.
Supported catalogs
| Catalog | Code | Example simulation name |
|---|---|---|
| SXS | SpEC | SXS:BBH:0001 |
| RIT | LazEv | RIT:BBH:0001-n100-id3 |
| MAYA / GT | MayaKranc | GT0001 |
New catalogs can be added without touching core code via the plugin registry.
Quick start
import nrcats as nrcat
# Load catalogs (explicit class methods)
ritcat = nrcat.RITCatalog.load()
sxscat = nrcat.SXSCatalog.load(download=False)
mayacat = nrcat.MayaCatalog.load()
# ...or use the unified helper
ritcat = nrcat.load_catalog("RIT")
# Browse simulations
print(ritcat.simulations_dataframe.index)
# Index(['RIT:BBH:0001-n100-id3', 'RIT:BBH:0002-n100-id0', ...], length=1879)
# Load a waveform
wfm = ritcat.get("RIT:BBH:0003-n100-id0")
print(wfm.LM) # available (ell, m) mode pairs
# Extract the (2,2) mode in physical units
mode22 = wfm.get_mode(2, 2, total_mass=60.0, distance=100.0,
delta_t_seconds=1./4096)
# Polarizations
pols = wfm.get_td_waveform(total_mass=40., distance=100.,
inclination=0.2, coa_phase=0.3)
hp, hc = pols.real(), -1 * pols.imag()
# PyCBC-compatible source parameters
params = ritcat.get_parameters("RIT:BBH:0001-n100-id3", total_mass=60.0)
# {'mass1': 30.0, 'mass2': 30.0, 'spin1x': 0.0, ..., 'f_lower': 23.4}
For a step-by-step walkthrough, start with the Loading a waveform tutorial.
Documentation map
| Section | What you’ll find |
|---|---|
| Installation | pip/conda install, dependencies, cache configuration |
| Tutorials | Worked examples: loading waveforms, cross-catalog mismatches, surrogate comparison |
| Catalog Reference | Per-catalog loading, metadata keys, file formats, cache layout |
| Catalog Organization | Spin/eccentricity classification of the three catalogs |
| WaveformModes Guide | Conceptual guide to the central waveform object and its unit conventions |
| Architecture | Class hierarchy, data flows, key design decisions |
| API Reference | Per-module reference generated from the source docstrings |
| Package Internals | Detailed module descriptions, unit conventions, usage patterns, gotchas |
| Scientific Goal | Motivation, source-frame ambiguity, BMS supertranslations, mismatch formalism |
| Contributing | Development setup, tests, docs builds, adding a new catalog |
| Changelog | Release history |
Module structure
nrcats/
├── __init__.py # Public API: RITCatalog, SXSCatalog, MayaCatalog,
│ # WaveformModes, load_catalog, registry, key maps
├── catalog.py # Abstract base CatalogABC + shared CatalogBase
├── rit.py # RITCatalog + RITCatalogHelper
├── sxs.py # SXSCatalog
├── maya.py # MayaCatalog
├── registry.py # @register_catalog plugin mechanism
├── metadata.py # Cross-catalog key maps + get_source_parameters_from_metadata
├── classification.py # Spin/eccentricity classification of catalog simulations
├── surrogate.py # NRSur7dq4 loading, evaluation, prior check
├── comparisons.py # End-to-end NR vs surrogate comparison pipeline
├── waveform/ # WaveformModes sub-package
│ ├── modes.py # WaveformModes class
│ ├── loaders.py # load_from_h5, load_from_targz
│ ├── matching.py # mode matching, Wigner rotation, PSD helpers
│ └── units.py # waveform-level constants
├── lvc.py # Frame-rotation helpers and LVCNR format utilities
├── utils.py # Cache paths, download helpers, unit conversions
└── schemas/ # YAML key-mapping tables (rit/sxs/maya)