Example #1
0
 private void checkPropertyExists(Devices.Keys devKey, Properties.Keys propKey) {
   if (!devices_.hasProperty(devKey, propKey)) {
     MyDialogUtils.showError(
         "Device \""
             + devices_.getMMDevice(devKey)
             + "\" doesn't have required property \""
             + propKey.toString()
             + "\"");
   }
 }
Example #2
0
  /**
   * Constructs a special JComboBox with all cameras that have only 1 channel
   *
   * @param deviceName
   * @return
   */
  public JComboBox makeSingleCameraDeviceBox(Devices.Keys deviceName, int maximumWidth) {
    List<String> singleCameras = new ArrayList<String>();
    singleCameras.add(0, "");
    String originalCamera = core_.getCameraDevice();
    try {
      StrVector strvDevices = core_.getLoadedDevicesOfType(mmcorej.DeviceType.CameraDevice);
      for (int i = 0; i < strvDevices.size(); i++) {
        String test = strvDevices.get(i);
        core_.setCameraDevice(test);
        if (core_.getNumberOfCameraChannels() == 1) {
          singleCameras.add(test);
        }
      }
    } catch (Exception ex) {
      MyDialogUtils.showError("Error detecting single camera devices");
    } finally {
      try {
        core_.setCameraDevice(originalCamera);
      } catch (Exception e) {
        MyDialogUtils.showError(e);
      }
    }

    JComboBox deviceBox = new JComboBox(singleCameras.toArray());
    deviceBox.addActionListener(new DeviceBoxListener(deviceName, deviceBox));
    deviceBox.setSelectedItem(
        devices_.getMMDevice(deviceName)); // selects whatever device was read in by prefs
    deviceBox.setMaximumSize(new Dimension(maximumWidth, 30));
    return deviceBox;
  }
Example #3
0
  /**
   * Constructs a special JComboBox with all cameras that have more than 1 channel, which we expect
   * to just be a single Multicamera device
   *
   * @param deviceName
   * @return
   */
  public JComboBox makeMultiCameraDeviceBox(Devices.Keys deviceName, int maximumWidth) {
    List<String> multiCameras = new ArrayList<String>();
    multiCameras.add(0, "");
    try {
      StrVector strvDevices = core_.getLoadedDevicesOfType(mmcorej.DeviceType.CameraDevice);
      for (int i = 0; i < strvDevices.size(); i++) {
        // find all Multi-camera devices (usually just one)
        String test = strvDevices.get(i);
        if (core_.getDeviceLibrary(test).equals(Devices.Libraries.UTILITIES.toString())
            && core_
                .getDeviceDescription(test)
                .equals("Combine multiple physical cameras into a single logical camera")) {
          multiCameras.add(strvDevices.get(i));
        }
      }
    } catch (Exception ex) {
      MyDialogUtils.showError("Error detecting multi camera devices");
    }

    JComboBox deviceBox = new JComboBox(multiCameras.toArray());
    deviceBox.addActionListener(new DeviceBoxListener(deviceName, deviceBox));
    // if we have one and only one multi-camera then set box to it
    if (multiCameras.size() == 2) { // recall we added empty string as the first entry
      deviceBox.setSelectedIndex(1);
    } else {
      deviceBox.setSelectedItem(
          devices_.getMMDevice(deviceName)); // selects whatever device was read in by prefs
    }
    deviceBox.setMaximumSize(new Dimension(maximumWidth, 30));
    return deviceBox;
  }
Example #4
0
  /** Gets called when this tab gets focus. Uses the ActionListeners of the UI components */
  @Override
  public void gotSelected() {
    posUpdater_.pauseUpdates(true);
    joystickPanel_.gotSelected();
    cameraPanel_.gotSelected();
    beamPanel_.gotSelected();
    props_.callListeners();

    // moves illumination piezo to home
    if (illumPiezoHomeEnable_.isSelected()
        && devices_.isValidMMDevice(piezoIlluminationDeviceKey_)) {
      props_.setPropValue(
          piezoIlluminationDeviceKey_, Properties.Keys.MOVE_TO_HOME, Properties.Values.DO_IT);
    }

    // set scan waveform to be triangle
    // SPIM use can change, but for alignment avoid sharp edges
    props_.setPropValue(
        micromirrorDeviceKey_, Properties.Keys.SA_PATTERN_X, Properties.Values.SAM_TRIANGLE, true);

    // move piezo and scanner to "center" position
    centerPiezoAndGalvo();

    posUpdater_.pauseUpdates(false);
  }
  // TODO make this automatically call all panels' method
  private void saveSettings() {
    // save selections as needed
    devices_.saveSettings();
    setupPanelA_.saveSettings();
    if (!ASIdiSPIM.oSPIM) {
      setupPanelB_.saveSettings();
    }
    navigationPanel_.saveSettings();
    acquisitionPanel_.saveSettings();
    settingsPanel_.saveSettings();

    // save tab location in prefs (dialog location now handled by MMDialog)
    prefs_.putInt(MAIN_PREF_NODE, Prefs.Keys.TAB_INDEX, tabbedPane_.getSelectedIndex());
  }
Example #6
0
 /**
  * checks firmware versions and gives any necessary warnings to user
  *
  * @param key
  */
 private void checkFirmwareVersion(Devices.Keys key) {
   // firmware version check only for ASI devices
   if (!devices_.isTigerDevice(key)) {
     return;
   }
   float firmwareVersion = props_.getPropValueFloat(key, Properties.Keys.FIRMWARE_VERSION);
   switch (key) {
     case PIEZOA:
     case PIEZOB:
       if (firmwareVersion == 0f) {
         // firmware version property wasn't found, maybe device hasn't been selected
       } else if (firmwareVersion < (float) 2.829) {
         MyDialogUtils.showError(
             "Device "
                 + devices_.getMMDevice(key)
                 + ": Piezo firmware is old; piezo may not move correctly in sync with sheet."
                 + " Contact ASI for updated firmware.");
       }
       break;
     case GALVOA:
     case GALVOB:
       if (firmwareVersion == 0f) {
         // firmware version property wasn't found, maybe device hasn't been selected
       } else if (firmwareVersion < (float) 2.809) {
         MyDialogUtils.showError(
             "Device "
                 + devices_.getMMDevice(key)
                 + ": Micromirror firmware is old; wheel control of some scanner axes may not work."
                 + " Contact ASI for updated firmware.");
       } else if (firmwareVersion < (float) 2.829) {
         MyDialogUtils.showError(
             "Device "
                 + devices_.getMMDevice(key)
                 + ": Micromirror firmware is old; imaging piezo not set correctly the first stack."
                 + " Contact ASI for updated firmware.");
       } else if (firmwareVersion < (float) 2.859) {
         MyDialogUtils.showError(
             "Device "
                 + devices_.getMMDevice(key)
                 + ": Micromirror firmware is old; not all timing parameters are supported."
                 + " Contact ASI for updated firmware.");
       }
       break;
     case PLOGIC:
       if (firmwareVersion < 3.069) {
         MyDialogUtils.showError(
             "Device "
                 + devices_.getMMDevice(key)
                 + ": PLogic firmware is old; some features may not work."
                 + " Contact ASI for updated firmware.");
       }
       break;
     default:
       break;
   }
 }
Example #7
0
 private void checkPropertyValueEquals(
     Devices.Keys devKey, Properties.Keys propKey, Properties.Values expectedValue) {
   if (!(props_.getPropValueString(devKey, propKey).equals(expectedValue.toString()))) {
     if (MyDialogUtils.getConfirmDialogResult(
         "This plugin may not work if property \""
             + propKey.toString()
             + "\" of device \""
             + devices_.getMMDevice(devKey)
             + "\" is not set to \""
             + expectedValue.toString()
             + "\".  Set it now?",
         JOptionPane.YES_NO_OPTION)) {
       props_.setPropValue(devKey, propKey, expectedValue);
     }
   }
 }
Example #8
0
 /**
  * Constructs a JComboBox populated with devices of specified Micro-Manager type Attaches a
  * listener and sets selected item to what is specified in the Devices class.
  *
  * @param deviceType - Micro-Manager device type (mmcorej.DeviceType)
  * @param deviceKey - ASi diSPIM device key (see Devices class)
  * @param maximumWidth -
  * @return final JComboBox
  */
 public JComboBox makeDeviceSelectionBox(
     mmcorej.DeviceType deviceType, Devices.Keys deviceKey, int maximumWidth) {
   // when editing this method do the same to the one with array argument too
   JComboBox deviceBox = new JComboBox();
   ArrayList<String> devices = new ArrayList<String>();
   StrVector strvDevices = core_.getLoadedDevicesOfType(deviceType);
   devices.addAll(Arrays.asList(strvDevices.toArray()));
   devices.add(0, "");
   deviceBox.removeAllItems();
   for (String device : devices) {
     deviceBox.addItem(device);
   }
   deviceBox.addActionListener(new DeviceBoxListener(deviceKey, deviceBox));
   deviceBox.setSelectedItem(
       devices_.getMMDevice(deviceKey)); // selects whatever device was read in by prefs
   deviceBox.setMaximumSize(new Dimension(maximumWidth, 30));
   return deviceBox;
 }
Example #9
0
 /**
  * checks that the device has correct library, properties that we need, and correct values set as
  * needed
  *
  * @param key
  */
 private void checkDeviceLibrary(Devices.Keys key) {
   Devices.Libraries deviceLibrary = devices_.getMMDeviceLibrary(key);
   if (deviceLibrary == Devices.Libraries.NODEVICE) {
     return;
   }
   switch (key) {
     case CAMERAA:
     case CAMERAB:
       switch (deviceLibrary) {
         case HAMCAM:
           checkPropertyExists(key, Properties.Keys.TRIGGER_SOURCE);
           checkPropertyValueEquals(
               key, Properties.Keys.TRIGGER_POLARITY, Properties.Values.POSITIVE);
           break;
         case PCOCAM:
           // trigger polarity not accessible in Micro-Manager, so we have to trust it is correct
           checkPropertyExists(key, Properties.Keys.TRIGGER_MODE_PCO);
           break;
         case ANDORCAM:
           // TODO check trigger polarity
           checkPropertyExists(key, Properties.Keys.TRIGGER_MODE);
           break;
         case DEMOCAM:
           checkPropertyValueEquals(key, Properties.Keys.PIXEL_TYPE, Properties.Values.SIXTEENBIT);
           break;
         default:
           MyDialogUtils.showError(
               "Plugin doesn't support your camera for SPIM yet;"
                   + " contact the authors for support (camera must have hardware trigger)");
       } // CamA/B case
       break;
     case GALVOA:
     case GALVOB:
       if (deviceLibrary == Devices.Libraries.ASITIGER) {
         checkPropertyValueEquals(
             key, Properties.Keys.INPUT_MODE, Properties.Values.INTERNAL_INPUT);
         // PLogic use in the plugin assumes "laser + side" output mode
         if (devices_.isValidMMDevice(Devices.Keys.PLOGIC)) {
           checkPropertyValueEquals(
               key, Properties.Keys.LASER_OUTPUT_MODE, Properties.Values.LASER_SHUTTER_SIDE);
         }
       } else {
         MyDialogUtils.showError("Plugin doesn't support galvo devices other than ASITiger");
       }
       break;
     case PIEZOA:
     case PIEZOB:
       if (deviceLibrary == Devices.Libraries.ASITIGER) {
         checkPropertyValueEquals(
             key, Properties.Keys.PIEZO_MODE, Properties.Values.INTERNAL_CLOSEDLOOP_INPUT);
       } else {
         MyDialogUtils.showError("Plugin doesn't support piezo devices other than ASITiger");
       }
       break;
     case PLOGIC:
       if (deviceLibrary == Devices.Libraries.ASITIGER) {
         // would like to do below line but we need to change pre-init value and reload config
         // checkPropertyValueEquals(key, Properties.Keys.PLOGIC_MODE,
         // Properties.Values.DISPIM_SHUTTER);
         if (!props_
             .getPropValueString(key, Properties.Keys.PLOGIC_MODE)
             .equals(Properties.Values.DISPIM_SHUTTER.toString())) {
           MyDialogUtils.showError(
               "Device "
                   + devices_.getMMDevice(key)
                   + ": need to set pre-initialization property PLogicMode to "
                   + "diSPIM Shutter (use Hardware Config Wizard, then edit device "
                   + devices_.getMMDevice(key)
                   + " on Step 2). Then reload the "
                   + " changed configuration and restart the diSPIM plugin.");
         }
         checkPropertyValueEquals(
             key, Properties.Keys.PLOGIC_TRIGGER_SOURCE, Properties.Values.PLOGIC_TRIGGER_MMIRROR);
         // PLogic use in the plugin assumes "laser + side" output mode
         for (Devices.Keys galvoKey : Devices.GALVOS) {
           if (devices_.isValidMMDevice(galvoKey)) {
             checkPropertyValueEquals(
                 galvoKey,
                 Properties.Keys.LASER_OUTPUT_MODE,
                 Properties.Values.LASER_SHUTTER_SIDE);
           }
         }
       } else {
         MyDialogUtils.showError("Plugin doesn't support shutter devices other than ASITiger");
       }
       break;
     default:
       break;
   }
 }
Example #10
0
  public SetupPanel(
      ScriptInterface gui,
      Devices devices,
      Properties props,
      Joystick joystick,
      final Devices.Sides side,
      Positions positions,
      Cameras cameras,
      Prefs prefs,
      StagePositionUpdater posUpdater,
      AutofocusUtils autofocus) {
    super(
        MyStrings.PanelNames.SETUP.toString() + side.toString(),
        new MigLayout("", "[center]8[center]", "[]16[]16[]"));

    devices_ = devices;
    props_ = props;
    joystick_ = joystick;
    positions_ = positions;
    cameras_ = cameras;
    autofocus_ = autofocus;
    prefs_ = prefs;
    posUpdater_ = posUpdater;
    gui_ = gui;
    core_ = gui_.getMMCore();
    PanelUtils pu = new PanelUtils(prefs_, props_, devices);
    final SetupPanel setupPanel = this;

    piezoImagingDeviceKey_ = Devices.getSideSpecificKey(Devices.Keys.PIEZOA, side);
    piezoIlluminationDeviceKey_ =
        Devices.getSideSpecificKey(Devices.Keys.PIEZOA, Devices.getOppositeSide(side));
    micromirrorDeviceKey_ = Devices.getSideSpecificKey(Devices.Keys.GALVOA, side);

    sheetStartPositionLabel_ =
        new StoredFloatLabel(
            panelName_,
            Properties.Keys.PLUGIN_SHEET_START_POS.toString(),
            -0.5f,
            prefs_,
            " \u00B0");
    sliceStartPos_ = sheetStartPositionLabel_.getFloat();
    sheetStopPositionLabel_ =
        new StoredFloatLabel(
            panelName_, Properties.Keys.PLUGIN_SHEET_END_POS.toString(), 0.5f, prefs_, " \u00B0");
    sliceStopPos_ = sheetStopPositionLabel_.getFloat();
    imagingPiezoStartPositionLabel_ =
        new StoredFloatLabel(
            panelName_,
            Properties.Keys.PLUGIN_PIEZO_START_POS.toString(),
            -50f,
            prefs_,
            " \u00B5" + "m");
    imagingPiezoStartPos_ = imagingPiezoStartPositionLabel_.getFloat();
    imagingPiezoStopPositionLabel_ =
        new StoredFloatLabel(
            panelName_,
            Properties.Keys.PLUGIN_PIEZO_END_POS.toString(),
            50f,
            prefs_,
            " \u00B5" + "m");
    imagingPiezoStopPos_ = imagingPiezoStopPositionLabel_.getFloat();

    JButton tmp_but;

    JPanel calibrationPanel =
        new JPanel(
            new MigLayout(
                "", "[right]2[center]2[right]4[left]8[center]8[center]8[center]", "[]8[]"));

    offsetField_ =
        pu.makeFloatEntryField(
            panelName_, Properties.Keys.PLUGIN_OFFSET_PIEZO_SHEET.toString(), 0, 5);
    rateField_ =
        pu.makeFloatEntryField(
            panelName_, Properties.Keys.PLUGIN_RATE_PIEZO_SHEET.toString(), 100, 5);
    piezoDeltaField_ =
        pu.makeFloatEntryField(
            panelName_, Properties.Keys.PLUGIN_PIEZO_SHEET_INCREMENT.toString(), 5, 3);
    piezoDeltaField_.setToolTipText("Piezo increment used by up/down arrow buttons");

    JButton upButton = new JButton();
    upButton.setIcon(SwingResourceManager.getIcon(MMStudio.class, "icons/arrow_up.png"));
    upButton.setText("");
    upButton.setToolTipText("Move slice and piezo up together");
    upButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            stepPiezoAndGalvo(1.);
          }
        });

    JButton downButton = new JButton();
    downButton.setIcon(SwingResourceManager.getIcon(MMStudio.class, "icons/arrow_down.png"));
    downButton.setText("");
    downButton.setToolTipText("Move slice and piezo down together");
    downButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            stepPiezoAndGalvo(-1.);
          }
        });

    calibrationPanel.add(new JLabel("Piezo/Slice Calibration"), "span 5, center");
    calibrationPanel.add(
        new JSeparator(SwingConstants.VERTICAL), "span 1 3, growy, shrinkx, center");
    calibrationPanel.add(new JLabel("Step"), "wrap");

    calibrationPanel.add(new JLabel("Slope: "));
    calibrationPanel.add(rateField_, "span 2, right");
    // TODO make calibration be in degrees instead of um
    // calibrationPanel.add(new JLabel("\u00B0/\u00B5m"));
    calibrationPanel.add(new JLabel("\u00B5m/\u00B0"));
    tmp_but = new JButton("Update");
    tmp_but.setMargin(new Insets(4, 8, 4, 8));
    tmp_but.setToolTipText(
        "Computes piezo vs. slice slope and offset from start and end positions");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            updateCalibrationSlopeAndOffset();
          }
        });
    tmp_but.setBackground(Color.green);
    calibrationPanel.add(tmp_but);

    calibrationPanel.add(upButton, "wrap");

    calibrationPanel.add(new JLabel("Offset: "));
    calibrationPanel.add(offsetField_, "span 2, right");
    // calibrationPanel.add(new JLabel("\u00B0"));
    calibrationPanel.add(new JLabel("\u00B5m"));
    tmp_but = new JButton("Update");
    tmp_but.setMargin(new Insets(4, 8, 4, 8));
    tmp_but.setToolTipText("Adjusts piezo vs. slice offset from current position");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            updateCalibrationOffset();
          }
        });
    tmp_but.setBackground(Color.green);
    calibrationPanel.add(tmp_but);

    calibrationPanel.add(downButton, "wrap");

    calibrationPanel.add(new JLabel("Step size: "), "span 2, left");
    calibrationPanel.add(piezoDeltaField_);
    calibrationPanel.add(new JLabel("\u00B5m"));

    tmp_but = new JButton("Focus");
    tmp_but.setMargin(new Insets(4, 8, 4, 8));
    tmp_but.setToolTipText("Autofocus at current piezo position");
    tmp_but.setBackground(Color.green);
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            autofocus_.runFocus(
                setupPanel,
                side,
                true,
                ASIdiSPIM.getFrame().getAcquisitionPanel().getSliceTiming(),
                true);
          }
        });
    calibrationPanel.add(tmp_but, "center, span 3, wrap");

    // start 2-point calibration frame
    // this frame is separate from main plugin window

    slopeCalibrationFrame_ = new MMFrame();
    slopeCalibrationFrame_.setTitle("Slope and Offset Calibration");
    slopeCalibrationFrame_.loadPosition(100, 100);

    JPanel slopeCalibrationPanel =
        new JPanel(new MigLayout("", "[center]8[center]8[center]8[center]8[center]", "[]8[]"));

    // TODO improve interface with multi-page UI and forward/back buttons
    // e.g. \mmstudio\src\org\micromanager\conf2\ConfiguratorDlg2.java

    slopeCalibrationPanel.add(new JLabel("Calibration Start Position"), "span 3, center");
    slopeCalibrationPanel.add(new JLabel("Calibration End Position"), "span 3, center, wrap");

    slopeCalibrationPanel.add(sheetStartPositionLabel_);

    // Go to start button
    tmp_but = new JButton("Go to");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            try {
              positions_.setPosition(micromirrorDeviceKey_, Directions.Y, sliceStartPos_, true);
              positions_.setPosition(piezoImagingDeviceKey_, imagingPiezoStartPos_, true);
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
          }
        });
    slopeCalibrationPanel.add(tmp_but, "");
    slopeCalibrationPanel.add(new JSeparator(SwingConstants.VERTICAL), "spany 2, growy");

    slopeCalibrationPanel.add(sheetStopPositionLabel_);

    // go to end button
    tmp_but = new JButton("Go to");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            try {
              positions_.setPosition(micromirrorDeviceKey_, Directions.Y, sliceStopPos_, true);
              positions_.setPosition(piezoImagingDeviceKey_, imagingPiezoStopPos_, true);
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
          }
        });
    slopeCalibrationPanel.add(tmp_but, "wrap");

    slopeCalibrationPanel.add(imagingPiezoStartPositionLabel_);

    tmp_but = new JButton("Set");
    tmp_but.setToolTipText(
        "Saves calibration start position for imaging piezo and scanner slice (should be focused)");
    tmp_but.setBackground(Color.red);
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            try {
              // bypass cached positions in positions_ in case they aren't current
              sliceStartPos_ = positions_.getUpdatedPosition(micromirrorDeviceKey_, Directions.Y);
              sheetStartPositionLabel_.setFloat((float) sliceStartPos_);
              imagingPiezoStartPos_ = positions_.getUpdatedPosition(piezoImagingDeviceKey_);
              imagingPiezoStartPositionLabel_.setFloat((float) imagingPiezoStartPos_);
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
          }
        });
    slopeCalibrationPanel.add(tmp_but);

    slopeCalibrationPanel.add(imagingPiezoStopPositionLabel_);

    tmp_but = new JButton("Set");
    tmp_but.setToolTipText(
        "Saves calibration end position for imaging piezo and scanner slice (should be focused)");
    tmp_but.setBackground(Color.red);
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            try {
              // bypass cached positions in positions_ in case they aren't current
              sliceStopPos_ = positions_.getUpdatedPosition(micromirrorDeviceKey_, Directions.Y);
              sheetStopPositionLabel_.setFloat((float) sliceStopPos_);
              imagingPiezoStopPos_ = positions_.getUpdatedPosition(piezoImagingDeviceKey_);
              imagingPiezoStopPositionLabel_.setFloat((float) imagingPiezoStopPos_);
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
          }
        });
    slopeCalibrationPanel.add(tmp_but, "wrap");

    slopeCalibrationPanel.add(
        new JSeparator(SwingConstants.HORIZONTAL), "span 5, growx, shrinky, wrap");

    tmp_but = new JButton("Use these!");
    tmp_but.setBackground(Color.green);
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            try {
              double rate =
                  (imagingPiezoStopPos_ - imagingPiezoStartPos_) / (sliceStopPos_ - sliceStartPos_);
              rateField_.setValue((Double) rate);
              double offset =
                  (imagingPiezoStopPos_ + imagingPiezoStartPos_) / 2
                      - (rate * ((sliceStopPos_ + sliceStartPos_) / 2));
              offsetField_.setValue((Double) offset);
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
            slopeCalibrationFrame_.setVisible(false);
          }
        });
    slopeCalibrationPanel.add(tmp_but, "span 5, split 3");

    tmp_but = new JButton("Focus");
    tmp_but.setToolTipText("Autofocus at current piezo position");
    tmp_but.setBackground(Color.green);
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            autofocus_.runFocus(
                setupPanel,
                side,
                true,
                ASIdiSPIM.getFrame().getAcquisitionPanel().getSliceTiming(),
                true);
          }
        });
    slopeCalibrationPanel.add(tmp_but);

    tmp_but = new JButton("Cancel");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            slopeCalibrationFrame_.setVisible(false);
          }
        });
    slopeCalibrationPanel.add(tmp_but, "wrap");

    slopeCalibrationFrame_.add(slopeCalibrationPanel);
    slopeCalibrationFrame_.pack();
    slopeCalibrationFrame_.setResizable(false);

    final int positionWidth = 50;
    final int labelWidth = 80;

    JPanel slicePanel =
        new JPanel(
            new MigLayout(
                "",
                "[" + labelWidth + "px!,right]8[" + positionWidth + "px!,center]8[center]8[center]",
                "[]8[]"));

    JLabel tmp_lbl = new JLabel("Imaging center: ", JLabel.RIGHT);
    tmp_lbl.setMaximumSize(new Dimension(labelWidth, 20));
    tmp_lbl.setMinimumSize(new Dimension(labelWidth, 20));
    slicePanel.add(tmp_lbl);
    imagingCenterPosLabel_ =
        new StoredFloatLabel(
            panelName_,
            Properties.Keys.PLUGIN_PIEZO_CENTER_POS.toString(),
            0,
            prefs_,
            " \u00B5" + "m");
    imagingCenterPosLabel_.setMaximumSize(new Dimension(positionWidth, 20));
    imagingCenterPosLabel_.setMinimumSize(new Dimension(positionWidth, 20));
    slicePanel.add(imagingCenterPosLabel_);

    // initialize the center position variable
    imagingCenterPos_ =
        prefs_.getFloat(
            MyStrings.PanelNames.SETUP.toString() + side.toString(),
            Properties.Keys.PLUGIN_PIEZO_CENTER_POS,
            0);

    tmp_but = new JButton("Go");
    tmp_but.setToolTipText("Moves piezo to specified center and also slice");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            centerPiezoAndGalvo();
          }
        });
    slicePanel.add(tmp_but);

    tmp_but = new JButton("Set");
    tmp_but.setToolTipText("Sets piezo center position for acquisition");
    tmp_but.setBackground(Color.red);
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            try {
              imagingCenterPos_ = positions_.getUpdatedPosition(piezoImagingDeviceKey_);
              imagingCenterPosLabel_.setFloat((float) imagingCenterPos_);
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
          }
        });
    slicePanel.add(tmp_but, "wrap");

    slicePanel.add(new JLabel("XY center: "));
    slicePanel.add(new JLabel("")); // TODO update this label with current value

    tmp_but = new JButton("Go");
    tmp_but.setToolTipText("Moves XY stage to specified center");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            // TODO replace with positions_ call to 2D position set (need to implement still)
            try {
              core_.setXYPosition(xyCenterPos_.x, xyCenterPos_.y);
            } catch (Exception ex) {
              ReportingUtils.showError(ex);
            }
          }
        });
    slicePanel.add(tmp_but);

    tmp_but = new JButton("Set");
    tmp_but.setToolTipText("Sets XY center position for acquisition");
    tmp_but.setBackground(Color.red);
    tmp_but.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            // TODO replace with positions_ call to 2D position set (need to implement still)
            try {
              xyCenterPos_ =
                  core_.getXYStagePosition(devices_.getMMDeviceException(Devices.Keys.XYSTAGE));
            } catch (Exception ex) {
              MyDialogUtils.showError(ex);
            }
          }
        });
    slicePanel.add(tmp_but, "wrap");

    slicePanel.add(new JSeparator(SwingConstants.HORIZONTAL), "span 5, growx, shrinky, wrap");

    slicePanel.add(new JLabel("Slice position:"));
    sheetPositionLabel_ = new JLabel("");
    slicePanel.add(sheetPositionLabel_);
    slicePanel.add(pu.makeSetPositionField(micromirrorDeviceKey_, Directions.Y, positions_));

    tmp_but = new JButton("Go to 0");
    tmp_but.setMargin(new Insets(4, 4, 4, 4));
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            positions_.setPosition(micromirrorDeviceKey_, Directions.Y, 0.0, true);
          }
        });
    slicePanel.add(tmp_but, "wrap");

    slicePanel.add(new JLabel("Imaging piezo:"));
    imagingPiezoPositionLabel_ = new JLabel("");
    slicePanel.add(imagingPiezoPositionLabel_);
    slicePanel.add(pu.makeSetPositionField(piezoImagingDeviceKey_, Directions.NONE, positions_));
    tmp_but = new JButton("Go to 0");
    tmp_but.setMargin(new Insets(4, 4, 4, 4));
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            positions_.setPosition(piezoImagingDeviceKey_, 0.0, true);
          }
        });
    slicePanel.add(tmp_but, "wrap");

    // Create sheet controls
    JPanel sheetPanel =
        new JPanel(
            new MigLayout(
                "",
                "[" + labelWidth + "px!,right]8[" + positionWidth + "px!,center]8[center]8[center]",
                "[]8[]8[]"));

    tmp_lbl = new JLabel("Illum. piezo:", JLabel.RIGHT);
    tmp_lbl.setMaximumSize(new Dimension(labelWidth, 20));
    tmp_lbl.setMinimumSize(new Dimension(labelWidth, 20));
    sheetPanel.add(tmp_lbl, "center");
    illuminationPiezoPositionLabel_ = new JLabel("");
    illuminationPiezoPositionLabel_.setMaximumSize(new Dimension(positionWidth, 20));
    illuminationPiezoPositionLabel_.setMinimumSize(new Dimension(positionWidth, 20));
    sheetPanel.add(illuminationPiezoPositionLabel_);
    sheetPanel.add(
        pu.makeSetPositionField(piezoIlluminationDeviceKey_, Directions.NONE, positions_));

    tmp_but = new JButton("Set home");
    tmp_but.setMargin(new Insets(4, 4, 4, 4));
    tmp_but.setToolTipText("During SPIM, illumination piezo is moved to home position");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            if (devices_.isValidMMDevice(piezoIlluminationDeviceKey_)) {
              props_.setPropValue(
                  piezoIlluminationDeviceKey_,
                  Properties.Keys.SET_HOME_HERE,
                  Properties.Values.DO_IT);
            }
          }
        });
    sheetPanel.add(tmp_but);

    tmp_but = new JButton("Go home");
    tmp_but.setMargin(new Insets(4, 4, 4, 4));
    tmp_but.setToolTipText("During SPIM, illumination piezo is moved to home position");
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            if (devices_.isValidMMDevice(piezoIlluminationDeviceKey_)) {
              props_.setPropValue(
                  piezoIlluminationDeviceKey_,
                  Properties.Keys.MOVE_TO_HOME,
                  Properties.Values.DO_IT);
            }
          }
        });
    sheetPanel.add(tmp_but);

    illumPiezoHomeEnable_ =
        pu.makeCheckBox(
            "Go home on tab activate",
            Properties.Keys.PREFS_ENABLE_ILLUM_PIEZO_HOME,
            panelName_,
            false);
    sheetPanel.add(illumPiezoHomeEnable_, "span 3, wrap");

    sheetPanel.add(new JLabel("Sheet width:"));
    sheetPanel.add(
        new JLabel(""),
        "span 2"); // TODO update this label with current value and/or allow user to directly enter
                   // value
    sheetPanel.add(
        makeIncrementButton(
            micromirrorDeviceKey_, Properties.Keys.SA_AMPLITUDE_X_DEG, "-", (float) -0.01),
        "split 2");
    sheetPanel.add(
        makeIncrementButton(
            micromirrorDeviceKey_, Properties.Keys.SA_AMPLITUDE_X_DEG, "+", (float) 0.01));
    JSlider tmp_sl =
        pu.makeSlider(
            0, // 0 is min amplitude
            props_.getPropValueFloat(micromirrorDeviceKey_, Properties.Keys.MAX_DEFLECTION_X)
                - props_.getPropValueFloat(
                    micromirrorDeviceKey_,
                    Properties.Keys.MIN_DEFLECTION_X), // compute max amplitude
            1000, // the scale factor between internal integer representation and float
                  // representation
            micromirrorDeviceKey_,
            Properties.Keys.SA_AMPLITUDE_X_DEG);
    sheetPanel.add(tmp_sl, "span 5, growx, center, wrap");

    sheetPanel.add(new JLabel("Sheet offset:"));
    sheetPanel.add(
        new JLabel(""),
        "span 2"); // TODO update this label with current value and/or allow user to directly enter
                   // value
    sheetPanel.add(
        makeIncrementButton(
            micromirrorDeviceKey_, Properties.Keys.SA_OFFSET_X_DEG, "-", (float) -0.01),
        "split 2");
    sheetPanel.add(
        makeIncrementButton(
            micromirrorDeviceKey_, Properties.Keys.SA_OFFSET_X_DEG, "+", (float) 0.01));
    tmp_but = new JButton("Center");
    tmp_but.setMargin(new Insets(4, 8, 4, 8));
    tmp_but.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            props_.setPropValue(micromirrorDeviceKey_, Properties.Keys.SA_OFFSET_X_DEG, 0f, true);
            props_.callListeners(); // update plot
          }
        });
    sheetPanel.add(tmp_but);
    tmp_sl =
        pu.makeSlider(
            props.getPropValueFloat(micromirrorDeviceKey_, Properties.Keys.MIN_DEFLECTION_X)
                / 4, // min value
            props.getPropValueFloat(micromirrorDeviceKey_, Properties.Keys.MAX_DEFLECTION_X)
                / 4, // max value
            1000, // the scale factor between internal integer representation and float
                  // representation
            micromirrorDeviceKey_,
            Properties.Keys.SA_OFFSET_X_DEG);
    sheetPanel.add(tmp_sl, "span 4, growx, center, wrap");

    // Create larger panel with slice, sheet, and calibration panels
    JPanel superPanel = new JPanel(new MigLayout("", "[]8[]", "[]8[]"));
    superPanel.setBorder(BorderFactory.createLineBorder(ASIdiSPIM.borderColor));

    superPanel.add(slicePanel);
    superPanel.add(new JSeparator(SwingConstants.VERTICAL), "growy, shrinkx, center");
    superPanel.add(calibrationPanel, "wrap");
    superPanel.add(new JSeparator(SwingConstants.HORIZONTAL), "span 3, growx, shrinky, wrap");
    superPanel.add(sheetPanel, "span 3");

    // Layout of the SetupPanel
    joystickPanel_ = new JoystickSubPanel(joystick_, devices_, panelName_, side, prefs_);
    add(joystickPanel_, "center");

    add(superPanel, "center, aligny top, span 1 3, wrap");

    beamPanel_ = new BeamSubPanel(gui_, devices_, panelName_, side, prefs_, props_);
    add(beamPanel_, "center, wrap");

    cameraPanel_ = new CameraSubPanel(gui_, cameras_, devices_, panelName_, side, prefs_, true);
    add(cameraPanel_, "center");
  } // end of SetupPanel constructor