diff --git a/src/main/java/net/preibisch/mvrecon/process/n5api/N5ApiTools.java b/src/main/java/net/preibisch/mvrecon/process/n5api/N5ApiTools.java index 9924d0d5..c3180bc0 100644 --- a/src/main/java/net/preibisch/mvrecon/process/n5api/N5ApiTools.java +++ b/src/main/java/net/preibisch/mvrecon/process/n5api/N5ApiTools.java @@ -25,11 +25,16 @@ import mpicbg.spim.data.sequence.ViewDescription; import mpicbg.spim.data.sequence.ViewId; import mpicbg.spim.data.sequence.ViewSetup; -import net.imglib2.FinalInterval; +import mpicbg.spim.data.sequence.VoxelDimensions; +import net.imglib2.Dimensions; import net.imglib2.RandomAccessibleInterval; +import net.imglib2.algorithm.blocks.BlockAlgoUtils; +import net.imglib2.algorithm.blocks.BlockSupplier; +import net.imglib2.algorithm.blocks.downsample.Downsample; import net.imglib2.img.Img; import net.imglib2.img.array.ArrayImgs; import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; import net.imglib2.type.numeric.integer.IntType; import net.imglib2.type.numeric.integer.UnsignedByteType; import net.imglib2.type.numeric.integer.UnsignedShortType; @@ -40,7 +45,6 @@ import net.imglib2.view.Views; import net.preibisch.legacy.io.IOFunctions; import net.preibisch.mvrecon.fiji.spimdata.SpimData2; -import net.preibisch.mvrecon.process.downsampling.lazy.LazyHalfPixelDownsample2x; import net.preibisch.mvrecon.process.interestpointregistration.pairwise.constellation.grouping.Group; import util.Grid; @@ -385,7 +389,7 @@ public static MultiResolutionLevelInfo[] setupBdvDatasetsN5( return mrInfo; } - public static void writeDownsampledBlock( + public static < T extends NativeType< T > & RealType< T > > void writeDownsampledBlock( final N5Writer n5, final MultiResolutionLevelInfo mrInfo, final MultiResolutionLevelInfo mrInfoPreviousScale, @@ -400,59 +404,21 @@ public static void writeDownsampledBlock( final DataType dataType = mrInfo.dataType;// n5.getAttribute( datasetPreviousScale, DatasetAttributes.DATA_TYPE_KEY, DataType.class ); final int[] blockSize = mrInfo.blockSize;// n5.getAttribute( datasetPreviousScale, DatasetAttributes.BLOCK_SIZE_KEY, int[].class ); - if ( dataType == DataType.UINT16 ) - { - RandomAccessibleInterval downsampled = N5Utils.open(n5, datasetPreviousScale); - - for ( int d = 0; d < downsampled.numDimensions(); ++d ) - if ( mrInfo.relativeDownsampling[ d ] > 1 ) - downsampled = LazyHalfPixelDownsample2x.init( - downsampled, - new FinalInterval( downsampled ), - new UnsignedShortType(), - blockSize, - d); - - final RandomAccessibleInterval sourceGridBlock = Views.offsetInterval(downsampled, gridBlock[0], gridBlock[1]); - N5Utils.saveNonEmptyBlock(sourceGridBlock, n5, dataset, gridBlock[2], new UnsignedShortType()); - } - else if ( dataType == DataType.UINT8 ) - { - RandomAccessibleInterval downsampled = N5Utils.open(n5, datasetPreviousScale); - - for ( int d = 0; d < downsampled.numDimensions(); ++d ) - if ( mrInfo.relativeDownsampling[ d ] > 1 ) - downsampled = LazyHalfPixelDownsample2x.init( - downsampled, - new FinalInterval( downsampled ), - new UnsignedByteType(), - blockSize, - d); - - final RandomAccessibleInterval sourceGridBlock = Views.offsetInterval(downsampled, gridBlock[0], gridBlock[1]); - N5Utils.saveNonEmptyBlock(sourceGridBlock, n5, dataset, gridBlock[2], new UnsignedByteType()); - } - else if ( dataType == DataType.FLOAT32 ) - { - RandomAccessibleInterval downsampled = N5Utils.open(n5, datasetPreviousScale);; - - for ( int d = 0; d < downsampled.numDimensions(); ++d ) - if ( mrInfo.relativeDownsampling[ d ] > 1 ) - downsampled = LazyHalfPixelDownsample2x.init( - downsampled, - new FinalInterval( downsampled ), - new FloatType(), - blockSize, - d); - - final RandomAccessibleInterval sourceGridBlock = Views.offsetInterval(downsampled, gridBlock[0], gridBlock[1]); - N5Utils.saveNonEmptyBlock(sourceGridBlock, n5, dataset, gridBlock[2], new FloatType()); - } - else + if ( dataType != DataType.UINT16 && dataType != DataType.UINT8 && dataType != DataType.FLOAT32 ) { n5.close(); throw new RuntimeException("Unsupported pixel type: " + dataType ); } + + final RandomAccessibleInterval previousScale = N5Utils.open(n5, datasetPreviousScale); + final T type = previousScale.getType().createVariable(); + + final BlockSupplier< T > blocks = BlockSupplier.of( previousScale ).andThen( Downsample.downsample( mrInfo.relativeDownsampling ) ); + final long[] dimensions = n5.getAttribute( dataset, DatasetAttributes.DIMENSIONS_KEY, long[].class ); + final RandomAccessibleInterval< T > downsampled = BlockAlgoUtils.cellImg( blocks, dimensions, new int[] { 64 } ); + + final RandomAccessibleInterval sourceGridBlock = Views.offsetInterval(downsampled, gridBlock[0], gridBlock[1]); + N5Utils.saveNonEmptyBlock(sourceGridBlock, n5, dataset, gridBlock[2], type); } public static ArrayList assembleJobs( final MultiResolutionLevelInfo mrInfo )