diff --git a/src/main/java/org/janelia/saalfeldlab/n5/ij/N5ScalePyramidExporter.java b/src/main/java/org/janelia/saalfeldlab/n5/ij/N5ScalePyramidExporter.java index f62380b2..a6243bed 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/ij/N5ScalePyramidExporter.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/ij/N5ScalePyramidExporter.java @@ -576,7 +576,7 @@ public & NativeType, M extends N5DatasetMetadata, N ex Arrays.fill(relativeFactors, 1); if (s > 0) { - relativeFactors = getRelativeDownsampleFactors(currentMetadata, currentChannelImg.numDimensions(), s, currentAbsoluteDownsampling); + relativeFactors = getRelativeDownsampleFactors(currentMetadata, currentChannelImg, s, currentAbsoluteDownsampling); // update absolute downsampling factors for (int i = 0; i < nd; i++) @@ -615,7 +615,7 @@ public & NativeType, M extends N5DatasetMetadata, N ex anyScalesWritten = true; // chunkSize variable is updated by the write method - if (lastScale(chunkSize, currentChannelImg)) + if (lastScale(chunkSize, currentChannelImg, currentMetadata)) break; } @@ -725,13 +725,15 @@ protected > N finalizeMultiscaleMetadata(final return multiscaleMetadata; } - protected boolean lastScale(final int[] chunkSize, final Interval imageDimensions) { + protected boolean lastScale(final int[] chunkSize, final Interval imageDimensions, final M metadata) { + + final Axis[] axes = getAxes(metadata, imageDimensions.numDimensions()); for (int i = 0; i < imageDimensions.numDimensions(); i++) { - if (imageDimensions.dimension(i) <= chunkSize[i]) - return true; + if (axes[i].getType().equals(Axis.SPACE) && imageDimensions.dimension(i) > chunkSize[i]) + return false; } - return false; + return true; } protected void fillResolution(final M baseMetadata, final double[] resolution) { @@ -866,9 +868,10 @@ protected long[] getDownsampleFactors(final M metadata, f return factors; } - protected long[] getRelativeDownsampleFactors(final M metadata, final int nd, final int scale, + protected long[] getRelativeDownsampleFactors(final M metadata, final Interval img, final int scale, final long[] downsampleFactors) { + int nd = img.numDimensions(); final Axis[] axes = getAxes(metadata, nd); // under what condisions is nd != axes.length @@ -876,7 +879,7 @@ protected long[] getRelativeDownsampleFactors(final M met for (int i = 0; i < nd; i++) { // only downsample spatial dimensions - if (axes[i].getType().equals(Axis.SPACE)) + if (axes[i].getType().equals(Axis.SPACE) && img.dimension(i) > 1) factors[i] = 2; else factors[i] = 1; diff --git a/src/test/java/org/janelia/saalfeldlab/n5/TestExportImports.java b/src/test/java/org/janelia/saalfeldlab/n5/TestExportImports.java index eab8d04d..5d3ea753 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/TestExportImports.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/TestExportImports.java @@ -659,6 +659,26 @@ public void testReadWriteParsePyramid() } } + @Test + public void testNumDownsamplingLevels() { + + final int bitDepth = 8; + final String dset = "scaleLevelsTest"; + + // the size of mitosis.tif sample image + final ImagePlus imp = NewImage.createImage("test", 171, 196, 2 * 5 * 51, bitDepth, NewImage.FILL_BLACK); + imp.setDimensions(2, 5, 51); + + final N5ScalePyramidExporter exp = new N5ScalePyramidExporter(); + exp.setOptions(imp, baseDir.getAbsolutePath(), dset, "16", true, N5ScalePyramidExporter.DOWN_AVERAGE, + N5Importer.MetadataOmeZarrKey, N5ScalePyramidExporter.RAW_COMPRESSION); + exp.run(); + + try (final N5Reader n5 = new N5FSReader(baseDir.getAbsolutePath())) { + assertEquals("5 scale levels", 5, n5.list(dset).length); + } + } + public void pyramidReadWriteParseTest( final ImagePlus imp, final String outputPath,