desisky 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.
Files changed (56) hide show
  1. desisky-0.1.0/.github/workflows/tests.yml +32 -0
  2. desisky-0.1.0/.gitignore +107 -0
  3. desisky-0.1.0/CHANGELOG.md +50 -0
  4. desisky-0.1.0/LICENSE.txt +9 -0
  5. desisky-0.1.0/PKG-INFO +426 -0
  6. desisky-0.1.0/README.md +370 -0
  7. desisky-0.1.0/docs/VAE_TRAINING.md +423 -0
  8. desisky-0.1.0/examples/00_quickstart.ipynb +753 -0
  9. desisky-0.1.0/examples/01_broadband_training.ipynb +539 -0
  10. desisky-0.1.0/examples/02_vae_inference.ipynb +487 -0
  11. desisky-0.1.0/examples/03_vae_analysis.ipynb +807 -0
  12. desisky-0.1.0/examples/04_vae_training.ipynb +507 -0
  13. desisky-0.1.0/examples/05_ldm_inference.ipynb +544 -0
  14. desisky-0.1.0/examples/06_ldm_training.ipynb +675 -0
  15. desisky-0.1.0/pyproject.toml +80 -0
  16. desisky-0.1.0/pytest.ini +25 -0
  17. desisky-0.1.0/src/desisky/__about__.py +4 -0
  18. desisky-0.1.0/src/desisky/__init__.py +20 -0
  19. desisky-0.1.0/src/desisky/data/__init__.py +32 -0
  20. desisky-0.1.0/src/desisky/data/_core.py +159 -0
  21. desisky-0.1.0/src/desisky/data/_enrich.py +636 -0
  22. desisky-0.1.0/src/desisky/data/skyspec.py +451 -0
  23. desisky-0.1.0/src/desisky/inference/__init__.py +15 -0
  24. desisky-0.1.0/src/desisky/inference/sampling.py +548 -0
  25. desisky-0.1.0/src/desisky/io/__init__.py +40 -0
  26. desisky-0.1.0/src/desisky/io/model_io.py +397 -0
  27. desisky-0.1.0/src/desisky/models/__init__.py +3 -0
  28. desisky-0.1.0/src/desisky/models/broadband.py +27 -0
  29. desisky-0.1.0/src/desisky/models/ldm.py +650 -0
  30. desisky-0.1.0/src/desisky/models/vae.py +324 -0
  31. desisky-0.1.0/src/desisky/scripts/__init__.py +3 -0
  32. desisky-0.1.0/src/desisky/scripts/download_data.py +59 -0
  33. desisky-0.1.0/src/desisky/scripts/train_vae.py +440 -0
  34. desisky-0.1.0/src/desisky/training/README.md +187 -0
  35. desisky-0.1.0/src/desisky/training/__init__.py +50 -0
  36. desisky-0.1.0/src/desisky/training/dataset.py +264 -0
  37. desisky-0.1.0/src/desisky/training/ldm_trainer.py +535 -0
  38. desisky-0.1.0/src/desisky/training/losses.py +129 -0
  39. desisky-0.1.0/src/desisky/training/trainer.py +375 -0
  40. desisky-0.1.0/src/desisky/training/vae_losses.py +255 -0
  41. desisky-0.1.0/src/desisky/training/vae_trainer.py +521 -0
  42. desisky-0.1.0/src/desisky/visualization/__init__.py +12 -0
  43. desisky-0.1.0/src/desisky/visualization/plots.py +318 -0
  44. desisky-0.1.0/src/desisky/weights/broadband_weights.eqx +0 -0
  45. desisky-0.1.0/tests/__init__.py +3 -0
  46. desisky-0.1.0/tests/conftest.py +47 -0
  47. desisky-0.1.0/tests/test_data_download.py +417 -0
  48. desisky-0.1.0/tests/test_enrichment.py +687 -0
  49. desisky-0.1.0/tests/test_external_weights.py +177 -0
  50. desisky-0.1.0/tests/test_ldm_sampling.py +378 -0
  51. desisky-0.1.0/tests/test_ldm_training.py +522 -0
  52. desisky-0.1.0/tests/test_model_io.py +390 -0
  53. desisky-0.1.0/tests/test_training.py +344 -0
  54. desisky-0.1.0/tests/test_vae.py +497 -0
  55. desisky-0.1.0/tests/test_vae_training.py +580 -0
  56. desisky-0.1.0/tests/test_visualization.py +266 -0
@@ -0,0 +1,32 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ pytest:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.10", "3.11"]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+
21
+ - name: Upgrade pip
22
+ run: python -m pip install -U pip
23
+
24
+ - name: Install deps (CPU track + data + viz + pytest)
25
+ run: |
26
+ python -m pip install -e .[cpu,data,viz]
27
+ python -m pip install pytest pytest-cov pytest-env
28
+
29
+ - name: Run tests
30
+ env:
31
+ JAX_PLATFORM_NAME: cpu
32
+ run: pytest -q
@@ -0,0 +1,107 @@
1
+ # OS cruft
2
+ .DS_Store
3
+ Thumbs.db
4
+
5
+ # Python bytecode / compiled extensions
6
+ __pycache__/
7
+ *.py[cod]
8
+ *.pyd
9
+ *.so
10
+ .Python
11
+
12
+ # Builds / packaging
13
+ build/
14
+ dist/
15
+ downloads/
16
+ .eggs/
17
+ *.egg-info/
18
+ *.egg
19
+ wheels/
20
+ share/python-wheels/
21
+ pip-wheel-metadata/
22
+ MANIFEST
23
+
24
+ # Virtual environments
25
+ .venv/
26
+ venv/
27
+ ENV/
28
+ env/
29
+ .env/
30
+ .python-version
31
+
32
+ # Conda (only matters if you ever create envs in-repo)
33
+ conda-bld/
34
+ .conda/
35
+ #mamba/
36
+ #.conda-env/
37
+
38
+ # Jupyter
39
+ .ipynb_checkpoints/
40
+ **/.ipynb_checkpoints/
41
+ *.nbconvert.ipynb
42
+ *.nb.html
43
+ nbconvert/
44
+
45
+ # Tests / coverage / tooling caches
46
+ .pytest_cache/
47
+ .coverage
48
+ .coverage.*
49
+ htmlcov/
50
+ .tox/
51
+ .nox/
52
+ .hypothesis/
53
+ .mypy_cache/
54
+ .ruff_cache/
55
+ .cache/
56
+ coverage.xml
57
+ pytestdebug.log
58
+
59
+ # Docs (if you add Sphinx/MkDocs later)
60
+ docs/_build/
61
+ site/
62
+ **/.doctrees
63
+
64
+ # Logs & temp
65
+ *.log
66
+ logs/
67
+ *.bak
68
+ *.tmp
69
+ *~
70
+
71
+ # ML experiment outputs & weights (common defaults)
72
+ wandb/
73
+ mlruns/
74
+ tensorboard/
75
+ tb_logs/
76
+ lightning_logs/
77
+ runs/
78
+ checkpoints/
79
+ *.ckpt
80
+ *.pt
81
+ *.pth
82
+ *.onnx
83
+ *.h5
84
+ *.safetensors
85
+
86
+ # Editors/IDEs
87
+ .vscode/
88
+ .idea/
89
+ *.code-workspace
90
+
91
+ # Example notebook archives and temporary data
92
+ examples/_archive/
93
+ examples/tmp/
94
+
95
+ # OPTIONAL: uncomment if you create these dirs for big artifacts
96
+ # data/
97
+ # outputs/
98
+ # examples/outputs/
99
+ # models/
100
+ # weights/
101
+
102
+ # External model weights (downloaded from HuggingFace on first use)
103
+ src/desisky/weights/vae_weights.eqx
104
+ src/desisky/weights/ldm_dark.eqx
105
+
106
+ # Solar flux data (can be downloaded or provided by user)
107
+ src/desisky/data/solarflux-2004-2025.csv
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2025-12-03
11
+
12
+ ### Added
13
+
14
+ - Initial release of `desisky` package
15
+ - Pre-trained broadband model for V, g, r, z magnitude prediction from observational metadata (moon position, transparency, eclipse fraction)
16
+ - Variational Autoencoder (VAE) for sky spectra compression (7,781 wavelength points → 8-dimensional latent space)
17
+ - Latent Diffusion Model (LDM) for generating realistic dark-time night-sky emission spectra conditioned on 8 observational parameters
18
+ - Data utilities for downloading and loading DESI DR1 Sky Spectra Value-Added Catalog (VAC) with automatic SHA-256 integrity verification
19
+ - Subset filtering methods for different observing conditions:
20
+ - `load_dark_time()` - Non-contaminated observations (sun/moon below horizon)
21
+ - `load_sun_contaminated()` - Twilight observations
22
+ - `load_moon_contaminated()` - Moon-bright observations
23
+ - Data enrichment features:
24
+ - V-band magnitude computation from spectra
25
+ - Lunar eclipse fraction calculation
26
+ - Solar flux integration
27
+ - Galactic and ecliptic coordinate transformations
28
+ - Command-line interface `desisky-data` for data management (download, verify, locate)
29
+ - Multiple sampling methods for latent diffusion inference:
30
+ - DDPM (Denoising Diffusion Probabilistic Models)
31
+ - DDIM (Denoising Diffusion Implicit Models)
32
+ - Heun (probability-flow ODE solver)
33
+ - Production-ready model I/O system with JSON metadata + binary weights
34
+ - Automatic caching for downloaded data and pre-trained models
35
+ - Comprehensive test suite with 123+ unit tests covering all major functionality
36
+ - Example Jupyter notebooks:
37
+ - `00_quickstart.ipynb` - Quick introduction to loading models and data
38
+ - `01_broadband_training.ipynb` - Train broadband model
39
+ - `02_vae_inference.ipynb` - VAE encoding/decoding
40
+ - `03_vae_analysis.ipynb` - Latent space analysis
41
+ - `04_vae_training.ipynb` - Train VAE from scratch
42
+ - `05_ldm_inference.ipynb` - Generate sky spectra with LDM
43
+ - `06_ldm_training.ipynb` - Train LDM from scratch
44
+ - JAX/Equinox-based models with automatic differentiation for high-performance inference
45
+ - PyTorch DataLoader integration for training workflows
46
+ - Support for CPU and CUDA (GPU) installations
47
+ - MIT License
48
+
49
+ [unreleased]: https://github.com/MatthewDowicz/desisky/compare/v0.1.0...HEAD
50
+ [0.1.0]: https://github.com/MatthewDowicz/desisky/releases/tag/v0.1.0
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present MatthewDowicz <mjdowicz@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
desisky-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,426 @@
1
+ Metadata-Version: 2.4
2
+ Name: desisky
3
+ Version: 0.1.0
4
+ Project-URL: Documentation, https://github.com/MatthewDowicz/desisky#readme
5
+ Project-URL: Issues, https://github.com/MatthewDowicz/desisky/issues
6
+ Project-URL: Source, https://github.com/MatthewDowicz/desisky
7
+ Author-email: MatthewDowicz <mdowicz@uci.edu>
8
+ License-Expression: MIT
9
+ License-File: LICENSE.txt
10
+ Keywords: DESI,astronomy,generative model,sky spectra
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: Implementation :: CPython
18
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: numpy
21
+ Requires-Dist: requests
22
+ Requires-Dist: scipy
23
+ Provides-Extra: all
24
+ Requires-Dist: astropy; extra == 'all'
25
+ Requires-Dist: equinox; extra == 'all'
26
+ Requires-Dist: fitsio; extra == 'all'
27
+ Requires-Dist: jax; extra == 'all'
28
+ Requires-Dist: matplotlib; extra == 'all'
29
+ Requires-Dist: optax; extra == 'all'
30
+ Requires-Dist: pandas; extra == 'all'
31
+ Requires-Dist: speclite; extra == 'all'
32
+ Requires-Dist: torch; extra == 'all'
33
+ Provides-Extra: cpu
34
+ Requires-Dist: equinox; extra == 'cpu'
35
+ Requires-Dist: jax; extra == 'cpu'
36
+ Requires-Dist: optax; extra == 'cpu'
37
+ Requires-Dist: torch; extra == 'cpu'
38
+ Provides-Extra: cuda12
39
+ Requires-Dist: equinox; extra == 'cuda12'
40
+ Requires-Dist: jax[cuda12]; extra == 'cuda12'
41
+ Requires-Dist: optax; extra == 'cuda12'
42
+ Requires-Dist: torch; extra == 'cuda12'
43
+ Provides-Extra: data
44
+ Requires-Dist: astropy; extra == 'data'
45
+ Requires-Dist: fitsio; extra == 'data'
46
+ Requires-Dist: pandas; extra == 'data'
47
+ Requires-Dist: speclite; extra == 'data'
48
+ Provides-Extra: train
49
+ Requires-Dist: equinox; extra == 'train'
50
+ Requires-Dist: jax; extra == 'train'
51
+ Requires-Dist: optax; extra == 'train'
52
+ Requires-Dist: torch; extra == 'train'
53
+ Provides-Extra: viz
54
+ Requires-Dist: matplotlib; extra == 'viz'
55
+ Description-Content-Type: text/markdown
56
+
57
+ # desisky
58
+
59
+ [![PyPI - Version](https://img.shields.io/pypi/v/desisky.svg)](https://pypi.org/project/desisky)
60
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/desisky.svg)](https://pypi.org/project/desisky)
61
+
62
+ -----
63
+
64
+ ## About
65
+
66
+ `desisky` provides machine learning models and tools for DESI sky modeling:
67
+
68
+ 1. **Predictive broadband model** - Predicts surface brightness in V, g, r, and z photometric bands from observational metadata (moon position, transparency, eclipse fraction)
69
+ 2. **Variational Autoencoder (VAE)** - Compresses sky spectra (7,781 wavelength points → 8-dimensional latent space) for analysis, anomaly detection, and dimensionality reduction
70
+ 3. **Latent Diffusion Model (LDM)** - Generates realistic dark-time night-sky emission spectra conditioned on observational parameters (sun/moon positions, transparency, galactic/ecliptic coordinates, solar flux)
71
+ 4. **Data utilities** - Download and load DESI DR1 Sky Spectra Value-Added Catalog (VAC) with automatic integrity verification and subset filtering
72
+
73
+ Built with **JAX/Equinox** for high-performance model inference and designed to integrate with SpecSim and survey forecasting workflows. This repository hosts the code and notebooks supporting the forthcoming paper by Dowicz et al. (20XX).
74
+
75
+ ## Table of Contents
76
+
77
+ - [Installation](#installation)
78
+ - [Quick Start](#quick-start)
79
+ - [Broadband Model](#load-pre-trained-broadband-model-and-run-inference)
80
+ - [VAE](#load-pre-trained-vae-and-encode-sky-spectra)
81
+ - [Latent Diffusion Model](#generate-sky-spectra-with-latent-diffusion-model)
82
+ - [Data Loading](#download-and-load-desi-sky-spectra-data)
83
+ - [Data Subsets](#data-subsets)
84
+ - [Loading Pre-trained Models](#loading-pre-trained-models)
85
+ - [Data Download](#data-download)
86
+ - [Examples](#examples)
87
+ - [Development](#development)
88
+ - [License](#license)
89
+
90
+ ## Installation
91
+
92
+ ### Basic installation (model inference only)
93
+
94
+ ```bash
95
+ pip install desisky[cpu]
96
+ ```
97
+
98
+ ### With data utilities (includes FITS file reading)
99
+
100
+ ```bash
101
+ pip install desisky[cpu,data]
102
+ ```
103
+
104
+ ### For GPU support
105
+
106
+ ```bash
107
+ pip install desisky[cuda12,data]
108
+ ```
109
+
110
+ **Note:** CUDA wheels require manual installation. See [JAX installation guide](https://jax.readthedocs.io/en/latest/installation.html) for details.
111
+
112
+ ## Quick Start
113
+
114
+ ### Load pre-trained broadband model and run inference
115
+
116
+ ```python
117
+ import desisky
118
+ import jax.numpy as jnp
119
+
120
+ # Load the pre-trained broadband model
121
+ model, meta = desisky.io.load_model("broadband")
122
+
123
+ # Example input: [placeholder for actual feature names]
124
+ x = jnp.array([...]) # Shape: (6,)
125
+
126
+ # Predict surface brightness in V, g, r, z bands
127
+ y = model(x) # Shape: (4,)
128
+ print(f"Predicted magnitudes: {y}")
129
+ ```
130
+
131
+ ### Load pre-trained VAE and encode sky spectra
132
+
133
+ ```python
134
+ from desisky.io import load_builtin
135
+ from desisky.data import SkySpecVAC
136
+ import jax.random as jr
137
+
138
+ # Load DESI sky spectra
139
+ vac = SkySpecVAC(version="v1.0", download=True)
140
+ wavelength, flux, metadata = vac.load()
141
+
142
+ # Load pre-trained VAE
143
+ vae, meta = load_builtin("vae")
144
+
145
+ # Encode a sky spectrum to latent representation
146
+ spectrum = flux[0].squeeze()
147
+ mean, logvar = vae.encode(spectrum)
148
+ print(f"Latent mean: {mean}") # Shape: (8,)
149
+
150
+ # Sample and decode
151
+ latent = vae.sample(mean, logvar, jr.PRNGKey(0))
152
+ reconstructed = vae.decode(latent)
153
+ print(f"Reconstructed shape: {reconstructed.shape}") # Shape: (7781,)
154
+
155
+ # Batch processing with vmap
156
+ import jax
157
+ batch_means, batch_logvars = jax.vmap(vae.encode)(flux.squeeze())
158
+ print(f"Batch latents shape: {batch_means.shape}") # Shape: (9176, 8)
159
+ ```
160
+
161
+ ### Generate sky spectra with Latent Diffusion Model
162
+
163
+ ```python
164
+ from desisky.io import load_builtin
165
+ from desisky.inference import LatentDiffusionSampler
166
+ import jax.random as jr
167
+ import jax.numpy as jnp
168
+
169
+ # Load pre-trained VAE and LDM
170
+ vae, _ = load_builtin("vae")
171
+ ldm, _ = load_builtin("ldm_dark")
172
+
173
+ # Create sampler (Heun method recommended for quality)
174
+ sampler = LatentDiffusionSampler(
175
+ ldm_model=ldm,
176
+ vae_model=vae,
177
+ method="heun",
178
+ num_steps=1000
179
+ )
180
+
181
+ # Define conditioning: [OBSALT, TRANSP, SUNALT, SOLFLUX, ECLLON, ECLLAT, GALLON, GALLAT]
182
+ conditioning = jnp.array([
183
+ [2100.0, 0.9, -30.0, 150.0, 45.0, 10.0, 120.0, 5.0], # Dark sky conditions
184
+ ])
185
+
186
+ # Generate spectrum
187
+ generated_spectra = sampler.sample(
188
+ key=jr.PRNGKey(42),
189
+ conditioning=conditioning,
190
+ guidance_scale=2.0
191
+ )
192
+
193
+ print(f"Generated spectrum shape: {generated_spectra.shape}") # (1, 7781)
194
+ ```
195
+
196
+ ### Download and load DESI sky spectra data
197
+
198
+ ```python
199
+ from desisky.data import SkySpecVAC
200
+
201
+ # Download DR1 VAC (274 MB, with SHA-256 verification)
202
+ vac = SkySpecVAC(version="v1.0", download=True)
203
+
204
+ # Load wavelength, flux, and metadata
205
+ wavelength, flux, metadata = vac.load()
206
+
207
+ print(f"Wavelength shape: {wavelength.shape}") # (7781,)
208
+ print(f"Flux shape: {flux.shape}") # (9176, 7781)
209
+ print(f"Metadata columns: {list(metadata.columns)}")
210
+ # ['NIGHT', 'EXPID', 'TILEID', 'AIRMASS', 'EBV', 'MOONFRAC', 'MOONALT', ...]
211
+
212
+ # Load with enrichment (adds V-band magnitudes and eclipse fraction)
213
+ wavelength, flux, metadata = vac.load(enrich=True)
214
+ print('SKY_MAG_V_SPEC' in metadata.columns) # True
215
+ print('ECLIPSE_FRAC' in metadata.columns) # True
216
+ ```
217
+
218
+ ## Data Subsets
219
+
220
+ The VAC provides three subset methods for filtering observations by sky conditions:
221
+
222
+ ### Dark Time (Non-contaminated)
223
+
224
+ ```python
225
+ # Load observations with minimal sun/moon contamination
226
+ wave, flux, meta = vac.load_dark_time()
227
+
228
+ # Filtering criteria:
229
+ # - SUNALT < -20° (Sun well below horizon)
230
+ # - MOONALT < -5° (Moon below horizon)
231
+ # - TRANSPARENCY_GFA > 0 (valid measurements)
232
+ ```
233
+
234
+ ### Sun Contaminated (Twilight)
235
+
236
+ ```python
237
+ # Load twilight observations
238
+ wave, flux, meta = vac.load_sun_contaminated()
239
+
240
+ # Filtering criteria:
241
+ # - SUNALT > -20° (Sun near or above horizon)
242
+ # - MOONALT <= -5° (Moon below horizon)
243
+ # - MOONSEP <= 110° (Sun-Moon separation)
244
+ # - TRANSPARENCY_GFA > 0
245
+ ```
246
+
247
+ ### Moon Contaminated
248
+
249
+ ```python
250
+ # Load moon-bright observations
251
+ wave, flux, meta = vac.load_moon_contaminated()
252
+
253
+ # Filtering criteria:
254
+ # - SUNALT < -20° (nighttime)
255
+ # - MOONALT > 5° (Moon above horizon)
256
+ # - MOONFRAC > 0.5 (Moon >50% illuminated)
257
+ # - MOONSEP <= 90° (Moon within 90°)
258
+ # - TRANSPARENCY_GFA > 0
259
+ ```
260
+
261
+ All subset methods include enrichment by default (`enrich=True`), adding computed columns for V-band magnitude and lunar eclipse fraction.
262
+
263
+ ## Loading Pre-trained Models
264
+
265
+ The `desisky.io.load_model()` function provides a unified interface for loading models:
266
+
267
+ ```python
268
+ import desisky
269
+
270
+ # Load packaged pre-trained weights
271
+ model, meta = desisky.io.load_model("broadband")
272
+
273
+ # Load from a custom checkpoint
274
+ model, meta = desisky.io.load_model("broadband", path="path/to/checkpoint.eqx")
275
+
276
+ # Save your own trained model
277
+ desisky.io.save(
278
+ "my_model.eqx",
279
+ model,
280
+ meta={
281
+ "schema": 1,
282
+ "arch": {"in_size": 6, "out_size": 4, "width_size": 128, "depth": 5},
283
+ "training": {"date": "2025-01-15", "commit": "abc123"},
284
+ }
285
+ )
286
+ ```
287
+
288
+ **Available models:**
289
+ - `"broadband"` - Multi-layer perceptron (6 inputs → 4 outputs) for V, g, r, z magnitude prediction from moon/transparency conditions
290
+ - `"vae"` - Variational autoencoder (7781 → 8 → 7781) for sky spectra compression, reconstruction, and latent space analysis
291
+ - `"ldm_dark"` - Latent diffusion model (1D U-Net) for generating dark-time sky spectra conditioned on 8 observational parameters
292
+
293
+ ## Data Download
294
+
295
+ ### Python API
296
+
297
+ ```python
298
+ from desisky.data import SkySpecVAC
299
+
300
+ # Download to default location (~/.desisky/data)
301
+ vac = SkySpecVAC(download=True)
302
+
303
+ # Download to custom location
304
+ vac = SkySpecVAC(root="/path/to/data", download=True)
305
+
306
+ # Skip SHA-256 verification (not recommended)
307
+ vac = SkySpecVAC(download=True, verify=False)
308
+
309
+ # Get path to downloaded file
310
+ print(vac.filepath())
311
+ ```
312
+
313
+ ### Command-line interface
314
+
315
+ ```bash
316
+ # Show default data directory
317
+ desisky-data dir
318
+
319
+ # Download DESI DR1 sky spectra VAC
320
+ desisky-data fetch --version v1.0
321
+
322
+ # Download to custom location
323
+ desisky-data fetch --root /path/to/data
324
+
325
+ # Skip checksum verification
326
+ desisky-data fetch --no-verify
327
+ ```
328
+
329
+ ### Environment variable
330
+
331
+ Override the default data directory:
332
+
333
+ ```bash
334
+ export DESISKY_DATA_DIR=/path/to/data
335
+ desisky-data dir # Shows /path/to/data
336
+ ```
337
+
338
+ ## Examples
339
+
340
+ See [examples/](examples/) directory for Jupyter notebooks demonstrating:
341
+
342
+ - **[00_quickstart.ipynb](examples/00_quickstart.ipynb)** - Quick introduction: loading models, data subsets, and running inference
343
+ - **[01_broadband_training.ipynb](examples/01_broadband_training.ipynb)** - Train the broadband model on moon-contaminated subset
344
+ - **[02_vae_inference.ipynb](examples/02_vae_inference.ipynb)** - VAE inference: encoding/decoding sky spectra and latent space visualization
345
+ - **[03_vae_analysis.ipynb](examples/03_vae_analysis.ipynb)** - Advanced VAE analysis: latent space interpolation and anomaly detection
346
+ - **[04_vae_training.ipynb](examples/04_vae_training.ipynb)** - Train a VAE from scratch with InfoVAE-MMD objective
347
+ - **[05_ldm_inference.ipynb](examples/05_ldm_inference.ipynb)** - Generate dark-time sky spectra using the latent diffusion model with custom conditioning
348
+
349
+ ## Development
350
+
351
+ ### Setting up development environment
352
+
353
+ ```bash
354
+ git clone https://github.com/MatthewDowicz/desisky.git
355
+ cd desisky
356
+ pip install -e ".[cpu,data]"
357
+ pip install pytest pytest-cov
358
+ ```
359
+
360
+ ### Running tests
361
+
362
+ ```bash
363
+ # Run all tests
364
+ pytest
365
+
366
+ # Run with coverage
367
+ pytest --cov=desisky --cov-report=html
368
+
369
+ # Run specific test file
370
+ pytest tests/test_model_io.py -v
371
+ ```
372
+
373
+ ### Project Structure
374
+
375
+ ```
376
+ desisky/
377
+ ├── src/desisky/
378
+ │ ├── io/ # Model I/O (save/load checkpoints with metadata)
379
+ │ ├── models/ # Model architectures
380
+ │ │ ├── broadband.py # Broadband MLP for magnitude prediction
381
+ │ │ ├── vae.py # Variational autoencoder (InfoVAE-MMD)
382
+ │ │ └── ldm.py # Latent diffusion model (1D U-Net)
383
+ │ ├── data/ # Data downloading, loading, and enrichment
384
+ │ │ ├── skyspec.py # SkySpecVAC class with subset filtering
385
+ │ │ ├── _enrich.py # V-band, eclipse, solar flux, coordinates
386
+ │ │ └── _core.py # Download utilities with SHA-256 verification
387
+ │ ├── training/ # Training infrastructure
388
+ │ │ ├── dataset.py # PyTorch Dataset wrappers
389
+ │ │ ├── vae_trainer.py # VAE training loop
390
+ │ │ ├── losses.py # Loss functions
391
+ │ │ └── vae_losses.py # InfoVAE-MMD loss
392
+ │ ├── inference/ # Sampling algorithms
393
+ │ │ └── sampling.py # DDPM, DDIM, Heun samplers for LDM
394
+ │ ├── visualization/ # Plotting utilities
395
+ │ ├── scripts/ # CLI tools (desisky-data)
396
+ │ └── weights/ # Pre-trained model weights (small models)
397
+ ├── tests/ # Comprehensive test suite (123+ tests)
398
+ │ ├── test_vae.py # VAE unit tests
399
+ │ ├── test_model_io.py # Model I/O tests
400
+ │ ├── test_enrichment.py # Data enrichment tests
401
+ │ ├── test_ldm_sampling.py # LDM sampling tests
402
+ │ └── ... # Other test modules
403
+ ├── examples/ # Jupyter notebook tutorials
404
+ │ ├── 00_quickstart.ipynb
405
+ │ ├── 01_broadband_training.ipynb
406
+ │ ├── 02_vae_inference.ipynb
407
+ │ ├── 03_vae_analysis.ipynb
408
+ │ ├── 04_vae_training.ipynb
409
+ │ └── 05_ldm_inference.ipynb
410
+ └── pyproject.toml # Package configuration
411
+ ```
412
+
413
+ ### Key Features
414
+
415
+ - **JAX/Equinox models**: High-performance, functional ML models with automatic differentiation
416
+ - **Production-ready I/O**: Checkpoint format with JSON metadata + binary weights
417
+ - **Automatic caching**: Downloaded data and models cached locally for fast re-use
418
+ - **Integrity verification**: SHA-256 checksums for all downloaded files
419
+ - **Subset filtering**: Easy access to dark-time, twilight, and moon-contaminated observations
420
+ - **Data enrichment**: Automatic computation of V-band magnitudes, eclipse fractions, solar flux, and coordinate transformations
421
+ - **Multiple sampling methods**: DDPM, DDIM, and Heun (probability-flow ODE) for LDM inference
422
+ - **Comprehensive tests**: 123+ unit tests ensuring reliability
423
+
424
+ ## License
425
+
426
+ `desisky` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.