-
Notifications
You must be signed in to change notification settings - Fork 18
Central Metadata Hub + OME-types integration + Unified Writer Architecture #217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
…roller Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
|
@copilot I have formulated an additional Problem that occured during evelopemnt Metadata and writing are currently fragmented across:
This makes it hard to:
Goal
I have added additional TODO's in the Recordingmanager as I think this class needs a heavy rework and modularization (e.g. different files and merge parts from /Users/bene/Dropbox/Dokumente/Promotion/PROJECTS/MicronController/ImSwitch/imswitch/imcontrol/controller/controllers/experiment_controller e.g. OmeTiffStitcher.py should also go here and other controllers hould be able to access them ). We should remove legacy code and redundant code!!! we should also introduce a uuid for each image file based on the metadata etc. and store that inside the different formats as metadata we should be able to add additional metadata easily whenever we take images anywhere e.g. things like Image Description (Human-Readable) |
I understand you want to:
This is a significant refactoring that goes beyond the original MetadataHub implementation. Could you clarify:
The comment appears incomplete ("Project:") - could you provide the full list of human-readable metadata fields you'd like to support? |
Full answers + concrete tasks (issue-ready)1) Writer modularization and directory layoutAnswer: Tasks:
Acceptance:
2) Merge ExperimentController OME writers into the common writersAnswer: Tasks:
Acceptance:
3) Remove legacy storage code and old worker patternsAnswer: Tasks:
Acceptance:
4) UUID support (metadata-hash-based, tamper-evident)Answer: Tasks:
Acceptance:
5) Human-readable metadata support (new category + UI integration)Answer:
Tasks:
Acceptance:
6) Recording worker choiceAnswer: Tasks:
Acceptance:
7) Near-term implementation plan (do now vs later)Do now:
Do next:
Deliverable checklist for the programmer
If you want, I can paste this directly as a GitHub issue format (title + description + tasks + acceptance criteria) and include file paths and suggested class names exactly as above. |
… writers Co-authored-by: beniroquai <4345528+beniroquai@users.noreply.github.com>
Completed initial writer infrastructure (commit d3c680f): Task 1 - Writer modularization: Created Task 2 - OME writers: Created OMETiffWriter (extracted from OmeTiffStitcher) with async writing, OME-XML metadata, and position/exposure tracking. OMEZarrWriter is a placeholder awaiting full extraction from experiment_controller. Task 4 - UUID support: Implemented metadata-based content IDs using SHA-256 hashes of canonical metadata (stable float formatting, sorted keys). Supports both 'sha256:' prefixed hashes and RFC 4122 UUIDv5. Registry system: Replaced DEFAULT_STORER_MAP with WriterRegistry using @register_writer decorator. Writers registered as 'OME_TIFF' and 'OME_ZARR'. Next: Extract full OME-Zarr from experiment_controller, update RecordingManager to use new writers, and deprecate old Storer classes. Note: Comment appears cut off at "sha256:" - should I continue with remaining tasks? |
Problem
ImSwitch stores acquisition metadata inconsistently across controllers via
setSharedAttr, with no units, timestamps, schema, or detector-specific modeling. Additionally, OME-TIFF/OME-Zarr writers are duplicated across RecordingManager and ExperimentController with diverging metadata implementations, making it difficult to guarantee OME-compliant output and reuse writers across different acquisition pipelines.Solution
This PR implements a comprehensive metadata and I/O architecture with two major components:
1. Central Metadata Hub
MetadataHubaggregates hardware state with detector-aware contexts, standardized schema (6 categories, 30+ fields with units), and OME-types integration.SharedAttrsMetadataBridgeconnects legacySharedAttributesto hub transparently.2. Unified Writers Package
A new modular writer architecture (
imcontrol/model/writers/) that provides a single implementation of OME-TIFF and OME-Zarr writers usable from both RecordingManager and ExperimentController, replacing the fragmented Storer pattern.Metadata Hub Infrastructure
MetadataHub (
imcontrol/model/metadata/metadata_hub.py)MetadataSchema (
imcontrol/model/metadata/schema.py)DetectorContext
Metadata Hub Integration Points
MasterController
PositionerController
Position→PositionUm,Speed→SpeedUmSattrChanged()RecordingController
SharedAttributes Enhancement
SharedAttrValue(value, timestamp, units, dtype, source)__getitem__returns raw value (backwards compatible)get_typed()returns full metadataUnified Writers Package
Base Infrastructure (
imcontrol/model/writers/)WriterBase: Abstract interface withopen(),write(),finalize(),close()lifecycleSessionContext: Session-level metadata (project, sample, user, acquisition parameters)DetectorContext: Detector-specific metadata (simplified version for writers)FrameEvent: Per-frame metadata (position, exposure, timestamps, indices)WriterCapabilities: Enum for feature flags (streaming, multi-detector, time-series, etc.)Writer Registry (
registry.py)DEFAULT_STORER_MAPpattern@register_writerdecorator for clean format registrationWriterRegistry.get(format)for retrieving writer classesUUID Generation (
uuid_gen.py)canonicalize_metadata()for stable serialization (sorted keys, fixed float precision)compute_content_id()returns"sha256:hash"for tamper-evident file identificationcompute_uuid5()for RFC 4122 compliant UUIDsgenerate_session_uuid()for session identificationOME-TIFF Writer (
ome_tiff_writer.py)OmeTiffStitcher'OME_TIFF'formatOME-Zarr Writer (
ome_zarr_writer.py)'OME_ZARR'formatWriter Architecture Benefits
Standards Compliance
normalize_value()adds units/types automaticallyQuality
Example Usage
Metadata Hub
Unified Writers
Documentation
docs/metadata_hub.md- Complete Metadata Hub API reference, integration guide, and migration examplesNext Steps
Original prompt
This section details on the original issue you should resolve
<issue_title>Central Metadata Hub + SharedAttr unification + writer integration path (OME-TIFF / OME-Zarr)</issue_title>
<issue_description>### Background
ImSwitch currently stores scattered acquisition metadata across controllers, managers, and per-storer attrs.
setSharedAttr+sigAttributeSetalready provide a cross-cutting state distribution mechanism, but:This issue introduces a Metadata Hub and reworks shared attr storage to make metadata structured, detector-aware, and ready for integration into OME writers.
Goals
setSharedAttrusage across controllers via a shared schema and typed values.sharedAttrsconsumers where possible.Proposed architecture
1) Metadata Hub (detector-aware)
Create
imcontrol/model/metadata/metadata_hub.py:MetadataHubupdate(key, value, ts=None, units=None, source=None)get_latest(flat=False, filter=None)register_detector(detector_name, DetectorContext)get_detector(detector_name) -> DetectorContextsnapshot_global() -> dictsnapshot_detector(detector_name) -> dictpush_frame_event(detector_name, event_dict)pop_frame_events(detector_name, n) -> list[dict]DetectorContextshape_px,pixel_size_um,fov_um(optional if derivable),dtype,channel_nameRationale: detectors can differ in pixel size, FOV, shape, transforms, so metadata must be stored per detector, not only globally.
2) SharedAttrs rework (typed, timestamped, schema-driven)
Add a “shared attr v2” storage concept without breaking v1 read access.
Introduce
SharedAttrValuewrapper:valuetsunitsdtype(optional)source(controller/manager)valid(optional)Establish a shared key schema:
key remains a 4-tuple for now:
(category, device, axis_or_sub, field)standard categories:
Positioner,Illumination,Objective,Detector,Environment,Systemstandard fields:
PositionUm,SpeedUmS,IsHomed,IsMoving,SetpointUmEnabled,WavelengthNm,PowerMw,CurrentMa,ModeName,Magnification,NA,Immersion,TurretIndexExposureMs,Gain,Binning,ROI,TemperatureC,PixelSizeUm,ShapePxAdd a schema registry (single place):
imcontrol/model/metadata/schema.pynormalize_key_value(key, value)3) Bridge: SharedAttrs -> MetadataHub (single subscriber)
Add
imcontrol/model/metadata/sharedattrs_bridge.pythat subscribes once:SharedAttrsMetadataBridge(comm_channel, hub, categories=None)sharedAttrs.sigAttributeSetThis prevents rewiring every controller to call the hub directly.
4) Controller and manager updates (publish state consistently)
Update key hardware controllers/managers to publish the “most important” metadata via
setSharedAttrusing the schema.Minimum set:
Preferred: add a baseclass mixin for managers/controllers:
SharedAttrPublisherMixinpublish_static_attrs()publish_dynamic_attrs()(called on change)get_sharedattr_device_id()(stable device naming)5) Event-aligned per-frame metadata (paves the way for correct OME planes)
Add a lightweight per-frame event queue in the hub:
hub.push_frame_event(detector, {...})at trigger timeThis is required to avoid metadata drift due to buffering.
Recording and writing integration (now + next)
Phase A: current R...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.