diff --git a/pom.xml b/pom.xml index eee839b9..104abfb4 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,7 @@ 1.0.0-beta-16 - 10.2.1 + 10.2.2 1.0.0-beta-28 diff --git a/src/main/java/org/embl/mobie/io/SpimDataOpener.java b/src/main/java/org/embl/mobie/io/SpimDataOpener.java index 42e0b3d1..04cf8b02 100644 --- a/src/main/java/org/embl/mobie/io/SpimDataOpener.java +++ b/src/main/java/org/embl/mobie/io/SpimDataOpener.java @@ -4,9 +4,11 @@ import bdv.spimdata.SpimDataMinimal; import bdv.util.volatiles.SharedQueue; import ij.IJ; +import lombok.extern.slf4j.Slf4j; import mpicbg.spim.data.SpimData; import mpicbg.spim.data.SpimDataException; import mpicbg.spim.data.generic.AbstractSpimData; +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; @@ -32,6 +34,7 @@ import static mpicbg.spim.data.XmlKeys.IMGLOADER_TAG; import static mpicbg.spim.data.XmlKeys.SEQUENCEDESCRIPTION_TAG; +@Slf4j public class SpimDataOpener { public static final String ERROR_WHILE_TRYING_TO_READ_SPIM_DATA = "Error while trying to read spimData"; @@ -156,18 +159,39 @@ private SpimData openOpenOrganelleS3(String path) throws SpimDataException { } } - private SpimData openBdvOmeZarrS3(String path, SharedQueue queue) throws SpimDataException { + private SpimData openBdvOmeZarrS3(String path, SharedQueue queue) { + //Todo: finish bug fixing try { - N5S3OMEZarrImageLoader imageLoader = createN5S3OmeZarrImageLoader(path, queue); - SpimData spimData = openBdvXml(path); - if (spimData != null) { - spimData.getSequenceDescription().setImgLoader(imageLoader); - return spimData; + SAXBuilder sax = new SAXBuilder(); + InputStream stream = FileAndUrlUtils.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 { - throw new SpimDataException("Error while trying to read spimData. SpimData is null"); + imageLoader = new N5S3OMEZarrImageLoader(imgLoaderElem.getChild("ServiceEndpoint").getText(), imgLoaderElem.getChild("SigningRegion").getText(), bucket, object, "."); } - } catch (IOException | JDOMException e) { - throw new SpimDataException(ERROR_WHILE_TRYING_TO_READ_SPIM_DATA + e.getMessage()); + SpimData spim = new SpimData(null, Cast.unchecked(imageLoader.getSequenceDescription()), imageLoader.getViewRegistrations()); + SpimData spimData; + try { + InputStream st = FileAndUrlUtils.getInputStream(path); + spimData = (new CustomXmlIoSpimData()).loadFromStream(st, path); + } catch (SpimDataException exception) { + log.debug("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) { + log.debug("Failed to open openBdvOmeZarrS3", e); + return null; } } @@ -207,12 +231,15 @@ private SpimData getSpimDataWithImageLoader(String path, @Nullable SharedQueue s 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 && new File(imagesFile).exists()) { - if (sharedQueue != null) { - return OMEZarrOpener.openFile(path, sharedQueue); + 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); + } } - return OMEZarrOpener.openFile(imagesFile); - } } catch (JDOMException | IOException e) { IJ.log(e.getMessage()); } 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 index 371f2530..06e857ba 100644 --- a/src/main/java/org/embl/mobie/io/n5/loaders/N5ImageLoader.java +++ b/src/main/java/org/embl/mobie/io/n5/loaders/N5ImageLoader.java @@ -277,7 +277,7 @@ private static class N5CacheArrayLoader implements SimpleCacheArrayLoader } @Override - public A loadArray(final long[] gridPosition) throws IOException { + public A loadArray(final long[] gridPosition, final int[] cellDimensions) throws IOException { DataBlock block = null; try { 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 index d51cfbea..ca61c6c0 100644 --- a/src/main/java/org/embl/mobie/io/n5/util/N5CacheArrayLoader.java +++ b/src/main/java/org/embl/mobie/io/n5/util/N5CacheArrayLoader.java @@ -22,7 +22,7 @@ public N5CacheArrayLoader(final N5Reader n5, final String pathName, final Datase } @Override - public A loadArray(final long[] gridPosition) { + public A loadArray(final long[] gridPosition, final int[] cellDimensions) { DataBlock block = null; try { 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 index 0586775f..f67f4378 100644 --- a/src/main/java/org/embl/mobie/io/n5/writers/WriteSequenceToN5.java +++ b/src/main/java/org/embl/mobie/io/n5/writers/WriteSequenceToN5.java @@ -325,7 +325,7 @@ public RandomAccessibleInterval getImage(final int level) throws IOException final long[] cellGridPosition = new long[n]; grid.getCellDimensions(key, cellMin, cellDims); grid.getCellGridPositionFlat(key, cellGridPosition); - return new Cell<>(cellDims, cellMin, cacheArrayLoader.loadArray(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 index cdc9196f..91c1adaf 100644 --- 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 @@ -275,6 +275,8 @@ private OmeZarrMultiscales[] getMultiscale(String pathName) throws IOException { 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); } 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 index a3c844f2..3c942b0f 100644 --- 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 @@ -25,6 +25,7 @@ */ package org.embl.mobie.io.ome.zarr.readers; +import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.AmazonS3Exception; import com.google.gson.GsonBuilder; @@ -266,28 +267,25 @@ public DataBlock readBlock( * * @param objectPath * @return null if the object does not exist, otherwise the loaded attributes. - * @throws IOException */ - public HashMap readJson(String objectPath) throws IOException { - if (!this.s3.doesObjectExist(this.bucketName, objectPath)) { - return null; - } else { + public HashMap readJson(String objectPath) { + try { InputStream in = this.readS3Object(objectPath); - Throwable var4 = null; + Throwable throwable = null; - HashMap var5; + HashMap hashMap; try { - var5 = GsonAttributesParser.readAttributes(new InputStreamReader(in), this.gson); - } catch (Throwable var14) { - var4 = var14; - throw var14; + hashMap = GsonAttributesParser.readAttributes(new InputStreamReader(in), this.gson); + } catch (Throwable error) { + throwable = error; + throw error; } finally { if (in != null) { - if (var4 != null) { + if (throwable != null) { try { in.close(); - } catch (Throwable var13) { - var4.addSuppressed(var13); + } catch (Throwable exception) { + throwable.addSuppressed(exception); } } else { in.close(); @@ -295,8 +293,10 @@ public HashMap readJson(String objectPath) throws IOExcepti } } - - return var5; + return hashMap; + } catch (SdkClientException | IOException e) { + log.debug("Failed to readJson: object {} does not exist in bucket {}", objectPath, this.bucketName); + return null; } } 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 index 4405578f..b020bf27 100644 --- 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 @@ -35,7 +35,7 @@ public N5OMEZarrCacheArrayLoader(final N5Reader n5, final String pathName, final } @Override - public A loadArray(final long[] gridPosition) throws IOException { + public A loadArray(final long[] gridPosition, int[] cellDimensions) throws IOException { DataBlock block = null; long[] dataBlockIndices = toDataBlockIndices(gridPosition); 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 index 571f1147..269ac3b1 100644 --- 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 @@ -408,7 +408,7 @@ public RandomAccessibleInterval getImage(final int level) throws IOException final long[] cellGridPosition = new long[n]; grid.getCellDimensions(key, cellMin, cellDims); grid.getCellGridPositionFlat(key, cellGridPosition); - return new Cell<>(cellDims, cellMin, cacheArrayLoader.loadArray(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 index 9fb07654..0603ccc7 100644 --- a/src/main/java/org/embl/mobie/io/openorganelle/N5CacheArrayLoader.java +++ b/src/main/java/org/embl/mobie/io/openorganelle/N5CacheArrayLoader.java @@ -24,7 +24,7 @@ public class N5CacheArrayLoader implements SimpleCacheArrayLoader { } @Override - public A loadArray(final long[] gridPosition) { + public A loadArray(final long[] gridPosition, final int[] cellDimensions) { DataBlock block = null; try { diff --git a/src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java b/src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java index bdc4c57f..35f3858c 100644 --- a/src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java +++ b/src/main/java/org/embl/mobie/io/util/CustomXmlIoSpimData.java @@ -41,28 +41,26 @@ import java.io.File; import java.io.InputStream; +import java.util.Objects; import static mpicbg.spim.data.XmlKeys.SPIMDATA_TAG; - public class CustomXmlIoSpimData extends XmlIoAbstractSpimData { public CustomXmlIoSpimData() { super(SpimData.class, new XmlIoSequenceDescription(), new XmlIoViewRegistrations()); } - // NOTE we still need to pass the xml filename here, so that bdv can determine the relative - // paths for local files. public SpimData loadFromStream(InputStream in, String xmlFilename) throws SpimDataException { - final SAXBuilder sax = new SAXBuilder(); + SAXBuilder sax = new SAXBuilder(); + Document doc; try { doc = sax.build(in); - } catch (final Exception e) { - throw new SpimDataIOException(e); + } catch (Exception exception) { + throw new SpimDataIOException(exception); } final Element root = doc.getRootElement(); - - if (root.getName() != SPIMDATA_TAG) + if (!root.getName().equals(SPIMDATA_TAG)) throw new RuntimeException("expected <" + SPIMDATA_TAG + "> root element. wrong file?"); return fromXml(root, new File(xmlFilename)); diff --git a/src/test/java/ui/BdvOmeZarrOpener.java b/src/test/java/ui/BdvOmeZarrOpener.java new file mode 100644 index 00000000..69283b8b --- /dev/null +++ b/src/test/java/ui/BdvOmeZarrOpener.java @@ -0,0 +1,29 @@ +package ui; + +import bdv.util.BdvFunctions; +import bdv.util.volatiles.SharedQueue; +import mpicbg.spim.data.SpimData; +import mpicbg.spim.data.SpimDataException; +import org.embl.mobie.io.ImageDataFormat; +import org.embl.mobie.io.SpimDataOpener; + +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.openSpimData("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); + } +}