Skip to content

Commit

Permalink
First try at scale transforms
Browse files Browse the repository at this point in the history
  • Loading branch information
melissalinkert committed Feb 8, 2022
1 parent 8f430e2 commit 53ec195
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 16 deletions.
92 changes: 76 additions & 16 deletions src/main/java/com/glencoesoftware/bioformats2raw/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -56,6 +55,7 @@
import loci.formats.ome.OMEXMLMetadata;
import loci.formats.services.OMEXMLService;
import loci.formats.services.OMEXMLServiceImpl;
import ome.units.quantity.Quantity;
import ome.xml.meta.OMEXMLMetadataRoot;
import ome.xml.model.enums.DimensionOrder;
import ome.xml.model.enums.EnumerationException;
Expand Down Expand Up @@ -1506,33 +1506,63 @@ private void setSeriesLevelMetadata(int series, int resolutions)
multiscale.put("metadata", metadata);
multiscale.put("version", nested ? "0.2" : "0.1");
multiscales.add(multiscale);
List<Map<String, String>> datasets = new ArrayList<Map<String, String>>();

IFormatReader v = null;
IMetadata meta = null;
String axisOrder = null;
try {
v = readers.take();
meta = (IMetadata) v.getMetadataStore();

if (dimensionOrder != null) {
axisOrder = dimensionOrder.toString();
}
else {
axisOrder = v.getDimensionOrder();
}
}
finally {
readers.put(v);
}

List<Map<String, Object>> datasets = new ArrayList<Map<String, Object>>();
for (int r = 0; r < resolutions; r++) {
resolutionString = String.format(
scaleFormatString, getScaleFormatStringArgs(series, r));
String lastPath = resolutionString.substring(
resolutionString.lastIndexOf('/') + 1);
datasets.add(Collections.singletonMap("path", lastPath));
}
multiscale.put("datasets", datasets);

String axisOrder = null;
if (dimensionOrder != null) {
axisOrder = dimensionOrder.toString();
}
else {
IFormatReader reader = readers.take();
try {
axisOrder = reader.getDimensionOrder();
}
finally {
readers.put(reader);
List<Map<String, Object>> transforms =
new ArrayList<Map<String, Object>>();
Map<String, Object> scale = new HashMap<String, Object>();
scale.put("type", "scale");
List<Double> axisValues = new ArrayList<Double>();
List<Integer> axisIndices = new ArrayList<Integer>();
for (int i=axisOrder.length()-1; i>=0; i--) {
Quantity axisScale = getScale(meta, series, axisOrder, i);
if (axisScale != null) {
// TODO: does this need to be recalculated for r > 0?
axisValues.add(axisScale.value().doubleValue());
axisIndices.add(axisOrder.length() - i - 1);
}
}
scale.put("scale", axisValues);
scale.put("axisIndices", axisIndices);

transforms.add(scale);

Map<String, Object> dataset = new HashMap<String, Object>();
dataset.put("path", lastPath);
dataset.put("transformations", transforms);
datasets.add(dataset);
}
multiscale.put("datasets", datasets);

List<Map<String, String>> axes = new ArrayList<Map<String, String>>();
for (int i=axisOrder.length()-1; i>=0; i--) {
String axis = axisOrder.substring(i, i + 1).toLowerCase();
String type = "space";
Quantity scale = getScale(meta, series, axisOrder, i);
if (axis.equals("t")) {
type = "time";
}
Expand All @@ -1542,6 +1572,9 @@ else if (axis.equals("c")) {
Map<String, String> thisAxis = new HashMap<String, String>();
thisAxis.put("name", axis);
thisAxis.put("type", type);
if (scale != null) {
thisAxis.put("unit", scale.unit().getSymbol());
}
axes.add(thisAxis);
}
multiscale.put("axes", axes);
Expand All @@ -1555,6 +1588,33 @@ else if (axis.equals("c")) {
LOGGER.debug(" finished writing subgroup attributes");
}

private Quantity getScale(
IMetadata meta, int series, String axisOrder, int axis)
{
if (meta == null) {
return null;
}
int seriesIndex = seriesList.indexOf(series);

if (seriesIndex < 0 || seriesIndex >= meta.getImageCount()) {
return null;
}

String axisChar = axisOrder.substring(axis, axis + 1).toLowerCase();
switch (axisChar.charAt(0)) {
case 'x':
return meta.getPixelsPhysicalSizeX(seriesIndex);
case 'y':
return meta.getPixelsPhysicalSizeY(seriesIndex);
case 'z':
return meta.getPixelsPhysicalSizeZ(seriesIndex);
case 't':
return meta.getPixelsTimeIncrement(seriesIndex);
default:
return null;
}
}

/**
* Takes exception from asynchronous execution and re-throw known exception
* types. If the end is reached with no known exception detected, either the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,44 @@ public void testSetOriginalDimensionOrder() throws Exception {
checkAxes(axes, "TZCYX");
}

/**
* Test that physical sizes are saved in axes/transformations metadata.
*/
@Test
public void testPhysicalSizes() throws Exception {
input = fake("physicalSizeX", "1.0mm",
"physicalSizeY", "0.5mm",
"physicalSizeZ", "2cm");
assertTool();

ZarrGroup z = ZarrGroup.open(output.resolve("0").toString());
List<Map<String, Object>> multiscales = (List<Map<String, Object>>)
z.getAttributes().get("multiscales");
assertEquals(1, multiscales.size());
Map<String, Object> multiscale = multiscales.get(0);
List<Map<String, Object>> axes =
(List<Map<String, Object>>) multiscale.get("axes");
checkAxes(axes, "TCZYX");

List<Map<String, Object>> datasets =
(List<Map<String, Object>>) multiscale.get("datasets");
assertEquals(2, datasets.size());

for (Map<String, Object> dataset : datasets) {
List<Map<String, Object>> transforms =
(List<Map<String, Object>>) dataset.get("transformations");
assertEquals(1, transforms.size());
Map<String, Object> scale = transforms.get(0);
assertEquals("scale", scale.get("type"));
List<Integer> axisIndices = (List<Integer>) scale.get("axisIndices");
List<Double> axisValues = (List<Double>) scale.get("scale");

assertEquals(axisIndices.size(), axisValues.size());
assertEquals(axisIndices, Arrays.asList(new Integer[] {2, 3, 4}));
assertEquals(axisValues, Arrays.asList(new Double[] {2.0, 0.5, 1.0}));
}
}

/**
* Test using a different tile size from the default (1024).
*/
Expand Down

0 comments on commit 53ec195

Please sign in to comment.