From 11735c265ee8bf31413f530d631a74b0c49a3907 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 12:15:07 -0700 Subject: [PATCH 01/16] change file name --- .../{PiezoCalibrationPanel.java => CalibrationPanel.java} | 4 ++-- .../lightsheetmanager/gui/tabs/setup/SetupPanel.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/{PiezoCalibrationPanel.java => CalibrationPanel.java} (97%) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/PiezoCalibrationPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/CalibrationPanel.java similarity index 97% rename from src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/PiezoCalibrationPanel.java rename to src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/CalibrationPanel.java index 40822a79..275372a3 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/PiezoCalibrationPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/CalibrationPanel.java @@ -15,7 +15,7 @@ import java.awt.Dimension; import java.util.Objects; -public class PiezoCalibrationPanel extends Panel { +public class CalibrationPanel extends Panel { private Button btnTwoPoint_; private Button btnUpdate_; @@ -37,7 +37,7 @@ public class PiezoCalibrationPanel extends Panel { private final PositionPanel panel_; private final LightSheetManager model_; - public PiezoCalibrationPanel(final LightSheetManager model, final PositionPanel panel, final int pathNum) { + public CalibrationPanel(final LightSheetManager model, final PositionPanel panel, final int pathNum) { super("Galvo Piezo Calibration"); model_ = Objects.requireNonNull(model); panel_ = Objects.requireNonNull(panel); diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java index e5027cdb..935959d5 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java @@ -12,7 +12,7 @@ */ public class SetupPanel extends Panel implements ListeningPanel { - private PiezoCalibrationPanel piezoPanel_; + private CalibrationPanel piezoPanel_; private BeamSheetControlPanel beamSheetPanel_; private PositionPanel positionPanel_; @@ -46,7 +46,7 @@ public SetupPanel(final LightSheetManager model, final int pathNum) { beamSheetPanel_ = new BeamSheetControlPanel(model_, pathNum); positionPanel_ = new PositionPanel(model_, pathNum); - piezoPanel_ = new PiezoCalibrationPanel(model_, positionPanel_, pathNum); + piezoPanel_ = new CalibrationPanel(model_, positionPanel_, pathNum); joystickPanel_ = new JoystickPanel(model_); excitationPanel_ = new ExcitationPanel(model_); From db86c502cb42a7255ea923f10cd86f3f63e1ac8d Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 12:20:07 -0700 Subject: [PATCH 02/16] rename setup path panel file name --- .../lightsheetmanager/gui/tabs/SetupPathTab.java | 3 +-- .../setup/{BeamSheetControlPanel.java => ScannerPanel.java} | 4 ++-- .../lightsheetmanager/gui/tabs/setup/SetupPanel.java | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) rename src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/{BeamSheetControlPanel.java => ScannerPanel.java} (98%) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java index a36e6d8e..0c14aac4 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java @@ -1,7 +1,6 @@ package org.micromanager.lightsheetmanager.gui.tabs; import org.micromanager.lightsheetmanager.api.data.CameraMode; -import org.micromanager.lightsheetmanager.api.data.GeometryType; import org.micromanager.lightsheetmanager.gui.components.Label; import org.micromanager.lightsheetmanager.gui.components.ListeningPanel; import org.micromanager.lightsheetmanager.gui.components.Panel; @@ -36,7 +35,7 @@ private void createUserInterface() { } public void swapPanels(final CameraMode cameraMode) { - setupPanel_.getBeamSheetPanel().swapPanels(cameraMode); + setupPanel_.getScannerPanel().swapPanels(cameraMode); } public int getPathNum() { diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/BeamSheetControlPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java similarity index 98% rename from src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/BeamSheetControlPanel.java rename to src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java index caf5bebe..a3bb3902 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/BeamSheetControlPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java @@ -13,7 +13,7 @@ import javax.swing.JLabel; import java.util.Objects; -public class BeamSheetControlPanel extends Panel { +public class ScannerPanel extends Panel { // first panel private TextField txtSlope_; @@ -50,7 +50,7 @@ public class BeamSheetControlPanel extends Panel { private final LightSheetManager model_; - public BeamSheetControlPanel(final LightSheetManager model, final int pathNum) { + public ScannerPanel(final LightSheetManager model, final int pathNum) { super("Light Sheet Synchronization"); model_ = Objects.requireNonNull(model); pathNum_ = pathNum; diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java index 935959d5..884b0952 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java @@ -13,7 +13,7 @@ public class SetupPanel extends Panel implements ListeningPanel { private CalibrationPanel piezoPanel_; - private BeamSheetControlPanel beamSheetPanel_; + private ScannerPanel beamSheetPanel_; private PositionPanel positionPanel_; @@ -44,7 +44,7 @@ public SetupPanel(final LightSheetManager model, final int pathNum) { leftPanel_ = new Panel(); rightPanel_ = new Panel(); - beamSheetPanel_ = new BeamSheetControlPanel(model_, pathNum); + beamSheetPanel_ = new ScannerPanel(model_, pathNum); positionPanel_ = new PositionPanel(model_, pathNum); piezoPanel_ = new CalibrationPanel(model_, positionPanel_, pathNum); @@ -69,7 +69,7 @@ public SetupPanel(final LightSheetManager model, final int pathNum) { add(rightPanel_, "aligny top"); } - public BeamSheetControlPanel getBeamSheetPanel() { + public ScannerPanel getScannerPanel() { return beamSheetPanel_; } From 7381e7e3bdd4494517f3e936f2d5847e5ed9b31e Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 12:34:44 -0700 Subject: [PATCH 03/16] rename file --- .../gui/tabs/setup/{ScannerPanel.java => LightSheetPanel.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/{ScannerPanel.java => LightSheetPanel.java} (100%) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/LightSheetPanel.java similarity index 100% rename from src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java rename to src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/LightSheetPanel.java From 94cd4107170a7912b167c41cc2ea9cfb20a099fa Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 12:35:11 -0700 Subject: [PATCH 04/16] rename excitations panel to scanner panel --- .../gui/tabs/setup/{ExcitationPanel.java => ScannerPanel.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/{ExcitationPanel.java => ScannerPanel.java} (100%) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ExcitationPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java similarity index 100% rename from src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ExcitationPanel.java rename to src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java From e0cbcb16b7a45ff2d34226d03188555cb2173084 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 12:39:34 -0700 Subject: [PATCH 05/16] rename files --- .../lightsheetmanager/gui/tabs/SetupPathTab.java | 10 +--------- .../lightsheetmanager/gui/tabs/TabPanel.java | 12 +----------- .../gui/tabs/setup/LightSheetPanel.java | 4 ++-- .../gui/tabs/setup/ScannerPanel.java | 4 ++-- .../gui/tabs/setup/SetupPanel.java | 16 ++++++++-------- 5 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java index 0c14aac4..6dfe1838 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/SetupPathTab.java @@ -35,15 +35,7 @@ private void createUserInterface() { } public void swapPanels(final CameraMode cameraMode) { - setupPanel_.getScannerPanel().swapPanels(cameraMode); - } - - public int getPathNum() { - return pathNum_; - } - - public SetupPanel getSetupPanel() { - return setupPanel_; + setupPanel_.getLightSheetPanel().swapPanels(cameraMode); } @Override diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/TabPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/TabPanel.java index 0c7a0a2a..8ec172e2 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/TabPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/TabPanel.java @@ -3,7 +3,6 @@ import org.micromanager.lightsheetmanager.api.data.CameraMode; import org.micromanager.lightsheetmanager.LightSheetManagerFrame; import org.micromanager.lightsheetmanager.LightSheetManager; -import org.micromanager.lightsheetmanager.api.data.GeometryType; import org.micromanager.lightsheetmanager.model.DeviceManager; import org.micromanager.lightsheetmanager.gui.components.Panel; import org.micromanager.lightsheetmanager.gui.components.TabbedPane; @@ -13,7 +12,6 @@ /** * The tabbed pane to select between different settings panels. - * */ public class TabPanel extends Panel { @@ -26,7 +24,7 @@ public class TabPanel extends Panel { private final TabbedPane tabbedPane_; - private DeviceManager devices_; + private final DeviceManager devices_; private final LightSheetManager model_; private final LightSheetManagerFrame frame_; @@ -105,18 +103,10 @@ public void swapSetupPathPanels(final CameraMode cameraMode) { } } - public NavigationTab getNavigationTab() { - return navigationTab_; - } - public AcquisitionTab getAcquisitionTab() { return acquisitionTab_; } - public CameraTab getCameraTab() { - return cameraTab_; - } - public SetupPathTab getSetupPathTab(final int view) { return setupPathTabs_.get(view-1); } diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/LightSheetPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/LightSheetPanel.java index a3bb3902..5b47f269 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/LightSheetPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/LightSheetPanel.java @@ -13,7 +13,7 @@ import javax.swing.JLabel; import java.util.Objects; -public class ScannerPanel extends Panel { +public class LightSheetPanel extends Panel { // first panel private TextField txtSlope_; @@ -50,7 +50,7 @@ public class ScannerPanel extends Panel { private final LightSheetManager model_; - public ScannerPanel(final LightSheetManager model, final int pathNum) { + public LightSheetPanel(final LightSheetManager model, final int pathNum) { super("Light Sheet Synchronization"); model_ = Objects.requireNonNull(model); pathNum_ = pathNum; diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java index 533269da..4ebd5eea 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java @@ -13,7 +13,7 @@ /** * Activate lasers and light sheet. */ -public class ExcitationPanel extends Panel implements ListeningPanel { +public class ScannerPanel extends Panel implements ListeningPanel { private CheckBox cbxBeamExc_; private CheckBox cbxSheetExc_; @@ -24,7 +24,7 @@ public class ExcitationPanel extends Panel implements ListeningPanel { private final LightSheetManager model_; - public ExcitationPanel(final LightSheetManager model) { + public ScannerPanel(final LightSheetManager model) { super("Scanner"); model_ = Objects.requireNonNull(model); createUserInterface(); diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java index 884b0952..e6ccb084 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/SetupPanel.java @@ -13,12 +13,12 @@ public class SetupPanel extends Panel implements ListeningPanel { private CalibrationPanel piezoPanel_; - private ScannerPanel beamSheetPanel_; + private LightSheetPanel beamSheetPanel_; private PositionPanel positionPanel_; private JoystickPanel joystickPanel_; - private ExcitationPanel excitationPanel_; + private ScannerPanel scannerPanel_; private CameraPanel cameraPanel_; private Panel leftPanel_; @@ -44,17 +44,17 @@ public SetupPanel(final LightSheetManager model, final int pathNum) { leftPanel_ = new Panel(); rightPanel_ = new Panel(); - beamSheetPanel_ = new ScannerPanel(model_, pathNum); + beamSheetPanel_ = new LightSheetPanel(model_, pathNum); positionPanel_ = new PositionPanel(model_, pathNum); piezoPanel_ = new CalibrationPanel(model_, positionPanel_, pathNum); joystickPanel_ = new JoystickPanel(model_); - excitationPanel_ = new ExcitationPanel(model_); + scannerPanel_ = new ScannerPanel(model_); cameraPanel_ = new CameraPanel(model_); // TODO: add joystick panel back in - leftPanel_.add(excitationPanel_, "growx, wrap"); - //leftPanel_.add(joystickPanel_, "growx, wrap"); + leftPanel_.add(scannerPanel_, "growx, wrap"); + leftPanel_.add(joystickPanel_, "growx, wrap"); if (model_.devices().adapter().geometry() == GeometryType.SCAPE) { singleAxisPanel_ = new SingleAxisPanel(model_); leftPanel_.add(singleAxisPanel_, "growx, wrap"); @@ -69,7 +69,7 @@ public SetupPanel(final LightSheetManager model, final int pathNum) { add(rightPanel_, "aligny top"); } - public ScannerPanel getScannerPanel() { + public LightSheetPanel getLightSheetPanel() { return beamSheetPanel_; } @@ -79,7 +79,7 @@ public int getPathNum() { @Override public void selected() { - excitationPanel_.selected(); + scannerPanel_.selected(); } @Override From 94563539d0baaac507feaf0682e6b85c50126a64 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 12:43:37 -0700 Subject: [PATCH 06/16] make combo boxes bigger --- .../lightsheetmanager/gui/tabs/setup/JoystickPanel.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index cc8a69d9..962ee096 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -34,12 +34,11 @@ private void createUserInterface() { "[]5[]" ); - // TODO: enum for combo values String[] labels = {"Imaging Piezo", "XYStage", "Imaging Slice"}; - cmbJoystick_ = new ComboBox<>(labels, "XYStage", 100, 20); - cmbLeftWheel_ = new ComboBox<>(labels, "Imaging Piezo", 100, 20); - cmbRightWheel_ = new ComboBox<>(labels, "Imaging Slice", 100, 20); + cmbJoystick_ = new ComboBox<>(labels, "XYStage", 100, 24); + cmbLeftWheel_ = new ComboBox<>(labels, "Imaging Piezo", 100, 24); + cmbRightWheel_ = new ComboBox<>(labels, "Imaging Slice", 100, 24); add(lblJoystick, ""); add(cmbJoystick_, "wrap"); From 9364b48e7e7b7b8c717e4cb91fb8c34a19dd4472 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 13:07:33 -0700 Subject: [PATCH 07/16] add check for timepoint interval < volume duration --- .../gui/tabs/setup/ScannerPanel.java | 17 ++++++++--------- .../acquisitions/AcquisitionEngineScape.java | 7 +++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java index 4ebd5eea..46afd0f0 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/ScannerPanel.java @@ -78,17 +78,16 @@ private void createEventHandlers() { }); } - cbxSheetExc_.registerListener(() -> { - - }); - - cbxBeamEpi_.registerListener(() -> { - - }); + if (model_.devices().adapter().geometry() == GeometryType.DISPIM) { + cbxSheetExc_.registerListener(() -> { + }); - cbxSheetEpi_.registerListener(() -> { + cbxBeamEpi_.registerListener(() -> { + }); - }); + cbxSheetEpi_.registerListener(() -> { + }); + } } // TODO: only handles SCAPE for now diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineScape.java b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineScape.java index f7a15170..13655585 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineScape.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineScape.java @@ -991,6 +991,13 @@ private boolean doHardwareCalculations(PLogicScape plc) { } } + if (acqSettings_.isUsingMultiplePositions() && acqSettings_.numTimePoints() > 1) { + if (timepointIntervalMs < volumeDuration) { + studio_.logs().showError("Time point interval shorter than the time to collect a single volume."); + return false; + } + } + // set exposure for imaging camera for (CameraBase camera : cameras) { camera.setExposure(exposureTime); From de789781320356b306d3da6628b1d6701e000bcc Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 13:47:53 -0700 Subject: [PATCH 08/16] use correct combo items for js panel --- .../lightsheetmanager/gui/tabs/setup/JoystickPanel.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index 962ee096..30e4bc88 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -34,11 +34,12 @@ private void createUserInterface() { "[]5[]" ); - String[] labels = {"Imaging Piezo", "XYStage", "Imaging Slice"}; + String[] joystickLabels = {"None", "Scanner", "XYStage"}; + String[] wheelLabels = {"None", "Imaging Piezo", "Imaging Slice", "Light Sheet Tilt", "Sample Height"}; - cmbJoystick_ = new ComboBox<>(labels, "XYStage", 100, 24); - cmbLeftWheel_ = new ComboBox<>(labels, "Imaging Piezo", 100, 24); - cmbRightWheel_ = new ComboBox<>(labels, "Imaging Slice", 100, 24); + cmbJoystick_ = new ComboBox<>(joystickLabels, "XYStage", 100, 24); + cmbLeftWheel_ = new ComboBox<>(wheelLabels, "Imaging Piezo", 100, 24); + cmbRightWheel_ = new ComboBox<>(wheelLabels, "Imaging Slice", 100, 24); add(lblJoystick, ""); add(cmbJoystick_, "wrap"); From 2e1edbba46234e53de76179fdeac60d3cf58c6af Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 17:05:40 -0700 Subject: [PATCH 09/16] add joytick methods to js class --- .../gui/tabs/setup/JoystickPanel.java | 91 +++++++++++++++-- .../model/devices/vendor/ASIScanner.java | 15 +-- .../model/devices/vendor/ASIXYStage.java | 7 ++ .../model/devices/vendor/ASIZStage.java | 7 ++ .../model/devices/vendor/Joystick.java | 99 +++++++++++++++++-- .../model/devices/vendor/SingleAxis.java | 4 +- 6 files changed, 201 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index 30e4bc88..34b78ce2 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -3,26 +3,56 @@ import org.micromanager.lightsheetmanager.gui.components.ComboBox; import org.micromanager.lightsheetmanager.gui.components.Panel; import org.micromanager.lightsheetmanager.LightSheetManager; +import org.micromanager.lightsheetmanager.model.devices.DeviceBase; +import org.micromanager.lightsheetmanager.model.devices.vendor.ASIScanner; +import org.micromanager.lightsheetmanager.model.devices.vendor.ASIXYStage; +import org.micromanager.lightsheetmanager.model.devices.vendor.Joystick; import javax.swing.JLabel; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; -// TODO: find a better way to organize vendor specific panels/ui elements +/** + * Control an ASI joystick. + */ public class JoystickPanel extends Panel { private ComboBox cmbJoystick_; private ComboBox cmbLeftWheel_; private ComboBox cmbRightWheel_; - private LightSheetManager model_; + private String previousDevice_; + private Map methods_; + + private final LightSheetManager model_; public JoystickPanel(final LightSheetManager model) { super("Joystick"); model_ = Objects.requireNonNull(model); + createMap(); createUserInterface(); createEventHandlers(); } + private void createMap() { + final ASIXYStage xyStage = model_.devices().device("SampleXY"); + final ASIScanner scanner = model_.devices().device("IllumSlice"); + + previousDevice_ = "None"; // set to the default value + methods_ = new HashMap<>(); + + // create map, these methods are called when switching js input + methods_.put("None", () -> { + // do nothing + }); + methods_.put("Scanner", () -> { + scanner.js().inputX(Joystick.Input.NONE); + scanner.js().inputY(Joystick.Input.NONE); + }); + methods_.put("XYStage", () -> xyStage.js().enabled(false)); + } + private void createUserInterface() { final JLabel lblJoystick = new JLabel("Joystick:"); final JLabel lblLeftWheel = new JLabel("Left Wheel:"); @@ -34,8 +64,8 @@ private void createUserInterface() { "[]5[]" ); - String[] joystickLabels = {"None", "Scanner", "XYStage"}; - String[] wheelLabels = {"None", "Imaging Piezo", "Imaging Slice", "Light Sheet Tilt", "Sample Height"}; + final String[] joystickLabels = {"None", "Scanner", "XYStage"}; + final String[] wheelLabels = {"None", "Imaging Piezo", "Imaging Slice", "Light Sheet Tilt", "Sample Height"}; cmbJoystick_ = new ComboBox<>(joystickLabels, "XYStage", 100, 24); cmbLeftWheel_ = new ComboBox<>(wheelLabels, "Imaging Piezo", 100, 24); @@ -51,16 +81,63 @@ private void createUserInterface() { private void createEventHandlers() { + // select joystick input cmbJoystick_.registerListener(() -> { - + final String selected = cmbJoystick_.getSelected(); + // disable the previous device + methods_.get(previousDevice_).run(); + // enable the selected device + switch (selected) { + case "None": + return; // early exit => do nothing + case "Scanner": + final ASIScanner scanner = model_.devices().device("IllumSlice"); + scanner.js().inputX(Joystick.Input.JOYSTICK_X); + scanner.js().inputY(Joystick.Input.JOYSTICK_Y); + break; + case "XYStage": + final ASIXYStage xyStage = model_.devices().device("SampleXY"); + xyStage.js().enabled(true); + break; + default: + break; + } + // track the previous device to disable later + previousDevice_ = selected; }); + // select left wheel input cmbLeftWheel_.registerListener(() -> { - + final String selected = cmbLeftWheel_.getSelected(); + switch (selected) { + case "Imaging Piezo": + break; + case "Imaging Slice": + break; + case "Light Sheet Tilt": + break; + case "Sample Height": + break; + default: + break; + } }); + // select right wheel input cmbRightWheel_.registerListener(() -> { - + final String selected = cmbRightWheel_.getSelected(); + switch (selected) { + case "Imaging Piezo": + break; + case "Imaging Slice": + break; + case "Light Sheet Tilt": + break; + case "Sample Height": + break; + default: + break; + } }); } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIScanner.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIScanner.java index 78838f82..881f7205 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIScanner.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIScanner.java @@ -7,30 +7,33 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -// TODO: single axis commands and joystick - /** * ASI Scanner Device - * */ public class ASIScanner extends ASITigerBase { - private SingleAxis singleAxis_; + private final SingleAxis singleAxis_; + private final Joystick joystick_; public ASIScanner(Studio studio, final String deviceName) { super(studio, deviceName); singleAxis_ = new SingleAxis(studio, deviceName); + joystick_ = new Joystick(studio, deviceName); } public SingleAxis sa() { return singleAxis_; } + public Joystick js() { + return joystick_; + } + public void setPosition(final double x, final double y) { try { core_.setGalvoPosition(deviceName_, x, y); } catch (Exception e) { - studio_.logs().showError("Could not move scanner!"); + studio_.logs().showError("Could not move the scanner!"); } } @@ -38,7 +41,7 @@ public Point2D.Double getPosition() { try { return core_.getGalvoPosition(deviceName_); } catch (Exception e) { - studio_.logs().showError("Could get the scanner position!"); + studio_.logs().showError("Could not get the scanner position!"); return new Point2D.Double(0.0, 0.0); } } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIXYStage.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIXYStage.java index 635d2fa5..86c04212 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIXYStage.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIXYStage.java @@ -9,8 +9,15 @@ public class ASIXYStage extends ASITigerBase { + private final Joystick joystick_; + public ASIXYStage(final Studio studio, final String deviceName) { super(studio, deviceName); + joystick_ = new Joystick(studio, deviceName); + } + + public Joystick js() { + return joystick_; } public void setRelativeXYPosition(final double x, final double y) { diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIZStage.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIZStage.java index 366f49df..e877c8fd 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIZStage.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIZStage.java @@ -4,8 +4,15 @@ public class ASIZStage extends ASITigerBase { + private final Joystick joystick_; + public ASIZStage(final Studio studio, final String deviceName) { super(studio, deviceName); + joystick_ = new Joystick(studio, deviceName); + } + + public Joystick js() { + return joystick_; } public void setPosition(final double position) { diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java index 02cbe647..438c4206 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java @@ -1,12 +1,99 @@ package org.micromanager.lightsheetmanager.model.devices.vendor; +import org.micromanager.Studio; +import org.micromanager.lightsheetmanager.model.devices.DeviceBase; + import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -public class Joystick { +public class Joystick extends DeviceBase { + + public Joystick(final Studio studio, final String deviceName) { + super(studio, deviceName); + } + + public void enabled(final boolean state) { + setProperty(Properties.ENABLED, state ? Values.YES : Values.NO); + } + + public boolean enabled() { + return getProperty(Properties.ENABLED).equals(Values.YES); + } + + public void input(final Input input) { + setProperty(Properties.INPUT, input.toString()); + } + + public Input input() { + return Input.fromString(getProperty(Properties.INPUT)); + } + + public void inputX(final Input input) { + setProperty(Properties.INPUT_X, input.toString()); + } + + public Input inputX() { + return Input.fromString(getProperty(Properties.INPUT_X)); + } + + public void inputY(final Input input) { + setProperty(Properties.INPUT_Y, input.toString()); + } + + public Input inputY() { + return Input.fromString(getProperty(Properties.INPUT_Y)); + } + + public void fastSpeed(final double speed) { + setProperty(Properties.FAST_SPEED, String.valueOf(speed)); + } + + public double fastSpeed() { + return Double.parseDouble(getProperty(Properties.FAST_SPEED)); + } + + public void slowSpeed(final double speed) { + setProperty(Properties.SLOW_SPEED, String.valueOf(speed)); + } + + public double slowSpeed() { + return Double.parseDouble(getProperty(Properties.SLOW_SPEED)); + } + + public void reverse(final boolean state) { + setProperty(Properties.REVERSE, state ? Values.YES : Values.NO); + } + + public boolean reverse() { + return getProperty(Properties.REVERSE).equals(Values.YES); + } + + public void rotate(final boolean state) { + setProperty(Properties.ROTATE, state ? Values.YES : Values.NO); + } + + public boolean rotate() { + return getProperty(Properties.ROTATE).equals(Values.YES); + } + + public static class Properties { + public static final String ENABLED = "JoystickEnabled"; + public static final String INPUT = "JoystickInput"; + public static final String INPUT_X = "JoystickInputX"; + public static final String INPUT_Y = "JoystickInputY"; + public static final String REVERSE = "JoystickReverse"; + public static final String ROTATE = "JoystickRotate"; + public static final String FAST_SPEED = "JoystickFastSpeed"; + public static final String SLOW_SPEED = "JoystickSlowSpeed"; + } + + public static class Values { + public static final String YES = "Yes"; + public static final String NO = "No"; + } - public enum JoystickInput { + public enum Input { NONE("0 - None"), JOYSTICK_X("2 - joystick X"), JOYSTICK_Y("3 - joystick Y"), @@ -15,10 +102,10 @@ public enum JoystickInput { private final String text_; - private static final Map stringToEnum = + private static final Map stringToEnum = Stream.of(values()).collect(Collectors.toMap(Object::toString, e -> e)); - JoystickInput(final String text) { + Input(final String text) { text_ = text; } @@ -27,8 +114,8 @@ public String toString() { return text_; } - public static JoystickInput fromString(final String symbol) { - return stringToEnum.getOrDefault(symbol, JoystickInput.NONE); + public static Input fromString(final String symbol) { + return stringToEnum.getOrDefault(symbol, Input.NONE); } } } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/SingleAxis.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/SingleAxis.java index 0162bfcf..d711fc4b 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/SingleAxis.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/SingleAxis.java @@ -10,7 +10,7 @@ public class SingleAxis extends DeviceBase { - public SingleAxis(Studio studio, String deviceName) { + public SingleAxis(final Studio studio, final String deviceName) { super(studio, deviceName); } @@ -204,7 +204,6 @@ public static String[] toArray() { } } - public enum ClockSource { EXTERNAL("external clock"), INTERNAL("internal 4kHz clock"); @@ -228,7 +227,6 @@ public static ClockSource fromString(final String symbol) { } } - public enum ClockPolarity { NEGATIVE("negative edge"), POSITIVE("positive edge"); From 7c0f3b8271f0d042191a1926a5cf7ded46c43942 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 17:20:25 -0700 Subject: [PATCH 10/16] fix joystick input enum --- .../lightsheetmanager/gui/tabs/setup/JoystickPanel.java | 7 +++---- .../lightsheetmanager/model/devices/vendor/Joystick.java | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index 34b78ce2..52c61543 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -3,7 +3,6 @@ import org.micromanager.lightsheetmanager.gui.components.ComboBox; import org.micromanager.lightsheetmanager.gui.components.Panel; import org.micromanager.lightsheetmanager.LightSheetManager; -import org.micromanager.lightsheetmanager.model.devices.DeviceBase; import org.micromanager.lightsheetmanager.model.devices.vendor.ASIScanner; import org.micromanager.lightsheetmanager.model.devices.vendor.ASIXYStage; import org.micromanager.lightsheetmanager.model.devices.vendor.Joystick; @@ -67,9 +66,9 @@ private void createUserInterface() { final String[] joystickLabels = {"None", "Scanner", "XYStage"}; final String[] wheelLabels = {"None", "Imaging Piezo", "Imaging Slice", "Light Sheet Tilt", "Sample Height"}; - cmbJoystick_ = new ComboBox<>(joystickLabels, "XYStage", 100, 24); - cmbLeftWheel_ = new ComboBox<>(wheelLabels, "Imaging Piezo", 100, 24); - cmbRightWheel_ = new ComboBox<>(wheelLabels, "Imaging Slice", 100, 24); + cmbJoystick_ = new ComboBox<>(joystickLabels, "None", 100, 24); + cmbLeftWheel_ = new ComboBox<>(wheelLabels, "None", 100, 24); + cmbRightWheel_ = new ComboBox<>(wheelLabels, "None", 100, 24); add(lblJoystick, ""); add(cmbJoystick_, "wrap"); diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java index 438c4206..e3981988 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/Joystick.java @@ -94,7 +94,7 @@ public static class Values { } public enum Input { - NONE("0 - None"), + NONE("0 - none"), JOYSTICK_X("2 - joystick X"), JOYSTICK_Y("3 - joystick Y"), RIGHT_WHEEL("22 - right wheel"), From 6961fb07b79dd3cfbf67ad608a15a72a759c9096 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 17:42:02 -0700 Subject: [PATCH 11/16] add more to js panel --- .../gui/tabs/setup/JoystickPanel.java | 57 ++++++++++++++----- .../model/devices/vendor/ASIPiezo.java | 6 ++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index 52c61543..7e937998 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -3,6 +3,7 @@ import org.micromanager.lightsheetmanager.gui.components.ComboBox; import org.micromanager.lightsheetmanager.gui.components.Panel; import org.micromanager.lightsheetmanager.LightSheetManager; +import org.micromanager.lightsheetmanager.model.devices.vendor.ASIPiezo; import org.micromanager.lightsheetmanager.model.devices.vendor.ASIScanner; import org.micromanager.lightsheetmanager.model.devices.vendor.ASIXYStage; import org.micromanager.lightsheetmanager.model.devices.vendor.Joystick; @@ -21,7 +22,9 @@ public class JoystickPanel extends Panel { private ComboBox cmbLeftWheel_; private ComboBox cmbRightWheel_; - private String previousDevice_; + private String previousJoystick_; + private String previousLeftWheel_; + private String previousRightWheel_; private Map methods_; private final LightSheetManager model_; @@ -37,19 +40,31 @@ public JoystickPanel(final LightSheetManager model) { private void createMap() { final ASIXYStage xyStage = model_.devices().device("SampleXY"); final ASIScanner scanner = model_.devices().device("IllumSlice"); + final ASIPiezo piezo = model_.devices().device("ImagingFocus"); + + // set to the default values + previousJoystick_ = "None"; + previousLeftWheel_ = "None"; + previousRightWheel_ = "None"; - previousDevice_ = "None"; // set to the default value methods_ = new HashMap<>(); - // create map, these methods are called when switching js input - methods_.put("None", () -> { - // do nothing - }); + // joystick keys + methods_.put("None", () -> { /* do nothing */ }); methods_.put("Scanner", () -> { scanner.js().inputX(Joystick.Input.NONE); scanner.js().inputY(Joystick.Input.NONE); }); methods_.put("XYStage", () -> xyStage.js().enabled(false)); + + // wheel keys + methods_.put("Imaging Piezo", () -> piezo.js().input(Joystick.Input.NONE)); + methods_.put("Imaging Slice", () -> { + scanner.js().inputX(Joystick.Input.NONE); + scanner.js().inputY(Joystick.Input.NONE); + }); + methods_.put("Light Sheet Tilt", () -> {}); + methods_.put("Sample Height", () -> {}); } private void createUserInterface() { @@ -63,8 +78,19 @@ private void createUserInterface() { "[]5[]" ); - final String[] joystickLabels = {"None", "Scanner", "XYStage"}; - final String[] wheelLabels = {"None", "Imaging Piezo", "Imaging Slice", "Light Sheet Tilt", "Sample Height"}; + final String[] joystickLabels = { + "None", + "Scanner", + "XYStage" + }; + + final String[] wheelLabels = { + "None", + "Imaging Piezo", + "Imaging Slice", + "Light Sheet Tilt", + "Sample Height" + }; cmbJoystick_ = new ComboBox<>(joystickLabels, "None", 100, 24); cmbLeftWheel_ = new ComboBox<>(wheelLabels, "None", 100, 24); @@ -83,9 +109,7 @@ private void createEventHandlers() { // select joystick input cmbJoystick_.registerListener(() -> { final String selected = cmbJoystick_.getSelected(); - // disable the previous device - methods_.get(previousDevice_).run(); - // enable the selected device + methods_.get(previousJoystick_).run(); // disable the previous device switch (selected) { case "None": return; // early exit => do nothing @@ -102,14 +126,16 @@ private void createEventHandlers() { break; } // track the previous device to disable later - previousDevice_ = selected; + previousJoystick_ = selected; }); // select left wheel input cmbLeftWheel_.registerListener(() -> { final String selected = cmbLeftWheel_.getSelected(); + methods_.get(previousLeftWheel_).run(); // disable the previous device switch (selected) { case "Imaging Piezo": + final ASIPiezo piezo = model_.devices().device("ImagingFocus"); break; case "Imaging Slice": break; @@ -120,13 +146,17 @@ private void createEventHandlers() { default: break; } + // track the previous device to disable later + previousLeftWheel_ = selected; }); // select right wheel input cmbRightWheel_.registerListener(() -> { final String selected = cmbRightWheel_.getSelected(); + methods_.get(previousRightWheel_).run(); // disable the previous device switch (selected) { case "Imaging Piezo": + final ASIPiezo piezo = model_.devices().device("ImagingFocus"); break; case "Imaging Slice": break; @@ -137,7 +167,8 @@ private void createEventHandlers() { default: break; } + // track the previous device to disable later + previousRightWheel_ = selected; }); - } } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIPiezo.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIPiezo.java index 4e1960dd..2ee7a761 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIPiezo.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/vendor/ASIPiezo.java @@ -9,16 +9,22 @@ public class ASIPiezo extends ASITigerBase { private final SingleAxis singleAxis_; + private final Joystick joystick_; public ASIPiezo(final Studio studio, final String deviceName) { super(studio, deviceName); singleAxis_ = new SingleAxis(studio, deviceName); + joystick_ = new Joystick(studio, deviceName); } public SingleAxis sa() { return singleAxis_; } + public Joystick js() { + return joystick_; + } + public void setPosition(final double position) { try { core_.setPosition(deviceName_, position); From 32a92f5fdd842ecf7564fb607a4a327d72359cd4 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Apr 2026 18:22:17 -0700 Subject: [PATCH 12/16] improvements to js panel --- .../gui/tabs/setup/JoystickPanel.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index 7e937998..637e037f 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -6,6 +6,7 @@ import org.micromanager.lightsheetmanager.model.devices.vendor.ASIPiezo; import org.micromanager.lightsheetmanager.model.devices.vendor.ASIScanner; import org.micromanager.lightsheetmanager.model.devices.vendor.ASIXYStage; +import org.micromanager.lightsheetmanager.model.devices.vendor.ASIZStage; import org.micromanager.lightsheetmanager.model.devices.vendor.Joystick; import javax.swing.JLabel; @@ -39,6 +40,7 @@ public JoystickPanel(final LightSheetManager model) { private void createMap() { final ASIXYStage xyStage = model_.devices().device("SampleXY"); + final ASIZStage zStage = model_.devices().device("SampleZ"); final ASIScanner scanner = model_.devices().device("IllumSlice"); final ASIPiezo piezo = model_.devices().device("ImagingFocus"); @@ -63,8 +65,8 @@ private void createMap() { scanner.js().inputX(Joystick.Input.NONE); scanner.js().inputY(Joystick.Input.NONE); }); - methods_.put("Light Sheet Tilt", () -> {}); - methods_.put("Sample Height", () -> {}); + methods_.put("Light Sheet Tilt", () -> {}); // TODO: impl + methods_.put("Sample Height", () -> zStage.js().input(Joystick.Input.NONE)); } private void createUserInterface() { @@ -136,12 +138,19 @@ private void createEventHandlers() { switch (selected) { case "Imaging Piezo": final ASIPiezo piezo = model_.devices().device("ImagingFocus"); + piezo.js().input(Joystick.Input.LEFT_WHEEL); break; case "Imaging Slice": + final ASIScanner scanner = model_.devices().device("IllumSlice"); + scanner.js().inputX(Joystick.Input.LEFT_WHEEL); break; case "Light Sheet Tilt": + //final ASIZStage stage = model_.devices().device("SampleZ"); + //stage.js().input(Joystick.Input.LEFT_WHEEL); break; case "Sample Height": + final ASIZStage zStage = model_.devices().device("SampleZ"); + zStage.js().input(Joystick.Input.LEFT_WHEEL); break; default: break; @@ -157,12 +166,19 @@ private void createEventHandlers() { switch (selected) { case "Imaging Piezo": final ASIPiezo piezo = model_.devices().device("ImagingFocus"); + piezo.js().input(Joystick.Input.RIGHT_WHEEL); break; case "Imaging Slice": + final ASIScanner scanner = model_.devices().device("IllumSlice"); + scanner.js().inputX(Joystick.Input.RIGHT_WHEEL); break; case "Light Sheet Tilt": + //final ASIZStage stage = model_.devices().device("SampleZ"); + //stage.js().input(Joystick.Input.RIGHT_WHEEL); break; case "Sample Height": + final ASIZStage zStage = model_.devices().device("SampleZ"); + zStage.js().input(Joystick.Input.RIGHT_WHEEL); break; default: break; From 2aee7e26dabfe9417b6551e53a528bc5af769065 Mon Sep 17 00:00:00 2001 From: Brandon Date: Fri, 24 Apr 2026 11:50:46 -0700 Subject: [PATCH 13/16] prevent errors if not using asi hardware --- .../lightsheetmanager/gui/tabs/setup/JoystickPanel.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java index 637e037f..168d8b78 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/setup/JoystickPanel.java @@ -33,7 +33,9 @@ public class JoystickPanel extends Panel { public JoystickPanel(final LightSheetManager model) { super("Joystick"); model_ = Objects.requireNonNull(model); - createMap(); + if (model_.devices().isUsingPLogic()) { + createMap(); + } createUserInterface(); createEventHandlers(); } From db9c47fc55e38e674d8e7e7d2e7fd41b7f04d5a6 Mon Sep 17 00:00:00 2001 From: Brandon Date: Fri, 24 Apr 2026 12:07:08 -0700 Subject: [PATCH 14/16] add logging to camera reset and readout time --- .../lightsheetmanager/gui/tabs/CameraTab.java | 8 +++++++- .../model/devices/cameras/HamamatsuCamera.java | 8 ++++---- .../model/devices/cameras/PvCamera.java | 15 +++++++++------ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java index f7b0e4a5..25c7f99d 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java @@ -7,6 +7,7 @@ import org.micromanager.lightsheetmanager.gui.components.ListeningPanel; import org.micromanager.lightsheetmanager.gui.components.Panel; import org.micromanager.lightsheetmanager.LightSheetManager; +import org.micromanager.lightsheetmanager.model.devices.cameras.CameraBase; import java.awt.Font; import java.util.Objects; @@ -67,7 +68,12 @@ private void createUserInterface() { } private void createEventHandlers() { - //model_.studio().core().setROI(); + btnUnchangedROI_.registerListener(() -> { + final CameraBase[] cameras = model_.devices().imagingCameras(); + for (CameraBase camera : cameras) { + camera.setROI(); + } + }); } @Override diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/HamamatsuCamera.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/HamamatsuCamera.java index d16347c3..fca33679 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/HamamatsuCamera.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/HamamatsuCamera.java @@ -187,8 +187,8 @@ public double getReadoutTime(final CameraMode cameraMode) { default: break; } -// ReportingUtils.logDebugMessage("camera readout time computed as " + readoutTimeMs + -// " for camera " + devices_.getMMDevice(camKey)); + studio_.logs().logDebugMessage("camera readout time computed as " + + readoutTimeMs + " for camera " + deviceName_); return readoutTimeMs; } @@ -210,8 +210,8 @@ public double getResetTime(final CameraMode cameraMode) { numRowsOverhead = 10; // overhead of 9 rows plus jitter of 1 row } final double resetTimeMs = camReadoutTime + (numRowsOverhead * rowReadoutTime); -// ReportingUtils.logDebugMessage("camera reset time computed as " + resetTimeMs + -// " for camera " + devices_.getMMDevice(camKey)); + studio_.logs().logDebugMessage("camera reset time computed as " + + resetTimeMs + " for camera " + deviceName_); return resetTimeMs; // assume 10ms readout if not otherwise possible to calculate } } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/PvCamera.java b/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/PvCamera.java index 50c46434..9f725889 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/PvCamera.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/devices/cameras/PvCamera.java @@ -39,12 +39,12 @@ public static class Values { public final static String EDGE_TRIGGER = "Edge Trigger"; } - public PvCamera(Studio studio, String deviceName) { + public PvCamera(final Studio studio, final String deviceName) { super(studio, deviceName); } @Override - public void setTriggerMode(CameraMode cameraMode) { + public void setTriggerMode(final CameraMode cameraMode) { switch (cameraMode) { case EDGE: case PSEUDO_OVERLAP: @@ -99,7 +99,7 @@ public double getRowReadoutTime() { } @Override - public double getReadoutTime(CameraMode cameraMode) { + public double getReadoutTime(final CameraMode cameraMode) { double readoutTimeMs = 10.0; switch (cameraMode) { case OVERLAP: @@ -109,7 +109,7 @@ public double getReadoutTime(CameraMode cameraMode) { if (isKinetix() || isPrime95B()) { final double preTime = getPropertyFloat(Properties.PRE_TRIGGER_TIME); readoutTimeMs = preTime / 1e6; - // for safety we make sure to wait at least a quarter millisecond to trigger + // for safety, we make sure to wait at least a quarter millisecond to trigger // (may have hidden assumptions in other code about at least one tic wait) if (readoutTimeMs < 0.249) { readoutTimeMs = 0.25; @@ -131,17 +131,18 @@ public double getReadoutTime(CameraMode cameraMode) { default: break; } + studio_.logs().logDebugMessage("camera readout time computed as " + + readoutTimeMs + " for camera " + deviceName_); return readoutTimeMs; } @Override - public double getResetTime(CameraMode cameraMode) { + public double getResetTime(final CameraMode cameraMode) { double resetTimeMs; if (cameraMode == CameraMode.VIRTUAL_SLIT) { resetTimeMs = 0.0; } else { // TODO(Jon): Confirm that the Kinetix camera is like the Prime 95B - // Photometrics Prime 95B is very different from other cameras so handle it as special case if (isKinetix() || isPrime95B()) { final double trigToGlobal = getPropertyFloat(Properties.POST_TRIGGER_TIME) @@ -153,6 +154,8 @@ public double getResetTime(CameraMode cameraMode) { resetTimeMs = 14.25; // strange number just to make it easy to find later; I think the original Prime needs to be added } } + studio_.logs().logDebugMessage("camera reset time computed as " + + resetTimeMs + " for camera " + deviceName_); return resetTimeMs; } From 531e5ca14e246d546fe97abc3655d2cda743af0d Mon Sep 17 00:00:00 2001 From: Brandon Date: Fri, 24 Apr 2026 13:39:39 -0700 Subject: [PATCH 15/16] start of camera roi implemetnation --- .../lightsheetmanager/gui/tabs/CameraTab.java | 109 +++++++++++++++--- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java index 25c7f99d..60b9f929 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/CameraTab.java @@ -1,15 +1,15 @@ package org.micromanager.lightsheetmanager.gui.tabs; -import org.micromanager.lightsheetmanager.api.data.CameraMode; import org.micromanager.lightsheetmanager.gui.components.Button; -import org.micromanager.lightsheetmanager.gui.components.ComboBox; import org.micromanager.lightsheetmanager.gui.components.Label; import org.micromanager.lightsheetmanager.gui.components.ListeningPanel; import org.micromanager.lightsheetmanager.gui.components.Panel; import org.micromanager.lightsheetmanager.LightSheetManager; +import org.micromanager.lightsheetmanager.gui.components.Spinner; import org.micromanager.lightsheetmanager.model.devices.cameras.CameraBase; import java.awt.Font; +import java.awt.Rectangle; import java.util.Objects; public class CameraTab extends Panel implements ListeningPanel { @@ -20,9 +20,12 @@ public class CameraTab extends Panel implements ListeningPanel { private Button btnQuarterROI_; private Button btnEigthROI_; private Button btnCustomROI_; - private Button btnGetCurrentROI_; + private Button btnCurrentROI_; - private ComboBox cmbCameraTriggerMode_; + private Spinner spnOffsetX_; + private Spinner spnOffsetY_; + private Spinner spnWidth_; + private Spinner spnHeight_; private final LightSheetManager model_; @@ -37,8 +40,8 @@ private void createUserInterface() { final Panel pnlROI = new Panel("Imaging ROI"); - final Label lblXOffset = new Label("X Offset:"); - final Label lblYOffset = new Label("Y Offset:"); + final Label lblOffsetX = new Label("Offset X:"); + final Label lblOffsetY = new Label("Offset Y:"); final Label lblWidth = new Label("Width:"); final Label lblHeight = new Label("Height:"); @@ -48,7 +51,12 @@ private void createUserInterface() { btnQuarterROI_ = new Button("1/4", 70, 30); btnEigthROI_ = new Button("1/8", 70, 30); btnCustomROI_ = new Button("Custom", 140, 30); - btnGetCurrentROI_ = new Button("Get Current ROI", 140, 30); + btnCurrentROI_ = new Button("Get Current ROI", 140, 30); + + spnOffsetX_ = Spinner.createIntegerSpinner(0, 0, Integer.MAX_VALUE, 1); + spnOffsetY_ = Spinner.createIntegerSpinner(0, 0, Integer.MAX_VALUE, 1); + spnWidth_ = Spinner.createIntegerSpinner(0, 0, Integer.MAX_VALUE, 1); + spnHeight_ = Spinner.createIntegerSpinner(0, 0, Integer.MAX_VALUE, 1); pnlROI.add(btnUnchangedROI_, "span 2, wrap"); pnlROI.add(btnFullROI_, ""); @@ -56,24 +64,95 @@ private void createUserInterface() { pnlROI.add(btnQuarterROI_, ""); pnlROI.add(btnEigthROI_, "wrap"); pnlROI.add(btnCustomROI_, "span 2, wrap"); - pnlROI.add(lblXOffset, "wrap"); - pnlROI.add(lblYOffset, "wrap"); - pnlROI.add(lblWidth, "wrap"); - pnlROI.add(lblHeight, "wrap"); - pnlROI.add(btnGetCurrentROI_, "span 2"); - + pnlROI.add(lblOffsetX, ""); + pnlROI.add(spnOffsetX_, "wrap"); + pnlROI.add(lblOffsetY, ""); + pnlROI.add(spnOffsetY_, "wrap"); + pnlROI.add(lblWidth, ""); + pnlROI.add(spnWidth_, "wrap"); + pnlROI.add(lblHeight, ""); + pnlROI.add(spnHeight_, "wrap"); + pnlROI.add(btnCurrentROI_, "span 2"); add(lblTitle, "wrap"); add(pnlROI, "wrap"); } + // TODO: should change roi for all cameras? private void createEventHandlers() { - btnUnchangedROI_.registerListener(() -> { + // roi is full camera + btnFullROI_.registerListener(() -> { + final CameraBase[] cameras = model_.devices().imagingCameras(); + for (CameraBase camera : cameras) { + camera.setROI(camera.getResolution()); + } + }); + + // roi 1/2 + btnHalfROI_.registerListener(() -> { + final CameraBase[] cameras = model_.devices().imagingCameras(); + for (CameraBase camera : cameras) { + camera.setROI(computeCenterRectangle(camera.getResolution(), 2)); + } + }); + + // roi 1/4 + btnQuarterROI_.registerListener(() -> { + final CameraBase[] cameras = model_.devices().imagingCameras(); + for (CameraBase camera : cameras) { + camera.setROI(computeCenterRectangle(camera.getResolution(), 4)); + } + }); + + // roi 1/8 + btnEigthROI_.registerListener(() -> { + final CameraBase[] cameras = model_.devices().imagingCameras(); + for (CameraBase camera : cameras) { + camera.setROI(computeCenterRectangle(camera.getResolution(), 8)); + } + }); + + // set custom roi + btnCustomROI_.registerListener(() -> { final CameraBase[] cameras = model_.devices().imagingCameras(); for (CameraBase camera : cameras) { - camera.setROI(); + camera.setROI(customROI()); } }); + + // populate spinner with current roi + btnCurrentROI_.registerListener(() -> { + final Rectangle roi = model_.devices().firstImagingCamera().getROI(); + spnOffsetX_.setValue(roi.x); + spnOffsetY_.setValue(roi.y); + spnWidth_.setValue(roi.width); + spnHeight_.setValue(roi.height); + }); + } + + // Returns the custom ROI set by the spinners. + private Rectangle customROI() { + return new Rectangle( + spnOffsetX_.getInt(), spnOffsetY_.getInt(), + spnWidth_.getInt(), spnHeight_.getInt() + ); + } + + // Computes the ROI based on a scaling factor. + private Rectangle computeCenterRectangle(final Rectangle rect, final int scale) { + if (scale < 1) { + model_.studio().logs().showError("scale must be > 1; could not compute ROI!"); + return rect; + } + if (rect.x != 0 || rect.y != 0) { + model_.studio().logs().showError("position must be (0, 0); could not compute ROI!"); + return rect; + } + final int width = rect.width / scale; + final int height = rect.height / scale; + final int x = (rect.width - width) / 2; + final int y = (rect.height - height) / 2; + return new Rectangle(x, y, width, height); } @Override From 91fe33723552d9bd0b4c66da16c6ec1e627bf881 Mon Sep 17 00:00:00 2001 From: Brandon Date: Fri, 24 Apr 2026 16:42:23 -0700 Subject: [PATCH 16/16] add checks to verify scape pre-init setup --- .../lightsheetmanager/LightSheetManagerFrame.java | 13 +++++++++++++ .../lightsheetmanager/LightSheetManagerPlugin.java | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerFrame.java b/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerFrame.java index 587fb3d4..abd58d4b 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerFrame.java +++ b/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerFrame.java @@ -3,6 +3,7 @@ import net.miginfocom.swing.MigLayout; import org.micromanager.lightsheetmanager.api.data.GeometryType; +import org.micromanager.lightsheetmanager.api.data.LightSheetType; import org.micromanager.lightsheetmanager.gui.components.Label; import org.micromanager.lightsheetmanager.gui.data.Icons; import org.micromanager.lightsheetmanager.gui.tabs.TabPanel; @@ -45,6 +46,18 @@ public LightSheetManagerFrame(final LightSheetManager model, final boolean isLoa model_.setErrorText("SCAPE geometry does not support multiple imaging paths. " + " Use the \"SimultaneousCameras\" property to support multiple cameras."); createErrorUserInterface(); + return; + } + if (model_.devices().adapter().numIlluminationPaths() > 1) { + model_.setErrorText("SCAPE geometry can only have a single illumination path."); + createErrorUserInterface(); + return; + } + if (model_.devices().adapter().lightSheetType() == LightSheetType.SCANNED) { + model_.setErrorText("Scanned light sheets are not implemented for SCAPE geometry, " + + "please contact the developers if you need this feature."); + createErrorUserInterface(); + return; } createUserInterface(); // update after loading the settings and creating ui diff --git a/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerPlugin.java b/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerPlugin.java index 8d24b24d..f49b99f5 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerPlugin.java +++ b/src/main/java/org/micromanager/lightsheetmanager/LightSheetManagerPlugin.java @@ -14,7 +14,7 @@ public class LightSheetManagerPlugin implements MenuPlugin, SciJavaPlugin { public static final String copyright = "Applied Scientific Instrumentation (ASI), 2022-2026"; public static final String description = "A plugin to control various types of light sheet microscopes."; public static final String menuName = "Light Sheet Manager"; - public static final String version = "0.6.3"; + public static final String version = "0.6.4"; private Studio studio_; private LightSheetManager model_;