Skip to content

feat(lif): extract per-scene acquisition/instrument block (date, microscope, imaging_method) into audit + inspect #62

Description

@ferrinm

What to build

Parse per-scene acquisition + instrument metadata from LIF scene XML and surface it in per_scene[i].acquisition (or the block name locked in ADR-0007) in both the convert audit and inspect() output.

Fields to extract

Per scene, mapping to Aperture BigQuery columns:

  • acquisition_date — timestamp of scene acquisition. LIF stores this in Attachment[TimeStampList] / TimeStamp elements on the scene.
  • microscope_model — brand + model of the instrument, e.g. "Stellaris", "SP8". LIF HardwareSetting / ATLConfocalSettingDefinition attributes carry this.
  • microscope_serial — instrument serial number (Aperture will map serial → user-facing microscope_name like "Snouty" on their side). Serial lives in HardwareSetting metadata.
  • imaging_method — normalised imaging modality (confocal, widefield_fluorescence, spinning_disk_confocal, light_sheet). LIF is nearly always confocal (from ATLConfocalSettingDefinition) but derive it, don't hardcode. Use the OME-conventional token set.

Where the values land

Per ADR-0007, values live under per_scene[i].acquisition (or the block name the ADR chooses) in the convert audit AND in each scene entry of inspect().scenes[i]. Missing values → key omitted from the block (no dummy zeros / empty strings). Missing block entirely → key absent from the scene entry.

Implementation notes

  • Add extractors to src/zarrmony/metadata/ — new module acquisition.py or extension of lif_channels.py depending on module-size preference at the time.
  • Call site: the same _lif_scene_channels code path in api.py walks scene XML for channels — extract acquisition alongside so we only parse once. Thread the returned dict into the scene record.
  • Fail-safe like channel + objective extraction: any parse failure returns None and conversion continues without the block (never crash over metadata).
  • Bump AUDIT_SCHEMA_VERSION.

Acceptance criteria

  • per_scene[i].acquisition populated on a Stellaris LIF fixture with all four fields.
  • Same block visible in inspect().scenes[i].
  • Missing fields → key omitted; missing block entirely → key absent from scene entry.
  • AUDIT_SCHEMA_VERSION bumped; audit.py docstring updated.
  • Tests: LIF fixture with all fields, LIF fixture with partial acquisition metadata, LIF fixture with none.
  • Post-conversion OME-NGFF validation still passes.
  • CHANGELOG entry under a minor version bump.

Blocked by

Follow-up (linked separately)

CZI, ND2, and default (OME-TIFF etc.) reader paths get parallel acquisition + instrument extraction as their own issues, subsuming the earlier #54/#55/#56 objective-only slices.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentTriaged and ready for an agent to implement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions