napari-omero
napari-omero copied to clipboard
omero IDs in napari layer metadata
See https://github.com/tlambert03/napari-omero/pull/14#discussion_r446664444
When opening an Image from OMERO, it will be useful to store the ID of that Image in the layer metadata,
E.g. get_omero_metadata()
could include
'metadata': {'omero_id': f'Image:{image.id}',}
This can then be used by other code to e.g. load / save ROIs back to OMERO etc.
Since this becomes a potential API with other code, need to think about what we want to store (and not change it without warning / versioning etc).
Simplest example above. But, we might have opened a HCS Well (as we can do with e.g. iviewer) or have other OMERO IDs we wnat to store.
so maybe omero_id
is not a good key. Or even omero_object: Image:1
since there might be other objects?
Maybe omero_image:1
and omero_well:2
could work?
cc @joshmoore
Few initial thoughts:
-
f'{class}:{id}
is a good value since that's used elsewhere (likeomero obj ...
) - Would one ever need a list of values?
- Will there be other metadata we want to include? If so, perhaps it's:
{ 'metadata': {
'omero': {
'objects': ...,
'login': ...
which we might be able to unify with the Zarr metadata work.
I like f'{class}:{id}
too. since we can now directly pass that string to viewer.open()
to retrieve the image.
I guess we'd need a list of we ever allowed someone to load multiple Image IDs as a single layer? could that ever happen with pyramid or multichannel data? (but that might also imply that they're storing the data in a non-standard way on OMERO that we're not supporting).
I like the metadata dict
... but I'm agnostic as to whether the additional level of nesting (under an omero
key) is necessary.
Connection info (excluding the password of course) occurs to me as another entry.
Thinking over this again:
- Let's assume that a layer in napari is only going to come from 1 image in OMERO
- We may also want to store other image metadata, name etc.
- Might want to store channel index or ID (e.g. save rendering settings back to OMERO)
- Also may wish to store Dataset info, Well info etc.
- I'd prefer to be converting from ID to
f'Image:{id}'
when needed than to be getting the ID fromomero_id = "Image:1"
viaimg_id = int(omero_id.split(':')[1])
So maybe something like:
'metadata': {
'omero': {
'image': {
'id': 1,
'name': 'my_image'
},
'channel': {
'index': 0,
},
'well': {
'id': 2,
},
'session': {
'id': 'af31d8f6-abf4-460d-a8e5-95da3cf80eb3'
},
'experimenter': {
'id': 3,
}
}
}
I guess it might be possible that we need multiple objects for some of these, but I think that would be the exception and making all of them lists would be painful. Could always have a list of e.g. 'lookuptables':[]
or 'rois':[]
etc.
Let's assume that a layer in napari is only going to come from 1 image in OMERO
this seems safe. there might be a many-to-one relationship between napari layers and an OMERO image, but probably never a one-to-many, right?
I agree with all of your points and I think this would be a fine starting point. if we need to modify later, no problem
cf: https://gitHub.com/ome/omero-marshal
I realize it's a bit overkill at this point, but at least to have an example of where we might be going both with general OMERO metadata as well as specifically with Zarr metadata, I've added some json-ld below. It's partially cleaned, but there's obviously still more that could be stripped for napari. Salient points are likely the use of @type
and @id
identifiers.
My overall hope would be to not build yet-another-parsing library for metadata.
The flip-side, that I/we recognize, is that the format itself is going to need to get more usable. That's possible with json-ld, but so far there just hasn't been a driver. E.g. it's possible to inline values like 'monochrome' so that using the json becomes much more natural.
json-ld output from /api/v0/m
$ curl http://idr.openmicroscopy.org/api/v0/m/images/9837306/ | jq > /tmp/omero-marshal.json
... some editing to strip omero:details (i.e. owner/group/permissions) as well as shortening
shortened @type strings. ...
{
"@type": "Image",
"@id": 9837306,
"Name": "3CBF362B2A",
"omero:series": 0,
"Pixels": {
"@type": "Pixels",
"@id": 9837306,
"omero:sha1": "Pending...",
"SignificantBits": 8,
"SizeX": 1572,
"SizeY": 780,
"SizeZ": 113,
"SizeC": 2,
"SizeT": 1,
"Type": {
"@type": "TBD#PixelsType",
"@id": 5,
"value": "uint8"
},
"Channels": [
{
"@type": "Channel",
"@id": 26294535,
"Color": -16776961,
"omero:LogicalChannelId": 10604485,
"SamplesPerPixel": 1,
"omero:photometricInterpretation": {
"@type": "TBD#PhotometricInterpretation",
"@id": 5,
"value": "Monochrome"
}
},
{
"@type": "Channel",
"@id": 26294536,
"Color": 16711935,
"omero:LogicalChannelId": 10604486,
"SamplesPerPixel": 1,
"omero:photometricInterpretation": {
"@type": "TBD#PhotometricInterpretation",
"@id": 5,
"value": "Monochrome"
}
}
]
},
"url:datasets": "https://idr.openmicroscopy.org/api/v0/m/images/9837306/datasets/",
"url:rois": "https://idr.openmicroscopy.org/api/v0/m/images/9837306/rois/"
}