Skip to content

Commit

Permalink
Merge pull request #550 from saalfeldlab/fix/1.5.1
Browse files Browse the repository at this point in the history
fix/1.5.1
  • Loading branch information
cmhulbert authored Oct 21, 2024
2 parents 75323a4 + f9d4957 commit 5cde7d8
Show file tree
Hide file tree
Showing 15 changed files with 206 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class ManagedMeshSettings<K> {

private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

public static final boolean DEFAULT_IS_MESH_LIST_ENABLED = false;
public static final boolean DEFAULT_IS_MESH_LIST_ENABLED = true;

public static final boolean DEFAULT_ARE_MESHES_ENABLED = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class Smooth {

public static final double DEFAULT_LAMBDA = 1.0;

public static final int DEFAULT_ITERATIONS = 1;
public static final int DEFAULT_ITERATIONS = 5;

private static boolean isBoundary(
final ArrayList<TIntHashSet> vertexTriangleLUT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.LongPredicate;
Expand Down Expand Up @@ -118,8 +119,10 @@ public List<ActionSet> makeActionSets(KeyTracker keyTracker, Supplier<ViewerPane
verifyPainteraNotDisabled(keyAction);
keyAction.verify(activeToolIsNavigationTool());
keyAction.keyMatchesBinding(LabelSourceStateKeys.SELECT_ALL);
keyAction.verify(event -> selectAllTask == null);
keyAction.onAction(keyEvent -> {
if (selectAllTask != null) {
selectAllTask.cancel(new CancellationException("Cancelled by User"));
}
selectAllTask = Tasks.createTask(() -> {
Paintera.getPaintera().getBaseView().getNode().getScene().setCursor(Cursor.WAIT);
selector.selectAll();
Expand All @@ -133,13 +136,19 @@ public List<ActionSet> makeActionSets(KeyTracker keyTracker, Supplier<ViewerPane
verifyPainteraNotDisabled(keyAction);
keyAction.verify(activeToolIsNavigationTool());
keyAction.keyMatchesBinding(LabelSourceStateKeys.SELECT_ALL_IN_CURRENT_VIEW);
keyAction.verify(event -> selectAllTask == null);
keyAction.verify(event -> getActiveViewer.get() != null);
keyAction.onAction(keyEvent -> {
if (selectAllTask != null) {
selectAllTask.cancel(new CancellationException("Cancelled by User"));
}
final ViewerPanelFX viewer = getActiveViewer.get();
selectAllTask = Tasks.createTask(() -> {
Paintera.getPaintera().getBaseView().getNode().getScene().setCursor(Cursor.WAIT);
selector.selectAllInCurrentView(getActiveViewer.get());
selector.selectAllInCurrentView(viewer);
}).onEnd((result, error) -> {
if (error != null) {
LOG.error("Error selecting all labels in view", error);
}
selectAllTask = null;
Paintera.getPaintera().getBaseView().getNode().getScene().setCursor(Cursor.DEFAULT);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import javafx.scene.paint.Color;
import net.imglib2.Volatile;
import net.imglib2.converter.Converter;
import net.imglib2.type.label.LabelMultisetType;
import net.imglib2.type.label.VolatileLabelMultisetType;
import net.imglib2.type.numeric.ARGBType;
import net.imglib2.type.numeric.IntegerType;
Expand Down Expand Up @@ -125,6 +126,9 @@ public static <T> HighlightingStreamConverter<T> forType(

LOG.debug("Getting {} for type {}", HighlightingStreamConverter.class.getSimpleName(), t);
if (t instanceof VolatileLabelMultisetType) {
return (HighlightingStreamConverter<T>)new HighlightingStreamConverterVolatileLabelMultisetType(stream);
}
if (t instanceof LabelMultisetType) {
return (HighlightingStreamConverter<T>)new HighlightingStreamConverterLabelMultisetType(stream);
}
if (t instanceof Volatile<?> && ((Volatile<?>)t).get() instanceof IntegerType<?>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package org.janelia.saalfeldlab.paintera.stream;

import net.imglib2.type.label.Label;
import net.imglib2.type.label.VolatileLabelMultisetType;
import net.imglib2.type.label.LabelMultisetType;
import net.imglib2.type.numeric.ARGBType;

public class HighlightingStreamConverterLabelMultisetType extends HighlightingStreamConverter<VolatileLabelMultisetType> {
public class HighlightingStreamConverterLabelMultisetType extends HighlightingStreamConverter<LabelMultisetType> {

final static private double ONE_OVER_255 = 1.0 / 255.0;

Expand All @@ -13,15 +12,9 @@ public HighlightingStreamConverterLabelMultisetType(final AbstractHighlightingAR
super(stream);
}

@Override
public void convert(final VolatileLabelMultisetType input, final ARGBType output) {
@Override public void convert(LabelMultisetType input, ARGBType output) {

final boolean isValid = input.isValid();
if (!isValid) {
return;
}
// entry
final var entries = input.get().entrySet();
final var entries = input.entrySet();
final int numEntries = entries.size();
if (numEntries == 0) {
final long emptyValue = 0;
Expand Down Expand Up @@ -51,5 +44,4 @@ public void convert(final VolatileLabelMultisetType input, final ARGBType output
output.set(((aInt << 8 | rInt) << 8 | gInt) << 8 | bInt);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.janelia.saalfeldlab.paintera.stream;

import net.imglib2.type.label.VolatileLabelMultisetType;
import net.imglib2.type.numeric.ARGBType;

public class HighlightingStreamConverterVolatileLabelMultisetType extends HighlightingStreamConverter<VolatileLabelMultisetType> {

private final HighlightingStreamConverterLabelMultisetType nonVolatileConverter;
public HighlightingStreamConverterVolatileLabelMultisetType(final AbstractHighlightingARGBStream stream) {

super(stream);
nonVolatileConverter = new HighlightingStreamConverterLabelMultisetType(stream);
}

public HighlightingStreamConverterLabelMultisetType getNonVolatileConverter() {
return nonVolatileConverter;
}

@Override
public void convert(final VolatileLabelMultisetType input, final ARGBType output) {

final boolean isValid = input.isValid();
if (!isValid) {
return;
}
nonVolatileConverter.convert(input.get(), output);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.janelia.saalfeldlab.bdv.fx.viewer

import bdv.viewer.Interpolation
import bdv.viewer.Source
import bdv.viewer.SourceAndConverter
import net.imglib2.converter.Converter
import net.imglib2.realtransform.AffineTransform3D
import net.imglib2.type.numeric.ARGBType
import org.janelia.saalfeldlab.paintera.data.DataSource
import org.janelia.saalfeldlab.paintera.stream.HighlightingStreamConverterVolatileLabelMultisetType

//FIXME Caleb: These are both private because imho this is a bit of a hack.
// We want to Paintera's DataSource implemenet Source over the volatile type,
// and the corrsponding SourceAndConverter has a convert also over the volatile type
// This makes it not possible get a non-volatile SourceAndConverter over the DataSource.
// So what we do here is manually unwrap, but we still want it to play nicely with the
// volatile renderer, so we need it to "equal" it's volatile version.
// I think SourceAndConverter has a `volatileConverter` that we should instead be using
// when we want volatile (most the time) and support a proper non-volatile version without
// wrapping/unwrapping this way.
private class UnwrappedDataSource<D>(val dataSource : DataSource<D, *>) : Source<D> {
override fun isPresent(t: Int) = dataSource.isPresent(t)

override fun getSource(t: Int, level: Int) = dataSource.getDataSource(t, level)

override fun getInterpolatedSource(t: Int, level: Int, method: Interpolation?) = dataSource.getInterpolatedDataSource(t, level, method)

override fun getSourceTransform(t: Int, level: Int, transform: AffineTransform3D?) {
dataSource.getSourceTransform(t, level, transform)
}

override fun getType() = dataSource.dataType

override fun getName() = dataSource.name

override fun getVoxelDimensions() = dataSource.voxelDimensions

override fun getNumMipmapLevels() = dataSource.numMipmapLevels

override fun hashCode() = dataSource.hashCode()

override fun equals(other: Any?) = dataSource == ((other as? UnwrappedDataSource<*>)?.dataSource ?: other)
}


private class WrappedSourceAndConverter<D>(val sourceAndConverter : SourceAndConverter<*>, source : Source<D>, converter : Converter<D, ARGBType>) : SourceAndConverter<D>(source, converter) {

override fun equals(other: Any?): Boolean {
return sourceAndConverter == ((other as? WrappedSourceAndConverter<*>)?.sourceAndConverter ?: other)
}

override fun hashCode(): Int {
return sourceAndConverter.hashCode()
}
}

internal fun <D : Any> getDataSourceAndConverter(sourceAndConverter: SourceAndConverter<*>): SourceAndConverter<*> {
val data = sourceAndConverter.spimSource as? DataSource<D, *> ?: return sourceAndConverter
val unwrappedDataSource = UnwrappedDataSource(data)

val converter = sourceAndConverter.converter.let {
(it as? HighlightingStreamConverterVolatileLabelMultisetType)?.nonVolatileConverter ?: it
} as Converter<D, ARGBType>

return WrappedSourceAndConverter(sourceAndConverter, unwrappedDataSource, converter)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ open class AsyncCacheWithLoader<K : Any, V>(
private val loader: suspend (K) -> V
) : Cache<K, V> {

private val loaderContext = Dispatchers.IO + Job()
private val loaderQueueContext = Dispatchers.IO + Job()
private val loaderScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private val loaderQueueScope = CoroutineScope(Dispatchers.IO + SupervisorJob())

val cacheSizeProperty = SimpleIntegerProperty()
var cacheSize by cacheSizeProperty.nonnull()
Expand All @@ -25,7 +25,7 @@ open class AsyncCacheWithLoader<K : Any, V>(
private set

fun cancelUnsubmittedLoadRequests() {
loaderQueueContext.cancelChildren()
loaderScope.coroutineContext.cancelChildren()
}

override fun getIfPresent(key: K): V? {
Expand All @@ -44,7 +44,7 @@ open class AsyncCacheWithLoader<K : Any, V>(
fun request(key: K, clear : Boolean = false): Deferred<V> = runBlocking {
cache.get(key) {
if (clear) cancelUnsubmittedLoadRequests()
async(loaderContext) { loader(key) }
loaderScope.async { loader(key) }
}.also { if (it.isCancelled) cache.invalidate(key) }
}

Expand All @@ -57,7 +57,7 @@ open class AsyncCacheWithLoader<K : Any, V>(
}

return runBlocking {
async(loaderQueueContext) {
loaderQueueScope.async {
if (!isActive) invalidate(key)
else request(key)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ import net.imglib2.parallel.TaskExecutors
import net.imglib2.realtransform.AffineTransform3D
import org.apache.commons.lang.builder.HashCodeBuilder
import org.apache.http.HttpException
import org.apache.http.client.HttpClient
import org.apache.http.client.config.RequestConfig
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.ContentType
import org.apache.http.entity.mime.MultipartEntityBuilder
import org.apache.http.impl.client.BasicCookieStore
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.util.EntityUtils
import org.janelia.saalfeldlab.bdv.fx.viewer.ViewerPanelFX
import org.janelia.saalfeldlab.bdv.fx.viewer.getDataSourceAndConverter
import org.janelia.saalfeldlab.fx.extensions.LazyForeignValue
import org.janelia.saalfeldlab.fx.ortho.OrthogonalViews.ViewerAndTransforms
import org.janelia.saalfeldlab.paintera.PainteraBaseView
Expand Down Expand Up @@ -86,9 +89,11 @@ object SamEmbeddingLoaderCache : AsyncCacheWithLoader<RenderUnitState, OnnxTenso
}

override fun handle(now: Long) {
if (requestCountDown.getAndDecrement() <= 0) {
/* currently using -1 to indicate no change to the transform */
if (requestCountDown.get() == -1) return
else if (requestCountDown.getAndDecrement() == 0) {
previousJob = load(viewer, globalToViewerTransform, sessionId)
requestCountDown.getAndSet(REQUEST_COUNTDOWN)
requestCountDown.getAndSet(-1)
}
}

Expand Down Expand Up @@ -234,6 +239,12 @@ object SamEmbeddingLoaderCache : AsyncCacheWithLoader<RenderUnitState, OnnxTenso
return super.load(sessionState)
}

val client: HttpClient = HttpClientBuilder.create()
.useSystemProperties()
.setDefaultRequestConfig(requestConfig)
.setDefaultCookieStore(BasicCookieStore())
.build()

private fun getSessionId(): String {
val url =
with(paintera.properties.segmentAnythingConfig) {
Expand All @@ -244,7 +255,6 @@ object SamEmbeddingLoaderCache : AsyncCacheWithLoader<RenderUnitState, OnnxTenso

val getSessionId = HttpGet(url)

val client = HttpClientBuilder.create().useSystemProperties().setDefaultRequestConfig(requestConfig).build()
val response = client.execute(getSessionId)
return EntityUtils.toString(response.entity!!, Charsets.UTF_8)
}
Expand Down Expand Up @@ -297,7 +307,7 @@ object SamEmbeddingLoaderCache : AsyncCacheWithLoader<RenderUnitState, OnnxTenso

val url = with(paintera.properties.segmentAnythingConfig) {
with(SegmentAnythingConfig) {
val compress = if (compressEncoding) "$COMPRESS_ENCODING_PARAMETER" else ""
val compress = if (compressEncoding) COMPRESS_ENCODING_PARAMETER else ""
"$serviceUrl/$EMBEDDING_REQUEST_ENDPOINT?$compress"
}
}
Expand Down Expand Up @@ -340,7 +350,10 @@ object SamEmbeddingLoaderCache : AsyncCacheWithLoader<RenderUnitState, OnnxTenso

fun ViewerPanelFX.getSamRenderState(globalToViewerTransform: AffineTransform3D? = null, size: Pair<Long, Long>? = null): RenderUnitState {
val activeSourceToSkip = paintera.currentSource?.sourceAndConverter?.spimSource
val sacs = state.sources.filterNot { it.spimSource == activeSourceToSkip }.toList()
val sacs = state.sources
.filterNot { it.spimSource == activeSourceToSkip }
.map { sac -> getDataSourceAndConverter<Any> (sac) } // to ensure non-volatile
.toList()
return RenderUnitState(
globalToViewerTransform?.copy() ?: AffineTransform3D().also { state.getViewerTransform(it) },
state.timepoint,
Expand All @@ -351,8 +364,8 @@ object SamEmbeddingLoaderCache : AsyncCacheWithLoader<RenderUnitState, OnnxTenso
}

private val LOG = KotlinLogging.logger { }
private const val HTTP_SUCCESS = 200;
private const val HTTP_CANCELLED = 499;
private const val HTTP_SUCCESS = 200
private const val HTTP_CANCELLED = 499
}

private data class SessionRenderUnitState(val sessionId: String, val state: RenderUnitState) : RenderUnitState(state.transform, state.timepoint, state.sources, state.width, state.height) {
Expand Down
Loading

0 comments on commit 5cde7d8

Please sign in to comment.