NOMAD
NOn-stationary Modulation-Aware Denoiser — an sgn-based reimplementation of NonSENS (Vajente et al., PRD 101, 042003) streaming noise subtraction for gravitational-wave strain data.
NOMAD measures excess noise in a target strain channel from auxiliary "noise
witness" channels that couple into strain through transfer functions whose
amplitude is modulated in time by slow "modulation witness" channels. The
noise estimate is a sum of terms alpha_i(f) * s_i(t), where each s_i is a
modulated signal (noise witness × products of modulation witnesses) and each
alpha_i is an optimal filter learned offline. The stationary case
(modulation_order = 0) is plain multi-channel Wiener filtering.
NOMAD's primary production role is the noise measurement: the SGN
calibration pipeline's CAL-NOLINES → CAL-CLEAN stage is a plain subtractor
that needs some other process to compute what to subtract (in O4 this was the
NonSENS front-end installation). nomad-subtract --measure-only --publish-noise is that process, publishing the noise-estimate channel to
arrakis on witnesses alone. It can also do the subtraction itself and publish
or frame the cleaned channel directly.
Status
- v0.1: streaming application of trained models as an sgn pipeline, reading witness and target channels from arrakis (or frame files) and publishing the noise estimate and/or subtracted strain back to arrakis (or frames).
- v0.2: native model training (
nomad-train, scipy L-BFGS over the analytic cost/gradient — no TensorFlow), plus conversion of original nonsens pickles (nomad-convert-model).
Installation
pip install gw-nomad # runtime
pip install "gw-nomad[convert]" # + dill, for converting original nonsens pickles
pip install "gw-nomad[plot]" # + matplotlib, for nomad-train --report
(The unrelated nomad package on PyPI is a SQL migration tool; install
gw-nomad instead.)
Usage
Train a model (or convert an existing NonSENS pickle):
nomad-train --config lho_isc.yaml --data-source frames \
--frame-cache O4.cache --start 1400000000 --end 1400000600 \
--output lho_isc.h5
nomad-convert-model lho_isc.pickle lho_isc.h5 # legacy pickles
The training config's target defaults to {ifo}:GDS-CALIB_STRAIN_NOLINES:
the noise estimate is consumed downstream of the line subtraction, so
training against NOLINES keeps already-removed lines out of the CSD
estimates. Set target in the config (or pass --target) to train against
any other channel, e.g. raw GDS-CALIB_STRAIN — as in the original nonsens,
the target is simply whatever channel you name. A minimal config:
ifo: H1
noise_witnesses: [ASC-DHARD_P_OUT_DQ, ASC-DHARD_Y_OUT_DQ, 60.0] # numbers = synthesized lines
modulation_witnesses: []
fs: 1024
t_fft: 10
fband: [8, 256]
n_sos: 10
glitches: {band: [15, 20], threshold: 3.0e-20}
Production: measure the excess noise and publish the estimate for the calibration pipeline's CLEAN subtractor (no target channel needed):
export ARRAKIS_SERVER=grpc://...
nomad-subtract --model lho_isc.h5 --data-source arrakis --queue-timeout 30 \
--measure-only --publish-noise --publisher-id nomad-h1 \
--noise-channel-name H1:CAL-NOMAD_NOISE_ESTIMATE
Standalone cleaning — arrakis in, subtracted strain out:
nomad-subtract --model lho_isc.h5 --data-source arrakis --queue-timeout 30 \
--publish-arrakis --publisher-id nomad-h1 \
--output-channel-name H1:GDS-CALIB_STRAIN_NOMAD
Published channels must be pre-registered with the arrakis server under the
given --publisher-id, at the target sample rate (float64). Note the noise
estimate carries the model's FIR high-pass group delay (length/2 seconds)
as stream latency; timestamps are true GPS times, so a timestamp-aligned
downstream subtractor handles it naturally.
Run offline — frames in, frames out:
nomad-subtract --model lho_isc.h5 --data-source frames \
--frame-cache O3.cache --start 1242441180 --end 1242443180 \
--frame-output-path '{instruments}-{description}-{gps_start_time}-{duration}.gwf'
Channels rarely share a frame type (strain lives in HOFT frames, witnesses
in raw R frames); pass each extra cache with --auxiliary-cache
(repeatable). Cache entries are grouped by frame type, one file per type is
probed for its channels, and each channel is read from whichever frame type
provides it — a single concatenated mixed cache works too. This applies to
nomad-train as well.
Development
hatch test # run the test suite
hatch run check # mypy
Golden-comparison tests against the original nonsens implementation are
skipped unless NOMAD_GOLDEN=1 is set and nonsens is importable.
Release files for gw-nomad 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gw_nomad-0.3.0.tar.gz | 274.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gw_nomad-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 373.3 kB
Release files / gw_nomad-0.3.0.tar.gz
| Download URL | gw_nomad-0.3.0.tar.gz |
|---|---|
| Size | 274.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
450324b3ea9eb38431cfe2e494973529da54605cc9cee884b136f0965161a8a5
|
|
BLAKE2b-256 checksum How to use checksums |
b695fde03208e05eb744daad8b02224da30822877e84561d9913f965ef1f5c69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.28.1
|
Release files / gw_nomad-0.3.0-py3-none-any.whl
| Download URL | gw_nomad-0.3.0-py3-none-any.whl |
|---|---|
| Size | 98.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
229a6702df5f27a5e5d5d3422cc4f361c8506ad7b7b6b3b2e5a593f4feeec830
|
|
BLAKE2b-256 checksum How to use checksums |
01bc66898aa0b80a26e292dc300ace302c713efa1fc51d617fa5afd9f089ead6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.28.1
|