Multichannel OME-TIFF import order (XYZCT vs. XYCZT)

I am trying to analyze immunofluorescence images from a 96-well plate using Qupath. I started with a czi file with multiple tile regions and used ZEN to export each tile region to an individual single-plane, 3-channel OME-TIFF.

When I open these files in ImageJ using the Bio-Formats importer with the Hyperstack setting (which defaults to XYCZT stack order), the image opens as expected, with three channels registered. However, when I try to import into Qupath using either the default or Bio-Formats image provider, the images are imported as a 3-slice z-stack with one channel (the little slider shows up in the upper-left corner). I assume this is because Qupath has used an XYZCT order.

Is there any way to either specify the proper order at the time of import in Qupath or to change the channel vs. slice structure of an image after it has been imported?

Hi @Boothman, can you share any example images? There’s no built-in way to change the interpretation in QuPath, you’d have to convert the images in Fiji – but I’m curious as to why it is getting it wrong in the first place.

Note under the ‘Image’ tab in QuPath you should see a ‘Dimensions (CZT)’ option as QuPath has interpreted them.

You can also use the following script to visualize the XML read by Bio-Formats (assuming Bio-Formats was the reader QuPath selected):

server = getCurrentServer()
xml = server.dumpMetadata()
print groovy.xml.XmlUtil.serialize(xml)

In general, the Zen export to tiff has stripped the metadata, so the stacks/channels are read however they are read. It also normally missed all of the channel information and pixel size metadata.

Maybe that has changed in 3.0+? Not sure, but I would usually avoid exporting and just use the CZI files for each individual region. QuPath and BioFormats should read those correctly. Is there some reason you need to use OME.TIFF in this situation (not that the problem is with ome, just with the Zen export).

1 Like

Thanks guys, and sorry for the belated reply! I’ve attached a sample image. The image is imported with the CZT dimensions 1 x 1 x 3 using Qupath 0.2.3 with the Bio-Formats builder. XML dump reads as follows:

INFO: <?xml version="1.0" encoding="UTF-8"?><OME xmlns:xsi="" xmlns="" xsi:schemaLocation="">
  <Image ID="Image:0" Name="MFB005_s30.ome.tiff">
    <Description>&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;OME xsi:schemaLocation="" xmlns:xsd="" xmlns:xsi="" xmlns=""&gt;&lt;Instrument ID="Instrument:1"&gt;&lt;Microscope Model="Axio Observer.Z1" Type="Inverted" /&gt;&lt;LightSource ID="LightSource:1"&gt;&lt;Filament Type="Halogen" /&gt;&lt;/LightSource&gt;&lt;Detector Model="Axiocam506m" ID="Detector:1" /&gt;&lt;Objective Model="EC Plan-Neofluar 5x/0.16 M27" ID="Objective:1" Immersion="Air" LensNA="0.16" NominalMagnification="5" WorkingDistance="13600" /&gt;&lt;FilterSet ID="FilterSet:1"&gt;&lt;ExcitationFilterRef ID="Filter:1" /&gt;&lt;DichroicRef ID="Dichroic:1" /&gt;&lt;EmissionFilterRef ID="Filter:2" /&gt;&lt;/FilterSet&gt;&lt;FilterSet ID="FilterSet:2"&gt;&lt;ExcitationFilterRef ID="Filter:3" /&gt;&lt;DichroicRef ID="Dichroic:2" /&gt;&lt;EmissionFilterRef ID="Filter:4" /&gt;&lt;/FilterSet&gt;&lt;Filter ID="Filter:1"&gt;&lt;TransmittanceRange CutIn="450" CutOut="490" /&gt;&lt;/Filter&gt;&lt;Filter ID="Filter:2"&gt;&lt;TransmittanceRange CutIn="500" CutOut="550" /&gt;&lt;/Filter&gt;&lt;Filter ID="Filter:3"&gt;&lt;TransmittanceRange CutIn="335" CutOut="383" /&gt;&lt;/Filter&gt;&lt;Filter ID="Filter:4"&gt;&lt;TransmittanceRange CutIn="420" CutOut="470" /&gt;&lt;/Filter&gt;&lt;Dichroic ID="Dichroic:1" /&gt;&lt;Dichroic ID="Dichroic:2" /&gt;&lt;/Instrument&gt;&lt;Image ID="Image:1" Name=""&gt;&lt;AcquiredDate&gt;2020-11-10T23:54:37.5971311Z&lt;/AcquiredDate&gt;&lt;Description /&gt;&lt;InstrumentRef ID="Instrument:1" /&gt;&lt;ObjectiveSettings ID="Objective:1" /&gt;&lt;Pixels ID="Pixels:1" DimensionOrder="XYZTC" Type="uint16" SizeX="5233" SizeY="4200" SizeZ="1" SizeC="3" SizeT="1" PhysicalSizeX="0.908" PhysicalSizeY="0.908"&gt;&lt;Channel ID="Channel:1:0" Name="Alexa Fluor 488" SamplesPerPixel="1" IlluminationType="Epifluorescence" AcquisitionMode="WideField" ContrastMethod="Fluorescence" ExcitationWavelength="493" EmissionWavelength="517" Fluor="Alexa Fluor 488" Color="65331"&gt;&lt;DetectorSettings ID="Detector:1" Binning="1x1" /&gt;&lt;FilterSetRef ID="FilterSet:1" /&gt;&lt;/Channel&gt;&lt;Channel ID="Channel:1:1" Name="DAPI" SamplesPerPixel="1" IlluminationType="Epifluorescence" AcquisitionMode="WideField" ContrastMethod="Fluorescence" ExcitationWavelength="353" EmissionWavelength="465" Fluor="DAPI" Color="255"&gt;&lt;DetectorSettings ID="Detector:1" Binning="1x1" /&gt;&lt;FilterSetRef ID="FilterSet:2" /&gt;&lt;/Channel&gt;&lt;Channel ID="Channel:1:2" Name="TL Brightfield" SamplesPerPixel="1" IlluminationType="Transmitted" AcquisitionMode="WideField" ContrastMethod="Brightfield" Fluor="TL Brightfield" Color="16777215"&gt;&lt;LightSourceSettings ID="LightSource:1" /&gt;&lt;DetectorSettings ID="Detector:1" Binning="1x1" /&gt;&lt;/Channel&gt;&lt;TiffData /&gt;&lt;/Pixels&gt;&lt;/Image&gt;&lt;/OME&gt;</Description>
    <Pixels BigEndian="false" DimensionOrder="XYCZT" ID="Pixels:0" Interleaved="false" SignificantBits="16" SizeC="1" SizeT="3" SizeX="5233" SizeY="4200" SizeZ="1" Type="uint16">
      <Channel ID="Channel:0:0" SamplesPerPixel="1">

For comparison I’ve also attached the full OME metadata and Bio-Formats metadata that are displayed when importing the image with Fiji. The metadata specifies XYCZT and it seems like Fiji’s Bio-Formats plugin is able to interpret this correctly (ImageJ-2.1.0/1.53c and Bio-Formats-6.5.1).

Fiji_BioFormats_OME_metadata.xml (2.9 KB) Fiji_BioFormats_original_metadata.csv (261 Bytes)

Sample image:

Thanks @Boothman, using your image I find that if I run the following script in both Fiji and QuPath I get different results:

import loci.formats.*

def id = "/path/to/MFB005_s30.ome.tiff"

meta = MetadataTools.createOMEXMLMetadata()
reader = new ImageReader()

println "c=${reader.getSizeC()}"
println "z=${reader.getSizeZ()}"
println "t=${reader.getSizeT()}"

In QuPath, I get

WARN: Could not transform version 2010-06 OME-XML.
INFO: c=1
INFO: z=1
INFO: t=3

Whereas in Fiji, I get


Since the Bio-Formats versions are the same, and that code contains nothing QuPath/Fiji-specific, I was stumped until seeing Curtis’ post here:

I was able to get it working in QuPath on my Mac by downloading bioformats_package.jar from and dragging it onto QuPath to install it as an extension.

I’m not sure how reliable this is as a solution: tbh I was surprised it worked, since I imagine both versions of Bio-Formats installed in QuPath would be jostling for attention on the classpath and I expected the winner to be the one that’s built-in. If this approach proves to be problematic/unpredictable, you could try deleting some of the Bio-Formats-related .jar files from your QuPath installation (e.g. formats-gpl.jar) so that only the newly-installed bioformats_package.jar works.


Thanks for the investigation @petebankhead,

I think you found the source of the issue: the sample file is a valid OME-TIFF using the 2010-06 version of the schema. Internally, the OME-TIFF reader first tries to transform the XML to the latest version (2016-06). However, the transforms is failing for similar reasons to the one discussed by Curtis in the issue you linked above and the image is detected as a simple multi-page TIFF.

Looking very quickly at the QuPath codebase , I suspect the issue comes from the manual exclusion of the serializer/xalan dependency as these are the ones handling the transformations from one schema to another -
That would also explain with bioformats_package.jar works as this uber-JAR bundles all the dependencies of Bio-Formats.


Thanks a lot for looking into this Pete! Makes sense. It’s not a big deal, as it’s fairly easy to convert the OME-TIFF in Fiji and then re-import into Qupath (or import native czi files as @MicroscopyRA suggests–although this unfortunately doesn’t work in some complex multi-region tiled experiments due to the somewhat limited export options in ZEN). But if I need to scale up and file conversion becomes rate limiting, then this is a good option.


Hi @Boothman,

What do you mean with limited export functionality in ZEN?
What are you missing or what does not work? Just curious…

On the version of ZEN available to our lab, an entire experiment can be saved as a czi file but cannot be broken into multiple smaller czi files. For my experiment, I needed each well of a 96-well plate (consisting of four tiles) to be exported as an individual file with appropriate metadata. It would have been ideal to export to 96 czi files in ZEN, but unfortunately I could not find any option to do this and had to export to OME-TIFFs instead–perhaps they have added more options in later versions, but we can’t afford to upgrade.

Split scenes (write files) should be available in the free versions of Zen (Lite), as far back as at least 2.3. And newer versions of Zen(free) definitely have it. There should also be an option during acquiring the images (in the Autosave box) to save each region or time point as an independent file, which could save you a step.
Looks like I was remembering Zen Black. Zen Blue has an automated export with similar features, but the only options seem to be TIFF and JPEG, which gets back to the same problem. So Split Scenes (write files) might be your best bet unless that has been improved in newer versions of Zen Blue.

Awesome, thanks for the heads up! I will give this a try.

1 Like

Hi @Boothman,

So I was not fast enough to answer… :grin:

Spot Scenes (write files) should do the job. It includes positions ans well names into the filename.
And there is the OME-TIFF export which also works in batch and can be scripted.

Let me know if help is needed.

There are
Quite some examples on the Zeiss GitHub page.