Zwicky Transient Facility
Our pipeline · difference viewer
Read this once
then keep it open in a tab

VIEWER
GUIDE.

The difference viewer packs a lot into one screen: an image stack, a tuning panel, three floating side-panels and a detail drawer. Nothing on it is decoration — every panel maps to a real, documented part of the pipeline. This page walks through what each piece is, where it lives on screen, and what it's showing you — including how to read a difference image itself, and the per-detection cutouts now attached to every row in the application — so the first few minutes in the viewer are orientation instead of guesswork.

Best used
side-by-side with the viewer
Reading time
~9 minutes
Covers
controls, difference images, cutouts
01 · Start here

The five things you need before anything else

If you open the viewer right now and do nothing else, this is everything you need to look around and find something interesting.

  1. Drag to pan, scroll (or the −/+ buttons) to zoom. The view boots wide on the real sky, then flies in on the one ZTF field this page is built from — give it a few seconds to land.
  2. Click any coloured marker (a reticle or bracket on the image) to open a detail drawer on the right with that detection's thumbnail and verdict.
  3. Press L or click the button (top-left) to open the full, filterable list of every detection in this field.
  4. The display button (top-right toolbar) is where you turn image layers on/off and adjust brightness/contrast — see Toolbar & display panel below.
  5. If the page just shows an error about a local server, you opened the file directly. Run ./serve.sh from the project root and reload — see Troubleshooting.
The difference viewer's default view: nav and honesty strip at the top, the sky-base survey picker top-left, the toolbar and its display/reset controls top-right, the ZTF field with coloured detection markers in the centre, the sky-context panel bottom-left, the recovery banner bottom-centre, and the nearby-detections panel bottom-right.
A real capture of the live viewer — every panel in its default state, caught early on load while the view is still zoomed wide. The ZTF field is the small bright square in the middle; once the fly-in lands it fills most of the screen. Nothing here has been touched.
Read this before you interpret anything

This is one ZTF exposure, run through our own pipeline. Not a discovery feed.

Every marker on the map is a detection our own difference-imaging and classification code produced — not an official ZTF alert, not a confirmed astronomical event. Three honest outcomes exist and the viewer is careful to keep them distinct: a recovery is a known, catalogued object our pipeline found blind (a validation of the detector, not news); a candidate is unconfirmed and, on a single field like this one, usually an artifact; a verdict is a real/bogus + object-type classification from the stationary branch. Where a branch never ran, it reads not run — never "bogus."

The colour in the sky image is synthetic: ZTF has two public optical bands (g and r), so red = r-band flux, blue = g-band flux, and green is a blended mix of the two — not a third real filter. This is ZTF data, not Rubin/LSST. And the whole page is baked around one field and one exposure (named in the strip at the very top of the viewer) — for the wider harvest across many fields and nights, see Survey and Cells.

02 · Orientation

Where everything lives

A schematic of the viewer's own screen, at the same corners the real controls sit in. Every labelled zone below has its own section further down this page.

03 · The picture itself

What's actually stacked on screen

The map is several images layered on top of each other. You rarely need to think about this — but when something looks unexpected, this is the first thing to check in the display panel's Layers list.

Deep sky stacksbase

the photographic backdrop

Many aligned exposures of this field median-stacked together (deep, low-noise), one stack per band. Red = r-band, blue = g-band, green = a synthetic blend of both. If the deep stacks weren't built, a single-epoch science frame is shown instead (in grayscale) — the Layers panel names whichever is active.

Change overlaydiff

the actual detector output

One exposure's science frame minus a deep reference template. Amber/warm = flux appeared or brightened; cyan/cool = flux faded, or an alignment "dipole" artifact. Transparent = below the noise floor, i.e. nothing changed. Subtle (30% opacity) by default so the sky stays the hero — the toolbar's changes button floods it back to full strength.

Deep templateoff by default

the "before" reference

The deep, multi-epoch co-add that the change overlay was subtracted against. Hidden by default; the blink button in the display panel toggles between it and the current sky every 0.7 s — the classic astronomer's trick for spotting a change by eye.

Real-sky backdropoff by default

context, not our data

An all-sky survey (not ours) shown behind the ZTF imagery when you zoom out past our field's footprint, or when sky ctx is switched on. Off by default so empty sky renders true black instead of a survey haze. Choose which survey via the sky-base picker.

A tight crop of the ZTF field with the change overlay set to 'emphasized' — a faint speckle of amber and cyan pixels appears across the frame in addition to the bracket and ring detection markers.
The change overlay, emphasized — the same field as above with changes: EMPHASIZED pressed. The scattered amber/cyan speckle is the raw per-pixel change signal; the bracket and ring markers are the catalogued detections built from it.
04 · The whole point

How to read a difference image

A difference image is not a photograph of the sky — it is a photograph of the change. A reference image of the same patch has already been subtracted, so every star that stayed exactly the same cancels to nothing. What is left is what moved, appeared, faded — plus whatever the subtraction failed to cancel cleanly. Learning to tell those two apart is most of the skill.

amber
Flux appeared or brightened here between the reference and this exposure.
cyan
Flux faded here — the source was brighter in the reference than it is now.
black
Nothing changed — or the change is below the display's noise floor. Empty sky is deliberately painted true black so the eye lands on real change rather than on noise; the underlying measurements are made on the full, unfloored data.

That amber-up / cyan-down language is the same on every surface of this site — the change overlay here, the per-cell stacks, the survey map's markers, and the cutouts in section 08.

Four shapes worth recognising

A compact blob

One tight amber (or cyan) knot the size of a star image. This is the interesting case: something genuinely changed brightness at a fixed position — a variable star, an AGN, a transient.

A line

An elongated smear. Something moved far enough during the exposure to draw a trail instead of a point — a fast asteroid, or a satellite. This is what feeds the pipeline's separate motion branch.

Amber and cyan side by side

A dipole — a bright-and-dark pair, or a ring, on a star that did not really change. The two images were not aligned to a perfect sub-pixel match, so subtraction left one edge over and the other under. An artifact, and a well-documented limit of this pipeline — not a fading star.

A hollow core with wings

A saturated star. Its centre pegged the detector's maximum in both images, so the centre carries no usable information and subtracts to a black hole ringed by leftovers. Always an artifact.

One star can produce two rows. Detection runs over the positive difference and the negative difference separately, so a dipole is frequently catalogued twice — once as a sign +1 detection and once as sign −1, at sky positions less than an arcsecond apart. If two entries in a list sit on top of each other with opposite signs, you are almost certainly looking at the two lobes of one imperfect subtraction, not at two objects.

Where else difference images live

Everything else in this guide describes this one field's viewer. It is not the only place the application draws real difference images:

05 · Top-right

The toolbar & the display panel

Everything about how the picture looks lives in these two places. The toolbar is always visible; the display panel opens from it.

The display panel open, showing the Layers section (three layer rows with visibility checkbox, opacity slider and tune-target radio, plus a blink button) and the Tuning section below it (stretch, colormap, contrast, min/max cut, sky ctx, grid, rotation).
The display panel, open — Layers on top, Tuning below. This build has no deep per-band stacks, so the Layers list shows the single-epoch science-frame fallback (named explicitly) instead of the two-band colour stack.

The toolbar

/ +
Zoom out / in. Scrolling with the mouse wheel does the same thing anywhere over the sky.
render
smooth (default) interpolates pixels for a continuous, photographic zoom. pixels switches to nearest-neighbour so you can inspect individual detector pixels — useful right up against a detection.
changes
subtle (default) keeps the change overlay quiet so the sky stays the hero. EMPHASIZED floods it to near-full opacity and a tighter contrast window — use this when you specifically want to see what the detector flagged. This is the image, not the markers.
markers
subtle (default) draws the detection reticles thin, so the sky reads as a photograph. BOLD thickens and brightens them when you are hunting for detections rather than looking at the sky. Shortcut: E. Easy to confuse with changes next to it — changes is the coloured image underneath, markers is the rings and brackets drawn on top.
display
Opens/closes the display panel described below.
reset
Snaps the view (position/zoom/rotation) and every layer's brightness/contrast/visibility back to their defaults in one click — the fastest way to undo any amount of fiddling.

The display panel — Layers section

One row per image layer (see above), listed top-to-bottom in the order they're actually drawn — the change overlay is always the top row because it's drawn last. Each row has:

checkbox
Show/hide that layer entirely.
opacity slider
0–100%, how strongly that layer blends into the composite.
tune target radio
Which layer the Tuning section below (stretch/colormap/cuts) currently edits — only one layer is "live" under the knobs at a time.
blink
Toggles a 0.7 s blink comparator between the current sky and the deep template. Needs both layers present; a status message says what's missing if it can't run.

The display panel — Tuning section

These apply only to whichever layer is currently the tune target above:

stretch
How raw brightness maps to displayed intensity. Cycles asinh → linear → sqrt → log. asinh is the default because the deep stacks span a huge brightness range that a plain linear map would render as almost all black with a few white dots.
colormap
The colour ramp for that layer (varies per layer — e.g. the sky layers cycle their own band colour ↔ grayscale ↔ magma).
contrast
A single slider setting how wide the black-to-white brightness window is. For the change overlay this is a symmetric ±count window (in units of its own noise); for sky layers it's a percentage of that layer's natural range.
min cut / max cut
The same black-point/white-point, entered directly as numbers — the advanced version of the contrast slider, useful for an asymmetric window.
sky ctx
Shows/hides the real-sky survey backdrop (see above). Off keeps empty sky pure black.
grid
An RA/Dec coordinate grid — a measuring tool, off by default since it can dominate the picture.
rotation
Rotates the whole view 0–360°.
06 · The floating panels

The four panels around the edges

These are collapsed/out of the way by default so the sky stays the focus — each one is one click (or one hover, for the status line) away.

≡ Detections listtop-left

the full catalogue for this field

Click the button (or press L) to slide open a drawer listing every detection: search by id or verdict, filter by SNR / braai-pass / sign, include or exclude bogus, and sort. Clicking a row flies the view there and opens its detail drawer — the fastest way to browse rather than hunt for markers by eye.

Sky-base pickertop-left, below ≡

which real survey shows as backdrop

Choose among a few real all-sky surveys (a colour photographic mosaic, the classic digitized plates, or a near-infrared survey) for whatever shows through when sky ctx is on or you zoom out past our field. The small i button explains what this layer is.

Sky contextbottom-left

named real objects nearby

A collapsed panel that, once expanded, lists real catalogued astronomical objects (from SIMBAD) near the current view. Click one to fly there — useful for orienting yourself against something already known, independent of our own detections.

Nearby detectionsbottom-right

our catalogue, filtered to what's on screen

Like the sidebar list, but scoped to whatever is currently inside your field of view, sorted by signal-to-noise. Zoom in and more (fainter) detections are revealed, mirroring how you'd actually explore an image. Click a row for its detail drawer.

The detections sidebar, open: a header showing the total count and honesty note, search box, SNR slider, braai-pass-only and include-bogus checkboxes, sign and sort dropdowns, and a scrollable list of detection rows each showing a coloured dot, row id, SNR, and any verdict badge.
The detections sidebar, open — every catalogued detection in this field, filterable and sortable, real data from the loaded catalogue.
A fifth banner may appear bottom-centre if the page was built with the 2019 BE5 recovery data: our pipeline's blindly-linked track of a real, previously-known asteroid, plotted against its true JPL Horizons position. It's explicitly labelled a recovery, not a discovery — the toggle switches the overlay on/off, and it's absent entirely on a field that doesn't have this validation data.

One more element, easy to miss: a small status line down the left-hand edge, above the sky-context panel, reports what just happened — load progress, a tuning change, or an error — and fades out on its own after a few seconds of inactivity.

07 · Click any marker

The detection drawer

Clicking a marker on the map, or a row in the sidebar / nearby-detections list, slides a drawer in from the right with everything known about that one detection:

The detection drawer for a real catalogued source: the honesty banner at top, a tinted science/reference/difference thumbnail with its channel legend, a catalog-attributes table (row id, ra, dec, snr, segment flux, elongation, ellipticity, sign), and a Stage-4 verdict table (final verdict, braai P(real), braai pass, point-source type, type path, braai stamp source).
A real detail drawer (source src_p1_024) — thumbnail, catalog attributes, and the Stage-4 classification verdict, exactly as the pipeline produced them.
  • · A repeat of the honesty banner, so the framing travels with the data.
  • · The detection's own cutout — a small square of real sky at that exact position, with a caption naming each panel it holds (science, reference, difference, or whichever of those exist for that exposure).
  • · Catalog attributes: sky position, signal-to-noise, sign, shape (elongation), and more.
  • · The classification verdict: the real/bogus gate's pass/fail and confidence, an object-type call if one was made, and the pipeline's final verdict — with any uncalibrated probability struck through and any branch that never ran reading not run rather than a silent "bogus."

Close it with the × button, Esc, or by clicking anywhere outside the drawer.

08 · The picture inside the drawer

Cutouts: the pixels behind every detection

Every detection in the application now carries its own cutout — a small square of real sky, cut straight from the images the measurement was made on, centred on that detection's own position. It is the fastest way to check a number against reality: a row can claim SNR 500, but the cutout shows you whether that is a star, a streak, or a subtraction artifact.

A three-panel cutout: a blue point source on black at left, a brighter green point source in the middle panel, and at right an amber ring with cyan flanks on an otherwise black square.
A three-panel cutout (detection src_p1_010, a catalogued variable star) — science, reference, difference, left to right. The star is present in both images; the difference panel shows what changed between them.

The panels, and why there may not be three

science
This night. The single exposure the detection was made in — the "after".
reference
Before. ZTF's deep co-add of the same sky, built from many earlier visits, so it is far quieter than any one night.
difference
What changed. Reference subtracted from science, in the amber/cyan language of section 04.

The caption under a cutout always names the panels it actually has, and it will not always say three. Most of the harvest was run in a motion-only mode that never downloads a science frame, so a great many detections have a reference + difference pair, and some have the difference alone. That is a statement about which images exist for that exposure, not about the quality of the detection — read the caption rather than assuming a fixed triplet.

A single-panel cutout: a bright amber diagonal streak crossing a black square.
Difference only — a streak. One of the pipeline's own detections of the near-Earth asteroid 2019 BE5: it moved far enough during the exposure to draw a line. A known object, found blind — a recovery, not a discovery.
A three-panel cutout of a saturated star: a blue spike, a green starburst with a black rectangular core, and a difference panel showing two cyan wings either side of a black gap.
A saturated star. The black core in the sky panels is where ZTF's own data flags the pixels as unusable — what a very bright star does to a detector. Nothing meaningful can be subtracted there, so the difference is leftover cyan wings either side of a dead centre: an artifact, correctly rejected.

Reading one

  1. Left to right is a story. Before, after, and what the subtraction made of the pair. Look at the difference panel last, once you know what was there to begin with.
  2. Compare the two sky panels first. If the source is obviously brighter or fainter in one, the change is real. If they look identical but the difference panel is loud, the subtraction is what is loud — suspect a dipole.
  3. Judge the difference panel's shape, using the four shapes in section 04: compact blob, line, dipole, or saturated core.
  4. Trust the scale. Every panel of every cutout in an exposure is stretched by the same measured noise level of the whole frame — not by its own brightest pixel — so a faint residual looks faint and two cutouts can be compared honestly against each other.
  5. Then read the verdict beside it. The picture and the classification are two independent opinions; a cutout that looks nothing like a star is a good reason to distrust a confident-sounding label.

Each panel is 63 × 63 pixels — the same stamp size ZTF puts in its own public alerts — and is cut by sky coordinates, so all the panels land on the same star even though they come from different nights and different pixel grids.

Where to click for one

this viewer
Click any marker on the map, or any row in the detections sidebar — the cutout is at the top of the drawer that slides in.
survey map
Pick an exposure and click a row in the list; or open one of the pre-built views (candidates, recoveries, brightest…) and click a row there; or zoom in past ~1.8° and click a detection marker directly on the sky.
a sky cell
Open a cell, then click a row in its epoch detection table. In that cell's own difference viewer, click a marker, or press L — every row in that list already shows its difference cutout as a thumbnail, and clicking one opens the full strip.
no cutout?
A handful of early runs carry a sky-position label that cannot be trusted, so their images cannot be identified on disk with certainty. Rather than show a nearby patch of sky and risk passing it off as the right one, the drawer says so plainly. The detection's own measurements are still its own.
09 · Vocabulary

Reading a detection

The handful of terms that show up on every marker, row and drawer.

sign +1
Flux appeared or brightened between the reference and this exposure.
sign −1
Flux faded — or, less interestingly, an alignment "dipole" artifact rather than a real fading source.
SNR
Signal-to-noise of the detection in the difference image; higher is more likely to be real.
braai pass
Whether the real/bogus classifier CNN accepted this as plausibly astrophysical rather than an artifact, with its own confidence score.
elongation
How stretched the detection's shape is — a high value can mean a fast-moving object (a streak) rather than a point source.
recovery
A known, catalogued object our pipeline found on its own — validates the detector; it is not news.
candidate
Unconfirmed; on a single field, usually an artifact until several link into a track elsewhere in the pipeline.
verdict
A real/bogus + object-type classification (e.g. variable star, AGN) from the stationary branch.
not run
That branch never executed for this detection — a gap in coverage, never a negative result.
10 · Cheatsheet

Mouse & keyboard

drag
Pan the view.
scroll
Zoom in / out, centred on the cursor.
/ +
Zoom out / in (toolbar buttons, same as scroll).
click marker
Open the detail drawer for that detection.
L
Toggle the detections sidebar.
E
Toggle marker emphasis (the toolbar's markers: subtle / BOLD).
Esc
Close the detection drawer, or the detections sidebar if that is what is open.
11 · If something looks wrong

Troubleshooting

"The page just shows an error about needing a local server."

You opened the file directly (file://). The viewer fetches its imagery and catalogue over HTTP, which browsers block for local files. Run ./serve.sh from the project root and open the printed address instead.

"The sky is completely black."

That's usually correct — empty sky is deliberately rendered true black. If the field itself looks empty, check the display panel's Layers list: a layer may be unchecked or its opacity down at 0%. Try reset in the toolbar to restore every default.

"I don't see any markers."

Markers only exist inside this page's one baked field/exposure (named in the strip at the top). If you've panned far away, fly back with reset, or open the sidebar and click any row to jump straight to it.

"Blink does nothing."

Blink needs both a sky layer and the deep template layer present. If either is missing on this build, a status message names which one — check the status line down the left-hand edge right after clicking.

"Why is there colour at all — is this real?"

It's synthetic two-band colour (ZTF g+r only), not a real three-filter photo and not Rubin data — see What you're looking at. If only one band was built, you'll see grayscale instead, and the Layers panel will say so explicitly.

"The view seems to still be loading / jumping."

Normal on first load: the viewer boots on the wide real sky, then flies in to the ~0.86° ZTF field once imagery has arrived — give it a few seconds before judging the picture.