Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0846f77
Add scaffold / mock-up for displacement field transform
minnerbe Jul 15, 2026
dfaaf87
transfer logic for SOFIMA import from hot-knife
StephanPreibisch Jul 16, 2026
de93962
Add N5 universe to dependencies to render-app
minnerbe Jul 17, 2026
2e03bb0
Clean up and abstract implementation of displacement field
minnerbe Jul 17, 2026
cbef28c
Add first version of sofima importer
minnerbe Jul 17, 2026
5928c0f
Rename completeStack to completeTargetStack
minnerbe Jul 22, 2026
a4e629c
Add a caching mechanism to displacement field transform
minnerbe Jul 24, 2026
644adaf
Bump java version to 21
minnerbe Aug 3, 2026
0161f04
Update jetty environment
minnerbe Aug 3, 2026
fd00ff8
Remove obsolete pin
minnerbe Aug 3, 2026
5d57229
Update spark version
minnerbe Aug 3, 2026
759db47
Fix pinned versions and exclusions
minnerbe Aug 3, 2026
a51d33c
Add a comment about java-spark compatibility
minnerbe Aug 3, 2026
495cdaf
Merge branch 'feature/java-21' into non-rigid-precomputed
minnerbe Aug 4, 2026
4495dd7
Use n5-precomputed in sofima importer
minnerbe Aug 4, 2026
d3c7241
Fix pull vs push format of displacement field
minnerbe Aug 4, 2026
794c9b6
Make target stack argument required
minnerbe Aug 4, 2026
690086d
Add defaults and slightly change parameter interpretation
minnerbe Aug 5, 2026
dd276c9
Parallelize ImportSofimaClient
minnerbe Aug 5, 2026
e19e8d5
Actually invert the deformation field
minnerbe Aug 5, 2026
098ba7a
Get the offset from the stack bounds
minnerbe Aug 7, 2026
d00fea5
Simplify transformation string key-value arguments
minnerbe Aug 7, 2026
c917879
Merge branch 'newsolver' into non-rigid-precomputed
minnerbe Sep 12, 2026
83b66fe
Use updated n5-ng-precomputed library (different groupId, deployed)
minnerbe Sep 12, 2026
d78677d
Pull query parameter parsing into separate class
minnerbe Sep 12, 2026
c75061d
Pipe lengthy comments through /wtf claude skill
minnerbe Sep 12, 2026
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
22 changes: 22 additions & 0 deletions render-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,28 @@
<artifactId>n5-hdf5</artifactId>
</dependency>

<!-- n5-universe aggregates the n5 backends (filesystem, zarr, aws-s3, google-cloud, hdf5, blosc). Managed by pom-scijava. -->
<dependency>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5-universe</artifactId>
</dependency>

<!-- Neuroglancer-precomputed backend used by DisplacementFieldTransform to read SOFIMA warp fields. -->
<dependency>
<groupId>org.janelia</groupId>
<artifactId>n5-ng-precomputed</artifactId>
<version>0.1.0</version>
</dependency>

<!-- PrecomputedTestVolumes writes tiny precomputed volumes; reused by DisplacementFieldTransformTest. -->
<dependency>
<groupId>org.janelia</groupId>
<artifactId>n5-ng-precomputed</artifactId>
<version>0.1.0</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<!-- Version comes from the jackson.version property in the root pom, which keeps jackson-databind
in sync with jackson-core, jackson-annotations and the jaxrs provider. -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.Optional;

import net.imglib2.loops.LoopBuilder;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import org.janelia.alignment.util.QueryKeyValueParameters;
import org.janelia.saalfeldlab.n5.DataType;
import org.janelia.saalfeldlab.n5.DatasetAttributes;
import org.janelia.saalfeldlab.n5.N5FSReader;
Expand Down Expand Up @@ -67,44 +69,19 @@ public ImageProcessor load(final String urlString)

final String defaultCharsetName = Charset.defaultCharset().name();
final String basePath = URLDecoder.decode(uri.getPath(), defaultCharsetName);
final String query = uri.getQuery();
final String[] queryKeyValuePairs = query.split("&"); // note: uses "fastpath" for simple regex
String dataSet = null;
Long x = null;
Long y = null;
Long z = null;
Integer width = null;
Integer height = null;
for (final String keyValuePair : queryKeyValuePairs) {
final String[] keyValue = keyValuePair.split("=");
if (keyValue.length == 2) {
final String key = keyValue[0];
if ("x".equals(key)){
x = Long.valueOf(keyValue[1]);
} else if ("y".equals(key)) {
y = Long.valueOf(keyValue[1]);
} else if ("z".equals(key)) {
z = Long.valueOf(keyValue[1]);
} else if ("w".equals(key)) {
width = Integer.valueOf(keyValue[1]);
} else if ("h".equals(key)) {
height = Integer.valueOf(keyValue[1]);
} else if ("dataSet".equals(key)) {
dataSet = URLDecoder.decode(keyValue[1], defaultCharsetName);
}
}
}
final QueryKeyValueParameters query = new QueryKeyValueParameters(uri.getQuery(), urlString);

long[] xAndYOffsets = null;
if (x != null) {
if (y != null) {
xAndYOffsets = new long[] { x, y };
} else {
xAndYOffsets = new long[] { x, 0 };
}
} else if (y != null) {
xAndYOffsets = new long[] { 0, y };
}
final Optional<String> rawDataSet = query.getString("dataSet");
final String dataSet = rawDataSet.isPresent() ? URLDecoder.decode(rawDataSet.get(), defaultCharsetName) : null;
final Long z = query.getLong("z").orElse(null);
Integer width = query.getInt("w").orElse(null);
Integer height = query.getInt("h").orElse(null);

final Optional<Long> x = query.getLong("x");
final Optional<Long> y = query.getLong("y");
final long[] xAndYOffsets = (x.isPresent() || y.isPresent())
? new long[] { x.orElse(0L), y.orElse(0L) }
: null;

if ((basePath != null) && (dataSet != null)) {

Expand All @@ -128,20 +105,13 @@ public ImageProcessor load(final String urlString)
height = (int) dimensions[1];
}

switch(dataType) {
case UINT8:
imageProcessor = UNSIGNED_BYTE_HELPER.load(reader, dataSet, width, height, xAndYOffsets, z);
break;
case INT16:
imageProcessor = SHORT_HELPER.load(reader, dataSet, width, height, xAndYOffsets, z);
break;
case FLOAT32:
imageProcessor = FLOAT_HELPER.load(reader, dataSet, width, height, xAndYOffsets, z);
break;
default:
// case INT8: case INT32: case INT64: case FLOAT64: case OBJECT: case UINT16: case UINT32: case UINT64:
throw new IllegalArgumentException("dataType " + dataType + " is not supported");
}
imageProcessor = switch (dataType) {
case UINT8 -> UNSIGNED_BYTE_HELPER.load(reader, dataSet, width, height, xAndYOffsets, z);
case INT16 -> SHORT_HELPER.load(reader, dataSet, width, height, xAndYOffsets, z);
case FLOAT32 -> FLOAT_HELPER.load(reader, dataSet, width, height, xAndYOffsets, z);
// case INT8: case INT32: case INT64: case FLOAT64: case OBJECT: case UINT16: case UINT32: case UINT64:
default -> throw new IllegalArgumentException("dataType " + dataType + " is not supported");
};

} else {
throw new IllegalArgumentException(
Expand Down
Loading
Loading