diff --git a/.gitignore b/.gitignore index 4f0f5d55..1bb075f9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ **/.project **/.settings **/target +src/test/tmp/* .DS_Store .classpath .project diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml deleted file mode 100644 index fc3ae7fb..00000000 --- a/dependency-reduced-pom.xml +++ /dev/null @@ -1,304 +0,0 @@ - - - - pom-scijava - org.scijava - 36.0.0 - ../pom.xml/pom.xml - - 4.0.0 - org.embl.mobie - mobie-io - MoBIE IO - 2.2.6 - Readers and writers for image data in MoBIE projects - https://github.com/mobie/mobie-io - - GitHub - https://github.com/mobie/mobie-io/issues - - - GitHub Actions - https://github.com/mobie/mobie-io/actions - - 2021 - - - ImageJ Forum - https://forum.image.sc/ - - - - - tischi - Christian Tischer - - lead - developer - debugger - reviewer - support - maintainer - - - - KateMoreva - Ekaterina Moreva - - lead - developer - debugger - reviewer - support - maintainer - - - - - - Kimberly Meechan - - developer - debugger - reviewer - support - - - - Tobias Pietzsch - - developer - debugger - reviewer - support - - - - - - Simplified BSD License - repo - - - - scm:git:https://github.com/mobie/mobie-io - scm:git:git@github.com:mobie/mobie-io - https://github.com/mobie/mobie-io - - - EMBL - http://embl.de/ - - - - - maven-surefire-plugin - - - ${someModule.test.excludes} - - - - - maven-shade-plugin - - - package - - shade - - - - - org.janelia.saalfeldlab:n5* - - - - - org.janelia.saalfeldlab.n5 - org.embl.mobie.io.n5.shaded - - - net.imglib2.realtransform - org.embl.mobie.io.n5.shaded - - net.imglib2.realtransform.AxisSelectionTransform - net.imglib2.realtransform.RealComponentMappingTransform - net.imglib2.realtransform.RealInvertibleComponentMappingTransform - net.imglib2.realtransform.StackedInvertibleRealTransform - net.imglib2.realtransform.StackedRealTransform - - - - - - - - - - - - scijava.public - https://maven.scijava.org/content/groups/public - - - - - net.imglib2 - imglib2 - 6.1.0 - compile - - - net.imglib2 - imglib2-cache - 1.0.0-beta-17 - compile - - - sc.fiji - bigdataviewer-core - 10.4.6 - compile - - - sc.fiji - bigdataviewer-vistools - 1.0.0-beta-32 - compile - - - sc.fiji - bigdataviewer_fiji - 6.2.4 - compile - - - sc.fiji - spim_data - 2.2.7 - compile - - - ome - bio-formats_plugins - 6.14.0 - compile - - - logback-classic - ch.qos.logback - - - - - com.google.http-client - google-http-client - 1.43.1 - compile - - - org.jetbrains - annotations - 16.0.2 - compile - - - net.imagej - ij - 1.54f - compile - - - tools - com.sun - - - - - ch.epfl.biop - bigdataviewer-image-loaders - 0.6.0 - compile - - - trove - trove - 1.0.2 - compile - - - com.moandjiezana.toml - toml4j - 0.7.2 - compile - - - org.junit.jupiter - junit-jupiter-api - 5.9.3 - test - - - opentest4j - org.opentest4j - - - junit-platform-commons - org.junit.platform - - - apiguardian-api - org.apiguardian - - - - - org.junit.jupiter - junit-jupiter-engine - 5.9.3 - test - - - junit-platform-engine - org.junit.platform - - - apiguardian-api - org.apiguardian - - - - - com.github.erosb - everit-json-schema - 1.14.0 - test - - - commons-validator - commons-validator - - - handy-uri-templates - com.damnhandy - - - - - - false - -Xmx4024m - 16.0.2 - org.embl.mobie.io - 1.14.0 - src/test/java/projects/local - 0.7.2 - 1.0.2 - 0.6.0 - EMBL - none - bsd_2 - sign,deploy-to-scijava - - diff --git a/pom.xml b/pom.xml index 12396a0b..ff844fd3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,12 @@ org.scijava pom-scijava - 36.0.0 + 37.0.0 org.embl.mobie mobie-io - 2.2.6 + 3.0.0-SNAPSHOT @@ -111,6 +111,19 @@ 1.0.2 1.14.0 0.7.2 + + 6.1.0 + 3.2.0 + 4.1.0 + 1.3.1 + 2.2.0 + 4.1.1 + 5.0.0 + 1.4.3 + 4.1.1 + 10.4.13 + 1.0.0-beta-34 + @@ -123,42 +136,6 @@ - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - - - org.janelia.saalfeldlab:n5* - - - - - org.janelia.saalfeldlab.n5 - org.embl.mobie.io.n5.shaded - - - net.imglib2.realtransform - org.embl.mobie.io.n5.shaded - - net.imglib2.realtransform.AxisSelectionTransform - net.imglib2.realtransform.RealComponentMappingTransform - net.imglib2.realtransform.RealInvertibleComponentMappingTransform - net.imglib2.realtransform.StackedInvertibleRealTransform - net.imglib2.realtransform.StackedRealTransform - - - - - - - @@ -171,7 +148,27 @@ org.janelia.saalfeldlab - n5-zarr + n5-viewer_fiji + + + org.janelia.saalfeldlab + n5-universe + + + org.janelia.saalfeldlab + n5-ij + + + org.janelia.saalfeldlab + n5 + + + org.janelia.saalfeldlab + n5-google-cloud + + + org.janelia.saalfeldlab + n5-aws-s3 net.imglib2 @@ -201,18 +198,6 @@ ome bio-formats_plugins - - org.janelia.saalfeldlab - n5-aws-s3 - - - org.janelia.saalfeldlab - n5-imglib2 - - - org.janelia.saalfeldlab - n5-hdf5 - com.google.http-client google-http-client diff --git a/src/main/java/org/embl/mobie/io/Axes.java b/src/main/java/org/embl/mobie/io/Axes.java deleted file mode 100644 index d0374924..00000000 --- a/src/main/java/org/embl/mobie/io/Axes.java +++ /dev/null @@ -1,179 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io; - -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.view.Views; - -import java.util.ArrayList; -import java.util.List; - -public abstract class Axes -{ - public static final String C = "c"; - public static final String Z = "z"; - public static final String T = "t"; - - public static < T > ArrayList< RandomAccessibleInterval< T > > getChannels( - final RandomAccessibleInterval< T > rai, List< String > axes ) - { - if ( rai.numDimensions() != axes.size() ) - throw new IllegalArgumentException( "provided axes doesn't match dimensionality of image" ); - - final ArrayList< RandomAccessibleInterval< T > > sourceStacks = new ArrayList< >(); - - /* - * If there are channels dimension, slice img along that dimension. - */ - final int c = axes.indexOf( C ); - if ( c != -1 ) - { - final int numSlices = ( int ) rai.dimension( c ); - for ( int s = 0; s < numSlices; ++s ) - sourceStacks.add( Views.hyperSlice( rai, c, s + rai.min( c ) ) ); - } - else - sourceStacks.add( rai ); - - /* - * If AxisOrder is a 2D variant (has no Z dimension), augment the - * sourceStacks by a Z dimension. - */ - final boolean addZ = !axes.contains( Z ); - if ( addZ ) - for ( int i = 0; i < sourceStacks.size(); ++i ) - sourceStacks.set( i, Views.addDimension( sourceStacks.get( i ), 0, 0 ) ); - - /* - * If at this point the dim order is XYTZ, permute to XYZT - */ - final boolean flipZ = !axes.contains( Z ) && axes.contains( T ); - if ( flipZ ) - for ( int i = 0; i < sourceStacks.size(); ++i ) - sourceStacks.set( i, Views.permute( sourceStacks.get( i ), 2, 3 ) ); - - return sourceStacks; - } - - -// -// public List getAxesList() { -// String pattern = "([a-z])"; -// List allMatches = new ArrayList<>(); -// Matcher m = Pattern.compile(pattern) -// .matcher(axes); -// while (m.find()) { -// allMatches.add(m.group()); -// } -// return allMatches; -// } -// -// public List< ZarrAxis > toAxesList( String spaceUnit, String timeUnit) { -// List zarrAxesList = new ArrayList<>(); -// List zarrAxesStrings = getAxesList(); -// -// String[] units = new String[]{spaceUnit, timeUnit}; -// -// // convert to valid ome-zarr units, if possible, otherwise just go ahead with -// // given unit -// for (int i = 0; i < units.length; i++) { -// String unit = units[i]; -// if (!UnitTypes.contains(unit)) { -// UnitTypes unitType = UnitTypes.convertUnit(unit); -// if (unitType != null) { -// units[i] = unitType.getTypeName(); -// } -// } -// } -// -// for (int i = 0; i < zarrAxesStrings.size(); i++) { -// String axisString = zarrAxesStrings.get(i); -// AxesTypes axisType = AxesTypes.getAxisType(axisString); -// -// String unit; -// if (axisType == AxesTypes.SPACE) { -// unit = units[0]; -// } else if (axisType == AxesTypes.TIME) { -// unit = units[1]; -// } else { -// unit = null; -// } -// -// zarrAxesList.add(new ZarrAxis(i, axisString, axisType.getTypeName(), unit)); -// } -// -// return zarrAxesList; -// } -// -// public boolean hasTimepoints() { -// return this.axes.equals(TCYX.axes) || this.axes.equals(TZYX.axes) || this.axes.equals(TYX.axes) || this.axes.equals(TCZYX.axes); -// } -// -// public boolean hasChannels() { -// return this.axes.equals(CZYX.axes) || this.axes.equals(CYX.axes) || this.axes.equals(TCYX.axes) || this.axes.equals(TCZYX.axes); -// } -// -// // the flag reverseAxes determines whether the index will be given w.r.t. -// // reversedAxes=true corresponds to the java/bdv axis convention -// // reversedAxes=false corresponds to the zarr axis convention -// public int axisIndex(String axisName, boolean reverseAxes) { -// if(reverseAxes) { -// List reverseAxesList = Lists.reverse(getAxesList()); -// return reverseAxesList.indexOf(axisName); -// } -// return getAxesList().indexOf(axisName); -// } -// -// public int timeIndex() { -// return axisIndex("t", true); -// } -// -// public int channelIndex() { -// return axisIndex("c", true); -// } -// -// // spatial: 0,1,2 (x,y,z) -// public Map spatialToArray() { -// final HashMap map = new HashMap<>(); -// map.put(0, 0); -// map.put(1, 1); -// if (hasZAxis()) { -// map.put(2, 2); -// } -// return map; -// } -// -// public boolean hasZAxis() { -// return this.axes.equals(TCZYX.axes) || this.axes.equals(CZYX.axes) || this.axes.equals(TZYX.axes) || this.axes.equals(ZYX.axes); -// } -// -// public int getNumDimension() { -// return getAxesList().size(); -// } -} diff --git a/src/main/java/org/embl/mobie/io/CachedCellImgOpener.java b/src/main/java/org/embl/mobie/io/CachedCellImgOpener.java deleted file mode 100644 index 7f9ebb13..00000000 --- a/src/main/java/org/embl/mobie/io/CachedCellImgOpener.java +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io; - -import bdv.cache.SharedQueue; -import bdv.util.volatiles.VolatileTypeMatcher; -import bdv.util.volatiles.VolatileViews; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; -import net.imglib2.cache.img.CachedCellImg; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.util.Util; -import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader; -import org.janelia.saalfeldlab.n5.imglib2.N5Utils; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class CachedCellImgOpener< T extends NativeType< T > & RealType< T > > -{ - private final String path; - private final ImageDataFormat imageDataFormat; - private final SharedQueue sharedQueue; - private boolean isOpen = false; - private List< RandomAccessibleInterval< T > > channelRAIs; - private ArrayList< RandomAccessibleInterval< Volatile< T > > > volatileChannelRAIs; - private T type; - - public CachedCellImgOpener( String path, ImageDataFormat imageDataFormat, SharedQueue sharedQueue ) - { - this.path = path; - this.imageDataFormat = imageDataFormat; - this.sharedQueue = sharedQueue; - } - - private void open() - { - if ( isOpen ) - return; - - try - { - switch ( imageDataFormat ) - { - case IlastikHDF5: - openIlastikHDF5(); - break; - default: - throw new UnsupportedOperationException( "Cannot open " + imageDataFormat ); - } - } catch ( Exception e ) - { - e.printStackTrace(); - throw new RuntimeException( e ); - } - } - - private void openIlastikHDF5() throws IOException - { - final N5HDF5Reader n5 = new N5HDF5Reader( path ); - - String dataset = "exported_data"; - if ( ! n5.datasetExists( dataset ) ) - dataset = "data"; - - List< String > axes = fetchAxesLabels( n5, dataset ); - - final CachedCellImg< T, ? > cachedCellImg = N5Utils.openVolatile( n5, dataset ); - channelRAIs = Axes.getChannels( cachedCellImg, axes ); - volatileChannelRAIs = Axes.getChannels( getVolatileRAI( cachedCellImg ), axes ); - type = Util.getTypeFromInterval( channelRAIs.get( 0 ) ); - isOpen = true; - } - - private RandomAccessibleInterval< Volatile< T > > getVolatileRAI( CachedCellImg< T, ? > cachedCellImg ) - { - if ( sharedQueue == null ) - { - return VolatileViews.wrapAsVolatile( cachedCellImg ); - } - else - { - return VolatileViews.wrapAsVolatile( cachedCellImg, sharedQueue ); - } - } - - private static List< String > fetchAxesLabels( N5HDF5Reader n5, String dataset ) throws IOException - { - try - { - ArrayList< String > axes = new ArrayList<>(); - final JsonObject axisTags = n5.getAttribute( dataset, "axistags", JsonObject.class ); - final JsonArray jsonArray = axisTags.get( "axes" ).getAsJsonArray(); - for ( JsonElement jsonElement : jsonArray ) - { - final JsonObject jsonObject = jsonElement.getAsJsonObject(); - final String axisLabel = jsonObject.get( "key" ).getAsString(); - axes.add( axisLabel ); - } - Collections.reverse( axes ); - return axes; - } - catch ( Exception e ) - { - List< String > axes = Arrays.asList( "t", "z", "y", "x", "c" ); - Collections.reverse( axes ); - return axes; - } - } - - public RandomAccessibleInterval< T > getRAI( int c ) - { - open(); - return channelRAIs.get( c ); - } - - public RandomAccessibleInterval< Volatile< T > > getVolatileRAI( int c ) - { - open(); - return volatileChannelRAIs.get( c ); - } - - public int getNumChannels() - { - open(); - return channelRAIs.size(); - } - - public T getType() - { - open(); - return type; - } -} diff --git a/src/main/java/org/embl/mobie/io/ImageDataFormat.java b/src/main/java/org/embl/mobie/io/ImageDataFormat.java index 301138fc..9488a489 100644 --- a/src/main/java/org/embl/mobie/io/ImageDataFormat.java +++ b/src/main/java/org/embl/mobie/io/ImageDataFormat.java @@ -30,7 +30,7 @@ import com.google.gson.annotations.SerializedName; -import static org.embl.mobie.io.ImageDataFormatNames.*; +import static org.embl.mobie.io.ImageDataFormat.Names.*; /** * Currently mobie-io supports the following data formats: @@ -101,12 +101,16 @@ public enum ImageDataFormat { BdvOmeZarrS3, @SerializedName(IMARIS) Imaris, - @SerializedName(SPIMDATA) + @SerializedName( IMAGEDATA ) SpimData, - @SerializedName(ILASTIKHDF5) - IlastikHDF5; + @SerializedName( IMAGEDATA ) + ImageData, + @SerializedName( ILASTIK ) + Ilastik; - public static ImageDataFormat fromString(String string) { + private String[] secretAndAccessKey; + + public static ImageDataFormat fromString( String string) { switch (string) { case TOML: return Toml; @@ -136,10 +140,10 @@ public static ImageDataFormat fromString(String string) { return OmeZarrS3; case IMARIS: return Imaris; - case SPIMDATA: + case IMAGEDATA: return SpimData; - case ILASTIKHDF5: - return IlastikHDF5; + case ILASTIK: + return Ilastik; default: throw new UnsupportedOperationException("Unknown file format: " + string); } @@ -180,8 +184,10 @@ public String toString() { return IMARIS; case SpimData: return SPIMDATA; - case IlastikHDF5: - return ILASTIKHDF5; + case ImageData: + return IMAGEDATA; + case Ilastik: + return ILASTIK; default: throw new UnsupportedOperationException("Unknown file format: " + this); } @@ -199,7 +205,7 @@ else if (lowerCase.endsWith( ".ome.tif" ) || lowerCase.endsWith( ".ome.tiff" ) ) else if (lowerCase.endsWith( ".tif" ) || lowerCase.endsWith( ".tiff" )) return ImageDataFormat.Tiff; else if (lowerCase.endsWith( ".h5" )) - return ImageDataFormat.IlastikHDF5; + return ImageDataFormat.Ilastik; else if (lowerCase.endsWith( ".toml" )) return ImageDataFormat.Toml; else @@ -210,6 +216,7 @@ public boolean inMemory() { switch (this) { case SpimData: + case ImageData: return true; default: return false; @@ -248,4 +255,36 @@ public boolean hasXml() { return false; } } + + public static class Names + { + public static final String TOML = "toml"; + public static final String TIFF = "tiff"; + public static final String IMAGEJ = "imagej"; + public static final String BIOFORMATS = "bioformats"; + public static final String BIOFORMATSS3 = "bioformats.s3"; + public static final String BDV = "bdv"; + public static final String BDVN5 = "bdv.n5"; + public static final String BDVN5S3 = "bdv.n5.s3"; + public static final String BDVHDF5 = "bdv.hdf5"; + public static final String BDVOMEZARR = "bdv.ome.zarr"; + public static final String BDVOMEZARRS3 = "bdv.ome.zarr.s3"; + public static final String OPENORGANELLES3 = "openOrganelle.s3"; + public static final String OMEZARR = "ome.zarr"; + public static final String OMEZARRS3 = "ome.zarr.s3"; + public static final String IMARIS = "ims"; + public static final String SPIMDATA = "spimData"; + public static final String IMAGEDATA = "imageData"; + public static final String ILASTIK = "ilastik"; + } + + public void setS3SecretAndAccessKey( String[] secretAndAccessKey ) + { + this.secretAndAccessKey = secretAndAccessKey; + } + + public String[] getSecretAndAccessKey() + { + return secretAndAccessKey; + } } diff --git a/src/main/java/org/embl/mobie/io/ImageDataFormatNames.java b/src/main/java/org/embl/mobie/io/ImageDataFormatNames.java deleted file mode 100644 index e9a271a3..00000000 --- a/src/main/java/org/embl/mobie/io/ImageDataFormatNames.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io; - -public class ImageDataFormatNames -{ - public static final String TOML = "toml"; - public static final String TIFF = "tiff"; - public static final String IMAGEJ = "imagej"; - public static final String BIOFORMATS = "bioformats"; - public static final String BIOFORMATSS3 = "bioformats.s3"; - public static final String BDV = "bdv"; - public static final String BDVN5 = "bdv.n5"; - public static final String BDVN5S3 = "bdv.n5.s3"; - public static final String BDVHDF5 = "bdv.hdf5"; - public static final String BDVOMEZARR = "bdv.ome.zarr"; - public static final String BDVOMEZARRS3 = "bdv.ome.zarr.s3"; - public static final String OPENORGANELLES3 = "openOrganelle.s3"; - public static final String OMEZARR = "ome.zarr"; - public static final String OMEZARRS3 = "ome.zarr.s3"; - public static final String IMARIS = "ims"; - public static final String SPIMDATA = "spimData"; - public static final String ILASTIKHDF5 = "ilastikHDF5"; -} diff --git a/src/main/java/org/embl/mobie/io/ImageDataOpener.java b/src/main/java/org/embl/mobie/io/ImageDataOpener.java new file mode 100644 index 00000000..51e96dd2 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/ImageDataOpener.java @@ -0,0 +1,101 @@ +/*- + * #%L + * Readers and writers for image data + * %% + * Copyright (C) 2021 - 2024 EMBL + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package org.embl.mobie.io; + +import bdv.cache.SharedQueue; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.embl.mobie.io.imagedata.*; +import org.embl.mobie.io.util.S3Utils; + + +public class ImageDataOpener +{ + + public static < T extends NumericType< T > & NativeType< T > > ImageData< T > open( + String uri ) + { + return open( + uri, + ImageDataFormat.fromPath( uri ), + new SharedQueue( Runtime.getRuntime().availableProcessors() - 1 )); + } + + + public static < T extends NumericType< T > & NativeType< T > > ImageData< T > open( + String uri, + SharedQueue sharedQueue ) + { + return open( + uri, + ImageDataFormat.fromPath( uri ), + sharedQueue ); + } + + public static < T extends NumericType< T > & NativeType< T > > ImageData< T > open( + String uri, + ImageDataFormat imageDataFormat, + SharedQueue sharedQueue ) + { + switch (imageDataFormat) + { + case OmeZarr: + case OmeZarrS3: + case OpenOrganelleS3: + return new N5ImageData<>( uri, sharedQueue, imageDataFormat.getSecretAndAccessKey() ); + case Toml: + return new TOMLImageData<>( uri, sharedQueue ); + case Tiff: + return new TIFFImageData<>( uri, sharedQueue ); + case ImageJ: + return new ImageJImageData<>( uri, sharedQueue ); + case Imaris: + return new ImarisImageData<>( uri, sharedQueue ); + case Ilastik: + return new IlastikImageData<>( uri, sharedQueue ); + case BioFormats: + return new BioFormatsImageData<>( uri, sharedQueue ); + case BioFormatsS3: + // TODO: use the s3AccessAndSecretKey + return new BioFormatsS3ImageData<>( uri, sharedQueue ); + case Bdv: + case BdvHDF5: + case BdvN5: + case BdvN5S3: + // TODO: use the s3AccessAndSecretKey + return new BDVXMLImageData<>( uri, sharedQueue ); + case BdvOmeZarr: + case BdvOmeZarrS3: + default: + throw new RuntimeException( "Opening " + imageDataFormat + " is not supported; " + + "if you need it please report here: " + + "https://github.com/mobie/mobie-io/issues" ); + } + } +} diff --git a/src/main/java/org/embl/mobie/io/OMEZarrWriter.java b/src/main/java/org/embl/mobie/io/OMEZarrWriter.java new file mode 100644 index 00000000..f5991dd1 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/OMEZarrWriter.java @@ -0,0 +1,105 @@ +/*- + * #%L + * Readers and writers for image data + * %% + * Copyright (C) 2021 - 2024 EMBL + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package org.embl.mobie.io; + +import bdv.export.ExportMipmapInfo; +import bdv.export.ProposeMipmaps; +import bdv.viewer.Source; +import ij.ImagePlus; +import mpicbg.spim.data.generic.sequence.BasicViewSetup; +import org.embl.mobie.io.util.IOHelper; +import org.janelia.saalfeldlab.n5.N5URI; +import org.janelia.saalfeldlab.n5.ij.N5Importer; +import org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter; + +import java.net.URISyntaxException; + +import static org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter.GZIP_COMPRESSION; +import static org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter.ZARR_FORMAT; + +public class OMEZarrWriter +{ + public enum ImageType + { + Intensities, + Labels; + } + + public static void write( ImagePlus imp, String uri, ImageType imageType, boolean overwrite ) + { + N5ScalePyramidExporter.DOWNSAMPLE_METHOD downsampleMethod = + imageType.equals( ImageType.Labels ) ? + N5ScalePyramidExporter.DOWNSAMPLE_METHOD.Sample + : N5ScalePyramidExporter.DOWNSAMPLE_METHOD.Average; + + String chunkSizeArg = imp.getNSlices() == 1 ? "1024,1024,1,1,1" : "96,96,1,96,1"; // X,Y,C,Z,T + + + try + { + N5URI n5URI = new N5URI( uri ); + String containerPath = n5URI.getContainerPath(); + String groupPath = n5URI.getGroupPath(); + int a = 1; + + N5ScalePyramidExporter exporter = new N5ScalePyramidExporter( + imp, + containerPath, + groupPath, + ZARR_FORMAT, + chunkSizeArg, + true, + downsampleMethod, + N5Importer.MetadataOmeZarrKey, + GZIP_COMPRESSION + ); + + exporter.setOverwrite( overwrite ); + exporter.run(); + } + catch ( URISyntaxException e ) + { + throw new RuntimeException( e ); + } + + // TODO: If we want to give the dataset a name we also have to + // update how we refer to such an image or segmentation in the dataset.JSON + // String n5Dataset = ""; +// String n5Dataset = imageType.equals( ImageType.Labels ) ? "labels" : "intensities"; +// if ( imageType.equals( ImageType.Labels ) ) +// { +// uri = IOHelper.combinePath( uri, "labels/0" ); +// } +// else +// { +// uri = IOHelper.combinePath( uri, "intensities" ); +// } + } + +} diff --git a/src/main/java/org/embl/mobie/io/OpenerLogging.java b/src/main/java/org/embl/mobie/io/OpenerLogging.java deleted file mode 100644 index 1a733296..00000000 --- a/src/main/java/org/embl/mobie/io/OpenerLogging.java +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io; - -public abstract class OpenerLogging -{ - protected static boolean logging; - - public static synchronized void setLogging(final boolean logging) { - OpenerLogging.logging = logging; - } -} diff --git a/src/main/java/org/embl/mobie/io/SpimDataOpener.java b/src/main/java/org/embl/mobie/io/SpimDataOpener.java deleted file mode 100644 index a77755b8..00000000 --- a/src/main/java/org/embl/mobie/io/SpimDataOpener.java +++ /dev/null @@ -1,388 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io; - -import bdv.cache.SharedQueue; -import bdv.img.cache.VolatileGlobalCellCache; -import bdv.img.imaris.Imaris; -import bdv.spimdata.SpimDataMinimal; -import ch.epfl.biop.bdv.img.CacheControlOverride; -import ch.epfl.biop.bdv.img.OpenersToSpimData; -import ch.epfl.biop.bdv.img.bioformats.BioFormatsHelper; -import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; -import ch.epfl.biop.bdv.img.opener.OpenerSettings; -import ij.IJ; -import ij.ImagePlus; -import ij.io.Opener; - -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.generic.AbstractSpimData; -import mpicbg.spim.data.generic.sequence.BasicImgLoader; -import net.imglib2.util.Cast; -import org.embl.mobie.io.n5.openers.N5Opener; -import org.embl.mobie.io.n5.openers.N5S3Opener; -import org.embl.mobie.io.ome.zarr.loaders.N5S3OMEZarrImageLoader; -import org.embl.mobie.io.ome.zarr.loaders.xml.XmlN5OmeZarrImageLoader; -import org.embl.mobie.io.ome.zarr.openers.OMEZarrOpener; -import org.embl.mobie.io.ome.zarr.openers.OMEZarrS3Opener; -import org.embl.mobie.io.openorganelle.OpenOrganelleS3Opener; -import org.embl.mobie.io.toml.TOMLOpener; -import org.embl.mobie.io.util.CustomXmlIoSpimData; -import org.embl.mobie.io.util.IOHelper; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; -import org.jdom2.input.SAXBuilder; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static mpicbg.spim.data.XmlKeys.IMGLOADER_TAG; -import static mpicbg.spim.data.XmlKeys.SEQUENCEDESCRIPTION_TAG; - - -public class SpimDataOpener { - - public static final String ERROR_WHILE_TRYING_TO_READ_SPIM_DATA = "Error while trying to read "; - - public SpimDataOpener() { - } - - public AbstractSpimData< ? > open(String imagePath, ImageDataFormat imageDataFormat, SharedQueue sharedQueue) throws UnsupportedOperationException, SpimDataException { - if (sharedQueue == null) - return open(imagePath, imageDataFormat); - return openWithSharedQueue(imagePath, imageDataFormat, sharedQueue); - } - - public AbstractSpimData< ? > open( String imagePath, ImageDataFormat imageDataFormat) throws UnsupportedOperationException, SpimDataException { - switch (imageDataFormat) { - case Toml: - return new TOMLOpener( imagePath ).asSpimData(); - case Tiff: - final File file = new File(imagePath); - return open((new Opener()).openTiff( file.getParent(), file.getName())); - case ImageJ: - return open(IJ.openImage(imagePath)); - case BioFormats: - return openWithBDVBioFormats(imagePath); - case BioFormatsS3: - return openWithBioFormatsFromS3(imagePath, 0, null ); - case Imaris: - return openImaris(imagePath); - case Bdv: - case BdvHDF5: - case BdvN5: - case BdvN5S3: - return openBdvXml(imagePath); - case OmeZarr: - return openOmeZarr(imagePath); - case OmeZarrS3: - return openOmeZarrS3(imagePath); - case BdvOmeZarr: - return openBdvOmeZarr(imagePath, null); - case BdvOmeZarrS3: - return openBdvOmeZarrS3(imagePath, null); - case OpenOrganelleS3: - return openOpenOrganelleS3(imagePath); - default: - throw new UnsupportedOperationException("Opening of " + imageDataFormat + " is not supported."); - } - } - - private AbstractSpimData< ? > openWithSharedQueue( String imagePath, ImageDataFormat imageDataFormat, SharedQueue sharedQueue) throws UnsupportedOperationException, SpimDataException { - switch (imageDataFormat) { - case Toml: - return new TOMLOpener( imagePath ).asSpimData(sharedQueue); - case Tiff: - return open(IOHelper.openTiffFromFile( imagePath ), sharedQueue); - case ImageJ: - ImagePlus imagePlus = IJ.openImage( imagePath ); - if ( imagePlus == null ) - throw new RuntimeException("Could not open " + imagePath ); - return open( imagePlus, sharedQueue); - case BioFormats: - return openWithBDVBioFormats(imagePath, sharedQueue); - case BioFormatsS3: - return openWithBioFormatsFromS3(imagePath, 0, sharedQueue ); - case BdvN5: - return openBdvN5(imagePath, sharedQueue); - case BdvN5S3: - return openBdvN5S3(imagePath, sharedQueue); - case OmeZarr: - return openOmeZarr(imagePath, sharedQueue); - case OmeZarrS3: - return openOmeZarrS3(imagePath, sharedQueue); - case BdvOmeZarr: - return openBdvOmeZarr(imagePath, sharedQueue); - case BdvOmeZarrS3: - return openBdvOmeZarrS3(imagePath, sharedQueue); - default: - // open without {@code SharedQueue} - return open(imagePath, imageDataFormat); - } - } - - public AbstractSpimData open( ImagePlus imagePlus ) - { - return ImagePlusToSpimData.getSpimData( imagePlus ); - } - - public AbstractSpimData open( ImagePlus imagePlus, SharedQueue sharedQueue ) - { - final AbstractSpimData< ? > spimData = open( imagePlus ); - setSharedQueue( sharedQueue, spimData ); - return spimData; - } - - public static void setSharedQueue( SharedQueue sharedQueue, AbstractSpimData< ? > spimData ) - { - BasicImgLoader imgLoader = spimData.getSequenceDescription().getImgLoader(); - - if (imgLoader instanceof CacheControlOverride) { - CacheControlOverride cco = (CacheControlOverride) imgLoader; - final VolatileGlobalCellCache volatileGlobalCellCache = new VolatileGlobalCellCache( sharedQueue ); - cco.setCacheControl( volatileGlobalCellCache ); - } - } - - @NotNull - private SpimDataMinimal openImaris(String imagePath) throws RuntimeException { - try { - return Imaris.openIms(imagePath); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private SpimData openBdvXml(String path) throws SpimDataException { - try { - InputStream stream = IOHelper.getInputStream(path); - return new CustomXmlIoSpimData().loadFromStream(stream, path); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openBdvN5(String path, SharedQueue queue) throws SpimDataException { - try { - return N5Opener.openFile(path, queue); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openBdvN5S3(String path, SharedQueue queue) throws SpimDataException { - try { - return N5S3Opener.readURL(path, queue); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openOmeZarr(String path) throws SpimDataException { - try { - return OMEZarrOpener.openFile(path); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openOmeZarr(String path, SharedQueue sharedQueue) throws SpimDataException { - try { - return OMEZarrOpener.openFile(path, sharedQueue); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openOmeZarrS3(String path) throws SpimDataException { - try { - return OMEZarrS3Opener.readURL(path); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openOmeZarrS3(String path, SharedQueue sharedQueue) throws SpimDataException { - try { - return OMEZarrS3Opener.readURL(path, sharedQueue); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - private SpimData openOpenOrganelleS3(String path) throws SpimDataException { - try { - return OpenOrganelleS3Opener.readURL(path); - } catch (Exception e) { - System.err.println("Error opening " + path); - throw new RuntimeException(e); - } - } - - @NotNull - private SpimData openBdvOmeZarrS3(String path, SharedQueue queue) { - //TODO: finish bug fixing - try { - SAXBuilder sax = new SAXBuilder(); - InputStream stream = IOHelper.getInputStream(path); - Document doc = sax.build(stream); - Element imgLoaderElem = doc.getRootElement().getChild("SequenceDescription").getChild("ImageLoader"); - String bucketAndObject = imgLoaderElem.getChild("BucketName").getText() + "/" + imgLoaderElem.getChild("Key").getText(); - String[] split = bucketAndObject.split("/"); - String bucket = split[0]; - String object = Arrays.stream(split).skip(1L).collect(Collectors.joining("/")); - N5S3OMEZarrImageLoader imageLoader; - if (queue != null) { - imageLoader = new N5S3OMEZarrImageLoader(imgLoaderElem.getChild("ServiceEndpoint").getText(), imgLoaderElem.getChild("SigningRegion").getText(), bucket, object, ".", queue); - } else { - imageLoader = new N5S3OMEZarrImageLoader(imgLoaderElem.getChild("ServiceEndpoint").getText(), imgLoaderElem.getChild("SigningRegion").getText(), bucket, object, "."); - } - SpimData spim = new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); - SpimData spimData; - try { - InputStream st = IOHelper.getInputStream(path); - spimData = (new CustomXmlIoSpimData()).loadFromStream(st, path); - } catch (SpimDataException exception) { - System.err.println("Failed to load stream from " + path + "; " + exception); - return null; - } - spimData.setBasePath(null); - spimData.getSequenceDescription().setImgLoader(spim.getSequenceDescription().getImgLoader()); - spimData.getSequenceDescription().getAllChannels().putAll(spim.getSequenceDescription().getAllChannels()); - return spimData; - } catch (JDOMException | IOException e) { - System.err.println("Failed to open BdvOmeZarrS3: " + e); - return null; - } - } - - public AbstractSpimData< ? > openWithBDVBioFormats( String path ) - { - final File file = new File( path ); - List< OpenerSettings > openerSettings = new ArrayList<>(); - int numSeries = BioFormatsHelper.getNSeries(file); - for (int i = 0; i < numSeries; i++) { - openerSettings.add( - OpenerSettings.BioFormats() - .location(file) - .setSerie(i) ); - } - return OpenersToSpimData.getSpimData( openerSettings ); - } - - public AbstractSpimData< ? > openWithBDVBioFormats( String path, SharedQueue sharedQueue ) - { - final AbstractSpimData< ? > spimData = openWithBDVBioFormats( path ); - setSharedQueue( sharedQueue, spimData ); - return spimData; - } - - // TODO: Currently does not support resolution pyramids - // - public AbstractSpimData< ? > openWithBioFormatsFromS3( String path, int seriesIndex, SharedQueue sharedQueue ) - { - ImagePlus imagePlus = IOHelper.openWithBioformatsFromS3( path, seriesIndex ); - - if ( sharedQueue != null ) - { - return open( imagePlus, sharedQueue ); - } - else - { - return open( imagePlus ); - } - } - - private SpimData openBdvOmeZarr(String path, @Nullable SharedQueue sharedQueue) throws SpimDataException { - SpimData spimData = openBdvXml(path); - SpimData spimDataWithImageLoader = getSpimDataWithImageLoader(path, sharedQueue); - if (spimData != null && spimDataWithImageLoader != null) { - spimData.getSequenceDescription().setImgLoader(spimDataWithImageLoader.getSequenceDescription().getImgLoader()); - spimData.getSequenceDescription().getAllChannels().putAll(spimDataWithImageLoader.getSequenceDescription().getAllChannels()); - return spimData; - } else { - throw new SpimDataException(ERROR_WHILE_TRYING_TO_READ_SPIM_DATA); - } - } - - @NotNull - private N5S3OMEZarrImageLoader createN5S3OmeZarrImageLoader(String path, @Nullable SharedQueue queue) throws IOException, JDOMException { - final SAXBuilder sax = new SAXBuilder(); - InputStream stream = IOHelper.getInputStream(path); - final Document doc = sax.build(stream); - final Element imgLoaderElem = doc.getRootElement().getChild(SEQUENCEDESCRIPTION_TAG).getChild(IMGLOADER_TAG); - String bucketAndObject = imgLoaderElem.getChild("BucketName").getText() + "/" + imgLoaderElem.getChild("Key").getText(); - final String[] split = bucketAndObject.split("/"); - String bucket = split[0]; - String object = Arrays.stream(split).skip(1).collect(Collectors.joining("/")); - if (queue == null) { - return new N5S3OMEZarrImageLoader(imgLoaderElem.getChild("ServiceEndpoint").getText(), imgLoaderElem.getChild("SigningRegion").getText(), bucket, object, "."); - } else { - return new N5S3OMEZarrImageLoader(imgLoaderElem.getChild("ServiceEndpoint").getText(), imgLoaderElem.getChild("SigningRegion").getText(), bucket, object, ".", queue); - } - } - - private SpimData getSpimDataWithImageLoader(String path, @Nullable SharedQueue sharedQueue) { - try { - final SAXBuilder sax = new SAXBuilder(); - InputStream stream = IOHelper.getInputStream(path); - final Document doc = sax.build(stream); - final Element imgLoaderElem = doc.getRootElement().getChild(SEQUENCEDESCRIPTION_TAG).getChild(IMGLOADER_TAG); - String imagesFile = XmlN5OmeZarrImageLoader.getDatasetsPathFromXml(imgLoaderElem, path); - if (imagesFile != null) { - if (new File(imagesFile).exists()) { - return sharedQueue != null ? OMEZarrOpener.openFile(imagesFile, sharedQueue) - : OMEZarrOpener.openFile(imagesFile); - } else { - return sharedQueue != null ? OMEZarrS3Opener.readURL(imagesFile, sharedQueue) - : OMEZarrS3Opener.readURL(imagesFile); - } - } - } catch (JDOMException | IOException e) { - IJ.log(e.getMessage()); - } - return null; - } -} diff --git a/src/main/java/org/embl/mobie/io/imagedata/BDVXMLImageData.java b/src/main/java/org/embl/mobie/io/imagedata/BDVXMLImageData.java new file mode 100644 index 00000000..fefc9c79 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/BDVXMLImageData.java @@ -0,0 +1,35 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.OpenersToSpimData; +import ch.epfl.biop.bdv.img.bioformats.BioFormatsHelper; +import ch.epfl.biop.bdv.img.opener.OpenerSettings; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.embl.mobie.io.util.IOHelper; +import org.embl.mobie.io.util.InputStreamXmlIoSpimData; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class BDVXMLImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + public BDVXMLImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws Exception + { + InputStream stream = IOHelper.getInputStream( uri ); + return new InputStreamXmlIoSpimData().open( stream, uri ); + } + } ); + this.uri = uri; + this.sharedQueue = sharedQueue; + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/BioFormatsImageData.java b/src/main/java/org/embl/mobie/io/imagedata/BioFormatsImageData.java new file mode 100644 index 00000000..417f1256 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/BioFormatsImageData.java @@ -0,0 +1,49 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.OpenersToSpimData; +import ch.epfl.biop.bdv.img.bioformats.BioFormatsHelper; +import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; +import ch.epfl.biop.bdv.img.opener.OpenerSettings; +import ij.IJ; +import ij.ImagePlus; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class BioFormatsImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + public BioFormatsImageData( SpimDataOpener spimDataOpener ) + { + super( spimDataOpener ); + } + + public BioFormatsImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws IOException + { + final File file = new File( uri ); + List< OpenerSettings > openerSettings = new ArrayList<>(); + int numSeries = BioFormatsHelper.getNSeries(file); + for (int i = 0; i < numSeries; i++) { + openerSettings.add( + OpenerSettings.BioFormats() + .location(file) + .setSerie(i) ); + } + + return OpenersToSpimData.getSpimData( openerSettings ); + } + } ); + this.uri = uri; + this.sharedQueue = sharedQueue; + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/BioFormatsS3ImageData.java b/src/main/java/org/embl/mobie/io/imagedata/BioFormatsS3ImageData.java new file mode 100644 index 00000000..14b0b97a --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/BioFormatsS3ImageData.java @@ -0,0 +1,28 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; +import ij.ImagePlus; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.embl.mobie.io.util.IOHelper; + +public class BioFormatsS3ImageData< T extends NumericType< T > & NativeType< T > > extends BioFormatsImageData< T > +{ + public BioFormatsS3ImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws Exception + { + ImagePlus imagePlus = IOHelper.openWithBioFormatsFromS3( uri, 0 ); + return ImagePlusToSpimData.getSpimData( imagePlus ); + } + } ); + + this.sharedQueue = sharedQueue; + this.uri = uri; + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/IlastikImageData.java b/src/main/java/org/embl/mobie/io/imagedata/IlastikImageData.java new file mode 100644 index 00000000..41a9f99e --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/IlastikImageData.java @@ -0,0 +1,217 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import bdv.util.volatiles.VolatileViews; +import bdv.viewer.Source; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import mpicbg.spim.data.sequence.FinalVoxelDimensions; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.Volatile; +import net.imglib2.cache.img.CachedCellImg; +import net.imglib2.realtransform.AffineTransform3D; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Pair; +import net.imglib2.util.Util; +import net.imglib2.util.ValuePair; +import net.imglib2.view.Views; +import org.embl.mobie.io.util.RandomAccessibleIntervalSource4D; +import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader; +import org.janelia.saalfeldlab.n5.imglib2.N5Utils; +import org.janelia.saalfeldlab.n5.universe.metadata.canonical.CanonicalDatasetMetadata; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class IlastikImageData< T extends NumericType< T > & NativeType< T >, V extends Volatile & NumericType > implements ImageData< T > +{ + private static final String C = "c"; + private static final String Z = "z"; + private static final String T = "t"; + public static final String X = "x"; + public static final String Y = "y"; + private final String uri; + private final SharedQueue sharedQueue; + private boolean isOpen; + private ArrayList< RandomAccessibleInterval< T > > channelRAIs; + private ArrayList< RandomAccessibleInterval< V > > volatileChannelRAIs; + + public IlastikImageData( String uri, SharedQueue sharedQueue ) + { + this.uri = uri; + this.sharedQueue = sharedQueue; + } + + @Override + public Pair< Source< T >, Source< ? extends Volatile< T > > > getSourcePair( int datasetIndex ) + { + if ( ! isOpen ) open(); + + Source< T > source = asSource( channelRAIs.get( datasetIndex ) ); + Source< ? extends Volatile< T > > vSource = asVolatileSource( volatileChannelRAIs.get( datasetIndex ) ); + + return new ValuePair<>( source, vSource ); + } + + private Source< T > asSource( RandomAccessibleInterval< T > rai ) + { + if ( rai.numDimensions() == 3 ) + { + // no time axis, thus we need to add one + rai = Views.addDimension( rai, 0, 0 ); + } + + return new RandomAccessibleIntervalSource4D<>( + rai, + Util.getTypeFromInterval( rai ), + new AffineTransform3D(), + new FinalVoxelDimensions( "pixel", 1, 1, 1 ), + "ilastik" ); + } + + private Source< V > asVolatileSource( RandomAccessibleInterval< V > rai ) + { + if ( rai.numDimensions() == 3 ) + { + // no time axis, thus we need to add one + rai = Views.addDimension( rai, 0, 0 ); + } + + return new RandomAccessibleIntervalSource4D<>( + rai, + Util.getTypeFromInterval( rai ), + new AffineTransform3D(), + new FinalVoxelDimensions( "pixel", 1, 1, 1 ), + "ilastik" ); + } + + + @Override + public int getNumDatasets() + { + if ( !isOpen ) open(); + + return channelRAIs.size(); + } + + @Override + public CanonicalDatasetMetadata getMetadata( int datasetIndex ) + { + if ( !isOpen ) open(); + + return null; + // white +// IntColorMetadata colorMetadata = new IntColorMetadata( ARGBType.rgba( 255, 255, 255, 255 ) ); +// +// // FIXME: in general, how do we deal with this being not known? +// return new CanonicalDatasetMetadata( +// uri, +// null, +// 0, +// 1, // FIXME: what is correct? +// colorMetadata +// ); + } + + private synchronized void open() + { + if ( isOpen ) return; + + try + { + final N5HDF5Reader n5 = new N5HDF5Reader( uri ); + String dataset = "exported_data"; + if ( ! n5.datasetExists( dataset ) ) + dataset = "data"; + List< String > axes = fetchAxesLabels( n5, dataset ); + final CachedCellImg< T, ? > cachedCellImg = N5Utils.openVolatile( n5, dataset ); + channelRAIs = splitIntoChannels( cachedCellImg, axes ); + volatileChannelRAIs = ( ArrayList ) splitIntoChannels( getVolatileRAI( cachedCellImg ), axes ); + isOpen = true; + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + private RandomAccessibleInterval< ? extends Volatile< T > > getVolatileRAI( CachedCellImg< T, ? > cachedCellImg ) + { + if ( sharedQueue == null ) + { + return VolatileViews.wrapAsVolatile( cachedCellImg ); + } + else + { + return VolatileViews.wrapAsVolatile( cachedCellImg, sharedQueue ); + } + } + + private static List< String > fetchAxesLabels( N5HDF5Reader n5, String dataset ) throws IOException + { + try + { + ArrayList< String > axes = new ArrayList<>(); + final JsonObject axisTags = n5.getAttribute( dataset, "axistags", JsonObject.class ); + final JsonArray jsonArray = axisTags.get( "axes" ).getAsJsonArray(); + for ( JsonElement jsonElement : jsonArray ) + { + final JsonObject jsonObject = jsonElement.getAsJsonObject(); + final String axisLabel = jsonObject.get( "key" ).getAsString(); + axes.add( axisLabel ); + } + Collections.reverse( axes ); + return axes; + } + catch ( Exception e ) + { + List< String > axes = Arrays.asList( T, Z, C, X, Y ); + Collections.reverse( axes ); + return axes; + } + } + + private static < T > ArrayList< RandomAccessibleInterval< T > > splitIntoChannels( + final RandomAccessibleInterval< T > rai, + List< String > axes ) + { + if ( rai.numDimensions() != axes.size() ) + throw new IllegalArgumentException( "provided axes doesn't match dimensionality of image" ); + + final ArrayList< RandomAccessibleInterval< T > > sourceStacks = new ArrayList<>(); + + /* + * If there is a channels dimension, slice img along that dimension. + */ + final int c = axes.indexOf( C ); + if ( c != -1 ) + { + final int numSlices = ( int ) rai.dimension( c ); + for ( int s = 0; s < numSlices; ++s ) + sourceStacks.add( Views.hyperSlice( rai, c, s + rai.min( c ) ) ); + } else + sourceStacks.add( rai ); + + /* + * If AxisOrder is a 2D variant (has no Z dimension), augment the + * sourceStacks by a Z dimension. + */ + final boolean addZ = !axes.contains( Z ); + if ( addZ ) + sourceStacks.replaceAll( interval -> Views.addDimension( interval, 0, 0 ) ); + + /* + * If at this point the dim order is XYTZ, permute to XYZT + */ + final boolean flipZ = !axes.contains( Z ) && axes.contains( T ); + if ( flipZ ) + sourceStacks.replaceAll( interval -> Views.permute( interval, 2, 3 ) ); + + return sourceStacks; + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/ImageData.java b/src/main/java/org/embl/mobie/io/imagedata/ImageData.java new file mode 100644 index 00000000..2e301807 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/ImageData.java @@ -0,0 +1,18 @@ +package org.embl.mobie.io.imagedata; + +import bdv.viewer.Source; +import net.imglib2.Volatile; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Pair; +import org.janelia.saalfeldlab.n5.universe.metadata.canonical.CanonicalDatasetMetadata; + +public interface ImageData < T extends NumericType< T > & NativeType< T > > +{ + Pair< Source< T >, Source< ? extends Volatile< T > > > getSourcePair( int datasetIndex ); + + int getNumDatasets(); + + // https://imagesc.zulipchat.com/#narrow/stream/327326-BigDataViewer/topic/Dataset.20Metadata + CanonicalDatasetMetadata getMetadata( int datasetIndex ); +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/ImageJImageData.java b/src/main/java/org/embl/mobie/io/imagedata/ImageJImageData.java new file mode 100644 index 00000000..d2ecd86c --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/ImageJImageData.java @@ -0,0 +1,33 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; +import ij.IJ; +import ij.ImagePlus; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; + +import java.io.IOException; + +public class ImageJImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + + public ImageJImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws IOException + { + ImagePlus imagePlus = IJ.openImage( uri ); + if ( imagePlus == null ) + throw new IOException(); + + return ImagePlusToSpimData.getSpimData( imagePlus ); + } + } ); + this.uri = uri; + this.sharedQueue = sharedQueue; + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/ImagePlusImageData.java b/src/main/java/org/embl/mobie/io/imagedata/ImagePlusImageData.java new file mode 100644 index 00000000..7a38d5e2 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/ImagePlusImageData.java @@ -0,0 +1,73 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; +import ij.IJ; +import ij.ImagePlus; +import ij.plugin.ContrastEnhancer; +import ij.process.ImageStatistics; +import ij.process.LUT; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.janelia.saalfeldlab.n5.universe.metadata.RGBAColorMetadata; +import org.janelia.saalfeldlab.n5.universe.metadata.canonical.CanonicalDatasetMetadata; + +import java.io.IOException; + +import static ij.measure.Measurements.MIN_MAX; + +public class ImagePlusImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + private final ImagePlus imagePlus; + + public ImagePlusImageData( ImagePlus imagePlus, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws IOException + { + return ImagePlusToSpimData.getSpimData( imagePlus ); + } + } ); + + this.imagePlus = imagePlus; + this.sharedQueue = sharedQueue; + } + + @Override + public CanonicalDatasetMetadata getMetadata( int datasetIndex ) + { + if ( ! isOpen ) open( spimDataOpener, uri ); + + imagePlus.setC( datasetIndex + 1 ); + LUT lut = imagePlus.getLuts()[ datasetIndex ]; + + RGBAColorMetadata colorMetadata = new RGBAColorMetadata( + lut.getRed( 255 ), + lut.getGreen( 255 ), + lut.getBlue( 255 ), + lut.getAlpha( 255 ) ); + + try + { + ImageStatistics statistics = ImageStatistics.getStatistics( imagePlus.getProcessor(), MIN_MAX, null ); + new ContrastEnhancer().stretchHistogram( imagePlus.getProcessor(), 0.35, statistics ); + } + catch ( Exception e ) + { + // https://forum.image.sc/t/b-c-for-a-whole-virtual-stack-cont/57811/12 + IJ.log( "[WARNING] Could not set auto-contrast for + " + imagePlus.getTitle() + " + due to: https://forum.image.sc/t/b-c-for-a-whole-virtual-stack-cont/57811/12" ); + } + + return new CanonicalDatasetMetadata( + null, + null, + imagePlus.getProcessor().getMin(), + imagePlus.getProcessor().getMax(), + colorMetadata + ); + } + +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/ImarisImageData.java b/src/main/java/org/embl/mobie/io/imagedata/ImarisImageData.java new file mode 100644 index 00000000..edbd8a23 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/ImarisImageData.java @@ -0,0 +1,31 @@ +package org.embl.mobie.io.imagedata; + +import bdv.ViewerImgLoader; +import bdv.cache.SharedQueue; +import bdv.img.imaris.Imaris; +import mpicbg.spim.data.generic.AbstractSpimData; +import mpicbg.spim.data.generic.sequence.BasicImgLoader; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; + +import java.io.IOException; + +public class ImarisImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + + public ImarisImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws IOException + { + return Imaris.openIms( uri ); + } + } ); + + this.uri = uri; + this.sharedQueue = sharedQueue; + } + +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/N5ImageData.java b/src/main/java/org/embl/mobie/io/imagedata/N5ImageData.java new file mode 100644 index 00000000..e49e9475 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/N5ImageData.java @@ -0,0 +1,175 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import bdv.tools.brightness.ConverterSetup; +import bdv.util.BdvOptions; +import bdv.viewer.Source; +import bdv.viewer.SourceAndConverter; +import com.amazonaws.auth.BasicAWSCredentials; +import net.imglib2.Volatile; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Pair; +import net.imglib2.util.ValuePair; +import org.janelia.saalfeldlab.n5.*; +import org.janelia.saalfeldlab.n5.bdv.N5Viewer; +import org.janelia.saalfeldlab.n5.ui.DataSelection; +import org.janelia.saalfeldlab.n5.universe.N5Factory; +import org.janelia.saalfeldlab.n5.universe.N5MetadataUtils; +import org.janelia.saalfeldlab.n5.universe.metadata.IntColorMetadata; +import org.janelia.saalfeldlab.n5.universe.metadata.N5Metadata; +import org.janelia.saalfeldlab.n5.universe.metadata.canonical.CanonicalDatasetMetadata; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class N5ImageData< T extends NumericType< T > & NativeType< T > > implements ImageData< T > +{ + private final String uri; + private final SharedQueue sharedQueue; + private final String[] s3AccessAndSecretKey; + private boolean isOpen; + private List< SourceAndConverter< T > > sourcesAndConverters; + private int numTimepoints; + private BdvOptions bdvOptions; + private List< ConverterSetup > converterSetups; + + public N5ImageData( String uri ) + { + this.uri = uri; + this.sharedQueue = new SharedQueue( 1 ); + this.s3AccessAndSecretKey = null; + } + + public N5ImageData( String uri, String[] s3AccessAndSecretKey ) + { + this.uri = uri; + this.sharedQueue = new SharedQueue( 1 ); + this.s3AccessAndSecretKey = s3AccessAndSecretKey; + } + + public N5ImageData( String uri, SharedQueue sharedQueue ) + { + this.uri = uri; + this.sharedQueue = sharedQueue; + this.s3AccessAndSecretKey = null; + } + + public N5ImageData( String uri, SharedQueue sharedQueue, String[] s3AccessAndSecretKey ) + { + this.uri = uri; + this.sharedQueue = sharedQueue; + this.s3AccessAndSecretKey = s3AccessAndSecretKey; + } + + @Override + public Pair< Source< T >, Source< ? extends Volatile< T > > > getSourcePair( int datasetIndex ) + { + if ( !isOpen ) open(); + + SourceAndConverter< T > sourceAndConverter = sourcesAndConverters.get( datasetIndex ); + + Source< T > source = sourceAndConverter.getSpimSource(); + Source< ? extends Volatile< T > > vSource = sourceAndConverter.asVolatile().getSpimSource(); + + Pair< Source< T >, Source< ? extends Volatile< T > > > sourcePair = + new ValuePair<>( + source, + vSource ); + + return sourcePair; + } + + @Override + public int getNumDatasets() + { + if ( !isOpen ) open(); + + return sourcesAndConverters.size(); + } + + @Override + public CanonicalDatasetMetadata getMetadata( int datasetIndex ) + { + if ( !isOpen ) open(); + + ConverterSetup converterSetup = converterSetups.get( datasetIndex ); + + IntColorMetadata colorMetadata = new IntColorMetadata( converterSetup.getColor().get() ); + + return new CanonicalDatasetMetadata( + uri, + null, + converterSetup.getDisplayRangeMin(), + converterSetup.getDisplayRangeMax(), + colorMetadata + ); + } + + public List< SourceAndConverter< T > > getSourcesAndConverters() + { + if ( !isOpen ) open(); + + return sourcesAndConverters; + } + + public int getNumTimepoints() + { + return numTimepoints; + } + + public BdvOptions getBdvOptions() + { + return bdvOptions; + } + + private synchronized void open() + { + if ( isOpen ) return; + + try + { + N5URI n5URI = new N5URI( uri ); + String containerPath = n5URI.getContainerPath(); + + N5Factory n5Factory = new N5Factory(); + if( s3AccessAndSecretKey != null ) + { + BasicAWSCredentials credentials = new BasicAWSCredentials( s3AccessAndSecretKey[ 0 ], s3AccessAndSecretKey[ 1 ] ); + n5Factory = n5Factory.s3UseCredentials( credentials ); + } + + N5Reader n5 = n5Factory.openReader( containerPath ); + String group = n5URI.getGroupPath() != null ? n5URI.getGroupPath() : "/"; + List< N5Metadata > metadata = Collections.singletonList( N5MetadataUtils.parseMetadata( n5, group ) ); + + final DataSelection selection = new DataSelection( n5, metadata ); + converterSetups = new ArrayList<>(); + sourcesAndConverters = new ArrayList<>(); + bdvOptions = BdvOptions.options().frameTitle( "" ); + + numTimepoints = N5Viewer.buildN5Sources( + n5, + selection, + sharedQueue, + converterSetups, + sourcesAndConverters, + bdvOptions ); + + if ( sourcesAndConverters.size() == 0 ) + throw new IOException( "N5ImageData: No datasets found." ); + } + catch ( Exception e ) + { + System.err.println( "N5ImageData: Error opening " + uri ); + e.printStackTrace(); + throw new RuntimeException( e ); + } + + isOpen = true; + } + +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/SpimDataImageData.java b/src/main/java/org/embl/mobie/io/imagedata/SpimDataImageData.java new file mode 100644 index 00000000..b607a9d8 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/SpimDataImageData.java @@ -0,0 +1,147 @@ +package org.embl.mobie.io.imagedata; + +import bdv.SpimSource; +import bdv.ViewerImgLoader; +import bdv.VolatileSpimSource; +import bdv.cache.SharedQueue; +import bdv.img.cache.VolatileGlobalCellCache; +import bdv.viewer.Source; +import ch.epfl.biop.bdv.img.CacheControlOverride; +import mpicbg.spim.data.generic.AbstractSpimData; +import mpicbg.spim.data.generic.sequence.BasicImgLoader; +import mpicbg.spim.data.generic.sequence.BasicViewSetup; +import mpicbg.spim.data.sequence.Angle; +import mpicbg.spim.data.sequence.Channel; +import net.imglib2.Volatile; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Pair; +import net.imglib2.util.ValuePair; +import org.janelia.saalfeldlab.n5.universe.metadata.RGBAColorMetadata; +import org.janelia.saalfeldlab.n5.universe.metadata.canonical.CanonicalDatasetMetadata; +import spimdata.util.Displaysettings; + +import java.io.IOException; + +public class SpimDataImageData< T extends NumericType< T > & NativeType< T > > implements ImageData< T > +{ + protected String uri; + + protected AbstractSpimData< ? > spimData; + + protected SpimDataOpener spimDataOpener; + + protected SharedQueue sharedQueue; + + protected boolean isOpen; + + public SpimDataImageData( SpimDataOpener spimDataOpener ) + { + this.spimDataOpener = spimDataOpener; + } + + protected void setSharedQueue( SharedQueue sharedQueue ) + { + BasicImgLoader imgLoader = spimData.getSequenceDescription().getImgLoader(); + + if ( imgLoader instanceof CacheControlOverride ) + { + CacheControlOverride cco = ( CacheControlOverride ) imgLoader; + final VolatileGlobalCellCache volatileGlobalCellCache = new VolatileGlobalCellCache( sharedQueue ); + cco.setCacheControl( volatileGlobalCellCache ); + } + else if ( imgLoader instanceof ViewerImgLoader ) + { + ( ( ViewerImgLoader ) imgLoader ).setCreatedSharedQueue( sharedQueue ); + } + else + { + // cannot set the sharedQueue + } + } + + @Override + public Pair< Source< T >, Source< ? extends Volatile< T > > > getSourcePair( int datasetIndex ) + { + if ( ! isOpen ) open( spimDataOpener, uri ); + + BasicViewSetup basicViewSetup = spimData.getSequenceDescription().getViewSetupsOrdered().get( datasetIndex ); + final String setupName = createSetupName( basicViewSetup ); + Pair< Source< T >, Source< ? extends Volatile< T > > > sourcePair = + new ValuePair<>( + new SpimSource<>( spimData, datasetIndex, setupName ), + new VolatileSpimSource<>( spimData, datasetIndex, setupName )); + + return sourcePair; + } + + @Override + public int getNumDatasets() + { + if ( ! isOpen ) open( spimDataOpener, uri ); + + return spimData.getSequenceDescription().getViewSetupsOrdered().size(); + } + + @Override + public CanonicalDatasetMetadata getMetadata( int datasetIndex ) + { + if ( ! isOpen ) open( spimDataOpener, uri ); + + try + { + // Using bigdataviewer-spimdata-extras + final Displaysettings displaysettings = spimData.getSequenceDescription().getViewSetupsOrdered().get( datasetIndex ).getAttribute( Displaysettings.class ); + + int[] color = displaysettings.color; + RGBAColorMetadata colorMetadata = new RGBAColorMetadata( color[ 0 ], color[ 1 ], color[ 2 ], color[ 3 ] ); + + return new CanonicalDatasetMetadata( + uri, + null, + displaysettings.min, + displaysettings.max, + colorMetadata + ); + } + catch ( Exception e ) + { + return null; + } + } + + protected synchronized void open( SpimDataOpener opener, String uri ) + { + if ( isOpen ) return; + + try + { + spimData = opener.open( uri ); + setSharedQueue( sharedQueue ); + isOpen = true; + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + + private static String createSetupName( final BasicViewSetup setup ) + { + if ( setup.hasName() ) + return setup.getName(); + + String name = ""; + + final Angle angle = setup.getAttribute( Angle.class ); + if ( angle != null ) + name += ( name.isEmpty() ? "" : " " ) + "a " + angle.getName(); + + final Channel channel = setup.getAttribute( Channel.class ); + if ( channel != null ) + name += ( name.isEmpty() ? "" : " " ) + "c " + channel.getName(); + + return name; + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/SpimDataOpener.java b/src/main/java/org/embl/mobie/io/imagedata/SpimDataOpener.java new file mode 100644 index 00000000..e67e653f --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/SpimDataOpener.java @@ -0,0 +1,10 @@ +package org.embl.mobie.io.imagedata; + +import mpicbg.spim.data.generic.AbstractSpimData; + +import java.io.IOException; + +public interface SpimDataOpener +{ + AbstractSpimData open( String uri ) throws Exception; +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/TIFFImageData.java b/src/main/java/org/embl/mobie/io/imagedata/TIFFImageData.java new file mode 100644 index 00000000..b995cb7b --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/TIFFImageData.java @@ -0,0 +1,30 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; +import ij.ImagePlus; +import mpicbg.spim.data.SpimData; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.embl.mobie.io.util.IOHelper; + +public class TIFFImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + public TIFFImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData< ? > open( String uri ) + { + ImagePlus imagePlus = IOHelper.openTiffFromFile( uri ); + return ImagePlusToSpimData.getSpimData( imagePlus ); + } + } ); + + this.uri = uri; + this.sharedQueue = sharedQueue; + + } +} diff --git a/src/main/java/org/embl/mobie/io/imagedata/TOMLImageData.java b/src/main/java/org/embl/mobie/io/imagedata/TOMLImageData.java new file mode 100644 index 00000000..969d969c --- /dev/null +++ b/src/main/java/org/embl/mobie/io/imagedata/TOMLImageData.java @@ -0,0 +1,27 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; +import ij.ImagePlus; +import mpicbg.spim.data.generic.AbstractSpimData; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.embl.mobie.io.toml.TOMLOpener; + +public class TOMLImageData< T extends NumericType< T > & NativeType< T > > extends SpimDataImageData< T > +{ + public TOMLImageData( String uri, SharedQueue sharedQueue ) + { + super( new SpimDataOpener() + { + @Override + public AbstractSpimData open( String uri ) throws Exception + { + ImagePlus imagePlus = new TOMLOpener( uri ).openImagePlus();; + return ImagePlusToSpimData.getSpimData( imagePlus ); + } + } ); + this.uri = uri; + this.sharedQueue = sharedQueue; + } +} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/N5FSImageLoader.java b/src/main/java/org/embl/mobie/io/n5/loaders/N5FSImageLoader.java deleted file mode 100644 index 1125a7e4..00000000 --- a/src/main/java/org/embl/mobie/io/n5/loaders/N5FSImageLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.loaders; - -import java.io.File; -import java.io.IOException; - -import org.janelia.saalfeldlab.n5.N5FSReader; - -import bdv.cache.SharedQueue; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; - -public class N5FSImageLoader extends N5ImageLoader { - private final File n5File; - - public N5FSImageLoader(final File n5File, final AbstractSequenceDescription sequenceDescription) throws IOException { - super(new N5FSReader(n5File.getAbsolutePath()), sequenceDescription); - this.n5File = n5File; - } - - public N5FSImageLoader(final File n5File, final AbstractSequenceDescription sequenceDescription, SharedQueue sharedQueue) throws IOException { - super(new N5FSReader(n5File.getAbsolutePath()), sequenceDescription, sharedQueue); - this.n5File = n5File; - } - - public File getN5File() { - return n5File; - } - -} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/N5ImageLoader.java b/src/main/java/org/embl/mobie/io/n5/loaders/N5ImageLoader.java deleted file mode 100644 index 53ffd6c1..00000000 --- a/src/main/java/org/embl/mobie/io/n5/loaders/N5ImageLoader.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.loaders; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.function.Function; - -import net.imglib2.img.basictypeaccess.DataAccess; -import org.embl.mobie.io.ome.zarr.util.OmeZarrMultiscales; -import org.janelia.saalfeldlab.n5.ByteArrayDataBlock; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.DoubleArrayDataBlock; -import org.janelia.saalfeldlab.n5.FloatArrayDataBlock; -import org.janelia.saalfeldlab.n5.IntArrayDataBlock; -import org.janelia.saalfeldlab.n5.LongArrayDataBlock; -import org.janelia.saalfeldlab.n5.N5Reader; -import org.janelia.saalfeldlab.n5.ShortArrayDataBlock; -import org.jdom2.Element; - -import bdv.AbstractViewerSetupImgLoader; -import bdv.ViewerImgLoader; -import bdv.cache.CacheControl; -import bdv.img.cache.SimpleCacheArrayLoader; -import bdv.img.cache.VolatileGlobalCellCache; -import bdv.util.ConstantRandomAccessible; -import bdv.util.MipmapTransforms; - -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.generic.sequence.ImgLoaderHint; -import mpicbg.spim.data.registration.ViewRegistrations; -import mpicbg.spim.data.sequence.MultiResolutionImgLoader; -import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; -import mpicbg.spim.data.sequence.SequenceDescription; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.FinalInterval; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; -import net.imglib2.cache.queue.BlockingFetchQueues; -import net.imglib2.cache.queue.FetcherThreads; -import net.imglib2.cache.volatiles.CacheHints; -import net.imglib2.cache.volatiles.LoadingStrategy; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileByteArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileDoubleArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileFloatArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileLongArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.img.cell.CellImg; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.integer.ByteType; -import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.LongType; -import net.imglib2.type.numeric.integer.ShortType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import net.imglib2.type.numeric.integer.UnsignedIntType; -import net.imglib2.type.numeric.integer.UnsignedLongType; -import net.imglib2.type.numeric.integer.UnsignedShortType; -import net.imglib2.type.numeric.real.DoubleType; -import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.type.volatiles.VolatileByteType; -import net.imglib2.type.volatiles.VolatileDoubleType; -import net.imglib2.type.volatiles.VolatileFloatType; -import net.imglib2.type.volatiles.VolatileIntType; -import net.imglib2.type.volatiles.VolatileLongType; -import net.imglib2.type.volatiles.VolatileShortType; -import net.imglib2.type.volatiles.VolatileUnsignedByteType; -import net.imglib2.type.volatiles.VolatileUnsignedIntType; -import net.imglib2.type.volatiles.VolatileUnsignedLongType; -import net.imglib2.type.volatiles.VolatileUnsignedShortType; -import net.imglib2.util.Cast; -import net.imglib2.view.Views; - -import static bdv.img.n5.BdvN5Format.DATA_TYPE_KEY; -import static bdv.img.n5.BdvN5Format.DOWNSAMPLING_FACTORS_KEY; -import static bdv.img.n5.BdvN5Format.getPathName; -import static mpicbg.spim.data.XmlKeys.BASEPATH_TAG; - - -public class N5ImageLoader implements ViewerImgLoader, MultiResolutionImgLoader { - protected final N5Reader n5; - /** - * Maps setup id to {@link SetupImgLoader}. - */ - private final Map setupImgLoaders = new HashMap<>(); - // TODO: it would be good if this would not be needed - // find available setups from the n5 - protected AbstractSequenceDescription seq; - protected ViewRegistrations viewRegistrations; - private volatile boolean isOpen = false; - private FetcherThreads fetchers; - private VolatileGlobalCellCache cache; - private BlockingFetchQueues> queue; - - - public N5ImageLoader(N5Reader n5Reader, AbstractSequenceDescription sequenceDescription) { - this.n5 = n5Reader; - this.seq = sequenceDescription; - } - - public N5ImageLoader(N5Reader n5Reader, AbstractSequenceDescription sequenceDescription, BlockingFetchQueues> queue) { - this.n5 = n5Reader; - this.seq = sequenceDescription; - this.queue = queue; - } - - private static File loadBasePath(final Element root, final File xmlFile) { - File xmlFileParentDirectory = xmlFile.getParentFile(); - if (xmlFileParentDirectory == null) - xmlFileParentDirectory = new File("."); - return XmlHelpers.loadPath(root, BASEPATH_TAG, ".", xmlFileParentDirectory); - } - - public static SimpleCacheArrayLoader createCacheArrayLoader(final N5Reader n5, final String pathName) throws IOException { - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - switch (attributes.getDataType()) { - case UINT8: - case INT8: - return new N5CacheArrayLoader<>(n5, pathName, attributes, - dataBlock -> new VolatileByteArray(Cast.unchecked(dataBlock.getData()), true)); - case UINT16: - case INT16: - return new N5CacheArrayLoader<>(n5, pathName, attributes, - dataBlock -> new VolatileShortArray(Cast.unchecked(dataBlock.getData()), true)); - case UINT32: - case INT32: - return new N5CacheArrayLoader<>(n5, pathName, attributes, - dataBlock -> new VolatileIntArray(Cast.unchecked(dataBlock.getData()), true)); - case UINT64: - case INT64: - return new N5CacheArrayLoader<>(n5, pathName, attributes, - dataBlock -> new VolatileLongArray(Cast.unchecked(dataBlock.getData()), true)); - case FLOAT32: - return new N5CacheArrayLoader<>(n5, pathName, attributes, - dataBlock -> new VolatileFloatArray(Cast.unchecked(dataBlock.getData()), true)); - case FLOAT64: - return new N5CacheArrayLoader<>(n5, pathName, attributes, - dataBlock -> new VolatileDoubleArray(Cast.unchecked(dataBlock.getData()), true)); - default: - throw new IllegalArgumentException(); - } - } - - public AbstractSequenceDescription getSequenceDescription() { - //open(); - seq.setImgLoader(Cast.unchecked(this)); - return seq; - } - - public ViewRegistrations getViewRegistrations() { - return viewRegistrations; - } - - public void setViewRegistrations(ViewRegistrations viewRegistrations) { - this.viewRegistrations = viewRegistrations; - } - - private DatasetAttributes getDatasetAttributes(String pathName) throws IOException { - return n5.getDatasetAttributes(pathName); - } - - public void setSeq(SequenceDescription seq) { - this.seq = seq; - } - - private void open() { - if (!isOpen) { - synchronized (this) { - if (isOpen) - return; - - try { - int maxNumLevels = 0; - final List setups = seq.getViewSetupsOrdered(); - for (final BasicViewSetup setup : setups) { - final int setupId = setup.getId(); - final SetupImgLoader setupImgLoader = createSetupImgLoader(setupId); - setupImgLoaders.put(setupId, setupImgLoader); - if (setupImgLoader != null) { - maxNumLevels = Math.max(maxNumLevels, setupImgLoader.numMipmapLevels()); - } - } - if (queue == null) { - final int numFetcherThreads = Math.max(1, Runtime.getRuntime().availableProcessors()); - queue = new BlockingFetchQueues<>(maxNumLevels, numFetcherThreads); - fetchers = new FetcherThreads(queue, numFetcherThreads); - } - cache = new VolatileGlobalCellCache(queue); - } catch (IOException e) { - throw new RuntimeException(e); - } - - isOpen = true; - } - } - } - - private String readName(OmeZarrMultiscales multiscale, int setupId) { - if (multiscale.name != null) - return multiscale.name; - else - return "image " + setupId; - } - - /** - * Clear the cache. Images that were obtained from - * this loader before {@link #close()} will stop working. Requesting images - * after {@link #close()} will cause the n5 to be reopened (with a - * new cache). - */ - public void close() { - if (isOpen) { - synchronized (this) { - if (!isOpen) - return; - if (fetchers != null) - fetchers.shutdown(); - cache.clearCache(); - isOpen = false; - } - } - } - - @Override - public SetupImgLoader getSetupImgLoader(final int setupId) { - open(); - return setupImgLoaders.get(setupId); - } - - private , V extends Volatile & NativeType> SetupImgLoader createSetupImgLoader(final int setupId) throws IOException { - final String pathName = getPathName(setupId); - final DataType dataType = n5.getAttribute(pathName, DATA_TYPE_KEY, DataType.class); - switch (dataType) { - case UINT8: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedByteType(), new VolatileUnsignedByteType())); - case UINT16: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedShortType(), new VolatileUnsignedShortType())); - case UINT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedIntType(), new VolatileUnsignedIntType())); - case UINT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedLongType(), new VolatileUnsignedLongType())); - case INT8: - return Cast.unchecked(new SetupImgLoader<>(setupId, new ByteType(), new VolatileByteType())); - case INT16: - return Cast.unchecked(new SetupImgLoader<>(setupId, new ShortType(), new VolatileShortType())); - case INT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new IntType(), new VolatileIntType())); - case INT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new LongType(), new VolatileLongType())); - case FLOAT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new FloatType(), new VolatileFloatType())); - case FLOAT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new DoubleType(), new VolatileDoubleType())); - } - return null; - } - - @Override - public CacheControl getCacheControl() { - open(); - return cache; - } - - private static class N5CacheArrayLoader implements SimpleCacheArrayLoader { - private final N5Reader n5; - private final String pathName; - private final DatasetAttributes attributes; - private final Function, A> createArray; - - N5CacheArrayLoader(final N5Reader n5, final String pathName, final DatasetAttributes attributes, final Function, A> createArray) { - this.n5 = n5; - this.pathName = pathName; - this.attributes = attributes; - this.createArray = createArray; - } - - @Override - public A loadArray(final long[] gridPosition, int[] cellDimensions) throws IOException { - DataBlock block = null; - - try { - block = n5.readBlock(pathName, attributes, gridPosition); - } catch (Exception e) { - System.err.println("Error loading " + pathName + " at block " + Arrays.toString(gridPosition) + ": " + e); - } - -// if ( block != null ) -// System.out.println( pathName + " " + Arrays.toString( gridPosition ) + " " + block.getNumElements() ); -// else -// System.out.println( pathName + " " + Arrays.toString( gridPosition ) + " NaN" ); - - - if (block == null) { - final int[] blockSize = attributes.getBlockSize(); - final int n = blockSize[0] * blockSize[1] * blockSize[2]; - switch (attributes.getDataType()) { - case UINT8: - case INT8: - return createArray.apply(new ByteArrayDataBlock(blockSize, gridPosition, new byte[n])); - case UINT16: - case INT16: - return createArray.apply(new ShortArrayDataBlock(blockSize, gridPosition, new short[n])); - case UINT32: - case INT32: - return createArray.apply(new IntArrayDataBlock(blockSize, gridPosition, new int[n])); - case UINT64: - case INT64: - return createArray.apply(new LongArrayDataBlock(blockSize, gridPosition, new long[n])); - case FLOAT32: - return createArray.apply(new FloatArrayDataBlock(blockSize, gridPosition, new float[n])); - case FLOAT64: - return createArray.apply(new DoubleArrayDataBlock(blockSize, gridPosition, new double[n])); - default: - throw new IllegalArgumentException(); - } - } else { - return createArray.apply(block); - } - } - } - - public class SetupImgLoader, V extends Volatile & NativeType> - extends AbstractViewerSetupImgLoader - implements MultiResolutionSetupImgLoader { - private final int setupId; - - private final double[][] mipmapResolutions; - - private final AffineTransform3D[] mipmapTransforms; - - public SetupImgLoader(final int setupId, final T type, final V volatileType) throws IOException { - super(type, volatileType); - this.setupId = setupId; - final String pathName = getPathName(setupId); - mipmapResolutions = n5.getAttribute(pathName, DOWNSAMPLING_FACTORS_KEY, double[][].class); - mipmapTransforms = new AffineTransform3D[mipmapResolutions.length]; - for (int level = 0; level < mipmapResolutions.length; level++) - mipmapTransforms[level] = MipmapTransforms.getMipmapTransformDefault(mipmapResolutions[level]); - } - - @Override - public RandomAccessibleInterval getVolatileImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BUDGETED, volatileType); - } - - @Override - public RandomAccessibleInterval getImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BLOCKING, type); - } - - @Override - public Dimensions getImageSize(final int timepointId, final int level) { - try { - final String pathName = getPathName(setupId, timepointId, level); - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - FinalDimensions dimensions = new FinalDimensions(attributes.getDimensions()); - return dimensions; - } catch (Exception e) { - return null; - } - } - - @Override - public double[][] getMipmapResolutions() { - return mipmapResolutions; - } - - @Override - public AffineTransform3D[] getMipmapTransforms() { - return mipmapTransforms; - } - - @Override - public int numMipmapLevels() { - return mipmapResolutions.length; - } - - @Override - public VoxelDimensions getVoxelSize(final int timepointId) { - return null; - } - - /** - * Create a {@link CellImg} backed by the cache. - */ - private > RandomAccessibleInterval prepareCachedImage(final int timepointId, final int level, final LoadingStrategy loadingStrategy, final T type) { - try { - final String pathName = getPathName(setupId, timepointId, level); - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - final long[] dimensions = attributes.getDimensions(); - final int[] cellDimensions = attributes.getBlockSize(); - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - - final int priority = numMipmapLevels() - 1 - level; - final CacheHints cacheHints = new CacheHints(loadingStrategy, priority, false); - - final SimpleCacheArrayLoader loader = createCacheArrayLoader(n5, pathName); - return cache.createImg(grid, timepointId, setupId, level, cacheHints, loader, type); - } catch (IOException e) { - System.err.println(String.format( - "image data for timepoint %d setup %d level %d could not be found.", - timepointId, setupId, level)); - return Views.interval( - new ConstantRandomAccessible<>(type.createVariable(), 3), - new FinalInterval(1, 1, 1)); - } - } - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/N5S3ImageLoader.java b/src/main/java/org/embl/mobie/io/n5/loaders/N5S3ImageLoader.java deleted file mode 100644 index b1b78e44..00000000 --- a/src/main/java/org/embl/mobie/io/n5/loaders/N5S3ImageLoader.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.loaders; - -import java.io.IOException; - -import org.embl.mobie.io.util.S3Utils; -import org.janelia.saalfeldlab.n5.s3.N5AmazonS3Reader; - -import com.amazonaws.services.s3.AmazonS3; - -import bdv.cache.SharedQueue; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; - -public class N5S3ImageLoader extends N5ImageLoader implements S3ImageLoader { - private final String serviceEndpoint; - private final String signingRegion; - private final String bucketName; - private final String key; - - public N5S3ImageLoader(String serviceEndpoint, String signingRegion, String bucketName, String key, AbstractSequenceDescription sequenceDescription) throws IOException { - super(new N5S3ImageLoader.N5AmazonS3ReaderCreator().create(serviceEndpoint, signingRegion, bucketName, key), sequenceDescription); - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - public N5S3ImageLoader(String serviceEndpoint, String signingRegion, String bucketName, String key, AbstractSequenceDescription sequenceDescription, SharedQueue sharedQueue) throws IOException { - super(new N5S3ImageLoader.N5AmazonS3ReaderCreator().create(serviceEndpoint, signingRegion, bucketName, key), sequenceDescription, sharedQueue); - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - public String getServiceEndpoint() { - return serviceEndpoint; - } - - public String getSigningRegion() { - return signingRegion; - } - - public String getBucketName() { - return bucketName; - } - - public String getKey() { - return key; - } - - static class N5AmazonS3ReaderCreator { - - public N5AmazonS3Reader create(String serviceEndpoint, String signingRegion, String bucketName, String key) throws IOException { - final AmazonS3 s3 = S3Utils.getS3Client(serviceEndpoint, signingRegion, bucketName); - return new N5AmazonS3Reader(s3, bucketName, key); - } - } - -} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/S3ImageLoader.java b/src/main/java/org/embl/mobie/io/n5/loaders/S3ImageLoader.java deleted file mode 100644 index be97ae41..00000000 --- a/src/main/java/org/embl/mobie/io/n5/loaders/S3ImageLoader.java +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.loaders; - -public interface S3ImageLoader { - - String getServiceEndpoint(); - - String getSigningRegion(); - - String getBucketName(); - - String getKey(); -} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/SetupImgLoader.java b/src/main/java/org/embl/mobie/io/n5/loaders/SetupImgLoader.java deleted file mode 100644 index c7faf94d..00000000 --- a/src/main/java/org/embl/mobie/io/n5/loaders/SetupImgLoader.java +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.loaders; - -import java.io.IOException; - -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5Reader; - -import bdv.AbstractViewerSetupImgLoader; -import bdv.img.cache.SimpleCacheArrayLoader; -import bdv.img.cache.VolatileGlobalCellCache; -import bdv.util.ConstantRandomAccessible; -import bdv.util.MipmapTransforms; - -import mpicbg.spim.data.generic.sequence.ImgLoaderHint; -import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.FinalInterval; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; -import net.imglib2.cache.volatiles.CacheHints; -import net.imglib2.cache.volatiles.LoadingStrategy; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.img.cell.CellImg; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.type.NativeType; -import net.imglib2.view.Views; - -import static bdv.img.n5.BdvN5Format.DOWNSAMPLING_FACTORS_KEY; -import static bdv.img.n5.BdvN5Format.getPathName; - - -public class SetupImgLoader, V extends Volatile & NativeType> - extends AbstractViewerSetupImgLoader - implements MultiResolutionSetupImgLoader { - private final int setupId; - private final double[][] mipmapResolutions; - private final AffineTransform3D[] mipmapTransforms; - protected N5Reader n5; - private VolatileGlobalCellCache cache; - - public SetupImgLoader(final int setupId, final T type, final V volatileType, N5Reader n5, VolatileGlobalCellCache cache) throws IOException { - super(type, volatileType); - this.n5 = n5; - this.cache = cache; - this.setupId = setupId; - final String pathName = getPathName(setupId); - mipmapResolutions = n5.getAttribute(pathName, DOWNSAMPLING_FACTORS_KEY, double[][].class); - mipmapTransforms = new AffineTransform3D[mipmapResolutions.length]; - for (int level = 0; level < mipmapResolutions.length; level++) - mipmapTransforms[level] = MipmapTransforms.getMipmapTransformDefault(mipmapResolutions[level]); - } - - @Override - public RandomAccessibleInterval getVolatileImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BUDGETED, volatileType); - } - - @Override - public RandomAccessibleInterval getImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BLOCKING, type); - } - - @Override - public Dimensions getImageSize(final int timepointId, final int level) { - try { - final String pathName = getPathName(setupId, timepointId, level); - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - return new FinalDimensions(attributes.getDimensions()); - } catch (Exception e) { - return null; - } - } - - @Override - public double[][] getMipmapResolutions() { - return mipmapResolutions; - } - - @Override - public AffineTransform3D[] getMipmapTransforms() { - return mipmapTransforms; - } - - @Override - public int numMipmapLevels() { - return mipmapResolutions.length; - } - - @Override - public VoxelDimensions getVoxelSize(final int timepointId) { - return null; - } - - /** - * Create a {@link CellImg} backed by the cache. - */ - private > RandomAccessibleInterval prepareCachedImage(final int timepointId, final int level, final LoadingStrategy loadingStrategy, final N type) { - try { - final String pathName = getPathName(setupId, timepointId, level); - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - final long[] dimensions = attributes.getDimensions(); - final int[] cellDimensions = attributes.getBlockSize(); - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - - final int priority = numMipmapLevels() - 1 - level; - final CacheHints cacheHints = new CacheHints(loadingStrategy, priority, false); - - final SimpleCacheArrayLoader loader = N5ImageLoader.createCacheArrayLoader(n5, pathName); - return cache.createImg(grid, timepointId, setupId, level, cacheHints, loader, type); - } catch (IOException e) { - System.err.println(String.format( - "image data for timepoint %d setup %d level %d could not be found.%n", - timepointId, setupId, level)); - return Views.interval( - new ConstantRandomAccessible<>(type.createVariable(), 3), - new FinalInterval(1, 1, 1)); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/xml/XmlIoN5FSImageLoader.java b/src/main/java/org/embl/mobie/io/n5/loaders/xml/XmlIoN5FSImageLoader.java deleted file mode 100644 index d72a7dd1..00000000 --- a/src/main/java/org/embl/mobie/io/n5/loaders/xml/XmlIoN5FSImageLoader.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.loaders.xml; - -import java.io.File; -import java.io.IOException; - -import org.embl.mobie.io.n5.loaders.N5FSImageLoader; -import org.jdom2.Element; - -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.ImgLoaderIo; -import mpicbg.spim.data.generic.sequence.XmlIoBasicImgLoader; - -import static mpicbg.spim.data.XmlHelpers.loadPath; -import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; - -@ImgLoaderIo(format = "bdv.n5", type = N5FSImageLoader.class) -public class XmlIoN5FSImageLoader implements XmlIoBasicImgLoader { - public static final String N5 = "n5"; - - @Override - public Element toXml(final N5FSImageLoader imgLoader, final File basePath) { - final Element elem = new Element("ImageLoader"); - elem.setAttribute(IMGLOADER_FORMAT_ATTRIBUTE_NAME, "bdv.n5"); - elem.setAttribute("version", "1.0"); - elem.addContent(XmlHelpers.pathElement(N5, imgLoader.getN5File(), basePath)); - return elem; - } - - @Override - public N5FSImageLoader fromXml(final Element elem, final File basePath, final AbstractSequenceDescription sequenceDescription) { -// final String version = elem.getAttributeValue( "version" ); - final File path = loadPath(elem, N5, basePath); - try { - return new N5FSImageLoader(path, sequenceDescription); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/openers/N5Opener.java b/src/main/java/org/embl/mobie/io/n5/openers/N5Opener.java deleted file mode 100644 index 584ff38d..00000000 --- a/src/main/java/org/embl/mobie/io/n5/openers/N5Opener.java +++ /dev/null @@ -1,166 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.openers; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.embl.mobie.io.OpenerLogging; -import org.embl.mobie.io.n5.loaders.N5FSImageLoader; -import org.embl.mobie.io.util.IOHelper; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; -import org.jdom2.input.SAXBuilder; - -import bdv.cache.SharedQueue; -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.registration.ViewRegistration; -import mpicbg.spim.data.registration.ViewRegistrations; -import mpicbg.spim.data.sequence.Angle; -import mpicbg.spim.data.sequence.Channel; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import mpicbg.spim.data.sequence.Illumination; -import mpicbg.spim.data.sequence.MissingViews; -import mpicbg.spim.data.sequence.SequenceDescription; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.TimePoints; -import mpicbg.spim.data.sequence.ViewSetup; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.util.Cast; - -public class N5Opener extends OpenerLogging -{ - private final String filePath; - - public N5Opener(String filePath) { - this.filePath = filePath; - } - - public static SpimData openFile(String filePath, SharedQueue sharedQueue) throws IOException { - N5Opener omeZarrOpener = new N5Opener(filePath); - return omeZarrOpener.setSettings(filePath, sharedQueue); - } - - private static Map createViewSetupsFromXml(final Element sequenceDescription) { - final HashMap setups = new HashMap<>(); - final HashMap channels = new HashMap<>(); - Element viewSetups = sequenceDescription.getChild("ViewSetups"); - - for (final Element elem : viewSetups.getChildren("ViewSetup")) { - final int id = XmlHelpers.getInt(elem, "id"); - int angleId = 0; - Angle angle = new Angle(angleId); - Channel channel = new Channel(angleId); - Illumination illumination = new Illumination(angleId); - try { - final int channelId = XmlHelpers.getInt(elem, "channel"); - channel = channels.get(channelId); - if (channel == null) { - channel = new Channel(channelId); - channels.put(channelId, channel); - } - } catch (NumberFormatException e) { - } - try { - final String sizeString = elem.getChildText("size"); - final String name = elem.getChildText("name"); - final String[] values = sizeString.split(" "); - final Dimensions size = new FinalDimensions(Integer.parseInt(values[0]), Integer.parseInt(values[1]), Integer.parseInt(values[2])); - final String[] voxelValues = elem.getChild("voxelSize").getChildText("size").split(" "); - final String unit = elem.getChild("voxelSize").getChildText("unit"); - final VoxelDimensions voxelSize = new FinalVoxelDimensions(unit, - Double.parseDouble(voxelValues[0]), - Double.parseDouble(voxelValues[1]), - Double.parseDouble(voxelValues[2])); - final ViewSetup setup = new ViewSetup(id, name, size, voxelSize, channel, angle, illumination); - setups.put(id, setup); - } catch (Exception e) { - System.out.println("No pixel parameters specified"); - } - } - return setups; - } - - private static TimePoints createTimepointsFromXml(final Element sequenceDescription) { - final Element timepoints = sequenceDescription.getChild("Timepoints"); - final String type = timepoints.getAttributeValue("type"); - if (type.equals("range")) { - final int first = Integer.parseInt(timepoints.getChildText("first")); - final int last = Integer.parseInt(timepoints.getChildText("last")); - final ArrayList tps = new ArrayList<>(); - for (int i = first, t = 0; i <= last; ++i, ++t) - tps.add(new TimePoint(t)); - return new TimePoints(tps); - } else { - throw new RuntimeException("unknown type: " + type); - } - } - - public SpimData setSettings(String url, SharedQueue sharedQueue) throws IOException { - final SAXBuilder sax = new SAXBuilder(); - Document doc; - try { - doc = sax.build(IOHelper.getInputStream(url)); - final Element root = doc.getRootElement(); - final Element sequenceDescriptionElement = root.getChild("SequenceDescription"); - final Element imageLoaderElement = sequenceDescriptionElement.getChild("ImageLoader"); - final TimePoints timepoints = createTimepointsFromXml(sequenceDescriptionElement); - final Map setups = createViewSetupsFromXml(sequenceDescriptionElement); - final MissingViews missingViews = null; - final Element viewRegistrations = root.getChild("ViewRegistrations"); - final ArrayList regs = new ArrayList<>(); - for (final Element vr : viewRegistrations.getChildren("ViewRegistration")) { - final int timepointId = Integer.parseInt(vr.getAttributeValue("timepoint")); - final int setupId = Integer.parseInt(vr.getAttributeValue("setup")); - final AffineTransform3D transform = new AffineTransform3D(); - transform.set(XmlHelpers.getDoubleArray(vr.getChild("ViewTransform"), "affine")); - regs.add(new ViewRegistration(timepointId, setupId, transform)); - } - SequenceDescription sequenceDescription = new SequenceDescription(timepoints, setups, null, missingViews); - File xmlFile = new File(filePath); - String imageLoaderPath = xmlFile.getParent() + "/" + imageLoaderElement.getChildText("n5"); - N5FSImageLoader imageLoader = new N5FSImageLoader(new File(imageLoaderPath), sequenceDescription, sharedQueue); - sequenceDescription.setImgLoader(imageLoader); - imageLoader.setViewRegistrations(new ViewRegistrations(regs)); - imageLoader.setSeq(sequenceDescription); - return new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); - } catch (JDOMException e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/openers/N5S3Opener.java b/src/main/java/org/embl/mobie/io/n5/openers/N5S3Opener.java deleted file mode 100644 index ef8e5cd9..00000000 --- a/src/main/java/org/embl/mobie/io/n5/openers/N5S3Opener.java +++ /dev/null @@ -1,174 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.openers; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.embl.mobie.io.n5.loaders.N5S3ImageLoader; -import org.embl.mobie.io.util.IOHelper; -import org.jdom2.Document; -import org.jdom2.Element; -import org.jdom2.JDOMException; -import org.jdom2.input.SAXBuilder; - -import bdv.cache.SharedQueue; - -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.registration.ViewRegistration; -import mpicbg.spim.data.registration.ViewRegistrations; -import mpicbg.spim.data.sequence.Angle; -import mpicbg.spim.data.sequence.Channel; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import mpicbg.spim.data.sequence.Illumination; -import mpicbg.spim.data.sequence.MissingViews; -import mpicbg.spim.data.sequence.SequenceDescription; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.TimePoints; -import mpicbg.spim.data.sequence.ViewSetup; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.util.Cast; - - -public class N5S3Opener extends S3Opener { - public static final String SERVICE_ENDPOINT = "ServiceEndpoint"; - public static final String SIGNING_REGION = "SigningRegion"; - public static final String BUCKET_NAME = "BucketName"; - public static final String KEY = "Key"; - - public N5S3Opener(String url) { - super(url); - } - - public static SpimData readURL(String url, SharedQueue sharedQueue) throws IOException { - final N5S3Opener reader = new N5S3Opener(url); - return reader.readURLData(url, sharedQueue); - } - - private static TimePoints createTimepointsFromXml(final Element sequenceDescription) { - final Element timepoints = sequenceDescription.getChild("Timepoints"); - final String type = timepoints.getAttributeValue("type"); - if (type.equals("range")) { - final int first = Integer.parseInt(timepoints.getChildText("first")); - final int last = Integer.parseInt(timepoints.getChildText("last")); - final ArrayList tps = new ArrayList<>(); - for (int i = first, t = 0; i <= last; ++i, ++t) - tps.add(new TimePoint(t)); - return new TimePoints(tps); - } else { - throw new RuntimeException("unknown type: " + type); - } - } - - private static Map createViewSetupsFromXml(final Element sequenceDescription) { - final HashMap setups = new HashMap<>(); - final HashMap channels = new HashMap<>(); - Element viewSetups = sequenceDescription.getChild("ViewSetups"); - - for (final Element elem : viewSetups.getChildren("ViewSetup")) { - final int id = XmlHelpers.getInt(elem, "id"); - int angleId = 0; - Angle angle = new Angle(angleId); - Channel channel = new Channel(angleId); - Illumination illumination = new Illumination(angleId); - try { - final int channelId = XmlHelpers.getInt(elem, "channel"); - channel = channels.get(channelId); - if (channel == null) { - channel = new Channel(channelId); - channels.put(channelId, channel); - } - } catch (NumberFormatException e) { - if (logging) { - System.out.println("No channel specified"); - } - } - try { - final String sizeString = elem.getChildText("size"); - final String name = elem.getChildText("name"); - final String[] values = sizeString.split(" "); - final Dimensions size = new FinalDimensions(Integer.parseInt(values[0]), Integer.parseInt(values[1]), Integer.parseInt(values[2])); - final String[] voxelValues = elem.getChild("voxelSize").getChildText("size").split(" "); - final String unit = elem.getChild("voxelSize").getChildText("unit"); - final VoxelDimensions voxelSize = new FinalVoxelDimensions(unit, - Double.parseDouble(voxelValues[0]), - Double.parseDouble(voxelValues[1]), - Double.parseDouble(voxelValues[2])); - final ViewSetup setup = new ViewSetup(id, name, size, voxelSize, channel, angle, illumination); - setups.put(id, setup); - } catch (Exception e) { - System.out.println("No pixel parameters specified"); - } - } - return setups; - } - - public SpimData readURLData(String url, SharedQueue sharedQueue) throws IOException { - InputStream stream = IOHelper.getInputStream(url); - final SAXBuilder sax = new SAXBuilder(); - try { - Document doc = sax.build(stream); - final Element root = doc.getRootElement(); - final Element sequenceDescriptionElement = root.getChild("SequenceDescription"); - final Element elem = sequenceDescriptionElement.getChild("ImageLoader"); - final String serviceEndpoint = XmlHelpers.getText(elem, SERVICE_ENDPOINT); - final String signingRegion = XmlHelpers.getText(elem, SIGNING_REGION); - final String bucketName = XmlHelpers.getText(elem, BUCKET_NAME); - final String key = XmlHelpers.getText(elem, KEY); - final TimePoints timepoints = createTimepointsFromXml(sequenceDescriptionElement); - final Map setups = createViewSetupsFromXml(sequenceDescriptionElement); - final MissingViews missingViews = null; - final Element viewRegistrations = root.getChild("ViewRegistrations"); - final ArrayList regs = new ArrayList<>(); - for (final Element vr : viewRegistrations.getChildren("ViewRegistration")) { - final int timepointId = Integer.parseInt(vr.getAttributeValue("timepoint")); - final int setupId = Integer.parseInt(vr.getAttributeValue("setup")); - final AffineTransform3D transform = new AffineTransform3D(); - transform.set(XmlHelpers.getDoubleArray(vr.getChild("ViewTransform"), "affine")); - regs.add(new ViewRegistration(timepointId, setupId, transform)); - } - SequenceDescription sequenceDescription = new SequenceDescription(timepoints, setups, null, (MissingViews) missingViews); - N5S3ImageLoader imageLoader = new N5S3ImageLoader(serviceEndpoint, signingRegion, bucketName, key, sequenceDescription, sharedQueue); - sequenceDescription.setImgLoader(imageLoader); - imageLoader.setViewRegistrations(new ViewRegistrations(regs)); - imageLoader.setSeq(sequenceDescription); - return new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); - } catch (JDOMException e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/openers/S3Opener.java b/src/main/java/org/embl/mobie/io/n5/openers/S3Opener.java deleted file mode 100644 index 14fec24d..00000000 --- a/src/main/java/org/embl/mobie/io/n5/openers/S3Opener.java +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.openers; - -import java.io.IOException; -import java.util.Arrays; -import java.util.stream.Collectors; - -import mpicbg.spim.data.SpimData; -import org.embl.mobie.io.OpenerLogging; -import org.embl.mobie.io.ome.zarr.openers.OMEZarrS3Opener; - -public class S3Opener extends OpenerLogging -{ - protected String serviceEndpoint; - protected String signingRegion; - protected String bucketName; - protected String key; - - public S3Opener(final String serviceEndpoint, final String signingRegion, final String bucketName) { - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = ""; - } - - public S3Opener(final String serviceEndpoint, final String signingRegion, final String bucketName, final String key) { - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - protected S3Opener(String url) { - url = url.replaceAll( "\\s", "" ); - url = url.trim(); - final String[] split = url.split("/"); - this.serviceEndpoint = Arrays.stream(split).limit(3).collect(Collectors.joining("/")); - this.signingRegion = null; // "us-west-2"; - this.bucketName = split[3]; - this.key = Arrays.stream(split).skip(4).collect(Collectors.joining("/")); - } - - public String getServiceEndpoint() { - return serviceEndpoint; - } - - public void setServiceEndpoint(String serviceEndpoint) { - this.serviceEndpoint = serviceEndpoint; - } - - public String getSigningRegion() { - return signingRegion; - } - - public void setSigningRegion(String signingRegion) { - this.signingRegion = signingRegion; - } - - public String getBucketName() { - return bucketName; - } - - public void setBucketName(String bucketName) { - this.bucketName = bucketName; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public SpimData readKey(final String key) throws IOException { - return null; - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/util/ArrayCreator.java b/src/main/java/org/embl/mobie/io/n5/util/ArrayCreator.java deleted file mode 100644 index 44f99fc5..00000000 --- a/src/main/java/org/embl/mobie/io/n5/util/ArrayCreator.java +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.util; - -import java.util.function.BiConsumer; - -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.imglib2.N5CellLoader; -import org.jetbrains.annotations.NotNull; - -import net.imglib2.img.array.ArrayImg; -import net.imglib2.img.array.ArrayImgs; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileByteArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileDoubleArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileFloatArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileLongArray; -import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.NativeType; -import net.imglib2.util.Cast; - -public abstract class ArrayCreator> { - protected final CellGrid cellGrid; - protected final DataType dataType; - protected final BiConsumer, DataBlock> copyFromBlock; - - public ArrayCreator(CellGrid cellGrid, DataType dataType) { - this.cellGrid = cellGrid; - this.dataType = dataType; - this.copyFromBlock = N5CellLoader.createCopy(dataType); - } - - @NotNull - public A VolatileDoubleArray(DataBlock dataBlock, long[] cellDims, int n) { - switch (dataType) { - case UINT8: - case INT8: - byte[] bytes = new byte[n]; - copyFromBlock.accept(Cast.unchecked(ArrayImgs.bytes(bytes, cellDims)), dataBlock); - return (A) new VolatileByteArray(bytes, true); - case UINT16: - case INT16: - short[] shorts = new short[n]; - copyFromBlock.accept(Cast.unchecked(ArrayImgs.shorts(shorts, cellDims)), dataBlock); - return (A) new VolatileShortArray(shorts, true); - case UINT32: - case INT32: - int[] ints = new int[n]; - copyFromBlock.accept(Cast.unchecked(ArrayImgs.ints(ints, cellDims)), dataBlock); - return (A) new VolatileIntArray(ints, true); - case UINT64: - case INT64: - long[] longs = new long[n]; - copyFromBlock.accept(Cast.unchecked(ArrayImgs.longs(longs, cellDims)), dataBlock); - return (A) new VolatileLongArray(longs, true); - case FLOAT32: - float[] floats = new float[n]; - copyFromBlock.accept(Cast.unchecked(ArrayImgs.floats(floats, cellDims)), dataBlock); - return (A) new VolatileFloatArray(floats, true); - case FLOAT64: - double[] doubles = new double[n]; - copyFromBlock.accept(Cast.unchecked(ArrayImgs.doubles(doubles, cellDims)), dataBlock); - return (A) new VolatileDoubleArray(doubles, true); - default: - throw new IllegalArgumentException(); - } - } - - public A createEmptyArray(long[] gridPosition) { - long[] cellDims = getCellDims(gridPosition); - int n = (int) (cellDims[0] * cellDims[1] * cellDims[2]); - switch (dataType) { - case UINT8: - case INT8: - return Cast.unchecked(new VolatileByteArray(new byte[n], true)); - case UINT16: - case INT16: - return Cast.unchecked(new VolatileShortArray(new short[n], true)); - case UINT32: - case INT32: - return Cast.unchecked(new VolatileIntArray(new int[n], true)); - case UINT64: - case INT64: - return Cast.unchecked(new VolatileLongArray(new long[n], true)); - case FLOAT32: - return Cast.unchecked(new VolatileFloatArray(new float[n], true)); - case FLOAT64: - return Cast.unchecked(new VolatileDoubleArray(new double[n], true)); - default: - throw new IllegalArgumentException(); - } - } - - public long[] getCellDims(long[] gridPosition) { - return null; - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/util/DownsampleBlock.java b/src/main/java/org/embl/mobie/io/n5/util/DownsampleBlock.java deleted file mode 100644 index 238089f6..00000000 --- a/src/main/java/org/embl/mobie/io/n5/util/DownsampleBlock.java +++ /dev/null @@ -1,642 +0,0 @@ -package org.embl.mobie.io.n5.util; - -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -import java.util.Arrays; - -import gnu.trove.iterator.TLongLongIterator; -import gnu.trove.map.hash.TLongLongHashMap; -import net.imglib2.AbstractLocalizableInt; -import net.imglib2.Cursor; -import net.imglib2.Localizable; -import net.imglib2.RandomAccess; -import net.imglib2.Sampler; -import net.imglib2.img.array.ArrayImgs; -import net.imglib2.loops.ClassCopyProvider; -import net.imglib2.type.numeric.RealType; -import net.imglib2.type.numeric.real.DoubleType; -import net.imglib2.util.Intervals; - -public interface DownsampleBlock> { - static > DownsampleBlock create( - final int[] blockDimensions, - final int[] downsamplingFactors, - final DownsamplingMethod downsamplingMethod, - final Class pixelTypeClass, - final Class inAccessClass) { - return DownsampleBlockInstances.create(blockDimensions, downsamplingFactors, downsamplingMethod, pixelTypeClass, inAccessClass); - } - - void downsampleBlock(final RandomAccess in, final Cursor out, final int[] dimensions); - - enum DownsamplingMethod { - Average, - Centre, - Mode - } -} - -class DownsampleBlockInstances { - @SuppressWarnings("rawtypes") - private static ClassCopyProvider provider; - private static DownsampleBlock.DownsamplingMethod lastDownsamplingMethod; - - @SuppressWarnings("unchecked") - public static > DownsampleBlock create( - final int[] blockDimensions, - final int[] downsamplingFactors, - DownsampleBlock.DownsamplingMethod downsamplingMethod, - final Class pixelTypeClass, - final Class inAccessClass) { - - if (provider == null || !(lastDownsamplingMethod == downsamplingMethod)) { - synchronized (DownsampleBlockInstances.class) { - if (provider == null || !(lastDownsamplingMethod == downsamplingMethod)) { - switch (downsamplingMethod) { - case Average: - provider = new ClassCopyProvider<>(AverageDownsampler.class, DownsampleBlock.class, int[].class, int[].class); - break; - case Centre: - provider = new ClassCopyProvider<>(CentreDownsampler.class, DownsampleBlock.class, int[].class, int[].class); - break; - case Mode: - provider = new ClassCopyProvider<>(ModeDownsampler.class, DownsampleBlock.class, int[].class, int[].class); - break; - } - lastDownsamplingMethod = downsamplingMethod; - } - } - } - - final int numDimensions = blockDimensions.length; - - Object key = Arrays.asList(numDimensions, pixelTypeClass, inAccessClass); - return provider.newInstanceForKey(key, blockDimensions, downsamplingFactors); - } - - public static class AverageDownsampler> implements DownsampleBlock { - private final int n; - - private final int[] downsamplingFactors; - - private final double scale; - - private final double[] accumulator; - - private final RandomAccess acc; - - public AverageDownsampler( - final int[] blockDimensions, - final int[] downsamplingFactors) { - n = blockDimensions.length; - if (n < 1 || n > 3) - throw new IllegalArgumentException(); - - this.downsamplingFactors = downsamplingFactors; - scale = 1.0 / Intervals.numElements(downsamplingFactors); - - accumulator = new double[(int) Intervals.numElements(blockDimensions)]; - - final long[] dims = new long[n]; - Arrays.setAll(dims, d -> blockDimensions[d]); - acc = ArrayImgs.doubles(accumulator, dims).randomAccess(); - } - - @Override - public void downsampleBlock( - final RandomAccess in, - final Cursor out, // must be flat iteration order - final int[] dimensions) { - clearAccumulator(); - - if (n == 3) { - downsampleBlock3D(acc, dimensions[0], dimensions[1], dimensions[2], in); - writeOutput3D(out, dimensions[0], dimensions[1], dimensions[2], acc); - } else if (n == 2) { - downsampleBlock2D(acc, dimensions[0], dimensions[1], in); - writeOutput2D(out, dimensions[0], dimensions[1], acc); - } else { - downsampleBlock1D(acc, dimensions[0], in); - writeOutput1D(out, dimensions[0], acc); - } - } - - private void clearAccumulator() { - Arrays.fill(accumulator, 0, accumulator.length, 0); - } - - private void downsampleBlock3D( - final RandomAccess acc, - final int asx, // size of output (resp accumulator) image - final int asy, - final int asz, - final RandomAccess in) { - final int bsz = downsamplingFactors[2]; - final int sz = asz * bsz; - for (int z = 0, bz = 0; z < sz; ++z) { - downsampleBlock2D(acc, asx, asy, in); - in.fwd(2); - if (++bz == bsz) { - bz = 0; - acc.fwd(2); - } - } - in.move(-sz, 2); - acc.move(-asz, 2); - } - - private void downsampleBlock2D( - final RandomAccess acc, - final int asx, // size of output (resp accumulator) image - final int asy, - final RandomAccess in) { - final int bsy = downsamplingFactors[1]; - final int sy = asy * bsy; - for (int y = 0, by = 0; y < sy; ++y) { - downsampleBlock1D(acc, asx, in); - in.fwd(1); - if (++by == bsy) { - by = 0; - acc.fwd(1); - } - } - in.move(-sy, 1); - acc.move(-asy, 1); - } - - private void downsampleBlock1D( - final RandomAccess acc, - final int asx, // size of output (resp accumulator) image - final RandomAccess in) { - final int bsx = downsamplingFactors[0]; - final int sx = asx * bsx; - for (int x = 0, bx = 0; x < sx; ++x) { - acc.get().set(acc.get().get() + in.get().getRealDouble()); - in.fwd(0); - if (++bx == bsx) { - bx = 0; - acc.fwd(0); - } - } - in.move(-sx, 0); - acc.move(-asx, 0); - } - - private void writeOutput3D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final int asy, - final int asz, - final RandomAccess acc) { - for (int z = 0; z < asz; ++z) { - writeOutput2D(out, asx, asy, acc); - acc.fwd(2); - } - acc.move(-asz, 2); - } - - private void writeOutput2D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final int asy, - final RandomAccess acc) { - for (int y = 0; y < asy; ++y) { - writeOutput1D(out, asx, acc); - acc.fwd(1); - } - acc.move(-asy, 1); - } - - private void writeOutput1D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final RandomAccess acc) { - final double scale = this.scale; - for (int x = 0; x < asx; ++x) { - out.next().setReal(acc.get().get() * scale); - acc.fwd(0); - } - acc.move(-asx, 0); - } - } - - public static class CentreDownsampler> implements DownsampleBlock { - private final int n; - - private final int[] downsamplingFactors; - - private final double[] accumulator; - - private final RandomAccess acc; - - public CentreDownsampler( - final int[] blockDimensions, - final int[] downsamplingFactors) { - n = blockDimensions.length; - if (n < 1 || n > 3) - throw new IllegalArgumentException(); - - this.downsamplingFactors = downsamplingFactors; - - accumulator = new double[(int) Intervals.numElements(blockDimensions)]; - - final long[] dims = new long[n]; - Arrays.setAll(dims, d -> blockDimensions[d]); - acc = ArrayImgs.doubles(accumulator, dims).randomAccess(); - } - - @Override - public void downsampleBlock( - final RandomAccess in, - final Cursor out, // must be flat iteration order - final int[] dimensions) { - clearAccumulator(); - - if (n == 3) { - downsampleBlock3D(acc, dimensions[0], dimensions[1], dimensions[2], in); - writeOutput3D(out, dimensions[0], dimensions[1], dimensions[2], acc); - } else if (n == 2) { - downsampleBlock2D(acc, dimensions[0], dimensions[1], in); - writeOutput2D(out, dimensions[0], dimensions[1], acc); - } else { - downsampleBlock1D(acc, dimensions[0], in); - writeOutput1D(out, dimensions[0], acc); - } - } - - private void clearAccumulator() { - Arrays.fill(accumulator, 0, accumulator.length, 0); - } - - private void downsampleBlock3D( - final RandomAccess acc, - final int asx, // size of accumulator image - final int asy, - final int asz, - final RandomAccess in) { - final int d = 2; - final int bsz = downsamplingFactors[d]; - in.move(bsz / 2, d); - for (int az = 0; az < asz; ++az) { - downsampleBlock2D(acc, asx, asy, in); - in.move(bsz, d); - acc.fwd(d); - } - in.move(-bsz * asz - bsz / 2, d); - acc.move(-asz, d); - } - - private void downsampleBlock2D( - final RandomAccess acc, - final int asx, // size of accumulator image - final int asy, - final RandomAccess in) { - final int d = 1; - final int bsy = downsamplingFactors[d]; - in.move(bsy / 2, d); - for (int ay = 0; ay < asy; ++ay) { - downsampleBlock1D(acc, asx, in); - in.move(bsy, d); - acc.fwd(d); - } - in.move(-bsy * asy - bsy / 2, d); - acc.move(-asy, d); - } - - private void downsampleBlock1D( - final RandomAccess acc, - final int asx, // size of output image - final RandomAccess in) { - final int d = 0; - final int bsx = downsamplingFactors[d]; - in.move(bsx / 2, d); - for (int ax = 0; ax < asx; ++ax) { - acc.get().set(in.get().getRealDouble()); - in.move(bsx, d); - acc.fwd(d); - } - in.move(-bsx * asx - bsx / 2, d); - acc.move(-asx, d); - } - - private void writeOutput3D( - final Cursor out, // must be flat iteration order - final int asx, // size of accumulator image - final int asy, - final int asz, - final RandomAccess acc) { - for (int z = 0; z < asz; ++z) { - writeOutput2D(out, asx, asy, acc); - acc.fwd(2); - } - acc.move(-asz, 2); - } - - private void writeOutput2D( - final Cursor out, // must be flat iteration order - final int asx, // size of output image - final int asy, - final RandomAccess acc) { - for (int y = 0; y < asy; ++y) { - writeOutput1D(out, asx, acc); - acc.fwd(1); - } - acc.move(-asy, 1); - } - - private void writeOutput1D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final RandomAccess acc) { - for (int x = 0; x < asx; ++x) { - out.next().setReal(acc.get().get()); - acc.fwd(0); - } - acc.move(-asx, 0); - } - } - - public static class ModeDownsampler> implements DownsampleBlock { - private final int n; - - private final int[] downsamplingFactors; - - private final TLongLongHashMapRandomAccess acc; - - public ModeDownsampler( - final int[] blockDimensions, - final int[] downsamplingFactors) { - n = blockDimensions.length; - if (n < 1 || n > 3) - throw new IllegalArgumentException(); - - this.downsamplingFactors = downsamplingFactors; - - final int[] dims = new int[n]; - Arrays.setAll(dims, d -> blockDimensions[d]); - - acc = new TLongLongHashMapRandomAccess(dims); - } - - @Override - public void downsampleBlock( - final RandomAccess in, - final Cursor out, // must be flat iteration order - final int[] dimensions) { - clearAccumulator(); - - if (n == 3) { - downsampleBlock3D(acc, dimensions[0], dimensions[1], dimensions[2], in); - writeOutput3D(out, dimensions[0], dimensions[1], dimensions[2], acc); - } else if (n == 2) { - downsampleBlock2D(acc, dimensions[0], dimensions[1], in); - writeOutput2D(out, dimensions[0], dimensions[1], acc); - } else { - downsampleBlock1D(acc, dimensions[0], in); - writeOutput1D(out, dimensions[0], acc); - } - } - - private void clearAccumulator() { - acc.init(); - } - - private void downsampleBlock3D( - final TLongLongHashMapRandomAccess acc, - final int asx, // size of output (resp accumulator) image - final int asy, - final int asz, - final RandomAccess in) { - final int bsz = downsamplingFactors[2]; - final int sz = asz * bsz; - for (int z = 0, bz = 0; z < sz; ++z) { - downsampleBlock2D(acc, asx, asy, in); - in.fwd(2); - if (++bz == bsz) { - bz = 0; - acc.fwd(2); - } - } - in.move(-sz, 2); - acc.move(-asz, 2); - } - - private void downsampleBlock2D( - final TLongLongHashMapRandomAccess acc, - final int asx, // size of output (resp accumulator) image - final int asy, - final RandomAccess in) { - final int bsy = downsamplingFactors[1]; - final int sy = asy * bsy; - for (int y = 0, by = 0; y < sy; ++y) { - downsampleBlock1D(acc, asx, in); - in.fwd(1); - if (++by == bsy) { - by = 0; - acc.fwd(1); - } - } - in.move(-sy, 1); - acc.move(-asy, 1); - } - - private void downsampleBlock1D( - final TLongLongHashMapRandomAccess acc, - final int asx, // size of output (resp accumulator) image - final RandomAccess in) { - final int bsx = downsamplingFactors[0]; - final int sx = asx * bsx; - for (int x = 0, bx = 0; x < sx; ++x) { - final long value = (long) in.get().getRealDouble(); - final TLongLongHashMap map = acc.get(); - final long newCount = map.get(value) + 1; - map.put(value, newCount); - - in.fwd(0); - if (++bx == bsx) { - bx = 0; - acc.fwd(0); - } - } - in.move(-sx, 0); - acc.move(-asx, 0); - } - - private void writeOutput3D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final int asy, - final int asz, - final TLongLongHashMapRandomAccess acc) { - for (int z = 0; z < asz; ++z) { - writeOutput2D(out, asx, asy, acc); - acc.fwd(2); - } - acc.move(-asz, 2); - } - - private void writeOutput2D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final int asy, - final TLongLongHashMapRandomAccess acc) { - for (int y = 0; y < asy; ++y) { - writeOutput1D(out, asx, acc); - acc.fwd(1); - } - acc.move(-asy, 1); - } - - private void writeOutput1D( - final Cursor out, // must be flat iteration order - final int asx, // size of output (resp accumulator) image - final TLongLongHashMapRandomAccess acc) { - for (int x = 0; x < asx; ++x) { - long label = getLabel(acc); - out.next().setReal(label); - acc.fwd(0); - } - acc.move(-asx, 0); - } - - private long getLabel(TLongLongHashMapRandomAccess acc) { - final TLongLongIterator iterator = acc.get().iterator(); - long maxCount = 0; - long label = 0; - while (iterator.hasNext()) { - iterator.advance(); - if (iterator.value() > maxCount) { - maxCount = iterator.value(); - label = iterator.key(); - } - } - return label; - } - } - - public static class TLongLongHashMapRandomAccess extends AbstractLocalizableInt implements RandomAccess { - private final int[] dims; - private TLongLongHashMap[][][] maps; - - public TLongLongHashMapRandomAccess(int[] dims) { - super(dims.length); - - this.dims = dims; - init(); - } - - public void init() { - if (dims.length == 1) - maps = new TLongLongHashMap[dims[0]][1][1]; - else if (dims.length == 2) - maps = new TLongLongHashMap[dims[0]][dims[1]][1]; - else if (dims.length == 3) - maps = new TLongLongHashMap[dims[0]][dims[1]][dims[2]]; - else - throw new UnsupportedOperationException("The number of dimensions must be <= 3"); - - for (int x = 0; x < dims[0]; x++) - for (int y = 0; y < dims[1]; y++) - for (int z = 0; z < dims[2]; z++) - maps[x][y][z] = new TLongLongHashMap(); - } - - @Override - public RandomAccess copy() { - throw new UnsupportedOperationException(); - } - - @Override - public void fwd(int d) { - position[d]++; - } - - @Override - public void bck(int d) { - position[d]--; - } - - @Override - public void move(int distance, int d) { - position[d] += distance; - } - - @Override - public void move(long distance, int d) { - position[d] += distance; - } - - @Override - public void move(Localizable distance) { - throw new UnsupportedOperationException(); - } - - @Override - public void move(int[] distance) { - throw new UnsupportedOperationException(); - } - - @Override - public void move(long[] distance) { - throw new UnsupportedOperationException(); - } - - @Override - public void setPosition(Localizable position) { - throw new UnsupportedOperationException(); - } - - @Override - public void setPosition(int[] position) { - throw new UnsupportedOperationException(); - } - - @Override - public void setPosition(long[] position) { - throw new UnsupportedOperationException(); - } - - @Override - public void setPosition(int position, int d) { - throw new UnsupportedOperationException(); - } - - @Override - public void setPosition(long position, int d) { - throw new UnsupportedOperationException(); - } - - @Override - public TLongLongHashMap get() { - return maps[position[0]][position[1]][position[2]]; - } - } -} - diff --git a/src/main/java/org/embl/mobie/io/n5/util/ExportScalePyramid.java b/src/main/java/org/embl/mobie/io/n5/util/ExportScalePyramid.java deleted file mode 100644 index ead6c557..00000000 --- a/src/main/java/org/embl/mobie/io/n5/util/ExportScalePyramid.java +++ /dev/null @@ -1,399 +0,0 @@ -package org.embl.mobie.io.n5.util; - -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; - -import bdv.export.CopyBlock; -import bdv.export.ExportMipmapInfo; -import bdv.export.ProgressWriter; -import bdv.export.ProgressWriterNull; -import bdv.export.SubTaskProgressWriter; -import net.imglib2.FinalInterval; -import net.imglib2.RandomAccess; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.cache.img.SingleCellArrayImg; -import net.imglib2.img.basictypeaccess.ArrayDataAccessFactory; -import net.imglib2.img.basictypeaccess.array.ArrayDataAccess; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.NativeType; -import net.imglib2.type.NativeTypeFactory; -import net.imglib2.type.numeric.RealType; -import net.imglib2.util.Cast; -import net.imglib2.util.Intervals; -import net.imglib2.view.Views; - -/** - * Write an image to a chunked mipmap representation. - */ -public class ExportScalePyramid { - /** - * Write an image to a chunked mipmap representation. - * - * @param img the image to be written. - * @param type instance of the pixel type of the image. - * @param mipmapInfo contains for each mipmap level of the setup, the subsampling - * factors and block sizes. - * @param io writer for image blocks. - * @param executorService ExecutorService where block-creator tasks are submitted. - * @param numThreads How many block-creator tasks to run in parallel. (This many - * tasks are submitted to the @code - * @param loopbackHeuristic heuristic to decide whether to create each resolution level by - * reading pixels from the original image or by reading back a - * finer resolution level already written to the hdf5. may be - * null (in this case always use the original image). - * @param afterEachPlane this is called after each "plane of blocks" is written, giving - * the opportunity to clear caches, etc. may be null. - * @param progressWriter completion ratio and status output will be directed here. may - * be null. - * @param Pixel type - * @param Dataset handle - * @throws IOException - */ - public static & NativeType, D> void writeScalePyramid( - final RandomAccessibleInterval img, - final T type, - final ExportMipmapInfo mipmapInfo, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, - final DatasetIO io, - final ExecutorService executorService, - final int numThreads, - final LoopbackHeuristic loopbackHeuristic, - final AfterEachPlane afterEachPlane, - ProgressWriter progressWriter) throws IOException { - final BlockCreator blockCreator = BlockCreator.forType(type); - - if (progressWriter == null) - progressWriter = new ProgressWriterNull(); - - // for progressWriter - final int numTasks = mipmapInfo.getNumLevels(); - int numCompletedTasks = 0; - progressWriter.setProgress(0.0); - - // write image data for all views to the HDF5 file - final int n = 3; // TODO checkNumDimensions( img.numDimensions() ); - final long[] dimensions = new long[n]; - - final int[][] resolutions = mipmapInfo.getExportResolutions(); - final int[][] subdivisions = mipmapInfo.getSubdivisions(); - final int numLevels = mipmapInfo.getNumLevels(); - - for (int level = 0; level < numLevels; ++level) { - progressWriter.out().println("writing level " + level); - - boolean useLoopBack = false; - int[] factorsToPreviousLevel = null; - RandomAccessibleInterval loopbackImg = null; - if (loopbackHeuristic != null) { - // Are downsampling factors a multiple of a level that we have - // already written? - int previousLevel = -1; - A: - for (int l = level - 1; l >= 0; --l) { - final int[] f = new int[n]; - for (int d = 0; d < n; ++d) { - f[d] = resolutions[level][d] / resolutions[l][d]; - if (f[d] * resolutions[l][d] != resolutions[level][d]) - continue A; - } - factorsToPreviousLevel = f; - previousLevel = l; - break; - } - // Now, if previousLevel >= 0 we can use loopback ImgLoader on - // previousLevel and downsample with factorsToPreviousLevel. - // - // whether it makes sense to actually do so is determined by a - // heuristic based on the following considerations: - // * if downsampling a lot over original image, the cost of - // reading images back from hdf5 outweighs the cost of - // accessing and averaging original pixels. - // * original image may already be cached (for example when - // exporting an ImageJ virtual stack. To compute blocks - // that downsample a lot in Z, many planes of the virtual - // stack need to be accessed leading to cache thrashing if - // individual planes are very large. - - if (previousLevel >= 0) - useLoopBack = loopbackHeuristic.decide(img, resolutions[level], previousLevel, factorsToPreviousLevel, subdivisions[level]); - - if (useLoopBack) - loopbackImg = io.getImage(previousLevel); - - if (loopbackImg == null) - useLoopBack = false; - } - - final RandomAccessibleInterval sourceImg; - final int[] factor; - if (useLoopBack) { - sourceImg = loopbackImg; - factor = factorsToPreviousLevel; - } else { - sourceImg = img; - factor = resolutions[level]; - } - - sourceImg.dimensions(dimensions); - - final long size = Intervals.numElements(factor); - final boolean fullResolution = size == 1; - if (!fullResolution) { - for (int d = 0; d < n; ++d) - dimensions[d] = Math.max(dimensions[d] / factor[d], 1); - } - - final long[] minRequiredInput = new long[n]; - final long[] maxRequiredInput = new long[n]; - sourceImg.min(minRequiredInput); - for (int d = 0; d < n; ++d) - maxRequiredInput[d] = minRequiredInput[d] + dimensions[d] * factor[d] - 1; - - // TODO: pass OutOfBoundsFactory - final RandomAccessibleInterval extendedImg = Views.interval(Views.extendBorder(sourceImg), new FinalInterval(minRequiredInput, maxRequiredInput)); - - final int[] cellDimensions = subdivisions[level]; - final D dataset = io.createDataset(level, dimensions, cellDimensions); - - final ProgressWriter subProgressWriter = new SubTaskProgressWriter( - progressWriter, (double) numCompletedTasks / numTasks, - (double) (numCompletedTasks + 1) / numTasks); - // generate one "plane" of cells after the other to avoid cache thrashing when exporting from virtual stacks - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - final long[] numCells = grid.getGridDimensions(); - final long numBlocksPerPlane = numElements(numCells, 0, 2); - final long numPlanes = numElements(numCells, 2, n); - for (int plane = 0; plane < numPlanes; ++plane) { - final long planeBaseIndex = numBlocksPerPlane * plane; - final AtomicInteger nextCellInPlane = new AtomicInteger(); - final List> tasks = new ArrayList<>(); - for (int threadNum = 0; threadNum < numThreads; ++threadNum) { - tasks.add(() -> { - final long[] currentCellMin = new long[n]; - final int[] currentCellDim = new int[n]; - final long[] currentCellPos = new long[n]; - final long[] blockMin = new long[n]; - final RandomAccess in = extendedImg.randomAccess(); - - final Class kl1 = type.getClass(); - final Class kl2 = in.getClass(); - final CopyBlock copyBlock = fullResolution ? CopyBlock.create(n, kl1, kl2) : null; - final DownsampleBlock downsampleBlock = fullResolution ? null : DownsampleBlock.create(cellDimensions, factor, downsamplingMethod, kl1, kl2); - - for (int i = nextCellInPlane.getAndIncrement(); i < numBlocksPerPlane; i = nextCellInPlane.getAndIncrement()) { - final long index = planeBaseIndex + i; - - grid.getCellDimensions(index, currentCellMin, currentCellDim); - grid.getCellGridPositionFlat(index, currentCellPos); - final Block block = blockCreator.create(currentCellDim, currentCellMin, currentCellPos); - - if (fullResolution) { - final RandomAccess out = block.getData().randomAccess(); - in.setPosition(currentCellMin); - out.setPosition(currentCellMin); - copyBlock.copyBlock(in, out, currentCellDim); - } else { - for (int d = 0; d < n; ++d) - blockMin[d] = currentCellMin[d] * factor[d]; - in.setPosition(blockMin); - downsampleBlock.downsampleBlock(in, block.getData().cursor(), currentCellDim); - } - - io.writeBlock(dataset, block); - } - return null; - }); - } - try { - final List> futures = executorService.invokeAll(tasks); - for (final Future future : futures) - future.get(); - } catch (final InterruptedException | ExecutionException e) { - // TODO... - e.printStackTrace(); - throw new IOException(e); - } - if (afterEachPlane != null) - afterEachPlane.afterEachPlane(useLoopBack); - - subProgressWriter.setProgress((double) plane / numPlanes); - } - io.flush(dataset); - progressWriter.setProgress((double) ++numCompletedTasks / numTasks); - } - } - - private static long numElements(final long[] size, final int mind, final int maxd) { - long numElements = 1; - for (int d = mind; d < maxd; ++d) - numElements *= size[d]; - return numElements; - } - - /** - * A heuristic to decide for a given resolution level whether the source - * pixels should be taken from the original image or read from a previously - * written resolution level in the output dataset. - */ - public interface LoopbackHeuristic { - /** - * @return {@code true} if source pixels should be read back from - * dataset. {@code false} if source pixels should be taken from - * original image. - */ - boolean decide( - final RandomAccessibleInterval originalImg, - final int[] factorsToOriginalImg, - final int previousLevel, - final int[] factorsToPreviousLevel, - final int[] chunkSize); - } - - /** - * Callback that is called after each "plane of blocks" is written, giving - * the opportunity to clear caches, etc. - */ - public interface AfterEachPlane { - /** - * Called after a "plane of blocks" is written. - * - * @param usedLoopBack {@code true}, if source was previously written resolution - * level in the output dataset. {@code false}, if source was - * the original image. - */ - void afterEachPlane(final boolean usedLoopBack); - } - - /** - * Writing and reading back data for each resolution level. - * - * @param Dataset handle - * @param Pixel type - */ - public interface DatasetIO> { - /** - * Create a dataset for the image of the given resolution {@code level}. - * - * @return a handle to the dataset. - */ - D createDataset( - final int level, - final long[] dimensions, - final int[] blockSize) throws IOException; - - /** - * Write the given {@code dataBlock} to the {@code dataset}. - */ - void writeBlock( - final D dataset, - final Block dataBlock) throws IOException; - - /** - * Blocks until all pending data was written to {@code dataset}. - */ - void flush(D dataset) throws IOException; - - /** - * Opens a dataset that was already written as a - * {@code RaπdomAccessibleInterval}. - */ - default RandomAccessibleInterval getImage(final int level) throws IOException { - return null; - } - } - - private interface BlockCreator> { - static & RealType, A extends ArrayDataAccess> BlockCreator forType(final T type) { - final A accessFactory = Cast.unchecked(ArrayDataAccessFactory.get(type)); - final NativeTypeFactory nativeTypeFactory = Cast.unchecked(type.getNativeTypeFactory()); - return (blockSize, blockMin, gridPosition) -> { - final A data = accessFactory.createArray((int) Intervals.numElements(blockSize)); - final SingleCellArrayImg img = new SingleCellArrayImg<>(blockSize, blockMin, data, null); - img.setLinkedType(nativeTypeFactory.createLinkedType(img)); - return new Block<>(img, blockSize, gridPosition); - }; - } - - Block create(final int[] blockSize, final long[] blockMin, final long[] gridPosition); - } - - /** - * Simple heuristic: use loopback image loader if saving 8 times or more on - * number of pixel access with respect to the original image. - */ - public static class DefaultLoopbackHeuristic implements LoopbackHeuristic { - @Override - public boolean decide(final RandomAccessibleInterval originalImg, final int[] factorsToOriginalImg, final int previousLevel, final int[] factorsToPreviousLevel, final int[] chunkSize) { - if (previousLevel < 0) - return false; - - if (Intervals.numElements(factorsToOriginalImg) / Intervals.numElements(factorsToPreviousLevel) >= 8) - return true; - - return false; - } - } - - /** - * A block to be written. See {@link DatasetIO#writeBlock(Object, Block) - * DatasetIO.writeBlock()}. - */ - public static class Block> { - final SingleCellArrayImg data; - final int[] size; - final long[] position; - - Block(final SingleCellArrayImg data, final int[] size, final long[] position) { - this.data = data; - this.size = size; - this.position = position; - } - - public SingleCellArrayImg getData() { - return data; - } - - public int[] getSize() { - return size; - } - - public long[] getGridPosition() { - return position; - } - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/util/N5CacheArrayLoader.java b/src/main/java/org/embl/mobie/io/n5/util/N5CacheArrayLoader.java deleted file mode 100644 index aad8bfa2..00000000 --- a/src/main/java/org/embl/mobie/io/n5/util/N5CacheArrayLoader.java +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.util; - -import java.util.Arrays; -import java.util.function.Function; - -import net.imglib2.img.basictypeaccess.DataAccess; -import org.janelia.saalfeldlab.n5.ByteArrayDataBlock; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.DoubleArrayDataBlock; -import org.janelia.saalfeldlab.n5.FloatArrayDataBlock; -import org.janelia.saalfeldlab.n5.IntArrayDataBlock; -import org.janelia.saalfeldlab.n5.LongArrayDataBlock; -import org.janelia.saalfeldlab.n5.N5Reader; -import org.janelia.saalfeldlab.n5.ShortArrayDataBlock; - -import bdv.img.cache.SimpleCacheArrayLoader; - -public class N5CacheArrayLoader implements SimpleCacheArrayLoader { - private final N5Reader n5; - private final String pathName; - private final DatasetAttributes attributes; - private final Function, A> createArray; - - public N5CacheArrayLoader(final N5Reader n5, final String pathName, final DatasetAttributes attributes, final Function, A> createArray) { - this.n5 = n5; - this.pathName = pathName; - this.attributes = attributes; - this.createArray = createArray; - } - - @Override - public A loadArray(final long[] gridPosition, int[] cellDimensions) { - DataBlock block = null; - - try { - block = n5.readBlock(pathName, attributes, gridPosition); - } catch (Exception e) { - System.err.println("Error loading " + pathName + " at block " + Arrays.toString(gridPosition) + ": " + e); - } - - if (block == null) { - final int[] blockSize = attributes.getBlockSize(); - final int n = blockSize[0] * blockSize[1] * blockSize[2]; - switch (attributes.getDataType()) { - case UINT8: - case INT8: - return createArray.apply(new ByteArrayDataBlock(blockSize, gridPosition, new byte[n])); - case UINT16: - case INT16: - return createArray.apply(new ShortArrayDataBlock(blockSize, gridPosition, new short[n])); - case UINT32: - case INT32: - return createArray.apply(new IntArrayDataBlock(blockSize, gridPosition, new int[n])); - case UINT64: - case INT64: - return createArray.apply(new LongArrayDataBlock(blockSize, gridPosition, new long[n])); - case FLOAT32: - return createArray.apply(new FloatArrayDataBlock(blockSize, gridPosition, new float[n])); - case FLOAT64: - return createArray.apply(new DoubleArrayDataBlock(blockSize, gridPosition, new double[n])); - default: - throw new IllegalArgumentException(); - } - } else { - return createArray.apply(block); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/util/N5DataTypeSize.java b/src/main/java/org/embl/mobie/io/n5/util/N5DataTypeSize.java deleted file mode 100644 index 531ee2a4..00000000 --- a/src/main/java/org/embl/mobie/io/n5/util/N5DataTypeSize.java +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.util; - -import org.janelia.saalfeldlab.n5.DataType; - -public abstract class N5DataTypeSize { - public static int getNumBytesPerElement(DataType dataType) { - switch (dataType) { - case UINT8: - case INT8: - return 1; - case UINT16: - case INT16: - return 2; - case UINT32: - case INT32: - case FLOAT32: - return 4; - case UINT64: - case INT64: - case FLOAT64: - return 8; - case OBJECT: - default: - return -1; - } - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/writers/WriteImagePlusToN5.java b/src/main/java/org/embl/mobie/io/n5/writers/WriteImagePlusToN5.java deleted file mode 100644 index 7f8c2052..00000000 --- a/src/main/java/org/embl/mobie/io/n5/writers/WriteImagePlusToN5.java +++ /dev/null @@ -1,402 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.writers; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.embl.mobie.io.n5.util.DownsampleBlock; -import org.embl.mobie.io.n5.util.ExportScalePyramid; -import org.janelia.saalfeldlab.n5.Compression; - -import bdv.export.ExportMipmapInfo; -import bdv.export.ProgressWriter; -import bdv.export.ProposeMipmaps; -import bdv.export.SubTaskProgressWriter; -import bdv.ij.util.PluginHelper; -import bdv.ij.util.ProgressWriterIJ; -import bdv.img.imagestack.ImageStackImageLoader; -import bdv.img.n5.N5ImageLoader; -import bdv.img.virtualstack.VirtualStackImageLoader; -import bdv.spimdata.SequenceDescriptionMinimal; -import bdv.spimdata.SpimDataMinimal; -import bdv.spimdata.XmlIoSpimDataMinimal; -import ij.IJ; -import ij.ImagePlus; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.generic.sequence.TypedBasicImgLoader; -import mpicbg.spim.data.registration.ViewRegistration; -import mpicbg.spim.data.registration.ViewRegistrations; -import mpicbg.spim.data.sequence.Channel; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.TimePoints; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.util.Intervals; - - -// splits functionality from https://github.com/bigdataviewer/bigdataviewer_fiji/blob/master/src/main/java/bdv/ij/ExportImagePlusAsN5PlugIn.java -// separating from GUI. Provides general export functions for ImagePlus. - -public class WriteImagePlusToN5 { - - // export, generating default source transform, and default resolutions / subdivisions - public void export(ImagePlus imp, String xmlPath, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression) { - if (!WriteImagePlusToN5Helper.isImageSuitable(imp)) { - return; - } - - FinalVoxelDimensions voxelSize = WriteImagePlusToN5Helper.getVoxelSize(imp); - final AffineTransform3D sourceTransform = WriteImagePlusToN5Helper.generateSourceTransform(voxelSize); - - Parameters defaultParameters = generateDefaultParameters(imp, xmlPath, sourceTransform, downsamplingMethod, - compression, null); - - export(imp, defaultParameters); - } - - // export, generating default resolutions / subdivisions - public void export(ImagePlus imp, String xmlPath, AffineTransform3D sourceTransform, - DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression) { - if (!WriteImagePlusToN5Helper.isImageSuitable(imp)) { - return; - } - - Parameters defaultParameters = generateDefaultParameters(imp, xmlPath, sourceTransform, - downsamplingMethod, compression, null); - - export(imp, defaultParameters); - } - - // export, generating default resolutions / subdivisions - public void export(ImagePlus imp, String xmlPath, AffineTransform3D sourceTransform, - DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression, - String[] viewSetupNames) { - if (!WriteImagePlusToN5Helper.isImageSuitable(imp)) { - return; - } - - Parameters defaultParameters = generateDefaultParameters(imp, xmlPath, sourceTransform, - downsamplingMethod, compression, viewSetupNames); - - export(imp, defaultParameters); - } - - public void export(ImagePlus imp, int[][] resolutions, int[][] subdivisions, String xmlPath, - AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, - Compression compression) { - export(imp, resolutions, subdivisions, xmlPath, sourceTransform, downsamplingMethod, compression, null); - } - - public void export(ImagePlus imp, int[][] resolutions, int[][] subdivisions, String xmlPath, - AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, - Compression compression, String[] viewSetupNames) { - if (resolutions.length == 0) { - IJ.showMessage("Invalid resolutions - length 0"); - return; - } - - if (subdivisions.length == 0) { - IJ.showMessage(" Invalid subdivisions - length 0"); - return; - } - - if (resolutions.length != subdivisions.length) { - IJ.showMessage("Subsampling factors and chunk sizes must have the same number of elements"); - return; - } - - String seqFilename = xmlPath; - if (!seqFilename.endsWith(".xml")) - seqFilename += ".xml"; - final File seqFile = WriteImagePlusToN5Helper.getSeqFileFromPath(seqFilename); - if (seqFile == null) { - return; - } - - final File n5File = WriteImagePlusToN5Helper.getN5FileFromXmlPath(seqFilename); - - Parameters exportParameters = new Parameters(resolutions, subdivisions, seqFile, n5File, sourceTransform, - downsamplingMethod, compression, viewSetupNames); - - export(imp, exportParameters); - } - - protected Parameters generateDefaultParameters(ImagePlus imp, String xmlPath, AffineTransform3D sourceTransform, - DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression, - String[] viewSetupNames) { - FinalVoxelDimensions voxelSize = WriteImagePlusToN5Helper.getVoxelSize(imp); - FinalDimensions size = WriteImagePlusToN5Helper.getSize(imp); - - // propose reasonable mipmap settings - final int maxNumElements = 64 * 64 * 64; - final ExportMipmapInfo autoMipmapSettings = ProposeMipmaps.proposeMipmaps( - new BasicViewSetup(0, "", size, voxelSize), - maxNumElements); - - int[][] resolutions = autoMipmapSettings.getExportResolutions(); - int[][] subdivisions = autoMipmapSettings.getSubdivisions(); - - if (resolutions.length == 0 || subdivisions.length == 0 || resolutions.length != subdivisions.length) { - IJ.showMessage("Error with calculating default subdivisions and resolutions"); - return null; - } - - String seqFilename = xmlPath; - if (!seqFilename.endsWith(".xml")) - seqFilename += ".xml"; - final File seqFile = WriteImagePlusToN5Helper.getSeqFileFromPath(seqFilename); - if (seqFile == null) { - return null; - } - - final File n5File = WriteImagePlusToN5Helper.getN5FileFromXmlPath(seqFilename); - - return new Parameters(resolutions, subdivisions, seqFile, n5File, sourceTransform, - downsamplingMethod, compression, viewSetupNames); - } - - protected void export(ImagePlus imp, Parameters params) { - - FinalVoxelDimensions voxelSize = WriteImagePlusToN5Helper.getVoxelSize(imp); - FinalDimensions size = WriteImagePlusToN5Helper.getSize(imp); - - final ProgressWriter progressWriter = new ProgressWriterIJ(); - progressWriter.out().println("starting export..."); - - // create ImgLoader wrapping the image - final TypedBasicImgLoader imgLoader; - final Runnable clearCache; - final boolean isVirtual = imp.getStack() != null && imp.getStack().isVirtual(); - if (isVirtual) { - final VirtualStackImageLoader il; - switch (imp.getType()) { - case ImagePlus.GRAY8: - il = VirtualStackImageLoader.createUnsignedByteInstance(imp); - break; - case ImagePlus.GRAY16: - il = VirtualStackImageLoader.createUnsignedShortInstance(imp); - break; - case ImagePlus.GRAY32: - default: - il = VirtualStackImageLoader.createFloatInstance(imp); - break; - } - imgLoader = il; - clearCache = il.getCacheControl()::clearCache; - } else { - switch (imp.getType()) { - case ImagePlus.GRAY8: - imgLoader = ImageStackImageLoader.createUnsignedByteInstance(imp); - break; - case ImagePlus.GRAY16: - imgLoader = ImageStackImageLoader.createUnsignedShortInstance(imp); - break; - case ImagePlus.GRAY32: - default: - imgLoader = ImageStackImageLoader.createFloatInstance(imp); - break; - } - clearCache = () -> { - }; - } - - final int numTimepoints = imp.getNFrames(); - final int numSetups = imp.getNChannels(); - - // write n5 - final HashMap setups = new HashMap<>(numSetups); - if (params.viewSetupNames != null && params.viewSetupNames.length != numSetups) { - throw new RuntimeException(params.viewSetupNames.length + " view setup names were given, " + - "but there are " + numSetups + " setups"); - } - for (int s = 0; s < numSetups; ++s) { - final BasicViewSetup setup; - if (params.viewSetupNames != null) { - setup = new BasicViewSetup(s, params.viewSetupNames[s], size, voxelSize); - } else { - setup = new BasicViewSetup(s, String.format("channel %d", s + 1), size, voxelSize); - } - setup.setAttribute(new Channel(s + 1)); - setups.put(s, setup); - } - final ArrayList timepoints = new ArrayList<>(numTimepoints); - for (int t = 0; t < numTimepoints; ++t) - timepoints.add(new TimePoint(t)); - final SequenceDescriptionMinimal seq = new SequenceDescriptionMinimal(new TimePoints(timepoints), setups, imgLoader, null); - - Map perSetupExportMipmapInfo; - perSetupExportMipmapInfo = new HashMap<>(); - final ExportMipmapInfo mipmapInfo = new ExportMipmapInfo(params.resolutions, params.subdivisions); - for (final BasicViewSetup setup : seq.getViewSetupsOrdered()) - perSetupExportMipmapInfo.put(setup.getId(), mipmapInfo); - - // LoopBackHeuristic: - // - If saving more than 8x on pixel reads use the loopback image over - // original image - // - For virtual stacks also consider the cache size that would be - // required for all original planes contributing to a "plane of - // blocks" at the current level. If this is more than 1/4 of - // available memory, use the loopback image. - final long planeSizeInBytes = imp.getWidth() * imp.getHeight() * imp.getBytesPerPixel(); - final long ijMaxMemory = IJ.maxMemory(); - final int numCellCreatorThreads = Math.max(1, PluginHelper.numThreads() - 1); - final ExportScalePyramid.LoopbackHeuristic loopbackHeuristic = new ExportScalePyramid.LoopbackHeuristic() { - @Override - public boolean decide(final RandomAccessibleInterval originalImg, final int[] factorsToOriginalImg, final int previousLevel, final int[] factorsToPreviousLevel, final int[] chunkSize) { - if (previousLevel < 0) - return false; - - if (Intervals.numElements(factorsToOriginalImg) / Intervals.numElements(factorsToPreviousLevel) >= 8) - return true; - - if (isVirtual) { - final long requiredCacheSize = planeSizeInBytes * factorsToOriginalImg[2] * chunkSize[2]; - if (requiredCacheSize > ijMaxMemory / 4) - return true; - } - - return false; - } - }; - - final ExportScalePyramid.AfterEachPlane afterEachPlane = new ExportScalePyramid.AfterEachPlane() { - @Override - public void afterEachPlane(final boolean usedLoopBack) { - if (!usedLoopBack && isVirtual) { - final long free = Runtime.getRuntime().freeMemory(); - final long total = Runtime.getRuntime().totalMemory(); - final long max = Runtime.getRuntime().maxMemory(); - final long actuallyFree = max - total + free; - - if (actuallyFree < max / 2) - clearCache.run(); - } - } - - }; - - try { - writeFiles(seq, perSetupExportMipmapInfo, params, loopbackHeuristic, afterEachPlane, numCellCreatorThreads, - progressWriter, numTimepoints, numSetups); - } catch (final SpimDataException | IOException e) { - throw new RuntimeException(e); - } - progressWriter.out().println("done"); - } - - protected void writeFiles(SequenceDescriptionMinimal seq, Map perSetupExportMipmapInfo, - Parameters params, ExportScalePyramid.LoopbackHeuristic loopbackHeuristic, - ExportScalePyramid.AfterEachPlane afterEachPlane, int numCellCreatorThreads, - ProgressWriter progressWriter, int numTimepoints, int numSetups) throws IOException, SpimDataException { - WriteSequenceToN5.writeN5File(seq, perSetupExportMipmapInfo, - params.downsamplingMethod, - params.compression, params.n5File, - loopbackHeuristic, afterEachPlane, numCellCreatorThreads, - new SubTaskProgressWriter(progressWriter, 0, 0.95)); - - // write xml sequence description - final N5ImageLoader n5Loader = new N5ImageLoader(params.n5File, null); - final SequenceDescriptionMinimal seqh5 = new SequenceDescriptionMinimal(seq, n5Loader); - - final ArrayList registrations = new ArrayList<>(); - for (int t = 0; t < numTimepoints; ++t) - for (int s = 0; s < numSetups; ++s) - registrations.add(new ViewRegistration(t, s, params.sourceTransform)); - - final File basePath = params.seqFile.getParentFile(); - final SpimDataMinimal spimData = new SpimDataMinimal(basePath, seqh5, new ViewRegistrations(registrations)); - - new XmlIoSpimDataMinimal().save(spimData, params.seqFile.getAbsolutePath()); - progressWriter.setProgress(1.0); - } - - protected static class Parameters { - public final int[][] resolutions; - - public final int[][] subdivisions; - - public final File seqFile; - - public final File n5File; - - public final AffineTransform3D sourceTransform; - - public final DownsampleBlock.DownsamplingMethod downsamplingMethod; - - public final Compression compression; - - public final String[] viewSetupNames; - - public final String timeUnit; - - public final double frameInterval; - - public Parameters( - final int[][] resolutions, final int[][] subdivisions, - final File seqFile, final File n5File, final AffineTransform3D sourceTransform, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, final Compression compression) { - this(resolutions, subdivisions, seqFile, n5File, sourceTransform, downsamplingMethod, compression, - null); - } - - public Parameters( - final int[][] resolutions, final int[][] subdivisions, - final File seqFile, final File n5File, final AffineTransform3D sourceTransform, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, final Compression compression, - final String[] viewSetupNames) { - this(resolutions, subdivisions, seqFile, n5File, sourceTransform, downsamplingMethod, compression, - viewSetupNames, null, 1); - } - - public Parameters( - final int[][] resolutions, final int[][] subdivisions, - final File seqFile, final File n5File, final AffineTransform3D sourceTransform, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, final Compression compression, - final String[] viewSetupNames, String timeUnit, double frameInterval) { - this.resolutions = resolutions; - this.subdivisions = subdivisions; - this.seqFile = seqFile; - this.n5File = n5File; - this.sourceTransform = sourceTransform; - this.downsamplingMethod = downsamplingMethod; - this.compression = compression; - this.viewSetupNames = viewSetupNames; - this.timeUnit = timeUnit; - this.frameInterval = frameInterval; - } - } - -} diff --git a/src/main/java/org/embl/mobie/io/n5/writers/WriteImagePlusToN5Helper.java b/src/main/java/org/embl/mobie/io/n5/writers/WriteImagePlusToN5Helper.java deleted file mode 100644 index 21596e05..00000000 --- a/src/main/java/org/embl/mobie/io/n5/writers/WriteImagePlusToN5Helper.java +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.n5.writers; - -import java.io.File; - -import ij.IJ; -import ij.ImagePlus; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.realtransform.AffineTransform3D; - -public class WriteImagePlusToN5Helper { - public static boolean isImageSuitable(ImagePlus imp) { - // check the image type - switch (imp.getType()) { - case ImagePlus.GRAY8: - case ImagePlus.GRAY16: - case ImagePlus.GRAY32: - break; - default: - IJ.showMessage("Only 8, 16, 32-bit images are supported currently!"); - return false; - } - - // check the image dimensionality - if (imp.getNDimensions() < 2) { - IJ.showMessage("Image must be at least 2-dimensional!"); - return false; - } - - return true; - } - - public static FinalVoxelDimensions getVoxelSize(ImagePlus imp) { - final double pw = imp.getCalibration().pixelWidth; - final double ph = imp.getCalibration().pixelHeight; - final double pd = imp.getCalibration().pixelDepth; - String punit = imp.getCalibration().getUnit(); - if (punit == null || punit.isEmpty()) - punit = "px"; - final FinalVoxelDimensions voxelSize = new FinalVoxelDimensions(punit, pw, ph, pd); - return voxelSize; - } - - public static FinalDimensions getSize(ImagePlus imp) { - final int w = imp.getWidth(); - final int h = imp.getHeight(); - final int d = imp.getNSlices(); - final FinalDimensions size = new FinalDimensions(w, h, d); - return size; - } - - public static File getSeqFileFromPath(String seqFilename) { - final File seqFile = new File(seqFilename); - final File parent = seqFile.getParentFile(); - if (parent == null || !parent.exists() || !parent.isDirectory()) { - IJ.showMessage("Invalid export filename " + seqFilename); - return null; - } - return seqFile; - } - - public static AffineTransform3D generateSourceTransform(FinalVoxelDimensions voxelSize) { - // create SourceTransform from the images calibration - final AffineTransform3D sourceTransform = new AffineTransform3D(); - sourceTransform.set(voxelSize.dimension(0), 0, 0, 0, 0, voxelSize.dimension(1), - 0, 0, 0, 0, voxelSize.dimension(2), 0); - return sourceTransform; - } - - public static File getN5FileFromXmlPath(String xmlPath) { - final String n5Filename = xmlPath.substring(0, xmlPath.length() - 4) + ".n5"; - return new File(n5Filename); - } - - public static File getOmeZarrFileFromXmlPath(String xmlPath) { - final String omeZarrFileName = xmlPath.substring(0, xmlPath.length() - 4) + ".ome.zarr"; - return new File(omeZarrFileName); - } -} diff --git a/src/main/java/org/embl/mobie/io/n5/writers/WriteSequenceToN5.java b/src/main/java/org/embl/mobie/io/n5/writers/WriteSequenceToN5.java deleted file mode 100644 index 3ae8e317..00000000 --- a/src/main/java/org/embl/mobie/io/n5/writers/WriteSequenceToN5.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.embl.mobie.io.n5.writers; -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.embl.mobie.io.n5.util.DownsampleBlock; -import org.embl.mobie.io.n5.util.ExportScalePyramid; -import org.janelia.saalfeldlab.n5.ByteArrayDataBlock; -import org.janelia.saalfeldlab.n5.Compression; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.DoubleArrayDataBlock; -import org.janelia.saalfeldlab.n5.FloatArrayDataBlock; -import org.janelia.saalfeldlab.n5.IntArrayDataBlock; -import org.janelia.saalfeldlab.n5.LongArrayDataBlock; -import org.janelia.saalfeldlab.n5.N5FSWriter; -import org.janelia.saalfeldlab.n5.N5Writer; -import org.janelia.saalfeldlab.n5.ShortArrayDataBlock; -import org.janelia.saalfeldlab.n5.imglib2.N5Utils; - -import bdv.export.ExportMipmapInfo; -import bdv.export.ProgressWriter; -import bdv.export.ProgressWriterNull; -import bdv.export.SubTaskProgressWriter; -import bdv.img.cache.SimpleCacheArrayLoader; -import bdv.img.n5.N5ImageLoader; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.BasicImgLoader; -import mpicbg.spim.data.generic.sequence.BasicSetupImgLoader; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.ViewId; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.cache.img.ReadOnlyCachedCellImgFactory; -import net.imglib2.img.cell.Cell; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.util.Cast; - -import static bdv.img.n5.BdvN5Format.DATA_TYPE_KEY; -import static bdv.img.n5.BdvN5Format.DOWNSAMPLING_FACTORS_KEY; -import static bdv.img.n5.BdvN5Format.getPathName; -import static net.imglib2.cache.img.ReadOnlyCachedCellImgOptions.options; - -/** - * @author Tobias Pietzsch - * @author John Bogovic - */ -public class WriteSequenceToN5 { - private static final String MULTI_SCALE_KEY = "multiScale"; - private static final String RESOLUTION_KEY = "resolution"; - - /** - * Create a n5 group containing image data from all views and all - * timepoints in a chunked, mipmaped representation. - * - * @param seq description of the sequence to be stored as hdf5. (The - * {@link AbstractSequenceDescription} contains the number of - * setups and timepoints as well as an {@link BasicImgLoader} - * that provides the image data, Registration information is not - * needed here, that will go into the accompanying xml). - * @param perSetupMipmapInfo this maps from setup {@link BasicViewSetup#getId() id} to - * {@link ExportMipmapInfo} for that setup. The - * {@link ExportMipmapInfo} contains for each mipmap level, the - * subsampling factors and subdivision block sizes. - * @param compression n5 compression scheme. - * @param n5File n5 root. - * @param loopbackHeuristic heuristic to decide whether to create each resolution level by - * reading pixels from the original image or by reading back a - * finer resolution level already written to the hdf5. may be - * null (in this case always use the original image). - * @param afterEachPlane this is called after each "plane of chunks" is written, giving - * the opportunity to clear caches, etc. - * @param numCellCreatorThreads The number of threads that will be instantiated to generate - * cell data. Must be at least 1. (In addition the cell creator - * threads there is one writer thread that saves the generated - * data to HDF5.) - * @param progressWriter completion ratio and status output will be directed here. - */ - public static void writeN5File( - final AbstractSequenceDescription seq, - final Map perSetupMipmapInfo, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, - final Compression compression, - final File n5File, - final ExportScalePyramid.LoopbackHeuristic loopbackHeuristic, - final ExportScalePyramid.AfterEachPlane afterEachPlane, - final int numCellCreatorThreads, - ProgressWriter progressWriter) throws IOException { - if (progressWriter == null) - progressWriter = new ProgressWriterNull(); - progressWriter.setProgress(0); - - final BasicImgLoader imgLoader = seq.getImgLoader(); - - for (final BasicViewSetup setup : seq.getViewSetupsOrdered()) { - final Object type = imgLoader.getSetupImgLoader(setup.getId()).getImageType(); - if (!(type instanceof RealType && - type instanceof NativeType && - N5Utils.dataType(Cast.unchecked(type)) != null)) - throw new IllegalArgumentException("Unsupported pixel type: " + type.getClass().getSimpleName()); - } - - final List timepointIds = seq.getTimePoints().getTimePointsOrdered().stream() - .map(TimePoint::getId) - .collect(Collectors.toList()); - final List setupIds = seq.getViewSetupsOrdered().stream() - .map(BasicViewSetup::getId) - .collect(Collectors.toList()); - - N5Writer n5 = new N5FSWriter(n5File.getAbsolutePath()); - - // write Mipmap descriptions - for (final int setupId : setupIds) { - final String pathName = getPathName(setupId); - final int[][] downsamplingFactors = perSetupMipmapInfo.get(setupId).getExportResolutions(); - final DataType dataType = N5Utils.dataType(Cast.unchecked(imgLoader.getSetupImgLoader(setupId).getImageType())); - n5.createGroup(pathName); - n5.setAttribute(pathName, DOWNSAMPLING_FACTORS_KEY, downsamplingFactors); - n5.setAttribute(pathName, DATA_TYPE_KEY, dataType); - } - - - // calculate number of tasks for progressWriter - int numTasks = 0; // first task is for writing mipmap descriptions etc... - for (final int timepointIdSequence : timepointIds) - for (final int setupIdSequence : setupIds) - if (seq.getViewDescriptions().get(new ViewId(timepointIdSequence, setupIdSequence)).isPresent()) - numTasks++; - int numCompletedTasks = 0; - - final ExecutorService executorService = Executors.newFixedThreadPool(numCellCreatorThreads); - try { - // write image data for all views - final int numTimepoints = timepointIds.size(); - int timepointIndex = 0; - for (final int timepointId : timepointIds) { - progressWriter.out().printf("proccessing timepoint %d / %d\n", ++timepointIndex, numTimepoints); - - // assemble the viewsetups that are present in this timepoint - final ArrayList setupsTimePoint = new ArrayList<>(); - for (final int setupId : setupIds) - if (seq.getViewDescriptions().get(new ViewId(timepointId, setupId)).isPresent()) - setupsTimePoint.add(setupId); - - final int numSetups = setupsTimePoint.size(); - int setupIndex = 0; - for (final int setupId : setupsTimePoint) { - progressWriter.out().printf("proccessing setup %d / %d\n", ++setupIndex, numSetups); - - final ExportMipmapInfo mipmapInfo = perSetupMipmapInfo.get(setupId); - final double startCompletionRatio = (double) numCompletedTasks++ / numTasks; - final double endCompletionRatio = (double) numCompletedTasks / numTasks; - final ProgressWriter subProgressWriter = new SubTaskProgressWriter(progressWriter, startCompletionRatio, endCompletionRatio); - writeScalePyramid( - n5, compression, downsamplingMethod, - imgLoader, setupId, timepointId, mipmapInfo, - executorService, numCellCreatorThreads, - loopbackHeuristic, afterEachPlane, subProgressWriter); - - - // additional attributes for paintera compatibility - final String pathName = getPathName(setupId, timepointId); - n5.createGroup(pathName); - n5.setAttribute(pathName, MULTI_SCALE_KEY, true); - final VoxelDimensions voxelSize = seq.getViewSetups().get(setupId).getVoxelSize(); - if (voxelSize != null) { - final double[] resolution = new double[voxelSize.numDimensions()]; - voxelSize.dimensions(resolution); - n5.setAttribute(pathName, RESOLUTION_KEY, resolution); - } - final int[][] downsamplingFactors = perSetupMipmapInfo.get(setupId).getExportResolutions(); - for (int l = 0; l < downsamplingFactors.length; ++l) - n5.setAttribute(getPathName(setupId, timepointId, l), DOWNSAMPLING_FACTORS_KEY, downsamplingFactors[l]); - } - } - } finally { - executorService.shutdown(); - } - - progressWriter.setProgress(1.0); - } - - static & NativeType> void writeScalePyramid( - final N5Writer n5, - final Compression compression, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, - final BasicImgLoader imgLoader, - final int setupId, - final int timepointId, - final ExportMipmapInfo mipmapInfo, - final ExecutorService executorService, - final int numThreads, - final ExportScalePyramid.LoopbackHeuristic loopbackHeuristic, - final ExportScalePyramid.AfterEachPlane afterEachPlane, - ProgressWriter progressWriter) throws IOException { - final BasicSetupImgLoader setupImgLoader = Cast.unchecked(imgLoader.getSetupImgLoader(setupId)); - final RandomAccessibleInterval img = setupImgLoader.getImage(timepointId); - final T type = setupImgLoader.getImageType(); - final N5DatasetIO io = new N5DatasetIO<>(n5, compression, setupId, timepointId, type); - ExportScalePyramid.writeScalePyramid( - img, type, mipmapInfo, downsamplingMethod, io, - executorService, numThreads, - loopbackHeuristic, afterEachPlane, progressWriter); - } - - static class N5Dataset { - final String pathName; - final DatasetAttributes attributes; - - public N5Dataset(final String pathName, final DatasetAttributes attributes) { - this.pathName = pathName; - this.attributes = attributes; - } - } - - static class N5DatasetIO & NativeType> implements ExportScalePyramid.DatasetIO { - private final N5Writer n5; - private final Compression compression; - private final int setupId; - private final int timepointId; - private final DataType dataType; - private final T type; - private final Function, DataBlock> getDataBlock; - - public N5DatasetIO(final N5Writer n5, final Compression compression, final int setupId, final int timepointId, final T type) { - this.n5 = n5; - this.compression = compression; - this.setupId = setupId; - this.timepointId = timepointId; - this.dataType = N5Utils.dataType(type); - this.type = type; - - switch (dataType) { - case UINT8: - getDataBlock = b -> new ByteArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case UINT16: - getDataBlock = b -> new ShortArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case UINT32: - getDataBlock = b -> new IntArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case UINT64: - getDataBlock = b -> new LongArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT8: - getDataBlock = b -> new ByteArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT16: - getDataBlock = b -> new ShortArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT32: - getDataBlock = b -> new IntArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT64: - getDataBlock = b -> new LongArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case FLOAT32: - getDataBlock = b -> new FloatArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case FLOAT64: - getDataBlock = b -> new DoubleArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - default: - throw new IllegalArgumentException(); - } - } - - @Override - public N5Dataset createDataset(final int level, final long[] dimensions, final int[] blockSize) throws IOException { - final String pathName = getPathName(setupId, timepointId, level); - n5.createDataset(pathName, dimensions, blockSize, dataType, compression); - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - return new N5Dataset(pathName, attributes); - } - - @Override - public void writeBlock(final N5Dataset dataset, final ExportScalePyramid.Block dataBlock) throws IOException { - n5.writeBlock(dataset.pathName, dataset.attributes, getDataBlock.apply(dataBlock)); - } - - @Override - public void flush(final N5Dataset dataset) { - } - - @Override - public RandomAccessibleInterval getImage(final int level) throws IOException { - final String pathName = getPathName(setupId, timepointId, level); - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - final long[] dimensions = attributes.getDimensions(); - final int[] cellDimensions = attributes.getBlockSize(); - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - final SimpleCacheArrayLoader cacheArrayLoader = N5ImageLoader.createCacheArrayLoader(n5, pathName); - return new ReadOnlyCachedCellImgFactory().createWithCacheLoader( - dimensions, type, - key -> { - final int n = grid.numDimensions(); - final long[] cellMin = new long[n]; - final int[] cellDims = new int[n]; - final long[] cellGridPosition = new long[n]; - grid.getCellDimensions(key, cellMin, cellDims); - grid.getCellGridPositionFlat(key, cellGridPosition); - return new Cell<>(cellDims, cellMin, cacheArrayLoader.loadArray(cellGridPosition, cellDims)); - }, - options().cellDimensions(cellDimensions)); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/N5OMEZarrImageLoader.java b/src/main/java/org/embl/mobie/io/ome/zarr/loaders/N5OMEZarrImageLoader.java deleted file mode 100644 index cdcf17e1..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/N5OMEZarrImageLoader.java +++ /dev/null @@ -1,664 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.loaders; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; - -import org.embl.mobie.io.ome.zarr.readers.N5OmeZarrReader; -import org.embl.mobie.io.ome.zarr.readers.N5S3OmeZarrReader; -import org.embl.mobie.io.ome.zarr.util.N5OMEZarrCacheArrayLoader; -import org.embl.mobie.io.ome.zarr.util.OmeZarrMultiscales; -import org.embl.mobie.io.ome.zarr.util.ZarrAxes; -import org.embl.mobie.io.ome.zarr.util.ZarrAxis; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5Reader; -import org.jetbrains.annotations.NotNull; - -import bdv.AbstractViewerSetupImgLoader; -import bdv.ViewerImgLoader; -import bdv.cache.CacheControl; -import bdv.img.cache.SimpleCacheArrayLoader; -import bdv.img.cache.VolatileGlobalCellCache; -import bdv.util.ConstantRandomAccessible; -import bdv.util.MipmapTransforms; - -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.generic.sequence.ImgLoaderHint; -import mpicbg.spim.data.registration.ViewRegistration; -import mpicbg.spim.data.registration.ViewRegistrations; -import mpicbg.spim.data.sequence.Angle; -import mpicbg.spim.data.sequence.Channel; -import mpicbg.spim.data.sequence.DefaultVoxelDimensions; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import mpicbg.spim.data.sequence.Illumination; -import mpicbg.spim.data.sequence.MultiResolutionImgLoader; -import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; -import mpicbg.spim.data.sequence.SequenceDescription; -import mpicbg.spim.data.sequence.Tile; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.TimePoints; -import mpicbg.spim.data.sequence.ViewSetup; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.FinalInterval; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; -import net.imglib2.cache.queue.BlockingFetchQueues; -import net.imglib2.cache.queue.FetcherThreads; -import net.imglib2.cache.volatiles.CacheHints; -import net.imglib2.cache.volatiles.LoadingStrategy; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.img.cell.CellImg; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.integer.ByteType; -import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.LongType; -import net.imglib2.type.numeric.integer.ShortType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import net.imglib2.type.numeric.integer.UnsignedIntType; -import net.imglib2.type.numeric.integer.UnsignedLongType; -import net.imglib2.type.numeric.integer.UnsignedShortType; -import net.imglib2.type.numeric.real.DoubleType; -import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.type.volatiles.VolatileByteType; -import net.imglib2.type.volatiles.VolatileDoubleType; -import net.imglib2.type.volatiles.VolatileFloatType; -import net.imglib2.type.volatiles.VolatileIntType; -import net.imglib2.type.volatiles.VolatileLongType; -import net.imglib2.type.volatiles.VolatileShortType; -import net.imglib2.type.volatiles.VolatileUnsignedByteType; -import net.imglib2.type.volatiles.VolatileUnsignedIntType; -import net.imglib2.type.volatiles.VolatileUnsignedLongType; -import net.imglib2.type.volatiles.VolatileUnsignedShortType; -import net.imglib2.util.Cast; -import net.imglib2.view.Views; - -import static org.embl.mobie.io.ome.zarr.util.OmeZarrMultiscales.MULTI_SCALE_KEY; - - -public class N5OMEZarrImageLoader implements ViewerImgLoader, MultiResolutionImgLoader { - - private static final int C = 3; - private static final int T = 4; - public static boolean logging = false; - public final N5Reader n5; - /** - * Maps setup id to {@link SetupImgLoader}. - */ - private final Map> setupImgLoaders = new HashMap<>(); - private final Map setupToPathname = new HashMap<>(); - private final Map setupToMultiscale = new HashMap<>(); - private final Map setupToAttributes = new HashMap<>(); - private final Map setupToChannel = new HashMap<>(); - protected AbstractSequenceDescription seq; - protected ViewRegistrations viewRegistrations; - private volatile boolean isOpen = false; - private int sequenceTimepoints = 0; - private FetcherThreads fetchers; - private VolatileGlobalCellCache cache; - private BlockingFetchQueues> queue; - - /** - * The sequenceDescription and viewRegistrations are known already, typically read from xml. - * - * @param n5Reader reader - * @param sequenceDescription - */ - @Deprecated - public N5OMEZarrImageLoader(N5Reader n5Reader, AbstractSequenceDescription sequenceDescription) { - this.n5 = n5Reader; - this.seq = sequenceDescription; // TODO: it is better to fetch from within Zarr - try { - initSetups(); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public N5OMEZarrImageLoader(N5Reader n5Reader) { - this.n5 = n5Reader; - fetchSequenceDescriptionAndViewRegistrations(); - } - - public N5OMEZarrImageLoader(N5Reader n5Reader, BlockingFetchQueues> queue) { - this.n5 = n5Reader; - this.queue = queue; - fetchSequenceDescriptionAndViewRegistrations(); - } - - - private void fetchSequenceDescriptionAndViewRegistrations() { - try { - initSetups(); - - ArrayList viewSetups = new ArrayList<>(); - ArrayList viewRegistrationList = new ArrayList<>(); - - int numSetups = setupToMultiscale.size(); - for (int setupId = 0; setupId < numSetups; setupId++) { - ViewSetup viewSetup = createViewSetup(setupId); - ZarrAxes zarrAxes = setupToMultiscale.get(setupId).axes; - int setupTimepoints = 1; - if (zarrAxes.hasTimepoints()) - setupTimepoints = (int) setupToAttributes.get(setupId).getDimensions()[zarrAxes.timeIndex()]; - sequenceTimepoints = Math.max(setupTimepoints, sequenceTimepoints); - viewSetups.add(viewSetup); - viewRegistrationList.addAll(createViewRegistrations(setupId, setupTimepoints)); - } - - viewRegistrations = new ViewRegistrations(viewRegistrationList); - - seq = new SequenceDescription(new TimePoints(createTimePoints(sequenceTimepoints)), viewSetups); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - @NotNull - private ArrayList createTimePoints(int sequenceTimepoints) { - ArrayList timePoints = new ArrayList<>(); - for (int t = 0; t < sequenceTimepoints; t++) { - timePoints.add(new TimePoint(t)); - } - return timePoints; - } - - private void initSetups() throws IOException { - int setupId = -1; - OmeZarrMultiscales[] multiscales = getMultiscale(""); // returns multiscales[ 0 ] - for (OmeZarrMultiscales multiscale : multiscales) { - DatasetAttributes attributes = getDatasetAttributes(multiscale.datasets[0].path); - - // TODO: Maybe AbstractOmeZarrReader which has .getAxes() - ZarrAxes zarrAxes = n5 instanceof N5OmeZarrReader ? ((N5OmeZarrReader) n5).getAxes() : - n5 instanceof N5S3OmeZarrReader ? ((N5S3OmeZarrReader) n5).getAxes() : ZarrAxes.TCZYX; - List zarrAxesList = n5 instanceof N5OmeZarrReader ? ((N5OmeZarrReader) n5).getZarrAxes() : - n5 instanceof N5S3OmeZarrReader ? ((N5S3OmeZarrReader) n5).getZarrAxes() : null; - - multiscale.axes = zarrAxes; - multiscale.zarrAxisList = zarrAxesList; - - long nC = 1; - if (zarrAxes.hasChannels()) { - nC = attributes.getDimensions()[zarrAxes.channelIndex()]; - } - - for (int c = 0; c < nC; c++) { - // each channel is one setup - setupId++; - setupToChannel.put(setupId, c); - - // all channels have the same multiscale and attributes - setupToMultiscale.put(setupId, multiscale); - setupToAttributes.put(setupId, attributes); - setupToPathname.put(setupId, ""); - } - } - - List labels = n5.getAttribute("labels", "labels", List.class); - if (labels != null) { - for (String label : labels) { - setupId++; - setupToChannel.put(setupId, 0); // TODO: https://github.com/ome/ngff/issues/19 - String pathName = "labels/" + label; - multiscales = getMultiscale(pathName); - for (OmeZarrMultiscales multiscale : multiscales) { - DatasetAttributes attributes = getDatasetAttributes(pathName + "/" + multiscale.datasets[0].path); - - ZarrAxes zarrAxes = n5 instanceof N5OmeZarrReader ? ((N5OmeZarrReader) n5).getAxes() : - n5 instanceof N5S3OmeZarrReader ? ((N5S3OmeZarrReader) n5).getAxes() : ZarrAxes.TCZYX; - List zarrAxesList = n5 instanceof N5OmeZarrReader ? ((N5OmeZarrReader) n5).getZarrAxes() : - n5 instanceof N5S3OmeZarrReader ? ((N5S3OmeZarrReader) n5).getZarrAxes() : null; - - multiscale.axes = zarrAxes; - multiscale.zarrAxisList = zarrAxesList; - - setupToMultiscale.put(setupId, multiscale); - setupToAttributes.put(setupId, attributes); - setupToPathname.put(setupId, pathName); - } - } - } - } - - /** - * The dataType, number of channels and number of timepoints are stored - * in the different pyramid levels (datasets). - * According to the spec all datasets must be indentical in that sense - * and we thus fetch this information from level 0. - *

- * In addition, level 0 contains the information about the size of the full resolution image. - * - * @param pathName - * @return - * @throws IOException - */ - private DatasetAttributes getDatasetAttributes(String pathName) throws IOException { - return n5.getDatasetAttributes(pathName); - } - - /** - * The primary use case for multiple multiscales at the moment (the one listed in the spec) - * is multiple different downsamplings. - * A base image with two multiscales each with a different scale or a different method. - *

- * I don't know a good logic right now how to deal with different pyramids, - * thus I just fetch the first one, i.e. multiscales[ 0 ]. - *

- * ??? There's no need for the two multiscales to have the same base though. - * ??? So it would also allow you to just have two pyramids (in our jargon) in the same zgroup. - * - * @param pathName - * @return - * @throws IOException - */ - private OmeZarrMultiscales[] getMultiscale(String pathName) throws IOException { - OmeZarrMultiscales[] multiscales = n5.getAttribute(pathName, MULTI_SCALE_KEY, OmeZarrMultiscales[].class); - if (multiscales == null) { - String location = ""; - if (n5 instanceof N5S3OmeZarrReader) { - final N5S3OmeZarrReader s3ZarrReader = (N5S3OmeZarrReader) n5; - s3ZarrReader.setDimensionSeparator("/"); - location += "service endpoint: " + s3ZarrReader.getServiceEndpoint(); - location += "; bucket: " + s3ZarrReader.getBucketName(); - location += "; container path: " + s3ZarrReader.getContainerPath(); - location += "; path: " + pathName; - location += "; attribute: " + MULTI_SCALE_KEY; - } else { - location += " path: " + pathName; - } - throw new UnsupportedOperationException("Could not find multiscales at " + location); - } - return multiscales; - } - - public AbstractSequenceDescription getSequenceDescription() { - //open(); - seq.setImgLoader(Cast.unchecked(this)); - return seq; - } - - public ViewRegistrations getViewRegistrations() { - return viewRegistrations; - } - - private void open() { - if (!isOpen) { - synchronized (this) { - if (isOpen) - return; - - try { - int maxNumLevels = 0; - final List setups = seq.getViewSetupsOrdered(); - for (final BasicViewSetup setup : setups) { - final int setupId = setup.getId(); - final SetupImgLoader setupImgLoader = createSetupImgLoader(setupId); - setupImgLoaders.put(setupId, setupImgLoader); - if (setupImgLoader != null) { - maxNumLevels = Math.max(maxNumLevels, setupImgLoader.numMipmapLevels()); - } - } - if (queue == null) { - final int numFetcherThreads = Math.max(1, Runtime.getRuntime().availableProcessors()); - queue = new BlockingFetchQueues<>(maxNumLevels, numFetcherThreads); - fetchers = new FetcherThreads(queue, numFetcherThreads); - } - cache = new VolatileGlobalCellCache(queue); - - } catch (IOException e) { - throw new RuntimeException(e); - } - - isOpen = true; - } - } - } - - @NotNull - private ArrayList createViewRegistrations(int setupId, int setupTimePoints) { - ArrayList viewRegistrations = new ArrayList<>(); - // 3D transform of full resolution level - AffineTransform3D transform = getAffineTransform3D(setupId, 0); - for (int t = 0; t < setupTimePoints; t++) { - viewRegistrations.add(new ViewRegistration(t, setupId, transform)); - } - - return viewRegistrations; - } - - private double[] getXYZScale(int setupId, OmeZarrMultiscales.CoordinateTransformations coordinateTransformations) { - double[] scale = coordinateTransformations.scale; - double[] xyzScale = null; - ZarrAxes zarrAxes = setupToMultiscale.get(setupId).axes; - List zarrAxesList = setupToMultiscale.get(setupId).zarrAxisList; - if (scale != null && zarrAxesList != null) { - xyzScale = new double[]{ - scale[zarrAxes.axisIndex("x", false)], - scale[zarrAxes.axisIndex("y", false)], - zarrAxes.hasZAxis() ? scale[zarrAxes.axisIndex("z", false)] : 1.0 - }; - } - return xyzScale; - } - - @NotNull - private AffineTransform3D getAffineTransform3D(int setupId, int datasetId) { - OmeZarrMultiscales multiscales = setupToMultiscale.get(setupId); - AffineTransform3D transform = new AffineTransform3D(); - if (multiscales.datasets[datasetId].coordinateTransformations != null) { - double[] scale = getXYZScale(setupId, multiscales.datasets[datasetId].coordinateTransformations[0]); - if (scale != null) { - transform.scale(scale[0], scale[1], scale[2]); - } - - double[] translation = multiscales.datasets[datasetId].coordinateTransformations[0].translation; - if (translation != null) { - transform.translate(translation); - } - } - return transform; - } - - private VoxelDimensions getVoxelDimensions3D(int setupId, int datasetId) { - OmeZarrMultiscales multiscales = setupToMultiscale.get(setupId); - - ZarrAxes zarrAxes = setupToMultiscale.get(setupId).axes; - List zarrAxesList = setupToMultiscale.get(setupId).zarrAxisList; - if (multiscales.datasets[datasetId].coordinateTransformations != null && zarrAxesList != null) { - double[] scale = getXYZScale(setupId, multiscales.datasets[datasetId].coordinateTransformations[0]); - // get unit of last dimension, under assumption this is the X axis (i.e. a space axis) - String unit = zarrAxesList.get(zarrAxesList.size() - 1).getUnit(); - - if (scale != null && unit != null) { - if (zarrAxes.hasZAxis()) { - return new FinalVoxelDimensions(unit, scale); - } else { - return new FinalVoxelDimensions(unit, new double[]{scale[0], scale[1], 1.0}); - } - } - } - - return new DefaultVoxelDimensions(3); - } - - private Dimensions getSpatialDimensions(int setupId, DatasetAttributes attributes) { - final long[] spatialDimensions = new long[3]; - long[] attributeDimensions = attributes.getDimensions(); - Arrays.fill(spatialDimensions, 1); - ZarrAxes zarrAxes = setupToMultiscale.get(setupId).axes; - final Map spatialToZarr = zarrAxes.spatialToZarr(); - for (Map.Entry entry : spatialToZarr.entrySet()) { - spatialDimensions[entry.getKey()] = attributeDimensions[entry.getValue()]; - } - return new FinalDimensions(spatialDimensions); - } - - private ViewSetup createViewSetup(int setupId) { - OmeZarrMultiscales multiscale = setupToMultiscale.get(setupId); - Dimensions dimensions = getSpatialDimensions(setupId, setupToAttributes.get(setupId)); - VoxelDimensions voxelDimensions = getVoxelDimensions3D(setupId, 0); - - Tile tile = new Tile(0); - - Channel channel; - if (setupToPathname.get(setupId).contains("labels")) - channel = new Channel(setupToChannel.get(setupId), "labels"); - else - channel = new Channel(setupToChannel.get(setupId)); - - Angle angle = new Angle(0); - Illumination illumination = new Illumination(0); - String name = readName(multiscale, setupId); - //if ( setupToPathname.get( setupId ).contains( "labels" )) - // viewSetup.setAttribute( new ImageType( ImageType.Type.IntensityImage ) ); - return new ViewSetup(setupId, name, dimensions, voxelDimensions, tile, channel, angle, illumination); - } - - private String readName(OmeZarrMultiscales multiscale, int setupId) { - if (multiscale.name != null) - return multiscale.name; - else - return "image " + setupId; - } - - /** - * Clear the cache. Images that were obtained from - * this loader before {@link #close()} will stop working. Requesting images - * after {@link #close()} will cause the n5 to be reopened (with a - * new cache). - */ - public void close() { - if (isOpen) { - synchronized (this) { - if (!isOpen) - return; - if (fetchers != null) - fetchers.shutdown(); - cache.clearCache(); - isOpen = false; - } - } - } - - @Override - public SetupImgLoader getSetupImgLoader(final int setupId) { - open(); - return setupImgLoaders.get(setupId); - } - - private , V extends Volatile & NativeType> SetupImgLoader createSetupImgLoader(final int setupId) throws IOException { - switch (setupToAttributes.get(setupId).getDataType()) { - case UINT8: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedByteType(), new VolatileUnsignedByteType())); - case UINT16: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedShortType(), new VolatileUnsignedShortType())); - case UINT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedIntType(), new VolatileUnsignedIntType())); - case UINT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedLongType(), new VolatileUnsignedLongType())); - case INT8: - return Cast.unchecked(new SetupImgLoader<>(setupId, new ByteType(), new VolatileByteType())); - case INT16: - return Cast.unchecked(new SetupImgLoader<>(setupId, new ShortType(), new VolatileShortType())); - case INT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new IntType(), new VolatileIntType())); - case INT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new LongType(), new VolatileLongType())); - case FLOAT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new FloatType(), new VolatileFloatType())); - case FLOAT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new DoubleType(), new VolatileDoubleType())); - } - return null; - } - - @Override - public CacheControl getCacheControl() { - open(); - return cache; - } - - // TODO: Add description - private int[] getBlockSize(int setupId, DatasetAttributes attributes) { - ZarrAxes zarrAxes = setupToMultiscale.get(setupId).axes; - if (!zarrAxes.hasZAxis()) { - return fillBlockSize(attributes); - } else { - return Arrays.stream(attributes.getBlockSize()).limit(3).toArray(); - } - } - - private int[] fillBlockSize(DatasetAttributes attributes) { - int[] tmp = new int[3]; - tmp[0] = Arrays.stream(attributes.getBlockSize()).toArray()[0]; - tmp[1] = Arrays.stream(attributes.getBlockSize()).toArray()[1]; - tmp[2] = 1; - return tmp; - } - - private SimpleCacheArrayLoader createCacheArrayLoader(final N5Reader n5, final String pathName, int setupId, int channel, int timepointId, CellGrid grid) throws IOException { - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - ZarrAxes zarrAxes = setupToMultiscale.get(setupId).axes; - return new N5OMEZarrCacheArrayLoader<>(n5, pathName, channel, timepointId, attributes, grid, zarrAxes); - } - - private class SetupImgLoader, V extends Volatile & NativeType> - extends AbstractViewerSetupImgLoader - implements MultiResolutionSetupImgLoader { - private final int setupId; - - private final double[][] mipmapResolutions; - - private final AffineTransform3D[] mipmapTransforms; - - public SetupImgLoader(final int setupId, final T type, final V volatileType) throws IOException { - super(type, volatileType); - this.setupId = setupId; - mipmapResolutions = readMipmapResolutions(); - mipmapTransforms = new AffineTransform3D[mipmapResolutions.length]; - for (int level = 0; level < mipmapResolutions.length; level++) { - mipmapTransforms[level] = MipmapTransforms.getMipmapTransformDefault(mipmapResolutions[level]); - } - } - - /** - * @return - * @throws IOException - */ - private double[][] readMipmapResolutions() throws IOException { - OmeZarrMultiscales multiscale = setupToMultiscale.get(setupId); - double[][] mipmapResolutions = new double[multiscale.datasets.length][]; - - long[] dimensionsOfLevel0 = getDatasetAttributes(getPathName(setupId, 0)).getDimensions(); - mipmapResolutions[0] = new double[]{1.0, 1.0, 1.0}; - - for (int level = 1; level < mipmapResolutions.length; level++) { - long[] dimensions = getDatasetAttributes(getPathName(setupId, level)).getDimensions(); - mipmapResolutions[level] = new double[3]; - for (int d = 0; d < 2; d++) { - mipmapResolutions[level][d] = Math.round(1.0 * dimensionsOfLevel0[d] / dimensions[d]); - } - mipmapResolutions[level][2] = multiscale.axes.hasZAxis() ? Math.round(1.0 * dimensionsOfLevel0[2] / dimensions[2]) : 1.0; - } - - return mipmapResolutions; - } - - @Override - public RandomAccessibleInterval getVolatileImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BUDGETED, volatileType); - } - - @Override - public RandomAccessibleInterval getImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BLOCKING, type); - } - - @Override - public Dimensions getImageSize(final int timepointId, final int level) { - final String pathName = getPathName(setupId, level); - try { - final DatasetAttributes attributes = getDatasetAttributes(pathName); - return new FinalDimensions(attributes.getDimensions()); - } catch (Exception e) { - throw new RuntimeException("Could not read from " + pathName); - } - } - - @NotNull - public String getPathName(int setupId, int level) { - return setupToPathname.get(setupId) + "/" + setupToMultiscale.get(this.setupId).datasets[level].path; - } - - @Override - public double[][] getMipmapResolutions() { - return mipmapResolutions; - } - - @Override - public AffineTransform3D[] getMipmapTransforms() { - return mipmapTransforms; - } - - @Override - public int numMipmapLevels() { - return mipmapResolutions.length; - } - - @Override - public VoxelDimensions getVoxelSize(final int timepointId) { - return null; - } - - /** - * Create a {@link CellImg} backed by the cache. - */ - private > RandomAccessibleInterval prepareCachedImage(final int timepointId, final int level, final LoadingStrategy loadingStrategy, final T type) { - try { - final String pathName = getPathName(setupId, level); - final DatasetAttributes attributes = getDatasetAttributes(pathName); - - if (logging) { - System.out.println("Preparing image " + pathName + " of data type " + attributes.getDataType()); - } - - // The below dimensions refer to one time point and one channel. - // That means they are either 2D or 3D. - long[] dimensions = getSpatialDimensions(setupId, attributes).dimensionsAsLongArray(); - final int[] cellDimensions = getBlockSize(setupId, attributes); - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - - final int priority = numMipmapLevels() - 1 - level; - final CacheHints cacheHints = new CacheHints(loadingStrategy, priority, false); - - final SimpleCacheArrayLoader loader = createCacheArrayLoader(n5, pathName, setupId, setupToChannel.get(setupId), timepointId, grid); - return cache.createImg(grid, timepointId, setupId, level, cacheHints, loader, type); - } catch (IOException e) { - System.err.println(String.format( - "image data for timepoint %d setup %d level %d could not be found.%n", - timepointId, setupId, level)); - return Views.interval( - new ConstantRandomAccessible<>(type.createVariable(), 3), - new FinalInterval(1, 1, 1)); - } - } - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/N5S3OMEZarrImageLoader.java b/src/main/java/org/embl/mobie/io/ome/zarr/loaders/N5S3OMEZarrImageLoader.java deleted file mode 100644 index 1670b41d..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/N5S3OMEZarrImageLoader.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.loaders; - -import java.io.IOException; - -import org.embl.mobie.io.n5.loaders.S3ImageLoader; -import org.embl.mobie.io.ome.zarr.readers.N5S3OmeZarrReader; -import org.embl.mobie.io.util.S3Utils; - -import com.amazonaws.services.s3.AmazonS3; - -import bdv.cache.SharedQueue; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; - -public class N5S3OMEZarrImageLoader extends N5OMEZarrImageLoader implements S3ImageLoader { - private final String serviceEndpoint; - private final String signingRegion; - private final String bucketName; - private final String key; - - - // sequenceDescription has been read from xml - public N5S3OMEZarrImageLoader(String serviceEndpoint, String signingRegion, String bucketName, String key, String dimensionSeparator, AbstractSequenceDescription sequenceDescription) throws IOException { - super(new N5S3ZarrReaderCreator().create(serviceEndpoint, signingRegion, bucketName, key, dimensionSeparator), sequenceDescription); - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - // sequenceDescription will be read from zarr - public N5S3OMEZarrImageLoader(String serviceEndpoint, String signingRegion, String bucketName, String key, String dimensionSeparator) throws IOException { - super(new N5S3ZarrReaderCreator().create(serviceEndpoint, signingRegion, bucketName, key, dimensionSeparator)); - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - public N5S3OMEZarrImageLoader(String serviceEndpoint, String signingRegion, String bucketName, String key, String dimensionSeparator, SharedQueue sharedQueue) throws IOException { - super(new N5S3ZarrReaderCreator().create(serviceEndpoint, signingRegion, bucketName, key, dimensionSeparator), sharedQueue); - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - public String getServiceEndpoint() { - return serviceEndpoint; - } - - public String getSigningRegion() { - return signingRegion; - } - - public String getBucketName() { - return bucketName; - } - - public String getKey() { - return key; - } - - static class N5S3ZarrReaderCreator { - public N5S3OmeZarrReader create(String serviceEndpoint, String signingRegion, String bucketName, String key, String dimensionSeparator) throws IOException { - final AmazonS3 s3 = S3Utils.getS3Client(serviceEndpoint, signingRegion, bucketName); - return new N5S3OmeZarrReader(s3, serviceEndpoint, bucketName, key, dimensionSeparator); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlIoN5S3ZarrImageLoader.java b/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlIoN5S3ZarrImageLoader.java deleted file mode 100644 index e51d6965..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlIoN5S3ZarrImageLoader.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.loaders.xml; - - -import java.io.File; -import java.io.IOException; - -import org.embl.mobie.io.ome.zarr.loaders.N5S3OMEZarrImageLoader; -import org.jdom2.Element; - -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.ImgLoaderIo; -import mpicbg.spim.data.generic.sequence.XmlIoBasicImgLoader; - -import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; - -@ImgLoaderIo(format = "ome.n5.zarr.s3", type = N5S3OMEZarrImageLoader.class) -public class XmlIoN5S3ZarrImageLoader implements XmlIoBasicImgLoader { - public static final String SERVICE_ENDPOINT = "ServiceEndpoint"; - public static final String SIGNING_REGION = "SigningRegion"; - public static final String BUCKET_NAME = "BucketName"; - public static final String KEY = "Key"; - - @Override - public Element toXml(final N5S3OMEZarrImageLoader imgLoader, final File basePath) { - final Element elem = new Element("ImageLoader"); - elem.setAttribute(IMGLOADER_FORMAT_ATTRIBUTE_NAME, "ome.n5.zarr.s3"); - elem.setAttribute("version", "1.0"); - elem.addContent(XmlHelpers.textElement(SERVICE_ENDPOINT, imgLoader.getServiceEndpoint())); - elem.addContent(XmlHelpers.textElement(SIGNING_REGION, imgLoader.getSigningRegion())); - elem.addContent(XmlHelpers.textElement(BUCKET_NAME, imgLoader.getBucketName())); - elem.addContent(XmlHelpers.textElement(KEY, imgLoader.getKey())); - - return elem; - } - - @Override - public N5S3OMEZarrImageLoader fromXml(final Element elem, final File basePath, final AbstractSequenceDescription sequenceDescription) { -// final String version = elem.getAttributeValue( "version" ); - - final String serviceEndpoint = XmlHelpers.getText(elem, SERVICE_ENDPOINT); - final String signingRegion = XmlHelpers.getText(elem, SIGNING_REGION); - final String bucketName = XmlHelpers.getText(elem, BUCKET_NAME); - final String key = XmlHelpers.getText(elem, KEY); - try { - return new N5S3OMEZarrImageLoader(serviceEndpoint, signingRegion, bucketName, key, "/", sequenceDescription); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlN5OmeZarrImageLoader.java b/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlN5OmeZarrImageLoader.java deleted file mode 100644 index 4aebec3e..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlN5OmeZarrImageLoader.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.loaders.xml; - -import java.io.File; - -import org.embl.mobie.io.ome.zarr.loaders.N5OMEZarrImageLoader; -import org.embl.mobie.io.ome.zarr.readers.N5OmeZarrReader; -import org.jdom2.Element; - -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.ImgLoaderIo; -import mpicbg.spim.data.generic.sequence.XmlIoBasicImgLoader; - -import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; - -@ImgLoaderIo(format = "bdv.ome.zarr", type = N5OMEZarrImageLoader.class) -public class XmlN5OmeZarrImageLoader implements XmlIoBasicImgLoader { - public static final String OmeZarr = "ome.zarr"; - - public static String getDatasetsPathFromXml(final Element parent, final String basePath) { - final Element elem = parent.getChild(OmeZarr); - if (elem == null) - return null; - final String path = elem.getText(); - final String pathType = elem.getAttributeValue("type"); - final boolean isRelative = null != pathType && pathType.equals("relative"); - if (isRelative) { - if (basePath == null) - return null; - else { - return new File(basePath).getParent() + File.separator + path; - } - } else - return path; - } - - @Override - public Element toXml(final N5OMEZarrImageLoader imgLoader, final File basePath) { - final Element elem = new Element("ImageLoader"); - elem.setAttribute(IMGLOADER_FORMAT_ATTRIBUTE_NAME, "bdv.ome.zarr"); - elem.setAttribute("version", "0.2"); - N5OmeZarrReader reader = (N5OmeZarrReader) imgLoader.n5; - elem.addContent(XmlHelpers.pathElement(OmeZarr, new File(reader.getBasePath()), basePath)); - return elem; - } - - @Override - public N5OMEZarrImageLoader fromXml(Element elem, File basePath, AbstractSequenceDescription sequenceDescription) { - return null; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlN5S3OmeZarrImageLoader.java b/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlN5S3OmeZarrImageLoader.java deleted file mode 100644 index 295b7d58..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/loaders/xml/XmlN5S3OmeZarrImageLoader.java +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.loaders.xml; - -import java.io.File; -import java.io.IOException; - -import org.embl.mobie.io.ome.zarr.loaders.N5S3OMEZarrImageLoader; -import org.jdom2.Element; - -import mpicbg.spim.data.XmlHelpers; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.ImgLoaderIo; -import mpicbg.spim.data.generic.sequence.XmlIoBasicImgLoader; - -import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; - -@ImgLoaderIo(format = "bdv.ome.zarr.s3", type = N5S3OMEZarrImageLoader.class) -public class XmlN5S3OmeZarrImageLoader implements XmlIoBasicImgLoader { - public static final String SERVICE_ENDPOINT = "ServiceEndpoint"; - public static final String SIGNING_REGION = "SigningRegion"; - public static final String BUCKET_NAME = "BucketName"; - public static final String KEY = "Key"; - - @Override - public Element toXml(final N5S3OMEZarrImageLoader imgLoader, final File basePath) { - final Element elem = new Element("ImageLoader"); - elem.setAttribute(IMGLOADER_FORMAT_ATTRIBUTE_NAME, "bdv.ome.zarr.s3"); - elem.setAttribute("version", "0.2"); - elem.addContent(XmlHelpers.textElement(SERVICE_ENDPOINT, imgLoader.getServiceEndpoint())); - elem.addContent(XmlHelpers.textElement(SIGNING_REGION, imgLoader.getSigningRegion())); - elem.addContent(XmlHelpers.textElement(BUCKET_NAME, imgLoader.getBucketName())); - elem.addContent(XmlHelpers.textElement(KEY, imgLoader.getKey())); - return elem; - } - - public Element toXml(String serviceEndpoint, String signingRegion, String bucketName, String key) { - final Element elem = new Element("ImageLoader"); - elem.setAttribute(IMGLOADER_FORMAT_ATTRIBUTE_NAME, "bdv.ome.zarr.s3"); - elem.addContent(new Element(KEY).addContent(key)); - elem.addContent(new Element(SIGNING_REGION).addContent(signingRegion)); - elem.addContent(new Element(SERVICE_ENDPOINT).addContent(serviceEndpoint)); - elem.addContent(new Element(BUCKET_NAME).addContent(bucketName)); - - return elem; - } - - @Override - public N5S3OMEZarrImageLoader fromXml(Element elem, File basePath, AbstractSequenceDescription sequenceDescription) { - final String serviceEndpoint = XmlHelpers.getText(elem, SERVICE_ENDPOINT); - final String signingRegion = XmlHelpers.getText(elem, SIGNING_REGION); - final String bucketName = XmlHelpers.getText(elem, BUCKET_NAME); - final String key = XmlHelpers.getText(elem, KEY); - try { - return new N5S3OMEZarrImageLoader(serviceEndpoint, signingRegion, bucketName, key, "/", sequenceDescription); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/openers/OMEZarrOpener.java b/src/main/java/org/embl/mobie/io/ome/zarr/openers/OMEZarrOpener.java deleted file mode 100644 index 44a16f9a..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/openers/OMEZarrOpener.java +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.openers; - -import java.io.File; -import java.io.IOException; - -import org.embl.mobie.io.OpenerLogging; -import org.embl.mobie.io.ome.zarr.loaders.N5OMEZarrImageLoader; -import org.embl.mobie.io.ome.zarr.readers.N5OmeZarrReader; - -import com.google.gson.GsonBuilder; - -import bdv.cache.SharedQueue; -import mpicbg.spim.data.SpimData; -import net.imglib2.util.Cast; - -public class OMEZarrOpener extends OpenerLogging -{ - private final String filePath; - - public OMEZarrOpener(String filePath) { - this.filePath = filePath; - } - - public static SpimData openFile(String filePath) throws IOException { - OMEZarrOpener omeZarrOpener = new OMEZarrOpener(filePath); - return omeZarrOpener.readFile(); - } - - public static SpimData openFile(String filePath, SharedQueue sharedQueue) throws IOException { - N5OMEZarrImageLoader.logging = logging; - OMEZarrOpener omeZarrOpener = new OMEZarrOpener(filePath); - return omeZarrOpener.readFile(sharedQueue); - } - - private SpimData readFile(SharedQueue sharedQueue) throws IOException { - N5OMEZarrImageLoader.logging = logging; - N5OmeZarrReader reader = new N5OmeZarrReader(this.filePath, new GsonBuilder()); - N5OMEZarrImageLoader imageLoader = new N5OMEZarrImageLoader(reader, sharedQueue); - return new SpimData( - new File(this.filePath), - Cast.unchecked(imageLoader.getSequenceDescription()), - imageLoader.getViewRegistrations()); - } - - private SpimData readFile() throws IOException { - N5OMEZarrImageLoader.logging = logging; - N5OmeZarrReader reader = new N5OmeZarrReader(this.filePath, new GsonBuilder()); - N5OMEZarrImageLoader imageLoader = new N5OMEZarrImageLoader(reader); - return new SpimData( - new File(this.filePath), - Cast.unchecked(imageLoader.getSequenceDescription()), - imageLoader.getViewRegistrations()); - } - -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/openers/OMEZarrS3Opener.java b/src/main/java/org/embl/mobie/io/ome/zarr/openers/OMEZarrS3Opener.java deleted file mode 100644 index efc71b8f..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/openers/OMEZarrS3Opener.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.openers; - -import java.io.IOException; - -import org.embl.mobie.io.n5.openers.S3Opener; -import org.embl.mobie.io.ome.zarr.loaders.N5OMEZarrImageLoader; -import org.embl.mobie.io.ome.zarr.loaders.N5S3OMEZarrImageLoader; - -import bdv.cache.SharedQueue; -import mpicbg.spim.data.SpimData; -import net.imglib2.util.Cast; - -public class OMEZarrS3Opener extends S3Opener { - - public OMEZarrS3Opener(String serviceEndpoint, String signingRegion, String bucketName) { - super(serviceEndpoint, signingRegion, bucketName); - } - - public OMEZarrS3Opener(String url) { - super(url); - } - - public static SpimData readURL(String url) throws IOException { - final OMEZarrS3Opener reader = new OMEZarrS3Opener(url); - return reader.readKey(reader.getKey()); - } - - public static SpimData readURL(String url, SharedQueue sharedQueue) throws IOException { - final OMEZarrS3Opener reader = new OMEZarrS3Opener(url); - return reader.readKey(reader.getKey(), sharedQueue); - } - - public SpimData readKey(String key, SharedQueue sharedQueue) throws IOException { - N5OMEZarrImageLoader.logging = logging; - N5S3OMEZarrImageLoader imageLoader = new N5S3OMEZarrImageLoader(serviceEndpoint, signingRegion, bucketName, key, ".", sharedQueue); - return new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); - } - - @Override - public SpimData readKey(String key) throws IOException { - N5OMEZarrImageLoader.logging = logging; - N5S3OMEZarrImageLoader imageLoader = new N5S3OMEZarrImageLoader(serviceEndpoint, signingRegion, bucketName, key, "."); - return new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/readers/N5OmeZarrReader.java b/src/main/java/org/embl/mobie/io/ome/zarr/readers/N5OmeZarrReader.java deleted file mode 100644 index 31ffe626..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/readers/N5OmeZarrReader.java +++ /dev/null @@ -1,395 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -/** - * Copyright (c) 2019, Stephan Saalfeld - * All rights reserved. - *

- * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - *

- * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - *

- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -package org.embl.mobie.io.ome.zarr.readers; - -import java.io.IOException; -import java.io.Reader; -import java.nio.channels.Channels; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -import org.embl.mobie.io.ome.zarr.util.N5ZarrImageReader; -import org.embl.mobie.io.ome.zarr.util.N5ZarrImageReaderHelper; -import org.embl.mobie.io.ome.zarr.util.OmeZArrayAttributes; -import org.embl.mobie.io.ome.zarr.util.ZArrayAttributes; -import org.embl.mobie.io.ome.zarr.util.ZarrAxes; -import org.embl.mobie.io.ome.zarr.util.ZarrAxis; -import org.embl.mobie.io.ome.zarr.util.ZarrDatasetAttributes; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.GsonAttributesParser; -import org.janelia.saalfeldlab.n5.N5FSReader; - -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; - - - - -/** - * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> - */ - -public class N5OmeZarrReader extends N5FSReader implements N5ZarrImageReader { - protected final boolean mapN5DatasetAttributes; - final N5ZarrImageReaderHelper n5ZarrImageReaderHelper; - protected String dimensionSeparator; - private ZarrAxes zarrAxes; - private List zarrAxesList; - - /** - * Opens an {@link N5OmeZarrReader} at a given base path with a custom - * {@link GsonBuilder} to support custom attributes. - * - * @param basePath Zarr base path - * @param gsonBuilder - * @param dimensionSeparator - * @param mapN5DatasetAttributes Virtually create N5 dataset attributes (dimensions, blockSize, - * compression, dataType) for datasets such that N5 code that - * reads or modifies these attributes directly works as expected. - * This can lead to name clashes if a zarr container uses these - * attribute keys for other purposes. - * @throws IOException - */ - public N5OmeZarrReader(final String basePath, final GsonBuilder gsonBuilder, final String dimensionSeparator, final boolean mapN5DatasetAttributes) throws IOException { - super(basePath, N5ZarrImageReader.initGsonBuilder(gsonBuilder)); - this.dimensionSeparator = dimensionSeparator; - this.mapN5DatasetAttributes = mapN5DatasetAttributes; - this.n5ZarrImageReaderHelper = new N5ZarrImageReaderHelper(basePath, N5ZarrImageReader.initGsonBuilder(gsonBuilder)); - } - - /** - * Opens an {@link N5OmeZarrReader} at a given base path with a custom - * {@link GsonBuilder} to support custom attributes. - * - * @param basePath Zarr base path - * @param gsonBuilder - * @param dimensionSeparator - * @throws IOException - */ - public N5OmeZarrReader(final String basePath, final GsonBuilder gsonBuilder, final String dimensionSeparator) throws IOException { - - this(basePath, gsonBuilder, dimensionSeparator, true); - } - - /** - * Opens an {@link N5OmeZarrReader} at a given base path. - * - * @param basePath Zarr base path - * @param dimensionSeparator - * @param mapN5DatasetAttributes Virtually create N5 dataset attributes (dimensions, blockSize, - * compression, dataType) for datasets such that N5 code that - * reads or modifies these attributes directly works as expected. - * This can lead to name collisions if a zarr container uses these - * attribute keys for other purposes. - * @throws IOException - */ - public N5OmeZarrReader(final String basePath, final String dimensionSeparator, final boolean mapN5DatasetAttributes) throws IOException { - - this(basePath, new GsonBuilder(), dimensionSeparator, mapN5DatasetAttributes); - } - - /** - * Opens an {@link N5OmeZarrReader} at a given base path. - * - * @param basePath Zarr base path - * @param mapN5DatasetAttributes Virtually create N5 dataset attributes (dimensions, blockSize, - * compression, dataType) for datasets such that N5 code that - * reads or modifies these attributes directly works as expected. - * This can lead to name collisions if a zarr container uses these - * attribute keys for other purposes. - * @throws IOException - */ - public N5OmeZarrReader(final String basePath, final boolean mapN5DatasetAttributes) throws IOException { - this(basePath, new GsonBuilder(), DEFAULT_SEPARATOR, mapN5DatasetAttributes); - } - - /** - * Opens an {@link N5OmeZarrReader} at a given base path with a custom - * {@link GsonBuilder} to support custom attributes. - *

- * Zarray metadata will be virtually mapped to N5 dataset attributes. - * - * @param basePath Zarr base path - * @param gsonBuilder - * @throws IOException - */ - public N5OmeZarrReader(final String basePath, final GsonBuilder gsonBuilder) throws IOException { - this(basePath, gsonBuilder, DEFAULT_SEPARATOR); - } - - /** - * Opens an {@link N5OmeZarrReader} at a given base path. - *

- * Zarray metadata will be virtually mapped to N5 dataset attributes. - * - * @param basePath Zarr base path - * @throws IOException - */ - public N5OmeZarrReader(final String basePath) throws IOException { - - this(basePath, new GsonBuilder()); - } - - @Override - public Version getVersion() throws IOException { - - final Path path; - if (groupExists("/")) { - path = Paths.get(basePath, zgroupFile); - } else if (datasetExists("/")) { - path = Paths.get(basePath, zarrayFile); - } else { - return VERSION; - } - - if (Files.exists(path)) { - - try (final LockedFileChannel lockedFileChannel = LockedFileChannel.openForReading(path)) { - final HashMap attributes = - GsonAttributesParser.readAttributes( - Channels.newReader( - lockedFileChannel.getFileChannel(), - StandardCharsets.UTF_8.name()), - gson); - - final Integer zarr_format = GsonAttributesParser.parseAttribute( - attributes, - "zarr_format", - Integer.class, - gson); - - if (zarr_format != null) - return new Version(zarr_format, 0, 0); - } - } - return VERSION; - } - - /** - * @return Zarr base path - */ - @Override - public String getBasePath() { - - return this.basePath; - } - - public boolean groupExists(final String pathName) { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zgroupFile); - return Files.exists(path) && Files.isRegularFile(path); - } - - @Override - public String getZarrDataBlockString(long[] gridPosition, String dimensionSeparator, boolean isRowMajor) { - return N5ZarrImageReader.super.getZarrDataBlockString(gridPosition, dimensionSeparator, isRowMajor); - } - - public ZArrayAttributes getZArrayAttributes(final String pathName) throws IOException { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zarrayFile); - OmeZArrayAttributes zArrayAttributes = null; - if (Files.exists(path)) { - try (final LockedFileChannel lockedFileChannel = LockedFileChannel.openForReading(path); - final Reader reader = Channels.newReader(lockedFileChannel.getFileChannel(), StandardCharsets.UTF_8.name())) { - zArrayAttributes = gson.fromJson(reader, OmeZArrayAttributes.class); - } - } else { - //System.out.println(path + " does not exist."); - } - this.dimensionSeparator = zArrayAttributes == null || zArrayAttributes.getDimensionSeparator() == null ? - DEFAULT_SEPARATOR : zArrayAttributes.getDimensionSeparator(); - - return zArrayAttributes; - } - - @Override - public DatasetAttributes getDatasetAttributes(final String pathName) throws IOException { - - final ZArrayAttributes zArrayAttributes = getZArrayAttributes(pathName); - return zArrayAttributes == null ? null : zArrayAttributes.getDatasetAttributes(); - } - - @Override - public boolean datasetExists(final String pathName) throws IOException { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zarrayFile); - return Files.exists(path) && Files.isRegularFile(path) && getDatasetAttributes(pathName) != null; - } - - /** - * @returns false if the group or dataset does not exist but also if the - * attempt to access - */ - @Override - public boolean exists(final String pathName) { - - try { - return groupExists(pathName) || datasetExists(pathName); - } catch (final IOException e) { - e.printStackTrace(); - return false; - } - } - - /** - * If {@link #mapN5DatasetAttributes} is set, dataset attributes will - * override attributes with the same key. - */ - @Override - public HashMap getAttributes(final String pathName) throws IOException { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zattrsFile); - final HashMap attributes = new HashMap<>(); - if (Files.exists(path)) { - try (final LockedFileChannel lockedFileChannel = LockedFileChannel.openForReading(path)) { - attributes.putAll( - GsonAttributesParser.readAttributes( - Channels.newReader( - lockedFileChannel.getFileChannel(), - StandardCharsets.UTF_8.name()), - gson)); - } - } - - try { - getDimensions(attributes); - } catch (IllegalArgumentException e) { - throw new IOException("Error while getting datasets dimensions", e); - } - - if (mapN5DatasetAttributes && datasetExists(pathName)) { - final DatasetAttributes datasetAttributes = getZArrayAttributes(pathName).getDatasetAttributes(); - n5ZarrImageReaderHelper.putAttributes(attributes, datasetAttributes); - } - - return attributes; - } - - @Override - public Map> listAttributes(String pathName) throws IOException { - return super.listAttributes(pathName); - } - - public ZarrAxes getAxes() { - return this.zarrAxes; - } - - @Override - public void setAxes(JsonElement axesJson) { - if (axesJson != null) { - this.zarrAxes = ZarrAxes.decode(axesJson.toString()); - } else { - this.zarrAxes = ZarrAxes.TCZYX; - } - } - - @Override - public void setAxes(List axes) { - this.zarrAxesList = axes; - } - - public List getZarrAxes() { - return this.zarrAxesList; - } - - @Override - public DataBlock readBlock( - final String pathName, - final DatasetAttributes datasetAttributes, - final long... gridPosition) throws IOException { - - final ZarrDatasetAttributes zarrDatasetAttributes; - if (datasetAttributes instanceof ZarrDatasetAttributes) - zarrDatasetAttributes = (ZarrDatasetAttributes) datasetAttributes; - else - zarrDatasetAttributes = getZArrayAttributes(pathName).getDatasetAttributes(); - - Path path = Paths.get( - basePath, - removeLeadingSlash(pathName), - getZarrDataBlockString( - gridPosition, - dimensionSeparator, - zarrDatasetAttributes.isRowMajor())); - if (!Files.exists(path)) { - return null; - } - - try (final LockedFileChannel lockedChannel = LockedFileChannel.openForReading(path)) { - return readBlock(Channels.newInputStream(lockedChannel.getFileChannel()), zarrDatasetAttributes, gridPosition); - } - } - - @Override - public String[] list(final String pathName) throws IOException { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName)); - try (final Stream pathStream = Files.list(path)) { - - return pathStream - .filter(Files::isDirectory) - .map(a -> path.relativize(a).toString()) - .filter(a -> exists(pathName + "/" + a)) - .toArray(String[]::new); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/readers/N5S3OmeZarrReader.java b/src/main/java/org/embl/mobie/io/ome/zarr/readers/N5S3OmeZarrReader.java deleted file mode 100644 index 8ea34160..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/readers/N5S3OmeZarrReader.java +++ /dev/null @@ -1,301 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -/** - * Copyright (c) 2019, Stephan Saalfeld - * All rights reserved. - *

- * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - *

- * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - *

- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -package org.embl.mobie.io.ome.zarr.readers; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import org.embl.mobie.io.ome.zarr.util.N5ZarrImageReader; -import org.embl.mobie.io.ome.zarr.util.N5ZarrImageReaderHelper; -import org.embl.mobie.io.ome.zarr.util.ZArrayAttributes; -import org.embl.mobie.io.ome.zarr.util.ZarrAxes; -import org.embl.mobie.io.ome.zarr.util.ZarrAxis; -import org.embl.mobie.io.ome.zarr.util.ZarrDatasetAttributes; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.GsonAttributesParser; -import org.janelia.saalfeldlab.n5.s3.N5AmazonS3Reader; - -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.model.AmazonS3Exception; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; - - - - -/** - * Attempt at a diamond inheritance solution for S3+Zarr. - */ - -public class N5S3OmeZarrReader extends N5AmazonS3Reader implements N5ZarrImageReader { - - final protected boolean mapN5DatasetAttributes; - private final String serviceEndpoint; - private final N5ZarrImageReaderHelper n5ZarrImageReaderHelper; - protected String dimensionSeparator; - List zarrAxesList = new ArrayList<>(); - private ZarrAxes zarrAxes; - - public N5S3OmeZarrReader(AmazonS3 s3, String serviceEndpoint, String bucketName, String containerPath, String dimensionSeparator) throws IOException { - super(s3, bucketName, containerPath, N5ZarrImageReader.initGsonBuilder(new GsonBuilder())); - this.serviceEndpoint = serviceEndpoint; // for debugging - this.dimensionSeparator = dimensionSeparator; - mapN5DatasetAttributes = true; - this.n5ZarrImageReaderHelper = new N5ZarrImageReaderHelper(N5ZarrImageReader.initGsonBuilder(new GsonBuilder())); - } - - public ZarrAxes getAxes() { - return this.zarrAxes; - } - - @Override - public void setAxes(JsonElement axesJson) { - if (axesJson != null) { - this.zarrAxes = ZarrAxes.decode(axesJson.toString()); - } else { - this.zarrAxes = ZarrAxes.TCZYX; - } - } - - @Override - public void setAxes(List axes) { - this.zarrAxesList = axes; - } - - public List getZarrAxes() { - return this.zarrAxesList; - } - - public void setDimensionSeparator(String dimensionSeparator) { - this.dimensionSeparator = dimensionSeparator; - } - - public AmazonS3 getS3() { - return s3; - } - - public String getBucketName() { - return bucketName; - } - - public String getContainerPath() { - return containerPath; - } - - public String getServiceEndpoint() { - return serviceEndpoint; - } - - /** - * Helper to encapsulate building the object key for a file like - * .zarray or .zgroup within any given path. - * - * @param pathName - * @param file One of .zarray, .zgroup or .zattrs - * @return - */ - private String objectFile(final String pathName, String file) { - StringBuilder sb = new StringBuilder(); - sb.append(containerPath); - String cleaned = removeLeadingSlash(pathName); - if (!cleaned.isEmpty()) { - sb.append('/'); - sb.append(cleaned); - } - sb.append('/'); - sb.append(file); - return sb.toString(); - } - - // remove getBasePath - - @Override - public Version getVersion() throws IOException { - HashMap meta; - meta = readJson(objectFile("", zgroupFile)); - if (meta == null) { - meta = readJson(objectFile("", zarrayFile)); - } - - if (meta != null) { - - final Integer zarr_format = GsonAttributesParser.parseAttribute( - meta, - "zarr_format", - Integer.class, - gson); - - if (zarr_format != null) - return new Version(zarr_format, 0, 0); - } - - return VERSION; - } - - public boolean groupExists(final String pathName) { - return exists(objectFile(pathName, zgroupFile)); - } - - public ZArrayAttributes getZArrayAttributes(final String pathName) throws IOException { - final String path = objectFile(pathName, zarrayFile); - HashMap attributes = readJson(path); - - if (attributes == null) { - //System.out.println(path + " does not exist."); - attributes = new HashMap<>(); - } - - JsonElement dimSep = attributes.get("dimension_separator"); - this.dimensionSeparator = dimSep == null ? DEFAULT_SEPARATOR : dimSep.getAsString(); - return n5ZarrImageReaderHelper.getN5DatasetAttributes(attributes); - } - - @Override - public DatasetAttributes getDatasetAttributes(final String pathName) throws IOException { - final ZArrayAttributes zArrayAttributes = getZArrayAttributes(pathName); - return zArrayAttributes == null ? null : zArrayAttributes.getDatasetAttributes(); - } - - @Override - public boolean datasetExists(final String pathName) throws IOException { - final String path = objectFile(pathName, zarrayFile); - return readJson(path) != null; - } - - /** - * If {@link #mapN5DatasetAttributes} is set, dataset attributes will - * override attributes with the same key. - */ - @Override - public HashMap getAttributes(final String pathName) throws IOException { - final String path = objectFile(pathName, zattrsFile); - HashMap attributes = readJson(path); - - if (attributes == null) { - attributes = new HashMap<>(); - } - - try { - getDimensions(attributes); - } catch (IllegalArgumentException e) { - throw new IOException("Error while getting datasets dimensions", e); - } - - if (mapN5DatasetAttributes) { - try - { - final DatasetAttributes datasetAttributes = getZArrayAttributes( pathName ).getDatasetAttributes(); - n5ZarrImageReaderHelper.putAttributes( attributes, datasetAttributes ); - } - catch ( Exception e ) - { - // no datasetAttributes found here - } - } - return attributes; - } - - @Override - public DataBlock readBlock( - final String pathName, - final DatasetAttributes datasetAttributes, - final long... gridPosition) throws IOException { - final ZarrDatasetAttributes zarrDatasetAttributes; - if (datasetAttributes instanceof ZarrDatasetAttributes) - zarrDatasetAttributes = (ZarrDatasetAttributes) datasetAttributes; - else - zarrDatasetAttributes = getZArrayAttributes(pathName).getDatasetAttributes(); - - final String dataBlockKey = - objectFile(pathName, - getZarrDataBlockString( - gridPosition, - dimensionSeparator, - zarrDatasetAttributes.isRowMajor())); - - // Currently exists() appends "/" - // if (!exists(dataBlockKey)) - // return null; - - try { - try (final InputStream in = this.readS3Object(dataBlockKey)) { - return readBlock(in, zarrDatasetAttributes, gridPosition); - } - } catch (Exception e) { - return null; - } - } - - /** - * Copied from getAttributes but doesn't change the objectPath in any way. - * CHANGES: returns null rather than empty hash map - * - * @param objectPath - * @return null if the object does not exist, otherwise the loaded attributes. - */ - public HashMap readJson(String objectPath) { - try (final InputStream in = this.readS3Object(objectPath)) { - return GsonAttributesParser.readAttributes(new InputStreamReader(in), gson); - } catch (Exception e) { - return null; - } - } - -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/AxesTypes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/AxesTypes.java deleted file mode 100644 index 5683b194..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/AxesTypes.java +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -public enum AxesTypes { - TIME("time"), - CHANNEL("channel"), - SPACE("space"); - - private final String typeName; - - AxesTypes(String typeName) { - this.typeName = typeName; - } - - public static boolean contains(String test) { - for (AxesTypes c : AxesTypes.values()) { - if (c.typeName.equals(test)) { - return true; - } - } - return false; - } - - public static AxesTypes getAxisType(String axisString) { - if (axisString.equals("x") || axisString.equals("y") || axisString.equals("z")) { - return AxesTypes.SPACE; - } else if (axisString.equals("t")) { - return AxesTypes.TIME; - } else if (axisString.equals("c")) { - return AxesTypes.CHANNEL; - } else { - return null; - } - } - - public String getTypeName() { - return typeName; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/N5OMEZarrCacheArrayLoader.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/N5OMEZarrCacheArrayLoader.java deleted file mode 100644 index 983cf173..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/N5OMEZarrCacheArrayLoader.java +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Map; - -import net.imglib2.img.basictypeaccess.DataAccess; -import org.embl.mobie.io.n5.util.N5DataTypeSize; -import org.embl.mobie.io.ome.zarr.loaders.N5OMEZarrImageLoader; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5Reader; - -import com.amazonaws.SdkClientException; - -import bdv.img.cache.SimpleCacheArrayLoader; - -import net.imglib2.img.cell.CellGrid; - -public class N5OMEZarrCacheArrayLoader implements SimpleCacheArrayLoader { - private final N5Reader n5; - private final String pathName; - private final int channel; - private final int timepoint; - private final DatasetAttributes attributes; - private final ZarrArrayCreator zarrArrayCreator; - private final ZarrAxes zarrAxes; - - public N5OMEZarrCacheArrayLoader(final N5Reader n5, final String pathName, final int channel, final int timepoint, final DatasetAttributes attributes, CellGrid grid, ZarrAxes zarrAxes) { - this.n5 = n5; - this.pathName = pathName; // includes the level - this.channel = channel; - this.timepoint = timepoint; - this.attributes = attributes; - final DataType dataType = attributes.getDataType(); - this.zarrArrayCreator = new ZarrArrayCreator<>(grid, dataType, zarrAxes); - this.zarrAxes = zarrAxes; - } - - @Override - public A loadArray(final long[] gridPosition, int[] cellDimensions) throws IOException { - DataBlock block = null; - - long[] dataBlockIndices = toZarrChunkIndices(gridPosition); - - long start = 0; - if (N5OMEZarrImageLoader.logging) - start = System.currentTimeMillis(); - - try { - block = n5.readBlock(pathName, attributes, dataBlockIndices); - } catch (SdkClientException e) { - System.err.println(e.getMessage()); // this happens sometimes, not sure yet why... - } - if (N5OMEZarrImageLoader.logging) { - if (block != null) { - final long millis = System.currentTimeMillis() - start; - final int numElements = block.getNumElements(); - final DataType dataType = attributes.getDataType(); - final float megaBytes = (float) numElements * N5DataTypeSize.getNumBytesPerElement(dataType) / 1000000.0F; - final float mbPerSecond = megaBytes / (millis / 1000.0F); - System.out.println(pathName + " " + Arrays.toString(dataBlockIndices) + ": " + "Read " + numElements + " " + dataType + " (" + String.format("%.3f", megaBytes) + " MB) in " + millis + " ms (" + String.format("%.3f", mbPerSecond) + " MB/s)."); - } else - System.out.println(pathName + " " + Arrays.toString(dataBlockIndices) + ": Missing, returning zeros."); - } - - if (block == null) { - return (A) zarrArrayCreator.createEmptyArray(gridPosition); - } else { - return zarrArrayCreator.createArray(block, gridPosition); - } - } - - private long[] toZarrChunkIndices(long[] gridPosition) { - - long[] chunkInZarr = new long[zarrAxes.getNumDimension()]; - - // fill in the spatial dimensions - final Map spatialToZarr = zarrAxes.spatialToZarr(); - for (Map.Entry entry : spatialToZarr.entrySet()) - chunkInZarr[entry.getValue()] = gridPosition[entry.getKey()]; - - if (zarrAxes.hasChannels()) - chunkInZarr[zarrAxes.channelIndex()] = channel; - - if (zarrAxes.hasTimepoints()) - chunkInZarr[zarrAxes.timeIndex()] = timepoint; - - return chunkInZarr; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/N5ZarrImageReader.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/N5ZarrImageReader.java deleted file mode 100644 index 5475639f..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/N5ZarrImageReader.java +++ /dev/null @@ -1,199 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.janelia.saalfeldlab.n5.BlockReader; -import org.janelia.saalfeldlab.n5.ByteArrayDataBlock; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.N5Reader; -import org.janelia.saalfeldlab.n5.zarr.DType; -import org.janelia.saalfeldlab.n5.zarr.ZarrCompressor; -import org.janelia.saalfeldlab.n5.zarr.ZarrDatasetAttributes; - -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; - -public interface N5ZarrImageReader extends N5Reader { - String DEFAULT_SEPARATOR = "."; - String zarrayFile = ".zarray"; - String zattrsFile = ".zattrs"; - String zgroupFile = ".zgroup"; - List zarrAxes = new ArrayList<>(); - - - static GsonBuilder initGsonBuilder(final GsonBuilder gsonBuilder) { - - gsonBuilder.registerTypeAdapter(DType.class, new DType.JsonAdapter()); - gsonBuilder.registerTypeAdapter(ZarrCompressor.class, ZarrCompressor.jsonAdapter); - gsonBuilder.registerTypeAdapter(ZarrAxes.class, new ZarrAxesAdapter()); - gsonBuilder.registerTypeAdapter(N5Reader.Version.class, new VersionAdapter()); - gsonBuilder.registerTypeAdapter(OmeZarrMultiscales.class, new OmeZarrMultiscalesAdapter()); - gsonBuilder.setPrettyPrinting(); - return gsonBuilder; - } - - default Version getVersion() throws IOException { - return VERSION; - } - - default String getDimensionSeparator(HashMap attributes) { - JsonElement dimSep = attributes.get("dimension_separator"); - return dimSep == null ? DEFAULT_SEPARATOR : dimSep.getAsString(); - } - - default void getDimensions(HashMap attributes) throws IllegalArgumentException { - JsonElement multiscales = attributes.get("multiscales"); - if (multiscales == null) { - return; - } - String version = multiscales.getAsJsonArray().get(0).getAsJsonObject().get("version").getAsString(); - if (version.equals("0.3")) { - JsonElement axes = multiscales.getAsJsonArray().get(0).getAsJsonObject().get("axes"); - setAxes(axes); - } else if (version.equals("0.4")) { - JsonArray axes = multiscales.getAsJsonArray().get(0).getAsJsonObject().get("axes").getAsJsonArray(); - int index = 0; - List zarrAxes = new ArrayList<>(); - for (JsonElement axis : axes) { - String name = axis.getAsJsonObject().get("name").getAsString(); - String type = axis.getAsJsonObject().get("type").getAsString(); - if (name.isEmpty() || type.isEmpty() || !AxesTypes.contains(type)) { - throw new IllegalArgumentException("Unsupported multiscales axes: " + name + ", " + type); - } - ZarrAxis zarrAxis; - if (axis.getAsJsonObject().get("unit") != null && axis.getAsJsonObject().get("unit").isJsonPrimitive()) { - String unit = axis.getAsJsonObject().get("unit").getAsString(); - zarrAxis = new ZarrAxis(index, name, type, unit); - } else { - zarrAxis = new ZarrAxis(index, name, type); - } - index++; - zarrAxes.add(zarrAxis); - } - setAxes(zarrAxes); - setAxes(ZarrAxis.convertToJson(zarrAxes)); - } else { - JsonElement axes = multiscales.getAsJsonArray().get(0).getAsJsonObject().get("axes"); - setAxes(axes); - } - } - - void setAxes(JsonElement axesJson); - - void setAxes(List axes); - - ZArrayAttributes getZArrayAttributes(final String pathName) throws IOException; - - boolean datasetExists(final String pathName) throws IOException; - - boolean groupExists(final String pathName); - - /** - * CHANGE: return String rather than Path, fixed javadoc - * Constructs the path for a data block in a dataset at a given grid position. - *

- * The returned path is - *

-     * $datasetPathName/$gridPosition[n]$dimensionSeparator$gridPosition[n-1]$dimensionSeparator[...]$dimensionSeparator$gridPosition[0]
-     * 
- *

- * This is the file into which the data block will be stored. - * - * @param gridPosition - * @param dimensionSeparator - * @return - */ - default String getZarrDataBlockString( - final long[] gridPosition, - final String dimensionSeparator, - final boolean isRowMajor) { - final StringBuilder pathStringBuilder = new StringBuilder(); - if (isRowMajor) { - pathStringBuilder.append(gridPosition[gridPosition.length - 1]); - for (int i = gridPosition.length - 2; i >= 0; --i) { - pathStringBuilder.append(dimensionSeparator); - pathStringBuilder.append(gridPosition[i]); - } - } else { - pathStringBuilder.append(gridPosition[0]); - for (int i = 1; i < gridPosition.length; ++i) { - pathStringBuilder.append(dimensionSeparator); - pathStringBuilder.append(gridPosition[i]); - } - } - - return pathStringBuilder.toString(); - } - - /** - * Reads a {@link DataBlock} from an {@link InputStream}. - * - * @param in - * @param datasetAttributes - * @param gridPosition - * @return - * @throws IOException - */ - @SuppressWarnings("incomplete-switch") - default DataBlock readBlock( - final InputStream in, - final ZarrDatasetAttributes datasetAttributes, - final long... gridPosition) throws IOException { - final int[] blockSize = datasetAttributes.getBlockSize(); - final DType dType = datasetAttributes.getDType(); - - final ByteArrayDataBlock byteBlock = dType.createByteBlock(blockSize, gridPosition); - - final BlockReader reader = datasetAttributes.getCompression().getReader(); - reader.read(byteBlock, in); - - switch (dType.getDataType()) { - case UINT8: - case INT8: - return byteBlock; - } - - /* else translate into target type */ - final DataBlock dataBlock = dType.createDataBlock(blockSize, gridPosition); - final ByteBuffer byteBuffer = byteBlock.toByteBuffer(); - byteBuffer.order(dType.getOrder()); - dataBlock.readData(byteBuffer); - - return dataBlock; - } - -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/N5ZarrImageReaderHelper.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/N5ZarrImageReaderHelper.java deleted file mode 100644 index 7a278e0d..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/N5ZarrImageReaderHelper.java +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; - -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5FSReader; -import org.janelia.saalfeldlab.n5.zarr.DType; -import org.janelia.saalfeldlab.n5.zarr.Filter; -import org.janelia.saalfeldlab.n5.zarr.ZarrCompressor; -import org.jetbrains.annotations.NotNull; - -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class N5ZarrImageReaderHelper extends N5FSReader { - - public N5ZarrImageReaderHelper(GsonBuilder gsonBuilder) throws IOException { - super("", gsonBuilder); - } - - public N5ZarrImageReaderHelper(String basePath, GsonBuilder gsonBuilder) throws IOException { - super(basePath, gsonBuilder); - } - - public ZArrayAttributes getN5DatasetAttributes(@NotNull HashMap attributes) throws IOException { - if (attributes.isEmpty()) { - throw new IOException("Empty ZArray attributes"); - } - return new ZArrayAttributes( - attributes.get("zarr_format").getAsInt(), - gson.fromJson(attributes.get("shape"), long[].class), - gson.fromJson(attributes.get("chunks"), int[].class), - gson.fromJson(attributes.get("dtype"), DType.class), - gson.fromJson(attributes.get("compressor"), ZarrCompressor.class), - attributes.get("fill_value").getAsString(), - attributes.get("order").getAsCharacter(), - gson.fromJson(attributes.get("filters"), TypeToken.getParameterized(Collection.class, Filter.class).getType())); - - } - - public void putAttributes(HashMap attributes, DatasetAttributes datasetAttributes) { - attributes.put("dimensions", gson.toJsonTree(datasetAttributes.getDimensions())); - attributes.put("blockSize", gson.toJsonTree(datasetAttributes.getBlockSize())); - attributes.put("dataType", gson.toJsonTree(datasetAttributes.getDataType())); - attributes.put("compression", gson.toJsonTree(datasetAttributes.getCompression())); - } - - - @Override - public HashMap getAttributes(String pathName) { - return null; - } - - @Override - public DataBlock readBlock(String pathName, DatasetAttributes datasetAttributes, long[] gridPosition) { - return null; - } - - @Override - public boolean exists(String pathName) { - return false; - } - - @Override - public String[] list(String pathName) throws IOException { - return new String[0]; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZArrayAttributes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZArrayAttributes.java deleted file mode 100644 index 8ca0ad78..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZArrayAttributes.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.util.Collection; -import java.util.HashMap; - -import org.janelia.saalfeldlab.n5.zarr.DType; -import org.janelia.saalfeldlab.n5.zarr.Filter; -import org.janelia.saalfeldlab.n5.zarr.ZarrCompressor; - -import com.google.gson.annotations.SerializedName; - -public class OmeZArrayAttributes extends ZArrayAttributes { - protected static final String dimensionSeparatorKey = "dimension_separator"; - - @SerializedName("dimension_separator") - private final String dimensionSeparator; - - public OmeZArrayAttributes(int zarr_format, long[] shape, int[] chunks, DType dtype, ZarrCompressor compressor, - String fill_value, char order, Collection filters, String dimensionSeparator) { - super(zarr_format, shape, chunks, dtype, compressor, fill_value, order, filters); - this.dimensionSeparator = dimensionSeparator; - } - - public String getDimensionSeparator() { - return dimensionSeparator; - } - - public HashMap asMap() { - - final HashMap map = super.asMap(); - map.put(dimensionSeparatorKey, dimensionSeparator); - - return map; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZarrMultiscales.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZarrMultiscales.java deleted file mode 100644 index d25fa53c..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZarrMultiscales.java +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.util.List; - -import mpicbg.spim.data.sequence.VoxelDimensions; - -public class OmeZarrMultiscales { - - // key in json for multiscales - public static final String MULTI_SCALE_KEY = "multiscales"; - - public transient ZarrAxes axes; - public List zarrAxisList; - public Dataset[] datasets; - public String name; - public String type; - public String version; - public CoordinateTransformations[] coordinateTransformations; - - public OmeZarrMultiscales() { - } - - public OmeZarrMultiscales(ZarrAxes axes, String name, String type, String version, - VoxelDimensions voxelDimensions, double[][] resolutions, String timeUnit, - double frameInterval) { - this.version = version; - this.name = name; - this.type = type; - this.axes = axes; - this.zarrAxisList = axes.toAxesList(voxelDimensions.unit(), timeUnit); - generateDatasets(voxelDimensions, frameInterval, resolutions); - } - - private void generateDatasets(VoxelDimensions voxelDimensions, double frameInterval, double[][] resolutions) { - - Dataset[] datasets = new Dataset[resolutions.length]; - for (int i = 0; i < resolutions.length; i++) { - Dataset dataset = new Dataset(); - - CoordinateTransformations coordinateTransformations = new CoordinateTransformations(); - coordinateTransformations.scale = getScale(voxelDimensions, frameInterval, resolutions[i]); - coordinateTransformations.type = "scale"; - - dataset.path = "s" + i; - dataset.coordinateTransformations = new CoordinateTransformations[]{coordinateTransformations}; - datasets[i] = dataset; - } - this.datasets = datasets; - } - - private double[] getScale(VoxelDimensions voxelDimensions, double frameInterval, double[] xyzScale) { - int nDimensions = zarrAxisList.size(); - double[] scale = new double[nDimensions]; - if (axes.timeIndex() != -1) { - scale[axes.timeIndex()] = frameInterval; - } - - if (axes.channelIndex() != -1) { - scale[axes.channelIndex()] = 1; - } - - for (int i = 0; i < 3; i++) { - double dimension = voxelDimensions.dimension(i) * xyzScale[i]; - scale[nDimensions - (i + 1)] = dimension; - } - - return scale; - } - - public static class Dataset { - public String path; - public CoordinateTransformations[] coordinateTransformations; - } - - public static class CoordinateTransformations { - public String type; - public double[] scale; - public double[] translation; - public String path; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZarrMultiscalesAdapter.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZarrMultiscalesAdapter.java deleted file mode 100644 index 2be02a1c..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/OmeZarrMultiscalesAdapter.java +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.lang.reflect.Type; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -public class OmeZarrMultiscalesAdapter implements JsonSerializer { - - @Override - public JsonElement serialize(OmeZarrMultiscales src, Type typeOfSrc, JsonSerializationContext context) { - JsonObject obj = new JsonObject(); - obj.add("axes", context.serialize(src.zarrAxisList)); - obj.add("datasets", context.serialize(src.datasets)); - obj.add("name", context.serialize(src.name)); - obj.add("type", context.serialize(src.type)); - obj.add("version", context.serialize(src.version)); - obj.add("coordinateTransformations", context.serialize(src.coordinateTransformations)); - return obj; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/TransformationTypes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/TransformationTypes.java deleted file mode 100644 index 669fef59..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/TransformationTypes.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -public enum TransformationTypes { - IDENTITY("identity"), - TRANSLATION("translation"), - SCALE("scale"); - - private final String typeName; - - TransformationTypes(String typeName) { - this.typeName = typeName; - } - - public static boolean contains(String test) { - for (TransformationTypes c : TransformationTypes.values()) { - if (c.typeName.equals(test)) { - return true; - } - } - return false; - } - - public String getTypeName() { - return typeName; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/UnitTypes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/UnitTypes.java deleted file mode 100644 index 5d8fda8f..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/UnitTypes.java +++ /dev/null @@ -1,134 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - - -import ucar.units.PrefixDBException; -import ucar.units.SpecificationException; -import ucar.units.Unit; -import ucar.units.UnitDBException; -import ucar.units.UnitFormat; -import ucar.units.UnitFormatManager; -import ucar.units.UnitSystemException; - - -public enum UnitTypes { - ANGSTROM("angstrom"), - ATTOMETER("attometer"), - CENTIMETER("centimeter"), - DECIMETER("decimeter"), - EXAMETER("exameter"), - FEMTOMETER("femtometer"), - FOOT("foot"), - GIGAMETER("gigameter"), - HECTOMETER("hectometer"), - INCH("inch"), - KILOMETER("kilometer"), - MEGAMETER("megameter"), - METER("meter"), - MICROMETER("micrometer"), - MILE("mile"), - MILLIMETER("millimeter"), - NANOMETER("nanometer"), - PARSEC("parsec"), - PETAMETER("petameter"), - PICOMETER("picometer"), - TERAMETER("terameter"), - YARD("yard"), - YOCTOMETER("yoctometer"), - YOTTAMETER("yottameter"), - ZEPTOMETER("zeptometer"), - ZETTAMETER("zettameter"), - - ATTOSECOND("attosecond"), - CENTISECOND("centisecond"), - DAY("day"), - DECISECOND("decisecond"), - EXASECOND("exasecond"), - FEMTOSECOND("femtosecond"), - GIGASECOND("gigasecond"), - HECTOSECOND("hectosecond"), - HOUR("hour"), - KILOSECOND("kilosecond"), - MEGASECOND("megasecond"), - MICROSECOND("microsecond"), - MILLISECOND("millisecond"), - MINUTE("minute"), - NANOSECOND("nanosecond"), - PETASECOND("petasecond"), - PICOSECOND("picosecond"), - SECOND("second"), - TERASECOND("terasecond"), - YOCTOSECOND("yoctosecond"), - YOTTASECOND("yottasecond"), - ZEPTOSECOND("zeptosecond"), - ZETTASECOND("zettasecond"); - - private final String typeName; - - UnitTypes(String typeName) { - this.typeName = typeName; - } - - public static boolean contains(String test) { - for (UnitTypes c : UnitTypes.values()) { - if (c.typeName.equals(test)) { - return true; - } - } - return false; - } - - public static UnitTypes convertUnit(String unit) { - // Convert the mu symbol into "u". - String unitString = unit.replace("\u00B5", "u"); - - try { - UnitFormat unitFormatter = UnitFormatManager.instance(); - Unit inputUnit = unitFormatter.parse(unitString); - - for (UnitTypes unitType : UnitTypes.values()) { - Unit zarrUnit = unitFormatter.parse(unitType.typeName); - if (zarrUnit.getCanonicalString().equals(inputUnit.getCanonicalString())) { - System.out.println("Converted unit: " + unit + " to recommended ome-zarr unit: " + unitType.getTypeName()); - return unitType; - } - } - } catch (SpecificationException | UnitDBException | PrefixDBException | UnitSystemException e) { - e.printStackTrace(); - } - - System.out.println(unit + " is not one of the recommended units for ome-zarr"); - return null; - } - - public String getTypeName() { - return typeName; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/VersionAdapter.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/VersionAdapter.java deleted file mode 100644 index 1b0f9b43..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/VersionAdapter.java +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - - -import java.lang.reflect.Type; - -import org.janelia.saalfeldlab.n5.N5Reader; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -public class VersionAdapter implements JsonDeserializer, JsonSerializer { - - @Override - public N5Reader.Version deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - String[] versionElements = json.getAsString().split("\\."); - int[] versionNumbers = new int[versionElements.length]; - - for (int i = 0; i < versionNumbers.length; i++) { - versionNumbers[i] = Integer.parseInt(versionElements[i]); - } - - if (versionNumbers.length > 2) { - return new N5Reader.Version(versionNumbers[0], versionNumbers[1], versionNumbers[2]); - } else { - return new N5Reader.Version(versionNumbers[0], versionNumbers[1], 0); - } - } - - @Override - public JsonElement serialize(N5Reader.Version src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.getMajor() + "." + src.getMinor() + "." + src.getPatch()); - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZArrayAttributes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/ZArrayAttributes.java deleted file mode 100644 index 4becfb39..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZArrayAttributes.java +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -import org.janelia.saalfeldlab.n5.Compression; -import org.janelia.saalfeldlab.n5.RawCompression; -import org.janelia.saalfeldlab.n5.zarr.DType; -import org.janelia.saalfeldlab.n5.zarr.Filter; -import org.janelia.saalfeldlab.n5.zarr.Utils; -import org.janelia.saalfeldlab.n5.zarr.ZarrCompressor; - -public class ZArrayAttributes { - - protected static final String zarrFormatKey = "zarr_format"; - protected static final String shapeKey = "shape"; - protected static final String chunksKey = "chunks"; - protected static final String dTypeKey = "dtype"; - protected static final String compressorKey = "compressor"; - protected static final String fillValueKey = "fill_value"; - protected static final String orderKey = "order"; - protected static final String filtersKey = "filters"; - - private final int zarr_format; - private final long[] shape; - private final int[] chunks; - private final DType dtype; - private final ZarrCompressor compressor; - private final String fill_value; - private final char order; - private final List filters = new ArrayList<>(); - - public ZArrayAttributes( - final int zarr_format, - final long[] shape, - final int[] chunks, - final DType dtype, - final ZarrCompressor compressor, - final String fill_value, - final char order, - final Collection filters) { - - this.zarr_format = zarr_format; - this.shape = shape; - this.chunks = chunks; - this.dtype = dtype; - this.compressor = compressor == null ? new ZarrCompressor.Raw() : compressor; - this.fill_value = fill_value; - this.order = order; - if (filters != null) - this.filters.addAll(filters); - } - - public ZarrDatasetAttributes getDatasetAttributes() { - final boolean isRowMajor = order == 'C'; - final long[] dimensions = shape.clone(); - final int[] blockSize = chunks.clone(); - - if (isRowMajor) { - Utils.reorder(dimensions); - Utils.reorder(blockSize); - } - - Compression compression = compressor != null ? compressor.getCompression() : new ZarrCompressor.Raw().getCompression(); - - return new ZarrDatasetAttributes( - dimensions, - blockSize, - dtype, - compression, - isRowMajor, - fill_value); - } - - public long[] getShape() { - return shape; - } - - public int getNumDimensions() { - return shape.length; - } - - public int[] getChunks() { - return chunks; - } - - public ZarrCompressor getCompressor() { - return compressor; - } - - public DType getDType() { - return dtype; - } - - public int getZarrFormat() { - return zarr_format; - } - - public char getOrder() { - return order; - } - - public String getFillValue() { - return fill_value; - } - - public HashMap asMap() { - - final HashMap map = new HashMap<>(); - - map.put(zarrFormatKey, zarr_format); - map.put(shapeKey, shape); - map.put(chunksKey, chunks); - map.put(dTypeKey, dtype.toString()); - map.put(compressorKey, compressor instanceof RawCompression ? null : compressor); - map.put(fillValueKey, fill_value); - map.put(orderKey, order); - map.put(filtersKey, filters); - - return map; - } - - public Collection getFilters() { - return filters; - } - - -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrArrayCreator.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrArrayCreator.java deleted file mode 100644 index 7c1d72d6..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrArrayCreator.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.util.Arrays; - -import org.embl.mobie.io.n5.util.ArrayCreator; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; - -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.NativeType; - -public class ZarrArrayCreator> extends ArrayCreator { - private final ZarrAxes zarrAxes; - - public ZarrArrayCreator(CellGrid cellGrid, DataType dataType, ZarrAxes zarrAxes) { - super(cellGrid, dataType); - this.zarrAxes = zarrAxes; - } - - public A createArray(DataBlock dataBlock, long[] gridPosition) { - long[] cellDims = getCellDims(gridPosition); - int n = (int) (cellDims[0] * cellDims[1] * cellDims[2]); - - if (zarrAxes.getNumDimension() == 2) - cellDims = Arrays.stream(cellDims).limit(2).toArray(); - - return (A) VolatileDoubleArray(dataBlock, cellDims, n); - } - - @Override - public long[] getCellDims(long[] gridPosition) { - long[] cellMin = new long[Math.max(zarrAxes.getNumDimension(), 3)]; - int[] cellDims = new int[Math.max(zarrAxes.getNumDimension(), 3)]; - - if(zarrAxes.hasChannels()) { - cellDims[zarrAxes.channelIndex()] = 1; - } - if(zarrAxes.hasTimepoints()) { - cellDims[zarrAxes.timeIndex()] = 1; - } - - cellGrid.getCellDimensions(gridPosition, cellMin, cellDims); - return Arrays.stream(cellDims).mapToLong(i -> i).toArray(); // casting to long for creating ArrayImgs.* - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxes.java deleted file mode 100644 index f3c47cc4..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxes.java +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.google.common.collect.Lists; - -@JsonFormat(shape = JsonFormat.Shape.ARRAY) -public enum ZarrAxes { - YX("[\"y\",\"x\"]"), - CYX("[\"c\",\"y\",\"x\"]"), - TYX("[\"t\",\"y\",\"x\"]"), - ZYX("[\"z\",\"y\",\"x\"]"), - CZYX("[\"c\",\"z\",\"y\",\"x\"]"), - TZYX("[\"t\",\"z\",\"y\",\"x\"]"), - TCYX("[\"t\",\"c\",\"y\",\"x\"]"), - TCZYX("[\"t\",\"c\",\"z\",\"y\",\"x\"]"); // v0.2 - - private final String axes; - - ZarrAxes(String axes) { - this.axes = axes; - } - - @JsonCreator - public static ZarrAxes decode(final String axes) { - return Stream.of(ZarrAxes.values()).filter(targetEnum -> - targetEnum.axes.equals(axes)).findFirst().orElse(TCZYX); - } - - public List getAxesList() { - String pattern = "([a-z])"; - List allMatches = new ArrayList<>(); - Matcher m = Pattern.compile(pattern) - .matcher(axes); - while (m.find()) { - allMatches.add(m.group()); - } - return allMatches; - } - - public List toAxesList(String spaceUnit, String timeUnit) { - List zarrAxesList = new ArrayList<>(); - List zarrAxesStrings = getAxesList(); - - String[] units = new String[]{spaceUnit, timeUnit}; - - // convert to valid ome-zarr units, if possible, otherwise just go ahead with - // given unit - for (int i = 0; i < units.length; i++) { - String unit = units[i]; - if (!UnitTypes.contains(unit)) { - UnitTypes unitType = UnitTypes.convertUnit(unit); - if (unitType != null) { - units[i] = unitType.getTypeName(); - } - } - } - - for (int i = 0; i < zarrAxesStrings.size(); i++) { - String axisString = zarrAxesStrings.get(i); - AxesTypes axisType = AxesTypes.getAxisType(axisString); - - String unit; - if (axisType == AxesTypes.SPACE) { - unit = units[0]; - } else if (axisType == AxesTypes.TIME) { - unit = units[1]; - } else { - unit = null; - } - - zarrAxesList.add(new ZarrAxis(i, axisString, axisType.getTypeName(), unit)); - } - - return zarrAxesList; - } - - public boolean hasTimepoints() { - return this.axes.equals(TCYX.axes) || this.axes.equals(TZYX.axes) || this.axes.equals(TYX.axes) || this.axes.equals(TCZYX.axes); - } - - public boolean hasChannels() { - return this.axes.equals(CZYX.axes) || this.axes.equals(CYX.axes) || this.axes.equals(TCYX.axes) || this.axes.equals(TCZYX.axes); - } - - // the flag reverseAxes determines whether the index will be given w.r.t. - // reversedAxes=true corresponds to the java/bdv axis convention - // reversedAxes=false corresponds to the zarr axis convention - public int axisIndex(String axisName, boolean reverseAxes) { - if(reverseAxes) { - List reverseAxesList = Lists.reverse(getAxesList()); - return reverseAxesList.indexOf(axisName); - } - return getAxesList().indexOf(axisName); - } - - public int timeIndex() { - return axisIndex("t", true); - } - - public int channelIndex() { - return axisIndex("c", true); - } - - // spatial: 0,1,2 (x,y,z) - public Map spatialToZarr() { - final HashMap map = new HashMap<>(); - map.put(0, 0); - map.put(1, 1); - if (hasZAxis()) { - map.put(2, 2); - } - return map; - } - - public boolean hasZAxis() { - return this.axes.equals(TCZYX.axes) || this.axes.equals(CZYX.axes) || this.axes.equals(TZYX.axes) || this.axes.equals(ZYX.axes); - } - - public int getNumDimension() { - return getAxesList().size(); - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxesAdapter.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxesAdapter.java deleted file mode 100644 index ee314425..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxesAdapter.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.lang.reflect.Type; -import java.util.List; - -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -public class ZarrAxesAdapter implements JsonDeserializer, JsonSerializer { - - @Override - public ZarrAxes deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - JsonArray array = json.getAsJsonArray(); - if (array.size() > 0) { - StringBuilder axisString = new StringBuilder("["); - for (int i = 0; i < array.size(); i++) { - String element; - try { - element = array.get(i).getAsString(); - } catch (UnsupportedOperationException e) { - try { - JsonElement jj = array.get(i); - element = jj.getAsJsonObject().get("name").getAsString(); - } catch (Exception exception) { - throw new JsonParseException("" + e); - } - } - if (i != 0) { - axisString.append(","); - } - axisString.append("\""); - axisString.append(element); - axisString.append("\""); - - } - axisString.append("]"); - return ZarrAxes.decode(axisString.toString()); - } else { - return null; - } - } - - @Override - public JsonElement serialize(ZarrAxes axes, Type typeOfSrc, JsonSerializationContext context) { - List axisList = axes.getAxesList(); - JsonArray jsonArray = new JsonArray(); - for (String axis : axisList) { - jsonArray.add(axis); - } - return jsonArray; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxis.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxis.java deleted file mode 100644 index a0409dbe..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrAxis.java +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.util; - -import java.util.List; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; - -public class ZarrAxis { - private transient final int index; - private final String name; - private final String type; - private String unit; - - public ZarrAxis(int index, String name, String type, String unit) { - this.index = index; - this.name = name; - this.type = type; - this.unit = unit; - } - - public ZarrAxis(int index, String name, String type) { - this.index = index; - this.name = name; - this.type = type; - } - - public static JsonElement convertToJson(List zarrAxes) { - StringBuilder axes = new StringBuilder(); - axes.append("["); - for (ZarrAxis axis : zarrAxes) { - axes.append("\"").append(axis.getName()).append("\""); - if (axis.getIndex() < zarrAxes.size() - 1) { - axes.append(","); - } - } - axes.append("]"); - Gson gson = new Gson(); - return gson.fromJson(axes.toString(), JsonElement.class); - } - - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - - public String getType() { - return type; - } - - public String getUnit() { - return unit; - } - - public void setUnit(String unit) { - this.unit = unit; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrDatasetAttributes.java b/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrDatasetAttributes.java deleted file mode 100644 index db199679..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/util/ZarrDatasetAttributes.java +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -/** - * Copyright (c) 2019, Stephan Saalfeld - * All rights reserved. - *

- * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - *

- * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - *

- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -package org.embl.mobie.io.ome.zarr.util; - -import org.janelia.saalfeldlab.n5.Compression; -import org.janelia.saalfeldlab.n5.zarr.DType; - -public class ZarrDatasetAttributes extends org.janelia.saalfeldlab.n5.zarr.ZarrDatasetAttributes { - private final transient String fillValue; - - public ZarrDatasetAttributes( - final long[] dimensions, - final int[] blockSize, - final DType dType, - final Compression compression, - final boolean isRowMajor, - final String fill_value) { - super(dimensions, blockSize, dType, compression, isRowMajor, fill_value); - this.fillValue = fill_value; - } - - public String getFillValue() { - return fillValue; - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/writers/N5OMEZarrWriter.java b/src/main/java/org/embl/mobie/io/ome/zarr/writers/N5OMEZarrWriter.java deleted file mode 100644 index 4ee1985c..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/writers/N5OMEZarrWriter.java +++ /dev/null @@ -1,687 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.writers; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.channels.Channels; -import java.nio.charset.StandardCharsets; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.FileSystemException; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.FileAttribute; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Stream; - -import org.embl.mobie.io.ome.zarr.readers.N5OmeZarrReader; -import org.embl.mobie.io.ome.zarr.util.OmeZArrayAttributes; -import org.embl.mobie.io.ome.zarr.util.ZArrayAttributes; -import org.embl.mobie.io.ome.zarr.util.ZarrDatasetAttributes; -import org.janelia.saalfeldlab.n5.BlockWriter; -import org.janelia.saalfeldlab.n5.ByteArrayDataBlock; -import org.janelia.saalfeldlab.n5.Compression; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.GsonAttributesParser; -import org.janelia.saalfeldlab.n5.N5FSReader; -import org.janelia.saalfeldlab.n5.N5Writer; -import org.janelia.saalfeldlab.n5.zarr.DType; -import org.janelia.saalfeldlab.n5.zarr.Utils; -import org.janelia.saalfeldlab.n5.zarr.ZarrCompressor; - -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; - -import net.imglib2.Cursor; -import net.imglib2.FinalInterval; -import net.imglib2.img.array.ArrayImg; -import net.imglib2.img.array.ArrayImgs; -import net.imglib2.img.basictypeaccess.array.ByteArray; -import net.imglib2.type.numeric.integer.ByteType; -import net.imglib2.util.Intervals; -import net.imglib2.view.Views; - -public class N5OMEZarrWriter extends N5OmeZarrReader implements N5Writer { - - /** - * Opens an {@link N5OMEZarrWriter} at a given base path with a custom - * {@link GsonBuilder} to support custom attributes. - *

- * If the base path does not exist, it will be created. - * - * @param basePath Zarr base path - * @param gsonBuilder - * @param dimensionSeparator - * @param mapN5DatasetAttributes Virtually create N5 dataset attributes (dimensions, blockSize, - * compression, dataType) for datasets such that N5 code that - * reads or modifies these attributes directly works as expected. - * This can lead to name clashes if a zarr container uses these - * attribute keys for other purposes. - * @throws IOException if the base path cannot be written to or cannot be created, - */ - public N5OMEZarrWriter(final String basePath, final GsonBuilder gsonBuilder, final String dimensionSeparator, final boolean mapN5DatasetAttributes) throws IOException { - - super(basePath, gsonBuilder, dimensionSeparator, mapN5DatasetAttributes); - createDirectories(Paths.get(basePath)); - } - - /** - * Opens an {@link N5OMEZarrWriter} at a given base path with a custom - * {@link GsonBuilder} to support custom attributes. - *

- * If the base path does not exist, it will be created. - * - * @param basePath Zarr base path - * @param gsonBuilder - * @param dimensionSeparator - * @throws IOException - */ - public N5OMEZarrWriter(final String basePath, final GsonBuilder gsonBuilder, final String dimensionSeparator) throws IOException { - - this(basePath, gsonBuilder, dimensionSeparator, true); - } - - /** - * Opens an {@link N5OMEZarrWriter} at a given base path. - *

- * If the base path does not exist, it will be created. - * - * @param basePath Zarr base path - * @param dimensionSeparator - * @param mapN5DatasetAttributes Virtually create N5 dataset attributes (dimensions, blockSize, - * compression, dataType) for datasets such that N5 code that - * reads or modifies these attributes directly works as expected. - * This can lead to name collisions if a zarr container uses these - * attribute keys for other purposes. - * @throws IOException - */ - public N5OMEZarrWriter(final String basePath, final String dimensionSeparator, final boolean mapN5DatasetAttributes) throws IOException { - - this(basePath, new GsonBuilder(), dimensionSeparator, mapN5DatasetAttributes); - } - - /** - * Opens an {@link N5OMEZarrWriter} at a given base path. - *

- * If the base path does not exist, it will be created. - * - * @param basePath Zarr base path - * @param mapN5DatasetAttributes Virtually create N5 dataset attributes (dimensions, blockSize, - * compression, dataType) for datasets such that N5 code that - * reads or modifies these attributes directly works as expected. - * This can lead to name collisions if a zarr container uses these - * attribute keys for other purposes. - * @throws IOException - */ - public N5OMEZarrWriter(final String basePath, final boolean mapN5DatasetAttributes) throws IOException { - - this(basePath, new GsonBuilder(), "/", mapN5DatasetAttributes); - } - - /** - * Opens an {@link N5OMEZarrWriter} at a given base path with a custom - * {@link GsonBuilder} to support custom attributes. - *

- * If the base path does not exist, it will be created. - * - * @param basePath Zarr base path - * @param gsonBuilder - * @throws IOException if the base path cannot be written to or cannot be created, - */ - public N5OMEZarrWriter(final String basePath, final GsonBuilder gsonBuilder) throws IOException { - - this(basePath, gsonBuilder, "/"); - } - - /** - * Opens an {@link N5OMEZarrWriter} at a given base path. - *

- * If the base path does not exist, it will be created. - *

- * If the base path exists and if the N5 version of the container is - * compatible with this implementation, the N5 version of this container - * will be set to the current N5 version of this implementation. - * - * @param basePath n5 base path - * @param gsonBuilder - * @throws IOException if the base path cannot be written to or cannot be created, - */ - public N5OMEZarrWriter(final String basePath) throws IOException { - - this(basePath, new GsonBuilder()); - } - - public static byte[] padCrop( - final byte[] src, - final int[] srcBlockSize, - final int[] dstBlockSize, - final int nBytes, - final int nBits, - final byte[] fill_value) { - - assert srcBlockSize.length == dstBlockSize.length : "Dimensions do not match."; - - final int n = srcBlockSize.length; - - if (nBytes != 0) { - final int[] srcStrides = new int[n]; - final int[] dstStrides = new int[n]; - final int[] srcSkip = new int[n]; - final int[] dstSkip = new int[n]; - srcStrides[0] = dstStrides[0] = nBytes; - for (int d = 1; d < n; ++d) { - srcStrides[d] = srcBlockSize[d] * srcBlockSize[d - 1]; - dstStrides[d] = dstBlockSize[d] * dstBlockSize[d - 1]; - } - for (int d = 0; d < n; ++d) { - srcSkip[d] = Math.max(1, dstBlockSize[d] - srcBlockSize[d]); - dstSkip[d] = Math.max(1, srcBlockSize[d] - dstBlockSize[d]); - } - - /* this is getting hairy, ImgLib2 alternative */ - /* byte images with 0-dimension d[0] * nBytes */ - final long[] srcIntervalDimensions = new long[n]; - final long[] dstIntervalDimensions = new long[n]; - srcIntervalDimensions[0] = srcBlockSize[0] * nBytes; - dstIntervalDimensions[0] = dstBlockSize[0] * nBytes; - for (int d = 1; d < n; ++d) { - srcIntervalDimensions[d] = srcBlockSize[d]; - dstIntervalDimensions[d] = dstBlockSize[d]; - } - - final byte[] dst = new byte[(int) Intervals.numElements(dstIntervalDimensions)]; - /* fill dst */ - for (int i = 0, j = 0; i < n; ++i) { - dst[i] = fill_value[j]; - if (++j == fill_value.length) - j = 0; - } - final ArrayImg srcImg = ArrayImgs.bytes(src, srcIntervalDimensions); - final ArrayImg dstImg = ArrayImgs.bytes(dst, dstIntervalDimensions); - - final FinalInterval intersection = Intervals.intersect(srcImg, dstImg); - final Cursor srcCursor = Views.interval(srcImg, intersection).cursor(); - final Cursor dstCursor = Views.interval(dstImg, intersection).cursor(); - while (srcCursor.hasNext()) - dstCursor.next().set(srcCursor.next()); - - return dst; - } else { - /* TODO deal with bit streams */ - return null; - } - } - - /** - * Writes a {@link DataBlock} into an {@link OutputStream}. - * - * @param out - * @param datasetAttributes - * @param dataBlock - * @throws IOException - */ - public static void writeBlock( - final OutputStream out, - final ZarrDatasetAttributes datasetAttributes, - final DataBlock dataBlock) throws IOException { - - final int[] blockSize = datasetAttributes.getBlockSize(); - final DType dType = datasetAttributes.getDType(); - final DataOutputStream dos = new DataOutputStream(out); - final BlockWriter writer = datasetAttributes.getCompression().getWriter(); - - if (!Arrays.equals(blockSize, dataBlock.getSize())) { - - final byte[] padCropped = padCrop( - dataBlock.toByteBuffer().array(), - dataBlock.getSize(), - blockSize, - dType.getNBytes(), - dType.getNBits(), - datasetAttributes.getFillBytes()); - - final DataBlock padCroppedDataBlock = - new ByteArrayDataBlock( - blockSize, - dataBlock.getGridPosition(), - padCropped); - - writer.write(padCroppedDataBlock, out); - - } else { - - writer.write(dataBlock, out); - } - } - - /** - * This is a copy of {@link Files#createDirectories(Path, FileAttribute...)} - * that follows symlinks. - *

- * Workaround for https://bugs.openjdk.java.net/browse/JDK-8130464 - *

- * Creates a directory by creating all nonexistent parent directories first. - * Unlike the {@link #createDirectory createDirectory} method, an exception - * is not thrown if the directory could not be created because it already - * exists. - * - *

The {@code attrs} parameter is optional {@link FileAttribute - * file-attributes} to set atomically when creating the nonexistent - * directories. Each file attribute is identified by its {@link - * FileAttribute#name name}. If more than one attribute of the same name is - * included in the array then all but the last occurrence is ignored. - * - *

If this method fails, then it may do so after creating some, but not - * all, of the parent directories. - * - * @param dir the directory to create - * @param attrs an optional list of file attributes to set atomically when - * creating the directory - * @return the directory - * @throws UnsupportedOperationException if the array contains an attribute that cannot be set atomically - * when creating the directory - * @throws FileAlreadyExistsException if {@code dir} exists but is not a directory (optional specific - * exception) - * @throws IOException if an I/O error occurs - * @throws SecurityException in the case of the default provider, and a security manager is - * installed, the {@link SecurityManager#checkWrite(String) checkWrite} - * method is invoked prior to attempting to create a directory and - * its {@link SecurityManager#checkRead(String) checkRead} is - * invoked for each parent directory that is checked. If {@code - * dir} is not an absolute path then its {@link Path#toAbsolutePath - * toAbsolutePath} may need to be invoked to get its absolute path. - * This may invoke the security manager's {@link - * SecurityManager#checkPropertyAccess(String) checkPropertyAccess} - * method to check access to the system property {@code user.dir} - */ - private static Path createDirectories(Path dir, final FileAttribute... attrs) - throws IOException { - // attempt to create the directory - try { - createAndCheckIsDirectory(dir, attrs); - return dir; - } catch (final FileAlreadyExistsException x) { - // file exists and is not a directory - throw x; - } catch (final IOException x) { - // parent may not exist or other reason - } - SecurityException se = null; - try { - dir = dir.toAbsolutePath(); - } catch (final SecurityException x) { - // don't have permission to get absolute path - se = x; - } - // find a decendent that exists - Path parent = dir.getParent(); - while (parent != null) { - try { - parent.getFileSystem().provider().checkAccess(parent); - break; - } catch (final NoSuchFileException x) { - // does not exist - } - parent = parent.getParent(); - } - if (parent == null) { - // unable to find existing parent - if (se == null) { - throw new FileSystemException(dir.toString(), null, - "Unable to determine if root directory exists"); - } else { - throw se; - } - } - - // create directories - Path child = parent; - for (final Path name : parent.relativize(dir)) { - child = child.resolve(name); - createAndCheckIsDirectory(child, attrs); - } - return dir; - } - - /** - * This is a copy of {@link Files#createAndCheckIsDirectory(Path, FileAttribute...)} - * that follows symlinks. - *

- * Workaround for https://bugs.openjdk.java.net/browse/JDK-8130464 - *

- * Used by createDirectories to attempt to create a directory. A no-op - * if the directory already exists. - */ - private static void createAndCheckIsDirectory(final Path dir, - final FileAttribute... attrs) - throws IOException { - try { - Files.createDirectory(dir, attrs); - } catch (final FileAlreadyExistsException x) { - if (!Files.isDirectory(dir)) - throw x; - } - } - - /** - * Removes the trailing slash from a given path and returns the corrected path. - * - * @param pathName - * @return - */ - protected static String removeTrailingSlash(final String pathName) { - - return pathName.endsWith("/") || pathName.endsWith("\\") ? pathName.substring(0, pathName.length() - 1) : pathName; - } - - @Override - public void createGroup(final String pathName) throws IOException { - - final Path path = Paths.get(basePath, pathName); - createDirectories(path); - - final Path root = Paths.get(basePath); - Path parent = path; - for (setGroupVersion(parent); !parent.equals(root); ) { - parent = parent.getParent(); - setGroupVersion(parent); - } - } - - protected void setGroupVersion(final Path groupPath) throws IOException { - - final Path path = groupPath.resolve(zgroupFile); - final HashMap map = new HashMap<>(); - map.put("zarr_format", new JsonPrimitive(N5OmeZarrReader.VERSION.getMajor())); - - try (final N5FSReader.LockedFileChannel lockedFileChannel = N5FSReader.LockedFileChannel.openForWriting(path)) { - lockedFileChannel.getFileChannel().truncate(0); - GsonAttributesParser.writeAttributes(Channels.newWriter(lockedFileChannel.getFileChannel(), StandardCharsets.UTF_8.name()), map, gson); - } - } - - public void setZArrayAttributes( - final String pathName, - final ZArrayAttributes attributes) throws IOException { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zarrayFile); - final HashMap map = new HashMap<>(); - GsonAttributesParser.insertAttributes(map, attributes.asMap(), gson); - - try (final N5FSReader.LockedFileChannel lockedFileChannel = N5FSReader.LockedFileChannel.openForWriting(path)) { - - lockedFileChannel.getFileChannel().truncate(0); - GsonAttributesParser.writeAttributes(Channels.newWriter(lockedFileChannel.getFileChannel(), StandardCharsets.UTF_8.name()), map, gson); - } - } - - @Override - public void setDatasetAttributes( - final String pathName, - final DatasetAttributes datasetAttributes) throws IOException { - - final long[] shape = datasetAttributes.getDimensions().clone(); - Utils.reorder(shape); - final int[] chunks = datasetAttributes.getBlockSize().clone(); - Utils.reorder(chunks); - - final OmeZArrayAttributes zArrayAttributes = new OmeZArrayAttributes( - N5OmeZarrReader.VERSION.getMajor(), - shape, - chunks, - new DType(datasetAttributes.getDataType()), - ZarrCompressor.fromCompression(datasetAttributes.getCompression()), - "0", - 'C', - null, - dimensionSeparator); - - setZArrayAttributes(pathName, zArrayAttributes); - } - - @Override - public void createDataset( - final String pathName, - final DatasetAttributes datasetAttributes) throws IOException { - int lastSlashIndex = removeTrailingSlash(pathName).lastIndexOf("/"); - - if (lastSlashIndex != -1) { - /* create parent groups */ - final String parentGroup = pathName.substring(0, removeTrailingSlash(pathName).lastIndexOf('/')); - if (!parentGroup.equals("")) - createGroup(parentGroup); - } - - final Path path = Paths.get(basePath, pathName); - createDirectories(path); - - setDatasetAttributes(pathName, datasetAttributes); - } - - public void setAttributes(HashMap elements, String pathName) throws IOException { - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zattrsFile); - try (final N5FSReader.LockedFileChannel lockedFileChannel = N5FSReader.LockedFileChannel.openForWriting(path)) { - elements.putAll( - GsonAttributesParser.readAttributes( - Channels.newReader( - lockedFileChannel.getFileChannel(), - StandardCharsets.UTF_8.name()), - gson)); - - lockedFileChannel.getFileChannel().truncate(0); - GsonAttributesParser.writeAttributes( - Channels.newWriter(lockedFileChannel.getFileChannel(), StandardCharsets.UTF_8.name()), - elements, - gson); - } - } - - @Override - public void setAttributes( - final String pathName, - Map attributes) throws IOException { - - final Path path = Paths.get(basePath, removeLeadingSlash(pathName), zattrsFile); - final HashMap map = new HashMap<>(); - - try (final N5FSReader.LockedFileChannel lockedFileChannel = N5FSReader.LockedFileChannel.openForWriting(path)) { - map.putAll( - GsonAttributesParser.readAttributes( - Channels.newReader( - lockedFileChannel.getFileChannel(), - StandardCharsets.UTF_8.name()), - gson)); - - if (mapN5DatasetAttributes && datasetExists(pathName)) { - attributes = new HashMap<>(attributes); - ZArrayAttributes zArrayAttributes = getZArrayAttributes(pathName); - long[] shape; - int[] chunks; - final DType dtype; - final ZarrCompressor compressor; - final boolean isRowMajor = zArrayAttributes.getOrder() == 'C'; - - if (attributes.containsKey("dimensions")) { - shape = (long[]) attributes.get("dimensions"); - attributes.remove("dimensions"); - if (isRowMajor) { - shape = shape.clone(); - Utils.reorder(shape); - } - } else - shape = zArrayAttributes.getShape(); - - if (attributes.containsKey("blockSize")) { - chunks = (int[]) attributes.get("blockSize"); - attributes.remove("blockSize"); - if (isRowMajor) { - chunks = chunks.clone(); - Utils.reorder(chunks); - } - } else - chunks = zArrayAttributes.getChunks(); - - if (attributes.containsKey("dataType")) { - dtype = new DType((DataType) attributes.get("dataType")); - attributes.remove("dataType"); - } else - dtype = zArrayAttributes.getDType(); - - if (attributes.containsKey("compression")) { - compressor = ZarrCompressor.fromCompression((Compression) attributes.get("compression")); - attributes.remove("compression"); - /* fails with null when compression is not supported by Zarr - * TODO invent meaningful error behavior */ - } else - compressor = zArrayAttributes.getCompressor(); - - zArrayAttributes = new OmeZArrayAttributes( - zArrayAttributes.getZarrFormat(), - shape, - chunks, - dtype, - compressor, - zArrayAttributes.getFillValue(), - zArrayAttributes.getOrder(), - zArrayAttributes.getFilters(), - dimensionSeparator); - - setZArrayAttributes(pathName, zArrayAttributes); - } - - GsonAttributesParser.insertAttributes(map, attributes, gson); - - lockedFileChannel.getFileChannel().truncate(0); - GsonAttributesParser.writeAttributes( - Channels.newWriter(lockedFileChannel.getFileChannel(), StandardCharsets.UTF_8.name()), - map, - gson); - } - } - - @Override - public void writeBlock( - final String pathName, - final DatasetAttributes datasetAttributes, - final DataBlock dataBlock) throws IOException { - final ZarrDatasetAttributes zarrDatasetAttributes; - if (datasetAttributes instanceof ZarrDatasetAttributes) - zarrDatasetAttributes = (ZarrDatasetAttributes) datasetAttributes; - else - zarrDatasetAttributes = getZArrayAttributes(pathName).getDatasetAttributes(); - - final Path path = Paths.get( - basePath, - removeLeadingSlash(pathName), - getZarrDataBlockString( - dataBlock.getGridPosition(), - dimensionSeparator, - zarrDatasetAttributes.isRowMajor())); - createDirectories(path.getParent()); - try (final N5FSReader.LockedFileChannel lockedChannel = N5FSReader.LockedFileChannel.openForWriting(path)) { - - lockedChannel.getFileChannel().truncate(0); - writeBlock( - Channels.newOutputStream(lockedChannel.getFileChannel()), - zarrDatasetAttributes, - dataBlock); - } - } - - @Override - public boolean deleteBlock(final String pathName, final long... gridPosition) throws IOException { - - final DatasetAttributes datasetAttributes = getDatasetAttributes(pathName); - - final ZarrDatasetAttributes zarrDatasetAttributes; - if (datasetAttributes instanceof ZarrDatasetAttributes) - zarrDatasetAttributes = (ZarrDatasetAttributes) datasetAttributes; - else - zarrDatasetAttributes = getZArrayAttributes(pathName).getDatasetAttributes(); - - final Path path = Paths.get( - basePath, - removeLeadingSlash(pathName), - getZarrDataBlockString( - gridPosition, - dimensionSeparator, - zarrDatasetAttributes.isRowMajor())); - - if (!Files.exists(path)) - return true; - - try (final N5FSReader.LockedFileChannel lockedChannel = N5FSReader.LockedFileChannel.openForWriting(path)) { - Files.delete(path); - } - - return !Files.exists(path); - } - - @Override - public boolean remove() throws IOException { - - return remove("/"); - } - - @Override - public boolean remove(final String pathName) throws IOException { - - final Path path = Paths.get(basePath, pathName); - if (Files.exists(path)) - try (final Stream pathStream = Files.walk(path)) { - pathStream.sorted(Comparator.reverseOrder()).forEach( - childPath -> { - if (Files.isRegularFile(childPath)) { - try (final N5FSReader.LockedFileChannel channel = N5FSReader.LockedFileChannel.openForWriting(childPath)) { - Files.delete(childPath); - } catch (final IOException e) { - e.printStackTrace(); - } - } else - try { - Files.delete(childPath); - } catch (final IOException e) { - e.printStackTrace(); - } - }); - } - - return !Files.exists(path); - } - -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/writers/imageplus/WriteImagePlusToN5OmeZarr.java b/src/main/java/org/embl/mobie/io/ome/zarr/writers/imageplus/WriteImagePlusToN5OmeZarr.java deleted file mode 100644 index c0a7c619..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/writers/imageplus/WriteImagePlusToN5OmeZarr.java +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.writers.imageplus; - -import java.io.File; -import java.io.IOException; -import java.util.Map; - -import org.embl.mobie.io.n5.util.DownsampleBlock; -import org.embl.mobie.io.n5.util.ExportScalePyramid; -import org.embl.mobie.io.n5.writers.WriteImagePlusToN5; -import org.janelia.saalfeldlab.n5.Compression; - -import bdv.export.ExportMipmapInfo; -import bdv.export.ProgressWriter; -import bdv.export.ProposeMipmaps; -import bdv.export.SubTaskProgressWriter; -import bdv.spimdata.SequenceDescriptionMinimal; -import ij.IJ; -import ij.ImagePlus; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.realtransform.AffineTransform3D; - -import static org.embl.mobie.io.n5.writers.WriteImagePlusToN5Helper.getSize; -import static org.embl.mobie.io.n5.writers.WriteImagePlusToN5Helper.getVoxelSize; - -public class WriteImagePlusToN5OmeZarr extends WriteImagePlusToN5 { - - // TODO - deal with transforms properly - here the voxel size is just taken directly from the imp for scaling. - // the sourceTransform is ignored. In next ome-zarr version, when affine is supported, - // need to properly add the provided affine. - // Also, I think viewSetupNames are ignored, as they are only relevant for xml style files. Should re-write this - // so less redundant now that the bdv xml style is removed - - // export, generating default source transform, and default resolutions / subdivisions - @Override - public void export(ImagePlus imp, String zarrPath, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression) { - super.export(imp, zarrPath, downsamplingMethod, compression); - } - - // export, generating default resolutions / subdivisions - @Override - public void export(ImagePlus imp, String zarrPath, AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression) { - super.export(imp, zarrPath, sourceTransform, downsamplingMethod, compression); - } - - - // export, generating default resolutions / subdivisions - @Override - public void export(ImagePlus imp, String zarrPath, AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression, String[] viewSetupNames) { - super.export(imp, zarrPath, sourceTransform, downsamplingMethod, compression, viewSetupNames); - } - - @Override - public void export(ImagePlus imp, int[][] resolutions, int[][] subdivisions, String zarrPath, AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression) { - export(imp, resolutions, subdivisions, zarrPath, sourceTransform, downsamplingMethod, compression, null); - } - - @Override - public void export(ImagePlus imp, int[][] resolutions, int[][] subdivisions, String zarrPath, AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression, String[] viewSetupNames) { - if (resolutions.length == 0) { - IJ.showMessage("Invalid resolutions - length 0"); - return; - } - - if (subdivisions.length == 0) { - IJ.showMessage(" Invalid subdivisions - length 0"); - return; - } - - if (resolutions.length != subdivisions.length) { - IJ.showMessage("Subsampling factors and chunk sizes must have the same number of elements"); - return; - } - - final File zarrFile = new File(zarrPath); - - Parameters exportParameters = new Parameters(resolutions, subdivisions, null, zarrFile, sourceTransform, downsamplingMethod, compression, viewSetupNames, imp.getCalibration().getTimeUnit(), imp.getCalibration().frameInterval); - - export(imp, exportParameters); - } - - @Override - protected Parameters generateDefaultParameters(ImagePlus imp, String zarrPath, AffineTransform3D sourceTransform, DownsampleBlock.DownsamplingMethod downsamplingMethod, Compression compression, String[] viewSetupNames) { - FinalVoxelDimensions voxelSize = getVoxelSize(imp); - FinalDimensions size = getSize(imp); - - // propose reasonable mipmap settings - final int maxNumElements = 64 * 64 * 64; - final ExportMipmapInfo autoMipmapSettings = ProposeMipmaps.proposeMipmaps( - new BasicViewSetup(0, "", size, voxelSize), - maxNumElements); - - int[][] resolutions = autoMipmapSettings.getExportResolutions(); - int[][] subdivisions = autoMipmapSettings.getSubdivisions(); - - if (resolutions.length == 0 || subdivisions.length == 0 || resolutions.length != subdivisions.length) { - IJ.showMessage("Error with calculating default subdivisions and resolutions"); - return null; - } - - final File zarrFile = new File(zarrPath); - - return new Parameters(resolutions, subdivisions, null, zarrFile, sourceTransform, - downsamplingMethod, compression, viewSetupNames, imp.getCalibration().getTimeUnit(), - imp.getCalibration().frameInterval); - } - - @Override - protected void writeFiles(SequenceDescriptionMinimal seq, Map perSetupExportMipmapInfo, Parameters params, ExportScalePyramid.LoopbackHeuristic loopbackHeuristic, ExportScalePyramid.AfterEachPlane afterEachPlane, int numCellCreatorThreads, ProgressWriter progressWriter, int numTimepoints, int numSetups) throws IOException { - WriteSequenceToN5OmeZarr.writeOmeZarrFile(seq, perSetupExportMipmapInfo, params.downsamplingMethod, params.compression, params.timeUnit, params.frameInterval, params.n5File, loopbackHeuristic, afterEachPlane, numCellCreatorThreads, new SubTaskProgressWriter(progressWriter, 0, 0.95)); - - progressWriter.setProgress(1.0); - } -} diff --git a/src/main/java/org/embl/mobie/io/ome/zarr/writers/imageplus/WriteSequenceToN5OmeZarr.java b/src/main/java/org/embl/mobie/io/ome/zarr/writers/imageplus/WriteSequenceToN5OmeZarr.java deleted file mode 100644 index 4e7e0238..00000000 --- a/src/main/java/org/embl/mobie/io/ome/zarr/writers/imageplus/WriteSequenceToN5OmeZarr.java +++ /dev/null @@ -1,451 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.ome.zarr.writers.imageplus; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.embl.mobie.io.n5.util.DownsampleBlock; -import org.embl.mobie.io.n5.util.ExportScalePyramid; -import org.embl.mobie.io.ome.zarr.util.N5OMEZarrCacheArrayLoader; -import org.embl.mobie.io.ome.zarr.util.OmeZarrMultiscales; -import org.embl.mobie.io.ome.zarr.util.ZarrAxes; -import org.embl.mobie.io.ome.zarr.util.ZarrDatasetAttributes; -import org.embl.mobie.io.ome.zarr.writers.N5OMEZarrWriter; -import org.janelia.saalfeldlab.n5.ByteArrayDataBlock; -import org.janelia.saalfeldlab.n5.Compression; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.DoubleArrayDataBlock; -import org.janelia.saalfeldlab.n5.FloatArrayDataBlock; -import org.janelia.saalfeldlab.n5.IntArrayDataBlock; -import org.janelia.saalfeldlab.n5.LongArrayDataBlock; -import org.janelia.saalfeldlab.n5.ShortArrayDataBlock; -import org.janelia.saalfeldlab.n5.imglib2.N5Utils; - -import com.google.gson.GsonBuilder; - -import bdv.export.ExportMipmapInfo; -import bdv.export.ProgressWriter; -import bdv.export.ProgressWriterNull; -import bdv.export.SubTaskProgressWriter; -import bdv.img.cache.SimpleCacheArrayLoader; -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.BasicImgLoader; -import mpicbg.spim.data.generic.sequence.BasicSetupImgLoader; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.ViewId; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.cache.img.ReadOnlyCachedCellImgFactory; -import net.imglib2.img.cell.Cell; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.util.Cast; - -import static net.imglib2.cache.img.ReadOnlyCachedCellImgOptions.options; -import static org.embl.mobie.io.ome.zarr.util.OmeZarrMultiscales.MULTI_SCALE_KEY; - -public class WriteSequenceToN5OmeZarr { - - private static final String ARRAY_DIMENSIONS_KEY = "_ARRAY_DIMENSIONS"; - - /** - * Create a ome zarr group containing image data from all views and all - * timepoints in a chunked, mipmaped representation. - * - * @param seq description of the sequence to be stored as ome-zarr. (The - * {@link AbstractSequenceDescription} contains the number of - * setups and timepoints as well as an {@link BasicImgLoader} - * that provides the image data, Registration information is not - * needed here, that will go into the accompanying xml). - * @param perSetupMipmapInfo this maps from setup {@link BasicViewSetup#getId() id} to - * {@link ExportMipmapInfo} for that setup. The - * {@link ExportMipmapInfo} contains for each mipmap level, the - * subsampling factors and subdivision block sizes. - * @param compression n5 compression scheme. - * @param zarrFile zarr file root. - * @param loopbackHeuristic heuristic to decide whether to create each resolution level by - * reading pixels from the original image or by reading back a - * finer resolution level already written to the ome-zarr. may be - * null (in this case always use the original image). - * @param afterEachPlane this is called after each "plane of chunks" is written, giving - * the opportunity to clear caches, etc. - * @param numCellCreatorThreads The number of threads that will be instantiated to generate - * cell data. Must be at least 1. (In addition the cell creator - * threads there is one writer thread that saves the generated - * data to HDF5.) - * @param progressWriter completion ratio and status output will be directed here. - */ - public static void writeOmeZarrFile( - final AbstractSequenceDescription seq, - final Map perSetupMipmapInfo, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, - final Compression compression, - final String timeUnit, - final double frameInterval, - final File zarrFile, - final ExportScalePyramid.LoopbackHeuristic loopbackHeuristic, - final ExportScalePyramid.AfterEachPlane afterEachPlane, - final int numCellCreatorThreads, - ProgressWriter progressWriter) throws IOException { - if (progressWriter == null) - progressWriter = new ProgressWriterNull(); - progressWriter.setProgress(0); - - final BasicImgLoader imgLoader = seq.getImgLoader(); - - for (final BasicViewSetup setup : seq.getViewSetupsOrdered()) { - final Object type = imgLoader.getSetupImgLoader(setup.getId()).getImageType(); - if (!(type instanceof RealType && - type instanceof NativeType && - N5Utils.dataType(Cast.unchecked(type)) != null)) - throw new IllegalArgumentException("Unsupported pixel type: " + type.getClass().getSimpleName()); - } - - final List timepointIds = seq.getTimePoints().getTimePointsOrdered().stream() - .map(TimePoint::getId) - .collect(Collectors.toList()); - final List setupIds = seq.getViewSetupsOrdered().stream() - .map(BasicViewSetup::getId) - .collect(Collectors.toList()); - - N5OMEZarrWriter zarrWriter = new N5OMEZarrWriter(zarrFile.getAbsolutePath(), new GsonBuilder(), "/"); - - ZarrAxes axes; - if (timepointIds.size() > 1 && setupIds.size() > 1) { - axes = ZarrAxes.TCZYX; - } else if (timepointIds.size() > 1) { - axes = ZarrAxes.TZYX; - } else if (setupIds.size() > 1) { - axes = ZarrAxes.CZYX; - } else { - axes = ZarrAxes.ZYX; - } - - // create group for top directory & add multiscales - // Currently we write v0.4 ome-zarr - // Assumes persetupmipmapinfo is the same for every setup, and unit same for every setup - OmeZarrMultiscales[] multiscales = new OmeZarrMultiscales[1]; - multiscales[0] = new OmeZarrMultiscales(axes, zarrFile.getName().split("\\.")[0], downsamplingMethod.name(), "0.4", seq.getViewSetupsOrdered().get(0).getVoxelSize(), perSetupMipmapInfo.get(0).getResolutions(), timeUnit, frameInterval); - - zarrWriter.createGroup(""); - zarrWriter.setAttribute("", MULTI_SCALE_KEY, multiscales); - - // calculate number of tasks for progressWriter - int numTasks = 0; // first task is for writing mipmap descriptions etc... - for (final int timepointIdSequence : timepointIds) - for (final int setupIdSequence : setupIds) - if (seq.getViewDescriptions().get(new ViewId(timepointIdSequence, setupIdSequence)).isPresent()) - numTasks++; - int numCompletedTasks = 0; - - final ExecutorService executorService = Executors.newFixedThreadPool(numCellCreatorThreads); - try { - // write image data for all views - final int numTimepoints = timepointIds.size(); - int timepointIndex = 0; - for (final int timepointId : timepointIds) { - progressWriter.out().printf("proccessing timepoint %d / %d\n", ++timepointIndex, numTimepoints); - - // assemble the viewsetups that are present in this timepoint - final ArrayList setupsTimePoint = new ArrayList<>(); - for (final int setupId : setupIds) - if (seq.getViewDescriptions().get(new ViewId(timepointId, setupId)).isPresent()) - setupsTimePoint.add(setupId); - - final int numSetups = setupsTimePoint.size(); - int setupIndex = 0; - for (final int setupId : setupsTimePoint) { - progressWriter.out().printf("proccessing setup %d / %d\n", ++setupIndex, numSetups); - - final ExportMipmapInfo mipmapInfo = perSetupMipmapInfo.get(setupId); - final double startCompletionRatio = (double) numCompletedTasks++ / numTasks; - final double endCompletionRatio = (double) numCompletedTasks / numTasks; - final ProgressWriter subProgressWriter = new SubTaskProgressWriter(progressWriter, startCompletionRatio, endCompletionRatio); - writeScalePyramid( - zarrWriter, compression, downsamplingMethod, - imgLoader, setupId, timepointId, numSetups, numTimepoints, axes, - mipmapInfo, - executorService, numCellCreatorThreads, - loopbackHeuristic, afterEachPlane, subProgressWriter); - } - } - } finally { - executorService.shutdown(); - } - - progressWriter.setProgress(1.0); - } - - static & NativeType> void writeScalePyramid( - final N5OMEZarrWriter zarrWriter, - final Compression compression, - final DownsampleBlock.DownsamplingMethod downsamplingMethod, - final BasicImgLoader imgLoader, - final int setupId, - final int timepointId, - final int totalNSetups, - final int totalNTimepoints, - final ZarrAxes axes, - final ExportMipmapInfo mipmapInfo, - final ExecutorService executorService, - final int numThreads, - final ExportScalePyramid.LoopbackHeuristic loopbackHeuristic, - final ExportScalePyramid.AfterEachPlane afterEachPlane, - ProgressWriter progressWriter) throws IOException { - final BasicSetupImgLoader setupImgLoader = Cast.unchecked(imgLoader.getSetupImgLoader(setupId)); - final RandomAccessibleInterval img = setupImgLoader.getImage(timepointId); - final T type = setupImgLoader.getImageType(); - final OmeZarrDatasetIO io = new OmeZarrDatasetIO<>(zarrWriter, compression, setupId, timepointId, type, - totalNSetups, totalNTimepoints, axes); - ExportScalePyramid.writeScalePyramid( - img, type, mipmapInfo, downsamplingMethod, io, - executorService, numThreads, - loopbackHeuristic, afterEachPlane, progressWriter); - } - - static class OmeZarrDataset { - final String pathName; - final DatasetAttributes attributes; - - public OmeZarrDataset(final String pathName, final DatasetAttributes attributes) { - this.pathName = pathName; - this.attributes = attributes; - } - } - - static class OmeZarrDatasetIO & NativeType> implements ExportScalePyramid.DatasetIO { - private final N5OMEZarrWriter zarrWriter; - private final Compression compression; - private final int setupId; - private final int timepointId; - private final DataType dataType; - private final T type; - private final Function, DataBlock> getDataBlock; - private final int totalNSetups; - private final int totalNTimepoints; - private final ZarrAxes axes; - - public OmeZarrDatasetIO(final N5OMEZarrWriter zarrWriter, final Compression compression, final int setupId, - final int timepointId, final T type, - final int totalNSetups, final int totalNTimepoints, ZarrAxes axes) { - this.zarrWriter = zarrWriter; - this.compression = compression; - this.setupId = setupId; - this.timepointId = timepointId; - this.dataType = N5Utils.dataType(type); - this.type = type; - this.totalNSetups = totalNSetups; - this.totalNTimepoints = totalNTimepoints; - this.axes = axes; - - switch (dataType) { - case UINT8: - getDataBlock = b -> new ByteArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case UINT16: - getDataBlock = b -> new ShortArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case UINT32: - getDataBlock = b -> new IntArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case UINT64: - getDataBlock = b -> new LongArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT8: - getDataBlock = b -> new ByteArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT16: - getDataBlock = b -> new ShortArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT32: - getDataBlock = b -> new IntArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case INT64: - getDataBlock = b -> new LongArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case FLOAT32: - getDataBlock = b -> new FloatArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - case FLOAT64: - getDataBlock = b -> new DoubleArrayDataBlock(b.getSize(), b.getGridPosition(), Cast.unchecked(b.getData().getStorageArray())); - break; - default: - throw new IllegalArgumentException(); - } - } - - private String getPathName(int level) { - if (totalNTimepoints > 1 && totalNSetups > 1) { - return String.format("s%d/%d/%d", level, timepointId, setupId); - } else if (totalNSetups > 1) { - return String.format("s%d/%d", level, setupId); - } else if (totalNTimepoints > 1) { - return String.format("s%d/%d", level, timepointId); - } else { - return String.format("s%d", level); - } - } - - private int[] addSingletonDimensionsToChunks(int[] zyxChunks) { - // add any required dimensions for time or channels (we enforce a chunk size of 1 for these axes) - int[] chunks; - - int nAxes; - if (totalNSetups > 1 && totalNTimepoints > 1) { - nAxes = 5; - } else if (totalNSetups > 1 || totalNTimepoints > 1) { - nAxes = 4; - } else { - nAxes = 3; - } - - if (nAxes > 3) { - chunks = new int[nAxes]; - for (int i = 0; i < nAxes; i++) { - if (i < 3) { - chunks[i] = zyxChunks[i]; - } else { - chunks[i] = 1; - } - } - } else { - chunks = zyxChunks; - } - - return chunks; - } - - private long[] addSetupAndTimeToShape(long[] zyxShape) { - // add any required dimensions for time or channels - long[] shape; - - if (totalNSetups > 1 && totalNTimepoints > 1) { - shape = new long[5]; - shape[3] = totalNSetups; - shape[4] = totalNTimepoints; - } else if (totalNSetups > 1) { - shape = new long[4]; - shape[3] = totalNSetups; - } else if (totalNTimepoints > 1) { - shape = new long[4]; - shape[3] = totalNTimepoints; - } else { - shape = new long[3]; - } - - for (int i = 0; i < 3; i++) { - shape[i] = zyxShape[i]; - } - - return shape; - } - - private long[] removeSetupAndTimeFromShape(long[] shape) { - long[] xyzShape = new long[3]; - for (int i = 0; i < 3; i++) { - xyzShape[i] = shape[i]; - } - return xyzShape; - } - - private int[] removeSetupAndTimeFromShape(int[] shape) { - int[] xyzShape = new int[3]; - for (int i = 0; i < 3; i++) { - xyzShape[i] = shape[i]; - } - return xyzShape; - } - - @Override - public OmeZarrDataset createDataset(final int level, final long[] zyxDimensions, final int[] zyxBlockSize) throws IOException { - // create dataset directory + metadata - final String pathName = "s" + level; - zarrWriter.createDataset(pathName, addSetupAndTimeToShape(zyxDimensions), - addSingletonDimensionsToChunks(zyxBlockSize), dataType, compression); - - // TODO - ideally this would go inside zarrWriter.createDataset(), but it's a bit complicated to get it there - zarrWriter.setAttribute(pathName, ARRAY_DIMENSIONS_KEY, axes); - - // here we have to get the zarr attributes that were written, and re-set the shape/chunks to just zyx, as - // all the chunking etc operates only in 3D - final ZarrDatasetAttributes zarrDatasetAttributes = (ZarrDatasetAttributes) zarrWriter.getDatasetAttributes(pathName); - final DatasetAttributes datasetAttributes = new ZarrDatasetAttributes(zyxDimensions, zyxBlockSize, - zarrDatasetAttributes.getDType(), compression, - zarrDatasetAttributes.isRowMajor(), - zarrDatasetAttributes.getFillValue()); - - // we provide the full path, including any time or channels to actually write blocks - return new OmeZarrDataset(getPathName(level), datasetAttributes); - } - - @Override - public void writeBlock(final OmeZarrDataset dataset, final ExportScalePyramid.Block dataBlock) throws IOException { - zarrWriter.writeBlock(dataset.pathName, dataset.attributes, getDataBlock.apply(dataBlock)); - } - - @Override - public void flush(final OmeZarrDataset dataset) { - } - - @Override - public RandomAccessibleInterval getImage(final int level) throws IOException { - // this needs to return the zyx image for the current timepoint and channel (as we are only chunking in zyx) - final String pathName = String.format("s%d", level); // only include level as rest is handled by N5OmeZarrCacheArrayLoader - final DatasetAttributes attributes = zarrWriter.getDatasetAttributes(pathName); - final long[] dimensions = removeSetupAndTimeFromShape(attributes.getDimensions()); - final int[] cellDimensions = removeSetupAndTimeFromShape(attributes.getBlockSize()); - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - final SimpleCacheArrayLoader cacheArrayLoader = - new N5OMEZarrCacheArrayLoader<>(zarrWriter, pathName, setupId, timepointId, attributes, grid, axes); - return new ReadOnlyCachedCellImgFactory().createWithCacheLoader( - dimensions, type, - key -> { - final int n = grid.numDimensions(); - final long[] cellMin = new long[n]; - final int[] cellDims = new int[n]; - final long[] cellGridPosition = new long[n]; - grid.getCellDimensions(key, cellMin, cellDims); - grid.getCellGridPositionFlat(key, cellGridPosition); - return new Cell<>(cellDims, cellMin, cacheArrayLoader.loadArray(cellGridPosition, cellDims)); - }, - options().cellDimensions(cellDimensions)); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/openorganelle/N5CacheArrayLoader.java b/src/main/java/org/embl/mobie/io/openorganelle/N5CacheArrayLoader.java deleted file mode 100644 index f761fe41..00000000 --- a/src/main/java/org/embl/mobie/io/openorganelle/N5CacheArrayLoader.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.openorganelle; - -import java.util.Arrays; - -import net.imglib2.img.basictypeaccess.DataAccess; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5Reader; - -import bdv.img.cache.SimpleCacheArrayLoader; - -import net.imglib2.img.cell.CellGrid; - - -public class N5CacheArrayLoader implements SimpleCacheArrayLoader { - private final N5Reader n5; - private final String pathName; - private final DatasetAttributes attributes; - private final OrganelleArrayCreator arrayCreator; - - N5CacheArrayLoader(final N5Reader n5, final String pathName, final DatasetAttributes attributes, CellGrid grid) { - this.n5 = n5; - this.pathName = pathName; - this.attributes = attributes; - this.arrayCreator = new OrganelleArrayCreator<>(grid, attributes.getDataType()); - } - - @Override - public A loadArray(final long[] gridPosition, int[] cellDimensions) { - DataBlock block = null; - - try { - block = n5.readBlock(pathName, attributes, gridPosition); - } catch (Exception e) { - System.err.println("Error loading " + pathName + " at block " + Arrays.toString(gridPosition) + ": " + e); - } - - if (block == null) { - return (A) arrayCreator.createEmptyArray(gridPosition); - } else { - return arrayCreator.createArray(block, gridPosition); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleN5ImageLoader.java b/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleN5ImageLoader.java deleted file mode 100644 index 827f2f8f..00000000 --- a/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleN5ImageLoader.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.openorganelle; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; - -import org.janelia.saalfeldlab.n5.DatasetAttributes; -import org.janelia.saalfeldlab.n5.N5Reader; -import org.jetbrains.annotations.NotNull; - -import bdv.AbstractViewerSetupImgLoader; -import bdv.ViewerImgLoader; -import bdv.cache.CacheControl; -import bdv.img.cache.SimpleCacheArrayLoader; -import bdv.img.cache.VolatileGlobalCellCache; -import bdv.util.ConstantRandomAccessible; -import bdv.util.MipmapTransforms; - -import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; -import mpicbg.spim.data.generic.sequence.BasicViewSetup; -import mpicbg.spim.data.generic.sequence.ImgLoaderHint; -import mpicbg.spim.data.registration.ViewRegistration; -import mpicbg.spim.data.registration.ViewRegistrations; -import mpicbg.spim.data.sequence.Angle; -import mpicbg.spim.data.sequence.Channel; -import mpicbg.spim.data.sequence.DefaultVoxelDimensions; -import mpicbg.spim.data.sequence.FinalVoxelDimensions; -import mpicbg.spim.data.sequence.Illumination; -import mpicbg.spim.data.sequence.MultiResolutionImgLoader; -import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; -import mpicbg.spim.data.sequence.SequenceDescription; -import mpicbg.spim.data.sequence.Tile; -import mpicbg.spim.data.sequence.TimePoint; -import mpicbg.spim.data.sequence.TimePoints; -import mpicbg.spim.data.sequence.ViewSetup; -import mpicbg.spim.data.sequence.VoxelDimensions; -import net.imglib2.Dimensions; -import net.imglib2.FinalDimensions; -import net.imglib2.FinalInterval; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.Volatile; -import net.imglib2.cache.queue.BlockingFetchQueues; -import net.imglib2.cache.queue.FetcherThreads; -import net.imglib2.cache.volatiles.CacheHints; -import net.imglib2.cache.volatiles.LoadingStrategy; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.img.cell.CellImg; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.integer.ByteType; -import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.LongType; -import net.imglib2.type.numeric.integer.ShortType; -import net.imglib2.type.numeric.integer.UnsignedByteType; -import net.imglib2.type.numeric.integer.UnsignedIntType; -import net.imglib2.type.numeric.integer.UnsignedLongType; -import net.imglib2.type.numeric.integer.UnsignedShortType; -import net.imglib2.type.numeric.real.DoubleType; -import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.type.volatiles.VolatileByteType; -import net.imglib2.type.volatiles.VolatileDoubleType; -import net.imglib2.type.volatiles.VolatileFloatType; -import net.imglib2.type.volatiles.VolatileIntType; -import net.imglib2.type.volatiles.VolatileLongType; -import net.imglib2.type.volatiles.VolatileShortType; -import net.imglib2.type.volatiles.VolatileUnsignedByteType; -import net.imglib2.type.volatiles.VolatileUnsignedIntType; -import net.imglib2.type.volatiles.VolatileUnsignedLongType; -import net.imglib2.type.volatiles.VolatileUnsignedShortType; -import net.imglib2.util.Cast; -import net.imglib2.view.Views; - - -public class OpenOrganelleN5ImageLoader implements ViewerImgLoader, MultiResolutionImgLoader { - public static boolean logging = false; - protected final N5Reader n5; - /** - * Maps setup id to {@link SetupImgLoader}. - */ - private final Map> setupImgLoaders = new HashMap<>(); - private final Map setupToPathname = new HashMap<>(); - private final Map setupToMultiscale = new HashMap<>(); - private final Map setupToAttributes = new HashMap<>(); - private final Map setupToChannel = new HashMap<>(); - private final Map setupToScales = new HashMap<>(); - protected AbstractSequenceDescription seq; - protected ViewRegistrations viewRegistrations; - private volatile boolean isOpen = false; - private FetcherThreads fetchers; - private VolatileGlobalCellCache cache; - private int sequenceTimepoints = 0; - - /** - * The sequenceDescription and viewRegistrations are to be read from the n5 attributes. - * - * @param n5Reader - */ - public OpenOrganelleN5ImageLoader(N5Reader n5Reader) { - this.n5 = n5Reader; - fetchSequenceDescriptionAndViewRegistrations(); - } - - private static SimpleCacheArrayLoader createCacheArrayLoader(final N5Reader n5, final String pathName, CellGrid grid) throws IOException { - final DatasetAttributes attributes = n5.getDatasetAttributes(pathName); - return new N5CacheArrayLoader<>(n5, pathName, attributes, grid); - } - - private void fetchSequenceDescriptionAndViewRegistrations() { - try { - initSetups(); - - ArrayList viewSetups = new ArrayList<>(); - ArrayList viewRegistrationList = new ArrayList<>(); - - int numSetups = setupToMultiscale.size(); - for (int setupId = 0; setupId < numSetups; setupId++) { - ViewSetup viewSetup = createViewSetup(setupId); - int setupTimepoints = 1; - sequenceTimepoints = Math.max(setupTimepoints, sequenceTimepoints); - viewSetups.add(viewSetup); - viewRegistrationList.addAll(createViewRegistrations(setupId, setupTimepoints)); - } - - viewRegistrations = new ViewRegistrations(viewRegistrationList); - - seq = new SequenceDescription(new TimePoints(createTimePoints(sequenceTimepoints)), viewSetups); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - @NotNull - private ArrayList createTimePoints(int sequenceTimepoints) { - ArrayList timePoints = new ArrayList<>(); - for (int t = 0; t < sequenceTimepoints; t++) { - timePoints.add(new TimePoint(t)); - } - return timePoints; - } - - private void initSetups() throws IOException { - int setupId = -1; - double[][] scales = n5.getAttribute("", "scales", double[][].class); - Multiscale multiscale = getMultiscale(""); // returns multiscales[ 0 ] - DatasetAttributes attributes = getDatasetAttributes(multiscale.datasets[0].path); - long nC = 1; - - for (int c = 0; c < nC; c++) { - // each channel is one setup - setupId++; - setupToChannel.put(setupId, c); - - // all channels have the same multiscale and attributes - setupToMultiscale.put(setupId, multiscale); - setupToAttributes.put(setupId, attributes); - setupToPathname.put(setupId, ""); - setupToScales.put(setupId, scales); - } - - List labels = n5.getAttribute("labels", "labels", List.class); - if (labels != null) { - for (String label : labels) { - setupId++; - setupToChannel.put(setupId, 0); // TODO: https://github.com/ome/ngff/issues/19 - String pathName = "labels/" + label; - multiscale = getMultiscale(pathName); - attributes = getDatasetAttributes(pathName + "/" + multiscale.datasets[0].path); - - setupToMultiscale.put(setupId, multiscale); - setupToAttributes.put(setupId, attributes); - setupToPathname.put(setupId, pathName); - } - } - } - - /** - * The dataType, number of channels and number of timepoints are stored - * in the different pyramid levels (datasets). - * According to the spec all datasets must be indentical in that sense - * and we thus fetch this information from level 0. - *

- * In addition, level 0 contains the information about the size of the full resolution image. - * - * @param pathName - * @return - * @throws IOException - */ - private DatasetAttributes getDatasetAttributes(String pathName) throws IOException { - return n5.getDatasetAttributes(pathName); - } - - /** - * The primary use case for multiple multiscales at the moment (the one listed in the spec) - * is multiple different downsamplings. - * A base image with two multiscales each with a different scale or a different method. - *

- * I don't know a good logic right now how to deal with different pyramids, - * thus I just fetch the first one, i.e. multiscales[ 0 ]. - *

- * ??? There's no need for the two multiscales to have the same base though. - * ??? So it would also allow you to just have two pyramids (in our jargon) in the same zgroup. - * - * @param pathName - * @return - * @throws IOException - */ - private Multiscale getMultiscale(String pathName) throws IOException { - final String key = "multiscales"; - Multiscale[] multiscales = n5.getAttribute(pathName, key, Multiscale[].class); - if (multiscales == null) { - String location = ""; - location += "; path: " + pathName; - location += "; attribute: " + key; - throw new UnsupportedOperationException("Could not find multiscales at " + location); - } else { - for (Multiscale multiscale : multiscales) { - multiscale.name = n5.getAttribute("", "name", String.class); - } - } - return multiscales[0]; - } - - public AbstractSequenceDescription getSequenceDescription() { - //open(); - seq.setImgLoader(Cast.unchecked(this)); - return seq; - } - - public ViewRegistrations getViewRegistrations() { - return viewRegistrations; - } - - private void open() { - if (!isOpen) { - synchronized (this) { - if (isOpen) - return; - - try { - int maxNumLevels = 0; - final List setups = seq.getViewSetupsOrdered(); - for (final BasicViewSetup setup : setups) { - final int setupId = setup.getId(); - final SetupImgLoader setupImgLoader = createSetupImgLoader(setupId); - setupImgLoaders.put(setupId, setupImgLoader); - if (setupImgLoader != null) { - maxNumLevels = Math.max(maxNumLevels, setupImgLoader.numMipmapLevels()); - } - } - - final int numFetcherThreads = Math.max(1, Runtime.getRuntime().availableProcessors()); - final BlockingFetchQueues> queue = new BlockingFetchQueues<>(maxNumLevels, numFetcherThreads); - fetchers = new FetcherThreads(queue, numFetcherThreads); - cache = new VolatileGlobalCellCache(queue); - } catch (IOException e) { - throw new RuntimeException(e); - } - - isOpen = true; - } - } - } - - @NotNull - private ArrayList createViewRegistrations(int setupId, int setupTimepoints) { - Multiscale multiscale = setupToMultiscale.get(setupId); - AffineTransform3D transform = new AffineTransform3D(); - - double[] scale = multiscale.datasets[0].transform.scale; - transform.scale(scale[0] / 1000, scale[1] / 1000, scale[2] / 1000); - - ArrayList viewRegistrations = new ArrayList<>(); - for (int t = 0; t < setupTimepoints; t++) - viewRegistrations.add(new ViewRegistration(t, setupId, transform)); - - return viewRegistrations; - } - - private ViewSetup createViewSetup(int setupId) { - final DatasetAttributes attributes = setupToAttributes.get(setupId); - FinalDimensions dimensions = new FinalDimensions(attributes.getDimensions()); - Multiscale multiscale = setupToMultiscale.get(setupId); - VoxelDimensions voxelDimensions = readVoxelDimensions(multiscale); - Tile tile = new Tile(0); - - Channel channel; - if (setupToPathname.get(setupId).contains("labels")) - channel = new Channel(setupToChannel.get(setupId), "labels"); - else - channel = new Channel(setupToChannel.get(setupId)); - - Angle angle = new Angle(0); - Illumination illumination = new Illumination(0); - String name = readName(multiscale, setupId); - //if ( setupToPathname.get( setupId ).contains( "labels" )) - // viewSetup.setAttribute( new ImageType( ImageType.Type.IntensityImage ) ); - return new ViewSetup(setupId, name, dimensions, voxelDimensions, tile, channel, angle, illumination); - } - - private String readName(Multiscale multiscale, int setupId) { - if (multiscale.name != null) - return multiscale.name; - else - return "image " + setupId; - } - - @NotNull - private VoxelDimensions readVoxelDimensions(Multiscale multiscale) { - try { - double[] voxeldim = {multiscale.datasets[0].transform.scale[0] / 1000, multiscale.datasets[0].transform.scale[1] / 1000, multiscale.datasets[0].transform.scale[2] / 1000}; - return new FinalVoxelDimensions(multiscale.datasets[0].transform.units[0], voxeldim); - } catch (Exception e) { - return new DefaultVoxelDimensions(3); - } - } - - /** - * Clear the cache. Images that were obtained from - * this loader before {@link #close()} will stop working. Requesting images - * after {@link #close()} will cause the n5 to be reopened (with a - * new cache). - */ - public void close() { - if (isOpen) { - synchronized (this) { - if (!isOpen) - return; - fetchers.shutdown(); - cache.clearCache(); - isOpen = false; - } - } - } - - @Override - public SetupImgLoader getSetupImgLoader(final int setupId) { - open(); - return setupImgLoaders.get(setupId); - } - - private , V extends Volatile & NativeType> SetupImgLoader createSetupImgLoader(final int setupId) throws IOException { - switch (setupToAttributes.get(setupId).getDataType()) { - case UINT8: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedByteType(), new VolatileUnsignedByteType())); - case UINT16: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedShortType(), new VolatileUnsignedShortType())); - case UINT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedIntType(), new VolatileUnsignedIntType())); - case UINT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new UnsignedLongType(), new VolatileUnsignedLongType())); - case INT8: - return Cast.unchecked(new SetupImgLoader<>(setupId, new ByteType(), new VolatileByteType())); - case INT16: - return Cast.unchecked(new SetupImgLoader<>(setupId, new ShortType(), new VolatileShortType())); - case INT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new IntType(), new VolatileIntType())); - case INT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new LongType(), new VolatileLongType())); - case FLOAT32: - return Cast.unchecked(new SetupImgLoader<>(setupId, new FloatType(), new VolatileFloatType())); - case FLOAT64: - return Cast.unchecked(new SetupImgLoader<>(setupId, new DoubleType(), new VolatileDoubleType())); - } - return null; - } - - @Override - public CacheControl getCacheControl() { - open(); - return cache; - } - - private static class Multiscale { - String name; - double[][] scales; - Dataset[] datasets; - } - - private static class Dataset { - String path; - Transform transform; - } - - private static class Transform { - String[] axes; - double[] scale; - double[] translate; - String[] units; - } - - private class SetupImgLoader, V extends Volatile & NativeType> - extends AbstractViewerSetupImgLoader - implements MultiResolutionSetupImgLoader { - private final int setupId; - - private final double[][] mipmapResolutions; - - private final AffineTransform3D[] mipmapTransforms; - - public SetupImgLoader(final int setupId, final T type, final V volatileType) { - super(type, volatileType); - this.setupId = setupId; - mipmapResolutions = readMipmapResolutions(); - mipmapTransforms = new AffineTransform3D[mipmapResolutions.length]; - for (int level = 0; level < mipmapResolutions.length; level++) - mipmapTransforms[level] = MipmapTransforms.getMipmapTransformDefault(mipmapResolutions[level]); - } - - /** - * @return - */ - private double[][] readMipmapResolutions() { - return setupToScales.get(setupId); - } - - @Override - public RandomAccessibleInterval getVolatileImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BUDGETED, volatileType); - } - - @Override - public RandomAccessibleInterval getImage(final int timepointId, final int level, final ImgLoaderHint... hints) { - return prepareCachedImage(timepointId, level, LoadingStrategy.BLOCKING, type); - } - - @Override - public Dimensions getImageSize(final int timepointId, final int level) { - final String pathName = getPathName(setupId, level); - try { - final DatasetAttributes attributes = getDatasetAttributes(pathName); - return new FinalDimensions(attributes.getDimensions()); - } catch (Exception e) { - throw new RuntimeException("Could not read from " + pathName); - } - } - - @NotNull - public String getPathName(int setupId, int level) { - return setupToPathname.get(setupId) + "/" + setupToMultiscale.get(this.setupId).datasets[level].path; - } - - @Override - public double[][] getMipmapResolutions() { - return mipmapResolutions; - } - - @Override - public AffineTransform3D[] getMipmapTransforms() { - return mipmapTransforms; - } - - @Override - public int numMipmapLevels() { - return mipmapResolutions.length; - } - - @Override - public VoxelDimensions getVoxelSize(final int timepointId) { - return null; - } - - /** - * Create a {@link CellImg} backed by the cache. - */ - private > RandomAccessibleInterval prepareCachedImage(final int timepointId, final int level, final LoadingStrategy loadingStrategy, final N type) { - try { - final String pathName = getPathName(setupId, level); - final DatasetAttributes attributes = getDatasetAttributes(pathName); - - if (logging) { - System.out.println("Preparing image " + pathName + " of data type " + attributes.getDataType()); - } - - // ome.zarr is 5D but BDV expects 3D - final long[] dimensions = Arrays.stream(attributes.getDimensions()).limit(3).toArray(); - final int[] cellDimensions = Arrays.stream(attributes.getBlockSize()).limit(3).toArray(); - final CellGrid grid = new CellGrid(dimensions, cellDimensions); - - final int priority = numMipmapLevels() - 1 - level; - final CacheHints cacheHints = new CacheHints(loadingStrategy, priority, false); - - final SimpleCacheArrayLoader loader = createCacheArrayLoader(n5, pathName, grid); - return cache.createImg(grid, timepointId, setupId, level, cacheHints, loader, type); - } catch (IOException e) { - System.err.println(String.format("image data for timepoint %d setup %d level %d could not be found.%n", - timepointId, setupId, level)); - return Views.interval( - new ConstantRandomAccessible<>(type.createVariable(), 3), - new FinalInterval(1, 1, 1)); - } - } - } - -} diff --git a/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleN5S3ImageLoader.java b/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleN5S3ImageLoader.java deleted file mode 100644 index 51e0681e..00000000 --- a/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleN5S3ImageLoader.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.openorganelle; - -import java.io.IOException; - -import org.embl.mobie.io.n5.loaders.S3ImageLoader; -import org.janelia.saalfeldlab.n5.s3.N5AmazonS3Reader; - -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.AnonymousAWSCredentials; -import com.amazonaws.client.builder.AwsClientBuilder; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.AmazonS3ClientBuilder; - -public class OpenOrganelleN5S3ImageLoader extends OpenOrganelleN5ImageLoader implements S3ImageLoader { - private final String serviceEndpoint; - private final String signingRegion; - private final String bucketName; - private final String key; - - // sequenceDescription will be read from - public OpenOrganelleN5S3ImageLoader(String serviceEndpoint, String signingRegion, String bucketName, String key) throws IOException { - super(new N5S3ReaderCreator().create(serviceEndpoint, signingRegion, bucketName, key)); - this.serviceEndpoint = serviceEndpoint; - this.signingRegion = signingRegion; - this.bucketName = bucketName; - this.key = key; - } - - public String getServiceEndpoint() { - return serviceEndpoint; - } - - public String getSigningRegion() { - return signingRegion; - } - - public String getBucketName() { - return bucketName; - } - - public String getKey() { - return key; - } - - static class N5S3ReaderCreator { - public N5AmazonS3Reader create(String serviceEndpoint, String signingRegion, String bucketName, String key) throws IOException { - final AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration(serviceEndpoint, signingRegion); - - final AmazonS3 s3 = AmazonS3ClientBuilder - .standard() - .withPathStyleAccessEnabled(true) - .withEndpointConfiguration(endpoint) - .withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials())) - .build(); - - return new N5AmazonS3Reader(s3, bucketName, key); - } - } -} diff --git a/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleS3Opener.java b/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleS3Opener.java deleted file mode 100644 index c428268b..00000000 --- a/src/main/java/org/embl/mobie/io/openorganelle/OpenOrganelleS3Opener.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.openorganelle; - -import java.io.IOException; - -import org.embl.mobie.io.n5.openers.S3Opener; - -import mpicbg.spim.data.SpimData; -import net.imglib2.util.Cast; - -public class OpenOrganelleS3Opener extends S3Opener { - - public OpenOrganelleS3Opener(String serviceEndpoint, String signingRegion, String bucketName) { - super(serviceEndpoint, signingRegion, bucketName); - } - - public OpenOrganelleS3Opener(String url) { - super(url); - } - - public static SpimData readURL(String url) throws IOException { - final OpenOrganelleS3Opener reader = new OpenOrganelleS3Opener(url); - return reader.readKey(reader.getKey()); - } - - @Override - public SpimData readKey(String key) throws IOException { - OpenOrganelleN5S3ImageLoader imageLoader = new OpenOrganelleN5S3ImageLoader(serviceEndpoint, signingRegion, bucketName, key); - return new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); - } -} diff --git a/src/main/java/org/embl/mobie/io/openorganelle/OrganelleArrayCreator.java b/src/main/java/org/embl/mobie/io/openorganelle/OrganelleArrayCreator.java deleted file mode 100644 index 929f823e..00000000 --- a/src/main/java/org/embl/mobie/io/openorganelle/OrganelleArrayCreator.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package org.embl.mobie.io.openorganelle; - -import java.util.Arrays; - -import org.embl.mobie.io.n5.util.ArrayCreator; -import org.janelia.saalfeldlab.n5.DataBlock; -import org.janelia.saalfeldlab.n5.DataType; - -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.NativeType; - -public class OrganelleArrayCreator> extends ArrayCreator { - public OrganelleArrayCreator(CellGrid cellGrid, DataType dataType) { - super(cellGrid, dataType); - } - - public A createArray(DataBlock dataBlock, long[] gridPosition) { - long[] cellDims = getCellDims(gridPosition); - int n = (int) (cellDims[0] * cellDims[1] * cellDims[2]); - return (A) VolatileDoubleArray(dataBlock, cellDims, n); - } - - @Override - public long[] getCellDims(long[] gridPosition) { - long[] cellMin = new long[3]; - int[] cellDims = new int[3]; - cellGrid.getCellDimensions(gridPosition, cellMin, cellDims); - return Arrays.stream(cellDims).mapToLong(i -> i).toArray(); // casting to long for creating ArrayImgs.* - } -} diff --git a/src/main/java/org/embl/mobie/io/package-info.java b/src/main/java/org/embl/mobie/io/package-info.java deleted file mode 100644 index d0bc1a0b..00000000 --- a/src/main/java/org/embl/mobie/io/package-info.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -/** - * Copyright (c) 2019, Stephan Saalfeld - * All rights reserved. - *

- * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - *

- * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - *

- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *

- * Zarr backends for N5 - * - * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> - *

- * Zarr backends for N5 - * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> - *

- * Zarr backends for N5 - * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> - *

- * Zarr backends for N5 - * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> - */ -/** - * Zarr backends for N5 - * - * @author Stephan Saalfeld <saalfelds@janelia.hhmi.org> - * - */ -package org.embl.mobie.io; diff --git a/src/main/java/org/embl/mobie/io/toml/TOMLOpener.java b/src/main/java/org/embl/mobie/io/toml/TOMLOpener.java index af93a319..c04877ac 100644 --- a/src/main/java/org/embl/mobie/io/toml/TOMLOpener.java +++ b/src/main/java/org/embl/mobie/io/toml/TOMLOpener.java @@ -28,15 +28,11 @@ */ package org.embl.mobie.io.toml; -import bdv.cache.SharedQueue; -import ch.epfl.biop.bdv.img.imageplus.ImagePlusToSpimData; import com.moandjiezana.toml.Toml; import ij.IJ; import ij.ImagePlus; import ij.VirtualStack; import ij.measure.Calibration; -import mpicbg.spim.data.generic.AbstractSpimData; -import org.embl.mobie.io.SpimDataOpener; import org.embl.mobie.io.util.IOHelper; import java.io.File; @@ -56,7 +52,7 @@ public TOMLOpener( String tomlImagePath ) this.tomlImagePath = tomlImagePath; } - public ImagePlus asImagePlus() + public ImagePlus openImagePlus() { final File tomlFile = new File( tomlImagePath ); final Toml toml = new Toml().read( tomlFile ); @@ -123,18 +119,4 @@ public ImagePlus asImagePlus() return imagePlus; } - - public AbstractSpimData< ? > asSpimData( SharedQueue sharedQueue ) - { - final AbstractSpimData< ? > spimData = asSpimData(); - SpimDataOpener.setSharedQueue( sharedQueue, spimData ); - return spimData; - } - - public AbstractSpimData< ? > asSpimData() - { - final ImagePlus imagePlus = asImagePlus(); - final AbstractSpimData< ? > spimData = ImagePlusToSpimData.getSpimData( imagePlus ); - return spimData; - } } diff --git a/src/main/java/org/embl/mobie/io/util/IOHelper.java b/src/main/java/org/embl/mobie/io/util/IOHelper.java index 53b0f8bd..ef0fd9a5 100644 --- a/src/main/java/org/embl/mobie/io/util/IOHelper.java +++ b/src/main/java/org/embl/mobie/io/util/IOHelper.java @@ -50,7 +50,6 @@ import ij.io.Opener; import loci.common.ByteArrayHandle; import loci.common.Location; -import loci.common.ReflectException; import loci.plugins.in.ImagePlusReader; import loci.plugins.in.ImportProcess; import loci.plugins.in.ImporterOptions; @@ -139,7 +138,7 @@ public static ImagePlus openWithBioFormats( String path, int seriesIndex ) switch ( type ) { case S3: - return openWithBioformatsFromS3( path, seriesIndex ); + return openWithBioFormatsFromS3( path, seriesIndex ); case FILE: return openWithBioFormatsFromFile( path, seriesIndex ); default: @@ -205,9 +204,9 @@ public static InputStream getInputStream(String uri) throws IOException { URL url = new URL(uri); return url.openStream(); case FILE: - return new FileInputStream(new File(uri)); + return Files.newInputStream( new File( uri ).toPath() ); case S3: - AmazonS3 s3 = S3Utils.getS3Client(uri); + AmazonS3 s3 = S3Utils.getS3Client( uri ); String[] bucketAndObject = S3Utils.getBucketAndObject(uri); return s3.getObject(bucketAndObject[0], bucketAndObject[1]).getObjectContent(); default: @@ -509,7 +508,7 @@ public static List< String > getPaths( String dir, String regex, int maxDepth ) } } - public static ImagePlus openWithBioformatsFromS3( String path, int seriesIndex ) + public static ImagePlus openWithBioFormatsFromS3( String path, int seriesIndex ) { try { diff --git a/src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java b/src/main/java/org/embl/mobie/io/util/InputStreamXmlIoSpimData.java similarity index 89% rename from src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java rename to src/main/java/org/embl/mobie/io/util/InputStreamXmlIoSpimData.java index 63333c56..11083e84 100644 --- a/src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java +++ b/src/main/java/org/embl/mobie/io/util/InputStreamXmlIoSpimData.java @@ -45,12 +45,12 @@ import static mpicbg.spim.data.XmlKeys.SPIMDATA_TAG; -public class CustomXmlIoSpimData extends XmlIoAbstractSpimData { - public CustomXmlIoSpimData() { +public class InputStreamXmlIoSpimData extends XmlIoAbstractSpimData { + public InputStreamXmlIoSpimData() { super(SpimData.class, new XmlIoSequenceDescription(), new XmlIoViewRegistrations()); } - public SpimData loadFromStream(InputStream in, String xmlFilename) throws SpimDataException { + public SpimData open( InputStream in, String xmlPath) throws SpimDataException { SAXBuilder sax = new SAXBuilder(); Document doc; @@ -63,6 +63,6 @@ public SpimData loadFromStream(InputStream in, String xmlFilename) throws SpimDa if (!root.getName().equals(SPIMDATA_TAG)) throw new RuntimeException("expected <" + SPIMDATA_TAG + "> root element. wrong file?"); - return fromXml(root, new File(xmlFilename)); + return fromXml(root, new File(xmlPath)); } } diff --git a/src/main/java/org/embl/mobie/io/util/RandomAccessibleIntervalSource4D.java b/src/main/java/org/embl/mobie/io/util/RandomAccessibleIntervalSource4D.java new file mode 100644 index 00000000..b8b6c5ef --- /dev/null +++ b/src/main/java/org/embl/mobie/io/util/RandomAccessibleIntervalSource4D.java @@ -0,0 +1,86 @@ +package org.embl.mobie.io.util; + +import java.util.Arrays; + +import bdv.util.AbstractSource; +import bdv.viewer.Interpolation; +import mpicbg.spim.data.sequence.FinalVoxelDimensions; +import mpicbg.spim.data.sequence.VoxelDimensions; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.RealRandomAccessible; +import net.imglib2.realtransform.AffineTransform3D; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.view.Views; + +public class RandomAccessibleIntervalSource4D< T extends NumericType< T > > extends AbstractSource< T > +{ + private final RandomAccessibleInterval< T > source; + + protected int currentTimePointIndex; + + private RandomAccessibleInterval< T > currentSource; + + private final RealRandomAccessible< T >[] currentInterpolatedSources; + + private final AffineTransform3D sourceTransform; + + public RandomAccessibleIntervalSource4D( + final RandomAccessibleInterval< T > img, + final T type, + final AffineTransform3D sourceTransform, + final VoxelDimensions voxelDimensions, + final String name ) + { + super( type, name, voxelDimensions ); + this.source = img; + this.sourceTransform = sourceTransform; + currentInterpolatedSources = new RealRandomAccessible[ Interpolation.values().length ]; + loadTimepoint( 0 ); + } + + private void loadTimepoint( final int timepointIndex ) + { + currentTimePointIndex = timepointIndex; + if ( isPresent( timepointIndex ) ) + { + final T zero = getType().createVariable(); + zero.setZero(); + currentSource = Views.hyperSlice( source, 3, timepointIndex ); + for ( final Interpolation method : Interpolation.values() ) + currentInterpolatedSources[ method.ordinal() ] = Views.interpolate( Views.extendValue( currentSource, zero ), interpolators.get( method ) ); + } + else + { + currentSource = null; + Arrays.fill( currentInterpolatedSources, null ); + } + } + + @Override + public boolean isPresent( final int t ) + { + return source.min( 3 ) <= t && t <= source.max( 3 ); + } + + @Override + public RandomAccessibleInterval< T > getSource( final int t, final int level ) + { + if ( t != currentTimePointIndex ) + loadTimepoint( t ); + return currentSource; + } + + @Override + public RealRandomAccessible< T > getInterpolatedSource( final int t, final int level, final Interpolation method ) + { + if ( t != currentTimePointIndex ) + loadTimepoint( t ); + return currentInterpolatedSources[ method.ordinal() ]; + } + + @Override + public synchronized void getSourceTransform( final int t, final int level, final AffineTransform3D transform ) + { + transform.set( sourceTransform ); + } +} diff --git a/src/main/java/org/embl/mobie/io/util/S3Utils.java b/src/main/java/org/embl/mobie/io/util/S3Utils.java index 4bb7430c..27b68b30 100644 --- a/src/main/java/org/embl/mobie/io/util/S3Utils.java +++ b/src/main/java/org/embl/mobie/io/util/S3Utils.java @@ -35,29 +35,31 @@ import java.util.Arrays; import java.util.stream.Collectors; -import com.amazonaws.AmazonServiceException; -import com.amazonaws.auth.AWSCredentialsProvider; -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.AnonymousAWSCredentials; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; +import com.amazonaws.auth.*; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.iterable.S3Objects; import com.amazonaws.services.s3.model.*; -import com.google.api.client.http.HttpStatusCodes; import ij.gui.GenericDialog; +import org.jetbrains.annotations.NotNull; -public abstract class S3Utils { +public abstract class S3Utils +{ private static String[] s3AccessAndSecretKey; private static boolean useCredentialsChain; - public static void setS3AccessAndSecretKey(String[] s3AccessAndSecretKey) { + // FIXME: We should remove this! + public static void setS3AccessAndSecretKey( String[] s3AccessAndSecretKey ) { S3Utils.s3AccessAndSecretKey = s3AccessAndSecretKey; } + // FIXME: We should remove this! + public static String[] getS3AccessAndSecretKey() + { + return s3AccessAndSecretKey; + } // look for credentials at common places // on the client computer @@ -65,50 +67,53 @@ public static void useS3Credenditals( boolean b ) { useCredentialsChain = b; } - // TODO: the bucket could be removed here - public static AmazonS3 getS3Client(String endpoint, String region, String bucket) + public static AmazonS3 getS3Client( String endpoint, String region ) { final AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, region); - // Configure the credentials - AWSCredentialsProvider credentialsProvider; - if (s3AccessAndSecretKey != null) + AWSCredentialsProvider credentialsProvider = getAwsCredentialsProvider(); + + // Create the access + AmazonS3 s3 = AmazonS3ClientBuilder + .standard() + .withPathStyleAccessEnabled( true ) + .withEndpointConfiguration( endpointConfiguration ) + .withCredentials( credentialsProvider ) + .build(); + + return s3; + } + + // FIXME: We should change this to take the s3AccessAndSecretKey as an argument! + @NotNull + public static AWSCredentialsProvider getAwsCredentialsProvider() + { + if ( s3AccessAndSecretKey != null) { // Use given credentials final BasicAWSCredentials credentials = new BasicAWSCredentials(s3AccessAndSecretKey[0], s3AccessAndSecretKey[1]); - credentialsProvider = new AWSStaticCredentialsProvider(credentials); + return new AWSStaticCredentialsProvider(credentials); } - else if (useCredentialsChain) + else if ( useCredentialsChain ) { // Look for credentials - credentialsProvider = new DefaultAWSCredentialsProviderChain(); - checkCredentialsExistence(credentialsProvider); + DefaultAWSCredentialsProviderChain credentialsProviderChain = new DefaultAWSCredentialsProviderChain(); + checkCredentialsExistence( credentialsProviderChain ); + return credentialsProviderChain; } else { // Anonymous - credentialsProvider = new AWSStaticCredentialsProvider( new AnonymousAWSCredentials() ); + return new AWSStaticCredentialsProvider( new AnonymousAWSCredentials() ); } - - // Create the access - AmazonS3 s3 = AmazonS3ClientBuilder - .standard() - .withPathStyleAccessEnabled( true ) - .withEndpointConfiguration( endpointConfiguration ) - .withCredentials( credentialsProvider ) - .build(); - - return s3; } - public static AmazonS3 getS3Client(String uri) { - final String endpoint = getEndpoint(uri); - final String region = null; // "us-west-2"; - final String[] bucketAndObject = getBucketAndObject(uri); - return getS3Client(endpoint, region, bucketAndObject[0]); + public static AmazonS3 getS3Client( String uri ) { + final String endpoint = getEndpoint( uri ); + return getS3Client( endpoint, null ); } - public static void checkCredentialsExistence(AWSCredentialsProvider credentialsProvider) { + public static void checkCredentialsExistence( AWSCredentialsProvider credentialsProvider ) { try { credentialsProvider.getCredentials(); } catch (Exception e) { @@ -116,20 +121,20 @@ public static void checkCredentialsExistence(AWSCredentialsProvider credentialsP } } - public static String[] getBucketAndObject(String uri) { + public static String[] getBucketAndObject( String uri ) { final String[] split = uri.split("/"); String bucket = split[3]; String object = Arrays.stream(split).skip(4).collect(Collectors.joining("/")); return new String[]{bucket, object}; } - public static String getEndpoint(String uri) { + public static String getEndpoint( String uri ) { final String[] split = uri.split("/"); String endpoint = Arrays.stream(split).limit(3).collect(Collectors.joining("/")); return endpoint; } - public static String selectS3PathFromDirectory(String directory, String objectName) throws IOException { + public static String selectS3PathFromDirectory( String directory, String objectName ) throws IOException { final String[] fileNames = getS3FileNames(directory); final GenericDialog gd = new GenericDialog("Select " + objectName); @@ -142,13 +147,13 @@ public static String selectS3PathFromDirectory(String directory, String objectNa return newFilePath; } - public static String[] getS3FileNames(String directory) { + public static String[] getS3FileNames( String directory ) { final ArrayList filePaths = getS3FilePaths(directory); return filePaths.stream().map(File::new).map(File::getName).toArray(String[]::new); } - public static ArrayList getS3FilePaths(String directory) { - final AmazonS3 s3 = getS3Client(directory); + public static ArrayList getS3FilePaths( String directory ) { + final AmazonS3 s3 = getS3Client( directory ); final String[] bucketAndObject = getBucketAndObject(directory); final String bucket = bucketAndObject[0]; @@ -162,7 +167,13 @@ public static ArrayList getS3FilePaths(String directory) { return paths; } - public static boolean isS3(String directory) { + public static boolean isS3( String directory ) { return directory.contains("s3.amazon.aws.com") || directory.startsWith("https://s3"); } + + public static String getURI( String serviceEndpoint, String bucketName, String key ) + { + String uri = IOHelper.combinePath( serviceEndpoint, bucketName, key ); + return uri; + } } diff --git a/src/main/java/org/embl/mobie/io/xml/N5S3ImageLoader.java b/src/main/java/org/embl/mobie/io/xml/N5S3ImageLoader.java new file mode 100644 index 00000000..e35618f9 --- /dev/null +++ b/src/main/java/org/embl/mobie/io/xml/N5S3ImageLoader.java @@ -0,0 +1,485 @@ +/* + * #%L + * Readers and writers for image data in MoBIE projects + * %% + * Copyright (C) 2021 - 2023 EMBL + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package org.embl.mobie.io.xml; + +import bdv.AbstractViewerSetupImgLoader; +import bdv.ViewerImgLoader; +import bdv.cache.CacheControl; +import bdv.cache.SharedQueue; +import bdv.img.cache.SimpleCacheArrayLoader; +import bdv.img.cache.VolatileGlobalCellCache; +import bdv.img.n5.DataTypeProperties; +import bdv.util.ConstantRandomAccessible; +import bdv.util.MipmapTransforms; +import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; +import mpicbg.spim.data.generic.sequence.BasicViewSetup; +import mpicbg.spim.data.generic.sequence.ImgLoaderHint; +import mpicbg.spim.data.sequence.MultiResolutionImgLoader; +import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; +import mpicbg.spim.data.sequence.VoxelDimensions; +import net.imglib2.*; +import net.imglib2.cache.volatiles.CacheHints; +import net.imglib2.cache.volatiles.LoadingStrategy; +import net.imglib2.img.basictypeaccess.DataAccess; +import net.imglib2.img.cell.CellGrid; +import net.imglib2.img.cell.CellImg; +import net.imglib2.realtransform.AffineTransform3D; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Cast; +import net.imglib2.util.Intervals; +import net.imglib2.view.Views; +import org.embl.mobie.io.util.S3Utils; +import org.janelia.saalfeldlab.n5.*; +import org.janelia.saalfeldlab.n5.universe.N5Factory; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.IntFunction; + +import static bdv.img.n5.BdvN5Format.*; + + +public class N5S3ImageLoader< T extends NumericType< T > & NativeType< T > > implements ViewerImgLoader, MultiResolutionImgLoader +{ + + private final Map< Integer, SetupImgLoader > setupImgLoaders = new HashMap<>(); + private final String serviceEndpoint; + private final String signingRegion; + private final String bucketName; + private final String key; + private AbstractSequenceDescription< ?, ?, ? > seq; + private volatile boolean isOpen = false; + private VolatileGlobalCellCache cache; + + + private SharedQueue createdSharedQueue; + private N5Reader n5; + private int requestedNumFetcherThreads = -1; + private SharedQueue requestedSharedQueue; + + + public N5S3ImageLoader( String serviceEndpoint, String signingRegion, String bucketName, String key, AbstractSequenceDescription< ?, ?, ? > seq ) + { + this.serviceEndpoint = serviceEndpoint; + this.signingRegion = signingRegion; + this.bucketName = bucketName; + this.key = key; + this.seq = seq; + } + + public String getServiceEndpoint() + { + return serviceEndpoint; + } + + public String getSigningRegion() + { + return signingRegion; + } + + public String getBucketName() + { + return bucketName; + } + + public String getKey() + { + return key; + } + + @Override + public synchronized void setNumFetcherThreads( final int n ) + { + requestedNumFetcherThreads = n; + } + + @Override + public void setCreatedSharedQueue( final SharedQueue createdSharedQueue ) + { + requestedSharedQueue = createdSharedQueue; + } + + private void open() + { + if ( !isOpen ) + { + synchronized ( this ) + { + if ( isOpen ) + return; + + try + { + String uri = S3Utils.getURI( serviceEndpoint, bucketName, key ); + N5Factory n5Factory = new N5Factory(); + // FIXME: here the credentials S3Utils.getCredentials... are currently not used.. + n5 = n5Factory.openReader( uri ); + + int maxNumLevels = 0; + final List< ? extends BasicViewSetup > setups = seq.getViewSetupsOrdered(); + for ( final BasicViewSetup setup : setups ) + { + final int setupId = setup.getId(); + final N5S3ImageLoader.SetupImgLoader setupImgLoader = createSetupImgLoader( setupId ); + setupImgLoaders.put( setupId, setupImgLoader ); + maxNumLevels = Math.max( maxNumLevels, setupImgLoader.numMipmapLevels() ); + } + + final int numFetcherThreads = requestedNumFetcherThreads >= 0 + ? requestedNumFetcherThreads + : Math.max( 1, Runtime.getRuntime().availableProcessors() ); + final SharedQueue queue = requestedSharedQueue != null + ? requestedSharedQueue + : ( createdSharedQueue = new SharedQueue( numFetcherThreads, maxNumLevels ) ); + cache = new VolatileGlobalCellCache( queue ); + } + catch ( final IOException e ) + { + throw new RuntimeException( e ); + } + + isOpen = true; + } + } + } + + /** + * Clear the cache. Images that were obtained from + * this loader before {@link #close()} will stop working. Requesting images + * after {@link #close()} will cause the n5 to be reopened (with a + * new cache). + */ + public void close() + { + if ( isOpen ) + { + synchronized ( this ) + { + if ( !isOpen ) + return; + + if ( createdSharedQueue != null ) + createdSharedQueue.shutdown(); + cache.clearCache(); + + createdSharedQueue = null; + isOpen = false; + } + } + } + + @Override + public SetupImgLoader getSetupImgLoader( final int setupId ) + { + open(); + return setupImgLoaders.get( setupId ); + } + + private < T extends NativeType< T >, V extends Volatile< T > & NativeType< V > > SetupImgLoader< T, V > createSetupImgLoader( final int setupId ) throws IOException + { + final String pathName = getPathName( setupId ); + final DataType dataType; + try + { + dataType = n5.getAttribute( pathName, DATA_TYPE_KEY, DataType.class ); + } + catch ( final N5Exception e ) + { + throw new IOException( e ); + } + return new SetupImgLoader<>( setupId, Cast.unchecked( DataTypeProperties.of( dataType ) ) ); + } + + @Override + public CacheControl getCacheControl() + { + open(); + return cache; + } + + public class SetupImgLoader< T extends NativeType< T >, V extends Volatile< T > & NativeType< V > > + extends AbstractViewerSetupImgLoader< T, V > + implements MultiResolutionSetupImgLoader< T > + { + private final int setupId; + + private final double[][] mipmapResolutions; + + private final AffineTransform3D[] mipmapTransforms; + + public SetupImgLoader( final int setupId, final DataTypeProperties< T, V, ?, ? > props ) throws IOException + { + this(setupId, props.type(), props.volatileType() ); + } + + public SetupImgLoader( final int setupId, final T type, final V volatileType ) throws IOException + { + super( type, volatileType ); + this.setupId = setupId; + final String pathName = getPathName( setupId ); + try + { + mipmapResolutions = n5.getAttribute( pathName, DOWNSAMPLING_FACTORS_KEY, double[][].class ); + } + catch ( final N5Exception e ) + { + throw new IOException( e ); + } + mipmapTransforms = new AffineTransform3D[ mipmapResolutions.length ]; + for ( int level = 0; level < mipmapResolutions.length; level++ ) + mipmapTransforms[ level ] = MipmapTransforms.getMipmapTransformDefault( mipmapResolutions[ level ] ); + } + + @Override + public RandomAccessibleInterval< V > getVolatileImage( final int timepointId, final int level, final ImgLoaderHint... hints ) + { + return prepareCachedImage( timepointId, level, LoadingStrategy.BUDGETED, volatileType ); + } + + @Override + public RandomAccessibleInterval< T > getImage( final int timepointId, final int level, final ImgLoaderHint... hints ) + { + return prepareCachedImage( timepointId, level, LoadingStrategy.BLOCKING, type ); + } + + @Override + public Dimensions getImageSize( final int timepointId, final int level ) + { + try + { + final String pathName = getPathName( setupId, timepointId, level ); + final DatasetAttributes attributes = n5.getDatasetAttributes( pathName ); + return new FinalDimensions( attributes.getDimensions() ); + } + catch( final RuntimeException e ) + { + return null; + } + } + + @Override + public double[][] getMipmapResolutions() + { + return mipmapResolutions; + } + + @Override + public AffineTransform3D[] getMipmapTransforms() + { + return mipmapTransforms; + } + + @Override + public int numMipmapLevels() + { + return mipmapResolutions.length; + } + + @Override + public VoxelDimensions getVoxelSize( final int timepointId ) + { + return null; + } + + /** + * Create a {@link CellImg} backed by the cache. + */ + private < T extends NativeType< T > > RandomAccessibleInterval< T > prepareCachedImage( final int timepointId, final int level, final LoadingStrategy loadingStrategy, final T type ) + { + try + { + final String pathName = getPathName( setupId, timepointId, level ); + final DatasetAttributes attributes = n5.getDatasetAttributes( pathName ); + final long[] dimensions = attributes.getDimensions(); + final int[] cellDimensions = attributes.getBlockSize(); + final CellGrid grid = new CellGrid( dimensions, cellDimensions ); + + final int priority = numMipmapLevels() - 1 - level; + final CacheHints cacheHints = new CacheHints( loadingStrategy, priority, false ); + + final SimpleCacheArrayLoader< ? > loader = createCacheArrayLoader( n5, pathName ); + return cache.createImg( grid, timepointId, setupId, level, cacheHints, loader, type ); + } + catch ( final IOException | N5Exception e ) + { + System.err.println( String.format( + "image data for timepoint %d setup %d level %d could not be found.", + timepointId, setupId, level ) ); + return Views.interval( + new ConstantRandomAccessible<>( type.createVariable(), 3 ), + new FinalInterval( 1, 1, 1 ) ); + } + } + } + + private static class N5CacheArrayLoader< T, A extends DataAccess > implements SimpleCacheArrayLoader< A > + { + private final N5Reader n5; + private final String pathName; + private final DatasetAttributes attributes; + private final IntFunction< T > createPrimitiveArray; + private final Function< T, A > createVolatileArrayAccess; + + N5CacheArrayLoader( final N5Reader n5, final String pathName, final DatasetAttributes attributes, + final DataTypeProperties< ?, ?, T, A > dataTypeProperties ) + { + this( n5, pathName, attributes, dataTypeProperties.createPrimitiveArray(), dataTypeProperties.createVolatileArrayAccess() ); + } + + N5CacheArrayLoader( final N5Reader n5, final String pathName, final DatasetAttributes attributes, + final IntFunction< T > createPrimitiveArray, + final Function< T, A > createVolatileArrayAccess ) + { + this.n5 = n5; + this.pathName = pathName; + this.attributes = attributes; + this.createPrimitiveArray = createPrimitiveArray; + this.createVolatileArrayAccess = createVolatileArrayAccess; + } + + @Override + public A loadArray( final long[] gridPosition, final int[] cellDimensions ) throws IOException + { + final DataBlock< T > dataBlock; + try + { + dataBlock = Cast.unchecked( n5.readBlock( pathName, attributes, gridPosition ) ); + } + catch ( final N5Exception e ) + { + throw new IOException( e ); + } + if ( dataBlock != null && Arrays.equals( dataBlock.getSize(), cellDimensions ) ) + { + return createVolatileArrayAccess.apply( dataBlock.getData() ); + } + else + { + final T data = createPrimitiveArray.apply( ( int ) Intervals.numElements( cellDimensions ) ); + if ( dataBlock != null ) + { + final T src = dataBlock.getData(); + final int[] srcDims = dataBlock.getSize(); + final int[] pos = new int[ srcDims.length ]; + final int[] size = new int[ srcDims.length ]; + Arrays.setAll( size, d -> Math.min( srcDims[ d ], cellDimensions[ d ] ) ); + ndArrayCopy( src, srcDims, pos, data, cellDimensions, pos, size ); + } + return createVolatileArrayAccess.apply( data ); + } + } + } + + public static SimpleCacheArrayLoader< ? > createCacheArrayLoader( final N5Reader n5, final String pathName ) throws IOException + { + final DatasetAttributes attributes; + try + { + attributes = n5.getDatasetAttributes( pathName ); + } + catch ( final N5Exception e ) + { + throw new IOException( e ); + } + return new N5CacheArrayLoader<>( n5, pathName, attributes, DataTypeProperties.of( attributes.getDataType() ) ); + } + + /** + * Like `System.arrayCopy()` but for flattened nD arrays. + * + * @param src + * the (flattened) source array. + * @param srcSize + * dimensions of the source array. + * @param srcPos + * starting position in the source array. + * @param dest + * the (flattened destination array. + * @param destSize + * dimensions of the source array. + * @param destPos + * starting position in the destination data. + * @param size + * the number of array elements to be copied. + */ + // TODO: This will be moved to a new imglib2-blk artifact later. Re-use it from there when that happens. + private static < T > void ndArrayCopy( + final T src, final int[] srcSize, final int[] srcPos, + final T dest, final int[] destSize, final int[] destPos, + final int[] size) + { + final int n = srcSize.length; + int srcStride = 1; + int destStride = 1; + int srcOffset = 0; + int destOffset = 0; + for ( int d = 0; d < n; ++d ) + { + srcOffset += srcStride * srcPos[ d ]; + srcStride *= srcSize[ d ]; + destOffset += destStride * destPos[ d ]; + destStride *= destSize[ d ]; + } + ndArrayCopy( n - 1, src, srcSize, srcOffset, dest, destSize, destOffset, size ); + } + + private static void ndArrayCopy( + final int d, + final T src, final int[] srcSize, final int srcPos, + final T dest, final int[] destSize, final int destPos, + final int[] size) + { + if ( d == 0 ) + System.arraycopy( src, srcPos, dest, destPos, size[ d ] ); + else + { + int srcStride = 1; + int destStride = 1; + for ( int dd = 0; dd < d; ++dd ) + { + srcStride *= srcSize[ dd ]; + destStride *= destSize[ dd ]; + } + + final int w = size[ d ]; + for ( int x = 0; x < w; ++x ) + { + ndArrayCopy( d - 1, + src, srcSize, srcPos + x * srcStride, + dest, destSize, destPos + x * destStride, + size ); + } + } + } +} diff --git a/src/main/java/org/embl/mobie/io/n5/loaders/xml/XmlIoN5S3ImageLoader.java b/src/main/java/org/embl/mobie/io/xml/XmlIoN5S3ImageLoader.java similarity index 84% rename from src/main/java/org/embl/mobie/io/n5/loaders/xml/XmlIoN5S3ImageLoader.java rename to src/main/java/org/embl/mobie/io/xml/XmlIoN5S3ImageLoader.java index e271936b..550917c6 100644 --- a/src/main/java/org/embl/mobie/io/n5/loaders/xml/XmlIoN5S3ImageLoader.java +++ b/src/main/java/org/embl/mobie/io/xml/XmlIoN5S3ImageLoader.java @@ -6,13 +6,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -26,18 +26,15 @@ * POSSIBILITY OF SUCH DAMAGE. * #L% */ -package org.embl.mobie.io.n5.loaders.xml; - -import java.io.File; -import java.io.IOException; - -import org.embl.mobie.io.n5.loaders.N5S3ImageLoader; -import org.jdom2.Element; +package org.embl.mobie.io.xml; import mpicbg.spim.data.XmlHelpers; import mpicbg.spim.data.generic.sequence.AbstractSequenceDescription; import mpicbg.spim.data.generic.sequence.ImgLoaderIo; import mpicbg.spim.data.generic.sequence.XmlIoBasicImgLoader; +import org.jdom2.Element; + +import java.io.File; import static mpicbg.spim.data.XmlKeys.IMGLOADER_FORMAT_ATTRIBUTE_NAME; @@ -52,7 +49,7 @@ public class XmlIoN5S3ImageLoader implements XmlIoBasicImgLoader sequenceDescription) { -// final String version = elem.getAttributeValue( "version" ); -// We would need to make below work in case we want to enable relative -// paths on S3 -// final File path = loadPath( elem, N5, basePath ); - final String serviceEndpoint = XmlHelpers.getText(elem, SERVICE_ENDPOINT); final String signingRegion = XmlHelpers.getText(elem, SIGNING_REGION); final String bucketName = XmlHelpers.getText(elem, BUCKET_NAME); final String key = XmlHelpers.getText(elem, KEY); - try { - return new N5S3ImageLoader(serviceEndpoint, signingRegion, bucketName, key, sequenceDescription); - } catch (IOException e) { - throw new RuntimeException(e); - } + return new N5S3ImageLoader(serviceEndpoint, signingRegion, bucketName, key, sequenceDescription); } } diff --git a/src/test/java/dataformats/BaseSpimDataChecker.java b/src/test/java/dataformats/BaseSpimDataChecker.java deleted file mode 100644 index f15068c1..00000000 --- a/src/test/java/dataformats/BaseSpimDataChecker.java +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats; - -import mpicbg.spim.data.sequence.ViewId; -import mpicbg.spim.data.sequence.VoxelDimensions; -import org.janelia.saalfeldlab.n5.imglib2.N5Utils; - - -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.generic.AbstractSpimData; -import mpicbg.spim.data.sequence.ImgLoader; -import net.imglib2.Dimensions; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.util.Cast; - - -public class BaseSpimDataChecker { - protected final SpimData spimData; - - public BaseSpimDataChecker(AbstractSpimData spimData) throws ClassCastException { - this.spimData = (SpimData) spimData; - } - - protected SpimData getSpimData() { - return spimData; - } - - protected int getAllChannelsSize() { - if (spimData == null) { - System.out.println("SpimData is null"); - return 0; - } - return spimData.getSequenceDescription().getAllChannels().size(); - } - - protected int getTimePointsSize() { - if (spimData == null) { - System.out.println("SpimData is null"); - return 0; - } - return spimData.getSequenceDescription().getTimePoints().size(); - } - - protected Dimensions getShape() { - if (spimData == null) { - System.out.println("SpimData is null"); - return null; - } - return spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImageSize(0); - } - - protected String getDType() { - if (spimData == null) { - System.out.println("SpimData is null"); - return null; - } - - ImgLoader imageLoader = spimData.getSequenceDescription().getImgLoader(); - final Object type = imageLoader.getSetupImgLoader(0).getImageType(); - if (type instanceof RealType && - type instanceof NativeType && - N5Utils.dataType(Cast.unchecked(type)) != null) { - return N5Utils.dataType(Cast.unchecked(type)).toString(); - } - return ""; - } - - protected double[] getScale() { - final double[] scale = new double[3]; - spimData.getSequenceDescription().getViewSetupsOrdered().get(0).getVoxelSize().dimensions(scale); - return scale; - } - - protected String getUnit() { - VoxelDimensions voxelDimensions = spimData.getSequenceDescription().getViewDescription(new ViewId(0,0)).getViewSetup().getVoxelSize(); - String unit = voxelDimensions.unit(); - return unit; - } - -} diff --git a/src/test/java/dataformats/BaseTest.java b/src/test/java/dataformats/BaseTest.java deleted file mode 100644 index 11e3e2c5..00000000 --- a/src/test/java/dataformats/BaseTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats; - -import org.embl.mobie.io.ImageDataFormat; -import org.embl.mobie.io.SpimDataOpener; -import org.junit.Assert; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.cache.SharedQueue; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.Dimensions; - - -public abstract class BaseTest extends BaseSpimDataChecker { - protected int expectedTimePoints = 0; - protected int expectedChannelsNumber = 1; - protected Dimensions expectedShape; - protected String expectedDType; - protected double[] expectedScale = null; - protected String expectedUnit = null; - - protected BaseTest(String path, ImageDataFormat format) throws SpimDataException { - super(new SpimDataOpener().open(path, format)); - } - - protected BaseTest(String path, ImageDataFormat format, SharedQueue sharedQueue) throws SpimDataException { - super(new SpimDataOpener().open(path, format, sharedQueue)); - } - - @Test - public void baseTest() { - Assertions.assertEquals(expectedTimePoints, getTimePointsSize()); - Assertions.assertEquals(expectedChannelsNumber, getAllChannelsSize()); - Assertions.assertEquals(expectedShape, getShape()); - Assertions.assertEquals(expectedDType, getDType()); - if(expectedScale != null) { - Assert.assertArrayEquals(expectedScale, getScale(), 0.0); - } - if(expectedUnit != null) { - Assertions.assertEquals(expectedUnit, getUnit()); - } - } - - public int getExpectedTimePoints() { - return expectedTimePoints; - } - - public void setExpectedTimePoints(int expectedTimePoints) { - this.expectedTimePoints = expectedTimePoints; - } - - public int getExpectedChannelsNumber() { - return expectedChannelsNumber; - } - - public void setExpectedChannelsNumber(int expectedChannelsNumber) { - this.expectedChannelsNumber = expectedChannelsNumber; - } - - public Dimensions getExpectedShape() { - return expectedShape; - } - - public void setExpectedShape(Dimensions expectedShape) { - this.expectedShape = expectedShape; - } - - public String getExpectedDType() { - return expectedDType; - } - - public void setExpectedDType(String expectedDType) { - this.expectedDType = expectedDType; - } - - protected void setExpectedScale(double[] scale) {this.expectedScale = scale;} - - protected void setExpectedUnit(String unit) {this.expectedUnit = unit;} -} diff --git a/src/test/java/dataformats/local/BaseLocalTest.java b/src/test/java/dataformats/local/BaseLocalTest.java deleted file mode 100644 index abcf28ea..00000000 --- a/src/test/java/dataformats/local/BaseLocalTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.embl.mobie.io.SpimDataOpener; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - -import mpicbg.spim.data.SpimDataException; -import dataformats.BaseSpimDataChecker; - -public class BaseLocalTest extends BaseSpimDataChecker { - protected int expectedTimePoints = 0; - protected int expectedChannelsNumber = 1; - - protected BaseLocalTest(String path, ImageDataFormat format) throws SpimDataException { - super(new SpimDataOpener().open(path, format)); - } - - @Test - public void baseTest() { - Assertions.assertEquals(expectedTimePoints, getTimePointsSize()); - Assertions.assertEquals(expectedChannelsNumber, getAllChannelsSize()); - } - - public int getExpectedTimePoints() { - return expectedTimePoints; - } - - public void setExpectedTimePoints(int expectedTimePoints) { - this.expectedTimePoints = expectedTimePoints; - } - - public int getExpectedChannelsNumber() { - return expectedChannelsNumber; - } - - public void setExpectedChannelsNumber(int expectedChannelsNumber) { - this.expectedChannelsNumber = expectedChannelsNumber; - } -} diff --git a/src/test/java/dataformats/local/ConstantinNoTablesTest.java b/src/test/java/dataformats/local/ConstantinNoTablesTest.java deleted file mode 100644 index e6971f69..00000000 --- a/src/test/java/dataformats/local/ConstantinNoTablesTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class ConstantinNoTablesTest extends BaseLocalTest { - private static final String PATH = "/Volumes/emcf/pape/jil"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public ConstantinNoTablesTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() throws SpimDataException { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/CovidEMCFTest.java b/src/test/java/dataformats/local/CovidEMCFTest.java deleted file mode 100644 index e1387a36..00000000 --- a/src/test/java/dataformats/local/CovidEMCFTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; - - -public class CovidEMCFTest extends BaseLocalTest { - private static final String PATH = "/Volumes/emcf/common/5792_Sars-Cov-2/covid-em/data"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - protected CovidEMCFTest(SpimData spimData) throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() throws SpimDataException { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/CovidEmDatasetsTest.java b/src/test/java/dataformats/local/CovidEmDatasetsTest.java deleted file mode 100644 index 5c80e1cd..00000000 --- a/src/test/java/dataformats/local/CovidEmDatasetsTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class CovidEmDatasetsTest extends BaseLocalTest { - private static final String PATH = "/pape/Work/mobie/covid-em-datasets/ngff-example/data"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvOmeZarr; - - public CovidEmDatasetsTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() throws SpimDataException { - Assertions.assertEquals(1, getTimePointsSize()); - } - -} diff --git a/src/test/java/dataformats/local/CovidPlateTest.java b/src/test/java/dataformats/local/CovidPlateTest.java deleted file mode 100644 index 95ce7812..00000000 --- a/src/test/java/dataformats/local/CovidPlateTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class CovidPlateTest extends BaseLocalTest { - private static final String PATH = "/g/kreshuk/pape/Work/mobie/covid-if-project/data"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarr; - - public CovidPlateTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/CovidTomosTest.java b/src/test/java/dataformats/local/CovidTomosTest.java deleted file mode 100644 index 73859844..00000000 --- a/src/test/java/dataformats/local/CovidTomosTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class CovidTomosTest extends BaseLocalTest { - private static final String PATH = "/Volumes/kreshuk/pape/Work/mobie/covid-tomo-datasets"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public CovidTomosTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/GiuliaMartinCLEMTest.java b/src/test/java/dataformats/local/GiuliaMartinCLEMTest.java deleted file mode 100644 index 6e0d7ac9..00000000 --- a/src/test/java/dataformats/local/GiuliaMartinCLEMTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class GiuliaMartinCLEMTest extends BaseLocalTest { - private static final String PATH = "/g/emcf/pape/clem-example-project"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public GiuliaMartinCLEMTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/JulianNoTablesTest.java b/src/test/java/dataformats/local/JulianNoTablesTest.java deleted file mode 100644 index 3d7fb4f9..00000000 --- a/src/test/java/dataformats/local/JulianNoTablesTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class JulianNoTablesTest extends BaseLocalTest { - private static final String PATH = "/Volumes/emcf/hennies/for_constantin/mobie_no_table_test/"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public JulianNoTablesTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/MartinFloatTest.java b/src/test/java/dataformats/local/MartinFloatTest.java deleted file mode 100644 index 1091bb26..00000000 --- a/src/test/java/dataformats/local/MartinFloatTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class MartinFloatTest extends BaseLocalTest { - private static final String PATH = "/Users/tischer/Desktop/mobie/MartinFloat"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarr; - - public MartinFloatTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() throws SpimDataException { - Assertions.assertEquals(1, getTimePointsSize()); - } - -} diff --git a/src/test/java/dataformats/local/OmeNgffPrototypesTest.java b/src/test/java/dataformats/local/OmeNgffPrototypesTest.java deleted file mode 100644 index 04483e99..00000000 --- a/src/test/java/dataformats/local/OmeNgffPrototypesTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class OmeNgffPrototypesTest extends BaseLocalTest { - private static final String PATH = "g/kreshuk/pape/Work/mobie/ngff/ome-ngff-prototypes/single_image/v0.4/yx.ome.zarr"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarr; - - public OmeNgffPrototypesTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() throws SpimDataException { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/OmeZarrTest.java b/src/test/java/dataformats/local/OmeZarrTest.java deleted file mode 100644 index 5c78c41b..00000000 --- a/src/test/java/dataformats/local/OmeZarrTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class OmeZarrTest extends BaseLocalTest { - private static final String PATH = "/g/kreshuk/pape/Work/mobie/covid-if-project/data"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarr; - - public OmeZarrTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/PlanktonTest.java b/src/test/java/dataformats/local/PlanktonTest.java deleted file mode 100644 index a60526e6..00000000 --- a/src/test/java/dataformats/local/PlanktonTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class PlanktonTest extends BaseLocalTest { - private static final String PATH = "/Volumes/emcf/pape/plankton-fibsem-project"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public PlanktonTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -//dataset("galdieria")); - -} diff --git a/src/test/java/dataformats/local/PlatynereisTest.java b/src/test/java/dataformats/local/PlatynereisTest.java deleted file mode 100644 index 068a6d0a..00000000 --- a/src/test/java/dataformats/local/PlatynereisTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class PlatynereisTest extends dataformats.local.BaseLocalTest -{ - private static final String PATH = "/g/arendt/EM_6dpf_segmentation/platy-browser-data/data/"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public PlatynereisTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/TestDataTest.java b/src/test/java/dataformats/local/TestDataTest.java deleted file mode 100644 index c4768470..00000000 --- a/src/test/java/dataformats/local/TestDataTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class TestDataTest extends BaseLocalTest { - private static final String PATH = "/g/emcf/pape/mobie-test-projects"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public TestDataTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/local/TobiasTest.java b/src/test/java/dataformats/local/TobiasTest.java deleted file mode 100644 index 0decbc52..00000000 --- a/src/test/java/dataformats/local/TobiasTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.local; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - - -import mpicbg.spim.data.SpimDataException; - - -public class TobiasTest extends BaseLocalTest { - private static final String PATH = "/g/schwab/Tobias/MoBIE"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5; - - public TobiasTest() throws SpimDataException { - super(PATH, FORMAT); - setExpectedTimePoints(1); - } - - @Test - public void generalTest() { - Assertions.assertEquals(1, getTimePointsSize()); - } -} diff --git a/src/test/java/dataformats/n5/ZebrafishTest.java b/src/test/java/dataformats/n5/ZebrafishTest.java deleted file mode 100644 index 5911b90e..00000000 --- a/src/test/java/dataformats/n5/ZebrafishTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.n5; - -import org.embl.mobie.io.ImageDataFormat; - -import bdv.cache.SharedQueue; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.BaseTest; - - -public class ZebrafishTest extends BaseTest { - private static final String URL = "https://raw.githubusercontent.com/mobie/zebrafish-lm-datasets/main/data/membrane/images/remote/membrane-056F63395C_lynEGFP.xml"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvN5S3; - - public ZebrafishTest() throws SpimDataException { - super(URL, FORMAT, new SharedQueue(4)); - setExpectedTimePoints(1); - setExpectedShape(new FinalDimensions(1636, 816, 156)); - setExpectedDType("uint8"); - } -} diff --git a/src/test/java/dataformats/ngff/NGFFWriterTest.java b/src/test/java/dataformats/ngff/NGFFWriterTest.java deleted file mode 100644 index ca61f848..00000000 --- a/src/test/java/dataformats/ngff/NGFFWriterTest.java +++ /dev/null @@ -1,400 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.util.List; - -import org.embl.mobie.io.ImageDataFormat; -import org.embl.mobie.io.SpimDataOpener; -import org.embl.mobie.io.n5.util.DownsampleBlock; -import org.embl.mobie.io.n5.writers.WriteImagePlusToN5; -import org.embl.mobie.io.ome.zarr.util.ZarrAxes; -import org.embl.mobie.io.ome.zarr.writers.imageplus.WriteImagePlusToN5OmeZarr; -import org.embl.mobie.io.util.IOHelper; -import org.everit.json.schema.Schema; -import org.everit.json.schema.loader.SchemaLoader; -import org.janelia.saalfeldlab.n5.Compression; -import org.janelia.saalfeldlab.n5.GzipCompression; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import bdv.img.cache.VolatileCachedCellImg; -import ij.IJ; -import ij.ImagePlus; -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.sequence.MultiResolutionSetupImgLoader; -import mpicbg.spim.data.sequence.SequenceDescription; -import mpicbg.spim.data.sequence.ViewSetup; -import net.imglib2.Dimensions; -import net.imglib2.RandomAccess; -import net.imglib2.img.cell.CellLocalizingCursor; -import net.imglib2.realtransform.AffineTransform3D; -import net.imglib2.type.numeric.integer.GenericByteType; - -import static org.apache.commons.io.FilenameUtils.removeExtension; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class NGFFWriterTest { - - private static JSONObject omeZarrSchema; - private String imageName; - private AffineTransform3D sourceTransform; - private File tempDir; - private DownsampleBlock.DownsamplingMethod downsamplingMethod; - private Compression compression; - private int defaultWidth; - private int defaultHeight; - private int defaultDepth; - private int defaultNChannels; - private int defaultNTimepoints; - - @BeforeAll - static void downloadSchema() throws IOException { - try (InputStream schemaInputStream = IOHelper.getInputStream( - "https://raw.githubusercontent.com/ome/ngff/main/0.4/schemas/image.schema")) { - omeZarrSchema = new JSONObject(new JSONTokener(schemaInputStream)); - } - } - - @BeforeEach - void setUp(@TempDir Path tempDir) throws IOException { - this.tempDir = tempDir.toFile(); - imageName = "testImage"; - sourceTransform = new AffineTransform3D(); - downsamplingMethod = DownsampleBlock.DownsamplingMethod.Average; - compression = new GzipCompression(); - // same dimensions as ImageJ sample head image - defaultWidth = 186; - defaultHeight = 226; - defaultDepth = 27; - defaultNChannels = 2; - defaultNTimepoints = 2; - } - - ImagePlus makeZYXImage(String imageName, int width, int height, int depth) { - // make an image with random values - return IJ.createImage(imageName, "8-bit noise", width, height, depth); - } - - ImagePlus makeCZYXImage(String imageName, int width, int height, int depth, int channels) { - return IJ.createImage(imageName, "8-bit ramp", width, height, channels, depth, 1); - } - - ImagePlus makeTZYXImage(String imageName, int width, int height, int depth, int timePoints) { - return IJ.createImage(imageName, "8-bit ramp", width, height, 1, depth, timePoints); - } - - ImagePlus makeTCZYXImage(String imageName, int width, int height, int depth, int channels, int timePoints) { - return IJ.createImage(imageName, "8-bit ramp", width, height, channels, depth, timePoints); - } - - String getXmlPath() { - return new File(tempDir, imageName + ".xml").getAbsolutePath(); - } - - String getZarrPath() { - return new File(tempDir, imageName + ".ome.zarr").getAbsolutePath(); - } - - String[] getViewSetupNames(ImagePlus imp, ImageDataFormat imageDataFormat) { - int nChannels = imp.getNChannels(); - return getViewSetupNames(nChannels, imageDataFormat); - } - - String[] getViewSetupNames(int nChannels, ImageDataFormat imageDataFormat) { - String[] viewSetupNames = new String[nChannels]; - - if (nChannels == 1) { - viewSetupNames[0] = imageName; - } else { - if (imageDataFormat == ImageDataFormat.BdvN5) { - // N5 supports different names for each setup - so we name by channel - for (int i = 0; i < nChannels; i++) { - viewSetupNames[i] = imageName + "-channel" + (i + 1); - } - } else { - // Ome-Zarr uses the image name for every setup (doesn't support different names currently) - for (int i = 0; i < nChannels; i++) { - viewSetupNames[i] = imageName; - } - } - } - - return viewSetupNames; - } - - void validateJSON(String zarrPath) throws IOException { - String zattrsPath = new File(zarrPath, ".zattrs").getAbsolutePath(); - - try (InputStream zattrsInputStream = new FileInputStream(zattrsPath)) { - JSONObject jsonSubject = new JSONObject(new JSONTokener(zattrsInputStream)); - - // library only supports up to draft 7 json schema - specify here, otherwise errors when reads 2020-12 in - // the schema file - SchemaLoader loader = SchemaLoader.builder() - .schemaJson(omeZarrSchema) - .draftV7Support() - .build(); - Schema schema = loader.load().build(); - - schema.validate(jsonSubject); - } - } - - void spimDataAssertions(SpimData spimData, int nChannels, int nTimepoints, ImageDataFormat imageDataFormat) { - SequenceDescription sequenceDescription = spimData.getSequenceDescription(); - assertEquals(sequenceDescription.getTimePoints().size(), nTimepoints); - assertEquals(sequenceDescription.getViewSetupsOrdered().size(), nChannels); - - // check view setup names - String[] viewSetupNames = getViewSetupNames(nChannels, imageDataFormat); - List viewSetups = sequenceDescription.getViewSetupsOrdered(); - for (int i = 0; i < viewSetups.size(); i++) { - assertEquals(viewSetups.get(i).getName(), viewSetupNames[i]); - } - - Dimensions dimensions = sequenceDescription.getViewSetupsOrdered().get(0).getSize(); - assertEquals(dimensions.dimension(0), defaultWidth); - assertEquals(dimensions.dimension(1), defaultHeight); - assertEquals(dimensions.dimension(2), defaultDepth); - } - - void n5Assertions(String xmlPath, int nChannels, int nTimepoints) throws SpimDataException { - assertTrue(new File(xmlPath).exists()); - assertTrue(new File(removeExtension(xmlPath) + ".n5").exists()); - - SpimData spimData = (SpimData) new SpimDataOpener().open(xmlPath, ImageDataFormat.BdvN5); - spimDataAssertions(spimData, nChannels, nTimepoints, ImageDataFormat.BdvN5); - } - - void zarrAssertions(String zarrPath, int nChannels, int nTimepoints) throws SpimDataException, IOException { - assertTrue(new File(zarrPath).exists()); - validateJSON(zarrPath); - - SpimData spimData = (SpimData) new SpimDataOpener().open(zarrPath, ImageDataFormat.OmeZarr); - spimDataAssertions(spimData, nChannels, nTimepoints, ImageDataFormat.OmeZarr); - } - - String writeImageAndGetPath(ImagePlus imp, ImageDataFormat imageDataFormat, - int[][] resolutions, int[][] subdivisions) { - String filePath; - - // gzip compression by default - switch (imageDataFormat) { - case BdvN5: - filePath = getXmlPath(); - new WriteImagePlusToN5().export(imp, resolutions, subdivisions, filePath, - sourceTransform, downsamplingMethod, compression, getViewSetupNames(imp, imageDataFormat)); - break; - - case OmeZarr: - filePath = getZarrPath(); - new WriteImagePlusToN5OmeZarr().export(imp, resolutions, subdivisions, filePath, - sourceTransform, downsamplingMethod, compression, getViewSetupNames(imp, imageDataFormat)); - break; - - default: - throw new UnsupportedOperationException(); - - } - - return filePath; - } - - String writeImageAndGetPath(ImageDataFormat imageDataFormat, ZarrAxes axes) { - - ImagePlus imp; - if (axes == ZarrAxes.ZYX) { - // make an image with random values, same size as the imagej sample head image - imp = makeZYXImage(imageName, defaultWidth, defaultHeight, defaultDepth); - } else if (axes == ZarrAxes.CZYX) { - imp = makeCZYXImage(imageName, defaultWidth, defaultHeight, defaultDepth, defaultNChannels); - } else if (axes == ZarrAxes.TZYX) { - imp = makeTZYXImage(imageName, defaultWidth, defaultHeight, defaultDepth, defaultNTimepoints); - } else if (axes == ZarrAxes.TCZYX) { - imp = makeTCZYXImage(imageName, defaultWidth, defaultHeight, defaultDepth, - defaultNChannels, defaultNTimepoints); - } else { - throw new UnsupportedOperationException("Unimplemented axis type"); - } - - String filePath; - - // gzip compression by default - switch (imageDataFormat) { - case BdvN5: - filePath = getXmlPath(); - new WriteImagePlusToN5().export(imp, filePath, sourceTransform, downsamplingMethod, - compression, getViewSetupNames(imp, imageDataFormat)); - break; - - case OmeZarr: - filePath = getZarrPath(); - new WriteImagePlusToN5OmeZarr().export(imp, filePath, sourceTransform, - downsamplingMethod, compression, getViewSetupNames(imp, imageDataFormat)); - break; - - default: - throw new UnsupportedOperationException(); - - } - - return filePath; - } - - VolatileCachedCellImg getImage(SpimData spimData, int setupId, int timepoint, int level) { - MultiResolutionSetupImgLoader imageLoader = (MultiResolutionSetupImgLoader) spimData. - getSequenceDescription().getImgLoader().getSetupImgLoader(setupId); - - return (VolatileCachedCellImg) imageLoader.getImage(timepoint, level); - } - - boolean isImageIdentical(VolatileCachedCellImg image1, VolatileCachedCellImg image2) { - - boolean isIdentical = true; - - CellLocalizingCursor cursorInput = image1.localizingCursor(); - RandomAccess randomAccessImage2 = image2.randomAccess(); - - while (cursorInput.hasNext()) { - cursorInput.fwd(); - - GenericByteType image1Value = (GenericByteType) cursorInput.get(); - GenericByteType image2Value = (GenericByteType) randomAccessImage2.setPositionAndGet(cursorInput); - - if (!image1Value.equals(image2Value)) { - isIdentical = false; - break; - } - } - return isIdentical; - } - - @Test - void writeAndReadZYXImageBdvN5() throws SpimDataException { - ImageDataFormat format = ImageDataFormat.BdvN5; - String xmlPath = writeImageAndGetPath(format, ZarrAxes.ZYX); - - n5Assertions(xmlPath, 1, 1); - } - - @Test - void writeAndReadCZYXImageBdvN5() throws SpimDataException { - ImageDataFormat format = ImageDataFormat.BdvN5; - String xmlPath = writeImageAndGetPath(format, ZarrAxes.CZYX); - - n5Assertions(xmlPath, defaultNChannels, 1); - } - - @Test - void writeAndReadTZYXImageBdvN5() throws SpimDataException { - ImageDataFormat format = ImageDataFormat.BdvN5; - String xmlPath = writeImageAndGetPath(format, ZarrAxes.TZYX); - - n5Assertions(xmlPath, 1, defaultNTimepoints); - } - - @Test - void writeAndReadTCZYXImageBdvN5() throws SpimDataException { - ImageDataFormat format = ImageDataFormat.BdvN5; - String xmlPath = writeImageAndGetPath(format, ZarrAxes.TCZYX); - - n5Assertions(xmlPath, defaultNChannels, defaultNTimepoints); - } - - @Test - void writeAndReadZYXImageOmeZarr() throws SpimDataException, IOException { - ImageDataFormat format = ImageDataFormat.OmeZarr; - String zarrPath = writeImageAndGetPath(format, ZarrAxes.ZYX); - - zarrAssertions(zarrPath, 1, 1); - } - - @Test - void writeAndReadCZYXImageOmeZarr() throws SpimDataException, IOException { - ImageDataFormat format = ImageDataFormat.OmeZarr; - String zarrPath = writeImageAndGetPath(format, ZarrAxes.CZYX); - - zarrAssertions(zarrPath, defaultNChannels, 1); - } - - @Test - void writeAndReadTZYXImageOmeZarr() throws SpimDataException, IOException { - ImageDataFormat format = ImageDataFormat.OmeZarr; - String zarrPath = writeImageAndGetPath(format, ZarrAxes.TZYX); - - zarrAssertions(zarrPath, 1, defaultNTimepoints); - } - - @Test - void writeAndReadTCZYXImageOmeZarr() throws SpimDataException, IOException { - ImageDataFormat format = ImageDataFormat.OmeZarr; - String zarrPath = writeImageAndGetPath(format, ZarrAxes.TCZYX); - - zarrAssertions(zarrPath, defaultNChannels, defaultNTimepoints); - } - - @Test - void checkOmeZarrLoopBack() throws SpimDataException { - // check that most downsampled levels are written properly for ome-zarr (i.e. that the loopback - // is working correctly) - // related to https://github.com/mobie/mobie-viewer-fiji/issues/572 - - // use resolutions / subdivisions that trigger 'loopback' i.e. reading from previously downsampled levels - // rather than the original image - int[][] resolutions = new int[][]{{1, 1, 1}, {2, 2, 2}, {4, 4, 4}}; - int[][] subdivisions = new int[][]{{64, 64, 64}, {64, 64, 64}, {64, 64, 64}}; - int lowestResolutionLevel = 2; - ImagePlus imp = makeZYXImage(imageName, 400, 400, 400); - - String zarrPath = writeImageAndGetPath(imp, ImageDataFormat.OmeZarr, resolutions, subdivisions); - String n5Path = writeImageAndGetPath(imp, ImageDataFormat.BdvN5, resolutions, subdivisions); - - SpimDataOpener spimDataOpener = new SpimDataOpener(); - SpimData spimDataZarr = (SpimData) spimDataOpener.open(zarrPath, ImageDataFormat.OmeZarr); - SpimData spimDataN5 = (SpimData) spimDataOpener.open(n5Path, ImageDataFormat.BdvN5); - - VolatileCachedCellImg lowestResN5 = getImage(spimDataN5, 0, 0, lowestResolutionLevel); - VolatileCachedCellImg lowestResZarr = getImage(spimDataZarr, 0, 0, lowestResolutionLevel); - - // check lowest resolution level of n5 and ome-zarr have identical pixel values - assertTrue(isImageIdentical(lowestResN5, lowestResZarr)); - } -} diff --git a/src/test/java/dataformats/ngff/base/CYXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/CYXNgffBaseTest.java deleted file mode 100644 index 9bd0fb5c..00000000 --- a/src/test/java/dataformats/ngff/base/CYXNgffBaseTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.UnsignedShortType; - - -public abstract class CYXNgffBaseTest extends NgffBaseTest { - protected CYXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(1); - setExpectedChannelsNumber(4); - setExpectedShape(new FinalDimensions(1024, 930, 4)); - setExpectedDType("uint16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{1024, 930, 1}; - int[] cellDims = new int[]{256, 256, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(0); - UnsignedShortType o = (UnsignedShortType) randomAccessibleInterval.getAt(647, 482, 0); - int value = o.get(); - int expectedValue = 4055; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(649, 346, 0); - value = o.get(); - expectedValue = 4213; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(2).getImage(0); - o = (UnsignedShortType) randomAccessibleInterval.getAt(559, 920, 0); - value = o.get(); - expectedValue = 1835; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(3).getImage(0); - o = (UnsignedShortType) randomAccessibleInterval.getAt(934, 929, 0); - value = o.get(); - expectedValue = 1724; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(770, 343, 0); - value = o.get(); - expectedValue = 2871; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/base/CZYXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/CZYXNgffBaseTest.java deleted file mode 100644 index 19ff69c7..00000000 --- a/src/test/java/dataformats/ngff/base/CZYXNgffBaseTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.ShortType; - - -public abstract class CZYXNgffBaseTest extends NgffBaseTest { - - protected CZYXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(1); - setExpectedChannelsNumber(2); - setExpectedShape(new FinalDimensions(512, 262, 486, 2)); - setExpectedDType("int16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{512, 262, 486}; - int[] cellDims = new int[]{64, 64, 64}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - ShortType o = (ShortType) randomAccessibleInterval.getAt(141, 27, 326); - int value = o.get(); - int expectedValue = 6; - Assertions.assertEquals(expectedValue, value); - - o = (ShortType) randomAccessibleInterval.getAt(120, 112, 326); - value = o.get(); - expectedValue = 339; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(0); - o = (ShortType) randomAccessibleInterval.getAt(70, 21, 303); - value = o.get(); - expectedValue = 6; - Assertions.assertEquals(expectedValue, value); - - o = (ShortType) randomAccessibleInterval.getAt(219, 253, 291); - value = o.get(); - expectedValue = 5; - Assertions.assertEquals(expectedValue, value); - - o = (ShortType) randomAccessibleInterval.getAt(355, 54, 251); - value = o.get(); - expectedValue = 6; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/base/MultiImageNgffBaseTest.java b/src/test/java/dataformats/ngff/base/MultiImageNgffBaseTest.java deleted file mode 100644 index a5356cbf..00000000 --- a/src/test/java/dataformats/ngff/base/MultiImageNgffBaseTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.UnsignedShortType; - - -public abstract class MultiImageNgffBaseTest extends NgffBaseTest { - public static final int MULTISCALES_SIZE = 4; - - protected MultiImageNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(1); - setExpectedShape(new FinalDimensions(1024, 930)); - setExpectedDType("uint16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{1024, 930, 1}; - int[] cellDims = new int[]{256, 256, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - UnsignedShortType o = (UnsignedShortType) randomAccessibleInterval.getAt(847, 886, 0); - int value = o.get(); - int expectedValue = 562; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(0); - o = (UnsignedShortType) randomAccessibleInterval.getAt(265, 882, 0); - value = o.get(); - expectedValue = 3328; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(2).getImage(0); - o = (UnsignedShortType) randomAccessibleInterval.getAt(516, 621, 0); - value = o.get(); - expectedValue = 2029; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(3).getImage(0); - o = (UnsignedShortType) randomAccessibleInterval.getAt(874, 281, 0); - value = o.get(); - expectedValue = 2325; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(19, 602, 0); - value = o.get(); - expectedValue = 2121; - Assertions.assertEquals(expectedValue, value); - } - - // make sure that we have 4 elements in the mulitscales represntation, - // corresponding to the 4 different images stored on the multi-scales level - @Test - public void checkMultiscalesSize() { - int multiscalesSize = spimData.getViewRegistrations().getViewRegistrations().size(); - Assertions.assertEquals(MULTISCALES_SIZE, multiscalesSize); - } -} diff --git a/src/test/java/dataformats/ngff/base/NgffBaseTest.java b/src/test/java/dataformats/ngff/base/NgffBaseTest.java deleted file mode 100644 index b88a8702..00000000 --- a/src/test/java/dataformats/ngff/base/NgffBaseTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.embl.mobie.io.ImageDataFormat; - -import mpicbg.spim.data.SpimDataException; - - -import dataformats.BaseTest; - - -public abstract class NgffBaseTest extends BaseTest { - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarrS3; - - protected NgffBaseTest(String url) throws SpimDataException { - super(url, FORMAT); - } - -} diff --git a/src/test/java/dataformats/ngff/base/TCYXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/TCYXNgffBaseTest.java deleted file mode 100644 index de60304d..00000000 --- a/src/test/java/dataformats/ngff/base/TCYXNgffBaseTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.ShortType; - - -public abstract class TCYXNgffBaseTest extends NgffBaseTest { - - protected TCYXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(3); - setExpectedChannelsNumber(2); - setExpectedShape(new FinalDimensions(512, 262, 2, 3)); - setExpectedDType("int16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{512, 262, 1}; - int[] cellDims = new int[]{256, 256, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python (coordinates are givn as tcxy) - // channel 0, tp 0 - // (0, 0, 508, 200) : 82 - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - ShortType o = (ShortType) randomAccessibleInterval.getAt(508, 200, 0); - int value = o.get(); - int expectedValue = 82; - Assertions.assertEquals(expectedValue, value); - - // (0, 0, 84, 255) : 8 - o = (ShortType) randomAccessibleInterval.getAt(84, 255, 0); - value = o.get(); - expectedValue = 8; - Assertions.assertEquals(expectedValue, value); - - // (0, 0, 386, 168) : 228 - o = (ShortType) randomAccessibleInterval.getAt(386, 168, 0); - value = o.get(); - expectedValue = 228; - Assertions.assertEquals(expectedValue, value); - - // channel 0, tp 1 - // (1, 0, 380, 118) : 21 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(1); - o = (ShortType) randomAccessibleInterval.getAt(380, 118, 0); - value = o.get(); - expectedValue = 21; - Assertions.assertEquals(expectedValue, value); - - // channel 1, tp 2 - // (2, 1, 243, 255) : 7 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(2); - o = (ShortType) randomAccessibleInterval.getAt(243, 255, 0); - value = o.get(); - expectedValue = 7; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/base/TCZYXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/TCZYXNgffBaseTest.java deleted file mode 100644 index 9529349a..00000000 --- a/src/test/java/dataformats/ngff/base/TCZYXNgffBaseTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.ShortType; - - -public abstract class TCZYXNgffBaseTest extends NgffBaseTest { - - protected TCZYXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(3); - setExpectedChannelsNumber(2); - setExpectedShape(new FinalDimensions(512, 262, 486, 2, 3)); - setExpectedDType("int16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{512, 262, 486}; - int[] cellDims = new int[]{64, 64, 64}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - ShortType o = (ShortType) randomAccessibleInterval.getAt(391, 70, 138); - int value = o.get(); - int expectedValue = 7; - Assertions.assertEquals(expectedValue, value); - - o = (ShortType) randomAccessibleInterval.getAt(91, 175, 178); - value = o.get(); - expectedValue = 47; - Assertions.assertEquals(expectedValue, value); - - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(0); - o = (ShortType) randomAccessibleInterval.getAt(458, 84, 65); - value = o.get(); - expectedValue = 8; - Assertions.assertEquals(expectedValue, value); - - o = (ShortType) randomAccessibleInterval.getAt(214, 105, 220); - value = o.get(); - expectedValue = 37; - Assertions.assertEquals(expectedValue, value); - - o = (ShortType) randomAccessibleInterval.getAt(207, 0, 99); - value = o.get(); - expectedValue = 8; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/base/TYXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/TYXNgffBaseTest.java deleted file mode 100644 index 649cc001..00000000 --- a/src/test/java/dataformats/ngff/base/TYXNgffBaseTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.ShortType; - - -public abstract class TYXNgffBaseTest extends NgffBaseTest { - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarrS3; - - protected TYXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(3); - setExpectedShape(new FinalDimensions(512, 262, 3)); - setExpectedDType("int16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{512, 262, 1}; - int[] cellDims = new int[]{256, 256, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python (coordinates = txy) - // timepoint 0 - //(0, 183, 238) : 8 - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - ShortType o = (ShortType) randomAccessibleInterval.getAt(183, 238, 0); - int value = o.get(); - int expectedValue = 8; - Assertions.assertEquals(expectedValue, value); - - // timepoint 1 - //(1, 325, 207) : 32 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(1); - o = (ShortType) randomAccessibleInterval.getAt(325, 207, 0); - value = o.get(); - expectedValue = 32; - Assertions.assertEquals(expectedValue, value); - - //(1, 409, 175) : 133 - o = (ShortType) randomAccessibleInterval.getAt(409, 175, 0); - value = o.get(); - expectedValue = 133; - Assertions.assertEquals(expectedValue, value); - - //(1, 109, 144) : 415 - o = (ShortType) randomAccessibleInterval.getAt(109, 144, 0); - value = o.get(); - expectedValue = 415; - Assertions.assertEquals(expectedValue, value); - - // timepoint 2 - //(2, 447, 132) : 64 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(2); - o = (ShortType) randomAccessibleInterval.getAt(447, 132, 0); - value = o.get(); - expectedValue = 64; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/base/YXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/YXNgffBaseTest.java deleted file mode 100644 index 2e521e0a..00000000 --- a/src/test/java/dataformats/ngff/base/YXNgffBaseTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.UnsignedShortType; - - -public abstract class YXNgffBaseTest extends NgffBaseTest { - - protected YXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(1); - setExpectedShape(new FinalDimensions(1024, 930)); - setExpectedDType("uint16"); - } - - @Test - public void checkDataset() { - long x = 0; - long y = 0; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{1024, 930, 1}; - int[] cellDims = new int[]{256, 256, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - - UnsignedShortType o = (UnsignedShortType) randomAccessibleInterval.getAt(0, 0, 0); - int value = o.get(); - int expectedValue = 538; - Assertions.assertEquals(expectedValue, value); - - // random test data generated independently with python - o = (UnsignedShortType) randomAccessibleInterval.getAt(294, 233, 0); - value = o.get(); - expectedValue = 627; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(970, 719, 0); - value = o.get(); - expectedValue = 611; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(962, 828, 0); - value = o.get(); - expectedValue = 688; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(219, 841, 0); - value = o.get(); - expectedValue = 580; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedShortType) randomAccessibleInterval.getAt(588, 710, 0); - value = o.get(); - expectedValue = 594; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/base/ZYXNgffBaseTest.java b/src/test/java/dataformats/ngff/base/ZYXNgffBaseTest.java deleted file mode 100644 index 8d7d7931..00000000 --- a/src/test/java/dataformats/ngff/base/ZYXNgffBaseTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.base; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.UnsignedByteType; - - -public abstract class ZYXNgffBaseTest extends NgffBaseTest { - - protected ZYXNgffBaseTest(String url) throws SpimDataException { - super(url); - //set values for base test - setExpectedTimePoints(1); - setExpectedShape(new FinalDimensions(483, 393, 603)); - setExpectedDType("uint8"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{483, 393, 603}; - int[] cellDims = new int[]{64, 64, 64}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - - // random test data generated independently with python - UnsignedByteType o = (UnsignedByteType) randomAccessibleInterval.getAt(232, 73, 503); - int value = o.get(); - int expectedValue = 137; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedByteType) randomAccessibleInterval.getAt(139, 180, 136); - value = o.get(); - expectedValue = 104; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedByteType) randomAccessibleInterval.getAt(165, 37, 581); - value = o.get(); - expectedValue = 156; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedByteType) randomAccessibleInterval.getAt(399, 45, 594); - value = o.get(); - expectedValue = 138; - Assertions.assertEquals(expectedValue, value); - - o = (UnsignedByteType) randomAccessibleInterval.getAt(116, 381, 281); - value = o.get(); - expectedValue = 156; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/bdv_ngff/BdvNgffTest.java b/src/test/java/dataformats/ngff/bdv_ngff/BdvNgffTest.java deleted file mode 100644 index a8505ca4..00000000 --- a/src/test/java/dataformats/ngff/bdv_ngff/BdvNgffTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.bdv_ngff; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.Disabled; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.BaseTest; - -/* - * This is a test for the legacy data format bdv.ome.zarr. - * It's kept here for reference, but is currently not used. - */ - -@Disabled -public class BdvNgffTest extends BaseTest { - private static final String URL = "https://s3.embl.de/i2k-2020/project-bdv-ome-zarr"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvOmeZarr; - - // The specified key does not exist. - public BdvNgffTest() throws SpimDataException { - super(URL, FORMAT); - } -} diff --git a/src/test/java/dataformats/ngff/bdv_ngff/COMULISTest.java b/src/test/java/dataformats/ngff/bdv_ngff/COMULISTest.java deleted file mode 100644 index c7f846e2..00000000 --- a/src/test/java/dataformats/ngff/bdv_ngff/COMULISTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.bdv_ngff; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.Disabled; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.BaseTest; - -/* - * This is a test for the legacy data format bdv.ome.zarr. - * It's kept here for reference, but is currently not used. - */ - -@Disabled -public class COMULISTest extends BaseTest { - private static final String URL = "https://s3.embl.de/comulis"; - private static final ImageDataFormat FORMAT = ImageDataFormat.BdvOmeZarrS3; - - public COMULISTest() throws SpimDataException { - super(URL, FORMAT); - } -} diff --git a/src/test/java/dataformats/ngff/v01/CYXNgffV01Test.java b/src/test/java/dataformats/ngff/v01/CYXNgffV01Test.java deleted file mode 100644 index 4032c5c7..00000000 --- a/src/test/java/dataformats/ngff/v01/CYXNgffV01Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v01; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.CYXNgffBaseTest; - - -public class CYXNgffV01Test extends CYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.1/cyx.ome.zarr"; - public CYXNgffV01Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(1024, 930, 1, 4, 1)); - } -} diff --git a/src/test/java/dataformats/ngff/v01/TCYXNgffV01Test.java b/src/test/java/dataformats/ngff/v01/TCYXNgffV01Test.java deleted file mode 100644 index 9b9c75ad..00000000 --- a/src/test/java/dataformats/ngff/v01/TCYXNgffV01Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v01; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.TCYXNgffBaseTest; - - -public class TCYXNgffV01Test extends TCYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.1/tcyx.ome.zarr"; - public TCYXNgffV01Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(512, 262, 1, 2, 3)); - } -} diff --git a/src/test/java/dataformats/ngff/v01/TCZYXNgffV01Test.java b/src/test/java/dataformats/ngff/v01/TCZYXNgffV01Test.java deleted file mode 100644 index 7f935100..00000000 --- a/src/test/java/dataformats/ngff/v01/TCZYXNgffV01Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v01; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TCZYXNgffBaseTest; - - -public class TCZYXNgffV01Test extends TCZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.1/tczyx.ome.zarr"; - public TCZYXNgffV01Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v01/TYXNgffV01Test.java b/src/test/java/dataformats/ngff/v01/TYXNgffV01Test.java deleted file mode 100644 index 35468024..00000000 --- a/src/test/java/dataformats/ngff/v01/TYXNgffV01Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v01; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.TYXNgffBaseTest; - - -public class TYXNgffV01Test extends TYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.1/tyx.ome.zarr"; - public TYXNgffV01Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(512, 262, 1, 1, 3)); - } -} diff --git a/src/test/java/dataformats/ngff/v01/YXNgffV01Test.java b/src/test/java/dataformats/ngff/v01/YXNgffV01Test.java deleted file mode 100644 index 9135f500..00000000 --- a/src/test/java/dataformats/ngff/v01/YXNgffV01Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v01; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.YXNgffBaseTest; - - -public class YXNgffV01Test extends YXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.1/yx.ome.zarr"; - public YXNgffV01Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(1024, 930, 1, 1, 1)); - } -} diff --git a/src/test/java/dataformats/ngff/v01/ZYXNgffV01Test.java b/src/test/java/dataformats/ngff/v01/ZYXNgffV01Test.java deleted file mode 100644 index 25d7cd58..00000000 --- a/src/test/java/dataformats/ngff/v01/ZYXNgffV01Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v01; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.ZYXNgffBaseTest; - - -public class ZYXNgffV01Test extends ZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.1/zyx.ome.zarr"; - public ZYXNgffV01Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(483, 393, 603, 1, 1)); - } -} diff --git a/src/test/java/dataformats/ngff/v02/CYXNgffV02Test.java b/src/test/java/dataformats/ngff/v02/CYXNgffV02Test.java deleted file mode 100644 index 2dd0a7aa..00000000 --- a/src/test/java/dataformats/ngff/v02/CYXNgffV02Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v02; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.CYXNgffBaseTest; - - -public class CYXNgffV02Test extends CYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.2/cyx.ome.zarr"; - public CYXNgffV02Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(1024, 930, 1, 4, 1)); - } -} diff --git a/src/test/java/dataformats/ngff/v02/TCYXNgffV02Test.java b/src/test/java/dataformats/ngff/v02/TCYXNgffV02Test.java deleted file mode 100644 index f0e49bfa..00000000 --- a/src/test/java/dataformats/ngff/v02/TCYXNgffV02Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v02; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.TCYXNgffBaseTest; - - -public class TCYXNgffV02Test extends TCYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.2/tcyx.ome.zarr"; - public TCYXNgffV02Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(512, 262, 1, 2, 3)); - } -} diff --git a/src/test/java/dataformats/ngff/v02/TCZYXNgffV02Test.java b/src/test/java/dataformats/ngff/v02/TCZYXNgffV02Test.java deleted file mode 100644 index fd4e8699..00000000 --- a/src/test/java/dataformats/ngff/v02/TCZYXNgffV02Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v02; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TCZYXNgffBaseTest; - - -public class TCZYXNgffV02Test extends TCZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.2/tczyx.ome.zarr"; - public TCZYXNgffV02Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v02/TYXNgffV02Test.java b/src/test/java/dataformats/ngff/v02/TYXNgffV02Test.java deleted file mode 100644 index a70a1a82..00000000 --- a/src/test/java/dataformats/ngff/v02/TYXNgffV02Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v02; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.TYXNgffBaseTest; - - -public class TYXNgffV02Test extends TYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.2/tyx.ome.zarr"; - public TYXNgffV02Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(512, 262, 1, 1, 3)); - } -} diff --git a/src/test/java/dataformats/ngff/v02/YXNgffV02Test.java b/src/test/java/dataformats/ngff/v02/YXNgffV02Test.java deleted file mode 100644 index 944b270c..00000000 --- a/src/test/java/dataformats/ngff/v02/YXNgffV02Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v02; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.YXNgffBaseTest; - - -public class YXNgffV02Test extends YXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.2/yx.ome.zarr"; - public YXNgffV02Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(1024, 930, 1, 1, 1)); - } -} diff --git a/src/test/java/dataformats/ngff/v02/ZYXNgffV02Test.java b/src/test/java/dataformats/ngff/v02/ZYXNgffV02Test.java deleted file mode 100644 index 8e832b09..00000000 --- a/src/test/java/dataformats/ngff/v02/ZYXNgffV02Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v02; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.ngff.base.ZYXNgffBaseTest; - - -public class ZYXNgffV02Test extends ZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.2/zyx.ome.zarr"; - public ZYXNgffV02Test() throws SpimDataException { - super(URL); - setExpectedShape(new FinalDimensions(483, 393, 603, 1, 1)); - } -} diff --git a/src/test/java/dataformats/ngff/v03/CYXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/CYXNgffV03Test.java deleted file mode 100644 index eaabab52..00000000 --- a/src/test/java/dataformats/ngff/v03/CYXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.CYXNgffBaseTest; - - -public class CYXNgffV03Test extends CYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/cyx.ome.zarr"; - public CYXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v03/CZYXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/CZYXNgffV03Test.java deleted file mode 100644 index 90e84083..00000000 --- a/src/test/java/dataformats/ngff/v03/CZYXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.CZYXNgffBaseTest; - - -public class CZYXNgffV03Test extends CZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/czyx.ome.zarr"; - public CZYXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v03/TCYXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/TCYXNgffV03Test.java deleted file mode 100644 index 5233ef8e..00000000 --- a/src/test/java/dataformats/ngff/v03/TCYXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TCYXNgffBaseTest; - - -public class TCYXNgffV03Test extends TCYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/tcyx.ome.zarr"; - public TCYXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v03/TCZYXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/TCZYXNgffV03Test.java deleted file mode 100644 index f0a2ff45..00000000 --- a/src/test/java/dataformats/ngff/v03/TCZYXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TCZYXNgffBaseTest; - - -public class TCZYXNgffV03Test extends TCZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/tczyx.ome.zarr"; - public TCZYXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v03/TYXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/TYXNgffV03Test.java deleted file mode 100644 index a9c153d6..00000000 --- a/src/test/java/dataformats/ngff/v03/TYXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TYXNgffBaseTest; - - -public class TYXNgffV03Test extends TYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/tyx.ome.zarr"; - public TYXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v03/YXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/YXNgffV03Test.java deleted file mode 100644 index 81e3f5a3..00000000 --- a/src/test/java/dataformats/ngff/v03/YXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.YXNgffBaseTest; - - -public class YXNgffV03Test extends YXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/yx.ome.zarr"; - public YXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v03/ZYXNgffV03Test.java b/src/test/java/dataformats/ngff/v03/ZYXNgffV03Test.java deleted file mode 100644 index 74c0ef7d..00000000 --- a/src/test/java/dataformats/ngff/v03/ZYXNgffV03Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v03; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.ZYXNgffBaseTest; - - -public class ZYXNgffV03Test extends ZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.3/zyx.ome.zarr"; - public ZYXNgffV03Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v04/CYXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/CYXNgffV04Test.java deleted file mode 100644 index 0c163369..00000000 --- a/src/test/java/dataformats/ngff/v04/CYXNgffV04Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.CYXNgffBaseTest; - - -public class CYXNgffV04Test extends CYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/cyx.ome.zarr"; - public CYXNgffV04Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v04/CZYXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/CZYXNgffV04Test.java deleted file mode 100644 index af60481c..00000000 --- a/src/test/java/dataformats/ngff/v04/CZYXNgffV04Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.CZYXNgffBaseTest; - - -public class CZYXNgffV04Test extends CZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/czyx.ome.zarr"; - public CZYXNgffV04Test() throws SpimDataException { - super(URL); - setExpectedScale(new double[]{0.65, 0.65, 1.0}); - setExpectedUnit("micrometer"); - } -} diff --git a/src/test/java/dataformats/ngff/v04/ImageWithLabelsNgffTest.java b/src/test/java/dataformats/ngff/v04/ImageWithLabelsNgffTest.java deleted file mode 100644 index 3b3d3a0f..00000000 --- a/src/test/java/dataformats/ngff/v04/ImageWithLabelsNgffTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.UnsignedShortType; -import dataformats.BaseTest; - -/* - * Test for image data with labels, to ensure that this data can be read correctly -*/ - - -public class ImageWithLabelsNgffTest extends BaseTest { - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/image-with-labels.ome.zarr"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarrS3; - - public ImageWithLabelsNgffTest() throws SpimDataException { - super(URL, FORMAT); - //set values for base test - setExpectedTimePoints(1); - setExpectedChannelsNumber(4); - setExpectedShape(new FinalDimensions(2048, 2048, 6, 4)); - setExpectedDType("uint16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{2048, 2048, 6}; - int[] cellDims = new int[]{512, 512, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python - //(0, 992, 397, 4) : 170 - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - // ShortType o = (ShortType) randomAccessibleInterval.getAt(992, 397, 4); - UnsignedShortType o = (UnsignedShortType) randomAccessibleInterval.getAt(992, 397, 4); - int value = o.get(); - int expectedValue = 170; - Assertions.assertEquals(expectedValue, value); - - //(1, 92, 762, 5) : 163 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(0); - // o = (ShortType) randomAccessibleInterval.getAt(92, 762, 5); - o = (UnsignedShortType) randomAccessibleInterval.getAt(92, 762, 5); - value = o.get(); - expectedValue = 163; - Assertions.assertEquals(expectedValue, value); - - //(1, 405, 1294, 4) : 186 - // o = (ShortType) randomAccessibleInterval.getAt(405, 1294, 4); - o = (UnsignedShortType) randomAccessibleInterval.getAt(405, 1294, 4); - value = o.get(); - expectedValue = 186; - Assertions.assertEquals(expectedValue, value); - - //(1, 737, 900, 3) : 177 - // o = (ShortType) randomAccessibleInterval.getAt(737, 900, 3); - o = (UnsignedShortType) randomAccessibleInterval.getAt(737, 900, 3); - value = o.get(); - expectedValue = 177; - Assertions.assertEquals(expectedValue, value); - - //(3, 520, 269, 3) : 1143 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(3).getImage(0); - // o = (ShortType) randomAccessibleInterval.getAt(520, 269, 3); - o = (UnsignedShortType) randomAccessibleInterval.getAt(520, 269, 3); - value = o.get(); - expectedValue = 1143; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/v04/MultiImageNgffV04Test.java b/src/test/java/dataformats/ngff/v04/MultiImageNgffV04Test.java deleted file mode 100644 index 8859a3c3..00000000 --- a/src/test/java/dataformats/ngff/v04/MultiImageNgffV04Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.MultiImageNgffBaseTest; - - -public class MultiImageNgffV04Test extends MultiImageNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/multi-image.ome.zarr"; - public MultiImageNgffV04Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v04/SpatialTranscriptomicsDataNgffTest.java b/src/test/java/dataformats/ngff/v04/SpatialTranscriptomicsDataNgffTest.java deleted file mode 100644 index 0b12aad4..00000000 --- a/src/test/java/dataformats/ngff/v04/SpatialTranscriptomicsDataNgffTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import bdv.img.cache.VolatileCachedCellImg; - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.cell.CellGrid; -import net.imglib2.type.numeric.integer.UnsignedShortType; -import dataformats.BaseTest; - -/* - * Extra test for the data from - * https://s3.embl.de/i2k-2020/spatial-transcriptomics-example/pos42/images/ome-zarr/MMStack_Pos42.ome.zarr - * which is for some reason not displayed properly in MoBIE / BDV. - * See https://github.com/mobie/mobie-viewer-fiji/issues/791 for details. -*/ - - -public class SpatialTranscriptomicsDataNgffTest extends BaseTest { - private static final String URL = "https://s3.embl.de/i2k-2020/spatial-transcriptomics-example/pos42/images/ome-zarr/MMStack_Pos42.ome.zarr"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OmeZarrS3; - - public SpatialTranscriptomicsDataNgffTest() throws SpimDataException { - super(URL, FORMAT); - //set values for base test - setExpectedTimePoints(1); - setExpectedChannelsNumber(4); - setExpectedShape(new FinalDimensions(2048, 2048, 6, 4)); - setExpectedDType("uint16"); - } - - @Test - public void checkDataset() { - long x = 1; - long y = 1; - long z = 1; - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - if (x > imageDimensions[0] || y > imageDimensions[1] || z > imageDimensions[2]) { - throw new RuntimeException("Coordinates out of bounds"); - } - - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - VolatileCachedCellImg volatileCachedCellImg = (VolatileCachedCellImg) randomAccessibleInterval; - CellGrid cellGrid = volatileCachedCellImg.getCellGrid(); - long[] dims = new long[]{2048, 2048, 6}; - int[] cellDims = new int[]{512, 512, 1}; - CellGrid expected = new CellGrid(dims, cellDims); - Assertions.assertEquals(expected, cellGrid); - } - - @Test - public void checkImgValue() { - - // random test data generated independently with python - //(0, 992, 397, 4) : 170 - RandomAccessibleInterval randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0); - // ShortType o = (ShortType) randomAccessibleInterval.getAt(992, 397, 4); - UnsignedShortType o = (UnsignedShortType) randomAccessibleInterval.getAt(992, 397, 4); - int value = o.get(); - int expectedValue = 170; - Assertions.assertEquals(expectedValue, value); - - //(1, 92, 762, 5) : 163 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(1).getImage(0); - // o = (ShortType) randomAccessibleInterval.getAt(92, 762, 5); - o = (UnsignedShortType) randomAccessibleInterval.getAt(92, 762, 5); - value = o.get(); - expectedValue = 163; - Assertions.assertEquals(expectedValue, value); - - //(1, 405, 1294, 4) : 186 - // o = (ShortType) randomAccessibleInterval.getAt(405, 1294, 4); - o = (UnsignedShortType) randomAccessibleInterval.getAt(405, 1294, 4); - value = o.get(); - expectedValue = 186; - Assertions.assertEquals(expectedValue, value); - - //(1, 737, 900, 3) : 177 - // o = (ShortType) randomAccessibleInterval.getAt(737, 900, 3); - o = (UnsignedShortType) randomAccessibleInterval.getAt(737, 900, 3); - value = o.get(); - expectedValue = 177; - Assertions.assertEquals(expectedValue, value); - - //(3, 520, 269, 3) : 1143 - randomAccessibleInterval = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(3).getImage(0); - // o = (ShortType) randomAccessibleInterval.getAt(520, 269, 3); - o = (UnsignedShortType) randomAccessibleInterval.getAt(520, 269, 3); - value = o.get(); - expectedValue = 1143; - Assertions.assertEquals(expectedValue, value); - } -} diff --git a/src/test/java/dataformats/ngff/v04/TCYXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/TCYXNgffV04Test.java deleted file mode 100644 index bbeff6eb..00000000 --- a/src/test/java/dataformats/ngff/v04/TCYXNgffV04Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TCYXNgffBaseTest; - - -public class TCYXNgffV04Test extends TCYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/tcyx.ome.zarr"; - public TCYXNgffV04Test() throws SpimDataException { - super(URL); - setExpectedScale(new double[]{0.65, 0.65, 1.0}); - setExpectedUnit("micrometer"); - } -} diff --git a/src/test/java/dataformats/ngff/v04/TCZYXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/TCZYXNgffV04Test.java deleted file mode 100644 index cbaefe81..00000000 --- a/src/test/java/dataformats/ngff/v04/TCZYXNgffV04Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.TCZYXNgffBaseTest; - - -public class TCZYXNgffV04Test extends TCZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/tczyx.ome.zarr"; - public TCZYXNgffV04Test() throws SpimDataException { - super(URL); - setExpectedScale(new double[]{0.65, 0.65, 1.0}); - setExpectedUnit("micrometer"); - } -} diff --git a/src/test/java/dataformats/ngff/v04/TYXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/TYXNgffV04Test.java deleted file mode 100644 index 87a85d87..00000000 --- a/src/test/java/dataformats/ngff/v04/TYXNgffV04Test.java +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - -import dataformats.ngff.base.TYXNgffBaseTest; -import mpicbg.spim.data.SpimDataException; - -public class TYXNgffV04Test extends TYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/tyx.ome.zarr"; - public TYXNgffV04Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v04/YXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/YXNgffV04Test.java deleted file mode 100644 index fa396255..00000000 --- a/src/test/java/dataformats/ngff/v04/YXNgffV04Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.YXNgffBaseTest; - - -public class YXNgffV04Test extends YXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/yx.ome.zarr"; - public YXNgffV04Test() throws SpimDataException { - super(URL); - } -} diff --git a/src/test/java/dataformats/ngff/v04/ZYXNgffV04Test.java b/src/test/java/dataformats/ngff/v04/ZYXNgffV04Test.java deleted file mode 100644 index b7a44777..00000000 --- a/src/test/java/dataformats/ngff/v04/ZYXNgffV04Test.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.ngff.v04; - - -import mpicbg.spim.data.SpimDataException; -import dataformats.ngff.base.ZYXNgffBaseTest; - - -public class ZYXNgffV04Test extends ZYXNgffBaseTest{ - private static final String URL = "https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/zyx.ome.zarr"; - public ZYXNgffV04Test() throws SpimDataException { - super(URL); - setExpectedScale(new double[]{64.0, 64.0, 64.0}); - setExpectedUnit("nanometer"); - } -} diff --git a/src/test/java/dataformats/openorganelle/OpenOrganelleTest.java b/src/test/java/dataformats/openorganelle/OpenOrganelleTest.java deleted file mode 100644 index 599dc4d1..00000000 --- a/src/test/java/dataformats/openorganelle/OpenOrganelleTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package dataformats.openorganelle; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.embl.mobie.io.ImageDataFormat; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - - -import mpicbg.spim.data.SpimDataException; -import net.imglib2.FinalDimensions; -import dataformats.BaseTest; - - -public class OpenOrganelleTest extends BaseTest { - private static final String URL = "https://janelia-cosem.s3.amazonaws.com/jrc_hela-2/jrc_hela-2.n5/em/fibsem-uint16"; - private static final ImageDataFormat FORMAT = ImageDataFormat.OpenOrganelleS3; - public static final int N = 3; - public final Map trueValuesMap = new LinkedHashMap<>(); - - public OpenOrganelleTest() throws SpimDataException { - super(URL, FORMAT); - setExpectedTimePoints(1); - setExpectedShape(new FinalDimensions(12000, 1600, 6368)); - setExpectedDType("uint16"); - init(); - } - - public int getRandomNumberUsingNextInt(int min, int max) { - Random random = new Random(); - return random.nextInt(max - min) + min; - } - - public void init() { - System.out.println("Before init() method called"); - long[] imageDimensions = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).dimensionsAsLongArray(); - for (int i = 0; i <= N; i++) { - long x = getRandomNumberUsingNextInt(0, Math.toIntExact(imageDimensions[0] - 1)); - long y = getRandomNumberUsingNextInt(0, Math.toIntExact(imageDimensions[1] - 1)); - long z = getRandomNumberUsingNextInt(0, Math.toIntExact(imageDimensions[2] - 1)); - long[] axes = new long[]{x, y, z}; - Object realPixelValue = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).getAt(x, y, z); - trueValuesMap.put(axes, realPixelValue); - } - } - - @Test - @DisplayName("Random SpimData test") - public void RandomSpimDataTest() { - System.out.println("Running random test"); - List testValues = new ArrayList<>(); - for (long[] axes : trueValuesMap.keySet()) { - Object realPixelValue = spimData.getSequenceDescription().getImgLoader().getSetupImgLoader(0).getImage(0).getAt(axes[0], axes[1], axes[2]); - testValues.add(realPixelValue); - } - assertArrayEquals(testValues.toArray(), trueValuesMap.values().toArray()); - } -} diff --git a/src/test/java/develop/DeleteMe.java b/src/test/java/develop/DeleteMe.java new file mode 100644 index 00000000..1b7c0ee2 --- /dev/null +++ b/src/test/java/develop/DeleteMe.java @@ -0,0 +1,18 @@ +package develop; + +import bdv.util.AbstractSource; +import bdv.util.RandomAccessibleIntervalSource4D; +import org.janelia.saalfeldlab.n5.universe.metadata.FinalVoxelDimensions; + +import java.lang.reflect.Field; + +public class DeleteMe +{ + public static void main( String[] args ) throws NoSuchFieldException, IllegalAccessException + { + //RandomAccessibleIntervalSource4D< ? > source4D = new RandomAccessibleIntervalSource4D<>( null,null, null ); + Field field = AbstractSource.class.getDeclaredField("voxelDimensions"); + field.setAccessible(true); + //field.set( source4D, new FinalVoxelDimensions( "pixel", 1.0, 1.0, 1.0 ) ); + } +} diff --git a/src/test/java/develop/HDF5ImageJ.java b/src/test/java/develop/HDF5ImageJ.java deleted file mode 100644 index 955f5d14..00000000 --- a/src/test/java/develop/HDF5ImageJ.java +++ /dev/null @@ -1,1050 +0,0 @@ -package develop; - -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -// -// Part of the HDF5 plugin for ImageJ -// written by: Olaf Ronneberger (ronneber@informatik.uni-freiburg.de) -// Copyright: GPL v2 -// - -import ch.systemsx.cisd.hdf5.*; -import ij.IJ; -import ij.ImagePlus; -import ij.ImageStack; -import ij.process.ImageProcessor; -import ij.process.ColorProcessor; -import ch.systemsx.cisd.base.mdarray.MDByteArray; -import ch.systemsx.cisd.base.mdarray.MDShortArray; -import ch.systemsx.cisd.base.mdarray.MDFloatArray; -import hdf.hdf5lib.exceptions.HDF5Exception; - -import java.awt.HeadlessException; -import java.util.ArrayList; -import java.util.List; - -public class HDF5ImageJ -{ - //----------------------------------------------------------------------------- - public static ImagePlus hdf5read( String filename, String datasetname) - { - String[] dsetNames = new String[1]; - dsetNames[0] = datasetname; - return loadDataSetsToHyperStack( filename, dsetNames, 1, 1); - } - - public static ImagePlus hdf5read( String filename, String[] datasets, int nFrames, int nChannels) - { - return loadDataSetsToHyperStack( filename, datasets, nFrames, nChannels, false); - } - - public static ImagePlus hdf5read( String filename, String datasetname, String layout) - { - String[] dsetNames = new String[1]; - dsetNames[0] = datasetname; - return loadCustomLayoutDataSetToHyperStack( filename, datasetname, layout, false); - } - - public static void hdf5write( String filename, String datasetname) - { - saveHyperStack( IJ.getImage(), filename, datasetname, "", "", 0, "replace"); - } - - public static void hdf5write( ImagePlus imp, String filename, String datasetname) - { - saveHyperStack( imp, filename, datasetname, "", "", 0, "replace"); - } - - public static void hdf5write( ImagePlus imp, String filename, String datasetname, boolean replace) - { - if (replace) { - saveHyperStack( imp, filename, datasetname, "", "", 0, "replace"); - } else { - saveHyperStack( imp, filename, datasetname, "", "", 0, "append"); - } - } - - public static void hdf5write( ImagePlus imp, String filename, String datasetname, String formatTime, String formatChannel, int compressionLevel) - { - saveHyperStack( imp, filename, datasetname, formatTime, formatChannel, compressionLevel, "replace"); - } - - public static void hdf5write( ImagePlus imp, String filename, String datasetname, String formatTime, String formatChannel, int compressionLevel, boolean replace) - { - if (replace) { - saveHyperStack( imp, filename, datasetname, formatTime, formatChannel, compressionLevel, "replace"); - } else { - saveHyperStack( imp, filename, datasetname, formatTime, formatChannel, compressionLevel, "append"); - } - } - - public static ArrayList< DataSetInfo > hdf5list( String filename) - { - IHDF5Reader reader = HDF5Factory.openForReading(filename); - ArrayList< DataSetInfo > dataSets = recursiveGetInfo( reader, reader.object().getLinkInformation("/")); - reader.close(); - return dataSets; - } - - static ArrayList< DataSetInfo > recursiveGetInfo( IHDF5Reader reader, HDF5LinkInformation link) - { - ArrayList< DataSetInfo > dataSets = new ArrayList< DataSetInfo >(); - recursiveGetInfo(reader, link, dataSets); - return dataSets; - } - - static void recursiveGetInfo(IHDF5Reader reader, HDF5LinkInformation link, ArrayList< DataSetInfo > dataSets) - { - List members = reader.object().getGroupMemberInformation(link.getPath(), true); - // DefaultMutableTreeNode node = new DefaultMutableTreeNode(link.getName()); - - for (HDF5LinkInformation info : members) - { - HDF5ObjectType type = info.getType(); - IJ.log(info.getPath() + ":" + type); - switch (type) - { - case EXTERNAL_LINK: - // update type to external link type - proceed through switch (no break) - // external link target paths are formatted: "EXTERNAL::/path/to/file::/path/to/object" - String[] extl_paths = info.tryGetSymbolicLinkTarget().split("::"); - IHDF5Reader extl_reader = HDF5Factory.openForReading(extl_paths[1]); - HDF5LinkInformation extl_target = extl_reader.object().getLinkInformation(extl_paths[2]); - type = extl_target.getType(); - extl_reader.close(); - case DATASET: - HDF5DataSetInformation dsInfo = reader.object().getDataSetInformation(info.getPath()); - HDF5DataTypeInformation dsType = dsInfo.getTypeInformation(); - - String dimText = ""; - if( dsInfo.getRank() == 0) - { - dimText ="1"; - } - else - { - dimText += dsInfo.getDimensions()[0]; - for( int i = 1; i < dsInfo.getRank(); ++i) - { - dimText += "x" + dsInfo.getDimensions()[i]; - } - } - - - String typeText = HDF5ImageJ.dsInfoToTypeString(dsInfo); - - // try to read element_size_um attribute - String element_size_um_text = "unknown"; - try { - float[] element_size_um = reader.float32().getArrayAttr(info.getPath(), "element_size_um"); - element_size_um_text = "" + element_size_um[0] + "x" - + element_size_um[1] + "x" + element_size_um[2]; - - } - catch (HDF5Exception err) { - IJ.log("Warning: Can't read attribute 'element_size_um' from dataset '" + info.getPath() + "':\n" - + err ); - } - - IJ.log(info.getPath() + ":" + dsInfo); - - dataSets.add( new DataSetInfo( info.getPath(), dimText, typeText, - element_size_um_text)); - - - break; - case SOFT_LINK: - IJ.log(info.getPath() + " -> " + info.tryGetSymbolicLinkTarget()); - // node.add(new DefaultMutableTreeNode(info.getName() + " -> " + info.tryGetSymbolicLinkTarget())); - - break; - case GROUP: - recursiveGetInfo( reader, info, dataSets); - // node.add( browse(reader,info)); - - break; - default: - break; - } - } - } - - static ImagePlus loadDataSetsToHyperStack( String filename, String[] dsetNames, - int nFrames, int nChannels) - { - return loadDataSetsToHyperStack( filename, dsetNames, nFrames, nChannels, true); - } - - //----------------------------------------------------------------------------- - static ImagePlus loadDataSetsToHyperStack( String filename, String[] dsetNames, - int nFrames, int nChannels, boolean show) - { - String dsetName = ""; - try - { - IHDF5ReaderConfigurator conf = HDF5Factory.configureForReading(filename); - conf.performNumericConversions(); - IHDF5Reader reader = conf.reader(); - ImagePlus imp = null; - int rank = 0; - int nLevels = 0; - int nRows = 0; - int nCols = 0; - boolean isRGB = false; - int nBits = 0; - double maxGray = 1; - String typeText = ""; - for (int frame = 0; frame < nFrames; ++frame) { - for (int channel = 0; channel < nChannels; ++channel) { - // load data set - // - dsetName = dsetNames[frame*nChannels+channel]; - IJ.showStatus( "Loading " + dsetName); - IJ.showProgress( frame*nChannels+channel+1, nFrames*nChannels); - HDF5DataSetInformation dsInfo = reader.object().getDataSetInformation(dsetName); - float[] element_size_um = {1,1,1}; - try { - element_size_um = reader.float32().getArrayAttr(dsetName, "element_size_um"); - } - catch (HDF5Exception err) { - IJ.log("Warning: Can't read attribute 'element_size_um' from file '" + filename - + "', dataset '" + dsetName + "':\n" - + err + "\n" - + "Assuming element size of 1 x 1 x 1 um^3"); - } - - // in first call create hyperstack - // - if (imp == null) { - rank = dsInfo.getRank(); - typeText = dsInfoToTypeString(dsInfo); - if (rank == 2) { - nLevels = 1; - nRows = (int)dsInfo.getDimensions()[0]; - nCols = (int)dsInfo.getDimensions()[1]; - } else if (rank == 3) { - nLevels = (int)dsInfo.getDimensions()[0]; - nRows = (int)dsInfo.getDimensions()[1]; - nCols = (int)dsInfo.getDimensions()[2]; - if( typeText.equals( "uint8") && nCols == 3) - { - nLevels = 1; - nRows = (int)dsInfo.getDimensions()[0]; - nCols = (int)dsInfo.getDimensions()[1]; - isRGB = true; - } - } else if (rank == 4 && typeText.equals( "uint8")) { - nLevels = (int)dsInfo.getDimensions()[0]; - nRows = (int)dsInfo.getDimensions()[1]; - nCols = (int)dsInfo.getDimensions()[2]; - isRGB = true; - } else { - IJ.error( dsetName + ": rank " + rank + " of type " + typeText + " not supported (yet)"); - return null; - } - - nBits = assignHDF5TypeToImagePlusBitdepth( typeText, isRGB); - - - imp = IJ.createHyperStack( filename + ": " + dsetName, - nCols, nRows, nChannels, nLevels, nFrames, nBits); - imp.getCalibration().pixelDepth = element_size_um[0]; - imp.getCalibration().pixelHeight = element_size_um[1]; - imp.getCalibration().pixelWidth = element_size_um[2]; - imp.getCalibration().setUnit("micrometer"); - imp.setDisplayRange(0,255); - } - - // copy slices to hyperstack - int sliceSize = nCols * nRows; - - if (typeText.equals( "uint8") && isRGB == false) { - MDByteArray rawdata = reader.uint8().readMDArray(dsetName); - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, - (byte[])ip.getPixels(), 0, - sliceSize); - } - maxGray = 255; - } else if (typeText.equals( "uint8") && isRGB) { // RGB data - MDByteArray rawdata = reader.uint8().readMDArray(dsetName); - byte[] srcArray = rawdata.getAsFlatArray(); - - - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - int[] trgArray = (int[])ip.getPixels(); - int srcOffset = lev*sliceSize*3; - - for( int rc = 0; rc < sliceSize; ++rc) - { - int red = srcArray[srcOffset + rc*3] & 0xff; - int green = srcArray[srcOffset + rc*3 + 1] & 0xff; - int blue = srcArray[srcOffset + rc*3 + 2] & 0xff; - trgArray[rc] = (red<<16) + (green<<8) + blue; - } - - } - maxGray = 255; - - } else if (typeText.equals( "uint16")) { - MDShortArray rawdata = reader.uint16().readMDArray(dsetName); - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, - (short[])ip.getPixels(), 0, - sliceSize); - } - short[] data = rawdata.getAsFlatArray(); - for (int i = 0; i < data.length; ++i) { - if (data[i] > maxGray) maxGray = data[i]; - } - } else if (typeText.equals( "int16")) { - MDShortArray rawdata = reader.int16().readMDArray(dsetName); - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, - (short[])ip.getPixels(), 0, - sliceSize); - } - short[] data = rawdata.getAsFlatArray(); - for (int i = 0; i < data.length; ++i) { - if (data[i] > maxGray) maxGray = data[i]; - } - } else if (typeText.equals( "float32") || typeText.equals( "float64") ) { - MDFloatArray rawdata = reader.float32().readMDArray(dsetName); - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, - (float[])ip.getPixels(), 0, - sliceSize); - } - float[] data = rawdata.getAsFlatArray(); - for (int i = 0; i < data.length; ++i) { - if (data[i] > maxGray) maxGray = data[i]; - } - } - } - } - reader.close(); - - // aqdjust max gray - for( int c = 1; c <= nChannels; ++c) - { - imp.setC(c); - imp.setDisplayRange(0,maxGray); - } - - imp.setC(1); - - if (show) { - try { - imp.show(); - } - catch (HeadlessException herr) {} - } - return imp; - } - - catch (HDF5Exception err) - { - IJ.error("Error while opening '" + filename - + "', dataset '" + dsetName + "':\n" - + err); - } - catch (Exception err) - { - IJ.error("Error while opening '" + filename - + "', dataset '" + dsetName + "':\n" - + err); - } - catch (OutOfMemoryError o) - { - IJ.outOfMemory("Load HDF5"); - } - return null; - - } - - static ImagePlus loadCustomLayoutDataSetToHyperStack( String filename, String dsetName, String layout) { - return loadCustomLayoutDataSetToHyperStack(filename, dsetName, layout, true); - } - - //----------------------------------------------------------------------------- - // - // Layout: any order of the letters x,y,z,c,t as string, e.g. "zyx" for a standard volumetric data set - // - static ImagePlus loadCustomLayoutDataSetToHyperStack( String filename, String dsetName, String layout, boolean show) { - try - { - IHDF5ReaderConfigurator conf = HDF5Factory.configureForReading(filename); - conf.performNumericConversions(); - IHDF5Reader reader = conf.reader(); - ImagePlus imp = null; - - // get datat set info and check layout string - // - IJ.showStatus( "Loading " + dsetName); - // IJ.showProgress( frame*nChannels+channel+1, nFrames*nChannels); - HDF5DataSetInformation dsInfo = reader.object().getDataSetInformation(dsetName); - float[] element_size_um = {1,1,1}; - try { - element_size_um = reader.float32().getArrayAttr(dsetName, "element_size_um"); - } - catch (HDF5Exception err) { - IJ.log("Warning: Can't read attribute 'element_size_um' from file '" + filename - + "', dataset '" + dsetName + "':\n" - + err + "\n" - + "Assuming element size of 1 x 1 x 1 um^3"); - } - - int rank = dsInfo.getRank(); - String typeText = dsInfoToTypeString(dsInfo); - - if( rank != layout.length()) { - IJ.error( dsetName + ": rank " + rank + " is incompatible with your given layout string '" + layout +"' (rank " + layout.length() + ")"); - return null; - } - - - // compute dset stride (element-to-element offset in the linear array) - // - long[] dsetExtent = dsInfo.getDimensions(); - int[] stride = new int[rank]; - stride[rank-1] = 1; - for (int d = rank-2; d >= 0; --d) { - stride[d] = (int)dsetExtent[d+1] * stride[d+1]; - } - - // interpret layout string and get assigned data set extents - // - int nLevels = 1; - int nRows = 1; - int nCols = 1; - int nFrames = 1; - int nChannels = 1; - int levelToLevelOffset = 0; - int rowToRowOffset = 0; - int colToColOffset = 0; - int frameToFrameOffset = 0; - int channelToChannelOffset = 0; - - int nBits = 0; - double maxGray = 1; - - // - for (int d = 0; d < rank; ++d) { - switch( layout.charAt(d)) { - case 'x': nCols = (int)dsetExtent[d]; colToColOffset = stride[d]; break; - case 'y': nRows = (int)dsetExtent[d]; rowToRowOffset = stride[d]; break; - case 'z': nLevels = (int)dsetExtent[d]; levelToLevelOffset = stride[d]; break; - case 'c': nChannels = (int)dsetExtent[d]; channelToChannelOffset = stride[d]; break; - case 't': nFrames = (int)dsetExtent[d]; frameToFrameOffset = stride[d]; break; - default: - IJ.error( "your given layout string '" + layout +"' contains the illegal character '" + layout.charAt(d) + "'. Allowed characters are 'xyzct'"); - return null; - } - } - - // create appropriate hyperstack - // - IJ.log("Creating hyperstack with " + nFrames + " frames, " - + nChannels + " channels, " - + nLevels + " levels, " - + nRows + " rows, and " - + nCols + " cols"); - - boolean isRGB = false; - nBits = assignHDF5TypeToImagePlusBitdepth( typeText, isRGB); - imp = IJ.createHyperStack( filename + ": " + dsetName, - nCols, nRows, nChannels, nLevels, nFrames, nBits); - imp.getCalibration().pixelDepth = element_size_um[0]; - imp.getCalibration().pixelHeight = element_size_um[1]; - imp.getCalibration().pixelWidth = element_size_um[2]; - imp.getCalibration().setUnit("micrometer"); - imp.setDisplayRange(0,255); - - - // load data set and copy it to hyperstack - // - if (typeText.equals( "uint8") ) { - byte[] rawdata = reader.uint8().readMDArray(dsetName).getAsFlatArray(); - for( int frame = 0; frame < nFrames; ++frame) { - for( int channel = 0; channel < nChannels; ++channel) { - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - for( int row = 0; row < nRows; ++row) { - byte[] trgData = (byte[])ip.getPixels(); - int trgOffset = row * nCols; - int srcOffset = - frame * frameToFrameOffset - + channel * channelToChannelOffset - + lev * levelToLevelOffset - + row * rowToRowOffset; - for( int col = 0; col < nCols; ++col) { - trgData[trgOffset] = rawdata[srcOffset]; - ++trgOffset; - srcOffset += colToColOffset; - } - } - } - } - } - maxGray = 255; - } - else if (typeText.equals( "uint16") ) { - short[] rawdata = reader.uint16().readMDArray(dsetName).getAsFlatArray(); - for( int frame = 0; frame < nFrames; ++frame) { - for( int channel = 0; channel < nChannels; ++channel) { - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - for( int row = 0; row < nRows; ++row) { - short[] trgData = (short[])ip.getPixels(); - int trgOffset = row * nCols; - int srcOffset = - frame * frameToFrameOffset - + channel * channelToChannelOffset - + lev * levelToLevelOffset - + row * rowToRowOffset; - for( int col = 0; col < nCols; ++col) { - trgData[trgOffset] = rawdata[srcOffset]; - ++trgOffset; - srcOffset += colToColOffset; - } - } - } - } - } - for (int i = 0; i < rawdata.length; ++i) { - if (rawdata[i] > maxGray) maxGray = rawdata[i]; - } - } - else if (typeText.equals( "int16") ) { - short[] rawdata = reader.int16().readMDArray(dsetName).getAsFlatArray(); - for( int frame = 0; frame < nFrames; ++frame) { - for( int channel = 0; channel < nChannels; ++channel) { - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - for( int row = 0; row < nRows; ++row) { - short[] trgData = (short[])ip.getPixels(); - int trgOffset = row * nCols; - int srcOffset = - frame * frameToFrameOffset - + channel * channelToChannelOffset - + lev * levelToLevelOffset - + row * rowToRowOffset; - for( int col = 0; col < nCols; ++col) { - trgData[trgOffset] = rawdata[srcOffset]; - ++trgOffset; - srcOffset += colToColOffset; - } - } - } - } - } - for (int i = 0; i < rawdata.length; ++i) { - if (rawdata[i] > maxGray) maxGray = rawdata[i]; - } - } - else if (typeText.equals( "float32") || typeText.equals( "float64") ) { - float[] rawdata = reader.float32().readMDArray(dsetName).getAsFlatArray(); - for( int frame = 0; frame < nFrames; ++frame) { - for( int channel = 0; channel < nChannels; ++channel) { - for( int lev = 0; lev < nLevels; ++lev) { - ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( - channel+1, lev+1, frame+1)); - for( int row = 0; row < nRows; ++row) { - float[] trgData = (float[])ip.getPixels(); - int trgOffset = row * nCols; - int srcOffset = - frame * frameToFrameOffset - + channel * channelToChannelOffset - + lev * levelToLevelOffset - + row * rowToRowOffset; - for( int col = 0; col < nCols; ++col) { - trgData[trgOffset] = rawdata[srcOffset]; - ++trgOffset; - srcOffset += colToColOffset; - } - } - } - } - } - for (int i = 0; i < rawdata.length; ++i) { - if (rawdata[i] > maxGray) maxGray = rawdata[i]; - } - } - - - - -// int sliceSize = nCols * nRows; -// -// if (typeText.equals( "uint8") && rank < 4) { -// MDByteArray rawdata = reader.uint8().readMDArray(dsetName); -// for( int lev = 0; lev < nLevels; ++lev) { -// ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( -// channel+1, lev+1, frame+1)); -// System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, -// (byte[])ip.getPixels(), 0, -// sliceSize); -// } -// maxGray = 255; -// } else if (typeText.equals( "uint8") && rank == 4) { // RGB data -// MDByteArray rawdata = reader.uint8().readMDArray(dsetName); -// byte[] srcArray = rawdata.getAsFlatArray(); -// -// -// for( int lev = 0; lev < nLevels; ++lev) { -// ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( -// channel+1, lev+1, frame+1)); -// int[] trgArray = (int[])ip.getPixels(); -// int srcOffset = lev*sliceSize*3; -// -// for( int rc = 0; rc < sliceSize; ++rc) -// { -// int red = srcArray[srcOffset + rc*3]; -// int green = srcArray[srcOffset + rc*3 + 1]; -// int blue = srcArray[srcOffset + rc*3 + 2]; -// trgArray[rc] = (red<<16) + (green<<8) + blue; -// } -// -// } -// maxGray = 255; -// -// } else if (typeText.equals( "uint16")) { -// MDShortArray rawdata = reader.uint16().readMDArray(dsetName); -// for( int lev = 0; lev < nLevels; ++lev) { -// ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( -// channel+1, lev+1, frame+1)); -// System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, -// (short[])ip.getPixels(), 0, -// sliceSize); -// } -// short[] data = rawdata.getAsFlatArray(); -// for (int i = 0; i < data.length; ++i) { -// if (data[i] > maxGray) maxGray = data[i]; -// } -// } else if (typeText.equals( "int16")) { -// MDShortArray rawdata = reader.int16().readMDArray(dsetName); -// for( int lev = 0; lev < nLevels; ++lev) { -// ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( -// channel+1, lev+1, frame+1)); -// System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, -// (short[])ip.getPixels(), 0, -// sliceSize); -// } -// short[] data = rawdata.getAsFlatArray(); -// for (int i = 0; i < data.length; ++i) { -// if (data[i] > maxGray) maxGray = data[i]; -// } -// } else if (typeText.equals( "float32") || typeText.equals( "float64") ) { -// MDFloatArray rawdata = reader.float32().readMDArray(dsetName); -// for( int lev = 0; lev < nLevels; ++lev) { -// ImageProcessor ip = imp.getStack().getProcessor( imp.getStackIndex( -// channel+1, lev+1, frame+1)); -// System.arraycopy( rawdata.getAsFlatArray(), lev*sliceSize, -// (float[])ip.getPixels(), 0, -// sliceSize); -// } -// float[] data = rawdata.getAsFlatArray(); -// for (int i = 0; i < data.length; ++i) { -// if (data[i] > maxGray) maxGray = data[i]; -// } -// } -// } -// } - - - reader.close(); - - // aqdjust max gray - imp.setDisplayRange(0,maxGray); - if (show) { - try { - imp.show(); - } - catch (HeadlessException herr) {} - } - return imp; - } - - catch (HDF5Exception err) - { - IJ.error("Error while opening '" + filename - + "', dataset '" + dsetName + "':\n" - + err); - } - catch (Exception err) - { - IJ.error("Error while opening '" + filename - + "', dataset '" + dsetName + "':\n" - + err); - } - catch (OutOfMemoryError o) - { - IJ.outOfMemory("Load HDF5"); - } - return null; - - } - - - //----------------------------------------------------------------------------- - static void saveHyperStack( ImagePlus imp, String filename, String dsetNameTemplate, - String formatTime, String formatChannel, int compressionLevel, - String saveMode) - { - int nFrames = imp.getNFrames(); - int nChannels = imp.getNChannels(); - int nLevs = imp.getNSlices(); - int nRows = imp.getHeight(); - int nCols = imp.getWidth(); - - // Name stubs for time points and channels - String[] substT = HDF5ImageJ.createNameList( formatTime, nFrames); - String[] substC = HDF5ImageJ.createNameList( formatChannel, nChannels); - - // - // Open output file - // - try - { - IHDF5Writer writer; - if( saveMode.equals( "append")) - { - writer = HDF5Factory.configure(filename).useSimpleDataSpaceForAttributes().writer(); - } - else - { - writer = HDF5Factory.configure(filename).useSimpleDataSpaceForAttributes().overwrite().writer(); - } - - // get element_size_um - // - ij.measure.Calibration cal = imp.getCalibration(); - float[] element_size_um = new float[3]; - element_size_um[0] = (float) cal.pixelDepth; - element_size_um[1] = (float) cal.pixelHeight; - element_size_um[2] = (float) cal.pixelWidth; - - // create channelDims vector for MDxxxArray - // - long[] channelDims = null; - if (nLevs > 1) - { - channelDims = new long[3]; - channelDims[0] = nLevs; - channelDims[1] = nRows; - channelDims[2] = nCols; - } - else - { - channelDims = new long[2]; - channelDims[0] = nRows; - channelDims[1] = nCols; - } - - - // - // loop through frames and channels - // - for( int t=0; t < nFrames; ++t) - { - for( int c=0; c < nChannels; ++c) - { - // format the data set name - // - String dsetName = dsetNameTemplate; - dsetName = dsetName.replace("{t}", substT[t]); - dsetName = dsetName.replace("{c}", substC[c]); - - System.out.println( "t="+t+",c="+c+" --> "+dsetName); - - // write Stack according to data type - // - int imgColorType = imp.getType(); - - if (imgColorType == ImagePlus.GRAY8 - || imgColorType == ImagePlus.COLOR_256 ) - { - // Save as Byte Array - // - MDByteArray arr = new MDByteArray( channelDims); - // copy data - // - ImageStack stack = imp.getStack(); - byte[] flatArr = arr.getAsFlatArray(); - int sliceSize = nRows*nCols; - - for(int lev = 0; lev < nLevs; ++lev) - { - int stackIndex = imp.getStackIndex(c + 1, - lev + 1, - t + 1); - System.arraycopy( stack.getPixels(stackIndex), 0, - flatArr, lev*sliceSize, - sliceSize); - } - - // save it - // - writer.uint8().writeMDArray( dsetName, arr, HDF5IntStorageFeatures.createDeflationDelete(compressionLevel)); - } - else if (imgColorType == ImagePlus.GRAY16) - { - // Save as Short Array - // - MDShortArray arr = new MDShortArray( channelDims); - - // copy data - // - ImageStack stack = imp.getStack(); - short[] flatArr = arr.getAsFlatArray(); - int sliceSize = nRows*nCols; - - for(int lev = 0; lev < nLevs; ++lev) - { - int stackIndex = imp.getStackIndex(c + 1, - lev + 1, - t + 1); - System.arraycopy( stack.getPixels(stackIndex), 0, - flatArr, lev*sliceSize, - sliceSize); - } - - // save it - // - writer.uint16().writeMDArray( dsetName, arr, HDF5IntStorageFeatures.createDeflationDelete(compressionLevel)); - } - else if (imgColorType == ImagePlus.GRAY32) - { - // Save as Float Array - // - MDFloatArray arr = new MDFloatArray( channelDims); - - // copy data - // - ImageStack stack = imp.getStack(); - float[] flatArr = arr.getAsFlatArray(); - int sliceSize = nRows*nCols; - - for(int lev = 0; lev < nLevs; ++lev) - { - int stackIndex = imp.getStackIndex(c + 1, - lev + 1, - t + 1); - System.arraycopy( stack.getPixels(stackIndex), 0, - flatArr, lev*sliceSize, - sliceSize); - } - - // save it - // - writer.float32().writeMDArray( dsetName, arr, - HDF5FloatStorageFeatures.createDeflationDelete( - compressionLevel)); - } - else if (imgColorType == ImagePlus.COLOR_RGB) - { - // Save RGB as Byte Array with additional dimension - // - long[] channelDimsRGB = null; - if (nLevs > 1) - { - channelDimsRGB = new long[4]; - channelDimsRGB[0] = nLevs; - channelDimsRGB[1] = nRows; - channelDimsRGB[2] = nCols; - channelDimsRGB[3] = 3; - } - else - { - channelDimsRGB = new long[3]; - channelDimsRGB[0] = nRows; - channelDimsRGB[1] = nCols; - channelDimsRGB[2] = 3; - } - MDByteArray arr = new MDByteArray( channelDimsRGB); - - // copy data - // - ImageStack stack = imp.getStack(); - byte[] flatArr = arr.getAsFlatArray(); - int sliceSize = nRows*nCols; - - for(int lev = 0; lev < nLevs; ++lev) - { - int stackIndex = imp.getStackIndex(c + 1, - lev + 1, - t + 1); - - ColorProcessor cp = (ColorProcessor)(stack.getProcessor(stackIndex)); - byte[] red = cp.getChannel(1); - byte[] green = cp.getChannel(2); - byte[] blue = cp.getChannel(3); - - int offset = lev*sliceSize*3; - for( int i=0; i < sliceSize; ++i) - { - flatArr[offset+3*i+0] = red[i]; - flatArr[offset+3*i+1] = green[i]; - flatArr[offset+3*i+2] = blue[i]; - } - - } - - // save it - // - writer.uint8().writeMDArray( dsetName, arr, HDF5IntStorageFeatures.createDeflationDelete(compressionLevel)); - - - } - - - // add element_size_um attribute - // - writer.float32().setArrayAttr( dsetName, "element_size_um", - element_size_um); - - - } - } - writer.close(); - } - - - catch (HDF5Exception err) - { - IJ.error("Error while saving '" + filename + "':\n" - + err); - } - catch (Exception err) - { - IJ.error("Error while saving '" + filename + "':\n" - + err); - } - catch (OutOfMemoryError o) - { - IJ.outOfMemory("Error while saving '" + filename + "'"); - } - } - - - - - //----------------------------------------------------------------------------- - static String dsInfoToTypeString( HDF5DataSetInformation dsInfo) { - HDF5DataTypeInformation dsType = dsInfo.getTypeInformation(); - String typeText = ""; - - if (dsType.isSigned() == false) { - typeText += "u"; - } - - switch( dsType.getDataClass()) - { - case INTEGER: - typeText += "int" + 8*dsType.getElementSize(); - break; - case FLOAT: - typeText += "float" + 8*dsType.getElementSize(); - break; - default: - typeText += dsInfo.toString(); - } - return typeText; - } - - //----------------------------------------------------------------------------- - static int assignHDF5TypeToImagePlusBitdepth( String type, boolean isRGB) { - int nBits = 0; - if (type.equals("uint8")) { - if( isRGB ) { - nBits = 24; - } else { - nBits = 8; - } - } else if (type.equals("uint16") || type.equals("int16")) { - nBits = 16; - } else if (type.equals("float32") || type.equals("float64")) { - nBits = 32; - } else { - IJ.error("Type '" + type + "' Not handled yet!"); - } - return nBits; - } - - - //----------------------------------------------------------------------------- - static String[] createNameList( String formatString, int nElements) - { - String[] nameList = new String[nElements]; - if( formatString.startsWith("%")) - { - for( int i=0; i < nElements; ++i) - { - nameList[i] = String.format(formatString, i); - } - } - else - { - String[] tokens = formatString.split("[,\\s]+"); - if( tokens.length >= nElements) - { - nameList = tokens; - } - else - { - IJ.log( "Warning: format-list \"" + formatString + "\" contains only " + tokens.length - + " tokens, but yout dataset needs " + nElements + " unique entries! " - + "Appending numbers \"" + tokens.length + "\" to \"" + (nElements-1) + "\"!"); - for( int i = 0; i < tokens.length; ++i) - { - nameList[i] = tokens[i]; - } - for( int i = tokens.length; i < nElements; ++i) - { - nameList[i] = String.format( "%d",i); - } - } - } - return nameList; - } -} - diff --git a/src/test/java/develop/OpenBdvHDF5.java b/src/test/java/develop/OpenBdvHDF5.java new file mode 100644 index 00000000..12091ef0 --- /dev/null +++ b/src/test/java/develop/OpenBdvHDF5.java @@ -0,0 +1,25 @@ +package develop; + +import bdv.cache.SharedQueue; +import bdv.util.BdvFunctions; +import bdv.viewer.Source; +import net.imglib2.Volatile; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Pair; +import org.embl.mobie.io.imagedata.BDVXMLImageData; + +public class OpenBdvHDF5 +{ + public static < T extends NumericType< T > & NativeType< T > > void main( String[] args ) + { + BDVXMLImageData< T > imageData = new BDVXMLImageData<>( + "/Users/tischer/Desktop/bdv/mri.xml", + new SharedQueue( Math.max( 1, Runtime.getRuntime().availableProcessors() / 2 ) ) + ); + + Pair< Source< T >, Source< ? extends Volatile< T > > > sourcePair = imageData.getSourcePair( 0 ); + + BdvFunctions.show( sourcePair.getB() ); + } +} diff --git a/src/test/java/develop/OpenBdvN5S3.java b/src/test/java/develop/OpenBdvN5S3.java new file mode 100644 index 00000000..e6fe7518 --- /dev/null +++ b/src/test/java/develop/OpenBdvN5S3.java @@ -0,0 +1,28 @@ +package develop; + +import bdv.cache.SharedQueue; +import bdv.util.BdvFunctions; +import bdv.viewer.Source; +import net.imglib2.Volatile; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import net.imglib2.util.Pair; +import org.embl.mobie.io.ImageDataFormat; +import org.embl.mobie.io.ImageDataOpener; +import org.embl.mobie.io.imagedata.BDVXMLImageData; +import org.embl.mobie.io.imagedata.ImageData; + +public class OpenBdvN5S3 +{ + public static < T extends NumericType< T > & NativeType< T > > void main( String[] args ) + { + ImageData< T > imageData = ImageDataOpener.open( + "https://raw.githubusercontent.com/mobie/platybrowser-project/main/data/1.0.1/images/remote/sbem-6dpf-1-whole-raw.xml", + ImageDataFormat.BdvN5S3, + new SharedQueue( Math.max( 1, Runtime.getRuntime().availableProcessors() / 2 ) ) ); + + Pair< Source< T >, Source< ? extends Volatile< T > > > sourcePair = imageData.getSourcePair( 0 ); + + BdvFunctions.show( sourcePair.getB() ); + } +} diff --git a/src/test/java/develop/OpenIlastikHDF5.java b/src/test/java/develop/OpenIlastikHDF5.java deleted file mode 100644 index 33252164..00000000 --- a/src/test/java/develop/OpenIlastikHDF5.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package develop; - -import bdv.util.BdvFunctions; -import net.imglib2.RandomAccessibleInterval; -import org.embl.mobie.io.CachedCellImgOpener; -import org.embl.mobie.io.ImageDataFormat; - -import java.io.IOException; - -public class OpenIlastikHDF5 -{ - public static void main( String[] args ) throws IOException - { - final CachedCellImgOpener< ? > opener = new CachedCellImgOpener( "/Users/tischer/Downloads/export.h5", ImageDataFormat.IlastikHDF5, null ); - final RandomAccessibleInterval< ? > rai = opener.getRAI( 0 ); - final RandomAccessibleInterval< ? > vRAI = opener.getVolatileRAI( 0 ); - BdvFunctions.show( rai, "sfsd" ); - } -} diff --git a/src/test/java/develop/OpenOMEZarr.java b/src/test/java/develop/OpenOMEZarr.java deleted file mode 100644 index ff692382..00000000 --- a/src/test/java/develop/OpenOMEZarr.java +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package develop; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.generic.AbstractSpimData; -import org.embl.mobie.io.ImageDataFormat; -import org.embl.mobie.io.SpimDataOpener; - -public class OpenOMEZarr -{ - public static void main( String[] args ) throws SpimDataException - { - final AbstractSpimData spimData = new SpimDataOpener().open( "https://s3.embl.de/ome-zarr-course/ome_zarr_data/xyzct_8bit__mitosis.zarr", ImageDataFormat.OmeZarrS3 ); - BdvFunctions.show( spimData ); - } -} diff --git a/src/test/java/develop/OpenOMEZarrAsN5ImageData.java b/src/test/java/develop/OpenOMEZarrAsN5ImageData.java new file mode 100644 index 00000000..7c6127f5 --- /dev/null +++ b/src/test/java/develop/OpenOMEZarrAsN5ImageData.java @@ -0,0 +1,26 @@ +package develop; + +import bdv.cache.SharedQueue; +import bdv.util.BdvFunctions; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.embl.mobie.io.imagedata.N5ImageData; + +import java.io.IOException; +import java.net.URISyntaxException; + +public class OpenOMEZarrAsN5ImageData +{ + public static < T extends NumericType< T > & NativeType< T > > void main( String[] args ) throws IOException, URISyntaxException + { + N5ImageData< T > imageData = new N5ImageData<>( + "https://s3.embl.de/i2k-2020/platy-raw.ome.zarr", + new SharedQueue( Math.max( 1, Runtime.getRuntime().availableProcessors() / 2 ) ) + ); + + BdvFunctions.show( + imageData.getSourcesAndConverters(), + imageData.getNumTimepoints(), + imageData.getBdvOptions()); + } +} diff --git a/src/test/java/develop/OpenOMEZarrWithN5Viewer.java b/src/test/java/develop/OpenOMEZarrWithN5Viewer.java new file mode 100644 index 00000000..6564df5f --- /dev/null +++ b/src/test/java/develop/OpenOMEZarrWithN5Viewer.java @@ -0,0 +1,50 @@ +package develop; + +import bdv.cache.SharedQueue; +import bdv.tools.brightness.ConverterSetup; +import bdv.util.BdvFunctions; +import bdv.util.BdvOptions; +import bdv.viewer.SourceAndConverter; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.NumericType; +import org.janelia.saalfeldlab.n5.N5Reader; +import org.janelia.saalfeldlab.n5.N5URI; +import org.janelia.saalfeldlab.n5.bdv.N5Viewer; +import org.janelia.saalfeldlab.n5.ui.DataSelection; +import org.janelia.saalfeldlab.n5.universe.N5Factory; +import org.janelia.saalfeldlab.n5.universe.N5MetadataUtils; +import org.janelia.saalfeldlab.n5.universe.metadata.N5Metadata; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class OpenOMEZarrWithN5Viewer +{ + public static & NativeType > void main( String[] args ) throws IOException, URISyntaxException + { + N5URI uri = new N5URI( "https://s3.embl.de/i2k-2020/platy-raw.ome.zarr" ); + String containerPath = uri.getContainerPath(); + String group = uri.getGroupPath() != null ? uri.getGroupPath() : "/"; + N5Reader n5 = new N5Factory().openReader( containerPath ); + List< N5Metadata > metadata = Collections.singletonList( N5MetadataUtils.parseMetadata( n5, group ) ); + + final DataSelection selection = new DataSelection(n5, metadata); + final SharedQueue sharedQueue = new SharedQueue(Math.max(1, Runtime.getRuntime().availableProcessors() / 2)); + final List< ConverterSetup > converterSetups = new ArrayList<>(); + final List< SourceAndConverter > sourcesAndConverters = new ArrayList<>(); + final BdvOptions options = BdvOptions.options().frameTitle("N5 Viewer"); + + int numTimepoints = N5Viewer.buildN5Sources( + n5, + selection, + sharedQueue, + converterSetups, + sourcesAndConverters, + options ); + + BdvFunctions.show(sourcesAndConverters, numTimepoints, options); + } +} diff --git a/src/test/java/develop/OpenTOML.java b/src/test/java/develop/OpenTOML.java index 28d455a5..decad083 100644 --- a/src/test/java/develop/OpenTOML.java +++ b/src/test/java/develop/OpenTOML.java @@ -28,9 +28,7 @@ */ package develop; -import bdv.util.BdvFunctions; import ij.ImagePlus; -import mpicbg.spim.data.generic.AbstractSpimData; import org.embl.mobie.io.toml.TOMLOpener; public class OpenTOML @@ -39,10 +37,10 @@ public static void main( String[] args ) { final TOMLOpener opener = new TOMLOpener( "/Volumes/cba/exchange/kristina-mirkes/develop/data-test/processed/exp/batch/date/MVI_1253/exp--batch--date--mvi_1253.image.toml" ); - //final ImagePlus imagePlus = opener.asImagePlus(); - //imagePlus.show(); + final ImagePlus imagePlus = opener.openImagePlus(); + imagePlus.show(); - final AbstractSpimData< ? > spimData = opener.asSpimData(); - BdvFunctions.show( spimData ); +// final AbstractSpimData< ? > spimData = opener.asSpimData(); +// BdvFunctions.show( spimData ); } } diff --git a/src/test/java/develop/WriteOMEZarr.java b/src/test/java/develop/WriteOMEZarr.java new file mode 100644 index 00000000..fe788fe1 --- /dev/null +++ b/src/test/java/develop/WriteOMEZarr.java @@ -0,0 +1,42 @@ +package develop; + +import ij.IJ; +import ij.ImagePlus; +import org.embl.mobie.io.OMEZarrWriter; +import org.janelia.saalfeldlab.n5.GzipCompression; +import org.janelia.saalfeldlab.n5.N5FSWriter; +import org.janelia.saalfeldlab.n5.ij.N5IJUtils; +import org.janelia.saalfeldlab.n5.ij.N5Importer; +import org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter; + +import java.io.IOException; + +import static org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter.GZIP_COMPRESSION; +import static org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter.ZARR_FORMAT; + +public class WriteOMEZarr +{ + public static void main( String[] args ) + { + ImagePlus imp = IJ.openImage( "http://imagej.net/images/mri-stack.zip" ); + + N5ScalePyramidExporter exporter = new N5ScalePyramidExporter( + imp, + "src/test/output/mri.ome.zarr", + "/", + ZARR_FORMAT, + "10,10,4", + true, + N5ScalePyramidExporter.DOWNSAMPLE_METHOD.Average, + N5Importer.MetadataOmeZarrKey, + GZIP_COMPRESSION + ); + + exporter.run(); + + OMEZarrWriter.write( imp, + "src/test/output/mri2.zarr", + OMEZarrWriter.ImageType.Intensities, + true ); + } +} diff --git a/src/test/java/i2k2020/OpenBDVN5S3XML.java b/src/test/java/i2k2020/OpenBDVN5S3XML.java deleted file mode 100644 index 650e6d8f..00000000 --- a/src/test/java/i2k2020/OpenBDVN5S3XML.java +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package i2k2020; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.XmlIoSpimData; - -public class OpenBDVN5S3XML { - public static void main(String[] args) throws SpimDataException { - SpimData spimData = new XmlIoSpimData().load("src/test/resources/prospr-myosin-n5.xml"); - BdvFunctions.show(spimData); - } -} diff --git a/src/test/java/i2k2020/OpenOMEZarrS3.java b/src/test/java/i2k2020/OpenOMEZarrS3.java deleted file mode 100644 index e7666166..00000000 --- a/src/test/java/i2k2020/OpenOMEZarrS3.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package i2k2020; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.XmlIoSpimData; - -public class OpenOMEZarrS3 { - public static void main(String[] args) throws SpimDataException { - // Note: this requires the native blosc library - // Tischi: for me on my Mac it worked copying libblosc.dylib from Fiji into /src/main/resources - SpimData spimData = new XmlIoSpimData().load("src/test/resources/prospr-myosin-zarr.xml"); - BdvFunctions.show(spimData); - } -} diff --git a/src/test/java/i2k2020/OpenOMEZarrS3XML.java b/src/test/java/i2k2020/OpenOMEZarrS3XML.java deleted file mode 100644 index 948a70c7..00000000 --- a/src/test/java/i2k2020/OpenOMEZarrS3XML.java +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package i2k2020; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; -import mpicbg.spim.data.XmlIoSpimData; - -public class OpenOMEZarrS3XML { - public static void main(String[] args) throws SpimDataException { - // Note: this requires the native blosc library - // Tischi: for me on my Mac it worked copying libblosc.dylib from Fiji into /src/main/resources - SpimData spimData = new XmlIoSpimData().load("src/test/resources/prospr-myosin-zarr.xml"); - BdvFunctions.show(spimData); - } -} diff --git a/src/test/java/i2k2020/S3Transfer.java b/src/test/java/i2k2020/S3Transfer.java deleted file mode 100644 index bcaaea28..00000000 --- a/src/test/java/i2k2020/S3Transfer.java +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package i2k2020; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - - - - -public class S3Transfer { - - /** - * -bash-4.2$ ls /g/arendt/EM_6dpf_segmentation/platy-browser-data/data/rawdata/sbem-6dpf-1-whole-raw.n5/setup0/timepoint0/s1 - * 0 107 116 125 134 143 23 32 41 50 6 69 78 87 96 - * 1 108 117 126 135 15 24 33 42 51 60 7 79 88 97 - * 10 109 118 127 136 16 25 34 43 52 61 70 8 89 98 - * 100 11 119 128 137 17 26 35 44 53 62 71 80 9 99 - * 101 110 12 129 138 18 27 36 45 54 63 72 81 90 attributes.json - * 102 111 120 13 139 19 28 37 46 55 64 73 82 91 - * 103 112 121 130 14 2 29 38 47 56 65 74 83 92 - * 104 113 122 131 140 20 3 39 48 57 66 75 84 93 - * 105 114 123 132 141 21 30 4 49 58 67 76 85 94 - * 106 115 124 133 142 22 31 40 5 59 68 77 86 95 - *

- * start from 94 inclusive - *

- * -bash-4.2$ ls /g/arendt/EM_6dpf_segmentation/platy-browser-data/data/rawdata/sbem-6dpf-1-whole-raw.n5/setup0/timepoint0/s0 - * 0 117 136 155 174 193 211 230 25 269 3 49 68 87 - * 1 118 137 156 175 194 212 231 250 27 30 5 69 88 - * 10 119 138 157 176 195 213 232 251 270 31 50 7 89 - * 100 12 139 158 177 196 214 233 252 271 32 51 70 9 - * 101 120 14 159 178 197 215 234 253 272 33 52 71 90 - * 102 121 140 16 179 198 216 235 254 273 34 53 72 91 - * 103 122 141 160 18 199 217 236 255 274 35 54 73 92 - * 104 123 142 161 180 2 218 237 256 275 36 55 74 93 - * 105 124 143 162 181 20 219 238 257 276 37 56 75 94 - * 106 125 144 163 182 200 22 239 258 277 38 57 76 95 - * 107 126 145 164 183 201 220 24 259 278 39 58 77 96 - * 108 127 146 165 184 202 221 240 26 279 4 59 78 97 - * 109 128 147 166 185 203 222 241 260 28 40 6 79 98 - * 11 129 148 167 186 204 223 242 261 280 41 60 8 99 - * 110 13 149 168 187 205 224 243 262 281 42 61 80 attributes.json - * 111 130 15 169 188 206 225 244 263 282 43 62 81 - * 112 131 150 17 189 207 226 245 264 283 44 63 82 - * 113 132 151 170 19 208 227 246 265 284 45 64 83 - * 114 133 152 171 190 209 228 247 266 285 46 65 84 - * 115 134 153 172 191 21 229 248 267 286 47 66 85 - * 116 135 154 173 192 210 23 249 268 29 48 67 86 - *

- * start from 142 inclusive - * - * @param args - */ - public static void main(String[] args) { - final String template = "sbatch -c 2 -t 48:00:00 --mem 16000 -e /g/cba/tischer/tmp/err_LEVEL_GROUP.txt -o /g/cba/tischer/tmp/out_LEVEL_GROUP.txt /g/cba/tischer/software/aws --profile tischi --endpoint-url=https://idr-ftp.openmicroscopy.org s3 cp --recursive /g/arendt/EM_6dpf_segmentation/platy-browser-data/data/rawdata/sbem-6dpf-1-whole-raw.n5/setup0/timepoint0/sLEVEL/GROUP s3://idr-upload/tischi/sbem-6dpf-1-whole-raw.n5/setup0/timepoint0/sLEVEL/GROUP"; - - // level 1, start "94", end 144 - // level 0, start "142", end 286 - List list = IntStream.range(0, 144).mapToObj(i -> String.valueOf(i)).collect(Collectors.toList()); - Collections.sort(list); - list.add("attributes.json"); - - IntStream.range(list.indexOf("94"), list.size()).forEach(i -> - { - String job = template.replace("LEVEL", "1").replace("GROUP", list.get(i)); - System.out.println(job); - }); - - // /g/cba/tischer/software/aws --profile tischi --endpoint-url=https://idr-ftp.openmicroscopy.org s3 sync /g/arendt/EM_6dpf_segmentation/platy-browser-data/data/rawdata/sbem-6dpf-1-whole-raw.n5/setup0/timepoint0/s1/94 s3://idr-upload/tischi/sbem-6dpf-1-whole-raw.n5/setup0/timepoint0/s1/94 - - - // sacct --format="JobID,State,CPUTime,MaxRSS" - // TODO: attributes.json => check whether it arrived (did the sync command work?) - } -} diff --git a/src/test/java/org/embl/mobie/io/OMEZarrWriterTest.java b/src/test/java/org/embl/mobie/io/OMEZarrWriterTest.java new file mode 100644 index 00000000..dff1e13b --- /dev/null +++ b/src/test/java/org/embl/mobie/io/OMEZarrWriterTest.java @@ -0,0 +1,34 @@ +package org.embl.mobie.io; + +import ij.IJ; +import ij.ImagePlus; +import org.embl.mobie.io.imagedata.ImageData; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.*; + +class OMEZarrWriterTest +{ + @Test + public void writeAndReadOMEZarr(@TempDir Path tempDir) + { + ImagePlus imp = IJ.createImage( "test", "8-bit ramp", 186, 226, 27 ); + + String uri = tempDir.resolve("test.zarr").toString(); + + OMEZarrWriter.write( imp, + uri, + OMEZarrWriter.ImageType.Intensities, + false ); + + ImageData< ? > imageData = ImageDataOpener.open( uri ); + + long dim0 = imageData.getSourcePair( 0 ).getB() + .getSource( 0, 0 ).dimension( 0 ); + + assertEquals( 186, dim0 ); + } +} \ No newline at end of file diff --git a/src/test/java/org/embl/mobie/io/imagedata/BDVXMLImageDataTest.java b/src/test/java/org/embl/mobie/io/imagedata/BDVXMLImageDataTest.java new file mode 100644 index 00000000..b206d68a --- /dev/null +++ b/src/test/java/org/embl/mobie/io/imagedata/BDVXMLImageDataTest.java @@ -0,0 +1,19 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import mpicbg.spim.data.sequence.VoxelDimensions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class BDVXMLImageDataTest +{ + @Test + public void openPlatybrowserBDVXMLN5() + { + BDVXMLImageData< ? > imageData = new BDVXMLImageData<>( "https://raw.githubusercontent.com/mobie/platybrowser-project/main/data/1.0.1/images/remote/sbem-6dpf-1-whole-raw.xml", new SharedQueue( 1 ) ); + VoxelDimensions voxelDimensions = imageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + +} \ No newline at end of file diff --git a/src/test/java/org/embl/mobie/io/imagedata/IlastikImageDataTest.java b/src/test/java/org/embl/mobie/io/imagedata/IlastikImageDataTest.java new file mode 100644 index 00000000..d5a6c20a --- /dev/null +++ b/src/test/java/org/embl/mobie/io/imagedata/IlastikImageDataTest.java @@ -0,0 +1,26 @@ +package org.embl.mobie.io.imagedata; + +import mpicbg.spim.data.sequence.VoxelDimensions; +import org.embl.mobie.io.ImageDataOpener; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class IlastikImageDataTest +{ + @Test + public void openIlastikSavedByFiji() + { + ImageData< ? > imageData = ImageDataOpener.open( "src/test/resources/ilastik/from-fiji.h5" ); + VoxelDimensions voxelDimensions = imageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + + @Test + public void openIlastikSavedByIlastik() + { + ImageData< ? > imageData = ImageDataOpener.open( "src/test/resources/ilastik/probabilities-from-ilastik.h5" ); + VoxelDimensions voxelDimensions = imageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + +} \ No newline at end of file diff --git a/src/test/java/org/embl/mobie/io/imagedata/N5ImageDataTest.java b/src/test/java/org/embl/mobie/io/imagedata/N5ImageDataTest.java new file mode 100644 index 00000000..ab8ab0a8 --- /dev/null +++ b/src/test/java/org/embl/mobie/io/imagedata/N5ImageDataTest.java @@ -0,0 +1,92 @@ +package org.embl.mobie.io.imagedata; + +import bdv.cache.SharedQueue; +import mpicbg.spim.data.sequence.VoxelDimensions; +import org.embl.mobie.io.ImageDataFormat; +import org.embl.mobie.io.ImageDataOpener; +import org.embl.mobie.io.util.S3Utils; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.jupiter.api.Assertions.*; + +class N5ImageDataTest +{ + // FIXME: https://imagesc.zulipchat.com/#narrow/stream/327326-BigDataViewer/topic/N5Viewer.20concurrency.20issues.3F + + @Test + public void openOMEZarrFromS3() + { + System.out.println("openOMEZarrFromS3"); + N5ImageData< ? > n5ImageData = new N5ImageData<>( "https://s3.embl.de/i2k-2020/platy-raw.ome.zarr" ); + VoxelDimensions voxelDimensions = n5ImageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + + @Test + public void openOMEZarrFromEBIS3() + { + System.out.println("openOMEZarrFromEBIS3"); + N5ImageData< ? > n5ImageData = new N5ImageData<>( "https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0138A/TimEmbryos-120919/HybCycle_29/MMStack_Pos0.ome.zarr" ); + VoxelDimensions voxelDimensions = n5ImageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + + @Test + public void openOMEZarrFromS3WithCredentials() + { + System.out.println("openOMEZarrFromS3WithCredentials"); + N5ImageData< ? > n5ImageData = new N5ImageData<>( + "https://s3.embl.de/mobie-credentials-test/test/images/ome-zarr/8kmont5.ome.zarr", + new String[]{ "4vJRUoUQZix2x7wPRlSy", "qtt7o93uv2PTvXSgYGMtoGtQkd3HsRqVH5XwitSf" }); + VoxelDimensions voxelDimensions = n5ImageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + + @Test + public void openOMEZarrFromS3WithCredentialsV2() + { + // This test uses the ImageDataOpener ( instead of directly N5ImageData ) + System.out.println("openOMEZarrFromS3WithCredentialsV2"); + ImageDataFormat imageDataFormat = ImageDataFormat.OmeZarrS3; + imageDataFormat.setS3SecretAndAccessKey( new String[]{ "4vJRUoUQZix2x7wPRlSy", "qtt7o93uv2PTvXSgYGMtoGtQkd3HsRqVH5XwitSf" } ); + ImageData< ? > imageData = ImageDataOpener.open( + "https://s3.embl.de/mobie-credentials-test/test/images/ome-zarr/8kmont5.ome.zarr", + imageDataFormat, + new SharedQueue( 1 ) ); + VoxelDimensions voxelDimensions = imageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + assertNotNull( voxelDimensions ); + } + + @Test + public void openOMEZarrFromS3WithWrongCredentials() + { + System.out.println("openOMEZarrFromS3WithWrongCredentials"); + + try + { + N5ImageData< ? > n5ImageData = new N5ImageData<>( + "https://s3.embl.de/mobie-credentials-test/test/images/ome-zarr/8kmont5.ome.zarr", + new String[]{ "4vJRUoUQZix2x7wPRlSy", "wrongSecretKey" }); + VoxelDimensions voxelDimensions = n5ImageData.getSourcePair( 0 ).getB().getVoxelDimensions(); + System.out.println("Succeeded incorrectly."); + fail(); + } + catch ( Exception e ) + { + System.out.println("Failed correctly."); + assertTrue( true ); + } + } + + public static void main( String[] args ) + { + ExecutorService exec = Executors.newCachedThreadPool(); + exec.submit(() -> {new N5ImageDataTest().openOMEZarrFromS3();}); + exec.submit(() -> {new N5ImageDataTest().openOMEZarrFromEBIS3();}); + exec.submit(() -> {new N5ImageDataTest().openOMEZarrFromS3WithCredentials();}); + exec.submit(() -> {new N5ImageDataTest().openOMEZarrFromS3WithWrongCredentials();}); + } +} \ No newline at end of file diff --git a/src/test/java/ui/BdvOmeZarrOpener.java b/src/test/java/ui/BdvOmeZarrOpener.java deleted file mode 100644 index 6106d5b6..00000000 --- a/src/test/java/ui/BdvOmeZarrOpener.java +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package ui; - -import org.embl.mobie.io.ImageDataFormat; -import org.embl.mobie.io.SpimDataOpener; - -import bdv.util.BdvFunctions; -import bdv.cache.SharedQueue; -import mpicbg.spim.data.SpimData; -import mpicbg.spim.data.SpimDataException; - -public class BdvOmeZarrOpener { - public static void main(String[] args) { - showProject(); - } - - public static void showProject() { - SharedQueue sharedQueue = new SharedQueue(7); - SpimDataOpener spimDataOpener = new SpimDataOpener(); - SpimData image = null; - try { -// image =(SpimData) spimDataOpener.openSpimData("https://raw.githubusercontent.com/mobie/clem-example-project//more-views/data/hela/images/bdv-n5-s3/fluorescence-a2-FMR-c2.xml", -// ImageDataFormat.BdvN5S3, sharedQueue); - image = (SpimData) spimDataOpener.open("https://s3.embl.de/i2k-2020/project-bdv-ome-zarr/Covid19-S4-Area2/images/bdv.ome.zarr.s3/raw.xml", - ImageDataFormat.BdvOmeZarrS3, sharedQueue); - } catch (SpimDataException e) { - e.printStackTrace(); - } - assert image != null; - BdvFunctions.show(image); - } -} diff --git a/src/test/java/ui/OmeZarrS3OpenerTests.java b/src/test/java/ui/OmeZarrS3OpenerTests.java deleted file mode 100644 index 2ec67b7e..00000000 --- a/src/test/java/ui/OmeZarrS3OpenerTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package ui; - -import java.io.IOException; -import java.util.List; - -import org.embl.mobie.io.ome.zarr.loaders.N5OMEZarrImageLoader; -import org.embl.mobie.io.ome.zarr.openers.OMEZarrS3Opener; - -import bdv.util.BdvFunctions; -import bdv.util.BdvOptions; -import bdv.util.BdvStackSource; -import mpicbg.spim.data.SpimData; -import net.imglib2.type.numeric.ARGBType; - -import static org.embl.mobie.io.ome.zarr.openers.OMEZarrS3Opener.readURL; - -public class OmeZarrS3OpenerTests { - - public static void main(String[] args) throws IOException { - //showMyosin(); - //showAll(); - //readI2KGif(); - //showIDR0(); - showIDR1(); - } - - public static void showIDR0() throws IOException { - // /idr/zarr/v0.1/6001237.zarr - N5OMEZarrImageLoader.logging = true; - OMEZarrS3Opener reader = new OMEZarrS3Opener("https://s3.embassy.ebi.ac.uk", "us-west-2", "idr"); - SpimData image = readURL("zarr/v0.1/6001237.zarr"); - List> sources = BdvFunctions.show(image); - sources.get(0).setColor(new ARGBType(ARGBType.rgba(0, 0, 255, 255))); - sources.get(0).setDisplayRange(0, 3000); - sources.get(1).setColor(new ARGBType(ARGBType.rgba(0, 255, 0, 255))); - sources.get(1).setDisplayRange(0, 3000); - sources.get(2).setColor(new ARGBType(ARGBType.rgba(255, 0, 0, 255))); - sources.get(2).setDisplayRange(0, 3000); - sources.get(3).setColor(new ARGBType(ARGBType.rgba(255, 255, 255, 255))); - sources.get(3).setDisplayRange(0, 3000); - //sources.get( 4 ).setDisplayRange( 0, 100 ); - // Sources.showAsLabelMask(sources.get(4)); - } - - public static void readI2KGif() throws IOException { - // https://play.minio.io:9000/i2k2020/gif.zarr - N5OMEZarrImageLoader.logging = true; - OMEZarrS3Opener reader = new OMEZarrS3Opener("https://play.minio.io:9000", "us-west-2", "i2k2020"); - SpimData image = readURL("gif.zarr"); - BdvFunctions.show(image); - } - - public static void showAll() throws IOException { - N5OMEZarrImageLoader.logging = true; - OMEZarrS3Opener reader = new OMEZarrS3Opener("https://s3.embl.de", "us-west-2", "i2k-2020"); - SpimData myosin = readURL("prospr-myosin.ome.zarr"); - List> myosinBdvSources = BdvFunctions.show(myosin); - SpimData em = readURL("em-raw.ome.zarr"); - List> sources = BdvFunctions.show(em, BdvOptions.options().addTo(myosinBdvSources.get(0).getBdvHandle())); - // Sources.showAsLabelMask(sources.get(1)); - // Sources.viewAsHyperstack(sources.get(0), 4); - } - - public static void showMyosin() throws IOException { - N5OMEZarrImageLoader.logging = true; - OMEZarrS3Opener reader = new OMEZarrS3Opener("https://s3.embl.de", "us-west-2", "i2k-2020"); - SpimData myosin = readURL("prospr-myosin.ome.zarr"); - BdvFunctions.show(myosin); - } - - public static void showIDR1() throws IOException { - N5OMEZarrImageLoader.logging = true; - OMEZarrS3Opener reader = new OMEZarrS3Opener("https://s3.embassy.ebi.ac.uk", "us-west-2", "idr"); - SpimData data = readURL("zarr/v0.1/9822151.zarr"); - BdvFunctions.show(data, BdvOptions.options().is2D()).get(0).setDisplayRange(3000, 15000); - } -} diff --git a/src/test/java/ui/OmeZarrS3V4Opener.java b/src/test/java/ui/OmeZarrS3V4Opener.java deleted file mode 100644 index b6c43d22..00000000 --- a/src/test/java/ui/OmeZarrS3V4Opener.java +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package ui; - -import java.io.IOException; - -import org.embl.mobie.io.ome.zarr.openers.OMEZarrS3Opener; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimData; -import net.imglib2.Dimensions; - -public class OmeZarrS3V4Opener { - public static void main(String[] args) throws IOException, InterruptedException { - multiImg(); - Thread.sleep(10000); - } - - public static void showYX() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/yx.ome.zarr"); - BdvFunctions.show(image); - } - - public static void showZYX() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/zyx.ome.zarr"); - BdvFunctions.show(image); - } - - public static void showCYX() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/cyx.ome.zarr"); - BdvFunctions.show(image); - } - - public static void showTYX() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/tyx.ome.zarr"); - Dimensions dimensions = image.getSequenceDescription().getViewSetupsOrdered().get(0).getSize(); - System.out.println(dimensions.toString()); - BdvFunctions.show(image); - } - - public static void showTCYX() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/tcyx.ome.zarr"); - Dimensions dimensions = image.getSequenceDescription().getViewSetupsOrdered().get(0).getSize(); - System.out.println(image.getSequenceDescription().getViewSetupsOrdered().size()); - System.out.println(dimensions.toString()); - Dimensions dimensions1 = image.getSequenceDescription().getViewSetupsOrdered().get(1).getSize(); - System.out.println(dimensions1.toString()); - BdvFunctions.show(image); - } - - public static void showTCZYX() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/tczyx.ome.zarr"); - BdvFunctions.show(image); - } - - public static void multiImg() throws IOException { - SpimData image = OMEZarrS3Opener.readURL("https://s3.embl.de/i2k-2020/ngff-example-data/v0.4/multi-image.ome.zarr"); - BdvFunctions.show(image); - } -} diff --git a/src/test/java/ui/OmeZarrV4FSOpener.java b/src/test/java/ui/OmeZarrV4FSOpener.java deleted file mode 100644 index a3f1a622..00000000 --- a/src/test/java/ui/OmeZarrV4FSOpener.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package ui; - -import java.io.IOException; - -import org.embl.mobie.io.ome.zarr.openers.OMEZarrOpener; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimData; - -public class OmeZarrV4FSOpener { - public static void main(String[] args) throws IOException { - showV4(); - } - - public static void showV4() throws IOException { - SpimData image = OMEZarrOpener.openFile("g/kreshuk/pape/Work/mobie/ngff/ome-ngff-prototypes/single_image/v0.4/tcyx.ome.zarr"); - BdvFunctions.show(image); - } -} diff --git a/src/test/java/ui/OpenOrganelleHelaTest.java b/src/test/java/ui/OpenOrganelleHelaTest.java deleted file mode 100644 index e5040e90..00000000 --- a/src/test/java/ui/OpenOrganelleHelaTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * #%L - * Readers and writers for image data in MoBIE projects - * %% - * Copyright (C) 2021 - 2023 EMBL - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package ui; - -import java.io.IOException; - -import org.embl.mobie.io.openorganelle.OpenOrganelleS3Opener; - -import bdv.util.BdvFunctions; -import mpicbg.spim.data.SpimData; - -public class OpenOrganelleHelaTest { - - public static void main(String[] args) throws IOException { - showHela(); - } - - public static void showHela() throws IOException { - OpenOrganelleS3Opener reader = new OpenOrganelleS3Opener( - "https://janelia-cosem.s3.amazonaws.com", - "us-west-2", - "jrc_hela-2"); - OpenOrganelleS3Opener.setLogging(true); - SpimData image = reader.readKey("jrc_hela-2.n5/em/fibsem-uint16"); - BdvFunctions.show(image); - } -} diff --git a/src/test/resources/ilastik/from-fiji.h5 b/src/test/resources/ilastik/from-fiji.h5 new file mode 100644 index 00000000..87291d50 Binary files /dev/null and b/src/test/resources/ilastik/from-fiji.h5 differ diff --git a/src/test/resources/ilastik/probabilities-from-ilastik.h5 b/src/test/resources/ilastik/probabilities-from-ilastik.h5 new file mode 100644 index 00000000..000936a5 Binary files /dev/null and b/src/test/resources/ilastik/probabilities-from-ilastik.h5 differ