Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix/1.5.1 #550

Merged
merged 14 commits into from
Oct 21, 2024
Merged
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
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
Loading