From 7a31f6eb28946934440d013c21d7f9693cf6930d Mon Sep 17 00:00:00 2001 From: Brandon Date: Fri, 21 Nov 2025 12:36:21 -0800 Subject: [PATCH] move channel settings into DefaultChannelSettings --- .../api/AcquisitionSettingsSCAPE.java | 52 -------- .../api/ChannelSettings.java | 9 +- .../api/data/CameraMode.java | 6 +- .../DefaultAcquisitionSettingsSCAPE.java | 126 +++--------------- .../api/internal/DefaultChannelSettings.java | 64 ++++++++- .../gui/tabs/channels/ChannelTable.java | 4 +- .../gui/tabs/channels/ChannelTablePanel.java | 17 ++- .../lightsheetmanager/model/PLogicSCAPE.java | 36 ++--- .../model/acquisitions/AcquisitionEngine.java | 8 +- .../acquisitions/AcquisitionEngineSCAPE.java | 28 ++-- .../acquisitions/LSMAcquisitionEvents.java | 8 +- 11 files changed, 137 insertions(+), 221 deletions(-) diff --git a/src/main/java/org/micromanager/lightsheetmanager/api/AcquisitionSettingsSCAPE.java b/src/main/java/org/micromanager/lightsheetmanager/api/AcquisitionSettingsSCAPE.java index 76731a8..c1a2c0a 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/api/AcquisitionSettingsSCAPE.java +++ b/src/main/java/org/micromanager/lightsheetmanager/api/AcquisitionSettingsSCAPE.java @@ -2,7 +2,6 @@ import org.micromanager.lightsheetmanager.api.data.AcquisitionMode; import org.micromanager.lightsheetmanager.api.data.CameraMode; -import org.micromanager.lightsheetmanager.api.data.MultiChannelMode; import org.micromanager.lightsheetmanager.api.internal.DefaultScanSettings; import org.micromanager.lightsheetmanager.api.internal.DefaultSheetCalibration; import org.micromanager.lightsheetmanager.api.internal.DefaultSliceCalibration; @@ -10,7 +9,6 @@ import org.micromanager.lightsheetmanager.api.internal.DefaultSliceSettingsLS; import org.micromanager.lightsheetmanager.api.internal.DefaultTimingSettings; import org.micromanager.lightsheetmanager.api.internal.DefaultVolumeSettings; -import org.micromanager.lightsheetmanager.model.channels.ChannelSpec; /** * Acquisition settings for SCAPE microscope geometries. @@ -26,13 +24,6 @@ interface Builder> extends AcquisitionS */ T acquisitionMode(final AcquisitionMode acqMode); - /** - * Sets the channel mode. - * - * @param channelMode the channel mode. - */ - T channelMode(final MultiChannelMode channelMode); - /** * Sets the camera mode. * @@ -103,20 +94,6 @@ interface Builder> extends AcquisitionS */ T postMoveDelay(final int postMoveDelay); - /** - * Sets the channel group. - * - * @param channelGroup the channel group. - */ - T channelGroup(final String channelGroup); - - /** - * Sets the channels array. - * - * @param channels the channel array - */ - T channels(final ChannelSpec[] channels); - /** * Sets the live scan period. * @@ -187,7 +164,6 @@ interface Builder> extends AcquisitionS * @return immutable DefaultSliceCalibration instance. */ DefaultSliceCalibration sliceCalibration(final int view); - //DefaultSliceCalibration sliceCalibration(); /** * Returns the acquisition mode. @@ -196,13 +172,6 @@ interface Builder> extends AcquisitionS */ AcquisitionMode acquisitionMode(); - /** - * Returns the channel mode. - * - * @return the channel mode. - */ - MultiChannelMode channelMode(); - /** * Returns the camera mode. * @@ -280,26 +249,5 @@ interface Builder> extends AcquisitionS */ int postMoveDelay(); - /** - * Returns the number of channels. - * - * @return the number of channels. - */ - int numChannels(); - - /** - * Returns the channel group. - * - * @return the channel group. - */ - String channelGroup(); - - /** - * Returns the channels as an array. - * - * @return the channels as an array. - */ - ChannelSpec[] channels(); - double liveScanPeriod(); } diff --git a/src/main/java/org/micromanager/lightsheetmanager/api/ChannelSettings.java b/src/main/java/org/micromanager/lightsheetmanager/api/ChannelSettings.java index 2a7bb48..8f98825 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/api/ChannelSettings.java +++ b/src/main/java/org/micromanager/lightsheetmanager/api/ChannelSettings.java @@ -1,14 +1,17 @@ package org.micromanager.lightsheetmanager.api; +import org.micromanager.lightsheetmanager.api.data.MultiChannelMode; import org.micromanager.lightsheetmanager.model.channels.ChannelSpec; public interface ChannelSettings { interface Builder { - Builder channelGroup(final String channelGroup); + Builder channelGroup(final String group); - Builder channels(); + Builder channelMode(final MultiChannelMode mode); + + Builder channels(final ChannelSpec[] channels); ChannelSettings build(); } @@ -19,6 +22,8 @@ interface Builder { String channelGroup(); + MultiChannelMode channelMode(); + String[] channelGroups(); ChannelSpec[] channels(); diff --git a/src/main/java/org/micromanager/lightsheetmanager/api/data/CameraMode.java b/src/main/java/org/micromanager/lightsheetmanager/api/data/CameraMode.java index 41d47b4..bba7d5d 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/api/data/CameraMode.java +++ b/src/main/java/org/micromanager/lightsheetmanager/api/data/CameraMode.java @@ -47,7 +47,7 @@ public static String[] toArray() { * Does camera support overlap/synchronous mode? * * @param camLib the camera device adapter - * @return + * @return {@code true} if the camera supports the mode */ public static boolean hasOverlapTrigger(final CameraLibrary camLib) { return camLib == CameraLibrary.HAMAMATSU || @@ -60,7 +60,7 @@ public static boolean hasOverlapTrigger(final CameraLibrary camLib) { * Both PCO and Photometrics 95B do (PCO panda seems to be exception but can't easily account for that) * * @param camLib the camera device adapter - * @return + * @return {@code true} if the camera supports the mode */ private static boolean hasPseudoOverlapTrigger(CameraLibrary camLib) { return camLib == CameraLibrary.PCOCAMERA || camLib == CameraLibrary.PVCAM; @@ -76,7 +76,7 @@ private static boolean hasLevelTrigger(CameraLibrary camLib) { * Does camera support light sheet mode? * * @param camLib the camera device adapter - * @return + * @return {@code true} if the camera supports the mode */ private static boolean hasLightSheetTrigger(CameraLibrary camLib) { return camLib == CameraLibrary.HAMAMATSU || diff --git a/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultAcquisitionSettingsSCAPE.java b/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultAcquisitionSettingsSCAPE.java index 5dc0fb0..3435180 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultAcquisitionSettingsSCAPE.java +++ b/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultAcquisitionSettingsSCAPE.java @@ -3,15 +3,12 @@ import org.micromanager.lightsheetmanager.api.AcquisitionSettingsSCAPE; import org.micromanager.lightsheetmanager.api.data.AcquisitionMode; import org.micromanager.lightsheetmanager.api.data.CameraMode; -import org.micromanager.lightsheetmanager.api.data.MultiChannelMode; -import org.micromanager.lightsheetmanager.model.channels.ChannelSpec; - -import java.util.Arrays; public class DefaultAcquisitionSettingsSCAPE extends DefaultAcquisitionSettings implements AcquisitionSettingsSCAPE { public static class Builder extends DefaultAcquisitionSettings.Builder implements AcquisitionSettingsSCAPE.Builder { + private DefaultChannelSettings.Builder csb_ = new DefaultChannelSettings.Builder(); private DefaultTimingSettings.Builder tsb_ = new DefaultTimingSettings.Builder(); private DefaultVolumeSettings.Builder vsb_ = new DefaultVolumeSettings.Builder(); private DefaultSliceSettings.Builder ssb_ = new DefaultSliceSettings.Builder(); @@ -20,7 +17,6 @@ public static class Builder extends DefaultAcquisitionSettings.Builder private DefaultSheetCalibration.Builder[] shcb_ = new DefaultSheetCalibration.Builder[1]; private DefaultSliceCalibration.Builder[] slcb_ = new DefaultSliceCalibration.Builder[1]; private AcquisitionMode acquisitionMode_ = AcquisitionMode.NONE; - private MultiChannelMode channelMode_ = MultiChannelMode.NONE; private CameraMode cameraMode_ = CameraMode.EDGE; private boolean useChannels_ = false; @@ -34,10 +30,6 @@ public static class Builder extends DefaultAcquisitionSettings.Builder private int numTimePoints_ = 1; private double timePointInterval_ = 0.0; private int postMoveDelay_ = 0; - - private int numChannels_ = 0; - private String channelGroup_ = ""; - private ChannelSpec[] channels_ = new ChannelSpec[]{}; private double liveScanPeriod_ = 20.0; public Builder() { @@ -49,6 +41,7 @@ public Builder() { public Builder(final DefaultAcquisitionSettingsSCAPE acqSettings) { super(acqSettings); + csb_ = acqSettings.channelSettings_.copyBuilder(); tsb_ = acqSettings.timingSettings_.copyBuilder(); vsb_ = acqSettings.volumeSettings_.copyBuilder(); ssb_ = acqSettings.sliceSettings_.copyBuilder(); @@ -59,7 +52,6 @@ public Builder(final DefaultAcquisitionSettingsSCAPE acqSettings) { shcb_[i] = acqSettings.sheetCalibrations_[i].copyBuilder(); } acquisitionMode_ = acqSettings.acquisitionMode_; - channelMode_ = acqSettings.channelMode_; cameraMode_ = acqSettings.cameraMode_; useChannels_ = acqSettings.useChannels_; useTimePoints_ = acqSettings.useTimePoints_; @@ -71,9 +63,6 @@ public Builder(final DefaultAcquisitionSettingsSCAPE acqSettings) { numTimePoints_ = acqSettings.numTimePoints_; timePointInterval_ = acqSettings.timePointInterval_; postMoveDelay_ = acqSettings.postMoveDelay_; - numChannels_ = acqSettings.numChannels_; - channelGroup_ = acqSettings.channelGroup_; - channels_ = acqSettings.channels_; liveScanPeriod_ = acqSettings.liveScanPeriod_; } @@ -94,17 +83,6 @@ public Builder acquisitionMode(final AcquisitionMode acqMode) { return this; } - /** - * Sets the channel mode. - * - * @param channelMode the channel mode. - */ - @Override - public Builder channelMode(final MultiChannelMode channelMode) { - channelMode_ = channelMode; - return this; - } - /** * Sets the camera mode. * @@ -215,29 +193,6 @@ public Builder postMoveDelay(final int postMoveDelay) { return this; } - /** - * Sets the channel group. - * - * @param channelGroup the channel group. - */ - @Override - public Builder channelGroup(final String channelGroup) { - channelGroup_ = channelGroup; - return this; - } - - /** - * Sets the channels array. - * - * @param channels the channel array - */ - @Override - public Builder channels(final ChannelSpec[] channels) { - channels_ = channels; - numChannels_ = channels_.length; - return this; - } - @Override public Builder liveScanPeriod(double liveScanPeriod) { liveScanPeriod_ = liveScanPeriod; @@ -245,6 +200,10 @@ public Builder liveScanPeriod(double liveScanPeriod) { } // getters for sub-builders + public DefaultChannelSettings.Builder channelSettingsBuilder() { + return csb_; + } + public DefaultTimingSettings.Builder timingSettingsBuilder() { return tsb_; } @@ -311,6 +270,7 @@ public String toString() { } + private final DefaultChannelSettings channelSettings_; private final DefaultTimingSettings timingSettings_; private final DefaultVolumeSettings volumeSettings_; private final DefaultSliceSettingsLS sliceSettingsLS_; @@ -320,7 +280,6 @@ public String toString() { private final DefaultSliceCalibration[] sliceCalibrations_; private final AcquisitionMode acquisitionMode_; - private final MultiChannelMode channelMode_; private final CameraMode cameraMode_; private final boolean useChannels_; @@ -334,15 +293,11 @@ public String toString() { private final int numTimePoints_; private final double timePointInterval_; private final int postMoveDelay_; - - private final int numChannels_; - private final String channelGroup_; - private final ChannelSpec[] channels_; - private final double liveScanPeriod_; private DefaultAcquisitionSettingsSCAPE(Builder builder) { super(builder); + channelSettings_ = builder.csb_.build(); timingSettings_ = builder.tsb_.build(); volumeSettings_ = builder.vsb_.build(); sliceSettings_ = builder.ssb_.build(); @@ -355,7 +310,6 @@ private DefaultAcquisitionSettingsSCAPE(Builder builder) { sliceCalibrations_[i] = builder.slcb_[i].build(); } acquisitionMode_ = builder.acquisitionMode_; - channelMode_ = builder.channelMode_; cameraMode_ = builder.cameraMode_; useChannels_ = builder.useChannels_; useTimePoints_ = builder.useTimePoints_; @@ -367,9 +321,6 @@ private DefaultAcquisitionSettingsSCAPE(Builder builder) { numTimePoints_ = builder.numTimePoints_; timePointInterval_ = builder.timePointInterval_; postMoveDelay_ = builder.postMoveDelay_; - numChannels_ = builder.numChannels_; - channelGroup_ = builder.channelGroup_; - channels_ = builder.channels_; liveScanPeriod_= builder.liveScanPeriod_; } // /** @@ -396,10 +347,7 @@ private DefaultAcquisitionSettingsSCAPE(Builder builder) { // useAdvancedTiming_, // numTimePoints_, // timePointInterval_, -// postMoveDelay_, -// numChannels_, -// channelGroup_, -// channels_ +// postMoveDelay_ // ); // } @@ -408,6 +356,16 @@ private DefaultAcquisitionSettingsSCAPE(Builder builder) { // return null; // } + /** + * Returns the immutable DefaultChannelSettings instance. + * + * @return immutable DefaultChannelSettings instance. + */ + //@Override + public DefaultChannelSettings channelSettings() { + return channelSettings_; + } + /** * Returns the immutable DefaultTimingSettings instance. * @@ -490,16 +448,6 @@ public AcquisitionMode acquisitionMode() { return acquisitionMode_; } - /** - * Returns the channel mode. - * - * @return the channel mode. - */ - @Override - public MultiChannelMode channelMode() { - return channelMode_; - } - /** * Returns the camera mode. * @@ -610,42 +558,6 @@ public int postMoveDelay() { return postMoveDelay_; } - /** - * Returns the number of channels. - * - * @return the number of channels. - */ - @Override - public int numChannels() { - return numChannels_; - } - - /** - * Returns the channel group. - * - * @return the channel group. - */ - @Override - public String channelGroup() { - return channelGroup_; - } - - /** - * Returns the channels as an array. - * - * @return the channels as an array. - */ - @Override - public ChannelSpec[] channels() { - return channels_; - } - - public ChannelSpec[] usedChannels() { - return Arrays.stream(channels_) - .filter(ChannelSpec::isUsed) - .toArray(ChannelSpec[]::new); - } - @Override public double liveScanPeriod() { return liveScanPeriod_; diff --git a/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultChannelSettings.java b/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultChannelSettings.java index c8c54ab..628d2be 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultChannelSettings.java +++ b/src/main/java/org/micromanager/lightsheetmanager/api/internal/DefaultChannelSettings.java @@ -1,6 +1,7 @@ package org.micromanager.lightsheetmanager.api.internal; import org.micromanager.lightsheetmanager.api.ChannelSettings; +import org.micromanager.lightsheetmanager.api.data.MultiChannelMode; import org.micromanager.lightsheetmanager.model.channels.ChannelSpec; import java.util.Arrays; @@ -11,6 +12,7 @@ public class DefaultChannelSettings implements ChannelSettings { public static class Builder implements ChannelSettings.Builder { private String channelGroup_ = ""; + private MultiChannelMode channelMode_ = MultiChannelMode.NONE; private HashMap groups_ = new HashMap<>(); public Builder() { @@ -18,18 +20,25 @@ public Builder() { public Builder(final DefaultChannelSettings channelSettings) { channelGroup_ = channelSettings.channelGroup_; + channelMode_ = channelSettings.channelMode_; groups_ = channelSettings.groups_; } @Override - public ChannelSettings.Builder channelGroup(final String channelGroup) { - channelGroup_ = channelGroup; + public ChannelSettings.Builder channelGroup(final String group) { + channelGroup_ = group; return this; } @Override - public ChannelSettings.Builder channels() { - //groups_ = ; + public ChannelSettings.Builder channelMode(final MultiChannelMode mode) { + channelMode_ = mode; + return this; + } + + @Override + public ChannelSettings.Builder channels(final ChannelSpec[] channels) { + groups_.put(channelGroup_, channels); return this; } @@ -40,10 +49,15 @@ public DefaultChannelSettings build() { } private final String channelGroup_; + private final MultiChannelMode channelMode_; private final HashMap groups_; + // default value for when the channel group key is not found + private static final ChannelSpec[] EMPTY_CHANNELS = new ChannelSpec[0]; + private DefaultChannelSettings(Builder builder) { channelGroup_ = builder.channelGroup_; + channelMode_ = builder.channelMode_; groups_ = builder.groups_; } @@ -51,29 +65,65 @@ public Builder copyBuilder() { return new Builder(this); } + /** + * Returns the number of channels for the selected channel group, + * and returns 0 if the channel group does not exist. + * + * @return the number of channels in the channel group + */ @Override public int numChannels() { - return groups_.get(channelGroup_).length; + return groups_.getOrDefault(channelGroup_, EMPTY_CHANNELS).length; } + /** + * Returns the number of channel groups in the channel settings. + * + * @return the number of channel groups + */ @Override public int numGroups() { return groups_.size(); } + /** + * Returns the channel group. + * + * @return the channel group + */ @Override public String channelGroup() { return channelGroup_; } + /** + * Returns the channel mode. + * + * @return the channel mode + */ + @Override + public MultiChannelMode channelMode() { + return channelMode_; + } + + /** + * Returns an array of all channel groups. + * + * @return an array of channel groups + */ @Override public String[] channelGroups() { - return groups_.keySet().toArray(new String[0]); + return groups_.keySet().toArray(String[]::new); } + /** + * Returns the channels for the selected channel group. + * + * @return the channels for the channel group. + */ @Override public ChannelSpec[] channels() { - return groups_.get(channelGroup_); + return groups_.getOrDefault(channelGroup_, EMPTY_CHANNELS); } @Override diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTable.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTable.java index 783ca2d..d920fe1 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTable.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTable.java @@ -31,8 +31,8 @@ public class ChannelTable extends JScrollPane { public ChannelTable(final LightSheetManager model) { model_ = Objects.requireNonNull(model); - final String channelGroup = model_.acquisitions().settings().channelGroup(); - final ChannelSpec[] channels = model_.acquisitions().settings().channels(); + final String channelGroup = model_.acquisitions().settings().channelSettings().channelGroup(); + final ChannelSpec[] channels = model_.acquisitions().settings().channelSettings().channels(); tableData_ = new ChannelTableData(channelGroup, channels); tableModel_ = new ChannelTableModel(tableData_); diff --git a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTablePanel.java b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTablePanel.java index ded96de..3b48019 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTablePanel.java +++ b/src/main/java/org/micromanager/lightsheetmanager/gui/tabs/channels/ChannelTablePanel.java @@ -27,7 +27,6 @@ public class ChannelTablePanel extends Panel { private ComboBox cmbChannelMode_; private final ChannelTable table_; - private final LightSheetManager model_; public ChannelTablePanel(final LightSheetManager model, final CheckBox checkBox) { @@ -52,11 +51,11 @@ private void createUserInterface() { final String[] groupLabels = table_.getChannelGroups(); cmbChannelGroup_ = new ComboBox(groupLabels, - model_.acquisitions().settings().channelGroup(), + model_.acquisitions().settings().channelSettings().channelGroup(), 120, 22); cmbChannelMode_ = new ComboBox(MultiChannelMode.toArray(), - model_.acquisitions().settings().channelMode().toString(), + model_.acquisitions().settings().channelSettings().channelMode().toString(), 120, 22); add(lblChannelGroup_, "split 2"); @@ -75,9 +74,9 @@ private void createEventHandlers() { cmbChannelGroup_.registerListener(e -> { final String channelGroup = cmbChannelGroup_.getSelected(); table_.updatePresetComboBoxes(channelGroup); - table_.getData().setChannels(channelGroup, model_.acquisitions().settings().channels()); + table_.getData().setChannels(channelGroup, model_.acquisitions().settings().channelSettings().channels()); table_.getData().setChannelGroup(channelGroup); - model_.acquisitions().settingsBuilder().channelGroup(channelGroup); + model_.acquisitions().settingsBuilder().channelSettingsBuilder().channelGroup(channelGroup); table_.refreshData(); }); @@ -85,7 +84,7 @@ private void createEventHandlers() { btnAddChannel_.registerListener(e -> { table_.getTableModel().addEmptyChannel(); final ChannelSpec[] channels = table_.getData().getChannels(); - model_.acquisitions().settingsBuilder().channels(channels); + model_.acquisitions().settingsBuilder().channelSettingsBuilder().channels(channels); //System.out.println("add channel"); //table_.getData().printChannelData(); }); @@ -96,14 +95,14 @@ private void createEventHandlers() { if (row != -1) { // is any row selected? table_.getTableModel().removeChannel(row); final ChannelSpec[] channels = table_.getData().getChannels(); - model_.acquisitions().settingsBuilder().channels(channels); + model_.acquisitions().settingsBuilder().channelSettingsBuilder().channels(channels); //System.out.println("remove row index: " + row); } }); // refresh channel table btnRefresh_.registerListener(e -> { - final String channelGroup = model_.acquisitions().settings().channelGroup(); + final String channelGroup = model_.acquisitions().settings().channelSettings().channelGroup(); final String[] groups = table_.getChannelGroups(); cmbChannelGroup_.removeAllItems(); for (String group : groups) { @@ -119,7 +118,7 @@ private void createEventHandlers() { // select channel mode cmbChannelMode_.registerListener(e -> { - model_.acquisitions().settingsBuilder() + model_.acquisitions().settingsBuilder().channelSettingsBuilder() .channelMode(MultiChannelMode.getByIndex(cmbChannelMode_.getSelectedIndex())); }); diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/PLogicSCAPE.java b/src/main/java/org/micromanager/lightsheetmanager/model/PLogicSCAPE.java index 4d22bd9..67f4b6a 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/PLogicSCAPE.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/PLogicSCAPE.java @@ -222,7 +222,7 @@ public boolean prepareControllerForAcquisition( numLines = 1; // assure in acquisition code that we can't have single-sided interleaved } if (settings.isUsingChannels()) { - numLines = numLines * (settings.numChannels() / computeScanChannelsPerPass(settings)); + numLines = numLines * (settings.channelSettings().numChannels() / computeScanChannelsPerPass(settings)); } xyStage_.setScanNumLines(numLines); @@ -282,7 +282,7 @@ public double computeScanSpeed(DefaultAcquisitionSettingsSCAPE settings, final i // compute how many channels we do in each one-way scan private int computeScanChannelsPerPass(DefaultAcquisitionSettingsSCAPE settings) { - return settings.channelMode() == MultiChannelMode.SLICE_HW ? settings.numChannels() : 1; + return settings.channelSettings().channelMode() == MultiChannelMode.SLICE_HW ? settings.channelSettings().numChannels() : 1; } /** @@ -405,8 +405,8 @@ public boolean prepareControllerForAcquisitionSide( // if we are changing color slice by slice then set controller to do multiple slices per piezo move // otherwise just set to 1 slice per piezo move int numSlicesPerPiezo = 1; - if (settings.isUsingChannels() && settings.channelMode() == MultiChannelMode.SLICE_HW) { - numSlicesPerPiezo = settings.numChannels(); + if (settings.isUsingChannels() && settings.channelSettings().channelMode() == MultiChannelMode.SLICE_HW) { + numSlicesPerPiezo = settings.channelSettings().numChannels(); } scanner_.setSPIMNumSlicesPerPiezo(numSlicesPerPiezo); @@ -415,8 +415,8 @@ public boolean prepareControllerForAcquisitionSide( // otherwise (no channels, software switching, slice by slice HW switching) // just do one volume per start trigger int numVolumesPerTrigger = 1; - if (settings.isUsingChannels() && settings.channelMode() == MultiChannelMode.VOLUME_HW) { - numVolumesPerTrigger = settings.numChannels(); + if (settings.isUsingChannels() && settings.channelSettings().channelMode() == MultiChannelMode.VOLUME_HW) { + numVolumesPerTrigger = settings.channelSettings().numChannels(); } // can either trigger controller once for all the time points and @@ -638,10 +638,10 @@ private boolean cleanUpControllerAfterAcquisitionSide( public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCAPE settings) { - MultiChannelMode channelMode = settings.channelMode(); + MultiChannelMode channelMode = settings.channelSettings().channelMode(); // PLogic can only handle up to 4 channels - if ((settings.numChannels() > 4) && + if ((settings.channelSettings().numChannels() > 4) && (channelMode == MultiChannelMode.VOLUME_HW || channelMode == MultiChannelMode.SLICE_HW)) { studio_.logs().showError("PLogic card cannot handle more than 4 channels for hardware switching."); return false; @@ -665,7 +665,7 @@ public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCA } // set up hardware counter - switch (settings.numChannels()) { + switch (settings.channelSettings().numChannels()) { case 1: plcLaser_.setPreset(22); // no counter break; @@ -692,7 +692,7 @@ public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCA // make sure the counters get reset on the acquisition start flag // turns out we can only do this for 2-counter and 4-counter implemented with D-flops // TODO: figure out alternative for 3-position counter - if (settings.numChannels() != 3) { + if (settings.channelSettings().numChannels() != 3) { plcLaser_.setPointerPosition(counterLSBAddr); plcLaser_.setCellInput(3, acquisitionFlagAddr + ASIPLogic.addrEdge); plcLaser_.setPointerPosition(counterMSBAddr); @@ -725,8 +725,8 @@ public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCA int lutValue = 0; // populate a 3-input lookup table with the combinations of lasers present // the LUT "MSB" is the laserTrigger, then the counter MSB, then the counter LSB - for (int channelNum = 0; channelNum < settings.numChannels(); ++channelNum) { - if (doesPLogicChannelIncludeLaser(laserNum, settings.channels()[channelNum], settings.channelGroup())) { + for (int channelNum = 0; channelNum < settings.channelSettings().numChannels(); ++channelNum) { + if (doesPLogicChannelIncludeLaser(laserNum, settings.channelSettings().channels()[channelNum], settings.channelSettings().channelGroup())) { lutValue += (int) Math.pow(2, channelNum + 4); // LUT adds 2^(code in decimal) for each setting, but trigger is MSB of this code } } @@ -759,8 +759,10 @@ public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCA int lutValue = 0; // populate a 3-input lookup table with the combinations of lasers present // the LUT "MSB" is the laserTrigger, then the counter MSB, then the counter LSB - for (int channelNum = 0; channelNum < settings.numChannels(); ++channelNum) { - if (doesPLogicChannelIncludeLaser(laserNum, settings.channels()[channelNum], settings.channelGroup())) { + for (int channelNum = 0; channelNum < settings.channelSettings().numChannels(); ++channelNum) { + if (doesPLogicChannelIncludeLaser(laserNum, + settings.channelSettings().channels()[channelNum], + settings.channelSettings().channelGroup())) { // LUT adds 2^(code in decimal) for each setting, but trigger is MSB of this code lutValue += (int) Math.pow(2, channelNum + 4); } @@ -783,9 +785,9 @@ public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCA // identify BNC from the preset and set counter inputs for 13-16 appropriately boolean[] hardwareChannelUsed = new boolean[4]; // initialized to all false - for (int channelNum = 0; channelNum < settings.numChannels(); channelNum++) { + for (int channelNum = 0; channelNum < settings.channelSettings().numChannels(); channelNum++) { // we already know there are between 1 and 4 channels - int outputNum = getPLogicOutputFromChannel(settings.channels()[channelNum], settings.channelGroup()); + int outputNum = getPLogicOutputFromChannel(settings.channelSettings().channels()[channelNum], settings.channelSettings().channelGroup()); // TODO: handle case where we have multiple simultaneous outputs, e.g. outputs 6/7 together // Note: harsh recently asked about double triggering, but ended up needing to split 1-4 if (outputNum < 5) { // check for error in getPLogicOutputFromChannel() @@ -808,7 +810,7 @@ public boolean setupHardwareChannelSwitching(final DefaultAcquisitionSettingsSCA // the following lines account for this by incrementing the channel number "match" by 1 in this special case int adjustedChannelNum = channelNum; if (channelMode == MultiChannelMode.VOLUME_HW && !(settings.volumeSettings().firstView() == 1)) { - adjustedChannelNum = (channelNum + 1) % settings.numChannels(); + adjustedChannelNum = (channelNum + 1) % settings.channelSettings().numChannels(); } // map the channel number to the equivalent addresses for the AND4 // inputs should be either 3 (for LSB high) or 67 (for LSB low) 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 ad70395..dbce269 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngine.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngine.java @@ -192,11 +192,11 @@ protected DefaultSummaryMetadata addMMSummaryMetadata(JSONObject summaryMetadata // These are the ones from the clojure engine that may yet need to be translated // "Channels" -> {Long@25854} 2 - summaryMetadata.put(PropertyKey.CHANNEL_GROUP.key(), acqSettings_.channelGroup()); + summaryMetadata.put(PropertyKey.CHANNEL_GROUP.key(), acqSettings_.channelSettings().channelGroup()); JSONArray chNames = new JSONArray(); JSONArray chColors = new JSONArray(); - if (acqSettings_.isUsingChannels() && acqSettings_.channels().length > 0) { - for (ChannelSpec c : acqSettings_.channels()) { + if (acqSettings_.isUsingChannels() && acqSettings_.channelSettings().numChannels() > 0) { + for (ChannelSpec c : acqSettings_.channelSettings().channels()) { chNames.put(c.getName()); // chColors.put(c.getRGB()); } @@ -215,7 +215,7 @@ protected DefaultSummaryMetadata addMMSummaryMetadata(JSONObject summaryMetadata .put(PropertyKey.SLICES.key(), doProjections ? 1 : acqSettings_.volumeSettings().slicesPerView()); summaryMetadata.put(PropertyKey.CHANNELS.key(), acqSettings_.isUsingChannels() ? - acqSettings_.channels().length : 1); + acqSettings_.channelSettings().numChannels() : 1); summaryMetadata .put(PropertyKey.POSITIONS.key(), acqSettings_.isUsingMultiplePositions() ? studio_.positions().getPositionList().getNumberOfPositions() : 1); 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 540dcef..8e1ed9f 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineSCAPE.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/AcquisitionEngineSCAPE.java @@ -760,25 +760,25 @@ private boolean doHardwareCalculations(PLogicSCAPE plc) { // } // setup channels - int nrChannelsSoftware = acqSettings_.numChannels(); // how many times we trigger the controller per stack + int nrChannelsSoftware = acqSettings_.channelSettings().numChannels(); // how many times we trigger the controller per stack int nrSlicesSoftware = acqSettings_.volumeSettings().slicesPerView(); //acqSettings_.volumeSettings().slicesPerView(); // TODO: channels need to modify panels and need extraChannelOffset_ boolean changeChannelPerVolumeSoftware = false; boolean changeChannelPerVolumeDoneFirst = false; if (acqSettings_.isUsingChannels()) { - if (acqSettings_.numChannels() == 0) { + if (acqSettings_.channelSettings().numChannels() == 0) { studio_.logs().showError("\"Channels\" is checked, but no channels are selected"); return false; // early exit } - switch (acqSettings_.channelMode()) { + switch (acqSettings_.channelSettings().channelMode()) { case VOLUME: changeChannelPerVolumeSoftware = true; changeChannelPerVolumeDoneFirst = true; break; case VOLUME_HW: case SLICE_HW: - if (acqSettings_.numChannels() == 1) { + if (acqSettings_.channelSettings().numChannels() == 1) { // only 1 channel selected so don't have to really use hardware switching //multiChannelPanel_.initializeChannelCycle(); //extraChannelOffset_ = multiChannelPanel_.selectNextChannelAndGetOffset(); @@ -792,12 +792,12 @@ private boolean doHardwareCalculations(PLogicSCAPE plc) { return false; // early exit } nrChannelsSoftware = 1; - nrSlicesSoftware = acqSettings_.volumeSettings().slicesPerView() * acqSettings_.numChannels(); + nrSlicesSoftware = acqSettings_.volumeSettings().slicesPerView() * acqSettings_.channelSettings().numChannels(); } break; default: studio_.logs().showError( - "Unsupported multichannel mode \"" + acqSettings_.channelMode().toString() + "\""); + "Unsupported multichannel mode \"" + acqSettings_.channelSettings().channelMode().toString() + "\""); return false; // early exit } } @@ -923,7 +923,7 @@ private boolean doHardwareCalculations(PLogicSCAPE plc) { // must use PLogic for channels when using hardware time points if (isUsingHardwareTimePoints) { - if (acqSettings_.isUsingChannels() && acqSettings_.channelMode() == MultiChannelMode.VOLUME) { + if (acqSettings_.isUsingChannels() && acqSettings_.channelSettings().channelMode() == MultiChannelMode.VOLUME) { studio_.logs().showError("Cannot use hardware time points (small time point interval) " + "with software channels (need to use PLogic channel switching)."); return false; @@ -991,7 +991,7 @@ public DefaultTimingSettings.Builder getTimingFromExposure() { // max of laser on time (for static light sheet) and total camera reset/readout time; will add excess later final double sliceDeadTime = NumberUtils.roundToQuarterMs(slicePeriodMin - laserDuration); // extra quarter millisecond to make sure interleaved slices works (otherwise laser signal never goes low) - final double sliceLaserInterleaved = (acqSettings_.channelMode() == MultiChannelMode.SLICE_HW ? 0.25f : 0.f); + final double sliceLaserInterleaved = (acqSettings_.channelSettings().channelMode() == MultiChannelMode.SLICE_HW ? 0.25f : 0.f); // TODO: is this getting the correct value? final double actualCameraResetTime = @@ -1015,8 +1015,8 @@ public DefaultTimingSettings.Builder getTimingFromExposure() { tsb.delayBeforeScan(0.0); break; case OVERLAP: // e.g. - if (acqSettings_.isUsingChannels() && acqSettings_.numChannels() > 1 - && acqSettings_.channelMode() == MultiChannelMode.SLICE_HW) { + if (acqSettings_.isUsingChannels() && acqSettings_.channelSettings().numChannels() > 1 + && acqSettings_.channelSettings().channelMode() == MultiChannelMode.SLICE_HW) { // for interleaved slices we should illuminate during global exposure but not during readout/reset time after each trigger tsb.scansPerSlice(1); tsb.scanDuration(1.0); @@ -1311,8 +1311,8 @@ private double computeTimePointDuration() { } private double computeActualVolumeDuration(final DefaultAcquisitionSettingsSCAPE acqSettings) { - final MultiChannelMode channelMode = acqSettings.channelMode(); - final int numChannels = acqSettings.numChannels(); + final MultiChannelMode channelMode = acqSettings.channelSettings().channelMode(); + final int numChannels = acqSettings.channelSettings().numChannels(); final int numViews = acqSettings.volumeSettings().numViews(); final double delayBeforeSide = acqSettings.volumeSettings().delayBeforeView(); int numCameraTriggers = acqSettings.volumeSettings().slicesPerView(); @@ -1418,8 +1418,8 @@ private double computeTimePointDuration2() { } public double computeVolumeDuration(final DefaultAcquisitionSettingsSCAPE acqSettings) { - final MultiChannelMode channelMode = acqSettings.channelMode(); - final int numChannels = acqSettings.numChannels(); + final MultiChannelMode channelMode = acqSettings.channelSettings().channelMode(); + final int numChannels = acqSettings.channelSettings().numChannels(); final int numViews = acqSettings.volumeSettings().numViews(); final double delayBeforeView = acqSettings.volumeSettings().delayBeforeView(); int numCameraTriggers = acqSettings.volumeSettings().slicesPerView(); diff --git a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/LSMAcquisitionEvents.java b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/LSMAcquisitionEvents.java index 4359bc1..67b296d 100644 --- a/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/LSMAcquisitionEvents.java +++ b/src/main/java/org/micromanager/lightsheetmanager/model/acquisitions/LSMAcquisitionEvents.java @@ -36,12 +36,12 @@ public static Iterator createTimelapseMultiChannelVolumeAcqEve timelapse(acquisitionSettings.numTimePoints(), acquisitionSettings.timePointInterval()); - if (acquisitionSettings.numChannels() == 1) { + if (acquisitionSettings.channelSettings().numChannels() == 1) { throw new RuntimeException("Expected multiple channels but only one found"); } Function> channels; - channels = channels(acquisitionSettings.channels()); + channels = channels(acquisitionSettings.channelSettings().channels()); Function> zStack = zStack(0, acquisitionSettings.volumeSettings().slicesPerView()); @@ -93,7 +93,7 @@ public static Iterator createMultiChannelVolumeAcqEvents( Function eventMonitor, boolean interleaved) { Function> channels = - channels(acquisitionSettings.channels()); + channels(acquisitionSettings.channelSettings().channels()); Function> zStack = zStack(0, acquisitionSettings.volumeSettings().slicesPerView()); @@ -136,7 +136,7 @@ public static Iterator createChannelAcqEvents( Function eventMonitor) { Function> channels = - channels(acquisitionSettings.channels()); + channels(acquisitionSettings.channelSettings().channels()); Function> cameras = cameras(cameraDeviceNames);