Skip to content

Commit 60c63fa

Browse files
committed
add v0.4zarr3
1 parent 94ef037 commit 60c63fa

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

src/main/java/dev/zarr/zarrjava/ome/MultiscaleImage.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ static MultiscaleImage open(StoreHandle storeHandle) throws IOException, ZarrExc
120120
}
121121
throw new ZarrException("v1.0 store at " + storeHandle + " is a Collection, not a MultiscaleImage. Use v1_0.Collection.openCollection() instead.");
122122
}
123+
if (version.startsWith("0.4-zarr3")) {
124+
return dev.zarr.zarrjava.ome.v0_4_zarr3.MultiscaleImage.openMultiscaleImage(storeHandle);
125+
}
123126
if (version.startsWith("0.6")) {
124127
return dev.zarr.zarrjava.ome.v0_6.MultiscaleImage.openMultiscaleImage(storeHandle);
125128
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package dev.zarr.zarrjava.ome.v0_4_zarr3;
2+
3+
import dev.zarr.zarrjava.ZarrException;
4+
import dev.zarr.zarrjava.ome.MultiscalesMetadataImage;
5+
import dev.zarr.zarrjava.ome.OmeV3Group;
6+
import dev.zarr.zarrjava.ome.metadata.Axis;
7+
import dev.zarr.zarrjava.ome.metadata.CoordinateTransformation;
8+
import dev.zarr.zarrjava.store.StoreHandle;
9+
import dev.zarr.zarrjava.v3.Array;
10+
import dev.zarr.zarrjava.v3.Group;
11+
import dev.zarr.zarrjava.v3.GroupMetadata;
12+
13+
import javax.annotation.Nonnull;
14+
import java.io.IOException;
15+
import java.util.ArrayList;
16+
import java.util.Collections;
17+
import java.util.List;
18+
19+
/**
20+
* OME-Zarr v0.4-zarr3 compatibility image reader backed by a Zarr v3 group.
21+
*/
22+
public final class MultiscaleImage extends OmeV3Group
23+
implements MultiscalesMetadataImage<dev.zarr.zarrjava.ome.v0_6.metadata.MultiscalesEntry> {
24+
25+
private dev.zarr.zarrjava.ome.v0_6.metadata.OmeMetadata omeMetadata;
26+
27+
private MultiscaleImage(
28+
@Nonnull StoreHandle storeHandle,
29+
@Nonnull GroupMetadata groupMetadata,
30+
@Nonnull dev.zarr.zarrjava.ome.v0_6.metadata.OmeMetadata omeMetadata
31+
) throws IOException {
32+
super(storeHandle, groupMetadata);
33+
this.omeMetadata = omeMetadata;
34+
}
35+
36+
public static MultiscaleImage openMultiscaleImage(@Nonnull StoreHandle storeHandle)
37+
throws IOException, ZarrException {
38+
Group group = Group.open(storeHandle);
39+
dev.zarr.zarrjava.ome.v0_6.metadata.OmeMetadata omeMetadata = readOmeAttribute(
40+
group.metadata.attributes, storeHandle, dev.zarr.zarrjava.ome.v0_6.metadata.OmeMetadata.class);
41+
if (!omeMetadata.version.startsWith("0.4-zarr3")) {
42+
throw new ZarrException(
43+
"Expected OME-Zarr version '0.4-zarr3', got '" + omeMetadata.version + "' at " + storeHandle);
44+
}
45+
return new MultiscaleImage(storeHandle, group.metadata, omeMetadata);
46+
}
47+
48+
@Override
49+
public StoreHandle getStoreHandle() {
50+
return this.storeHandle;
51+
}
52+
53+
@Override
54+
public dev.zarr.zarrjava.ome.v0_6.metadata.MultiscalesEntry getMultiscalesEntry(int i) throws ZarrException {
55+
return omeMetadata.multiscales.get(i);
56+
}
57+
58+
@Override
59+
public dev.zarr.zarrjava.core.Array openScaleLevel(int i) throws IOException, ZarrException {
60+
String path = getMultiscalesEntry(0).datasets.get(i).path;
61+
return Array.open(storeHandle.resolve(path));
62+
}
63+
64+
@Override
65+
public int getScaleLevelCount() throws ZarrException {
66+
return getMultiscalesEntry(0).datasets.size();
67+
}
68+
69+
@Override
70+
public void createScaleLevel(
71+
String path,
72+
dev.zarr.zarrjava.core.ArrayMetadata arrayMetadata,
73+
List<CoordinateTransformation> coordinateTransformations
74+
) throws IOException, ZarrException {
75+
throw new ZarrException("OME-Zarr v0.4-zarr3 create/write is not supported by this compatibility reader");
76+
}
77+
78+
@Override
79+
public dev.zarr.zarrjava.ome.metadata.MultiscalesEntry getMultiscaleNode(int i) throws ZarrException {
80+
dev.zarr.zarrjava.ome.v0_6.metadata.MultiscalesEntry entry = getMultiscalesEntry(i);
81+
List<dev.zarr.zarrjava.ome.metadata.Dataset> mappedDatasets = new ArrayList<>();
82+
for (dev.zarr.zarrjava.ome.v0_6.metadata.Dataset ds : entry.datasets) {
83+
List<CoordinateTransformation> mapped = new ArrayList<>();
84+
for (dev.zarr.zarrjava.ome.v0_6.metadata.CoordinateTransformation ct : ds.coordinateTransformations) {
85+
mapped.add(new CoordinateTransformation(ct.type, ct.scale, ct.translation, ct.path));
86+
}
87+
mappedDatasets.add(new dev.zarr.zarrjava.ome.metadata.Dataset(ds.path, mapped));
88+
}
89+
90+
List<Axis> axes = entry.axes;
91+
if ((axes == null || axes.isEmpty()) && entry.coordinateSystems != null && !entry.coordinateSystems.isEmpty()) {
92+
axes = entry.coordinateSystems.get(0).axes;
93+
}
94+
95+
return new dev.zarr.zarrjava.ome.metadata.MultiscalesEntry(
96+
axes != null ? axes : Collections.<Axis>emptyList(),
97+
mappedDatasets,
98+
null,
99+
entry.name,
100+
null,
101+
null,
102+
"0.4-zarr3");
103+
}
104+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package dev.zarr.zarrjava.ome;
2+
3+
import dev.zarr.zarrjava.store.FilesystemStore;
4+
import dev.zarr.zarrjava.store.StoreHandle;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.util.Arrays;
8+
9+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
10+
import static org.junit.jupiter.api.Assertions.assertEquals;
11+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
12+
13+
public class OmeZarrV04Zarr3Test extends OmeZarrBaseTest {
14+
15+
@Override
16+
StoreHandle imageStoreHandle() throws Exception {
17+
return new FilesystemStore(TESTDATA.resolve("l4_sample").resolve("color")).resolve();
18+
}
19+
20+
@Override
21+
Class<?> expectedConcreteClass() {
22+
return dev.zarr.zarrjava.ome.v0_4_zarr3.MultiscaleImage.class;
23+
}
24+
25+
@Override
26+
int expectedScaleLevelCount() {
27+
return 5;
28+
}
29+
30+
@Override
31+
long[] expectedLevel0Shape() {
32+
return new long[]{1, 4096, 4096, 2048};
33+
}
34+
35+
@Override
36+
java.util.List<String> expectedAxisNames() {
37+
return Arrays.asList("c", "x", "y", "z");
38+
}
39+
40+
@Test
41+
void openL4SampleSegmentation() throws Exception {
42+
StoreHandle segmentation = new FilesystemStore(TESTDATA.resolve("l4_sample").resolve("segmentation")).resolve();
43+
MultiscaleImage image = MultiscaleImage.open(segmentation);
44+
45+
assertInstanceOf(dev.zarr.zarrjava.ome.v0_4_zarr3.MultiscaleImage.class, image);
46+
assertEquals(5, image.getScaleLevelCount());
47+
assertEquals(Arrays.asList("c", "x", "y", "z"), image.getAxisNames());
48+
assertArrayEquals(new long[]{1, 4096, 4096, 2048}, image.openScaleLevel(0).metadata().shape);
49+
}
50+
51+
@Test
52+
void normalizedEntryCarriesCompatibilityVersion() throws Exception {
53+
MultiscaleImage image = MultiscaleImage.open(imageStoreHandle());
54+
dev.zarr.zarrjava.ome.metadata.MultiscalesEntry entry = image.getMultiscaleNode(0);
55+
assertEquals("0.4-zarr3", entry.version);
56+
assertEquals("1", entry.datasets.get(0).path);
57+
assertEquals("16-16-4", entry.datasets.get(entry.datasets.size() - 1).path);
58+
assertEquals("scale", entry.datasets.get(0).coordinateTransformations.get(0).type);
59+
}
60+
}

0 commit comments

Comments
 (0)