User Guide ========== This guide takes a new user from "I have a PDS3, VICAR, or FITS file on disk" to "I have a JPEG or TIFF". .. contents:: :local: :depth: 2 1. Overview ----------- ``rms-picmaker`` is a SETI / PDS Ring-Moon Systems Node tool that converts binary 2-D and 3-D astronomy images into picture files suitable for visual display. It accepts: * PDS3-labeled images, with either attached or detached labels. * VICAR images. * FITS images. * Pickled NumPy arrays (``.pkl``) and ``.npy`` files. * Common raster formats: BMP, GIF, JPEG, PNG, plain TIFF. It produces JPEG, PNG, BMP, GIF, or TIFF picture files (8-bit per channel by default; 16-bit TIFF when ``--16`` is set). ``rms-picmaker`` ships as both a command-line tool (``picmaker``) and an importable Python library (``import picmaker``). The CLI is the fastest way to get a single image converted; the library lets you script multi-file pipelines and embed the conversion inside larger tools. The library entry point is ``images_to_pics``, which accepts the same keyword arguments the CLI binds to, so any CLI invocation is exactly equivalent to one library call. 2. Installation --------------- Install from PyPI:: pip install rms-picmaker If you only need the command-line tool, ``pipx`` keeps it isolated from your other Python environments:: pipx install rms-picmaker ``rms-picmaker`` requires Python 3.11 or later. 3. Quick start -------------- Convert one VICAR image to a JPEG:: picmaker tests/fixtures/cassini_iss.vic --directory /tmp/out The output file is written next to the input by default, or in ``--directory`` when given. Globbing across a tree is done by combining ``--recursive`` with ``--pattern``:: picmaker --pattern '*.IMG' --recursive /path/to/data --directory /tmp/out The full command-line reference is in section 4 below. The same operation from Python: .. code-block:: python from picmaker import images_to_pics images_to_pics( ['tests/fixtures/cassini_iss.vic'], directory='/tmp/out', ) 4. Command-line reference ------------------------- The flag groups below mirror the ``picmaker --help`` output exactly. Control options ~~~~~~~~~~~~~~~ * ``--directory DIR`` (default: input directory) — Output directory. Required when ``--recursive`` is set. * ``-r``, ``--recursive`` — Descend into directory trees, mirroring the input layout under ``--directory``. * ``--pattern PATTERN`` (default: ``'*'``) — Glob filter applied to file names during recursion. * ``--movie`` — Share one set of enhancement limits across every input. Incompatible with ``--hst``. * ``--versions FILE`` — For each non-blank line in ``FILE``, re-parse the command line with that line's tokens appended and run the resulting pipeline. Produces one output per non-blank line. * ``--verbose N`` (default: ``0``) — ``1`` prints each directory in a recursive walk; ``2`` prints every file path. * ``--replace POLICY`` (default: ``all``) — One of ``all`` (silent overwrite), ``none`` (skip silently), ``warn`` (overwrite with a warning), ``error`` (abort). * ``--proceed`` — On a per-file error, log the traceback and continue with the remaining inputs instead of aborting. Output options ~~~~~~~~~~~~~~ * ``-x EXT``, ``--extension EXT`` (default: ``jpg``, or ``tiff`` if ``--16``) — Output file format. Choices: ``bmp``, ``dib``, ``gif``, ``jpg``, ``jpeg``, ``png``, ``tif``, ``tiff`` (any-case). * ``-s STR``, ``--suffix STR`` (default: ``''``) — Inserted between the file stem and ``.``. * ``--strip STR`` (default: ``''``) — Substring to remove from the output filename's stem before appending the suffix. * ``--alt-strip STR``, ``--alt_strip STR`` — Additional substring to strip; both ``--strip`` and ``--alt-strip`` apply. * ``-q N``, ``--quality N`` (default: ``75``) — JPEG quality, 1-100. Ignored for non-JPEG outputs. * ``--16`` — Emit a 16-bit grayscale or 16-bit RGB TIFF. Forces ``--extension`` to ``tiff`` when unset. Incompatible with ``--filter`` (16-bit filters are not supported). Selection options ~~~~~~~~~~~~~~~~~ * ``-b N``, ``--band N`` (default: ``0``) — Select a single band from a 3-D array. Incompatible with ``--bands`` (except when ``band == bands[0] == bands[1]``). * ``--bands LO HI`` (default: ``(band, band+1)``) — Average bands ``LO..HI-1`` (half-open range). * ``--rectangle S1 L1 S2 L2`` — Sub-region selection by sample / line corners. * ``-o N``, ``--object N`` (default: first valid) — Index of the PDS object to read when a file contains multiple image objects. * ``--pointer PTR`` (default: ``IMAGE``) — PDS pointer name (without leading ``^``) identifying the image object in a detached label. * ``--alt-pointer PTR``, ``--alt_pointer PTR`` — Fallback pointer tried when ``--pointer`` is not in the label. * ``--pds3-label-method METHOD``, ``--pds3_label_method METHOD`` (default: ``strict``) — Parsing strictness forwarded to :class:`pdsparser.PdsLabel` for ``.LBL`` inputs. Choices: ``strict`` (rigorous PDS3 grammar), ``loose`` (allow common deviations), ``compound`` (try strict then loose), ``fast`` (minimum-overhead key/value scan). Sizing options ~~~~~~~~~~~~~~ * ``--size W H`` — Force output dimensions in pixels. Incompatible with ``--frame``. * ``--scale PCT`` (default: ``100``) — Uniform percentage scale. Incompatible with ``--wscale`` / ``--hscale``. * ``--wscale PCT`` (default: matches ``--scale``) — Horizontal-only percentage scale. * ``--hscale PCT`` (default: matches ``--scale``) — Vertical-only percentage scale. * ``--crop VALUE`` — Crop outer rows / columns whose every pixel equals ``VALUE`` (typically used to trim CCD frames of zeros). * ``--frame W H`` — Fit the image inside a ``W x H`` box, preserving aspect ratio. Incompatible with ``--size`` and ``--wrap-ratio``. * ``--pad`` — When set with ``--frame``, pad the output to the full frame size; otherwise the output is cropped to content. * ``--pad-color NAME`` (default: ``black``) — Padding fill color (any X11 color name or ``#RRGGBB``). * ``--frame_max PCT`` — When set with ``--frame``, the up-scaling is capped at this percentage of the input size (prevents up-scaling a tiny image to fill a large frame). Layout options ~~~~~~~~~~~~~~ * ``--wrap`` — Split very elongated images into stacked sections. * ``--wrap-ratio R`` — Wrap when ``max(W, H) / min(W, H) > R``. Incompatible with ``--frame``. * ``--overlap PCT`` (default: ``0``) — Per-section overlap percentage (single value). Incompatible with ``--overlaps``. * ``--overlaps LO HI`` — Range of overlap percentages explored to pick the best fit. * ``--gap-size N``, ``--gapsize N`` (default: ``1``) — Width in pixels of the gap drawn between wrapped sections. * ``--gap-color NAME``, ``--gapcolor NAME`` (default: ``white``) — Gap color (X11 color name or ``#RRGGBB``). * ``--hst`` — Construct a mosaic from all HST detector panels (ACS/WFC, WFPC2). Incompatible with ``--band`` / ``--bands`` / ``--movie``. Scaling options (histogram and intensity controls) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``-v LO HI``, ``--valid LO HI`` — Pixels outside ``[LO, HI]`` are treated as invalid (filled with ``--invalid`` color, excluded from the histogram). * ``-l LO HI``, ``--limits LO HI`` — Force the histogram stretch endpoints. Overrides ``--percentiles``. * ``-p LO HI``, ``--percentiles LO HI`` (default: ``(0, 100)``) — Percentile cut for the histogram stretch. Used when ``--limits`` is not set. * ``--trim N`` (default: ``0``) — Pixels at the image edge to ignore when computing the histogram. * ``--trim-zeros``, ``--trimzeros`` — Ignore exterior rows / columns that are entirely zero (CCD overscan cleanup). * ``--footprint D`` (default: ``0``) — Diameter in pixels of a circular median-filter footprint used to compute the histogram. * ``--histogram`` — Use a flat-histogram stretch instead of the linear stretch. Enhancement options ~~~~~~~~~~~~~~~~~~~ * ``-c NAME``, ``--colormap NAME`` — Apply a named colormap (e.g. ``black-white``, ``red-blue``, ``black-blue-white``). Names are hyphen-separated lists of X11 color stops. * ``--below COLOR`` — Color used for pixels below the lower limit. * ``--above COLOR`` — Color used for pixels above the upper limit. * ``--invalid COLOR`` (default: ``black``) — Color used for invalid pixel values and NaNs. * ``-g G``, ``--gamma G`` (default: ``1.0``) — Power-law correction applied to the grayscale axis. * ``--tint`` — Override the colormap with the per-instrument tint inferred from the filter name. See section 6. Orientation options ~~~~~~~~~~~~~~~~~~~ * ``-u``, ``--up`` — Force the image to be drawn with line numbers increasing upward (overrides per-instrument default). * ``-d``, ``--down`` — Force line numbers increasing downward. Incompatible with ``--up``. * ``--rotate KIND`` (default: ``none``) — One of ``none``, ``fliplr``, ``fliptb``, ``rot90``, ``rot180``, ``rot270`` (any-case). Processing options ~~~~~~~~~~~~~~~~~~ * ``-f NAME``, ``--filter NAME`` (default: ``none``) — One of the Pillow filter presets (``blur``, ``contour``, ``detail``, ``edge_enhance``, ``edge_enhance_more``, ``emboss``, ``find_edges``, ``smooth``, ``smooth_more``, ``sharpen``, ``median_``, ``minimum_``, ``maximum_`` for ``n`` in 3, 5, 7), plus ``none``. Any-case. * ``--zebra`` — Interpolate across the black "zebra stripes" some legacy detectors put at the start and end of each line. 5. Supported input formats -------------------------- ``rms-picmaker`` reads the following input formats: * **PDS3 detached label** — a ``.LBL`` file pointing at one or more ``IMAGE`` objects in a sibling data file. ``--pointer`` and ``--alt-pointer`` choose which pointer to follow when more than one is present. * **PDS3 attached label** — the label header precedes the image data in the same file. * **VICAR** — including per-instrument variants (Cassini ISS, Voyager ISS, Galileo SSI). The instrument is recognized automatically from the label, which enables instrument-aware tinting (see section 6). * **FITS** — including HST (WFC3, ACS, WFPC2, NICMOS) and New Horizons (MVIC). HST mosaics across multiple detector panels are reconstructed with ``--hst``. * **Pickled NumPy arrays** (``.pkl``) and **NumPy** ``.npy`` files. * **Common raster formats** — BMP, GIF, JPEG, PNG, plain TIFF. 6. Supported instruments and filters ------------------------------------ When ``--tint`` is enabled, ``rms-picmaker`` recognizes images from the instruments below and applies a per-filter tint. Cassini ISS ~~~~~~~~~~~ Recognized from VICAR labels for the Cassini Orbiter. Filters are selected from the ``FILTER_NAME`` tuple joined with ``'+'`` (e.g. ``CL1+GRN``). The tint is chosen by a chain of substring tests on the filter key: * ``IR`` → reddish IR shading * ``UV`` → violet * ``VIO`` → violet * ``BL`` → blue * ``GRN`` → green * ``RED`` → red * ``MT1``, ``CB1``, ``HAL``, ``MT``, ``CB`` → narrowband methane / hydrogen-alpha shadings Unknown filters fall back to neutral gray. Voyager ISS ~~~~~~~~~~~ Recognized from Voyager VICAR labels. Supported filters and their tints: * ``UV`` → (200, 60, 255) * ``VIOLET`` → (200, 120, 255) * ``BLUE`` → (110, 110, 255) * ``GREEN`` → (110, 255, 110) * ``ORANGE`` → (255, 170, 100) * ``NAD`` → (110, 255, 110) * ``SODIUM`` → (110, 255, 110) * ``CH4_U`` / ``CH4/U`` → (255, 60, 60) * ``CH4_JS`` / ``CH4/JS`` → (255, 60, 60) Galileo SSI ~~~~~~~~~~~ Recognized from Galileo SSI VICAR labels. Supported filters and their tints: * ``CLEAR`` → (128, 128, 128) * ``RED`` → (190, 130, 100) * ``GREEN`` → (110, 190, 110) * ``VIOLET`` → (160, 100, 200) * ``IR-7270`` → (200, 100, 100) * ``IR-7560`` → (210, 80, 80) * ``IR-8890`` → (220, 60, 60) * ``IR-9680`` → (230, 40, 40) HST (WFC3 / ACS / WFPC2 / NICMOS) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Recognized from FITS headers. The tint is derived from the wavelength inferred by parsing the digits out of the filter name (for example, ``F606W`` becomes 606 nm) and looking that wavelength up in an internal CIE-style color table. Per-detector adjustments: * **NICMOS** scales the inferred number by 3.5 (NICMOS filter names encode tens of nm, not nm). * **WFC3/IR** and **ACS/SBC** scale by 3.5 when the inferred number is below 200. * **WFPC2** quad-filters ``FQUV*`` and ``FQCH4*`` are pinned to 300 nm and 900 nm respectively. * **NICMOS** polarisers ``POL0S`` / ``POL0L`` are pinned to 110 nm and 220 nm. The broadband filters ``F350LP``, ``F606W``, and ``LONG_PASS`` use a plain black-to-white colormap. When no wavelength can be inferred the tint is skipped and the existing colormap is left in place. New Horizons MVIC ~~~~~~~~~~~~~~~~~ Recognized from New Horizons MVIC FITS headers. Supported filters and their tints: * ``BLUE`` → (110, 110, 210) * ``RED`` → (190, 100, 100) * ``NIR`` → (210, 65, 45) * ``CH4`` → (230, 35, 35) 7. Output formats and their controls ------------------------------------ ``--extension`` (alias ``-x``) chooses the output container: * ``bmp`` / ``dib`` — Windows Bitmap. 8-bit grayscale or 24-bit RGB; lossless. * ``gif`` — GIF. 8-bit indexed; transparency not preserved. * ``jpg`` / ``jpeg`` — JPEG. 8-bit RGB only; ``--quality 1..100`` controls compression. * ``png`` — PNG. 8-bit grayscale or 24-bit RGB; lossless. * ``tif`` / ``tiff`` — TIFF. 8-bit by default. With ``--16`` the output is a 16-bit grayscale TIFF (or 16-bit RGB when the colormap path produced 3-channel data). The output filename stem is built as ``.``, with ``--strip`` and ``--alt-strip`` each removing the first occurrence of their value from ````. 8. Enhancement controls ----------------------- The intensity pipeline runs in this order: 1. ``--valid LO HI`` masks pixels outside the range (replaced with ``--invalid`` color). 2. ``--limits`` or ``--percentiles`` chooses the linear stretch endpoints (``--limits`` wins when both are set). ``--trim`` / ``--trim-zeros`` / ``--footprint`` further refine which pixels are considered. 3. ``--histogram`` switches the stretch from linear to flat-histogram-equalised. 4. ``--colormap NAME`` maps the stretched values into RGB. Names are hyphen-separated lists of X11 color names. ``--tint`` overrides this step with the per-instrument tint from section 6. 5. ``--below``, ``--above``, ``--invalid`` override the colors used for the three special cases. 6. ``--gamma G`` applies a final power-law correction (``out = in ** (1 / G)``). 9. Geometry controls -------------------- Geometry runs in this order: 1. ``--rectangle`` / ``--crop`` / ``--trim`` shrink the working region. 2. ``--rotate`` (or the implicit default from the per-instrument detector geometry) flips / rotates the working array. 3. ``--size`` / ``--scale`` / ``--wscale`` / ``--hscale`` resize the working array. ``--frame W H`` instead picks the largest scale that fits inside ``W x H``; ``--frame_max PCT`` caps how far the image may be enlarged. 4. ``--wrap`` / ``--wrap-ratio`` / ``--overlap`` / ``--overlaps`` split very elongated images into stacked panels separated by a ``--gap-size`` × ``--gap-color`` gap. 5. ``--pad`` re-introduces the full ``--frame`` box, filling with ``--pad-color``. 10. The ``--versions FILE`` form -------------------------------- ``--versions FILE`` re-parses the command line once per non-blank line in ``FILE``, appending the line's tokens to the command for each run. The same input file therefore produces one output per line, each with its own suffix / quality / colormap / etc. For example, ``two_versions.txt``:: --suffix _v1 --extension jpg --quality 90 --suffix _v2 --extension tif --16 paired with ``input.IMG`` produces ``input_v1.jpg`` and ``input_v2.tif`` in one read. Lines starting with ``#`` and blank lines are skipped. Every mutex / value-validity check the CLI performs fires per line, so an invalid version doesn't abort the others (when combined with ``--proceed``). 11. Programmatic usage ---------------------- The library mirrors the CLI: every flag binds to a keyword argument of ``images_to_pics``. .. code-block:: python from picmaker import images_to_pics # Convert one file with a percentile stretch and a colormap. images_to_pics( ['data/cassini.vic'], directory='/tmp/out', percentiles=(5.0, 95.0), colormap='black-blue-white', extension='png', ) # Re-use the same stretch across a sequence of frames (movie mode). limits, _, _ = images_to_pics(['frame_001.vic'], directory='/tmp/out') for n in range(2, 100): images_to_pics( [f'frame_{n:03d}.vic'], directory='/tmp/out', limits=limits, ) Lower-level helpers are re-exported on the top-level package: .. code-block:: python from picmaker import ( read_one_image_array, tinted_colormap, apply_colormap, array_to_pil, ) See :doc:`module` for the full API reference. 12. Troubleshooting ------------------- * ``Unrecognized image file format`` — None of the supported readers recognized the file. Check the file is not truncated and that its magic bytes match one of the supported formats. * ``Unknown HST filter: `` — HST wavelength inference failed for this filter; no tint is applied and the existing colormap is preserved. * ``hst and band options are incompatible`` — ``--hst`` (mosaic mode) consumes every detector panel, so it cannot be combined with ``--band`` or ``--bands``. * ``band and bands options are incompatible`` — ``--band`` and ``--bands`` were both given with mismatched values. Use one or the other. * ``scale and wscale options are incompatible`` — ``--scale`` sets both axes; use ``--wscale`` / ``--hscale`` instead for per-axis control. * ``frame and size options are incompatible`` — ``--frame`` and ``--size`` both specify the output dimensions and can't be combined. * ``frame and wrap_ratio options are incompatible`` — ``--frame`` and ``--wrap-ratio`` produce conflicting layout decisions. * ``only tiffs can be written in 16-bit mode`` — ``--16`` requires ``--extension tiff``. * ``16-bit filter options are not supported`` — The Pillow filter presets only work on 8-bit images; drop ``--filter`` when using ``--16``.