Skip to content
| Marketplace
Sign in
Visual Studio Code>Data Science>Pixel Clarity — FITS, ASDF, HDF5 & NumPy image viewerNew to Visual Studio Code? Get it now.
Pixel Clarity — FITS, ASDF, HDF5 & NumPy image viewer

Pixel Clarity — FITS, ASDF, HDF5 & NumPy image viewer

Clarity Orbital Inc.

|
8 installs
| (0) | Free
Inspect FITS, ASDF, HDF5, NumPy and TIFF images and CSV/ECSV tables in VS Code, including Roman Space Telescope ASDF products: zscale, stretches, colormaps, histogram, region stats and cuts, plus a fast catalog viewer with sort, search, expression filters and plots. Built for Remote-SSH: data and st
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Pixel Clarity

A fast scientific image viewer for VS Code, built for working on remote machines. It opens FITS, ASDF, HDF5 and NumPy files, plus TIFF and PNG, as an editor tab, and ECSV and CSV tables (catalogs, curves, time series) in a table viewer with filtering, statistics and plots.

File formats

  • FITS (.fits, .fit, .fts, .fits.gz): every HDU in multi-extension files, BSCALE/BZERO/BLANK, cubes, and world coordinates from the header.
  • ASDF (.asdf), the format of Roman Space Telescope data and reference files: every array in the tree is listed by its path (roman.data, roman.dq, roman.err, …), and the science image opens first. Quantities show their unit, and the whole tree is searchable in the Metadata panel as roman.meta.exposure.start_time-style keys. Uncompressed and lz4-compressed blocks (the Roman default) are read in pieces, so a multi-hundred-MB file streams from disk like FITS and is never decompressed whole. zlib blocks are decompressed when first read. bzip2 blocks, structured (table) arrays and complex arrays are listed but not shown. World coordinates from a gwcs are not evaluated yet.
  • HDF5 (.h5, .hdf5, .he5): every dataset by path, with its attributes.
  • NumPy (.npy, .npz): integer, float and bool arrays in C or Fortran order, compressed or not.
  • TIFF and PNG: 8/16-bit and float, multi-page, colour channels. TIFF opens in Pixel Clarity by default; PNG keeps VS Code's image preview unless you use Open in Pixel Clarity.
  • Tables: ECSV, CSV and TSV (.ecsv, .csv and .tsv, also gzipped, open in the table viewer; Open as text in its toolbar, or Reopen Editor With… → Text Editor, shows the file as text; .tab files open with Open as Table). ECSV column types, units, descriptions, formats and metadata come from the header (astropy's !!omap meta, UCDs and mixin columns included). Plain CSV is sniffed: delimiter (comma, tab, semicolon, pipe or aligned whitespace), header row or a # col1 col2 comment line, and per-column types (integers, floats, booleans, ISO times, text). 64-bit IDs such as Gaia source_id stay exact. Headers with invalid YAML (common in hand-edited files) still open, with a note.

Features

  • Scale functions: linear, log, pow, sqrt, squared, asinh, sinh and histogram equalization.
  • Limits: min/max, zscale (matches astropy), percentiles (99.5–90%), or typed values. You can lock limits so they stay put across slices and reloads.
  • Mouse and keyboard: right-drag adjusts contrast and bias, the wheel zooms about the pointer, and the arrow keys move the crosshair one pixel at a time. These are the controls most astronomy viewers share, so they should feel familiar.
  • RGB composites: show three same-size planes as red, green and blue, each with its own limits and stretch (linked by default). Files that label their planes as a colour set (FITS EXTNAME/CHANNEL of RED, GREEN, BLUE, or three different numbered FILTERs, and colour PNG/TIFF) open in colour; for others, the RGB button composes the current plane with the next two of the same size, and the plane picker changes the selected channel. To combine three separate files (for example stitched_red/green/blue.fits), select them in the explorer and choose Open Three Images as RGB; they are ordered by colour words or filter numbers in their names, and each gets its own data worker, so a reload of one file re-reads only that file. Blank pixels are black.
  • Colormaps: classic astronomy maps (heat, cool, a, b, bb, he, i8, aips0…) plus matplotlib's perceptual and diverging maps, with an invert toggle.
  • Row/column cuts pinned under and beside the image, kept aligned with its zoom and pan. When zoomed out they show the min–max envelope of the pixels each screen column covers. Their intensity axes sit in the corner between them, with a numbered tick on every grid line (1-2-5 steps sized to the space; a shared exponent for very large or small values). The hovered pixel's value is marked on both cuts.
  • Histogram with draggable lo/hi markers and the stretch curve drawn on top.
  • World coordinates: RA/Dec (or galactic, ecliptic, or linear axes) under the cursor, in sexagesimal or degrees, read from the FITS WCS: TAN with SIP distortion, SIN, ARC, STG, ZEA and CAR, with CD, PC/CDELT or CROTA2 matrices and INHERIT in extensions. A compass shows north and east, and the Info panel gives the plate scale, field size and rotation. The readout is computed in the viewer, so moving the mouse sends nothing over the network.
  • Regions: box, circle, line (profile) and point. Each gets N, sum, mean, median, σ, min/max and a flux-weighted centroid. Stats copy as TSV. Regions save and load as DS9 .reg files, in sky coordinates (fk5/icrs) when the image has a WCS, so you can move them between tools. Region files with thousands of shapes, such as source catalogs, load as a fast read-only overlay.
  • Navigation and inspection: pixel table (3×3 to 9×9; every cell gets the same precision, as much as fits and the dtype carries, switching to a shared ×10ⁿ or offset when needed; hover for the full value), magnifier, panner, a searchable FITS header / HDF5 attributes / ASDF metadata panel, an HDU/dataset/array picker, and a cube slider with play.
  • Full-resolution export: the export button (or Pixel Clarity: Export Image (Full Resolution)…) writes a PNG of the whole image, the visible area or a selected box, at full resolution or block-averaged by 2–16, with the current limits, stretch and colormap or RGB channels. It is rendered by the extension next to the data, reading the file in bands, so a multi-gigabyte mosaic exports with a few hundred MB of memory and nothing crosses the network; the file is saved on that machine. Export View as PNG still saves exactly what is on screen.
  • Live reload: the view refreshes when the file is rewritten, for example by a testbed loop. Zoom, stretch and regions are kept.

Table viewer

Catalogs, photometry tables, instrument curves and housekeeping time series open as a grid that scrolls smoothly through millions of rows.

  • Search (Ctrl+F) keeps the rows containing some text in any shown column.
  • Filters are expressions in a Python-like syntax: phot_g_mean_mag < 18 and parallax > 0, 18 < mag <= 20, class in ('STAR', 'QSO'), `SCU 1` > 0.4, isnull(z), contains(name, 'ngc'), matches(id, '^J\d+'), cone(ra, dec, 80.12, -69.32, 0.05), ObsTime >= '2026-09-12 05:30'. Column names and functions autocomplete; mistakes are underlined as you type, with a hint (No column named 'magg'. Did you mean mag?). Filters stack as chips you can edit, switch off or remove. Missing values never equal anything; != keeps them, as in pandas.
  • Filter from the data: right-click a cell for == value, != value, ≤, ≥ or only missing; click a most-common value in the Column panel; drag across its histogram for a range; or drag a box on the plot.
  • Sort by clicking a header (Shift+click adds further keys). Text sorts naturally (SCU 2 before SCU 10); missing values always go last.
  • Columns: drag headers to reorder, drag their edge to resize (double-click to fit), pin columns to the left, hide them, or find them by name, unit or description in the Columns panel. Units sit under the names; descriptions show on hover.
  • Computed columns use the same expressions: abs_g = phot_g_mean_mag + 5*log10(parallax/100). They can be filtered, sorted, plotted and exported like any other.
  • Row panel: the selected row with every column at full precision, searchable, for wide catalogs. Column panel: count, missing, NaN, min, max, mean, median, σ, percentiles, distinct values, a histogram (central 99% when there are outliers) and the most common values.
  • Plot: scatter of any columns, switching to a density map binned next to the data when there are more points than are worth sending; several Y columns as lines (QE curves, sensitivity tables); a histogram when no Y is chosen; time axes for time columns; log axes; flip Y for magnitudes; colour by a third column. Wheel zooms, drag a box to zoom or filter, double-click resets, click a point to select its row.
  • Copy the selection as tab-separated text (Ctrl+C, Ctrl+Shift+C with the header) to paste into a spreadsheet or notebook.
  • Export the view (filtered, sorted, shown columns) or the whole table as CSV, TSV or ECSV that astropy.table.Table.read reads back with types, units, masks and metadata, or as a region file of circles or points from RA/Dec or pixel columns (0- or 1-based). Overlay on image sends the same markers straight to an image open in Pixel Clarity, so you can filter a catalog and see the result on the frame.
  • Cells show values as the file writes them: its decimals, its exponent digits, the ECSV format, float32 values at float32 precision, times in the file's own ISO style.

On a 2-million-row, 12-column catalog (372 MB CSV) the remote loads it in about 3 s; filters take 15–65 ms, a sort about 0.5 s, column statistics 0.16 s and a density plot 0.1 s. Scrolling to the last row over a simulated 10 Mbit/s link transferred about 10 KB.

Built for remote work

When VS Code is attached over SSH, or to a container, the pixels stay on the remote machine:

  • The extension's data server runs next to the file. It decodes frames, builds a tile pyramid and does all the statistics at full precision.
  • The viewer runs locally and renders with your GPU through WebGL. Pan, zoom, re-stretch and colormap changes never touch the network.
  • Tables work the same way: the file is parsed, filtered, sorted, summarized and binned for plots next to the data, and the viewer fetches only the rows and columns on screen. Exports are written on that machine.
  • Only the tiles you're looking at are sent. A screen-sized overview comes first, and detail follows coarse-to-fine.
  • Full-resolution tiles are lossless and compressed. Integer data, including float files that only hold integers, travels as int16/uint16.

Very large images (stitched focal-plane mosaics and similar) are streamed rather than loaded. Above pixelClarity.streamAboveMB, which defaults to 512 MB:

  • The data server makes one sequential pass that builds a downsampled overview and exact min/max/mean/σ. zscale, percentiles and the histogram come from an even sample of about 500k pixels, marked "(sampled)" in the UI.
  • Full-resolution tiles, cuts, pixel values and region stats are read from disk only when you look at them, so memory stays at a few hundred MB whatever the image size.
  • This applies to uncompressed FITS images, C-order .npy/.npz, and ASDF arrays in uncompressed or lz4 blocks.
  • On a 26000 × 16000 float32 mosaic (1.66 GB, 18 SCAs with NaN gaps):
    • the overview pass took 2.6 s with the file in the OS cache;
    • full-resolution tiles come back in 20–50 ms;
    • region stats over a whole 4088² SCA take 0.6 s;
    • peak memory was about 450 MB;
    • the fit-to-window view needed under 1 MB over the link.

On a simulated 10 Mbit/s, 150 ms link, a 4096² float32 frame (64 MB) shows its first overview in about 0.7 s and is fully sharp in about 1.4 s, after receiving about 1.1 MB.

Keys

f fit · 1/2/4 zoom · z zscale · m min/max · s cycle scale · i invert · r reset contrast · c crosshair · [ ] slices · space play · b/o/l/p region tools · Esc pan tool · ? help

Acknowledgements

The zscale algorithm is ported from astropy, which derives it from STScI's numdisplay. The colormap tables come from matplotlib. Licenses for these and for the bundled npm packages are in THIRD_PARTY_NOTICES.md, which ships with the extension.

License

MIT © 2026 Clarity Orbital Inc. See LICENSE.

Development

npm install
npm test                 # decoder + statistics tests against astropy/numpy/h5py fixtures
npm run dev              # build + browser harness at http://localhost:5178 (add &rtt=150&mbps=10 to throttle)
npm run package          # → pixel-clarity-<version>.vsix
code --install-extension pixel-clarity-0.1.0.vsix

To regenerate the test fixtures (nothing is installed into conda base):

uv run --no-project --with numpy --with astropy --with h5py --with tifffile --with pillow --with asdf --with asdf-astropy --with lz4 python scripts/make_fixtures.py

Releasing

  1. Add notes under ## Unreleased in CHANGELOG.md as you go.
  2. npm run release -- patch (or minor, major, 1.2.3). This bumps the version, moves the notes under it, commits Release vX.Y.Z and tags vX.Y.Z.
  3. git push origin main --follow-tags. The Release workflow tests the tag, builds the extension and attaches it as pixel-clarity.vsix to a GitHub release named after the tag, with the same notes.
  4. Download the .vsix from that release and upload it to the Marketplace (publisher clarity-orbital → Pixel Clarity → Update).

Each Marketplace version then has a GitHub release with the identical .vsix and notes.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft