Skip to content

Commit 0a63c99

Browse files
committed
Fix: Ensure wizards function in stream mode
1 parent 2d2cd10 commit 0a63c99

7 files changed

Lines changed: 101 additions & 22 deletions

File tree

‎src/main/java/sc/fiji/snt/InteractiveTracerCanvas.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,8 @@ private void handleCanvasClick(final MouseEvent e) {
12951295
}
12961296

12971297
private void startSigmaWizard(final int canvasX, final int canvasY) {
1298-
tracerPlugin.getUI().launchSigmaPaletteAround(myOffScreenX(canvasX), myOffScreenY(canvasY));
1298+
tracerPlugin.getUI().launchSigmaPaletteAround(myOffScreenX(canvasX), myOffScreenY(canvasY),
1299+
tracerPlugin.getImagePlus().getZ());
12991300
restoreDefaultCursor();
13001301
}
13011302

‎src/main/java/sc/fiji/snt/SNTUI.java‎

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.formdev.flatlaf.extras.FlatSVGIcon;
2727
import ij.ImageListener;
2828
import ij.ImagePlus;
29+
import net.imglib2.RandomAccessibleInterval;
2930
import ij.gui.ImageCanvas;
3031
import ij.gui.ImageWindow;
3132
import ij.measure.Calibration;
@@ -5470,21 +5471,36 @@ protected void abortCurrentOperation() {// FIXME: MOVE TO SNT?
54705471
changeState(plugin.tracingHalted ? TRACING_PAUSED : WAITING_TO_START_PATH);
54715472
}
54725473

5473-
protected void launchSigmaPaletteAround(final int x, final int y) {
5474+
/**
5475+
* Crops a small region around the given point and launches the {@link SigmaPalette} preview
5476+
* grid, exactly as if the user had clicked at that position on the classic-mode tracing canvas
5477+
* (see {@code InteractiveTracerCanvas#startSigmaWizard}). Public (rather than the previous
5478+
* {@code protected}) so it can also be triggered from a Bdv/Bvv viewer action, since there is no
5479+
* classic canvas to click on in Stream mode (see {@code AbstractBigViewer.Actions#pickSigmaPointAction()}).
5480+
*
5481+
* @param x pixel X position (0-based)
5482+
* @param y pixel Y position (0-based)
5483+
* @param z 1-based Z-slice index, matching {@link ImagePlus#getZ()}'s convention
5484+
*/
5485+
public void launchSigmaPaletteAround(final int x, final int y, final int z) {
54745486

54755487
final int either_side_xy = 40;
54765488
final int either_side_z = 15;
5477-
final int z = plugin.getImagePlus().getZ();
54785489
int x_min = x - either_side_xy;
54795490
int x_max = x + either_side_xy;
54805491
int y_min = y - either_side_xy;
54815492
int y_max = y + either_side_xy;
54825493
int z_min = z - either_side_z; // 1-based index
54835494
int z_max = z + either_side_z; // 1-based index
54845495

5485-
final int originalWidth = plugin.getImagePlus().getWidth();
5486-
final int originalHeight = plugin.getImagePlus().getHeight();
5487-
final int originalDepth = plugin.getImagePlus().getNSlices();
5496+
// Bounds sourced from the RAI backing the data being traced (see SNT#getLoadedData()) rather
5497+
// than plugin.getImagePlus(), so this also works in Stream mode, where no ImagePlus/canvas
5498+
// exists. SigmaPalette itself is already mode-agnostic (its image comes from
5499+
// SNT#getLoadedDataAsImp(), a lazy wrap that works the same way regardless of mode)
5500+
final RandomAccessibleInterval<?> data = plugin.getLoadedData();
5501+
final int originalWidth = (int) data.dimension(0);
5502+
final int originalHeight = (int) data.dimension(1);
5503+
final int originalDepth = (data.numDimensions() > 2) ? (int) data.dimension(2) : 1;
54885504

54895505
if (x_min < 0) x_min = 0;
54905506
if (y_min < 0) y_min = 0;

‎src/main/java/sc/fiji/snt/gui/cmds/ComputeSecondaryImg.java‎

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,25 @@ protected void init() {
222222
resolveInput("run");
223223
snt.setCanvasLabelAllPanes("Running " + filter + "....");
224224
}
225+
if (ui != null && ui.isStreamMode()) {
226+
// MEDIAN requires useLazy==false which is exactly what Stream mode. Prune it from the choices
227+
final MutableModuleItem<String> filterItem = getInfo().getMutableInput("filter", String.class);
228+
final List<String> choices = new ArrayList<>(filterItem.getChoices());
229+
choices.remove(MEDIAN);
230+
choices.remove(NONE);
231+
filterItem.setChoices(choices);
232+
if (MEDIAN.equals(filter) || MEDIAN_ALT.equals(filter) || NONE.equals(filter)) {
233+
filter = TUBENESS;
234+
filterItem.setValue(this, TUBENESS);
235+
}
236+
// "Preprocess" (LAZY_LOADING_FALSE) eagerly allocates a full-size in-RAM image and filters
237+
// the *entire* streamed dataset
238+
useLazyChoice = LAZY_LOADING_TRUE;
239+
resolveInput("useLazyChoice");
240+
show = false; // "Display image" only applies to the now-unavailable Preprocess strategy
241+
resolveInput("show");
242+
resolveInput("triggerThicknessCmd"); // Local Thickness is a traditional ImagePlus-only Fiji plugin
243+
}
225244
resolveInput("calledFromScript");
226245
resolveInput("syncObject");
227246
updatePrompt();
@@ -317,12 +336,22 @@ private void triggerSigmaPalette() {
317336
paletteStatus = PALETTE_WAITING;
318337
break;
319338
case PALETTE_WAITING:
320-
msg("Click on a representative structure (e.g., branch point or neurite) on the image being "
321-
+ "traced. Once you have done so, a preview grid with several kernel sizes will be "
322-
+ "displayed, allowing you to better select the size(s) for the filtering operation.<br><br>"
323-
+ "If you have never used the preview grid before, you can press 'H' (<u>H</u>elp) "
324-
+ "once it opens to access its built-in documentation.",//
325-
"Click on a Representative Structure: How-To");
339+
if (ui.isStreamMode()) {
340+
msg("Activate BDV/BVV, navigate to a representative structure (e.g., branch point or neurite), "
341+
+ "hover over it, then press 'P'. Once you have done so, a preview grid with several kernel "
342+
+ "sizes will be displayed, allowing you to better select the size(s) for the "
343+
+ "filtering operation.<br><br>"
344+
+ "If you have never used the preview grid before, you can press 'H' (<u>H</u>elp) "
345+
+ "once it opens to access its built-in documentation.",//
346+
"Pick a Representative Structure: How-To");
347+
} else {
348+
msg("Click on a representative structure (e.g., branch point or neurite) on the image being "
349+
+ "traced. Once you have done so, a preview grid with several kernel sizes will be "
350+
+ "displayed, allowing you to better select the size(s) for the filtering operation.<br><br>"
351+
+ "If you have never used the preview grid before, you can press 'H' (<u>H</u>elp) "
352+
+ "once it opens to access its built-in documentation.",//
353+
"Click on a Representative Structure: How-To");
354+
}
326355
return;
327356
default:
328357
break; // do nothing;
@@ -359,7 +388,10 @@ private void updatePrompt() {
359388
//mmi.setDescription("Scale(s) are being chosen in palette");
360389
break;
361390
case PALETTE_WAITING:
362-
mmi.setLabel("Now Click on a Representative Structure...");
391+
if (ui != null && ui.isStreamMode())
392+
mmi.setLabel("Press 'P' Over a Representative Structure...");
393+
else
394+
mmi.setLabel("Now Click on a Representative Structure...");
363395
//mmi.setDescription("Once you click on the image, a preview of clicked neighborhood will open");
364396
break;
365397
default:

‎src/main/java/sc/fiji/snt/gui/cmds/CostFunctionSelectionCmd.java‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,16 @@ public void run() {
5656
// The command relies entirely on side state (image / selection / path manager); no @Parameter inputs.
5757
// There is no harvester dialog because the input map is empty
5858
if (isCanceled()) return;
59-
if (snt != null && snt.getUI() != null && snt.getUI().isStreamMode()) {
60-
error("This option requires the entire image to be loaded into memory (RAM).");
61-
return;
62-
}
63-
if (snt == null || !snt.accessToValidImageData() || snt.getImagePlus() == null) {
59+
if (snt == null || !snt.accessToValidImageData()) {
6460
error("This option requires valid image data to be loaded.");
6561
return;
6662
}
63+
// In Stream mode there is no classic canvas/ImagePlus, so imp is null here and the PointRoi option is skipped
6764
final ImagePlus imp = snt.getImagePlus();
6865
final PathAndFillManager pafm = snt.getPathAndFillManager();
6966

70-
// 1. Extract a pair of points from PointRoi
71-
final Roi roi = imp.getRoi();
67+
// 1. Extract a pair of points from PointRoi (classic mode only; no ROI concept in Stream mode)
68+
final Roi roi = (imp != null) ? imp.getRoi() : null;
7269
PointInImage a = null;
7370
PointInImage b = null;
7471
Path probePath = null;
@@ -93,12 +90,14 @@ public void run() {
9390
}
9491

9592
if (a == null || b == null) {
93+
final boolean streamMode = snt.getUI() != null && snt.getUI().isStreamMode();
9694
error("No probe path found. The <i>Cost Function Selection Wizard</i> needs a "
9795
+ "representative neurite segment between two endpoints to run its A* comparison. "
9896
+ "You can either:</p>"
9997
+ "<ul>"
100-
+ "<li>Pause tracing in SNT and create a multi-point ROI (2+ points) across a representative "
101-
+ "neurite segment</li>"
98+
+ ((streamMode) ? "" // no classic canvas/ROI concept in Stream mode
99+
: "<li>Pause tracing in SNT and create a multi-point ROI (2+ points) across a "
100+
+ "representative neurite segment</li>")
102101
+ "<li>Trace a short path over a relevant feature</li>"
103102
+ "<li>Select a path in the Path Manager</li>"
104103
+ "</ul>"

‎src/main/java/sc/fiji/snt/viewer/AbstractBigViewer.java‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,33 @@ public void actionPerformed(final java.awt.event.ActionEvent e) {
771771
};
772772
}
773773

774+
/**
775+
* Reads the world position currently under the cursor and feeds it to {@link
776+
* SNTUI#launchSigmaPaletteAround(int, int, int)}, mirroring {@code InteractiveTracerCanvas}'s
777+
* classic-mode click handling for {@link SNTUI#WAITING_FOR_SIGMA_POINT_I}. Does nothing
778+
* _unless_ the Sigma palette is actually waiting for a point (i.e., "Select visually..." was
779+
* just pressed in the Compute Secondary Image dialog)
780+
*
781+
*/
782+
Action pickSigmaPointAction() {
783+
return new AbstractAction("Pick Point for Sigma Preview") {
784+
@Override
785+
public void actionPerformed(final java.awt.event.ActionEvent e) {
786+
if (snt == null || snt.getUI() == null
787+
|| snt.getUI().getState() != SNTUI.WAITING_FOR_SIGMA_POINT_I) {
788+
return;
789+
}
790+
final RealPoint pos = new RealPoint(3);
791+
getGlobalMouseCoordinates(pos);
792+
final int x = (int) Math.round(pos.getDoublePosition(0) / snt.getPixelWidth());
793+
final int y = (int) Math.round(pos.getDoublePosition(1) / snt.getPixelHeight());
794+
// +1: launchSigmaPaletteAround expects a 1-based Z-slice index (see ImagePlus#getZ())
795+
final int z = (int) Math.round(pos.getDoublePosition(2) / snt.getPixelDepth()) + 1;
796+
snt.getUI().launchSigmaPaletteAround(x, y, z);
797+
}
798+
};
799+
}
800+
774801
Action toggleVisibilityAction(final JComponent... componentsToDisableWhenHidden) {
775802
return new AbstractAction("Show/hide All Annotations") {
776803
@Override

‎src/main/java/sc/fiji/snt/viewer/Bdv.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,8 @@ public void actionPerformed(final java.awt.event.ActionEvent e) {
824824
sntAMap.put("snt-hide-annotations-release", actions.hideAnnotationsReleaseAction());
825825
sntIMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_L, 0), "snt-toggle-secondary-layer");
826826
sntAMap.put("snt-toggle-secondary-layer", actions.toggleSecondaryLayerTracingAction());
827+
sntIMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "snt-pick-sigma-point");
828+
sntAMap.put("snt-pick-sigma-point", actions.pickSigmaPointAction());
827829
if (tracer != null) {
828830
// Finish/discard the in-progress tracing path without a canvas click (see Bvv's identical
829831
// wiring for why Enter/Esc are used instead of a double click to finish)

‎src/main/java/sc/fiji/snt/viewer/Bvv.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,8 @@ private void attachControlPanel(final BvvSource source) {
13951395
sntAMap.put("snt-hide-annotations-release", actions.hideAnnotationsReleaseAction());
13961396
sntIMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L, 0), "snt-toggle-secondary-layer");
13971397
sntAMap.put("snt-toggle-secondary-layer", actions.toggleSecondaryLayerTracingAction());
1398+
sntIMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, 0), "snt-pick-sigma-point");
1399+
sntAMap.put("snt-pick-sigma-point", actions.pickSigmaPointAction());
13981400
if (tracer != null) {
13991401
// Finish/discard the in-progress tracing path without a canvas click: a double click to finish is itself a
14001402
// click, and its first (clickCount==1) event is indistinguishable from an ordinary "extend path" click, so

0 commit comments

Comments
 (0)