The pipeline

What Nebula Stacker actually does

Stacking is treated as one joint inverse problem rather than a sequence of independent fixes, and the order below is the order it runs in — each phase using what the last one measured. Nothing here is a preset.

Several of these decline on ordinary data, and that is the design rather than a shortfall: a correction that cannot be measured safely reports why and changes nothing. A module that quietly returns nothing is a bug this project has found three times.
01

Calibration and the noise model

Before anything is combined, the program works out what your sensor does — so that later steps weigh each pixel by how much it can be trusted rather than treating them alike.

Per-gain masters

Bias frames are split by their own median level and each frame gets the master below it. A bias frame measures the readout at one gain, and averaging two ISOs into one master leaves a pedestal in every frame that the flat then divides and prints its own vignetting onto.

Photon transfer curve

Gain in electrons per ADU, fitted across signal levels. Read noise always comes from the bias frames rather than the curve's intercept — extrapolating from tens of thousands of ADU down to tens gets it wrong by threefold.

Per-pixel weighting

A read-noise map turned into 1/variance weights. A pixel that flickers counts for less, continuously — no bad-pixel verdict, no threshold to tune.

Hot and dead photosites

Found from the dither: a defect is fixed on the detector, a star is fixed on the sky, and the frames move. A hot pixel's excess is subtracted; a dead one has its weight set to zero, because no arithmetic recovers a signal that was never there.

Superflat

The flat field measured from your light frames themselves — same optics, same dust, same moment — using the registration to know where the target is rather than inferring it. Flat frames become optional: a stack with none comes out no worse than one with them.

Anscombe transform

Variance-stabilising, so that the comparison used for outliers means the same thing at the bright end as at the faint end.

02

Separating the sky from the detector

Light pollution is added to your frames; vignetting multiplies them. Telling the two apart is what the dither pays for, and the commonest way for a stacker to eat a galaxy is to get it wrong.

Skyglow, per frame

The background is never fitted to a frame. It is fitted to what is left of a frame once the current sky estimate has been reprojected into that frame's detector coordinates and subtracted — so real nebulosity is already in the estimate, is therefore not in the residual, and a low-order surface cannot absorb it.

One shape with a colour

Skyglow has a spectrum, so whatever shape it makes it makes the same shape in red, green and blue. Ten degrees of freedom instead of eighteen, and the eight given up are exactly the ones a background model uses to eat a target. A nebula can no longer be absorbed unless it is the colour of the streetlights — and Hα is not.

Smoothed along the session

Skyglow changes over minutes rather than between subs, so the fits are smoothed in capture order and only the surface's shape is subtracted — its level is not separable from the sky's own brightness.

The sky floor

Uses the axis a narrow dither cannot: time. Regressing each cell against the frame's own sky level over a night separates what is there at zero sky — amp glow, a light leak — from what scales with it, which is the sky's own gradient.

03

Coaddition

How the frames are actually combined. Two estimators, and the frames choose which — a decision the program makes from your data and then reports.

Fourier coaddition

Zackay & Ofek's form: each frame weighted per spatial frequency by what its own seeing and noise let it contribute there, then deconvolved and reconvolved to a stated target. With frames that are alike it reduces exactly to the plain mean, so it can never do worse.

Drizzle

Where the frames are undersampled, the mosaic is stacked at the sensor's own grid and demosaiced once, at the end. A superpixel demosaic throws away half the resolution before the first frame is placed. Measured: a quarter tighter stars and eighty per cent more of them resolved.

Elliptical per-frame PSF

A trailed frame is not a blurred frame — it is sharp across the trail and smeared along it. Fitting an ellipse rather than a circle undoes the smear in the direction it actually runs, so a marginal sub still contributes what it has.

Nearest-neighbour sampling

Deliberate. Interpolating would correlate neighbouring pixels and break the noise statistics every other measurement here depends on — so a sample lands on one output pixel or on none.

Wavelet scale weights

The fallback estimator: an à trous decomposition weighting each frame separately at each scale. What it scales is the frame's deviation from the estimate, which averages to zero over any subset — so masked pixels do not skew it.

04

Outliers, as objects

Sigma clipping asks each pixel in isolation whether it looks odd. At three sigma one pixel in 370 is odd by chance, and rejecting those is exactly the mottling it was meant to prevent.

Satellite trails

A Hough transform over the exceedance map finds the line, its width is measured from the seed-rate profile across it, and the whole feature is masked. Searched on a coarse grid and verified at full resolution, because the thresholds mean what they were measured at.

Cosmic rays and hot columns

Connected components, dilated and masked whole. Scattered single pixels are left alone deliberately.

Contrast gate

A line is only believed if the seeds along it are four times denser than the seeds beside it. A Hough transform finds lines in anything dense enough; a satellite is a line with quiet sky either side.

Student's t thresholds

“Three sigma” on four frames is not one in 370 — it is one in seventeen, because the spread was estimated from those same four. The threshold is the t quantile for the number of frames actually there.

05

Registration

Aligning the frames, and putting them on a common photometric scale — which on a real night is worth more than everything else combined.

Plate solving

The reference frame is solved against a star catalogue once; every other frame is matched against the reference by quads, which is far cheaper and far more accurate than solving each one blind.

Differential distortion

A similarity transform has four numbers and a real field distorts by several pixels at the corners. A third-order polynomial fits what the similarity could not explain — 0.97 px rms down to 0.12 px on real subs. Refused unless it beats doing nothing.

Atmospheric dispersion

Red, green and blue are refracted by different amounts and arrive displaced. The offsets are measured from the frame's own stars and smoothed along the session, because dispersion follows airmass over tens of minutes.

Photometric normalisation

Every frame put on the reference's scale by the median flux ratio over matched stars — and only the light above the sky is divided by transparency, because the skyglow was there whatever the weather. On a night running 0.82× to 1.02× this took star signal-to-noise from 59 to 115.

06

Mixed exposures

Long subs for the faint structure, short ones for the cores that burnt out — combined without a blending stage.

Censoring

A sample at full scale is not a measurement: the well filled and the count stopped, so it says “at least this much”. Those samples are left out and the shorter subs say what is inside the core. Each pixel uses whatever actually measured it.

Well fullness

The question is asked of the raw reading, before calibration touches it — “the count stopped” is a statement about the ADC, and nothing a bias subtraction does to the number afterwards can be part of it.

Per-exposure grading

A 90-second sub among 600-second ones has a third of the stars because it is a 90-second sub. One quality baseline per exposure length, or every short frame gets set aside as cloud.

07

Colour

Three overlapping filters over one sensor, calibrated against a catalogue rather than against taste.

White balance from Gaia

The field is plate-solved, catalogue stars are matched to measured ones, and a robust line through BP − RP separates the instrument from the sky. The convention: a solar-colour star renders neutral.

Two greens kept apart

G1 and G2 sit on opposite diagonals of the Bayer tile and are not the same detector. Averaging them is what produces the maze artefact conventional debayering is famous for. They are carried separately and balanced — measured at 0.088 % apart — so the artefact never exists rather than being filtered out.

Chroma smoothing

Colour varies smoothly across almost all astronomical structure and the eye has far less acuity for it. The ratios are averaged and the Rec. 709 luminance put back untouched — not the plain sum, which lets a star's brightness drift while the arithmetic looks preserved.

Colour flat

A smooth multiplicative colour cast across the field, fitted from stars whose catalogue colours are known. On a well-flatted field it measures the gradient as insignificant and declines — which is a measurement of your optics, not a failure.

08

Measurement and reporting

Every number the result screen shows is measured on your delivered pixels. Where something could not be measured safely, the program says so instead of guessing.

Star width and roundness

Width at half maximum, interpolated between pixels and reported per region — a field sharp in the middle and soft at the corners has no single width. Roundness from second moments, because a smeared star has almost the same width as a round one.

Noise and structure

Noise from first differences between adjacent pixels, which cancels gradients and stars. Separate measures for texture at 32 px and real structure at 128 px, because a correction can improve every per-pixel number while printing a visible pattern.

Optics report

Tilt and field curvature fitted separately, because they want opposite fixes and one “the corners are soft” number points at the wrong screw half the time. Below the frame-to-frame wander, the field is reported even rather than a fault invented.

Suggestions

Every line names a number from your run. Generic good practice is the same list for everybody and is worth nothing.