Architecture
Valerian turns a set of deep-sky subframes into a finished image. This page is the map: which crate does what, how data flows, and the rules that keep the CPU and GPU paths honest. The foundation milestone has landed the workspace; each section says what exists today.
Crate map
| Crate | Kind | Role |
|---|---|---|
valerian-core | library | Image maths and file formats on the CPU. No GPU code, #![forbid(unsafe_code)]. Builds on helia-core. |
valerian-gpu | library | wgpu compute backend on the device helia-gpu opens: WGSL kernels for calibration, the registration warp and the stack combiner, a fused stack that keeps frames on the device, and the benchmark. Implements valerian_core::compute::Compute. |
valerian-cli | binary valerian | calibrate, register, stack, background, stretch and info, with a per-frame table; the clap definition also generates the CLI reference. |
valerian-gui | binary valerian-gui | The desktop app: night-sky and night-vision themes, embedded IBM Plex fonts, the workflow rail (rail), the folder steps Calibrate, Register and Stack (pipeline), the image view with zoom, pan and histogram (view), the Process tools, Export, notices and the About page. |
xtask | binary | Repository automation: generated documentation and the licensing check. |
valerian-core modules today:
about: the author, copyright, licence and dedication notices, and the build record (commit, date, profile, target, compiler) thatbuild.rscaptures. Shared by--versionand the About page, so they cannot drift apart.fits: FITS reader and writer that keep the whole header and the physical pixel values in ADU (the reader inhelia-coredrops the header and scales to 0..1).Imageis a header plus one or morehelia_core::Frameplanes. Rows stay in file order.stats: median, MAD, percentiles, clipped statistics and noise estimates that skip NaN (NaN means "no data" throughout).compute: theComputetrait through which calibration, the warp and the combiner (and a whole stack plane) are run, withCpuas the reference implementation that a GPU engine must match, andstack_plane_classic, the specification of the fused stack.combine: the per-pixel combiner under masters and stacks: min/max, sigma, winsorised sigma and linear fit rejection, weights, and per-frame rejection counts.calibrate: master bias, dark, flat and dark flat, the hot/cold/dead pixel map, cosmetic correction, dark scaling andCalibrator.streaming: the same masters ascalibrate, built from files a band of rows at a time with a byte budget, so memory does not grow with the number of frames.fits::Readerreads rows of a plane without reading the file.debayer: bilinear and Malvar-He-Cutler demosaicing to three planes.background: sky-gradient extraction: tile samples, a polynomial or thin-plate spline surface fitted with rejection, star and nebula masks, the target mask, subtract or divide, and the rules that decline a fit when there is no clear sky.stars: background model, star detection, windowed centroids, FWHM and ellipticity.transform: similarity, affine and homography transforms and their least-squares fits.register: triangle matching with voting and a RANSAC search, then a least-squares refinement on every matching star.stack:align(reference choice, registration, resampling, level matching),integrate(weights, rejection, header) andstackfor both: reference choice, registration, resampling, level matching, noise and FWHM weights, rejection, and a per-frame report.drizzle: variable-pixel linear reconstruction on a finer grid: registration throughstack::register_frames, square drops mapped through each frame's transform and clipped exactly against the output pixels (banded across threads), raw Bayer mosaics dropped into their own colour plane, and a second pass that rejects pixels outside the range of the first result read back.warp: resampling through a transform (bilinear, bicubic, Lanczos-3), NaN outside the source footprint.stretch: levels (black and white points) and the tone curves: midtone transfer function, arcsinh and the generalised hyperbolic stretch, each with its inverse, and an automatic stretch that puts the sky at a target. The stretch is recorded in the header so it can be undone.testutil(featuretestutil): a seeded random generator, a pixel-integrated Gaussian star field and a model sensor (bias, dark current with hot pixels, flat with vignetting and dust, dead pixels, read and shot noise) for known-answer tests.
Data flow
Subframes are read by FITS input, calibrated with master bias, dark and flat
frames, debayered when they come from a one-shot-colour camera, searched for
stars, registered to a reference by matching star patterns, and stacked with
outlier rejection and weighting. That much exists, on the CPU. Plate solving,
colour calibration and star removal follow; stretching exists as valerian stretch and background extraction as valerian background, both on finished
stacks.
The CPU implementation is the reference that any GPU kernel must match.
Relationship to Helia
Valerian is the deep-sky sibling of Helia.
Until the shared code is extracted into a common workspace
(planned), Valerian
depends on helia-core and helia-gpu as git dependencies pinned to a tag in
the root Cargo.toml. The same lint set, formatting, deny.toml, licensing
headers, documentation rules and CI shape apply.
Licensing
Every source file carries an SPDX header and a pointer to
ADDITIONAL-TERMS.md (GPL section 7). cargo xtask reuse-check enforces the
headers, the REUSE.toml annotations for everything else, and that the
copyright line and the dedication stay in the README, the terms, the book
introduction and crates/valerian-core/src/about.rs.