diff --git a/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java b/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java index 0e967992..db8ec36c 100644 --- a/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java +++ b/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java @@ -561,7 +561,7 @@ public void convert() ((OMEXMLMetadata) meta).resolveReferences(); if (!noHCS) { - noHCS = meta.getPlateCount() == 0; + noHCS = !hasValidPlate(meta); } else { ((OMEXMLMetadata) meta).resolveReferences(); @@ -1761,6 +1761,31 @@ private Class<?> getBaseReaderClass() throws FormatException, IOException { } } + /** + * Check if the given metadata object contains at least one plate + * with at least one well that links to an image. + * + * @param meta metadata object + * @return true if a valid plate exists, false otherwise + */ + private boolean hasValidPlate(IMetadata meta) { + List<String> images = new ArrayList<String>(); + for (int i=0; i<meta.getImageCount(); i++) { + images.add(meta.getImageID(i)); + } + for (int p=0; p<meta.getPlateCount(); p++) { + for (int w=0; w<meta.getWellCount(p); w++) { + for (int ws=0; ws<meta.getWellSampleCount(p, w); ws++) { + if (images.contains(meta.getWellSampleImageRef(p, w, ws))) { + return true; + } + } + } + LOGGER.warn("Encountered invalid plate #{}", p); + } + return false; + } + private int calculateResolutions(int width, int height) { int resolutions = 1; while (width > minSize || height > minSize) { diff --git a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java index a68efbb2..01a26090 100644 --- a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java +++ b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java @@ -879,6 +879,27 @@ public void testHCSMetadata() throws Exception { assertEquals(1, ome.sizeOfPlateList()); } + /** + * Plate defined with no linked images. + */ + @Test + public void testEmptyPlate() throws Exception { + input = getTestFile("empty-plate.ome.xml"); + assertTool(); + + ZarrGroup z = ZarrGroup.open(output); + + // Check dimensions and block size for consistency + // with non-HCS layout + ZarrArray series0 = z.openArray("0/0"); + assertArrayEquals(new int[] {1, 1, 1, 4, 6}, series0.getShape()); + assertArrayEquals(new int[] {1, 1, 1, 4, 6}, series0.getChunks()); + + // Check OME metadata to make sure the empty plate was preserved + OME ome = getOMEMetadata(); + assertEquals(1, ome.sizeOfPlateList()); + } + /** * 96 well plate with only well E6. */ diff --git a/src/test/resources/com/glencoesoftware/bioformats2raw/test/empty-plate.ome.xml b/src/test/resources/com/glencoesoftware/bioformats2raw/test/empty-plate.ome.xml new file mode 100755 index 00000000..dd62ba82 --- /dev/null +++ b/src/test/resources/com/glencoesoftware/bioformats2raw/test/empty-plate.ome.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<OME xmlns="http://www.openmicroscopy.org/Schemas/OME/2016-06" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.openmicroscopy.org/Schemas/OME/2016-06 + http://www.openmicroscopy.org/Schemas/OME/2016-06/ome.xsd"> + <Plate + ID="Plate:1" + Name="Control Platedasd" + ColumnNamingConvention="letter" + RowNamingConvention="number" + Columns="12" + Rows="8" + > + </Plate> + + <Image ID="Image:0" Name="6x6x1x8-swatch.tif"> + <AcquisitionDate>2010-02-23T12:51:30</AcquisitionDate> + <Pixels DimensionOrder="XYCZT" ID="Pixels:0:0" PhysicalSizeX="10000.0" + PhysicalSizeY="10000.0" Type="uint8" SizeC="1" SizeT="1" SizeX="6" SizeY="4" SizeZ="1"> + <Channel Color="-2147483648" ID="Channel:0"/> + <BinData BigEndian="false" Length="32" + >/wCrzur//wB5oMPi/wBIbJO3AP8ePGCF</BinData> + </Pixels> + </Image> + +</OME> \ No newline at end of file