diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/frames/XYZGridFrame.java b/src/main/java/org/micromanager/lightsheetmanager/gui/frames/XYZGridFrame.java index 88c6504..7498d62 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/frames/XYZGridFrame.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/frames/XYZGridFrame.java @@ -20,6 +20,22 @@ public class XYZGridFrame extends JFrame { private Button btnComputeGrid_; private Button btnRunOverviewAcq_; + private JLabel lblXStart_; + private JLabel lblYStart_; + private JLabel lblZStart_; + + private JLabel lblXStop_; + private JLabel lblYStop_; + private JLabel lblZStop_; + + private JLabel lblXDelta_; + private JLabel lblYDelta_; + private JLabel lblZDelta_; + + private JLabel lblXCount_; + private JLabel lblYCount_; + private JLabel lblZCount_; + private CheckBox cbxUseX_; private CheckBox cbxUseY_; private CheckBox cbxUseZ_; @@ -50,6 +66,7 @@ public XYZGridFrame(final LightSheetManager model) { WindowPositioning.setUpBoundsMemory(this, this.getClass(), this.getClass().getSimpleName()); createUserInterface(); createEventHandlers(); + loadFromSettings(); } private void createUserInterface() { @@ -90,67 +107,67 @@ private void createUserInterface() { final Panel pnlButtons = new Panel(); // X - final JLabel lblXStart = new JLabel("X start [µm]:"); - final JLabel lblXStop = new JLabel("X stop [µm]:"); - final JLabel lblXDelta = new JLabel("X delta [µm]:"); - final JLabel lblXCount = new JLabel("Slice count:"); + lblXStart_ = new JLabel("X start [µm]:"); + lblXStop_ = new JLabel("X stop [µm]:"); + lblXDelta_ = new JLabel("X delta [µm]:"); + lblXCount_ = new JLabel("Slice count:"); spnXStart_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); spnXStop_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); spnXDelta_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); // Y - final JLabel lblYStart = new JLabel("Y start [µm]:"); - final JLabel lblYStop = new JLabel("Y stop [µm]:"); - final JLabel lblYDelta = new JLabel("Y delta [µm]:"); - final JLabel lblYCount = new JLabel("Y count:"); + lblYStart_ = new JLabel("Y start [µm]:"); + lblYStop_ = new JLabel("Y stop [µm]:"); + lblYDelta_ = new JLabel("Y delta [µm]:"); + lblYCount_ = new JLabel("Y count:"); spnYStart_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); spnYStop_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); spnYDelta_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); // Z - final JLabel lblZStart = new JLabel("Z start [µm]:"); - final JLabel lblZStop = new JLabel("Z stop [µm]:"); - final JLabel lblZDelta = new JLabel("Z delta [µm]:"); - final JLabel lblZCount = new JLabel("Z count:"); + lblZStart_ = new JLabel("Z start [µm]:"); + lblZStop_ = new JLabel("Z stop [µm]:"); + lblZDelta_ = new JLabel("Z delta [µm]:"); + lblZCount_ = new JLabel("Z count:"); spnZStart_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); spnZStop_ = Spinner.createDoubleSpinner(0.0, -Double.MAX_VALUE, Double.MAX_VALUE, 100.0); spnZDelta_ = Spinner.createDoubleSpinner(0.0,-Double.MAX_VALUE, Double.MAX_VALUE, 100.0); final Panel pnlSettings = new Panel("Grid Settings"); - final JLabel lblOverlap = new JLabel("Overlap (Y and Z) [%]"); + final JLabel lblOverlap = new JLabel("Overlap (Y and Z) [%]:"); Spinner.setDefaultSize(4); spnOverlapYZ_ = Spinner.createIntegerSpinner(10, 0, 100, 1); cbxClearPositions_ = new CheckBox("Clear position list if YZ unused", false); - pnlX.add(lblXStart, ""); + pnlX.add(lblXStart_, ""); pnlX.add(spnXStart_, "wrap"); - pnlX.add(lblXStop, ""); + pnlX.add(lblXStop_, ""); pnlX.add(spnXStop_, "wrap"); - pnlX.add(lblXDelta, ""); + pnlX.add(lblXDelta_, ""); pnlX.add(spnXDelta_, "wrap"); - pnlX.add(lblXCount, ""); + pnlX.add(lblXCount_, ""); pnlX.add(lblXCountValue_, ""); - pnlY.add(lblYStart, ""); + pnlY.add(lblYStart_, ""); pnlY.add(spnYStart_, "wrap"); - pnlY.add(lblYStop, ""); + pnlY.add(lblYStop_, ""); pnlY.add(spnYStop_, "wrap"); - pnlY.add(lblYDelta, ""); + pnlY.add(lblYDelta_, ""); pnlY.add(spnYDelta_, "wrap"); - pnlY.add(lblYCount, ""); + pnlY.add(lblYCount_, ""); pnlY.add(lblYCountValue_, ""); - pnlZ.add(lblZStart, ""); + pnlZ.add(lblZStart_, ""); pnlZ.add(spnZStart_, "wrap"); - pnlZ.add(lblZStop, ""); + pnlZ.add(lblZStop_, ""); pnlZ.add(spnZStop_, "wrap"); - pnlZ.add(lblZDelta, ""); + pnlZ.add(lblZDelta_, ""); pnlZ.add(spnZDelta_, "wrap"); - pnlZ.add(lblZCount, ""); + pnlZ.add(lblZCount_, ""); pnlZ.add(lblZCountValue_, ""); pnlSettings.add(lblOverlap, "split 2"); @@ -172,50 +189,127 @@ private void createUserInterface() { } private void createEventHandlers() { - final XYZGrid xyzGrid = model_.getXYZGrid(); + final XYZGrid grid = model_.pluginSettings().xyzGrid(); // Check Boxes - cbxUseX_.registerListener(e -> - xyzGrid.setUseX(cbxUseX_.isSelected())); - cbxUseY_.registerListener(e -> - xyzGrid.setUseY(cbxUseY_.isSelected())); - cbxUseZ_.registerListener(e -> - xyzGrid.setUseZ(cbxUseZ_.isSelected())); + cbxUseX_.registerListener(e -> { + final boolean selected = cbxUseX_.isSelected(); + grid.setUseX(selected); + setEnabledX(selected); + }); + + cbxUseY_.registerListener(e -> { + final boolean selected = cbxUseY_.isSelected(); + grid.setUseY(selected); + setEnabledY(selected); + }); + + cbxUseZ_.registerListener(e -> { + final boolean selected = cbxUseZ_.isSelected(); + grid.setUseZ(selected); + setEnabledZ(selected); + }); + + cbxClearPositions_.registerListener(e -> + grid.setClearYZ(cbxClearPositions_.isSelected())); // Spinners X spnXStart_.registerListener(e -> - xyzGrid.setStartX(spnXStart_.getDouble())); + grid.setStartX(spnXStart_.getDouble())); spnXStop_.registerListener(e -> - xyzGrid.setStopX(spnXStop_.getDouble())); + grid.setStopX(spnXStop_.getDouble())); spnXDelta_.registerListener(e -> - xyzGrid.setDeltaX(spnXDelta_.getDouble())); + grid.setDeltaX(spnXDelta_.getDouble())); // Spinners Y spnYStart_.registerListener(e -> - xyzGrid.setStartY(spnYStart_.getDouble())); + grid.setStartY(spnYStart_.getDouble())); spnYStop_.registerListener(e -> - xyzGrid.setStopY(spnYStop_.getDouble())); + grid.setStopY(spnYStop_.getDouble())); spnYDelta_.registerListener(e -> - xyzGrid.setDeltaY(spnYDelta_.getDouble())); + grid.setDeltaY(spnYDelta_.getDouble())); // Spinners Z spnZStart_.registerListener(e -> - xyzGrid.setStartZ(spnZStart_.getDouble())); + grid.setStartZ(spnZStart_.getDouble())); spnZStop_.registerListener(e -> - xyzGrid.setStopZ(spnZStop_.getDouble())); + grid.setStopZ(spnZStop_.getDouble())); spnZDelta_.registerListener(e -> - xyzGrid.setDeltaZ(spnZDelta_.getDouble())); + grid.setDeltaZ(spnZDelta_.getDouble())); // Overlap spnOverlapYZ_.registerListener(e -> - xyzGrid.setOverlapYZ(spnOverlapYZ_.getInt())); + grid.setOverlapYZ(spnOverlapYZ_.getInt())); // Buttons - btnComputeGrid_.registerListener(e -> - xyzGrid.computeGrid()); + btnComputeGrid_.registerListener(e -> { + grid.computeGrid(model_); + loadFromSettings(); + }); btnEditPositionList_.registerListener(e -> model_.studio().app().showPositionList()); btnRunOverviewAcq_.registerListener(e -> - model_.studio().logs().showError("Not implemented yet!")); + model_.studio().logs().showError("Not implemented yet!")); // TODO: !!! + } + + private void loadFromSettings() { + final XYZGrid grid = model_.pluginSettings().xyzGrid(); + + cbxUseX_.setSelected(grid.getUseX()); + cbxUseY_.setSelected(grid.getUseY()); + cbxUseZ_.setSelected(grid.getUseZ()); + cbxClearPositions_.setSelected(grid.getClearYZ()); + + spnXStart_.setValue(grid.getStartX()); + spnYStart_.setValue(grid.getStartY()); + spnZStart_.setValue(grid.getStartZ()); + + spnXStop_.setValue(grid.getStopX()); + spnYStop_.setValue(grid.getStopY()); + spnZStop_.setValue(grid.getStopZ()); + + spnXDelta_.setValue(grid.getDeltaX()); + spnYDelta_.setValue(grid.getDeltaY()); + spnZDelta_.setValue(grid.getDeltaZ()); + + spnOverlapYZ_.setValue(grid.getOverlapYZ()); + + // enable/disable based on loaded settings + setEnabledX(grid.getUseX()); + setEnabledY(grid.getUseY()); + setEnabledZ(grid.getUseZ()); + } + + private void setEnabledX(final boolean state) { + lblXStart_.setEnabled(state); + lblXStop_.setEnabled(state); + lblXDelta_.setEnabled(state); + spnXStart_.setEnabled(state); + spnXStop_.setEnabled(state); + spnXDelta_.setEnabled(state); + lblXCount_.setEnabled(state); + lblXCountValue_.setEnabled(state); + } + + private void setEnabledY(final boolean state) { + lblYStart_.setEnabled(state); + lblYStop_.setEnabled(state); + lblYDelta_.setEnabled(state); + spnYStart_.setEnabled(state); + spnYStop_.setEnabled(state); + spnYDelta_.setEnabled(state); + lblYCount_.setEnabled(state); + lblYCountValue_.setEnabled(state); + } + + private void setEnabledZ(final boolean state) { + lblZStart_.setEnabled(state); + lblZStop_.setEnabled(state); + lblZDelta_.setEnabled(state); + spnZStart_.setEnabled(state); + spnZStop_.setEnabled(state); + spnZDelta_.setEnabled(state); + lblZCount_.setEnabled(state); + lblZCountValue_.setEnabled(state); } } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/PluginSettings.java b/src/main/java/org/micromanager/lightsheetmanager/model/PluginSettings.java index 870fc2b..3570882 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/PluginSettings.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/PluginSettings.java @@ -10,6 +10,12 @@ public class PluginSettings { private boolean isPollingPositions_ = true; + private XYZGrid xyzGrid_ = new XYZGrid(); + + public XYZGrid xyzGrid() { + return xyzGrid_; + } + public void setPollingPositions(final boolean state) { isPollingPositions_ = state; } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/UserSettings.java b/src/main/java/org/micromanager/lightsheetmanager/model/UserSettings.java index 66eab6d..1e50cc7 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/UserSettings.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/UserSettings.java @@ -22,11 +22,12 @@ public class UserSettings { private final String userName_; private final MutablePropertyMapView settings_; + private static final String SETTINGS_PLUGIN = "LSM_PLUGIN_SETTINGS"; + // This is the prefix String for saving the current acquisition settings // based on the microscope geometry type, "LSM_ACQ_SETTINGS_SCAPE" for example. // Note: GeometryType will be converted to uppercase: "LSM_ACQ_SETTINGS_DISPIM". - private static final String SETTINGS_KEY = "LSM_PLUGIN_SETTINGS"; - private static final String SETTINGS_PREFIX_KEY = "LSM_ACQ_SETTINGS_"; + private static final String SETTINGS_PREFIX = "LSM_ACQ_SETTINGS_"; private static final String SETTINGS_NOT_FOUND = "Settings Not Found"; // Note: increase this value based on the amount of nested json in the settings @@ -75,7 +76,7 @@ public void load() { final GeometryType geometryType = model_.devices() .getDeviceAdapter().getMicroscopeGeometry(); - final String key = SETTINGS_PREFIX_KEY + geometryType.toString().toUpperCase(); + final String key = SETTINGS_PREFIX + geometryType.toString().toUpperCase(); final String json = settings_.getString(key, SETTINGS_NOT_FOUND); // use default settings if settings data not found in profile @@ -97,12 +98,12 @@ public void load() { } // load plugin settings or default plugin settings - final String jsonStr = settings_.getString(SETTINGS_KEY, SETTINGS_NOT_FOUND); + final String jsonStr = settings_.getString(SETTINGS_PLUGIN, SETTINGS_NOT_FOUND); if (jsonStr.equals(SETTINGS_NOT_FOUND)) { model_.studio().logs().logDebugMessage("settings not found, using default plugin settings."); } else { model_.pluginSettings(PluginSettings.fromJson(jsonStr)); - model_.studio().logs().logDebugMessage("loaded PluginSettings from " + SETTINGS_KEY + ": " + model_.studio().logs().logDebugMessage("loaded PluginSettings from " + SETTINGS_PLUGIN + ": " + model_.pluginSettings().toPrettyJson()); } } @@ -117,7 +118,7 @@ public void save() { // settings key based on geometry type final GeometryType geometryType = model_.devices() .getDeviceAdapter().getMicroscopeGeometry(); - final String key = SETTINGS_PREFIX_KEY + + final String key = SETTINGS_PREFIX + geometryType.toString().toUpperCase(); // save acquisition settings @@ -126,8 +127,8 @@ public void save() { + model_.acquisitions().settings().toPrettyJson()); // save plugin settings - settings_.putString(SETTINGS_KEY, model_.pluginSettings().toJson()); - model_.studio().logs().logDebugMessage("saved PluginSettings to " + SETTINGS_KEY + ": " + settings_.putString(SETTINGS_PLUGIN, model_.pluginSettings().toJson()); + model_.studio().logs().logDebugMessage("saved PluginSettings to " + SETTINGS_PLUGIN + ": " + model_.pluginSettings().toPrettyJson()); } diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/XYZGrid.java b/src/main/java/org/micromanager/lightsheetmanager/model/XYZGrid.java index 7410a0f..aec90c0 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/XYZGrid.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/XYZGrid.java @@ -9,8 +9,6 @@ import org.micromanager.lightsheetmanager.model.utils.GeometryUtils; import org.micromanager.lightsheetmanager.model.utils.NumberUtils; -import java.util.Objects; - /** * Creates an XYZ grid and puts it in a Micro-Manager {@code PositionList}. *

@@ -34,13 +32,10 @@ public class XYZGrid { private double deltaY_; private double deltaZ_; - private int overlapYZ_; - private boolean clearYZ_; - - private final LightSheetManager model_; + private int overlapPercentYZ_; + private boolean clearPositions_; - public XYZGrid(final LightSheetManager model) { - model_ = Objects.requireNonNull(model); + public XYZGrid() { } private int updateGridXCount() { @@ -85,10 +80,10 @@ private int updateGridZCount() { /** * Computes grid (position list as well as slices/spacing) based on current settings */ - public void computeGrid() { + public void computeGrid(final LightSheetManager model) { - XYStage xyStage = model_.devices().getDevice("SampleXY"); - Stage zStage = model_.devices().getDevice("SampleZ"); + XYStage xyStage = model.devices().getDevice("SampleXY"); + Stage zStage = model.devices().getDevice("SampleZ"); final int numX = useX_ ? updateGridXCount() : 1; final int numY = useY_ ? updateGridYCount() : 1; @@ -105,9 +100,9 @@ public void computeGrid() { if (useX_) { // TODO: update GUI with values, aliases for asb and vsb? final double speedFactor = GeometryUtils.getStageGeometricSpeedFactor( - model_.acquisitions().settings().scanSettings().scanAngleFirstView(),true); - model_.acquisitions().settingsBuilder().volumeSettingsBuilder().sliceStepSize(Math.abs(deltaX_)/speedFactor); - model_.acquisitions().settingsBuilder().volumeSettingsBuilder().slicesPerView(numX); + model.acquisitions().settings().scanSettings().scanAngleFirstView(),true); + model.acquisitions().settingsBuilder().volumeSettingsBuilder().sliceStepSize(Math.abs(deltaX_)/speedFactor); + model.acquisitions().settingsBuilder().volumeSettingsBuilder().slicesPerView(numX); // move to X center if we aren't generating a position list with it if (!useY_ && !useZ_) { xyStage.setXYPosition(centerX, xyStage.getXYPosition().y); // TODO: make convenience method? @@ -126,7 +121,7 @@ public void computeGrid() { startY = xyStage.getXYPosition().y; // Note: only the Y coordinate } - if (!useY_ && !useZ_ && !clearYZ_) { + if (!useY_ && !useZ_ && !clearPositions_) { return; // early exit => YZ unused } @@ -160,7 +155,7 @@ public void computeGrid() { } } } - model_.studio().positions().setPositionList(positionList); + model.studio().positions().setPositionList(positionList); } public boolean getUseX() { @@ -188,19 +183,19 @@ public void setUseZ(final boolean state) { } public boolean getClearYZ() { - return clearYZ_; + return clearPositions_; } public void setClearYZ(final boolean state) { - clearYZ_ = state; + clearPositions_ = state; } public void setOverlapYZ(final int value) { - overlapYZ_ = value; + overlapPercentYZ_ = value; } public int getOverlapYZ() { - return overlapYZ_; + return overlapPercentYZ_; } public double getStartX() {