diff --git a/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java b/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java index db8ec36c..ae0f4674 100644 --- a/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java +++ b/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java @@ -1472,9 +1472,10 @@ private void saveHCSMetadata(IMetadata meta) throws IOException { * @param resolutions Total number of resolutions from which * names will be generated. * @throws IOException + * @throws InterruptedException */ private void setSeriesLevelMetadata(int series, int resolutions) - throws IOException + throws IOException, InterruptedException { LOGGER.debug("setSeriesLevelMetadata({}, {})", series, resolutions); String resolutionString = String.format( @@ -1514,6 +1515,37 @@ private void setSeriesLevelMetadata(int series, int resolutions) datasets.add(Collections.singletonMap("path", lastPath)); } multiscale.put("datasets", datasets); + + String axisOrder = null; + if (dimensionOrder != null) { + axisOrder = dimensionOrder.toString(); + } + else { + IFormatReader reader = readers.take(); + try { + axisOrder = reader.getDimensionOrder(); + } + finally { + readers.put(reader); + } + } + List> axes = new ArrayList>(); + for (int i=axisOrder.length()-1; i>=0; i--) { + String axis = axisOrder.substring(i, i + 1).toLowerCase(); + String type = "space"; + if (axis.equals("t")) { + type = "time"; + } + else if (axis.equals("c")) { + type = "channel"; + } + Map thisAxis = new HashMap(); + thisAxis.put("name", axis); + thisAxis.put("type", type); + axes.add(thisAxis); + } + multiscale.put("axes", axes); + Path subGroupPath = getRootPath().resolve(seriesString); LOGGER.debug(" creating subgroup {}", subGroupPath); ZarrGroup subGroup = ZarrGroup.create(subGroupPath); diff --git a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java index 01a26090..1a166ef1 100644 --- a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java +++ b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java @@ -260,6 +260,10 @@ public void testMultiscalesMetadata() throws Exception { (List>) multiscale.get("datasets"); assertTrue(datasets.size() > 0); assertEquals("0", datasets.get(0).get("path")); + + List> axes = + (List>) multiscale.get("axes"); + checkAxes(axes, "TCZYX"); } /** @@ -284,6 +288,15 @@ public void testSetXYCZTDimensionOrder() throws Exception { ZarrGroup z = ZarrGroup.open(output.toString()); ZarrArray array = z.openArray("0/0"); assertArrayEquals(new int[] {1, 1, 2, 512, 512}, array.getShape()); + + z = ZarrGroup.open(output.resolve("0").toString()); + List> multiscales = (List>) + z.getAttributes().get("multiscales"); + assertEquals(1, multiscales.size()); + Map multiscale = multiscales.get(0); + List> axes = + (List>) multiscale.get("axes"); + checkAxes(axes, "TZCYX"); } /** @@ -296,6 +309,15 @@ public void testSetOriginalDimensionOrder() throws Exception { ZarrGroup z = ZarrGroup.open(output.toString()); ZarrArray array = z.openArray("0/0"); assertArrayEquals(new int[] {1, 1, 2, 512, 512}, array.getShape()); + + z = ZarrGroup.open(output.resolve("0").toString()); + List> multiscales = (List>) + z.getAttributes().get("multiscales"); + assertEquals(1, multiscales.size()); + Map multiscale = multiscales.get(0); + List> axes = + (List>) multiscale.get("axes"); + checkAxes(axes, "TZCYX"); } /** @@ -1413,6 +1435,15 @@ private void checkWell(ZarrGroup wellGroup, int fieldCount) } } + private void checkAxes(List> axes, String order) { + assertEquals(axes.size(), order.length()); + for (int i=0; i