Skip to content

Publishing a catalog info page

When you share a HATS catalog with collaborators, the first questions are always the same: what is this, how big is it, where on the sky does it cover, what columns can I query, and how do I get it? acid web turns a catalog's own metadata into a small, self-contained web page that answers exactly those questions — a "should I use this catalog?" landing page.

The page is static: index.html (with a shipped skymap.js) reads JSON, a sky-map PNG, and a small density grid over HTTP, and renders an interactive sky map in the browser. There's no server process to keep running and no database behind it — you can drop the folder on any static host.

The three steps

acid web init ./catalog-site            # 1. scaffold a web directory
acid web add gaia_dr3 --into ./catalog-site   # 2. add a catalog (repeatable)
acid web serve ./catalog-site           # 3. serve it → http://localhost:8000/

1. init — scaffold a web directory

acid web init ./catalog-site

This creates a directory you can serve:

catalog-site/
  index.html        # the page
  skymap.js         # the WebGL sky-map renderer (shipped with the page)
  index.json        # the manifest (title, subtitle, download URL, catalog list)
  datasets/         # filled in by `acid web add`
  .acid.webdir      # marker that identifies this as an acid web directory

Set the page heading and the site-wide download link up front if you like:

acid web init ./catalog-site \
  --title "Survey Data Center" \
  --url   "https://data.example.org"

2. add — add a catalog

acid web add gaia_dr3 --into ./catalog-site

CATALOG is resolved the same way acid query resolves a name: a bare name is looked up on your ACID_PATH, or you can pass a local path (acid web add /data/hats/gaia_dr3 --into ./catalog-site). For each catalog, add:

  • writes, into <catalog>/acid.web/:
    • card.json — the catalog's metadata;
    • skymap.png — the density image (also the 2D-fallback texture), rendered from the catalog's point_map.fits;
    • density.bin.gz — exact per-HEALPix-pixel row counts, gzipped, powering the live rows/deg² readout under the cursor (the browser gunzips it natively);
    • partitions.json — the catalog's HATS partition tiles, for the overlay;
  • creates a relative symlink catalog-site/datasets/<name> → the catalog, so the page can read those files over the same origin;
  • records the catalog in catalog-site/index.json.

Run it once per catalog to build up the sidebar. Re-running it for the same catalog just regenerates the card.

add writes next to the catalog

The card, sky map, density grid, and partition tiles live in <catalog>/acid.web/, so they travel with the catalog and can be re-added to any number of sites. This means add needs write access to the catalog directory.

3. serve — view it

acid web serve ./catalog-site
# serving ./catalog-site at http://localhost:8000/

serve prints a URL and waits (Ctrl-C to stop). It does not open a browser — handy over SSH. Pass --host 0.0.0.0 to expose it on your network, or --port to pick a port. From inside the web directory you can drop the path:

cd ./catalog-site
acid web add sdss_dr17     # --into defaults to the current dir
acid web serve             # DIR defaults to the current dir

Listing what's in a site

acid web list shows the catalogs currently linked into a web directory — id, display name, row count, column count, and where each one points:

acid web list ./catalog-site

It reads the manifest, so it's a quick way to see what a site contains (and it flags any entry whose catalog has gone missing). The output is aligned on a terminal and tab-separated when piped.

Removing a catalog

acid web rm is the inverse of add — it drops the catalog's manifest entry and its datasets/ symlink:

acid web rm sdss_dr17 --from ./catalog-site   # or from inside the site dir, just: acid web rm sdss_dr17

The catalog's data is never touched. By default the generated <catalog>/acid.web/ (its card, sky map, density grid, and partition tiles) is left in place, since another site may symlink the same catalog; add --purge to delete it too.

The interactive sky map

The sky map is an interactive WebGL2 Mollweide projection of the catalog's source density, rendered from its point_map.fits. It is pan + zoom:

  • Drag to re-center — an oblique Mollweide rotation, not an image slide, so the projection stays correct as you move around the sphere.
  • Mouse-wheel (or pinch) to zoom about the cursor, up to ~64×.
  • Double-click to reset to the default view.

These gestures act only while the cursor is over the map ellipse. Longitude/RA increases to the left, following the usual astronomical convention.

Above the map, a row of controls lets a viewer reframe and annotate it:

  • Frame chips (equ / ecl / gal, equatorial by default) reproject the whole map between equatorial (ICRS), ecliptic, and galactic frames, client-side.
  • A HATS tiles toggle overlays the catalog's HEALPix partition tiles — a faint fill tinted by partition order with bright tile borders — so you can see how the catalog is partitioned.
  • A graticule (a 30° grid with degree labels) and three reference great circles — the celestial equator, the ecliptic, and the galactic equator, each in its own color, with a small legend under the map. The circle that coincides with the current frame's own equator is still drawn.

A cursor readout at the top-left of the map tracks the position under the pointer — RA/Dec, or l/b in galactic, or λ/β in ecliptic — together with the containing HATS pixel (HEALPix order + npix) and the local source density in rows/deg². The color bar beneath the map is labeled with the catalog's actual min/max density (rows/deg²).

A light/dark theme toggle sits at the top-right of the header; the page defaults to dark and remembers your choice.

Self-contained, with a fallback

The renderer is same-origin vanilla JavaScript shipped with the page (skymap.js) — no CDN and no external libraries. On a browser without WebGL2, or if the GL context is lost, it falls back to an equivalent 2D-canvas renderer, so a viewer never sees a blank map.

What's derived, and what you fill in

Everything technical is read straight from the catalog and is always correct:

On the page From the catalog
Row count, sky coverage, partition count, on-disk size properties (hats_nrows, moc_sky_fraction, hats_estsize)
HEALPix scheme, order range, leaf count, margin radius partition_info.csv, the margin cache
Column names, types, units, descriptions the parquet schema (units/descriptions from hats:unit / hats:description field metadata, when present)
The density sky map point_map.fits
The rows/deg² density readout under the cursor point_map.fits (via density.bin.gz)
The HATS partition-tiles overlay partition_info.csv (via partitions.json)

A HATS catalog carries no editorial information — there's nowhere in the format for a description, a license, an author, a DOI, or a "where to download it" link. Those come from an optional sidecar.

The editorial sidecar (acid-web.yaml)

The first time you add a catalog with no sidecar, acid web writes a starter acid-web.yaml next to it and tells you. Fill in the blanks and re-run add:

name: Gaia DR3
abbr: Gaia
source: ESA Gaia Archive
blurb: >
  Micro-arcsecond astrometry and three-band photometry for nearly two
  billion stars, quasars and galaxies across the whole sky.
license: CC BY 4.0
author: Gaia Collaboration
year: 2023
doi: 10.1051/0004-6361/202243940
download_url: https://example.org/gaia_dr3   # overrides the site-wide link

# Optional: extra key facts, merged by key with the derived ones
facts:
  - { k: "Reference epoch", v: "J2016.0" }
  - { k: "Mag range (G)",   v: "3  21" }

# Optional: per-column units / descriptions the catalog didn't store
columns:
  ra: { unit: deg, desc: "Right ascension (ICRS)" }

The derived card is the base; the sidecar overlays it — scalars override, facts merge by key, columns fill in units/descriptions. Anything you leave blank is simply omitted from the page (a catalog with no citation fields, for instance, just won't show a Cite button). Keep the sidecar somewhere else and point at it with acid web add … --meta path/to/meta.yaml.

Deploying it

The result is plain static files, so any static host works. Two notes:

  • The page reads JSON over HTTP, so it must be served, not opened from file://. acid web serve is the easy local option.
  • serve follows the datasets/ symlinks out to your catalog directories — fine for local, owned serving. To publish on a static host, copy the catalog acid.web/ folders in place of the symlinks (or serve from a machine where the catalogs are mounted).