glitchgan 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- glitchgan-0.1.0/.gitattributes +1 -0
- glitchgan-0.1.0/.github/workflows/publish.yml +51 -0
- glitchgan-0.1.0/.gitignore +41 -0
- glitchgan-0.1.0/.readthedocs.yaml +16 -0
- glitchgan-0.1.0/MODEL_CARD.md +146 -0
- glitchgan-0.1.0/PKG-INFO +125 -0
- glitchgan-0.1.0/README.md +89 -0
- glitchgan-0.1.0/docs/_static/custom.css +120 -0
- glitchgan-0.1.0/docs/conf.py +83 -0
- glitchgan-0.1.0/docs/guides/installation.rst +58 -0
- glitchgan-0.1.0/docs/guides/overview.rst +84 -0
- glitchgan-0.1.0/docs/guides/quickstart.rst +70 -0
- glitchgan-0.1.0/docs/guides/training.rst +65 -0
- glitchgan-0.1.0/docs/index.rst +40 -0
- glitchgan-0.1.0/environment.yml +51 -0
- glitchgan-0.1.0/history.json +1 -0
- glitchgan-0.1.0/models/README.md +26 -0
- glitchgan-0.1.0/notebooks/evaluation.ipynb +999 -0
- glitchgan-0.1.0/notebooks/gspy_classification.ipynb +420 -0
- glitchgan-0.1.0/notebooks/inject_into_detector_noise.ipynb +449 -0
- glitchgan-0.1.0/pyproject.toml +62 -0
- glitchgan-0.1.0/scripts/convert_keras2_to_keras3.py +145 -0
- glitchgan-0.1.0/scripts/convert_tf_generator.py +73 -0
- glitchgan-0.1.0/scripts/setup_local.sh +75 -0
- glitchgan-0.1.0/setup.cfg +4 -0
- glitchgan-0.1.0/src/glitchgan/__init__.py +5 -0
- glitchgan-0.1.0/src/glitchgan/_version.py +24 -0
- glitchgan-0.1.0/src/glitchgan/glitchgan.py +372 -0
- glitchgan-0.1.0/src/glitchgan/tf/__init__.py +5 -0
- glitchgan-0.1.0/src/glitchgan/tf/gan_models.py +317 -0
- glitchgan-0.1.0/src/glitchgan/tf/model_components.py +202 -0
- glitchgan-0.1.0/src/glitchgan/tf/train.py +162 -0
- glitchgan-0.1.0/src/glitchgan/tf/utils.py +320 -0
- glitchgan-0.1.0/src/glitchgan/utils.py +481 -0
- glitchgan-0.1.0/src/glitchgan.egg-info/PKG-INFO +125 -0
- glitchgan-0.1.0/src/glitchgan.egg-info/SOURCES.txt +43 -0
- glitchgan-0.1.0/src/glitchgan.egg-info/dependency_links.txt +1 -0
- glitchgan-0.1.0/src/glitchgan.egg-info/entry_points.txt +2 -0
- glitchgan-0.1.0/src/glitchgan.egg-info/requires.txt +19 -0
- glitchgan-0.1.0/src/glitchgan.egg-info/top_level.txt +1 -0
- glitchgan-0.1.0/tests/conftest.py +28 -0
- glitchgan-0.1.0/tests/test_glitchgan.py +181 -0
- glitchgan-0.1.0/tests/test_snr.py +58 -0
- glitchgan-0.1.0/weights/pytorch/README.md +38 -0
- glitchgan-0.1.0/weights/tensorflow/generator_210_keras3.keras +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*pkl filter=lfs diff=lfs merge=lfs -text
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.11"
|
|
19
|
+
|
|
20
|
+
- name: Extract version from tag
|
|
21
|
+
id: version
|
|
22
|
+
run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
|
23
|
+
|
|
24
|
+
- name: Build distributions
|
|
25
|
+
env:
|
|
26
|
+
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ steps.version.outputs.version }}
|
|
27
|
+
run: |
|
|
28
|
+
pip install build
|
|
29
|
+
python -m build
|
|
30
|
+
|
|
31
|
+
- name: Upload build artifacts
|
|
32
|
+
uses: actions/upload-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: dist
|
|
35
|
+
path: dist/
|
|
36
|
+
|
|
37
|
+
publish:
|
|
38
|
+
needs: build
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
environment: pypi
|
|
41
|
+
permissions:
|
|
42
|
+
id-token: write # required for Trusted Publisher (OIDC)
|
|
43
|
+
steps:
|
|
44
|
+
- name: Download build artifacts
|
|
45
|
+
uses: actions/download-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: dist
|
|
48
|
+
path: dist/
|
|
49
|
+
|
|
50
|
+
- name: Publish to PyPI
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Data (too large for git — see README for download instructions)
|
|
2
|
+
data/
|
|
3
|
+
|
|
4
|
+
# Generated outputs
|
|
5
|
+
evaluation_plots/
|
|
6
|
+
plots/
|
|
7
|
+
GAN_outputs*/
|
|
8
|
+
|
|
9
|
+
# GravitySpy model weights (large binary — download separately)
|
|
10
|
+
models/
|
|
11
|
+
|
|
12
|
+
# PyTorch weights (not part of published release)
|
|
13
|
+
weights/pytorch/
|
|
14
|
+
|
|
15
|
+
# Python
|
|
16
|
+
__pycache__/
|
|
17
|
+
*.py[cod]
|
|
18
|
+
*.egg-info/
|
|
19
|
+
dist/
|
|
20
|
+
build/
|
|
21
|
+
.eggs/
|
|
22
|
+
*.egg
|
|
23
|
+
src/cdvgan/_version.py
|
|
24
|
+
src/glitchgan/_version.py
|
|
25
|
+
|
|
26
|
+
# Jupyter
|
|
27
|
+
.ipynb_checkpoints/
|
|
28
|
+
|
|
29
|
+
# Environment
|
|
30
|
+
.env
|
|
31
|
+
*.log
|
|
32
|
+
|
|
33
|
+
# macOS
|
|
34
|
+
.DS_Store
|
|
35
|
+
|
|
36
|
+
# Classification output CSVs
|
|
37
|
+
notebooks/*.csv
|
|
38
|
+
|
|
39
|
+
# Sphinx docs build + auto-copied notebooks (canonical copies live in notebooks/)
|
|
40
|
+
docs/_build/
|
|
41
|
+
docs/notebooks/
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
license: mit
|
|
3
|
+
tags:
|
|
4
|
+
- gravitational-waves
|
|
5
|
+
- time-series
|
|
6
|
+
- generative-model
|
|
7
|
+
- gan
|
|
8
|
+
- ligo
|
|
9
|
+
- detector-characterization
|
|
10
|
+
- physics
|
|
11
|
+
library_name: keras
|
|
12
|
+
pipeline_tag: time-series-to-time-series
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# GlitchGAN — Synthetic LIGO Glitch Generator
|
|
16
|
+
|
|
17
|
+
GlitchGAN is a class-conditional generative model that synthesizes realistic
|
|
18
|
+
gravitational-wave detector glitches directly in the time domain.
|
|
19
|
+
It is built on the **cDVGAN** (Conditional Derivative GAN) architecture,
|
|
20
|
+
which uses a first-derivative discriminator alongside the standard signal
|
|
21
|
+
discriminator to enforce temporal smoothness in generated waveforms.
|
|
22
|
+
|
|
23
|
+
The model is trained on high-quality glitch reconstructions produced by
|
|
24
|
+
[DeepExtractor](https://github.com/fbianco/deepextractor), a U-Net framework
|
|
25
|
+
for glitch reconstruction from LIGO strain data, covering seven common glitch
|
|
26
|
+
classes observed during LIGO's third observing run (O3).
|
|
27
|
+
|
|
28
|
+
## Supported glitch classes
|
|
29
|
+
|
|
30
|
+
| Index | Class | Description |
|
|
31
|
+
|-------|-------|-------------|
|
|
32
|
+
| 0 | Blip | Short, broadband transient |
|
|
33
|
+
| 1 | Fast\_Scattering | Arches at low frequency from scattered light |
|
|
34
|
+
| 2 | Koi\_Fish | Low-frequency dispersive burst |
|
|
35
|
+
| 3 | Low\_Frequency\_Burst | Broadband low-frequency transient |
|
|
36
|
+
| 4 | Scattered\_Light | Repeated arch pattern from optical scattering |
|
|
37
|
+
| 5 | Tomte | Short, low-frequency transient |
|
|
38
|
+
| 6 | Whistle | Narrow-band high-frequency chirp |
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install glitchgan
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from cdvgan import GlitchGAN
|
|
48
|
+
|
|
49
|
+
# Download pretrained weights automatically (cached after first call)
|
|
50
|
+
model = GlitchGAN.from_pretrained()
|
|
51
|
+
|
|
52
|
+
# Generate 10 Blip glitches at SNR 50
|
|
53
|
+
blips = model.generate("Blip", n=10, snr=50)
|
|
54
|
+
# blips.shape → (10, 8192) — 2 s at 4096 Hz
|
|
55
|
+
|
|
56
|
+
# Generate a mix of classes
|
|
57
|
+
glitches = model.generate(["Blip", "Tomte", "Whistle"], n=3, snr=30)
|
|
58
|
+
|
|
59
|
+
# Class interpolation — hybrid Blip/Koi Fish morphology
|
|
60
|
+
hybrids = model.interpolate([0.5, 0, 0.5, 0, 0, 0, 0], n=5)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Output waveforms are 2-second segments at 4096 Hz (8192 samples).
|
|
64
|
+
Pass `snr=None` (default) to get the raw normalized generator output,
|
|
65
|
+
or specify a target SNR to rescale to a physically meaningful amplitude.
|
|
66
|
+
|
|
67
|
+
## Model details
|
|
68
|
+
|
|
69
|
+
| Property | Value |
|
|
70
|
+
|----------|-------|
|
|
71
|
+
| Architecture | cDVGAN (conditional WGAN-GP + derivative discriminator) |
|
|
72
|
+
| Signal length | 8192 samples (2 s at 4096 Hz) |
|
|
73
|
+
| Noise dim | 100 |
|
|
74
|
+
| Num classes | 7 |
|
|
75
|
+
| Training epochs | 210 |
|
|
76
|
+
| Optimizer | RMSprop (lr=1e-4) |
|
|
77
|
+
| Gradient penalty weight | 10 |
|
|
78
|
+
| Framework | TensorFlow / Keras 3 |
|
|
79
|
+
|
|
80
|
+
## Training data
|
|
81
|
+
|
|
82
|
+
The model was trained on DeepExtractor reconstructions of real LIGO glitches
|
|
83
|
+
from O3 (2019–2020), curated using [Gravity Spy](https://www.zooniverse.org/projects/zooniverse/gravity-spy)
|
|
84
|
+
classifications.
|
|
85
|
+
Seven glitch classes were selected with balanced class sizes.
|
|
86
|
+
Waveforms are whitened and normalized before training; the generator
|
|
87
|
+
therefore learns a normalized waveform distribution and SNR scaling is
|
|
88
|
+
applied at inference time.
|
|
89
|
+
|
|
90
|
+
## Evaluation
|
|
91
|
+
|
|
92
|
+
Synthetic glitches were evaluated against real data using:
|
|
93
|
+
|
|
94
|
+
1. **Gravity Spy classification** — the fraction of generated samples
|
|
95
|
+
correctly classified by the state-of-the-art Gravity Spy classifier.
|
|
96
|
+
2. **UMAP embeddings** — unsupervised 3-D projections to compare the
|
|
97
|
+
morphological distributions of real and synthetic samples.
|
|
98
|
+
|
|
99
|
+
Selected Gravity Spy results at SNR 100 (100 samples per class):
|
|
100
|
+
|
|
101
|
+
| Class | Accuracy |
|
|
102
|
+
|-------|----------|
|
|
103
|
+
| Blip | 88% |
|
|
104
|
+
| Fast Scattering | 72% |
|
|
105
|
+
| Koi Fish | 20% (SNR-sensitive; 79% at SNR 150) |
|
|
106
|
+
| Low Frequency Burst | 100% |
|
|
107
|
+
| Scattered Light | 42% (often confused with Fast Scattering) |
|
|
108
|
+
| Tomte | 92% |
|
|
109
|
+
| Whistle | 94% |
|
|
110
|
+
|
|
111
|
+
UMAP embeddings show strong overlap between real and synthetic samples
|
|
112
|
+
for most classes. Whistle glitches show partial separation, attributed to
|
|
113
|
+
the model's difficulty with fine-scale high-frequency structure.
|
|
114
|
+
|
|
115
|
+
## Limitations
|
|
116
|
+
|
|
117
|
+
- **SNR sensitivity**: GlitchGAN does not model an SNR distribution.
|
|
118
|
+
Generated waveforms must be manually rescaled. Classification accuracy
|
|
119
|
+
for morphologically ambiguous classes (Koi Fish, Scattered Light) is
|
|
120
|
+
strongly SNR-dependent.
|
|
121
|
+
- **Whistle class**: Synthetic Whistle glitches form a partially distinct
|
|
122
|
+
cluster from real data in UMAP space, indicating incomplete capture of
|
|
123
|
+
high-frequency structure.
|
|
124
|
+
- **Seven classes only**: The model covers the seven classes present in
|
|
125
|
+
the O3 training set. It cannot generate unseen glitch morphologies.
|
|
126
|
+
- **LIGO-specific**: Trained on LIGO H1/L1 data. Generalization to Virgo
|
|
127
|
+
or KAGRA data has not been evaluated.
|
|
128
|
+
|
|
129
|
+
## Citation
|
|
130
|
+
|
|
131
|
+
If you use GlitchGAN in your work, please cite:
|
|
132
|
+
|
|
133
|
+
```bibtex
|
|
134
|
+
@article{Dooney2026GlitchGAN,
|
|
135
|
+
title = {Realistic Time-Domain Synthesis of Gravitational-Wave Detector
|
|
136
|
+
Glitches using Class-Conditional Derivative Generative Adversarial Networks},
|
|
137
|
+
author = {Dooney, Tom and de Boer, Mees and Narola, Harsh and Lopez, Melissa
|
|
138
|
+
and Bromuri, Stefano and Tan, Daniel Stanley and Van Den Broeck, Chris},
|
|
139
|
+
journal = {Physical Review D},
|
|
140
|
+
year = {2026},
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT
|
glitchgan-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: glitchgan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Synthetic LIGO gravitational-wave glitch generator (cDVGAN architecture)
|
|
5
|
+
Author-email: Tom Dooney <tom.dooney95@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/tomdooney95/glitchgan
|
|
8
|
+
Project-URL: Documentation, https://glitchgan.readthedocs.io/
|
|
9
|
+
Keywords: gravitational-waves,LIGO,GAN,glitch,machine-learning
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: numpy>=1.26
|
|
21
|
+
Requires-Dist: matplotlib>=3.9
|
|
22
|
+
Requires-Dist: huggingface_hub>=0.23
|
|
23
|
+
Requires-Dist: tensorflow>=2.16
|
|
24
|
+
Requires-Dist: keras>=3.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
28
|
+
Provides-Extra: docs
|
|
29
|
+
Requires-Dist: sphinx>=7; extra == "docs"
|
|
30
|
+
Requires-Dist: sphinx-autoapi>=3; extra == "docs"
|
|
31
|
+
Requires-Dist: furo>=2024.1.29; extra == "docs"
|
|
32
|
+
Requires-Dist: myst-parser>=3; extra == "docs"
|
|
33
|
+
Requires-Dist: nbsphinx>=0.9; extra == "docs"
|
|
34
|
+
Provides-Extra: all
|
|
35
|
+
Requires-Dist: glitchgan[dev,docs]; extra == "all"
|
|
36
|
+
|
|
37
|
+
# GlitchGAN
|
|
38
|
+
|
|
39
|
+
Conditional Dual-discriminator Variational GAN (cDVGAN) for synthesising LIGO gravitational-wave glitch signals. Trained on seven Gravity Spy glitch classes from the O3 observing run.
|
|
40
|
+
|
|
41
|
+
## Overview
|
|
42
|
+
|
|
43
|
+
GlitchGAN uses a Wasserstein GAN with gradient penalty (WGAN-GP) augmented by a first-derivative discriminator. The derivative discriminator encourages the generator to produce signals with realistic time-domain structure, not just realistic amplitude distributions.
|
|
44
|
+
|
|
45
|
+
**Architecture:** Generator + Discriminator + Derivative Discriminator
|
|
46
|
+
**Classes:** Blip, Fast Scattering, Koi Fish, Low Frequency Burst, Scattered Light, Tomte, Whistle
|
|
47
|
+
**Signal length:** 8192 samples @ 4096 Hz (~2 s)
|
|
48
|
+
|
|
49
|
+
## Repository structure
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
glitchgan/
|
|
53
|
+
├── evaluation.ipynb # UMAP + GravitySpy evaluation notebook
|
|
54
|
+
├── src/cdvgan/
|
|
55
|
+
│ ├── tf/
|
|
56
|
+
│ │ ├── model_components.py # Generator / discriminator layers
|
|
57
|
+
│ │ ├── gan_models.py # cWGAN, cDVGAN, cDVGAN2, GlitchGAN
|
|
58
|
+
│ │ ├── train.py # Training entry point
|
|
59
|
+
│ │ └── utils.py # Dataset, callbacks, checkpointing
|
|
60
|
+
│ └── utils.py # Signal processing utilities
|
|
61
|
+
├── weights/tensorflow/
|
|
62
|
+
│ └── generator_210_keras3.keras # Trained generator (epoch 210)
|
|
63
|
+
├── models/ # GravitySpy CNN weights (gitignored — see below)
|
|
64
|
+
├── data/ # Training data (gitignored — see below)
|
|
65
|
+
└── environment.yml
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Setup
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
conda env create -f environment.yml
|
|
72
|
+
conda activate cdvgan
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The environment installs TensorFlow, Keras 3, GWpy, PyCBC, umap-learn, and GravitySpy.
|
|
76
|
+
|
|
77
|
+
> **Note:** `environment.yml` targets Apple Silicon (tensorflow-macos / tensorflow-metal). On Linux/HPC replace those with `tensorflow` and remove `tensorflow-metal`.
|
|
78
|
+
|
|
79
|
+
## Data
|
|
80
|
+
|
|
81
|
+
The training data (~2.3 GB) is not included in this repository.
|
|
82
|
+
|
|
83
|
+
**Download from Zenodo:** *(link TBD — will be added before publication)*
|
|
84
|
+
|
|
85
|
+
Place the downloaded files in `data/`:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
data/
|
|
89
|
+
├── glitch_GAN_samples_scaled_balanced.npy # (N, 8192) float32 signals
|
|
90
|
+
├── glitch_GAN_labels_balanced.npy # (N, 7) one-hot labels
|
|
91
|
+
└── glitch_GAN_label_order.npy # class name ordering
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## GravitySpy model
|
|
95
|
+
|
|
96
|
+
The GravitySpy O3 CNN (`sidd-cqg-paper-O3-model.h5`) is not included. It ships with the `gravityspy` package or can be found in a local GravitySpy clone.
|
|
97
|
+
|
|
98
|
+
1. Install GravitySpy: `pip install gravityspy`
|
|
99
|
+
2. Copy the model to `models/sidd-cqg-paper-O3-model.h5`
|
|
100
|
+
3. Set `PATH_TO_REPO` in `evaluation.ipynb` to your GravitySpy clone path
|
|
101
|
+
|
|
102
|
+
## Training
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
python -m cdvgan.tf.train \
|
|
106
|
+
--data-dir data/ \
|
|
107
|
+
--variant cDVGAN \
|
|
108
|
+
--epochs 500 \
|
|
109
|
+
--output-dir GAN_outputs/
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
See `src/cdvgan/tf/train.py` for all options.
|
|
113
|
+
|
|
114
|
+
## Evaluation
|
|
115
|
+
|
|
116
|
+
Open `evaluation.ipynb` and run all cells. The notebook:
|
|
117
|
+
|
|
118
|
+
1. Loads real glitch data and the trained generator
|
|
119
|
+
2. Visualises real vs generated waveforms
|
|
120
|
+
3. Embeds real and generated signals jointly in 3D UMAP space (correlation metric)
|
|
121
|
+
4. Injects generated signals into whitened H1 background and classifies with GravitySpy
|
|
122
|
+
|
|
123
|
+
## Citation
|
|
124
|
+
|
|
125
|
+
*(BibTeX will be added upon publication)*
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# GlitchGAN
|
|
2
|
+
|
|
3
|
+
Conditional Dual-discriminator Variational GAN (cDVGAN) for synthesising LIGO gravitational-wave glitch signals. Trained on seven Gravity Spy glitch classes from the O3 observing run.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
GlitchGAN uses a Wasserstein GAN with gradient penalty (WGAN-GP) augmented by a first-derivative discriminator. The derivative discriminator encourages the generator to produce signals with realistic time-domain structure, not just realistic amplitude distributions.
|
|
8
|
+
|
|
9
|
+
**Architecture:** Generator + Discriminator + Derivative Discriminator
|
|
10
|
+
**Classes:** Blip, Fast Scattering, Koi Fish, Low Frequency Burst, Scattered Light, Tomte, Whistle
|
|
11
|
+
**Signal length:** 8192 samples @ 4096 Hz (~2 s)
|
|
12
|
+
|
|
13
|
+
## Repository structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
glitchgan/
|
|
17
|
+
├── evaluation.ipynb # UMAP + GravitySpy evaluation notebook
|
|
18
|
+
├── src/cdvgan/
|
|
19
|
+
│ ├── tf/
|
|
20
|
+
│ │ ├── model_components.py # Generator / discriminator layers
|
|
21
|
+
│ │ ├── gan_models.py # cWGAN, cDVGAN, cDVGAN2, GlitchGAN
|
|
22
|
+
│ │ ├── train.py # Training entry point
|
|
23
|
+
│ │ └── utils.py # Dataset, callbacks, checkpointing
|
|
24
|
+
│ └── utils.py # Signal processing utilities
|
|
25
|
+
├── weights/tensorflow/
|
|
26
|
+
│ └── generator_210_keras3.keras # Trained generator (epoch 210)
|
|
27
|
+
├── models/ # GravitySpy CNN weights (gitignored — see below)
|
|
28
|
+
├── data/ # Training data (gitignored — see below)
|
|
29
|
+
└── environment.yml
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Setup
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
conda env create -f environment.yml
|
|
36
|
+
conda activate cdvgan
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The environment installs TensorFlow, Keras 3, GWpy, PyCBC, umap-learn, and GravitySpy.
|
|
40
|
+
|
|
41
|
+
> **Note:** `environment.yml` targets Apple Silicon (tensorflow-macos / tensorflow-metal). On Linux/HPC replace those with `tensorflow` and remove `tensorflow-metal`.
|
|
42
|
+
|
|
43
|
+
## Data
|
|
44
|
+
|
|
45
|
+
The training data (~2.3 GB) is not included in this repository.
|
|
46
|
+
|
|
47
|
+
**Download from Zenodo:** *(link TBD — will be added before publication)*
|
|
48
|
+
|
|
49
|
+
Place the downloaded files in `data/`:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
data/
|
|
53
|
+
├── glitch_GAN_samples_scaled_balanced.npy # (N, 8192) float32 signals
|
|
54
|
+
├── glitch_GAN_labels_balanced.npy # (N, 7) one-hot labels
|
|
55
|
+
└── glitch_GAN_label_order.npy # class name ordering
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## GravitySpy model
|
|
59
|
+
|
|
60
|
+
The GravitySpy O3 CNN (`sidd-cqg-paper-O3-model.h5`) is not included. It ships with the `gravityspy` package or can be found in a local GravitySpy clone.
|
|
61
|
+
|
|
62
|
+
1. Install GravitySpy: `pip install gravityspy`
|
|
63
|
+
2. Copy the model to `models/sidd-cqg-paper-O3-model.h5`
|
|
64
|
+
3. Set `PATH_TO_REPO` in `evaluation.ipynb` to your GravitySpy clone path
|
|
65
|
+
|
|
66
|
+
## Training
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
python -m cdvgan.tf.train \
|
|
70
|
+
--data-dir data/ \
|
|
71
|
+
--variant cDVGAN \
|
|
72
|
+
--epochs 500 \
|
|
73
|
+
--output-dir GAN_outputs/
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
See `src/cdvgan/tf/train.py` for all options.
|
|
77
|
+
|
|
78
|
+
## Evaluation
|
|
79
|
+
|
|
80
|
+
Open `evaluation.ipynb` and run all cells. The notebook:
|
|
81
|
+
|
|
82
|
+
1. Loads real glitch data and the trained generator
|
|
83
|
+
2. Visualises real vs generated waveforms
|
|
84
|
+
3. Embeds real and generated signals jointly in 3D UMAP space (correlation metric)
|
|
85
|
+
4. Injects generated signals into whitened H1 background and classifies with GravitySpy
|
|
86
|
+
|
|
87
|
+
## Citation
|
|
88
|
+
|
|
89
|
+
*(BibTeX will be added upon publication)*
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/* ── GlitchGAN custom dark theme ─────────────────────────────────────── */
|
|
2
|
+
|
|
3
|
+
/* Force dark mode as default */
|
|
4
|
+
:root {
|
|
5
|
+
color-scheme: dark;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/* Code blocks */
|
|
9
|
+
[data-theme="dark"] div[class*="highlight"] {
|
|
10
|
+
background: #161b27;
|
|
11
|
+
border: 1px solid #2a3147;
|
|
12
|
+
border-radius: 6px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
[data-theme="dark"] pre {
|
|
16
|
+
background: #161b27 !important;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Inline code */
|
|
20
|
+
[data-theme="dark"] code.literal {
|
|
21
|
+
background: #1c2333;
|
|
22
|
+
border: 1px solid #2a3147;
|
|
23
|
+
border-radius: 4px;
|
|
24
|
+
color: #79c0ff;
|
|
25
|
+
padding: 1px 5px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Tables */
|
|
29
|
+
[data-theme="dark"] table.docutils {
|
|
30
|
+
border: 1px solid #2a3147;
|
|
31
|
+
border-radius: 6px;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[data-theme="dark"] table.docutils th {
|
|
36
|
+
background: #161b27;
|
|
37
|
+
color: #e6edf3;
|
|
38
|
+
border-bottom: 2px solid #2a3147;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[data-theme="dark"] table.docutils td {
|
|
42
|
+
border-color: #2a3147;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
[data-theme="dark"] table.docutils tr:hover td {
|
|
46
|
+
background: #1c2333;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Admonition boxes */
|
|
50
|
+
[data-theme="dark"] .admonition {
|
|
51
|
+
border-radius: 6px;
|
|
52
|
+
border-left: 4px solid var(--color-brand-primary);
|
|
53
|
+
background: #161b27;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[data-theme="dark"] .admonition.note {
|
|
57
|
+
border-left-color: #58a6ff;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[data-theme="dark"] .admonition.warning {
|
|
61
|
+
border-left-color: #d29922;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
[data-theme="dark"] .admonition.tip {
|
|
65
|
+
border-left-color: #3fb950;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Sidebar logo / title */
|
|
69
|
+
.sidebar-brand-text {
|
|
70
|
+
font-weight: 700;
|
|
71
|
+
letter-spacing: 0.02em;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Content headings */
|
|
75
|
+
[data-theme="dark"] h1,
|
|
76
|
+
[data-theme="dark"] h2,
|
|
77
|
+
[data-theme="dark"] h3 {
|
|
78
|
+
color: #e6edf3;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[data-theme="dark"] h1 {
|
|
82
|
+
border-bottom: 1px solid #2a3147;
|
|
83
|
+
padding-bottom: 0.3em;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* API reference member entries */
|
|
87
|
+
[data-theme="dark"] dl.py dt {
|
|
88
|
+
background: #161b27;
|
|
89
|
+
border-left: 3px solid #58a6ff;
|
|
90
|
+
border-radius: 0 4px 4px 0;
|
|
91
|
+
padding: 4px 8px;
|
|
92
|
+
color: #79c0ff;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Search bar */
|
|
96
|
+
[data-theme="dark"] input[type="search"] {
|
|
97
|
+
background: #161b27;
|
|
98
|
+
border: 1px solid #2a3147;
|
|
99
|
+
color: #e6edf3;
|
|
100
|
+
border-radius: 6px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Scrollbar */
|
|
104
|
+
[data-theme="dark"] ::-webkit-scrollbar {
|
|
105
|
+
width: 6px;
|
|
106
|
+
height: 6px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
[data-theme="dark"] ::-webkit-scrollbar-track {
|
|
110
|
+
background: #0d1117;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
[data-theme="dark"] ::-webkit-scrollbar-thumb {
|
|
114
|
+
background: #2a3147;
|
|
115
|
+
border-radius: 3px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover {
|
|
119
|
+
background: #58a6ff;
|
|
120
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
|
|
4
|
+
# Auto-copy notebooks into docs/notebooks/ so Sphinx can include them in the
|
|
5
|
+
# toctree (Sphinx cannot reference files outside its source directory).
|
|
6
|
+
# docs/notebooks/ is gitignored — the canonical copies live in notebooks/.
|
|
7
|
+
_here = os.path.dirname(__file__)
|
|
8
|
+
_nb_src = os.path.join(_here, "..", "notebooks")
|
|
9
|
+
_nb_dst = os.path.join(_here, "notebooks")
|
|
10
|
+
os.makedirs(_nb_dst, exist_ok=True)
|
|
11
|
+
for _nb in [
|
|
12
|
+
"evaluation.ipynb",
|
|
13
|
+
"gspy_classification.ipynb",
|
|
14
|
+
"inject_into_detector_noise.ipynb",
|
|
15
|
+
]:
|
|
16
|
+
_src = os.path.join(_nb_src, _nb)
|
|
17
|
+
if os.path.exists(_src):
|
|
18
|
+
shutil.copy(_src, os.path.join(_nb_dst, _nb))
|
|
19
|
+
|
|
20
|
+
project = "GlitchGAN"
|
|
21
|
+
author = "Tom Dooney"
|
|
22
|
+
copyright = "2026, Tom Dooney"
|
|
23
|
+
html_title = "GlitchGAN"
|
|
24
|
+
|
|
25
|
+
extensions = [
|
|
26
|
+
"sphinx.ext.autodoc",
|
|
27
|
+
"sphinx.ext.autosummary",
|
|
28
|
+
"sphinx.ext.napoleon", # Google/NumPy-style docstrings
|
|
29
|
+
"sphinx.ext.viewcode",
|
|
30
|
+
"sphinx.ext.intersphinx",
|
|
31
|
+
"autoapi.extension",
|
|
32
|
+
"myst_parser", # Markdown support
|
|
33
|
+
"nbsphinx", # Render Jupyter notebooks
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
autoapi_dirs = ["../src"]
|
|
37
|
+
autoapi_type = "python"
|
|
38
|
+
autoapi_options = ["members", "undoc-members", "show-inheritance"]
|
|
39
|
+
|
|
40
|
+
intersphinx_mapping = {
|
|
41
|
+
"python": ("https://docs.python.org/3", None),
|
|
42
|
+
"numpy": ("https://numpy.org/doc/stable", None),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
html_theme = "furo"
|
|
46
|
+
html_static_path = ["_static"]
|
|
47
|
+
html_css_files = ["custom.css"]
|
|
48
|
+
|
|
49
|
+
html_theme_options = {
|
|
50
|
+
"dark_css_variables": {
|
|
51
|
+
"--color-background-primary": "#0f1117",
|
|
52
|
+
"--color-background-secondary": "#161b27",
|
|
53
|
+
"--color-background-hover": "#1c2333",
|
|
54
|
+
"--color-background-border": "#2a3147",
|
|
55
|
+
"--color-brand-primary": "#58a6ff",
|
|
56
|
+
"--color-brand-content": "#79c0ff",
|
|
57
|
+
"--color-foreground-primary": "#e6edf3",
|
|
58
|
+
"--color-foreground-secondary": "#8b949e",
|
|
59
|
+
"--color-foreground-muted": "#6e7681",
|
|
60
|
+
"--color-foreground-border": "#30363d",
|
|
61
|
+
"--color-sidebar-background": "#0d1117",
|
|
62
|
+
"--color-sidebar-background-border": "#21262d",
|
|
63
|
+
"--color-sidebar-brand-text": "#e6edf3",
|
|
64
|
+
"--color-sidebar-caption-text": "#8b949e",
|
|
65
|
+
"--color-sidebar-link-text": "#c9d1d9",
|
|
66
|
+
"--color-sidebar-link-text--top-level": "#e6edf3",
|
|
67
|
+
"--color-sidebar-item-background--current": "#1f2937",
|
|
68
|
+
"--color-sidebar-item-background--hover": "#1c2333",
|
|
69
|
+
"--color-sidebar-item-expander-background--hover": "#1c2333",
|
|
70
|
+
"--color-inline-code-background": "#1c2333",
|
|
71
|
+
"--color-admonition-background": "#161b27",
|
|
72
|
+
},
|
|
73
|
+
"light_css_variables": {
|
|
74
|
+
"--color-brand-primary": "#0969da",
|
|
75
|
+
"--color-brand-content": "#0969da",
|
|
76
|
+
},
|
|
77
|
+
"navigation_with_keys": True,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exclude_patterns = ["_build", "**/_build", "**.ipynb_checkpoints"]
|
|
81
|
+
|
|
82
|
+
# Do not re-execute notebooks during the docs build
|
|
83
|
+
nbsphinx_execute = "never"
|