ngff_zarr.structural_validation¶
Structural validation for OME-Zarr v0.4 image/multiscales metadata.
This module implements the OME-Zarr v0.4 specification MUSTs that a JSON
Schema cannot express, layered conceptually on top of the schema validation
performed by :mod:ngff_zarr.validate (which checks the raw attribute dict).
Where schema validation answers “is this shaped like OME-Zarr?”, the rules
here answer “does this obey the spec’s structural invariants?” – e.g. axis
counts, axis ordering, coordinate-transformation arity, finest-to-coarsest
dataset ordering, and OMERO channel color format.
The rules are pure Python (standard library only) and operate on the already
parsed :class:~ngff_zarr.v04.zarr_metadata.Metadata dataclass, so they work
even when the optional [validate] extra (jsonschema) is not installed.
Each rule is identified by a stable, kebab-case :class:SpecRule value that
is part of the observable surface (reused verbatim in logs, tests, and the
TypeScript port). Rules fail fast: the orchestrator
(:func:validate_structural) raises a :class:ValidationError on the first
violation, in canonical spec-MUST order.
Module Contents¶
Classes¶
Stable, kebab-case identifiers for the structural spec rules. |
|
How much validation :func: |
|
Options controlling structural validation. |
Functions¶
Check one coordinate transform’s vector length against the axis count. |
|
Return the first |
|
Validate that the axis count is within the v0.4-permitted range. |
|
Validate axis-type multiplicity. |
|
Validate the class ordering of axes. |
|
Validate the count and names of spatial axes. |
|
Validate that each dataset defines exactly one |
|
Validate coordinate-transform vector lengths against the axis count. |
|
Validate coordinate-transform ordering within each dataset. |
|
Validate that datasets are ordered finest to coarsest. |
|
Validate the color format of each OMERO channel. |
|
Render a parsed :class: |
|
Validate RFC 4 anatomical-orientation metadata on the spatial axes. |
|
Validate each plate well’s recorded indices against its |
|
Validate that well images reference an acquisition when required. |
|
Run the structural image/multiscales rules in canonical spec order. |
|
Run the structural HCS plate rules in canonical spec order. |
|
Run the structural HCS well rules in canonical spec order. |
Data¶
API¶
- class ngff_zarr.structural_validation.SpecRule¶
-
Stable, kebab-case identifiers for the structural spec rules.
Inheriting from :class:
strmakes the kebab-case identifier the member’s value, so it can be compared and logged directly (SpecRule.AXIS_COUNT == "axis-count") for stable assertions. Members are listed in canonical spec-MUST evaluation order.Initialization
Initialize self. See help(type(self)) for accurate signature.
- AXIS_COUNT¶
‘axis-count’
- AXIS_TYPE¶
‘axis-type’
- AXIS_ORDER¶
‘axis-order’
- SCALE_LENGTH_MISMATCH¶
‘scale-length-mismatch’
- GLOBAL_COORD_TRANSFORM_AFTER_PER_LEVEL¶
‘global-coord-transform-after-per-level’
- DATASET_ORDER_HIGHEST_TO_LOWEST¶
‘dataset-order-highest-to-lowest’
- OMERO_CHANNEL_COLOR_FORMAT¶
‘omero-channel-color-format’
- AXIS_ORIENTATION_CONSISTENT_TYPE¶
‘axis-orientation-consistent-type’
- AXIS_ORIENTATION_COMPLETENESS¶
‘axis-orientation-completeness’
- PLATE_ROW_INDEX_CONSISTENCY¶
‘plate-row-index-consistency’
- WELL_ACQUISITION_MISSING¶
‘well-acquisition-missing’
- class ngff_zarr.structural_validation.ValidationLevel¶
-
How much validation :func:
validate_structuralperforms.STRICTis the default and runs every structural image/multiscales rule in this module.SCHEMA_ONLYskips them (schema validation is handled separately by :mod:ngff_zarr.validateon the raw attribute dict). Deep, store-reading checks (e.g. confirming each dataset array exists with the expected shape) are intentionally out of scope for both levels.Initialization
Initialize self. See help(type(self)) for accurate signature.
- SCHEMA_ONLY¶
‘schema_only’
- STRICT¶
‘strict’
- class ngff_zarr.structural_validation.ValidateOptions¶
Options controlling structural validation.
Attributes
level: Validation level to run. Defaults to :attr:
ValidationLevel.STRICT. allow_unknown_fields: Whether unknown metadata fields are tolerated. Defaults toTrueto mirror the parser, which warns on (rather than rejects) unknown fields.- level: ngff_zarr.structural_validation.ValidationLevel¶
None
- exception ngff_zarr.structural_validation.ValidationError(
- rule: ngff_zarr.structural_validation.SpecRule,
- message: str,
- location: str | None = None,
Bases:
ExceptionRaised when a structural spec rule is violated.
Carries the offending :class:
SpecRule, a human-readablemessage, and an optionallocationidentifying the offending metadata node in dotted-segment (JSON-Pointer-style) form, e.g.multiscales[0].datasets[2].coordinateTransformations[0].Initialization
Initialize self. See help(type(self)) for accurate signature.
- ngff_zarr.structural_validation._transform_len_mismatch(
- transform: ngff_zarr.v04.zarr_metadata.Transform,
- axes_len: int,
Check one coordinate transform’s vector length against the axis count.
Centralizes the length invariant shared by the global and per-dataset coordinate-transformation checks (see
- Attr:
SpecRule.SCALE_LENGTH_MISMATCH), so the rule lives in one place.
Returns
("scale", actual_len)or("translation", actual_len)when the transform’s vector length disagrees withaxes_len; otherwise returnsNone. Transforms that carry no length-bearing vector (e.g.identity) are ignored and returnNone.
- ngff_zarr.structural_validation._first_scale_vector(
- dataset: ngff_zarr.v04.zarr_metadata.Dataset,
Return the first
scalevector in a dataset, orNoneif absent.Used by :func:
validate_dataset_orderto compare adjacent multiscale levels without re-deriving the per-datasetscalelookup.
- ngff_zarr.structural_validation._AXIS_TYPE_RANK¶
None
- ngff_zarr.structural_validation._SPATIAL_AXIS_NAMES¶
(‘z’, ‘y’, ‘x’)
- ngff_zarr.structural_validation.validate_axis_count(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate that the axis count is within the v0.4-permitted range.
OME-Zarr v0.4 requires between 2 and 5 axes, inclusive.
Raises
ValidationError With :attr:
SpecRule.AXIS_COUNTwhenlen(metadata.axes)lies outside2..=5; locationmultiscales[0].axes.
- ngff_zarr.structural_validation.validate_axis_type(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate axis-type multiplicity.
At most one
timeaxis and at most onechannelaxis may be present.Raises
ValidationError With :attr:
SpecRule.AXIS_TYPEwhen more than onetimeaxis or more than onechannelaxis is present; locationmultiscales[0].axes.
- ngff_zarr.structural_validation.validate_axis_order(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate the class ordering of axes.
Axes are ranked by type (
time<channel<space) and must be listed in non-decreasing rank order: everytimeaxis precedes everychannelaxis, which precedes everyspaceaxis. The first adjacent pair that inverts this ranking is reported.Raises
ValidationError With :attr:
SpecRule.AXIS_ORDERfor the first adjacent pair where a lower-ranked axis type follows a higher-ranked one; locationmultiscales[0].axes[i+1].
- ngff_zarr.structural_validation.validate_spatial_axis_order(
- metadata: ngff_zarr.v04.zarr_metadata.Metadata,
Validate the count and names of spatial axes.
The
spaceaxes, taken in order, must be the matching-length suffix of(z, y, x): one spatial axis must be(x,), two must be(y, x), and three must be(z, y, x). At most threespaceaxes are permitted.Raises
ValidationError With :attr:
SpecRule.AXIS_ORDERwhen there are more than threespaceaxes, or when their names are not the expected suffix of(z, y, x).
- ngff_zarr.structural_validation.validate_per_dataset_scale_count(
- metadata: ngff_zarr.v04.zarr_metadata.Metadata,
Validate that each dataset defines exactly one
scaletransform.Every dataset’s
coordinateTransformationsmust contain exactly onescale(the per-level voxel size). This shares the per-dataset coordinate-transform-shape rule identifier (:attr:SpecRule.GLOBAL_COORD_TRANSFORM_AFTER_PER_LEVEL); there is no dedicated identifier for the scale count.Raises
ValidationError With :attr:
SpecRule.GLOBAL_COORD_TRANSFORM_AFTER_PER_LEVELwhen a dataset has zero or more than onescaletransform; locationmultiscales[0].datasets[i].coordinateTransformations.
- ngff_zarr.structural_validation.validate_scale_length(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate coordinate-transform vector lengths against the axis count.
Every
scaleandtranslationvector – in the globalcoordinateTransformations(if present) and in each dataset – must have exactly one entry per axis. The first mismatch, scanned global-then- per-dataset, is reported. The length invariant itself lives in- Func:
_transform_len_mismatch.
Raises
ValidationError With :attr:
SpecRule.SCALE_LENGTH_MISMATCHfor the first transform whose vector length disagrees withlen(metadata.axes); location identifies the offending transform.
- ngff_zarr.structural_validation.validate_transform_order(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate coordinate-transform ordering within each dataset.
Within a dataset’s
coordinateTransformations, atranslation(if present) must follow itsscale– ascalemust never appear after atranslation.Raises
ValidationError With :attr:
SpecRule.GLOBAL_COORD_TRANSFORM_AFTER_PER_LEVELfor the first dataset where ascalefollows atranslation; location identifies the offendingscale.
- ngff_zarr.structural_validation.validate_dataset_order(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate that datasets are ordered finest to coarsest.
Multiscale datasets must be listed from highest resolution (finest, i.e. smallest spatial
scale) to lowest (coarsest). For each adjacent pair, the later level’sscalemust not be smaller than the earlier level’s on anyspaceaxis. Pairs whosescalevectors are missing or too short to index a spatial axis are skipped – those shapes are the concern of- Func:
validate_per_dataset_scale_countand :func:validate_scale_length– so this rule never raisesIndexError.
Raises
ValidationError With :attr:
SpecRule.DATASET_ORDER_HIGHEST_TO_LOWESTfor the first adjacent pair whose later (coarser) level has a smaller spatial scale; locationmultiscales[0].datasets[i+1].
- ngff_zarr.structural_validation.validate_omero_color_hex(metadata: ngff_zarr.v04.zarr_metadata.Metadata) None¶
Validate the color format of each OMERO channel.
When OMERO rendering metadata is present, every channel
colormust be exactly six hexadecimal digits (RGB). This reuses the existing- Meth:
~ngff_zarr.v04.zarr_metadata.OmeroChannel.validate_colorpredicate rather than re-implementing the format check.
Raises
ValidationError With :attr:
SpecRule.OMERO_CHANNEL_COLOR_FORMATfor the first channel whosecoloris not six hex digits; locationmultiscales[0].omero.channels[i].color.
- ngff_zarr.structural_validation._axis_to_validation_dict( ) dict[str, Any]¶
Render a parsed :class:
Axisback to the dict form RFC 4 consumes.Emits only the fields the RFC 4 helpers inspect –
name,type, and (for a spatial axis that declares it)orientationas a{"type", "value"}dict. A storedorientationmay be a raw dict (the image read path builds axes viaAxis(**axis_dict), so no coercion happens) or an :class:~ngff_zarr.rfc4.AnatomicalOrientationdataclass; an enumvalueis reduced to its string, mirroring the package’shasattr(..., "value")convention.
- ngff_zarr.structural_validation.validate_axis_orientation(
- metadata: ngff_zarr.v04.zarr_metadata.Metadata,
Validate RFC 4 anatomical-orientation metadata on the spatial axes.
This rule does not reimplement RFC 4; it wraps the package’s existing logic – :func:
~ngff_zarr.rfc4_validation.has_rfc4_orientation_metadataand- Func:
~ngff_zarr.rfc4_validation.validate_rfc4_orientation– and surfaces its failures through the unified :class:ValidationErrorchannel. The parsed- Class:
~ngff_zarr.v04.zarr_metadata.Axisobjects are first rendered back to the axis-dict form those helpers expect (see :func:_axis_to_validation_dict).
Orientation is optional in RFC 4, so when no spatial axis carries it the rule is a no-op and the comparatively heavy
jsonschemaimport inside- Func:
validate_rfc4_orientationis never triggered.
Raises
ValidationError With :attr:
SpecRule.AXIS_ORIENTATION_CONSISTENT_TYPEwhen the spatial axes’ orientations do not all share onetype, or :attr:SpecRule.AXIS_ORIENTATION_COMPLETENESSwhen orientation is defined for some but not all spatial axes; locationmultiscales[0].axes. The original RFC 4 message text is preserved. jsonschema.exceptions.ValidationError Propagated unchanged when an orientation value is outside the RFC 4 vocabulary – a schema-level concern with no dedicated structural rule.
- ngff_zarr.structural_validation.validate_plate_well_index_consistency( ) None¶
Validate each plate well’s recorded indices against its
path.Every :class:
~ngff_zarr.v04.zarr_metadata.PlateWellrecords apathof the form"<row>/<column>"(e.g."B/03") alongside numericrowIndexandcolumnIndexfields. OME-Zarr v0.4 requires these to agree: the row segment must name an entry inplate.rowswhose position equalsrowIndex, and the column segment must name an entry inplate.columnswhose position equalscolumnIndex. The first offending well, scanned in order, is reported.Raises
ValidationError With :attr:
SpecRule.PLATE_ROW_INDEX_CONSISTENCYfor the first well whosepathis not"<row>/<column>", whose row/column segment is absent fromplate.rows/plate.columns, or whose recordedrowIndex/columnIndexdisagrees with that segment’s position; locationplate.wells[i].
- ngff_zarr.structural_validation.validate_well_acquisition( ) None¶
Validate that well images reference an acquisition when required.
When a plate declares more than one acquisition, every image in each of its wells must carry an
acquisitionreference so the field can be attributed to a specific acquisition. Plates with zero or one acquisition impose no such requirement, so this rule is a no-op for them. The first image missing its reference, scanned in order, is reported.Raises
ValidationError With :attr:
SpecRule.WELL_ACQUISITION_MISSINGfor the first :class:~ngff_zarr.v04.zarr_metadata.WellImagewhoseacquisitionisNonewhile the plate declares multiple acquisitions; locationwell.images[i].acquisition.
- ngff_zarr.structural_validation.validate_structural(
- metadata: ngff_zarr.v04.zarr_metadata.Metadata,
- options: ngff_zarr.structural_validation.ValidateOptions | None = None,
Run the structural image/multiscales rules in canonical spec order.
Orchestrates the per-rule
validate_*functions in this module. It is fail-fast: the rules run in canonical spec-MUST order and the first- Class:
ValidationErrorraised propagates to the caller – later rules do not run.
The rules run in this order:
- func:
validate_axis_count
- func:
validate_axis_type
- func:
validate_axis_order
- func:
validate_spatial_axis_order
- func:
validate_per_dataset_scale_count
- func:
validate_scale_length
- func:
validate_transform_order
- func:
validate_dataset_order
- func:
validate_omero_color_hex
- func:
validate_axis_orientation
Parameters
metadata: The parsed OME-Zarr v0.4 multiscales metadata to validate. options: Validation options. Defaults to :class:
ValidateOptions, i.e. :attr:ValidationLevel.STRICT. Under :attr:ValidationLevel.SCHEMA_ONLYthis function returns immediately without running any structural rule – shape/schema validation is the separate concern of :mod:ngff_zarr.validate, which checks the raw attribute dict.Raises
ValidationError For the first structural rule violated, carrying the offending :class:
SpecRuleandlocation. Never raised under :attr:ValidationLevel.SCHEMA_ONLY, which runs no structural rule.Notes
This orchestrator covers the image/multiscales rules, including the RFC 4 anatomical-orientation checks (:func:
validate_axis_orientation, a no-op when no axis declares orientation). The HCS plate/well structural rules operate on separate metadata objects and are dispatched by the companion- Func:
validate_plateand :func:validate_wellentry points.
- ngff_zarr.structural_validation.validate_plate(
- plate: ngff_zarr.v04.zarr_metadata.Plate,
- options: ngff_zarr.structural_validation.ValidateOptions | None = None,
Run the structural HCS plate rules in canonical spec order.
The plate-level counterpart to :func:
validate_structural: it orchestrates the structural rules that operate on a parsed- Class:
~ngff_zarr.v04.zarr_metadata.Plate. Like its image/multiscales sibling it is fail-fast – the first :class:ValidationErrorpropagates to the caller and later rules do not run.
The rules run in this order:
- func:
validate_plate_well_index_consistency
Per-well image rules (e.g. acquisition references) are the separate concern of :func:
validate_well, which is called where each well’s own metadata is loaded.Parameters
plate: The parsed OME-Zarr v0.4 plate metadata to validate. options: Validation options. Defaults to :class:
ValidateOptions, i.e. :attr:ValidationLevel.STRICT. Under :attr:ValidationLevel.SCHEMA_ONLYthis function returns immediately without running any structural rule – shape/schema validation is the separate concern of :mod:ngff_zarr.validate, which checks the raw attribute dict.Raises
ValidationError For the first structural plate rule violated, carrying the offending :class:
SpecRuleandlocation. Never raised under :attr:ValidationLevel.SCHEMA_ONLY, which runs no structural rule.
- ngff_zarr.structural_validation.validate_well(
- plate: ngff_zarr.v04.zarr_metadata.Plate,
- well: ngff_zarr.v04.zarr_metadata.Well,
- options: ngff_zarr.structural_validation.ValidateOptions | None = None,
Run the structural HCS well rules in canonical spec order.
Validates a single :class:
~ngff_zarr.v04.zarr_metadata.Wellin the context of its parent :class:~ngff_zarr.v04.zarr_metadata.Plate– the plate’s acquisition declarations govern whether each well image must reference an acquisition. Fail-fast, like :func:validate_structuraland- Func:
validate_plate.
The rules run in this order:
- func:
validate_well_acquisition
Parameters
plate: The parsed plate metadata that owns
well; supplies the acquisition context the well rules consult. well: The parsed well metadata to validate. options: Validation options. Defaults to :class:ValidateOptions, i.e. :attr:ValidationLevel.STRICT. Under :attr:ValidationLevel.SCHEMA_ONLYthis function returns immediately without running any structural rule – shape/schema validation is the separate concern of :mod:ngff_zarr.validate, which checks the raw attribute dict.Raises
ValidationError For the first structural well rule violated, carrying the offending :class:
SpecRuleandlocation. Never raised under :attr:ValidationLevel.SCHEMA_ONLY, which runs no structural rule.