Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ plugins {
group = 'com.glencoesoftware.omero'
version = '0.6.0-SNAPSHOT'

sourceCompatibility = 1.11
targetCompatibility = 1.11
// Java 11 compatibility configuration
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

// Ensure UTF-8 encoding for compilation
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

repositories {
mavenCentral()
Expand All @@ -31,14 +39,47 @@ repositories {
}
}

configurations.all {
resolutionStrategy {
// Force all Jackson dependencies to version 2.14.2
eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'com.fasterxml.jackson.core' ||
details.requested.group == 'com.fasterxml.jackson.dataformat' ||
details.requested.group == 'com.fasterxml.jackson.datatype' ||
details.requested.group == 'com.fasterxml.jackson.module' ||
details.requested.group == 'com.fasterxml.jackson.jr') {
details.useVersion '2.14.2'
}
}

// Explicit force for common Jackson modules
force 'com.fasterxml.jackson.core:jackson-core:2.14.2'
force 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
force 'com.fasterxml.jackson.core:jackson-annotations:2.14.2'
}
}

dependencies {
api 'org.openmicroscopy:omero-blitz:5.8.3'

implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
implementation 'dev.zarr:jzarr:0.4.2'
implementation 'org.lasersonlab:s3fs:2.2.3'
implementation 'com.amazonaws:aws-java-sdk-s3:1.12.659'
implementation 'org.apache.tika:tika-core:1.28.5'
implementation 'net.java.dev.jna:jna:5.10.0'
implementation 'ome:formats-gpl:7.3.1'
implementation 'info.picocli:picocli:4.7.5'
implementation 'com.univocity:univocity-parsers:2.8.4'
implementation 'dev.zarr:zarr-java:0.0.4'
implementation 'javax.xml.bind:jaxb-api:2.3.0'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.3.14'
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.3.14'
implementation 'org.apache.maven:maven-artifact:3.9.4'

implementation 'com.fasterxml.jackson.core:jackson-core:2.14.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'

testImplementation 'info.picocli:picocli:4.7.5'
testImplementation 'com.glencoesoftware:bioformats2raw:0.11.0'
}
Expand Down
112 changes: 45 additions & 67 deletions src/main/java/com/glencoesoftware/omero/zarr/ZarrPixelBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@

package com.glencoesoftware.omero.zarr;

import com.bc.zarr.DataType;
import com.bc.zarr.ZarrArray;
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.glencoesoftware.omero.zarr.compat.ZArray;
import com.glencoesoftware.omero.zarr.compat.ZarrPath;
import java.awt.Dimension;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -56,7 +55,7 @@ public class ZarrPixelBuffer implements PixelBuffer {
private final Pixels pixels;

/** Root of the OME-NGFF multiscale we are operating on. */
private final Path root;
private final ZarrPath root;

/** Requested resolution level. */
private int resolutionLevel;
Expand All @@ -74,7 +73,7 @@ public class ZarrPixelBuffer implements PixelBuffer {
private final Map<String, Object> rootGroupAttributes;

/** Zarr array corresponding to the current resolution level. */
private ZarrArray array;
private ZArray array;

/**
* Mapping of Z plane indexes in full resolution to
Expand All @@ -90,10 +89,10 @@ public class ZarrPixelBuffer implements PixelBuffer {

/** Root path vs. metadata cache. */
private final
AsyncLoadingCache<Path, Map<String, Object>> zarrMetadataCache;
AsyncLoadingCache<ZarrPath, Map<String, Object>> zarrMetadataCache;

/** Array path vs. ZarrArray cache. */
private final AsyncLoadingCache<Path, ZarrArray> zarrArrayCache;
/** Array path vs. ZArray cache */
private final AsyncLoadingCache<ZarrPath, ZArray> zarrArrayCache;

/** Supported axes, X and Y are essential. */
public enum Axis {
Expand All @@ -109,10 +108,10 @@ public enum Axis {
* @param pixels Pixels metadata for the pixel buffer
* @param root The root of this buffer
*/
public ZarrPixelBuffer(Pixels pixels, Path root, Integer maxPlaneWidth,
public ZarrPixelBuffer(Pixels pixels, ZarrPath root, Integer maxPlaneWidth,
Integer maxPlaneHeight,
AsyncLoadingCache<Path, Map<String, Object>> zarrMetadataCache,
AsyncLoadingCache<Path, ZarrArray> zarrArrayCache)
AsyncLoadingCache<ZarrPath, Map<String, Object>> zarrMetadataCache,
AsyncLoadingCache<ZarrPath, ZArray> zarrArrayCache)
throws IOException {
log.info("Creating ZarrPixelBuffer");
this.pixels = pixels;
Expand All @@ -121,7 +120,13 @@ public ZarrPixelBuffer(Pixels pixels, Path root, Integer maxPlaneWidth,
this.zarrArrayCache = zarrArrayCache;
this.isRemote = root.toString().startsWith("s3://") ? true : false;
try {
rootGroupAttributes = this.zarrMetadataCache.get(this.root).get();
Map<String, Object> tmp = this.zarrMetadataCache.get(this.root).get();
if (tmp.containsKey("ome")) {
// for ngff challenge data attr are often nested within "ome" key
rootGroupAttributes = (Map<String, Object>) tmp.get("ome");
} else {
rootGroupAttributes = tmp;
}
} catch (ExecutionException | InterruptedException e) {
throw new IOException(e);
}
Expand Down Expand Up @@ -158,36 +163,6 @@ public ZarrPixelBuffer(Pixels pixels, Path root, Integer maxPlaneWidth,
});
}

/**
* Get Bio-Formats/OMERO pixels type for buffer.
*
* @return See above.
*/
public int getPixelsType() {
DataType dataType = array.getDataType();
switch (dataType) {
case u1:
return FormatTools.UINT8;
case i1:
return FormatTools.INT8;
case u2:
return FormatTools.UINT16;
case i2:
return FormatTools.INT16;
case u4:
return FormatTools.UINT32;
case i4:
return FormatTools.INT32;
case f4:
return FormatTools.FLOAT;
case f8:
return FormatTools.DOUBLE;
default:
throw new IllegalArgumentException(
"Data type " + dataType + " not supported");
}
}

/**
* Calculates the pixel length of a given NumPy like "shape".
*
Expand Down Expand Up @@ -223,43 +198,43 @@ private void read(byte[] buffer, int[] shape, int[] offset)
}
try {
ByteBuffer asByteBuffer = ByteBuffer.wrap(buffer);
DataType dataType = array.getDataType();
int dataType = array.getPixelsType();
for (int z = 0; z < planes; z++) {
if (axesOrder.containsKey(Axis.Z)) {
offset[axesOrder.get(Axis.Z)] = zIndexMap.get(originalZIndex + z);
}
switch (dataType) {
case u1:
case i1:
case FormatTools.UINT8:
case FormatTools.INT8:
array.read(buffer, shape, offset);
break;
case u2:
case i2:
case FormatTools.UINT16:
case FormatTools.INT16:
{
short[] data = (short[]) array.read(shape, offset);
asByteBuffer.asShortBuffer().put(data);
break;
}
case u4:
case i4:
case FormatTools.UINT32:
case FormatTools.INT32:
{
int[] data = (int[]) array.read(shape, offset);
asByteBuffer.asIntBuffer().put(data);
break;
}
case i8:
{
long[] data = (long[]) array.read(shape, offset);
asByteBuffer.asLongBuffer().put(data);
break;
}
case f4:
// case FormatTools.INT64:
// {
// long[] data = (long[]) array.read(shape, offset);
// asByteBuffer.asLongBuffer().put(data);
// break;
// }
case FormatTools.FLOAT:
{
float[] data = (float[]) array.read(shape, offset);
asByteBuffer.asFloatBuffer().put(data);
break;
}
case f8:
case FormatTools.DOUBLE:
{
double[] data = (double[]) array.read(shape, offset);
asByteBuffer.asDoubleBuffer().put(data);
Expand All @@ -284,7 +259,7 @@ private PixelData toPixelData(byte[] buffer) {
return null;
}
PixelData d = new PixelData(
FormatTools.getPixelTypeString(getPixelsType()),
FormatTools.getPixelTypeString(array.getPixelsType()),
ByteBuffer.wrap(buffer));
d.setOrder(ByteOrder.BIG_ENDIAN);
return d;
Expand All @@ -300,8 +275,8 @@ public int[][] getChunks() throws IOException {
List<Map<String, String>> datasets = getDatasets();
List<int[]> chunks = new ArrayList<int[]>();
for (Map<String, String> dataset : datasets) {
ZarrArray resolutionArray = ZarrArray.open(
root.resolve(dataset.get("path")));
ZarrPath dsPath = root.resolve(dataset.get("path"));
ZArray resolutionArray = dsPath.getArray();
int[] shape = resolutionArray.getChunks();
chunks.add(shape);
}
Expand Down Expand Up @@ -843,17 +818,17 @@ public byte[] calculateMessageDigest() throws IOException {

@Override
public int getByteWidth() {
return FormatTools.getBytesPerPixel(getPixelsType());
return FormatTools.getBytesPerPixel(array.getPixelsType());
}

@Override
public boolean isSigned() {
return FormatTools.isSigned(getPixelsType());
return FormatTools.isSigned(array.getPixelsType());
}

@Override
public boolean isFloat() {
return FormatTools.isFloatingPoint(getPixelsType());
return FormatTools.isFloatingPoint(array.getPixelsType());
}

@Override
Expand Down Expand Up @@ -925,6 +900,10 @@ public int getResolutionLevel() {
resolutionLevel - (resolutionLevels - 1));
}

public int getPixelsType() {
return array.getPixelsType();
}

@Override
public void setResolutionLevel(int resolutionLevel) {
if (resolutionLevel >= resolutionLevels) {
Expand All @@ -945,10 +924,9 @@ public void setResolutionLevel(int resolutionLevel) {
zIndexMap.clear();
}
try {
array = zarrArrayCache.get(
root.resolve(Integer.toString(this.resolutionLevel))).get();

ZarrArray fullResolutionArray = zarrArrayCache.get(
ZarrPath p = root.resolve(Integer.toString(this.resolutionLevel));
array = zarrArrayCache.get(p).get();
ZArray fullResolutionArray = zarrArrayCache.get(
root.resolve("0")).get();

if (axesOrder.containsKey(Axis.Z)) {
Expand Down
Loading
Loading