Skip to content

Commit

Permalink
perf: user preference determines downsampling policy
Browse files Browse the repository at this point in the history
* default is conservative (fewer scale levels)
* add script for setting the user pref
  • Loading branch information
bogovicj committed Dec 5, 2024
1 parent 51d49c9 commit d90f962
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 4 deletions.
7 changes: 7 additions & 0 deletions scripts/setDownsamplingPolicy.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#@ String (visibility=MESSAGE, value="<html>Sets the downsampling policy for the N5 scale pyramid exporter<br><ul><li>Aggressive: more scale levels</li><li>Conservative: fewer scale levels</li><ul></html>") docmsg
#@ PrefService prefs
#@ String (choices={"Aggressive", "Conservative"}, style="radioButtonHorizontal") policy

prefs.put(N5ScalePyramidExporter.class, N5ScalePyramidExporter.IJ_PROPERTY_DOWNSAMPLE_POLICY, policy);

import org.janelia.saalfeldlab.n5.ij.N5ScalePyramidExporter;
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ public class N5ScalePyramidExporter extends ContextCommand implements WindowList
public static final String N5_FORMAT = "N5";
public static final String ZARR_FORMAT = "Zarr";

public static final String IJ_PROPERTY_DOWNSAMPLE_POLICY = "N5-DOWNSAMPLE-POLICY";
private static final String IJ_PROPERTY_DO_NOT_WARN = "N5-SKIP-OVERWRITE-SKIP-WARNING";

public static enum DOWNSAMPLE_POLICY {
Conservative, Aggressive
};

public static enum DOWNSAMPLE_METHOD {
Sample, Average
};
Expand All @@ -160,8 +167,6 @@ public static enum DOWNSAMPLE_METHOD {

public static final String NONE = "None";

private static final String IJ_PROPERTY_DO_NOT_WARN = "N5-SKIP-OVERWRITE-SKIP-WARNING";

@Parameter
private LogService log;

Expand Down Expand Up @@ -783,6 +788,32 @@ protected <N extends SpatialMetadataGroup<?>> N finalizeMultiscaleMetadata(final

protected <M extends N5Metadata> boolean lastScale(final int[] chunkSize, final Interval imageDimensions, final M metadata) {

// null check for tests
final String downsamplePolicy = prefs != null ?
prefs.get(getClass(), IJ_PROPERTY_DOWNSAMPLE_POLICY, DOWNSAMPLE_POLICY.Conservative.toString()) :
DOWNSAMPLE_POLICY.Conservative.toString();

switch( DOWNSAMPLE_POLICY.valueOf(downsamplePolicy)) {
case Aggressive:
return lastScaleAggressive(chunkSize, imageDimensions, metadata);
default:
return lastScaleConservative(chunkSize, imageDimensions, metadata);
}
}

/**
* A policy that aggressively downsamples data.
* <p>
* Stops downsampling if all spatial dimensions are smaller than its respective block size.
*
* @param <M> metadata type
* @param chunkSize block size
* @param imageDimensions image interval
* @param metadata metadata instance
* @return true if this should be the last scale level
*/
protected <M extends N5Metadata> boolean lastScaleAggressive(final int[] chunkSize, final Interval imageDimensions, final M metadata) {

/*
* Note: Using N5Viewer metadata, will sometimes pass a 4D interval to this method, but
* will have the metadata provide 3 (spatial) axes. The 4D interval is ordered XYZT in this case,
Expand All @@ -797,6 +828,34 @@ protected <M extends N5Metadata> boolean lastScale(final int[] chunkSize, final
return true;
}

/**
* A policy that conservatively downsamples data.
* <p>
* Stops downsampling if any spatial dimension is smaller than its respective block size.
*
* @param <M> metadata type
* @param chunkSize block size
* @param imageDimensions image interval
* @param metadata metadata instance
* @return true if this should be the last scale level
*/
protected <M extends N5Metadata> boolean lastScaleConservative(final int[] chunkSize, final Interval imageDimensions, final M metadata) {

/*
* Note: Using N5Viewer metadata, will sometimes pass a 4D interval to this method, but
* will have the metadata provide 3 (spatial) axes. The 4D interval is ordered XYZT in this case,
* so downsampling factors will be calculated correctly if time dimensions are not downsampled.
*/
final Axis[] axes = getAxes(metadata, imageDimensions.numDimensions());
final int nd = axes.length;
for (int i = 0; i < nd; i++) {
if (axes[i].getType().equals(Axis.SPACE) && imageDimensions.dimension(i) <= chunkSize[i])
return true;
}

return false;
}

protected <M extends N5DatasetMetadata> void fillResolution(final M baseMetadata, final double[] resolution) {

if (baseMetadata == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -669,12 +669,12 @@ public void testNumDownsamplingLevels() {
imp.setDimensions(2, 5, 51);

final N5ScalePyramidExporter exp = new N5ScalePyramidExporter();
exp.setOptions(imp, baseDir.getAbsolutePath(), dset, "16", true, N5ScalePyramidExporter.DOWN_AVERAGE,
exp.setOptions(imp, baseDir.getAbsolutePath(), dset, "16,16,1", true, N5ScalePyramidExporter.DOWN_AVERAGE,
N5Importer.MetadataOmeZarrKey, N5ScalePyramidExporter.RAW_COMPRESSION);
exp.run();

try (final N5Reader n5 = new N5FSReader(baseDir.getAbsolutePath())) {
assertEquals("5 scale levels", 5, n5.list(dset).length);
assertEquals("3 scale levels", 3, n5.list(dset).length);
}
}

Expand Down

0 comments on commit d90f962

Please sign in to comment.