Geometry table subsystem

Overview

The geometry subsystem computes geometric quantities for each observation and writes them as tables. It is the geometry_support package; the Architecture chapter introduces its principal classes. This chapter describes the modules and the contracts that are easy to get wrong.

Entry point

process_tables() (in metadata_tools.geometry_support.process) parses the command line through get_args() and walks the output tree (the tree that already holds the supplemental index files). For each volume it constructs a Suite and calls create(). The --new_only option skips volumes that already contain an *_inventory.csv; supplying explicit volumes disables it.

Suite

Suite reads the volume’s observations through the host’s from_index hook, builds the per-mode meshgrids once, and creates a list of tables for each requested level (an inventory table plus sky, ring, and body tables). It loops over observations, building a Record per level and dispatching each record to every table whose level matches. A RuntimeError is raised if a volume contains more than one index file.

Record and prep

Record holds one observation’s state: the primary body (from get_primary()), the selected bodies, the oops backplane, and the level-specific column dictionaries from the metadata_tools.columns package. add() calls prep_row(), which evaluates each column’s backplane key, applies the excluded-pixel mask, and formats the result; postprocess() then applies the null-linking rules so that linked columns go null together.

Masks

construct_excluded_mask() builds the boolean mask of pixels to exclude for a column, honoring the column’s masker, shadower, and face codes. It depends only on oops and numpy so it can be unit-tested without a host plugin.

Formatting and formats

formatted_column() turns a masked oops scalar into one or two formatted column strings, converting radians to degrees, handling cyclic (longitude) ranges, ISO times, null values, valid-range clipping, and overflow. It is driven by an entry from FORMAT_DICT.

The format-dictionary contract

FORMAT_DICT maps each column name to a ten-element tuple:

(flag, number_of_values, column_width, standard_format, overflow_format,
 null_value, valid_minimum, valid_maximum, link_id, link)

where flag controls unit conversion ("RAD"/"DEG" radians to degrees, "360" degrees with 360-degree periodicity, "-180" the (-180, 180) range, "ISO" time, "" no change), and link_id / link tie columns together for null-linking. ALT_FORMAT_DICT holds alternate formats keyed by (column_name, alt_format_tag).

Body selection

metadata_tools.geometry_support.bodies_select decides which bodies appear in a record: the primary and secondaries are always included; children of the primary and any additions are included when they intersect the field of view; the target and its parent are always included. It also produces the field-of-view inventory and, when SPICE pointing is unavailable, sets the record’s pointing_available flag so the row is written with null geometry.

Important invariants

  • Units. Backplane values are in radians; columns whose flag is "RAD", "DEG", "360", or "-180" are converted to degrees by formatted_column(). Do not pre-convert.

  • Column-description tuples. A column description is (backplane_key, (masker, shadower, face)) with an optional trailing alternate-format tag. The masker/shadower strings concatenate "P" (planet), "R" (rings), and "M" (blocker body); the face is "D", "N", or "". These tuples live in the metadata_tools.columns package.

  • Meshgrids are built once per Suite and selected per observation by telemetry mode; they are not rebuilt per row.

  • Summary vs. detailed. A summary call writes exactly one row per observation, even if every value is null; a detailed call writes only rows for non-empty tiles.

API reference

See Geometry table support and Geometry column definitions.