Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ private boolean doHardwareCalculations(PLogicDispim plc) {
boolean changeChannelPerVolumeSoftware = false;
boolean changeChannelPerVolumeDoneFirst = false;
if (acqSettings_.channels().enabled()) {
if (acqSettings_.channels().count() > 1) {
if (acqSettings_.channels().count() == 0) {
studio_.logs().showError("\"Channels\" is checked, but no channels are selected");
return false; // early exit
}
Expand All @@ -650,14 +650,14 @@ private boolean doHardwareCalculations(PLogicDispim plc) {
// we have at least 2 channels
// intentionally leave extraChannelOffset_ untouched so that it can be specified by user by choosing a preset
// for the channel in the main Micro-Manager window
final boolean success = plc.setupHardwareChannelSwitching(acqSettings_);
if (!success) {
studio_.logs().showError("Couldn't set up slice hardware channel switching.");
return false; // early exit
}
nrChannelsSoftware = 1;
nrSlicesSoftware = acqSettings_.volume().slicesPerView() * acqSettings_.channels().count();
}
final boolean success = plc.setupHardwareChannelSwitching(acqSettings_);
if (!success) {
studio_.logs().showError("Couldn't set up slice hardware channel switching.");
return false; // early exit
}
nrChannelsSoftware = 1;
nrSlicesSoftware = acqSettings_.volume().slicesPerView() * acqSettings_.channels().count();
break;
default:
studio_.logs().showError(
Expand Down Expand Up @@ -762,7 +762,7 @@ public void recalculateSliceTiming() {
CameraBase camera = model_.devices().device("ImagingCamera");
camera.setTriggerMode(acqSettings_.cameraMode());
studio_.logs().logDebugMessage(
"camera \"" + camera.getDeviceName() + "\" set to mode: " + camera.getTriggerMode());
"camera \"" + camera.getDeviceName() + "\" requested mode: " + camera.getTriggerMode());
}
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,6 @@ boolean run() {
studio_.logs().showError("Must have stage with scan-enabled firmware for stage scanning.");
return false;
}
if (acqSettings_.acquisitionMode() == AcquisitionMode.STAGE_SCAN_INTERLEAVED) {
if (acqSettings_.volume().numViews() < 2) {
studio_.logs().showError("Interleaved stage scan requires two sides.");
}
return false;
}

// second part: initialize stage scanning, so we can restore state later
xyPosUm_ = xyStage.getXYPosition();
origSpeedX_ = xyStage.getSpeedX();
Expand Down Expand Up @@ -873,7 +866,7 @@ private boolean doHardwareCalculations(PLogicScape plc) {
for (CameraBase camera : cameras) {
camera.setTriggerMode(acqSettings_.cameraMode());
studio_.logs().logMessage("camera \"" + camera.getDeviceName()
+ "\" set to mode: " + camera.getTriggerMode());
+ "\" requested mode: " + camera.getTriggerMode());
}

// make sure slice timings are up-to-date
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ public AndorCamera(Studio studio, String deviceName) {
}

@Override
public void setTriggerMode(CameraMode cameraMode) {
mode_ = cameraMode;
protected void applyTriggerMode(CameraMode cameraMode) {
// work-around a bug in SDK3 device adapter, can't switch from light sheet mode
// to "normal" center out simultaneous but works if we always go through the in-between mode
if (hasProperty(Properties.SENSOR_READOUT_MODE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@
* This is the base camera class.
*
* <p>Methods that need per-vendor knowledge are abstract on purpose: a camera class that
* forgets one fails to compile. Cameras whose device library resolves to
* {@code CameraLibrary.UNKNOWN} use {@link UnknownCamera}.
* forgets one fails to compile.
*
* <p>Trigger mode is the exception: implement {@link #applyTriggerMode}, which only has to write
* the mode to the device. {@link #setTriggerMode} is final and records it here for
* {@link #getTriggerMode}, so no vendor has to maintain it.
*
* <p>Cameras whose device library resolves to {@code CameraLibrary.UNKNOWN} use
* {@link UnknownCamera}.
*/
public abstract class CameraBase extends DeviceBase implements LightSheetCamera {

Expand Down Expand Up @@ -239,13 +245,32 @@ public int roiReadoutRowsSplitReadout(Rectangle roi, Rectangle sensor) {

// needed for subclasses

/**
* Sets the camera trigger mode and records it.
*
* <p>Final because the recorded mode is base state, which a vendor override would have to
* remember to maintain. Vendors implement {@link #applyTriggerMode} instead.
*/
@Override
public void setTriggerMode(CameraMode cameraMode) {
public final void setTriggerMode(final CameraMode cameraMode) {
applyTriggerMode(cameraMode);
mode_ = cameraMode;
}

/**
* Writes the trigger mode to the device.
*/
protected abstract void applyTriggerMode(final CameraMode cameraMode);

/**
* Returns the last mode requested through {@link #setTriggerMode}.
*
* <p>This is not a device readback because the vendor mapping from camera mode to device
* properties is not always reversible, so the requested mode is the only answer every camera
* can give.
*/
@Override
public CameraMode getTriggerMode() {
public final CameraMode getTriggerMode() {
return mode_;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public DemoCamera(Studio studio, String deviceName) {
}

@Override
public void setTriggerMode(final CameraMode cameraMode) {
protected void applyTriggerMode(final CameraMode cameraMode) {
// do nothing - no camera trigger modes - always internal - log for debug convenience
studio_.logs().logMessage(
"setTriggerMode(" + cameraMode + ") called but the DemoCamera is always in internal mode.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public HamamatsuCamera(final Studio studio, final String deviceName) {
}

@Override
public void setTriggerMode(final CameraMode cameraMode) {
mode_ = cameraMode;
protected void applyTriggerMode(final CameraMode cameraMode) {
setProperty(Properties.TRIGGER_SOURCE, (cameraMode == CameraMode.INTERNAL) ? Values.INTERNAL : Values.EXTERNAL);
setProperty(Properties.SENSOR_MODE, (cameraMode == CameraMode.VIRTUAL_SLIT) ? Values.PROGRESSIVE : Values.AREA);
switch (cameraMode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public PcoCamera(Studio studio, String deviceName) {
}

@Override
public void setTriggerMode(CameraMode cameraMode) {
mode_ = cameraMode;
protected void applyTriggerMode(CameraMode cameraMode) {
switch (cameraMode) {
case EDGE:
case PSEUDO_OVERLAP:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public PvCamera(final Studio studio, final String deviceName) {
}

@Override
public void setTriggerMode(final CameraMode cameraMode) {
protected void applyTriggerMode(final CameraMode cameraMode) {
switch (cameraMode) {
case EDGE:
case PSEUDO_OVERLAP:
Expand All @@ -58,11 +58,6 @@ public void setTriggerMode(final CameraMode cameraMode) {
}
}

@Override
public CameraMode getTriggerMode() {
return CameraMode.fromString(getProperty(Properties.TRIGGER_MODE));
}

@Override
public void setBinning() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ private UnsupportedOperationException unsupported(final String what) {
+ " is unknown. Supported: AndorSDK3, HamamatsuHam, PCO_Camera, PVCAM, DemoCamera.");
}

@Override
protected void applyTriggerMode(final CameraMode cameraMode) {
throw unsupported("trigger mode");
}

@Override
public void setBinning() {
throw unsupported("binning");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static double roundToPlace(final double value, final int place) {
/**
* Return the double value rounded up to the nearest increment of 0.25.
* <p>Example: 0.0 goes to 0.0 but 0.01 goes to 0.25
* <p>Quarter milliseconds are the timing quantum because the PLogic evaluates its cells at 4kHz.
*
* @param value the value to round up
* @return the value rounded up
Expand All @@ -58,6 +59,7 @@ public static double ceilToQuarterMs(final double value) {

/**
* Return the double value rounded to the nearest increment of 0.25.
* <p>Quarter milliseconds are the timing quantum because the PLogic evaluates its cells at 4kHz.
*
* @param value the value to round
* @return the rounded value
Expand Down
Loading