# Molecular-line science reader

The ZIP is standalone scientific Python, without the app, Node/Worker Engine,
original observation, native molecular table or observation-derived images.
Own code and synthetic input carry the included MIT license.

Exact ZIP: molecular-line-cube-reader-science-v1.zip, 61,187 bytes.
SHA256: cf85e8e080669d55e84c0272e555017d0e45d4606a7ea5281492542774a44704.
It retains the original independent science producer and adds two own analytic
figures and READER-NOTES. The original scientific files remain unchanged.

Use an existing Python environment with NumPy, SciPy and Matplotlib. The actual
tested environment was Python 3.9.6, NumPy 2.0.2, SciPy 1.13.1, Matplotlib 3.9.4.
No dependency installer runs automatically.

Unpack into an empty directory and run the actual offline calculations:

    python3 -W error::RuntimeWarning scripts/astronomy/ac36/replay.py --output /absolute/new/path/ppv-demo

For the full registered refinements add --full-mesh. Results retain failed
coarse meshes and contrast them with improved finite cases. The default produces
its own exactly-two-level model, not a LAMDA CO catalog and not observed data.

For the real TW Hya disk exercise, review the linked source's scientific-use
conditions, keep the input and all derived observation products private, then run:

    python3 scripts/astronomy/ac36/optional_reader.py --source-dir /absolute/private/sources --download
    python3 -W error::RuntimeWarning scripts/astronomy/ac36/replay.py --native-source-dir /absolute/private/sources --full-mesh --output /absolute/new/path/alma-review

Only two complete fixed files are fetched: 4,763,520-byte official ALMA teaching
FITS and 444,204-byte LAMDA table. Exact URLs and full SHA256 values are in the
reader. There is no archive, alternate-data or installation fallback.

An implementation reader run actually acquired 5,207,724 fresh HTTP body bytes,
then completed all ten native/scientific replay steps in 447.4466 seconds. This
supplements the older package README's historical local-source run. Acquisition
and the following offline verification are different events. A local receipt may
be rewritten by offline verification with zero newly received bytes; preserve
the original acquisition receipt when maintaining a network budget.

The observed cube is already imaged and continuum-subtracted. The reader computes
native WCS/radio-LSRK coordinates, brightness and aperture spectra, signed and
positive-threshold moments, empirical correlated-channel diagnostics and actual
plots. It does not redo raw visibility imaging or infer a calibrated disk/cloud
posterior. Saved 0.12 km/s sampling differs from roughly 0.2 km/s effective
resolution. The 41-level finite native LTE model has no certified omitted-level
tail bound. Full scientific limits are in the bundled contract.

The website's single-column synthetic figures repeat the same independent
physical calculations with a more readable layout; the ZIP retains its original
two figure files. Both are own analytic/synthetic references.

## Read an interactive saved cube

The .ppv export is a self-describing Float64 record. Its first eight bytes are
ASCII SPPPV01 followed by a newline. The next four bytes hold an unsigned
little-endian JSON header length. UTF-8 JSON starts at byte 12; the remaining
bytes are little-endian Float64 brightness, reshaped as channel, y, x.
The header supplies velocity edges, physical units, settings and generation.
This decoding recipe reads a saved measurement without invoking an app model:

    import json, struct, numpy as np
    payload = open("molecular-line-cube-g1.ppv", "rb").read()
    assert payload[:8] == b"SPPPV01\n"
    size = struct.unpack_from("<I", payload, 8)[0]
    header = json.loads(payload[12:12+size])
    cube = np.frombuffer(payload, dtype="<f8", offset=12+size).reshape(header["shape"])

The physical scene has true geometric depth. The third data coordinate remains
velocity; decoding the record does not recover unknown real depth.
