From c6acf2de679684ceb2686f4bd8d5cd15bb8fdd09 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Tue, 4 Feb 2025 16:05:22 -0500 Subject: [PATCH] Improve how ometiff internal metadata is exposed --- CHANGELOG.md | 2 + .../large_image_source_ometiff/__init__.py | 43 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2181f042b..2fa2aad55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,13 @@ - Improve how we use vips to read lower tile levels ([#1794](../../pull/1794)) - Be more specific in casting when converting images via vips ([#1795](../../pull/1795)) +- Improve how ometiff internal metadata is exposed ([#1806](../../pull/1806)) ### Bug Fixes - Fix an issue with lazy tiles that have non power of two scaling ([#1797](../../pull/1797)) - Use zarr.empty not np.empty when creating large zarr sinks ([#1801](../../pull/1801)) +- Fix zarr sink addTile when no samples axis is specified ([#1805](../../pull/1805)) ## 1.31.0 diff --git a/sources/ometiff/large_image_source_ometiff/__init__.py b/sources/ometiff/large_image_source_ometiff/__init__.py index 33fbcd161..0abb914db 100644 --- a/sources/ometiff/large_image_source_ometiff/__init__.py +++ b/sources/ometiff/large_image_source_ometiff/__init__.py @@ -360,6 +360,41 @@ def getMetadata(self): self._addMetadataFrameInformation(result, channels) return result + def _reduceInternalMetadata(self, result, entry, prefix=''): # noqa + starts = ['StructuredAnnotations:OriginalMetadata:Series 0 ', + 'StructuredAnnotations:OriginalMetadata:'] + for start in starts: + if prefix.startswith(start): + prefix = prefix[len(start):] + if isinstance(entry, dict): + for key, val in entry.items(): + pkey = f'{prefix}:{key}'.strip(':') + if pkey in starts or (pkey + ':') in starts: + pkey = '' + if isinstance(val, dict): + if 'ID' in val and 'Value' in val: + self._reduceInternalMetadata(result, val['Value'], prefix) + elif 'Key' in val and 'Value' in val: + result[f'{pkey}:{val["Key"]}'.strip(':')] = val['Value'] + else: + self._reduceInternalMetadata(result, val, pkey) + elif isinstance(val, list): + for subidx, subval in enumerate(val): + if isinstance(subval, dict): + if 'ID' in subval and 'Value' in subval: + self._reduceInternalMetadata(result, subval['Value'], prefix) + elif 'Key' in subval and 'Value' in subval: + result[f'{pkey}:{subval["Key"]}'] = subval['Value'] + else: + self._reduceInternalMetadata( + result, subval, f'{pkey}:{subidx}'.strip(':')) + elif not isinstance(subval, list): + result[f'{pkey}:{subidx}'.strip(':')] = subval + elif key == 'ID' and str(val).split(':')[0] in prefix: + continue + elif val != '' and pkey: + result[pkey] = val + def getInternalMetadata(self, **kwargs): """ Return additional known metadata about the tile source. Data returned @@ -368,7 +403,13 @@ def getInternalMetadata(self, **kwargs): :returns: a dictionary of data or None. """ - return {'omeinfo': self._omeinfo} + result = {'omeinfo': self._omeinfo} + try: + result['omereduced'] = {} + self._reduceInternalMetadata(result['omereduced'], self._omeinfo) + except Exception: + pass + return result def getNativeMagnification(self): """