Skip to main content

JanusReader

Version DOI

JanusReader is the official Python library for reading data from the JANUS instrument on board ESA's JUICE mission. It loads image pixels and metadata from the accompanying PDS4 label.

DOI: 10.5281/zenodo.13364878

Installation

The current source version is 0.18.3 and requires Python >=3.14,<4.

Install the published package:

python3 -m pip install JanusReader

To install the version in this checkout, first install uv:

uv sync --locked --no-default-groups

The published package may differ from the source version. Check the installed version with:

python3 -m JanusReader --version

For the uv-managed checkout, use uv run --locked --no-default-groups python -m JanusReader --version to query the project environment.

The CLI reads its version from installed package metadata. Run uv sync after changing the version in pyproject.toml to refresh the lockfile and installed metadata.

Input products

Keep the image file and its matching .lblx label in the same directory, with the same basename.

Input Behavior
.vic Reads raw pixels as a NumPy uint16 array, using the offset and dimensions in the label.
.dat Reads calibrated pixels as a NumPy float32 array. The file must contain exactly the image pixels; this read does not apply the label offset.
.lblx or .xml Resolves to .vic when the filename contains raw, or to .dat when it contains cal. It then loads the matching .lblx label, even when the supplied suffix is .xml.

Pixel interpretation follows the label's processing_level: raw uses the raw reader; other levels use the calibrated reader. Both readers use NumPy's native byte order.

For calibrated products, the filename must follow the JANUS naming convention: the fourth underscore-separated component from the end contains a leading character followed by the hexadecimal skipped-calibration bit mask (for example, a_b_c_c03_d_e_tail.dat). Arbitrary calibrated filenames are not supported.

Python usage

from JanusReader import JanusReader

product = JanusReader("datafile.vic")
image = product.image  # NumPy array with shape (Lines, Samples)

print(product.target, product.level)
print(product.startDT, product.endDT)
product.Show()          # General product information
product.Show(all=True)  # Includes processing and instrument metadata

# Both distances are None when geom:Distances or the target distance is missing.
spacecraft_solar_distance = product.spacecraftSolarDistance
target_solar_distance = product.targetSolarDistance

The constructor accepts a string or pathlib.Path, an optional Rich console, and the boolean options debug and vicar (both default to False). Set vicar=True to parse the embedded raw VICAR header into product.vicar; calibrated .dat products ignore this option with a warning.

Common attributes

Attribute names are case-sensitive.

Attribute Contents
image, Lines, Samples Image array and dimensions.
fileName, labelFile Resolved image and label paths.
title, prodVersion, level, dataDesc Product identification, last modification version, processing level, and optional observation comment.
startDT, endDT, creationDate Python datetime values without timezone information.
startSC, endSC Spacecraft clock counts from the label.
target, phaseName, phaseID Target and mission context.
Exposure, Filter, subFrame, instrumentState Exposure, filter, subframe, and instrument temperature metadata.
onBoardProcessing, onGroundProcessing, proceesingContext Processing metadata; proceesingContext retains its existing API spelling.
spacecraftSolarDistance, targetSolarDistance Heliocentric distance values as stored in the label, without unit conversion.
skippedCalibrationSteps Calibrated-product object with a .steps list; None for raw products.

Since 0.18.0, psa:stop_orbit_number is no longer read, endOrbit is no longer created, and the information display omits End Orbit. Since 0.18.1, psa:start_orbit_number, startOrbit, and the Start Orbit display row are also removed.

Since 0.18.3, a missing geom:target_heliocentric_distance produces no missing-label warning; a missing spacecraft distance produces a warning again. If geom:Distances or the target distance field is absent, the constructor sets both spacecraftSolarDistance and targetSolarDistance to None. If only geom:spacecraft_heliocentric_distance is absent, it emits a warning and sets spacecraftSolarDistance to None, preserving the target distance.

Missing scalar label values generally produce a warning and return None; missing required XML structures can raise IndexError. Missing files raise FileNotFoundError, and malformed XML raises a parser error. With vicar=True, an invalid raw VICAR header raises JanusReader.exceptions.NOT_VALID_VICAR_FILE.

Command line

janusReader datafile.vic
janusReader --all datafile.vic
janusReader --debug datafile.vic
janusReader --show-skipped-process a_b_c_c03_d_e_tail.dat
janusReader --version
janusReader --help

The default output shows general product information. --all (-a) adds instrument and processing tables; --show-skipped-process (-s) displays skipped calibration steps instead. --debug (-d) prints input-type diagnostics, and --help (-h) lists the options.

The same CLI is available through the active Python interpreter:

python3 -m JanusReader --help

Development

Install uv, then run:

uv sync --locked
uv run --locked pytest
uv run --locked python -m JanusReader --help
uv run --locked janusReader --version
uv lock --check
uv pip check
uv build

.python-version selects Python 3.14. uv sync creates .venv and installs the project in editable mode. The devel and test dependency groups are installed by default. For a runtime-only environment, use uv sync --locked --no-default-groups; add --extra docs to install Sphinx.

uv.lock is the authoritative dependency lockfile. Commit it alongside pyproject.toml when dependencies change. --locked prevents commands from silently updating it. The build uses uv_build with the case-sensitive JanusReader module under src/; pip installation remains supported. The release workflow installs locked dependencies, runs tests, and builds distributions with uv before publishing.

The repository's pytest configuration writes coverage reports under coverage/. Tests use synthetic products to check image loading, label compatibility, metadata helpers, and VICAR header parsing.

Publishing

Local publication with uv

Before each release, set the version with uv version <version> (or uv version --bump patch), and update the README version badge, changelog, and citation metadata to match. Commit the updated pyproject.toml and uv.lock together.

For version 0.18.3:

uv sync --locked
uv run --locked pytest
uv lock --check
uv pip check
uv build --no-sources

Set UV_PUBLISH_TOKEN to a PyPI API token through your shell or secret manager, then upload only the artifacts for the intended version:

uv publish dist/janusreader-0.18.3.tar.gz dist/janusreader-0.18.3-py3-none-any.whl

Avoid a bare uv publish when dist/ contains artifacts from older releases: it defaults to uploading all files in that directory. PyPI does not allow replacing an existing distribution filename with different contents; publish changed code under a new version.

GitHub release publication

The workflow Upload Python Package starts on a GitHub release's published event.

  1. Commit and push the release changes, including the workflow and uv.lock.
  2. In the repository's Settings → Secrets and variables → Actions, create the repository secret PYPI_API_TOKEN with a PyPI token authorized to publish JanusReader, or verify that it is already configured.
  3. In Actions → Upload Python Package, enable the workflow if it is disabled.
  4. In Releases → Draft a new release, choose a tag matching the package version (for example, v0.18.3) and target the commit containing the release changes. Add release notes and select Publish release.
  5. Follow the job in Actions. It installs Python 3.14 and locked dependencies, runs tests, builds the sdist and wheel with uv, and uploads them using pypa/gh-action-pypi-publish and the configured token.

A push, a tag alone, or a saved release draft does not trigger this workflow. It has no workflow_dispatch trigger, so there is no manual Run workflow button. GitHub Pages and environment configuration are not required for this PyPI publication.

See the uv publishing guide and GitHub release guide for details.

See CHNGELOG.md for version history.

Metadata

Release files for JanusReader 0.18.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for JanusReader 0.18.3
File Size Uploaded
janusreader-0.18.3.tar.gz 17.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for JanusReader 0.18.3
File Interpreter ABI Platform
janusreader-0.18.3-py3-none-any.whl Python 3 none any Details

Total release size: 30.8 kB

Release files / janusreader-0.18.3.tar.gz

Download URL janusreader-0.18.3.tar.gz
Size 17.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e90ea74257d2f10a84220eee10eda0d6527f1192e194291531ab240e420aa2ec
BLAKE2b-256 checksum
How to use checksums
cbe95b6af65cd5d98ab4fa3540bce691104117acc5144d61554cb4e037d0ef7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / janusreader-0.18.3-py3-none-any.whl

Download URL janusreader-0.18.3-py3-none-any.whl
Size 13.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
295b5d8f3ec2c1d057d307035d9985d1d84c3a10c41e4c9799d42ebc2a0068b7
BLAKE2b-256 checksum
How to use checksums
a49b95b7ce3987e0c9a6d0abd91bd03013fd025b2e512fe73c3173bcb56a223b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

0.18.3 This release

2 release files

0.18.2

2 release files

0.17.0

2 release files

0.16.1

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.12.2

2 release files

0.12.1

2 release files

0.12.0

1 release file

0.11.1

1 release file

0.11.0

1 release file

0.10.1

1 release file

0.10.0

1 release file

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page