Architecture
Design Principles
- Modular separation: The package is organized into distinct layers — null
stream construction, calibration, likelihood, immutable data, and results
- Scientific correctness: All transforms preserve the physical meaning of
gravitational-wave data
- Testability: Each module has a corresponding test module under
tests/
Project Structure
src/nullcal/
├── data.py # Frozen detector-array container and loader
├── clustering/ # Time-frequency clustering algorithms
│ ├── base.py # Base clustering interface
│ ├── injection.py # Clustering of externally prepared injections
│ ├── precompute.py # Precomputed clustering
│ ├── single.py # Single-detector clustering
│ └── time_frequency_map.py # Time-frequency map representation
├── likelihood/ # Likelihood computations
│ └── recalibration_likelihood.py # Bayesian recalibration likelihood
├── metadata/ # Metadata handling
│ └── yaml.py # YAML metadata serialization
├── null_stream/ # Core null stream logic
│ ├── calibration.py # Calibration parameter handling
│ ├── null_stream.py # Null stream computer
│ ├── projector.py # Null stream projector
│ └── whiten.py # Data whitening
├── result/ # Result analysis
│ ├── result.py # Result container
│ └── utils.py # Result utilities
├── time_frequency_transform/ # Wavelet and STFT transforms
│ ├── inverse_wavelet_freq_funcs.py
│ ├── inverse_wavelet_time_funcs.py
│ ├── stft.py
│ ├── transform_freq_funcs.py
│ ├── transform_time_funcs.py
│ ├── utils.py
│ └── wavelet_transforms.py
├── utils/ # Shared utilities
│ ├── log.py # Logging utilities
│ └── snr.py # Signal-to-noise ratio
└── version.py # Package version
```text
## Data Flow
1. **Input**: Strain data from a closed-geometry detector network
2. **Null Stream**: The `NullStreamComputer` constructs a data combination that
cancels the gravitational-wave signal, leaving only noise
3. **Calibration**: `RecalibrationLikelihood.logdensity_fn(params)` evaluates
the JAX null-stream likelihood and Gaussian knot prior without mutable state
4. **Sampling**: BlackJAX NUTS consumes the pure log density and returns the
package-owned result container with convergence diagnostics
## Extension Points
- New clustering algorithms can be added under `clustering/`
- Additional likelihood models can extend the `likelihood/` module
- Custom time-frequency transforms can be added to `time_frequency_transform/`