ome / ngff

Next-generation file format (NGFF) specifications for storing bioimaging data in the cloud.
https://ngff.openmicroscopy.org
Other
117 stars 38 forks source link

Optional sub-group(s) in multiscale image #187

Open tibuch opened 1 year ago

tibuch commented 1 year ago

This issue started as a discussion on image.sc.

TL;DR; It would be nice to save processed versions, e.g. projections of 3D volumes, in the same zarr structure as the acquired raw data.

The forum thread discusses this in the context of HCS plates and out of three options the following option, suggested by @imagejan, seems to be the most favored one:

plate.zarr               
    ├── A                        # row
    │   ├── 1                    # column
    │   │   ├── 0                # zeroth field: 4D CZYX
    │   │   │   ├── 0            # zeroth resolution level
    │   │   │   ├── labels   
    │   │   │   │   └── 0        # labels corresponding to A/1/0/0
    │   │   │   ├── projections  # <--- New sub-group: 3D CYX
    │   │   │   │   ├── 0        # zeroth resolution level projection
    │   │   │   │   └── labels
    │   │   │   │       └── 0    # labels corresponding to A/1/0/projections/0

The new sub-group is another multi-scale image. In the case of projections it would have one dimension less than the original raw data.

The content and name of the sub-group should not be fixed. The spec should be general enough such that we could store any kind of processed data. It would be nice to cover the following use-case as well:

plate.zarr               
    ├── A                        # row
    │   ├── 1                    # column
    │   │   ├── 0                # zeroth field: 4D CZYX
    │   │   │   ├── 0            # zeroth resolution level
    │   │   │   ├── labels   
    │   │   │   │   └── 0        # labels corresponding to A/1/0/0
    │   │   │   ├── projections  # <--- New sub-group: 3D CYX
    │   │   │   │   ├── 0        # zeroth resolution level projection
    │   │   │   │   └── labels
    │   │   │   │       └── 0    # labels corresponding to A/1/0/projections/0
    │   │   │   ├── deconvolved  # <--- New sub-group: 4D CZYX (channels which are not deconvolved are zeros)
    │   │   │   │   ├── 0        # zeroth resolution level deconvolution
    │   │   │   │   └── labels
    │   │   │   │       └── 0    # labels corresponding to A/1/0/deconvolved/0
    │   │   │   ├── histograms  # <--- New sub-group: 1D C 
    │   │   │   │   └── 0        # zeroth resolution level histogram

@jluethi suggested to add the information of these sub-groups to the multiscales list in .zattrs. This would allow consumers to know about the different sub-groups by only parsing .zattrs.

The plate.zarr/A/1/0/.zattrs for the second example would then look like this:

{
    "multiscales": [
        {
            "axes": [
                {
                    "name": "c",
                    "type": "channel"
                },
                {
                    "name": "z",
                    "type": "space",
                    "unit": "micrometer"
                },
                {
                    "name": "y",
                    "type": "space",
                    "unit": "micrometer"
                },
                {
                    "name": "x",
                    "type": "space",
                    "unit": "micrometer"
                }
            ],
            "datasets": [
                {
                    "coordinateTransformations": [
                        {
                            "scale": [
                                1.0,
                                5.02,
                                1.3668,
                                1.3668
                            ],
                            "type": "scale"
                        }
                    ],
                    "path": "0"
                }
            ],
            "name": "raw",
            "version": "0.4"
        },
       {
            "axes": [
                {
                    "name": "c",
                    "type": "channel"
                },
                {
                    "name": "y",
                    "type": "space",
                    "unit": "micrometer"
                },
                {
                    "name": "x",
                    "type": "space",
                    "unit": "micrometer"
                }
            ],
            "datasets": [
                {
                    "coordinateTransformations": [
                        {
                            "scale": [
                                1.0,
                                1.3668,
                                1.3668
                            ],
                            "type": "scale"
                        }
                    ],
                    "path": "projections"
                }
            ],
            "name": "projections",
            "version": "0.4"
        },
        {
            "axes": [
                {
                    "name": "c",
                    "type": "channel"
                },
                {
                    "name": "z",
                    "type": "space",
                    "unit": "micrometer"
                },
                {
                    "name": "y",
                    "type": "space",
                    "unit": "micrometer"
                },
                {
                    "name": "x",
                    "type": "space",
                    "unit": "micrometer"
                }
            ],
            "datasets": [
                {
                    "coordinateTransformations": [
                        {
                            "scale": [
                                1.0,
                                5.02,
                                1.3668,
                                1.3668
                            ],
                            "type": "scale"
                        }
                    ],
                    "path": "deconvolved"
                }
            ],
            "name": "deconvolved",
            "version": "0.4"
        },
        {
            "axes": [
                {
                    "name": "c",
                    "type": "channel"
                }
            ],
            "datasets": [
                {
                    "coordinateTransformations": [
                        {
                            "scale": [
                                1.0
                            ],
                            "type": "scale"
                        }
                    ],
                    "path": "histograms"
                }
            ],
            "name": "histograms",
            "version": "0.4"
        }
    ]
}

Looking forward to develop this further and extending the ome-zarr spec :balloon:

imagesc-bot commented 1 year ago

This issue has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/faim-hcs-functions-to-work-with-hcs-data/78868/18