-
Notifications
You must be signed in to change notification settings - Fork 54
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
Handling “acquisitions” in plate & well reading #225
Comments
Hi - when you say...
I tried to reproduce that with your data and There aren't any plans to change the acquisition handling in the NGFF spec, as far as I know. cc @chris-allan @melissalinkert. The change you referred to above was pre-v0.1 release and was removed before the v0.1 HCS spec. However, I'm not sure of the best way to handle acquisitions in napari. I don't think that loading them all as additional layers (as in your first screenshot) should be the default behaviour for a whole Plate in napari. Maybe a whole Well would be OK, but the amount of data you'd load for a Plate might be too much, since at least the lowest resolution tile for each acquisition of each Well would be loaded initially, even if you never wanted to look at the nth acquisition. Ideally I think you'd want some other UI widget in napari to move between acquisitions. I haven't looked at napari UI plugins recently, so I don't know if it's possible for a reader plugin to show UI widgets for a particular data format? cc @tlambert03 ? |
What I did is: For our usecases of multiplexing, this is actually the representation we'd want. Both acquisitions are of the same location, but we imaged different markers. Thus, it's important to be able to visualize them all together. At some level, what we have are "extra channels" that we want to see, but they are grouped into acquisitions. Thus, "stacking" acquisitions would be the "natural" thing I'd expect if the acquisitions are multiplexing data (or some other form of really imaging the same location different times). Stitching in x & y makes sense to me if we have multiple images in the same acquisition which are actually just different field of views of the microscope. We avoid doing this with ome/ngff#137 (=> all of our wells consist of a single, large image for each acquisition). Thus, my thinking would be that multiple images of the same acquisitions should get tiled, while multiple images of different acquisitions would get stacked. Are there other use-cases for acquisitions where we would expect a different behavior?
For us, the alternative we'd consider for multiplexing would just be actually making them separate channels in the same acquisition (=> not using acquisitions), because each channel in each acquisition is a separate channel the user may want to visualize. Regarding performance on a plate level, I think there are 2 points:
Certainly interesting for some use cases, could also be achieved if we could group layers, right? And for some applications, we want to see multiple acquisitions at once I think there is a place for a OME-Zarr reader plugin with widgets (I'm currently toying with a version that can load ROIs from AnnData tables), but it's also very powerful if the standard plugin can give access to the full image data. |
Another option is to use another non-Channel dimension to stack the acquisitions. But in your case, if seems that you really have multi-channel images where the channels just happen to be acquired at different rounds of imaging. It probably makes more sense to store these as extra channels. In this case then other tools (e.g. vizarr) would also display them as you'd want. |
Hmm, displaying them as many channels of the same acquisition certainly would be the fastest & easiest way to start displaying those channels in napari. But we will need to store metadata about the acquisition round for each channel and we will need the ability to process data per acquisition. I fear that if we go down the channel route, we're building a second, redundant way of storing "acquisition"/"cycle" metadata. And given that we're using this for an image processing platform we're building to encourage people to use OME-NGFFs, I'm quite hesitant to deviate from the spec if not fully necessary. If the acquisition part of the OME-NGFF really isn't meant for multiplexing data, then it makes sense to me that we'd invent something new. But my impression is that the acquisition structure in OME-NGFF actually fits the model for multiplexing data very well. Thus, it would be great if we can find a way to use that structure and find a way to also visualize it appropriately. Is there a place where there is an overview of the different use-cases for how to visualize acquisitions in napari? I don't fully understand all the different use-cases yet that would use the acquisition approach. If there are examples were my suggestion below would be bad, let me know! Use-cases I would be aware of for acquisitions in the HCS context:
Here is a suggestion of how the visualization could be handled and if that's something that's acceptable for ome-zarr-py / napari-ome-zarr, happy to start working on a PR to implement this:
@will-moore Do you foresee uses of the acquisitions spec where such an approach in ome-zarr-py would be detrimental? Comparing it to the idea of stacking acquisitions as another dimension: If we can get to layer groups in napari, it would be as easy to switch between acquisitions, without the assumption that the order of acquisition needs to contain specific meaning & with the ability to expose things like names for the acquisition & the channels. Stacking appears to me like an approach that handles a subset of the use-cases. But maybe I'm not aware of important uses-cases |
That actually sounds pretty good. I don't know of many acquisitions use-cases, but I think what you're suggesting makes sense. Just thinking about how to implement these proposed changes... For a However, probably a tougher question is what I imagine you could add another for-loop in ome-zarr-py/ome_zarr/reader.py Line 558 in 13165f4
tile_name for get_tile() could include the acquisition - NB: the comment """tile_name is 'level,z,c,t,row,col'""" is out-dated as it only row, col now.
Currently, it is assumed that the data loaded for each Well I hope I haven't missed any gotchas here... |
Thanks for starting the discussion. I think #225 (comment) does a good job of enumerating the main use cases. Adding a few other variants to the list:
Another example of this multi-modal use case would be bright-field/fluorescence.
In a similar vein, the other case I have seen is when multiple acquisitions effectively capture multiple fields of views for each well. The plates of Reading briefly through the proposal, I support the idea to update the reader to be able to access all acquisitions. Acquisitions is only metadata allowing to annotate images within a well and group them but there is no reason to exclude a subset of them. I also agree it is reasonable to assume different acquisitions within the same well should be represented in the same coordinate space. The biggest worry is to converge towards a single viewer implementation allowing to resolve all the scenarios described. Part of the discussion above around concatenating channels works nicely with the multiplexing use case but how would this work in the |
Thanks for the comments and additional usage example of acquisitions @sbesson !
I would argue that acquisition metadata should be used for images that can be placed in the same coordinate system. I would think the multi-modal case should work well with the proposed approach of loading everything into the same coordinate space. If the right transformations & scales are applied, then they should be overlayed correctly. If no metadata is defined, then there is obviously no way to display them correctly (unless the default overlay happens to be correct). The If the
To avoid misunderstandings, I would not be suggesting to combine channels here, but to display every acquisition as its own channel (fitting very well for multiplexing & multi-modality datasets, while being something that can display |
As it is defined in the current OME-NGFF specification,
The OME-NGFF mirrors this representation with a few modifications:
There is an element of confusion here because for historical reasons, the OMERO viewer splits each plate acquisition in a separate virtual containers. These can be seen and selected under the Plate container in the left-hand panel.For NGFF and napari, I do not think adhering to this constraint is a requirement (or even desirable)
In the case of
I think we are discussing is a different acquisition concept that is not defined in the current specification and thus I disagree with your first statement. But I strongly second your second statement about storing coordinate transformations when it relevant. Unfortunately in the case of
I wonder whether the terminology is a bit misleading here. Although Loading a well in napari displays 30 stitched images Definitely agree there is a known limitation as only a subset of multi-FOVs are being displayed. I am concerned that using separate layers is a scalable approach in scenarios like the above where you have 4 channels and 30 fields of views / well. |
Thanks a lot for this context & for taking the time @sbesson ! I do believe there are a few different questions here. I tried to summarize them here, as well as a summary of my response to them. Details below. 1) What are acquisitions and are they used consistently?Acquisition = run of the microscope. Mostly used correctly, but I believe 2) How do we load multi field-of-view / multi-FOV datasets on the plate level independent of the acquisition topic?Separate topic, see e.g. discussions in #200. I don't believe the multi-FOV use case scales for plate visualization. But using a single, fused FOV per well, we could scale the same size of a dataset and even load multiple acquisitions. 3) What should we now do we acquisitions and multi-FOV datasets?In my opinion, there's not much we can do for multi-FOV dataset full plate visualization that scales. Our solution is to use fused FOVs as a single image per well & channel. This scales. Details that lead me to that conclusion: Part 1)
So we could say that acquisition = run of the microscope, right? And I think the multiplexing use-case actually follows this definition very well: We acquire 1-n FOVs in a well once for the first round (=> acquisition 1), then we acquire them again for the second round with different markers (=> acquisition 2).
I don't know the actual acquisition settings on the microscope, but I highly doubt each field of view was acquired in a separate run by the microscope. That would be a terribly inefficient way to image a multi-well plate! My suspicion here would be that Part 2)
Yes, though I think that's a bit of a separate discussion. We originally thought that the best idea would be to store FOVs in that way and load all of the FOVs for a given well or for the full plate. On a well-level, that can still be loaded as you show above. But for a full plate like Thus, we came to the conclusion that the only scalable way to save wells with many FOVs was to combine the FOVs into a single array and save that as a single image for each channel. See PR to the spec for this here: ome/ngff#137 How we should handle multi-FOV plates in the same acquisition (like Part 3)Back to the discussion about acquisitions: I am not proposing that we use acquisitions as a way to load multi-FOV use-cases. If someone put acquisitions on top of there multi-FOV use case like in PS: I can't access |
At least, for
Looking at the structure of the raw data which can be downloaded via Aspera, for each plate, there are 6 measurement folders which are mapped into acquisition runs which image the same wells (A1 == 001001001) at different positions:
Without debating the efficiency of the approach, there are (public) examples of data generated using this modality. I believe the existence of such data is also why the OME concept of plate acquisition has been kept loosely defined as "a group of well samples".
You'll probably need to access sub-paths like https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0056B/7361.zarr/.zattrs. Alternatively, you can point |
🤯🤯🤯 Wow! I guess that should teach me about making any assumptions on the type of microscopy acquisitions people perform. Thanks for citing the actual details of this, would not have thought this possible if I didn't see it here! In that case, acquisition = run of the microscope is correct. But how people run their microscope can vary greatly...
I would assume this is by far the most common case, a single acquisition run to image a whole plate once. For me, the question then becomes what we want to do when loading acquisitions for viewing. After your example above, I'm not sure anymore whether there is a single framework for loading that will scale optimally for all ways of doing acquisitions. Currently, ome-zarr-py does not do anything with the acquisition metadata (and, due to performance concerns, only loads a single image/FOV per well). What I'm proposing would be a way to load acquisitions for multiple common ways of having acquisitions (multi-plexing, multi-modality). We could make this optional, e.g. have a flag that can be turned on or off for acquisition loading? |
Agreed and based upon OME's experience of dealing with formats and data, heterogeneity is simply part of the reality. As you said, different acquisition choices will have implications in terms of performance and/or visualization and it is also valuable to identify and discuss recommended layouts for different modalities.
From my side, an API allowing to control the layout used for loading plate data would be an interesting approach to support different scenarios. Another benefit of this idea would be its extensibility so that different consumers could specify the way data need to be loaded for their application. |
Thanks a lot for the discussion! In that case, I'll start looking into creating an implementation (draft) for how this scenario could be loaded best. Will keep these ideas about the heterogeneity & extensibility in mind :) |
This issue has been mentioned on Image.sc Forum. There might be relevant details there: https://forum.image.sc/t/best-approach-for-appending-to-ome-ngff-datasets/89070/2 |
We are looking to save multiplexing data (⇒ multiple cycles of acquisitions for the same plate) to HCS OME-Zarr files. Reading in the OME-NGFF spec, plates have the acquisitions key. This appears like a good way to save multiple acquisitions to the same plate.
I tested this with a small test dataset containing 2 acquisitions for a tiny plate (single well, single large image per well & acquisition): https://www.dropbox.com/s/tj8jj5iu5yxinz9/2_acquisitions.ome.zarr.zip?dl=0
This example has 2 images per well (/FOVs, see ome/ngff#137), 1 per acquisition (2 times the exact same images for both acquisitions for testing purposes). When loading the images individually into napari with the napari-ome-zarr plugin, I get the desired behavior of all 3 channels of both acquisitions being loaded ⇒ 6 channels & 2 label channels.
When loading the whole well or the plate, I get behaviors that don’t match this. Loading as a well, I get the two acquisitions as the same channel, just tiled next to each other (probably a limitation of our well loading PR that just tiles all the images and doesn’t check for acquisitions).
When I load the plate, I just get the first acquisition, the second acquisition is ignored.
Now my big question: Is the current spec version of having multiple acquisitions what should be implemented to the ome-zarr-py? Is loading multiple acquisition as in the first image a behavior that ome-zarr-py would want to support for wells & plates?
Or has the thinking changed in how to handle multiple acquisitions? I saw that there originally was acquisition loading support for plates, but it was removed in #111
@will-moore : Was this just for the original implementation of acquisitions (as an additional level), or also for the new spec?
If the current acquisition logic in the spec is what should be supported, we’d start using this for our multiplexing data and happy to have a go at trying to implement this for napari-ome-zarr plate & well reading. But if the thinking on this topic has changed, I’d be curious to join discussions on how to save multiple acquisitions to a Zarr file.
The text was updated successfully, but these errors were encountered: