BayesWave pipeline integration for Asimov.
This package provides a plugin for Asimov 0.7+ that enables integration with the BayesWave parameter estimation pipeline for gravitational wave data analysis.
- ๐ Plugin Architecture: Seamlessly integrates with Asimov via entry points
- ๐ PSD Generation: Automatic power spectral density estimation and collection
- ๐ Signal/glitch reconstruction: Beyond on-source PSD estimation,
likelihood.componentscan request a signal-only, glitch-only, or combined signal+glitch ("full") BayesWave run, collecting waveform reconstructions, log Bayes factors and (for a signal run) a sky map โ see "Requesting signal/glitch reconstructions" below - ๐ Format Conversion: Converts PSDs to XML format for use with other pipelines
(where
convert_psd_ascii2xmlis available โ see "Operational notes" below) - ๐ Scheduler-agnostic: Automated DAG generation and job submission via Asimov's HTCondor/Slurm scheduler API
- ๐ Result Collection: Automatic collection of megaplot outputs and visualizations
- ๐ฏ PSD Suppression: Support for suppressing frequency bands in PSDs
- ๐งช Well Tested: Unit tests plus a genuine end-to-end test (real
bayeswave_pipeDAG generation and HTCondor execution โBayesWave,BayesWavePost,megaplot.pyโ against real GW150914 H1 GWOSC strain, waiting for a real, parseableglitch_median_PSD_forLI_H1.dat, not a smoke test)
If you have asimov 0.7+, you can install gravitational wave pipelines including bayeswave with:
pip install asimov[gw]This will automatically install asimov-bayeswave and other GW analysis plugins.
pip install asimov-bayeswavegit clone https://github.com/transientlunatic/asimov-bayeswave.git
cd asimov-bayeswave
pip install -e .pip install -e ".[docs,test]"Once installed, the BayesWave pipeline is automatically available in Asimov. To add a new bayeswave analysis you can create a blueprint YAML file like the following:
kind: analysis
pipeline: bayeswave
comment: PSD generation with BayesWave
likelihood:
sample rate: 2048
segment length: 8
data:
channels:
H1: H1:GDS-CALIB_STRAIN
L1: L1:GDS-CALIB_STRAIN
quality:
minimum frequency:
H1: 20
L1: 20By default (no likelihood.components block) a BayesWave analysis only estimates an
on-source PSD, exactly as before. To also (or instead) request BayesWave's signal and/or
glitch wavelet models โ for source reconstructions, a coherence test, or both โ add a
likelihood.components block, following asimov's pipeline-agnostic ledger vocabulary
(nothing pipeline-specific is added to the blueprint):
kind: analysis
pipeline: bayeswave
comment: Signal and glitch reconstruction with BayesWave
likelihood:
sample rate: 2048
segment length: 8
minimum frequency:
H1: 20
L1: 20
components:
signal: wavelets # none | wavelets | chirplets | cbc (cbc: not yet supported)
glitch: wavelets # none | wavelets | chirplets
noise:
psd: fit # fit | fixed (fixed: not yet supported)
lines: true # BayesLine spectral-line modelling
coherence test: true # implies signal: wavelets, glitch: wavelets if not given
data:
channels:
H1: H1:GDS-CALIB_STRAIN
L1: L1:GDS-CALIB_STRAINlikelihood.components.signal/.glitch default to none (unset entirely, or a bare
components: block with neither key given, stays a PSD-only run โ e.g.
components: {noise: {lines: false}} on its own does not turn on signal/glitch).
coherence test: true is the one thing that defaults unset signal/glitch to wavelets.
This resolves to one of five run modes:
likelihood.components / coherence test |
Run mode | BayesWave flag(s) |
|---|---|---|
| nothing given | psd |
--cleanOnly (unchanged) |
signal: none, glitch: none (or components: {}) |
psd |
--cleanOnly |
signal: wavelets, glitch: none |
signal |
--signalOnly |
signal: none, glitch: wavelets |
glitch |
--glitchOnly |
signal: wavelets, glitch: wavelets (no coherence test) |
full |
--fullOnly |
coherence test: true (any components, or none) |
coherence |
(no restriction flag) |
full mode (--fullOnly) runs BayesWave's combined signal+glitch model: it's the right
choice for a joint reconstruction, but BayesWave only writes a single "full" evidence for
it, not separate signal/glitch/noise evidences โ there is no signal:glitch Bayes factor to
compute from a full-mode run. A coherence test instead needs signal, glitch and
noise run as genuinely independent phases so their evidences can be compared; that's
BayesWave's own default model set with no restriction flag at all, which is exactly what
coherence test: true ("coherence" mode) requests. Because of this, coherence test: true combined with signal: none or glitch: none is rejected with a
PipelineException โ a coherence test needs both. On-source PSD estimation ("clean"
model) always runs alongside whichever mode is chosen, so
collect_assets()["psds"]/["xml psds"] keep working the same way regardless of mode.
Once the production completes, collect_assets() additionally returns:
"reconstructions":{component: {ifo: path}}for each of"signal"/"glitch"that was requested โ the median time-domain waveform reconstruction BayesWavePost produces."bayes factors": log Bayes factors parsed from BayesWave'sevidence.dat, e.g.{"signal:noise": 12.3, "signal:glitch": 6.1, "glitch:noise": 6.2}โ only for"coherence"mode (BayesWave always writes placeholder"<model> 0 0"lines toevidence.datfor models that didn't actually run, so this is{}for every other mode, includingfull, rather than risk misleading zero-based Bayes factors)."skymap": path toplots/skymap.png, produced by megaplot.py once a signal model has run.
after_completion() stores the reconstructions to the event repository and the Asimov store
the same way it does PSDs, and merges the Bayes factors into production.meta.
# Build the DAG
asimov manage build --production Prod0
# Submit the job
asimov manage submit --production Prod0
# Monitor progress
asimov manage monitorfrom asimov_bayeswave import BayesWave
# Create pipeline instance
pipeline = BayesWave(production)
# Build and submit
pipeline.build_dag()
pipeline.submit_dag()
# Collect results after completion
assets = pipeline.collect_assets()
psds = assets["psds"]
xml_psds = assets["xml psds"]
reconstructions = assets["reconstructions"] # {} unless likelihood.components requested them
bayes_factors = assets["bayes factors"] # {} likewise- Python >= 3.9
- asimov >= 0.7.0
- numpy
- BayesWave (must be installed separately) โ via conda-forge:
conda install -c conda-forge bayeswave bayeswaveutils
bayeswaveships the compiled samplers (BayesWave,BayesWavePost, ...);bayeswave_pipe(the DAG-generation script this plugin'sbuild_dag()shells out to) andmegaplot.py/megasky.pycome from the separatebayeswaveutilspackage. Unlike the siblingasimov-lalinferenceplugin, nonumpy<2pin is needed โ the current conda-forgebayeswaveutilsbuild'smegaplot.pyhas already been patched for numpy 2.0.
after_completion() tries to convert each ascii-format PSD to XML via a
convert_psd_ascii2xml executable. As of this writing that tool is not shipped by any
current public conda-forge package โ bayeswave, bayeswaveutils, lalinference and
lalapps were all checked while building this plugin's end-to-end test, and none of them
provide it (it may only exist in older or IGWN-internal environments). bayeswave does
ship a BayesWaveToLALPSD executable that looks like a plausible modern replacement, but
its calling convention (positional run name, requires --gnuplot output enabled during
the original run, reads specific paths under waveforms/) is substantially different and
has not been validated here.
This is handled gracefully rather than worked around: after_completion() catches the
resulting PipelineException, logs it, and continues on to store the ascii-format PSD via
store_assets() regardless (see collect_assets()["psds"]). If your environment does
have a working convert_psd_ascii2xml, XML-format PSD conversion and storage will work as
documented above with no changes needed. If not, downstream pipelines that specifically
need an XML-format PSD (rather than the ascii format) won't get one from this plugin until
someone wires up BayesWaveToLALPSD (or an equivalent) as a real replacement.
Full documentation is available at asimov-bayeswave.readthedocs.io.
cd docs
make htmlThe built documentation will be in docs/build/html/.
Run the unit test suite with:
pytestFor coverage reporting:
pytest --cov=asimov_bayeswave --cov-report=html.github/workflows/e2e.yml runs a genuine end-to-end test on real GitHub Actions
infrastructure: a real bayeswave_pipe DAG (BayesWave clean run -> BayesWavePost ->
megaplot.py), submitted to and run by a real (disposable, in-container) HTCondor pool,
against real (trimmed, ~32s) GW150914 H1 GWOSC strain vendored into
tests/test_data/frames/. It waits for and validates a genuine, parseable
glitch_median_PSD_forLI_H1.dat โ the same file detect_completion()/collect_assets()
themselves look for โ not just "the DAG was submitted", and separately checks that a
production reaches a genuinely finished/uploaded state and that the missing
convert_psd_ascii2xml tool (see "Operational notes" above) is handled gracefully. It's
what found several of the real bugs described in CHANGELOG.md.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure:
- All tests pass
- New features include tests
- Documentation is updated
- Code follows PEP 8 style guidelines
If you're upgrading from Asimov 0.6 which included BayesWave support natively:
- Install this plugin:
pip install asimov-bayeswave - The plugin will be automatically discovered by Asimov 0.7+
- No changes to your configuration files are required
This project is licensed under the MIT License - see the LICENSE file for details.
- Daniel Williams (daniel.williams@ligo.org)
- The LIGO Scientific Collaboration
- The BayesWave development team
- The Asimov development team
If you use this software in your research, please cite:
@software{asimov_bayeswave,
author = {Williams, Daniel},
title = {asimov-bayeswave: BayesWave integration for Asimov},
url = {https://github.com/transientlunatic/asimov-bayeswave},
year = {2026}
}For issues, questions, or contributions, please use the GitHub issue tracker.