diff --git a/pom.xml b/pom.xml
index ac8db6c..e4914ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -144,7 +144,7 @@
0.8.1
0.7.3
- 8.0.0-SNAPSHOT
+ 7.3.1
diff --git a/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsHelper.java b/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsHelper.java
index 414a8e3..65933e8 100644
--- a/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsHelper.java
+++ b/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsHelper.java
@@ -202,7 +202,6 @@ public static Length[] getSeriesVoxelSizeAsLengths(IMetadata omeMeta,
}
protected static AffineTransform3D getSeriesRootTransform(IMetadata omeMeta,
- IFormatReader reader,
int iSerie, Unit u,
// Bioformats location fix
double[] positionPreTransformMA, double[] positionPostTransformMA,
@@ -236,7 +235,7 @@ protected static AffineTransform3D getSeriesRootTransform(IMetadata omeMeta,
voxSizePostTransform.set(voxSizePostTransformMA);
}
- return getSeriesRootTransform(omeMeta, reader, iSerie, u,
+ return getSeriesRootTransform(omeMeta, iSerie, u,
// Bioformats location fix
positionPreTransform, positionPostTransform, positionReferenceFrameLength,
positionIsImageCenter,
@@ -247,7 +246,6 @@ protected static AffineTransform3D getSeriesRootTransform(IMetadata omeMeta,
}
public static AffineTransform3D getSeriesRootTransform(IMetadata omeMeta,
- IFormatReader reader,
int iSerie, Unit u,
// Bioformats location fix
AffineTransform3D positionPreTransform,
@@ -284,7 +282,7 @@ else if (voxSize[iDimension].unit().getSymbol().equals(
Length[] pos = getSeriesPositionAsLengths(omeMeta, iSerie);
double[] p = new double[3];
- Dimensions dims = getSeriesDimensions(omeMeta, reader, iSerie);
+ Dimensions dims = getSeriesDimensions(omeMeta, iSerie);
for (int iDimension = 0; iDimension < 3; iDimension++) { // X:0; Y:1; Z:2
if ((pos[iDimension].unit() != null) && (pos[iDimension].unit()
@@ -406,16 +404,14 @@ public int numDimensions() {
return voxelDimensions;
}
- public static Dimensions getSeriesDimensions(IMetadata omeMeta, IFormatReader reader, int iSerie) {
+ public static Dimensions getSeriesDimensions(IMetadata omeMeta, int iSerie) {
// Always set 3d to allow for Big Stitcher compatibility
int numDimensions = 3;
- omeMeta.getPixelsSizeX(iSerie);
- reader.setSeries(iSerie);
- int sX = reader.getSizeX();
- int sY = reader.getSizeY();
- int sZ = reader.getSizeZ();
+ int sX = omeMeta.getPixelsSizeX(iSerie).getValue();//reader.getSizeX();
+ int sY = omeMeta.getPixelsSizeY(iSerie).getValue();//reader.getSizeY();
+ int sZ = omeMeta.getPixelsSizeZ(iSerie).getValue();//reader.getSizeZ();
long[] dims = new long[3];
diff --git a/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsOpener.java b/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsOpener.java
index fe54e54..5ad5933 100644
--- a/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsOpener.java
+++ b/src/main/java/ch/epfl/biop/bdv/img/bioformats/BioFormatsOpener.java
@@ -24,6 +24,8 @@
import bdv.img.cache.VolatileGlobalCellCache;
import ch.epfl.biop.bdv.img.OpenerSetupLoader;
+import ch.epfl.biop.bdv.img.entity.Field;
+import ch.epfl.biop.bdv.img.entity.Plate;
import ch.epfl.biop.bdv.img.opener.ChannelProperties;
import ch.epfl.biop.bdv.img.opener.Opener;
import ch.epfl.biop.bdv.img.ResourcePool;
@@ -57,6 +59,9 @@
import ome.units.UNITS;
import ome.units.quantity.Length;
import ome.units.unit.Unit;
+import ome.xml.meta.OMEXMLMetadataRoot;
+import ome.xml.model.Well;
+import ome.xml.model.WellSample;
import org.apache.commons.io.FilenameUtils;
import org.scijava.Context;
import org.slf4j.Logger;
@@ -66,9 +71,11 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.function.Supplier;
import static ch.epfl.biop.bdv.img.opener.OpenerHelper.memoize;
@@ -125,8 +132,6 @@ public class BioFormatsOpener implements Opener {
private final Map readerOptions;
- IFormatReader model;
-
/**
*
* @param context
@@ -214,11 +219,17 @@ public BioFormatsOpener(
return currentIndexFilename;
});
- this.model = this.getNewReader();
this.pool = memoize("opener.bioformats."+splitRGBChannels+"."+dataLocation+"."+options,
cachedObjects,
- () -> new ReaderPool(poolSize, true,
- this::getNewReader, model));
+ () -> {
+ try {
+ return new ReaderPool(poolSize, true,
+ this::getNewReader, dataLocation.toUpperCase().trim().endsWith(".CZI") ); // Create base reader only for czi files
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ });
int pixelType;
{ // Indentation just for the pool / recycle operation -> force limiting the scope of reader
IFormatReader reader = pool.takeOrCreate();
@@ -262,7 +273,6 @@ public BioFormatsOpener(
AffineTransform3D rootTransform = BioFormatsHelper.getSeriesRootTransform(
this.omeMeta, //metadata
- model,
iSerie, // serie
BioFormatsHelper.getUnitFromString(unit), // unit
positionPreTransformMatrixArray, // AffineTransform3D for positionPreTransform,
@@ -294,6 +304,7 @@ public List getEntities(int iChannel) {
ArrayList entityList = new ArrayList<>();
entityList.add(new FileName(idxFilename, filename));
entityList.add(new SeriesIndex(iSerie));
+ addPlateInfo(entityList, options, iSerie, cachedObjects);
return entityList;
}
@@ -311,6 +322,67 @@ public AffineTransform3D getTransform() {
} else meta = null;
}
+ private void addPlateInfo(ArrayList entityList,
+ String options,
+ int iSerie,
+ Map cachedObjects) {
+ if (omeMeta.getPlateCount() == 0 ) return; // No plate information
+
+ // Check that we can read information
+ if (omeMeta.getPlateCount() > 1) {
+ logger.warn("Plate information ignored: only bio-formats containing single wells are supported");
+ return;
+ }
+
+ if (!(omeMeta.getRoot() instanceof OMEXMLMetadataRoot)) {
+ logger.warn("Can't detect plate information since ome meta root is not of class OMEXMLMetadataRoot");
+ return;
+ }
+
+ OMEXMLMetadataRoot r = (OMEXMLMetadataRoot) omeMeta.getRoot();
+ ome.xml.model.Plate plate = r.getPlate(0);
+
+ // Gets a unique identifier for the plate
+
+ Integer currentPlateIndex = memoize("opener.bioformats.currentplateindex", cachedObjects, () -> 0);
+ int idxPlate = memoize("opener.bioformats.plateIndex."+dataLocation+"."+options, cachedObjects, () -> {
+ cachedObjects.put("opener.bioformats.currentplateindex", currentPlateIndex + 1 );
+ return currentPlateIndex;
+ });
+
+ entityList.add(new Plate(idxPlate, plate.getName()));
+
+ Map idToWellSample = memoize("opener.bioformats.idtowell."+dataLocation+"."+options, cachedObjects, () -> {
+ Map idToWS = new HashMap<>();
+ plate.copyWellList().forEach(well -> well.copyWellSampleList().forEach(ws -> {
+ if (ws.getLinkedImage()!=null) {
+ if (ws.getLinkedImage().getID()!=null) {
+ // "Image:0"
+ idToWS.put(Integer.parseInt(ws.getLinkedImage().getID().split(":")[1]), ws);
+ }
+ }
+ }));
+ return idToWS;
+ });
+
+ if (idToWellSample.containsKey(iSerie)) {
+ WellSample ws = idToWellSample.get(iSerie);
+ System.out.println("ws="+ws.getID());
+ // WellSample:0:0:2
+ int id = Integer.parseInt(ws.getID().split(":")[3]);
+ entityList.add(new Field(id));
+ if (ws.getWell()!=null) {
+ Well w = ws.getWell();
+ entityList.add(
+ new ch.epfl.biop.bdv.img.entity.Well(
+ Integer.parseInt(w.getID().split(":")[2]),
+ (char)(w.getRow().getValue()+'A')+Integer.toString(w.getColumn().getValue()+1),
+ w.getRow().getValue(), w.getColumn().getValue()));
+ }
+ }
+
+ }
+
/**
* Build a channelProperties object for each image channel.
* @param omeMeta = image metadata
@@ -435,7 +507,7 @@ public IFormatReader getNewReader() {
reader = new ChannelSeparator(reader);
}
- if (memoize) { // Can't memoize with bf Options
+ if (memoize) {
Memoizer memo = new Memoizer(reader);
try {
memo.setId(dataLocation);
@@ -590,14 +662,6 @@ public void close() {
e.printStackTrace();
}
});
- if (model!=null) {
- try {
- model.close();
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
}
/**
@@ -620,22 +684,15 @@ private static class ReaderPool extends ResourcePool {
final IFormatReader model;
public ReaderPool(int size, Boolean dynamicCreation,
- Supplier readerSupplier)
- {
- super(size, dynamicCreation);
- createPool();
- this.readerSupplier = readerSupplier;
- model = null;
- }
-
- public ReaderPool(int size, Boolean dynamicCreation,
- Supplier readerSupplier,
- IFormatReader model)
- {
+ Supplier readerSupplier, boolean createBase) throws Exception {
super(size, dynamicCreation);
- this.model = model;
createPool();
this.readerSupplier = readerSupplier;
+ if (createBase) {
+ model = this.takeOrCreate();
+ } else {
+ model = null;
+ }
}
@Override
@@ -648,5 +705,19 @@ public IFormatReader createObject() {
}
return readerSupplier.get();
}
+
+ @Override
+ public synchronized void shutDown(Consumer closer) {
+ if (model!=null) {
+ try {
+ recycle(model);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ closer.accept(model);
+ }
+ super.shutDown(closer);
+ }
+
}
}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/entity/Field.java b/src/main/java/ch/epfl/biop/bdv/img/entity/Field.java
new file mode 100644
index 0000000..7c35954
--- /dev/null
+++ b/src/main/java/ch/epfl/biop/bdv/img/entity/Field.java
@@ -0,0 +1,47 @@
+/*-
+ * #%L
+ * Various image loaders for bigdataviewer (Bio-Formats, Omero, QuPath)
+ * %%
+ * Copyright (C) 2022 - 2024 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP)
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+
+package ch.epfl.biop.bdv.img.entity;
+
+import mpicbg.spim.data.generic.base.Entity;
+
+public class Field extends Entity implements
+ Comparable
+{
+
+ public Field(final int id) {
+ super(id);
+ }
+
+ /**
+ * Compares the {@link #getId() ids}.
+ */
+ @Override
+ public int compareTo(final Field o) {
+ return getId() - o.getId();
+ }
+
+ /**
+ * Empty constructor strictly necessary for dataset deserialization
+ */
+ protected Field() {}
+}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/entity/Plate.java b/src/main/java/ch/epfl/biop/bdv/img/entity/Plate.java
new file mode 100644
index 0000000..6a5df3e
--- /dev/null
+++ b/src/main/java/ch/epfl/biop/bdv/img/entity/Plate.java
@@ -0,0 +1,47 @@
+/*-
+ * #%L
+ * Various image loaders for bigdataviewer (Bio-Formats, Omero, QuPath)
+ * %%
+ * Copyright (C) 2022 - 2024 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP)
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+
+package ch.epfl.biop.bdv.img.entity;
+
+import mpicbg.spim.data.generic.base.NamedEntity;
+
+public class Plate extends NamedEntity implements
+ Comparable
+{
+
+ public Plate(final int id, final String name) {
+ super(id, name);
+ }
+
+ /**
+ * Compares the {@link #getId() ids}.
+ */
+ @Override
+ public int compareTo(final Plate o) {
+ return getId() - o.getId();
+ }
+
+ /**
+ * Empty constructor strictly necessary for dataset deserialization
+ */
+ protected Plate() {}
+}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/entity/Well.java b/src/main/java/ch/epfl/biop/bdv/img/entity/Well.java
new file mode 100644
index 0000000..1274456
--- /dev/null
+++ b/src/main/java/ch/epfl/biop/bdv/img/entity/Well.java
@@ -0,0 +1,66 @@
+/*-
+ * #%L
+ * Various image loaders for bigdataviewer (Bio-Formats, Omero, QuPath)
+ * %%
+ * Copyright (C) 2022 - 2024 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP)
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+
+package ch.epfl.biop.bdv.img.entity;
+
+import mpicbg.spim.data.SpimDataException;
+import mpicbg.spim.data.XmlHelpers;
+import mpicbg.spim.data.generic.base.NamedEntity;
+
+
+public class Well extends NamedEntity implements
+ Comparable
+{
+
+ int row, column;
+
+ public Well(final int id, final String name, int row, int column) {
+ super(id, name);
+ this.row = row;
+ this.column = column;
+ }
+
+ public int getRow() {
+ return row;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ /**
+ * Compares the {@link #getId() ids}.
+ */
+ @Override
+ public int compareTo(final Well o) {
+ return getId() - o.getId();
+ }
+
+ /**
+ * Empty constructor strictly necessary for dataset deserialization
+ */
+ protected Well() {}
+
+
+
+
+}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoField.java b/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoField.java
new file mode 100644
index 0000000..8c64b28
--- /dev/null
+++ b/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoField.java
@@ -0,0 +1,37 @@
+/*-
+ * #%L
+ * Various image loaders for bigdataviewer (Bio-Formats, Omero, QuPath)
+ * %%
+ * Copyright (C) 2022 - 2024 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP)
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+package ch.epfl.biop.bdv.img.entity;
+
+import mpicbg.spim.data.generic.base.ViewSetupAttributeIo;
+import mpicbg.spim.data.generic.base.XmlIoEntity;
+
+/**
+ * For xml serialization and deserialization of {@link ImageName}
+ */
+@ViewSetupAttributeIo(name = "field", type = Field.class)
+public class XmlIoField extends XmlIoEntity {
+
+ public XmlIoField() {
+ super("field", Field.class);
+ }
+
+}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoPlate.java b/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoPlate.java
new file mode 100644
index 0000000..c9378ce
--- /dev/null
+++ b/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoPlate.java
@@ -0,0 +1,37 @@
+/*-
+ * #%L
+ * Various image loaders for bigdataviewer (Bio-Formats, Omero, QuPath)
+ * %%
+ * Copyright (C) 2022 - 2024 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP)
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+package ch.epfl.biop.bdv.img.entity;
+
+import mpicbg.spim.data.generic.base.ViewSetupAttributeIo;
+import mpicbg.spim.data.generic.base.XmlIoNamedEntity;
+
+/**
+ * For xml serialization and deserialization of {@link ImageName}
+ */
+@ViewSetupAttributeIo(name = "plate", type = Plate.class)
+public class XmlIoPlate extends XmlIoNamedEntity {
+
+ public XmlIoPlate() {
+ super("plate", Plate.class);
+ }
+
+}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoWell.java b/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoWell.java
new file mode 100644
index 0000000..c08026b
--- /dev/null
+++ b/src/main/java/ch/epfl/biop/bdv/img/entity/XmlIoWell.java
@@ -0,0 +1,56 @@
+/*-
+ * #%L
+ * Various image loaders for bigdataviewer (Bio-Formats, Omero, QuPath)
+ * %%
+ * Copyright (C) 2022 - 2024 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE, Switzerland, BioImaging And Optics Platform (BIOP)
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program. If not, see
+ * .
+ * #L%
+ */
+package ch.epfl.biop.bdv.img.entity;
+
+import mpicbg.spim.data.SpimDataException;
+import mpicbg.spim.data.XmlHelpers;
+import mpicbg.spim.data.generic.base.ViewSetupAttributeIo;
+import mpicbg.spim.data.generic.base.XmlIoNamedEntity;
+import org.jdom2.Element;
+
+/**
+ * For xml serialization and deserialization of {@link ImageName}
+ */
+@ViewSetupAttributeIo(name = "well", type = Well.class)
+public class XmlIoWell extends XmlIoNamedEntity {
+
+ public XmlIoWell() {
+ super("well", Well.class);
+ }
+
+ @Override
+ public Element toXml(final Well w) {
+ final Element elem = super.toXml(w);
+ elem.addContent(XmlHelpers.intElement("row", w.row));
+ elem.addContent(XmlHelpers.intElement("column", w.column));
+ return elem;
+ }
+
+ @Override
+ public Well fromXml(final Element elem) throws SpimDataException {
+ final Well w = super.fromXml(elem);
+ w.row = XmlHelpers.getInt(elem, "row");
+ w.column = XmlHelpers.getInt(elem, "column");
+ return w;
+ }
+
+}
diff --git a/src/main/java/ch/epfl/biop/bdv/img/opener/ChannelProperties.java b/src/main/java/ch/epfl/biop/bdv/img/opener/ChannelProperties.java
index 05391d3..b3548ec 100644
--- a/src/main/java/ch/epfl/biop/bdv/img/opener/ChannelProperties.java
+++ b/src/main/java/ch/epfl/biop/bdv/img/opener/ChannelProperties.java
@@ -21,7 +21,6 @@
*/
package ch.epfl.biop.bdv.img.opener;
-import IceInternal.Ex;
import com.google.gson.Gson;
import net.imglib2.type.Type;
import net.imglib2.type.numeric.ARGBType;