Skip to content

Commit

Permalink
Merge pull request #544 from saalfeldlab/fix/defaultToN5
Browse files Browse the repository at this point in the history
fix: default to N5 as often as possible; require for new label multis…
  • Loading branch information
cmhulbert authored Jul 30, 2024
2 parents 5ae6542 + ccac7df commit fe6d660
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 71 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<main-class>org.janelia.saalfeldlab.paintera.Paintera</main-class>
<app.name>Paintera</app.name>
<app.package>paintera</app.package>
<app.version>1.3.0</app.version>
<app.version>1.3.4</app.version>
<jvm.modules>javafx.base,javafx.controls,javafx.fxml,javafx.media,javafx.swing,javafx.web,javafx.graphics,java.naming,java.management,java.sql</jvm.modules>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<windows.upgrade.uuid>f918b6f9-8685-4b50-9fbd-9be7a1209249</windows.upgrade.uuid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ private static void createAndAddNewLabelDataset(

public static void createAndAddNewLabelDataset(
final PainteraBaseView pbv,
final Supplier<String> projecDirectory,
final Supplier<String> projectDirectory,
final Consumer<Exception> exceptionHandler,
final Source<?> currentSource,
final Source<?>... allSources) {

try {
createAndAddNewLabelDataset(pbv, projecDirectory, currentSource, allSources);
createAndAddNewLabelDataset(pbv, projectDirectory, currentSource, allSources);
} catch (final Exception e) {
exceptionHandler.accept(e);
}
Expand Down
98 changes: 48 additions & 50 deletions src/main/java/org/janelia/saalfeldlab/util/n5/N5Data.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import org.janelia.saalfeldlab.n5.imglib2.N5Utils;
import org.janelia.saalfeldlab.n5.universe.metadata.N5SpatialDatasetMetadata;
import org.janelia.saalfeldlab.n5.universe.metadata.SpatialMultiscaleMetadata;
import org.janelia.saalfeldlab.paintera.Paintera;
import org.janelia.saalfeldlab.paintera.cache.WeakRefVolatileCache;
import org.janelia.saalfeldlab.paintera.data.DataSource;
import org.janelia.saalfeldlab.paintera.data.n5.N5DataSource;
Expand Down Expand Up @@ -69,7 +68,7 @@ public class N5Data {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param priority in fetching queue
* @param <T> data type
Expand All @@ -95,7 +94,7 @@ ImagesWithTransform<T, V> openRaw(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -131,7 +130,7 @@ DataSource<T, V> openRawAsSource(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -163,7 +162,7 @@ DataSource<T, V> openScalarAsSource(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -197,7 +196,7 @@ DataSource<T, V> openScalarAsSource(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -256,7 +255,7 @@ ImagesWithTransform<T, V> openRaw(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -287,7 +286,7 @@ ImagesWithTransform<T, V> openRaw(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param priority in fetching queue
* @param <T> data type
Expand All @@ -314,7 +313,7 @@ ImagesWithTransform<T, V>[] openRawMultiscale(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param resolution voxel resolution
* @param offset offset in real world coordinates
Expand Down Expand Up @@ -419,7 +418,7 @@ ImagesWithTransform<T, V>[] openRawMultiscale(
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -481,7 +480,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param priority in fetching queue
* @return image data with cache invalidation
Expand All @@ -504,7 +503,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param resolution voxel size
* @param offset in world coordinates
Expand Down Expand Up @@ -560,7 +559,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param priority in fetching queue
* @return multi-scale image data with cache invalidation
Expand All @@ -583,7 +582,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>[
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param resolution voxel size
* @param offset in world coordinates
Expand Down Expand Up @@ -652,7 +651,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>[
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform from voxel space to world coordinates
* @param priority in fetching queue
Expand Down Expand Up @@ -705,7 +704,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>[
}

/**
* @param reader container
* @param reader N5Reader
* @param dataset dataset
* @param transform transforms voxel data into real world coordinates
* @param priority in fetching queue
Expand All @@ -716,8 +715,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>[
* @throws IOException if any N5 operation throws {@link IOException}
*/
@SuppressWarnings("unchecked")
public static <D extends NativeType<D>, T extends NativeType<T>> DataSource<D, T>
openAsLabelSource(
public static <D extends NativeType<D>, T extends NativeType<T>> DataSource<D, T> openAsLabelSource(
final N5Reader reader,
final String dataset,
final AffineTransform3D transform,
Expand All @@ -731,8 +729,8 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>[
}

/**
* @param container container
* @param group target group in {@code container}
* @param writer N5Writer
* @param group target group in {@code writer}
* @param dimensions size
* @param blockSize chunk size
* @param resolution voxel size
Expand All @@ -743,7 +741,7 @@ public static ImagesWithTransform<LabelMultisetType, VolatileLabelMultisetType>[
* @throws IOException if any n5 operation throws {@link IOException}
*/
public static void createEmptyLabelDataset(
final String container,
final N5Writer writer,
final String group,
final long[] dimensions,
final int[] blockSize,
Expand All @@ -753,12 +751,12 @@ public static void createEmptyLabelDataset(
@Nullable final int[] maxNumEntries,
final boolean labelMultiset) throws IOException {

createEmptyLabelDataset(container, group, dimensions, blockSize, resolution, offset, relativeScaleFactors, maxNumEntries, labelMultiset, false);
createEmptyLabelDataset(writer, group, dimensions, blockSize, resolution, offset, relativeScaleFactors, maxNumEntries, labelMultiset, false);
}

/**
* @param container container
* @param group target group in {@code container}
* @param writer N5Writer
* @param group target group in {@code writer}
* @param dimensions size
* @param blockSize chunk size
* @param resolution voxel size
Expand All @@ -771,7 +769,7 @@ public static void createEmptyLabelDataset(
* already exists and {@code ignorExisting} is {@code false}
*/
public static void createEmptyLabelDataset(
final String container,
final N5Writer writer,
final String group,
final long[] dimensions,
final int[] blockSize,
Expand All @@ -784,35 +782,35 @@ public static void createEmptyLabelDataset(

final Map<String, String> pd = new HashMap<>();
pd.put("type", "label");
final N5Writer n5 = Paintera.getN5Factory().newWriter(container);
final String uniqueLabelsGroup = String.format("%s/unique-labels", group);

if (!ignoreExisiting && n5.datasetExists(group))
throw new IOException(String.format("Dataset `%s' already exists in container `%s'", group, container));
var n5Uri = writer.getURI();
if (!ignoreExisiting && writer.datasetExists(group))
throw new IOException(String.format("Dataset `%s' already exists in container `%s'", group, n5Uri));

if (!n5.exists(group))
n5.createGroup(group);
if (!writer.exists(group))
writer.createGroup(group);

if (!ignoreExisiting && n5.getAttribute(group, N5Helpers.PAINTERA_DATA_KEY, JsonObject.class) != null)
throw new IOException(String.format("Group '%s' already exists in container '%s' and is a Paintera dataset", group, container));
if (!ignoreExisiting && writer.getAttribute(group, N5Helpers.PAINTERA_DATA_KEY, JsonObject.class) != null)
throw new IOException(String.format("Group '%s' already exists in container '%s' and is a Paintera dataset", group, n5Uri));

if (!ignoreExisiting && n5.exists(uniqueLabelsGroup))
throw new IOException(String.format("Unique labels group '%s' already exists in container '%s' -- conflict likely.", uniqueLabelsGroup, container));
if (!ignoreExisiting && writer.exists(uniqueLabelsGroup))
throw new IOException(String.format("Unique labels group '%s' already exists in container '%s' -- conflict likely.", uniqueLabelsGroup, n5Uri));

n5.setAttribute(group, N5Helpers.PAINTERA_DATA_KEY, pd);
n5.setAttribute(group, N5Helpers.MAX_ID_KEY, 0L);
writer.setAttribute(group, N5Helpers.PAINTERA_DATA_KEY, pd);
writer.setAttribute(group, N5Helpers.MAX_ID_KEY, 0L);

final String dataGroup = String.format("%s/data", group);
n5.createGroup(dataGroup);
writer.createGroup(dataGroup);


n5.setAttribute(dataGroup, N5Helpers.MULTI_SCALE_KEY, true);
n5.setAttribute(dataGroup, N5Helpers.OFFSET_KEY, offset);
n5.setAttribute(dataGroup, N5Helpers.RESOLUTION_KEY, resolution);
n5.setAttribute(dataGroup, N5Helpers.IS_LABEL_MULTISET_KEY, labelMultisetType);
writer.setAttribute(dataGroup, N5Helpers.MULTI_SCALE_KEY, true);
writer.setAttribute(dataGroup, N5Helpers.OFFSET_KEY, offset);
writer.setAttribute(dataGroup, N5Helpers.RESOLUTION_KEY, resolution);
writer.setAttribute(dataGroup, N5Helpers.IS_LABEL_MULTISET_KEY, labelMultisetType);

n5.createGroup(uniqueLabelsGroup);
n5.setAttribute(uniqueLabelsGroup, N5Helpers.MULTI_SCALE_KEY, true);
writer.createGroup(uniqueLabelsGroup);
writer.setAttribute(uniqueLabelsGroup, N5Helpers.MULTI_SCALE_KEY, true);

final String scaleDatasetPattern = String.format("%s/s%%d", dataGroup);
final String scaleUniqueLabelsPattern = String.format("%s/s%%d", uniqueLabelsGroup);
Expand All @@ -830,17 +828,17 @@ public static void createEmptyLabelDataset(
final String uniqeLabelsDataset = String.format(scaleUniqueLabelsPattern, scaleLevel);

if (labelMultisetType) {
n5.createDataset(dataset, scaledDimensions, blockSize, DataType.UINT8, new GzipCompression());
writer.createDataset(dataset, scaledDimensions, blockSize, DataType.UINT8, new GzipCompression());
final int maxNum = downscaledLevel < 0 ? -1 : maxNumEntries[downscaledLevel];
n5.setAttribute(dataset, N5Helpers.MAX_NUM_ENTRIES_KEY, maxNum);
n5.setAttribute(dataset, N5Helpers.IS_LABEL_MULTISET_KEY, true);
writer.setAttribute(dataset, N5Helpers.MAX_NUM_ENTRIES_KEY, maxNum);
writer.setAttribute(dataset, N5Helpers.IS_LABEL_MULTISET_KEY, true);
} else
n5.createDataset(dataset, scaledDimensions, blockSize, DataType.UINT64, new GzipCompression());
writer.createDataset(dataset, scaledDimensions, blockSize, DataType.UINT64, new GzipCompression());

n5.createDataset(uniqeLabelsDataset, scaledDimensions, blockSize, DataType.UINT64, new GzipCompression());
writer.createDataset(uniqeLabelsDataset, scaledDimensions, blockSize, DataType.UINT64, new GzipCompression());
if (scaleLevel != 0) {
n5.setAttribute(dataset, N5Helpers.DOWNSAMPLING_FACTORS_KEY, accumulatedFactors);
n5.setAttribute(uniqeLabelsDataset, N5Helpers.DOWNSAMPLING_FACTORS_KEY, accumulatedFactors);
writer.setAttribute(dataset, N5Helpers.DOWNSAMPLING_FACTORS_KEY, accumulatedFactors);
writer.setAttribute(uniqeLabelsDataset, N5Helpers.DOWNSAMPLING_FACTORS_KEY, accumulatedFactors);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ class PainteraMainWindow(val gateway: PainteraGateway = PainteraGateway()) {
{ projectDirectory.actualDirectory.absolutePath },
{ indexToState[it] })
val gson = builder.create()
val json = projectDirectory.actualDirectory
?.let { Paintera.n5Factory.openReader(it.absolutePath).getAttribute("/", PAINTERA_KEY, JsonElement::class.java) }
val json = projectDirectory.actualDirectory.absolutePath
.let { Paintera.n5Factory.openReader(it).getAttribute("/", PAINTERA_KEY, JsonElement::class.java) }
?.takeIf { it.isJsonObject }
?.asJsonObject
Paintera.n5Factory.gsonBuilder(builder)
Expand Down Expand Up @@ -156,7 +156,7 @@ class PainteraMainWindow(val gateway: PainteraGateway = PainteraGateway()) {

fun save(notify: Boolean = true) {

/* Not allowd to save if any source is RAI */
/* Not allowed to save if any source is RAI */
baseView.sourceInfo().canSourcesBeSerialized().nullable?.let { reasonSoureInfoCannotBeSerialized ->
val alert = PainteraAlerts.alert(Alert.AlertType.WARNING)
alert.title = "Cannot Serialize All Sources"
Expand Down Expand Up @@ -184,7 +184,7 @@ class PainteraMainWindow(val gateway: PainteraGateway = PainteraGateway()) {
}
}

/* Change back to the currect mode. */
/* Change back to the correct mode. */
baseView.changeMode(curMode)
}

Expand Down Expand Up @@ -331,11 +331,9 @@ class PainteraMainWindow(val gateway: PainteraGateway = PainteraGateway()) {

private const val TILDE = "~"

private fun replaceUserHomeWithTilde(path: String) = if (path.startsWith(USER_HOME)) path.replaceFirst(USER_HOME, TILDE) else path
internal fun String.homeToTilde() = if (startsWith(USER_HOME)) replaceFirst(USER_HOME, TILDE) else this

internal fun String.homeToTilde() = replaceUserHomeWithTilde(this)

internal fun String.tildeToHome() = if (this.startsWith(TILDE)) this.replaceFirst(TILDE, USER_HOME) else this
internal fun String.tildeToHome() = if (startsWith(TILDE)) replaceFirst(TILDE, USER_HOME) else this

}

Expand Down
Loading

0 comments on commit fe6d660

Please sign in to comment.