diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/AcquisitionTab.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/AcquisitionTab.java index 21d1f2d..3cfaa95 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/AcquisitionTab.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/AcquisitionTab.java @@ -79,6 +79,9 @@ public AcquisitionTab(final LightSheetManagerModel model) { createEventHandlers(); } + /** + * Create the user interface. + */ private void createUserInterface() { final DefaultAcquisitionSettingsSCAPE acqSettings = @@ -207,56 +210,25 @@ private void createUserInterface() { add(pnlButtons_, "span 3, gaptop 60"); } - private void acqFinishedCallback() { - try { - SwingUtilities.invokeAndWait(() -> { - btnRunAcquisition_.setState(false); - btnPauseAcquisition_.setEnabled(false); - btnSpeedTest_.setEnabled(true); - }); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - - private void runAcquisition(boolean speedTest) { - btnPauseAcquisition_.setEnabled(true); - btnSpeedTest_.setEnabled(false); - Future acqFinished = model_.acquisitions().requestRun(speedTest); - // Launch new thread to update the button when the acquisition is complete - new Thread(() -> { - try { - acqFinished.get(); - } catch (Exception e) { - e.printStackTrace(); - } - // update the GUI when acquisition complete - acqFinishedCallback(); - }).start(); - } - + /** + * Create event handlers for the user interface. + */ private void createEventHandlers() { // start/stop acquisitions btnRunAcquisition_.registerListener(e -> { if (btnRunAcquisition_.isSelected()) { runAcquisition(false); - System.out.println("request run"); } else { model_.acquisitions().requestStop(); - System.out.println("request stop"); } }); btnPauseAcquisition_.registerListener(e -> { if (btnPauseAcquisition_.isSelected()) { model_.acquisitions().requestPause(); - System.out.println("request pause"); } else { model_.acquisitions().requestResume(); - System.out.println("request resume"); } }); @@ -265,7 +237,6 @@ private void createEventHandlers() { btnSpeedTest_.registerListener(e -> runAcquisition(true)); btnRunOverviewAcq_.registerListener(e -> { - System.out.println("run overview acquisition"); // TODO: run the overview acq }); @@ -295,27 +266,29 @@ private void createEventHandlers() { cmbAcquisitionModes_.registerListener(e -> { final int index = cmbAcquisitionModes_.getSelectedIndex(); model_.acquisitions().settingsBuilder().acquisitionMode(AcquisitionMode.getByIndex(index)); - //System.out.println("getAcquisitionMode: " + model_.acquisitions().getAcquisitionSettings().getAcquisitionMode()); }); + // TODO: should timing recalc be part of setting use advanced timing value in model? // switches timing panels based on check box cbxUseAdvancedTiming_.registerListener(e -> { - final boolean state = cbxUseAdvancedTiming_.isSelected(); - model_.acquisitions().settingsBuilder().useAdvancedTiming(state); - switchTimingSettings(state); + final boolean useAdvTiming = cbxUseAdvancedTiming_.isSelected(); + model_.acquisitions().settingsBuilder().useAdvancedTiming(useAdvTiming); + swapTimingSettingsPanels(useAdvTiming); + if (useAdvTiming) { + pnlAdvancedTiming_.updateSpinners(); + } else { + model_.acquisitions().updateAcquisitionSettings(); + model_.acquisitions().recalculateSliceTiming(); + } }); } - public SliceSettingsPanel getSliceSettingsPanel() { - return pnlSliceSettings_; - } - /** * Switch between slice timing panel and advanced timing panel. * * @param state the state of the CheckBox */ - private void switchTimingSettings(final boolean state) { + private void swapTimingSettingsPanels(final boolean state) { pnlRight_.removeAll(); if (state) { pnlRight_.add(pnlVolumeSettings_, "growx, wrap"); @@ -330,6 +303,40 @@ private void switchTimingSettings(final boolean state) { pnlRight_.repaint(); } + public SliceSettingsPanel getSliceSettingsPanel() { + return pnlSliceSettings_; + } + + private void acqFinishedCallback() { + try { + SwingUtilities.invokeAndWait(() -> { + btnRunAcquisition_.setState(false); + btnPauseAcquisition_.setEnabled(false); + btnSpeedTest_.setEnabled(true); + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + private void runAcquisition(boolean speedTest) { + btnPauseAcquisition_.setEnabled(true); + btnSpeedTest_.setEnabled(false); + Future acqFinished = model_.acquisitions().requestRun(speedTest); + // Launch new thread to update the button when the acquisition is complete + new Thread(() -> { + try { + acqFinished.get(); + } catch (Exception e) { + studio_.logs().logError("error in runAcquisition"); + } + // update the GUI when acquisition complete + acqFinishedCallback(); + }).start(); + } + @Override public void selected() { diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/AdvancedTimingPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/AdvancedTimingPanel.java index 50287a7..c24c3f4 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/AdvancedTimingPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/AdvancedTimingPanel.java @@ -136,4 +136,21 @@ private void createEventHandlers() { .timingSettingsBuilder().useAlternateScanDirection(cbxAlternateScanDirection_.isSelected()); }); } + + /** + * Updates the spinner values from the timing settings builder. + */ + public void updateSpinners() { + final DefaultTimingSettings timingSettings = model_.acquisitions() + .settingsBuilder().timingSettingsBuilder().build(); + spnDelayBeforeScan_.setDouble(timingSettings.delayBeforeScan()); + spnScansPerSlice_.setInt(timingSettings.scansPerSlice()); + spnScanDuration_.setDouble(timingSettings.scanDuration()); + spnDelayBeforeLaser_.setDouble(timingSettings.delayBeforeLaser()); + spnLaserTriggerDuration_.setDouble(timingSettings.laserTriggerDuration()); + spnDelayBeforeCamera_.setDouble(timingSettings.delayBeforeCamera()); + spnCameraTriggerDuration_.setDouble(timingSettings.cameraTriggerDuration()); + spnCameraExposure_.setDouble(timingSettings.cameraExposure()); + cbxAlternateScanDirection_.setSelected(timingSettings.useAlternateScanDirection()); + } } diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/SliceSettingsPanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/SliceSettingsPanel.java index 71ce58f..7a5282e 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/SliceSettingsPanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/acquisition/SliceSettingsPanel.java @@ -94,16 +94,25 @@ private void createEventHandlers() { spnSlicePeriod_.setEnabled(!selected); model_.acquisitions().settingsBuilder() .sliceSettingsBuilder().minimizeSlicePeriod(selected); + // update slice timing + model_.acquisitions().updateAcquisitionSettings(); + model_.acquisitions().recalculateSliceTiming(); }); spnSlicePeriod_.registerListener(e -> { model_.acquisitions().settingsBuilder() .sliceSettingsBuilder().slicePeriod(spnSlicePeriod_.getDouble()); + // update slice timing + model_.acquisitions().updateAcquisitionSettings(); + model_.acquisitions().recalculateSliceTiming(); }); spnSampleExposure_.registerListener(e -> { model_.acquisitions().settingsBuilder() .sliceSettingsBuilder().sampleExposure(spnSampleExposure_.getDouble()); + // update slice timing + model_.acquisitions().updateAcquisitionSettings(); + model_.acquisitions().recalculateSliceTiming(); }); // virtual slit panel diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/LightSheetManagerModel.java b/src/main/java/org/micromanager/lightsheetmanager/model/LightSheetManagerModel.java index 2fc9e58..10bfb95 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/LightSheetManagerModel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/LightSheetManagerModel.java @@ -1,7 +1,6 @@ package org.micromanager.lightsheetmanager.model; import mmcorej.CMMCore; -import org.micromanager.LogManager; import org.micromanager.Studio; import org.micromanager.lightsheetmanager.api.AutofocusSettings; import org.micromanager.lightsheetmanager.api.LightSheetManager; @@ -9,7 +8,6 @@ import org.micromanager.lightsheetmanager.api.VolumeSettings; import org.micromanager.lightsheetmanager.api.data.GeometryType; import org.micromanager.lightsheetmanager.model.acquisitions.AcquisitionEngine; -//import org.micromanager.lightsheetmanager.model.acquisitions.AcquisitionEngineDISPIM; import org.micromanager.lightsheetmanager.model.acquisitions.AcquisitionEngineDISPIM; import org.micromanager.lightsheetmanager.model.acquisitions.AcquisitionEngineSCAPE; import org.micromanager.lightsheetmanager.model.playlist.AcquisitionTableData; @@ -23,7 +21,6 @@ public class LightSheetManagerModel implements LightSheetManager { private final Studio studio_; private final CMMCore core_; - private final LogManager logs_; private String errorText_; @@ -39,7 +36,6 @@ public class LightSheetManagerModel implements LightSheetManager { public LightSheetManagerModel(final Studio studio) { studio_ = Objects.requireNonNull(studio); core_ = studio_.core(); - logs_ = studio_.logs(); settings_ = new UserSettings(this); xyzGrid_ = new XYZGrid(this); diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngine.java b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngine.java index 15517d8..279cd63 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngine.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngine.java @@ -16,7 +16,6 @@ import org.micromanager.data.internal.PropertyKey; import org.micromanager.lightsheetmanager.LightSheetManagerPlugin; import org.micromanager.lightsheetmanager.api.AcquisitionManager; -import org.micromanager.lightsheetmanager.api.internal.DefaultAcquisitionSettingsDISPIM; import org.micromanager.lightsheetmanager.api.internal.DefaultAcquisitionSettingsSCAPE; import org.micromanager.lightsheetmanager.gui.LightSheetManagerFrame; import org.micromanager.lightsheetmanager.model.autofocus.AutofocusRunner; @@ -69,7 +68,6 @@ public AcquisitionEngine(final LightSheetManagerModel model) { acqSettings_ = asb_.build(); } - //public abstract DefaultAcquisitionSettingsDISPIM settings(); //public abstract > T settingsBuilder(); @@ -80,6 +78,8 @@ public AcquisitionEngine(final LightSheetManagerModel model) { abstract boolean finish(); + public abstract void recalculateSliceTiming(); + public void setFrame(final LightSheetManagerFrame frame) { frame_ = Objects.requireNonNull(frame); } @@ -94,6 +94,10 @@ public void setAcquisitionSettings(final DefaultAcquisitionSettingsSCAPE acqSett acqSettings_ = acqSettings; } + public void updateAcquisitionSettings() { + acqSettings_ = asb_.build(); + } + @Override public Future requestRun(boolean speedTest) { // Run on a new thread, so it doesn't block the EDT diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineDISPIM.java b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineDISPIM.java index 08d8a8e..adf1b40 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineDISPIM.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineDISPIM.java @@ -680,6 +680,7 @@ private void doHardwareCalculationsNIDAQ() { //daq.setProperty("PropertyName", "1"); } + @Override public void recalculateSliceTiming() { // don't change timing settings if user is using advanced timing if (acqSettings_.isUsingAdvancedTiming()) { 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 4b95d09..000f5a0 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineSCAPE.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineSCAPE.java @@ -89,7 +89,7 @@ boolean run() { setAcquisitionSettings(asb_.build()); // TODO: delete later, this is the settings before everything is set up in doHardwareCalculations (used to debug) - studio_.logs().logMessage("debug info:\n" + acqSettings_.toPrettyJson()); + //studio_.logs().logMessage("debug info:\n" + acqSettings_.toPrettyJson()); final boolean isLiveModeOn = studio_.live().isLiveModeOn(); if (isLiveModeOn) { @@ -913,6 +913,7 @@ private void doHardwareCalculationsNIDAQ() { //daq.setProperty("PropertyName", "1"); } + @Override public void recalculateSliceTiming() { // update timing settings if not using advanced timing if (!acqSettings_.isUsingAdvancedTiming()) { @@ -921,8 +922,14 @@ public void recalculateSliceTiming() { } final double sliceDuration = getSliceDuration(asb_.timingSettingsBuilder()); asb_.timingSettingsBuilder().sliceDuration(sliceDuration); + //System.out.println(asb_.timingSettingsBuilder()); } + /** + * Single objective timing settings. + * + * @return a builder for DefaultTimingSettings + */ public DefaultTimingSettings.Builder getTimingFromExposure() { // Note: sliceDuration is computed in recalculateSliceTiming DefaultTimingSettings.Builder tsb = new DefaultTimingSettings.Builder(); @@ -942,7 +949,6 @@ public DefaultTimingSettings.Builder getTimingFromExposure() { final double slicePeriod = Math.max(Math.max(laserDuration, cameraTotalTime), isSlicePeriodMinimized ? 0 : desiredSlicePeriod); final double sliceDeadTime = NumberUtils.roundToQuarterMs(slicePeriod - laserDuration); - switch (cameraMode) { case PSEUDO_OVERLAP: // e.g. Kinetix tsb.scansPerSlice(1);