Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix for computeScanSpeed #266

Merged
merged 1 commit into from
Apr 18, 2024
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 @@ -17,6 +17,7 @@
import org.micromanager.lightsheetmanager.model.devices.vendor.ASIXYStage;
import org.micromanager.lightsheetmanager.model.devices.vendor.ASIZStage;
import org.micromanager.lightsheetmanager.model.devices.vendor.SingleAxis;
import org.micromanager.lightsheetmanager.model.utils.GeometryUtils;
import org.micromanager.lightsheetmanager.model.utils.NumberUtils;

import java.awt.Rectangle;
Expand Down Expand Up @@ -404,17 +405,17 @@ public boolean prepareControllerForAcquisitionSCAPE(
// Compute appropriate motor speed in mm/s for the given stage scanning settings
public double computeScanSpeed(DefaultAcquisitionSettingsSCAPE settings, final int numScansPerSlice) {
//double sliceDuration = settings.timingSettings().sliceDuration();
//double sliceDuration = 0.0; // TODO: get from SliceTiming
double sliceDuration = getSliceDuration(settings.timingSettings(), numScansPerSlice); // TODO: ???
// TODO: getSliceDuration only used here, but maybe should be computed elsewhere, and get with method above?
double sliceDuration = getSliceDuration(settings.timingSettings(), numScansPerSlice);
if (settings.acquisitionMode() == AcquisitionMode.STAGE_SCAN_INTERLEAVED) {
// pretend like our slice takes twice as long so that we move the correct speed
// this has the effect of halving the motor speed
// but keeping the scan distance the same
// this has the effect of halving the motor speed, but keeping the scan distance the same
sliceDuration *= 2;
}
final int channelsPerPass = computeScanChannelsPerPass(settings);
//return settings.getStepSize() * du.getStageGeometricSpeedFactor(settings.firstSideIsA) / sliceDuration / channelsPerPass;
return settings.volumeSettings().sliceStepSize() / sliceDuration / channelsPerPass; // TODO: add getStageGeometricSpeedFactor
final double speedFactor = GeometryUtils.getStageGeometricSpeedFactor(
settings.scanSettings().scanAngleFirstView(), settings.volumeSettings().firstView() == 1);
return settings.volumeSettings().sliceStepSize() * speedFactor / sliceDuration / channelsPerPass;
}

// compute how many channels we do in each one-way scan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ public void computeGrid() {

if (useX_) {
// TODO: update GUI with values, aliases for asb and vsb?
final double speedFactor = GeometryUtils.DISPIM.getStageGeometricSpeedFactor(true);
final double speedFactor = GeometryUtils.getStageGeometricSpeedFactor(
model_.acquisitions().settings().scanSettings().scanAngleFirstView(),true);
model_.acquisitions().settingsBuilder().volumeSettingsBuilder().sliceStepSize(Math.abs(deltaX_)/speedFactor);
model_.acquisitions().settingsBuilder().volumeSettingsBuilder().slicesPerView(numX);
// move to X center if we aren't generating a position list with it
Expand Down Expand Up @@ -171,15 +172,15 @@ public void setUseX(final boolean state) {
}

public boolean getUseY() {
return useX_;
return useY_;
}

public void setUseY(final boolean state) {
useY_ = state;
}

public boolean getUseZ() {
return useX_;
return useZ_;
}

public void setUseZ(final boolean state) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,54 @@
package org.micromanager.lightsheetmanager.model.utils;

// TODO: make this generic for diSPIM/SCOPE or have separate static classes
public class GeometryUtils {

public static class DISPIM {

/***
* Compute how far we need to shift each image for deskew relative to Z-step size (orthogonal to image) based on user-specified angle
* e.g. with diSPIM, angle is 45 degrees so factor is 1.0, for oSPIM the factor is tan(60 degrees) = sqrt(3), etc.
* if pathA is false then we compute based on Path B angle (assumed to be 90 degrees minus one specified for Path A)
* @param pathA true if using Path A
* @return factor, e.g. 1.0 for 45 degrees, sqrt(3) for 60 degrees, etc.
*/
public static double getStageGeometricShiftFactor(boolean pathA) {
double angle = 1.0; // TODO: props_.getPropValueFloat(Devices.Keys.PLUGIN, Properties.Keys.PLUGIN_STAGESCAN_ANGLE_PATHA);
if (angle < 1) { // case when property not defined
angle = 45.0;
//angle = ASIdiSPIM.oSPIM ? 60.0 : 45.0;
}
if (!pathA) {
angle = 90.0 - angle;
}
return Math.tan(angle/180.0*Math.PI);
/***
* Compute how far we need to shift each image for deskew relative to Z-step size (orthogonal to image) based on user-specified angle
* e.g. with diSPIM, angle is 45 degrees so factor is 1.0, for oSPIM the factor is tan(60 degrees) = sqrt(3), etc.
* if pathA is false then we compute based on Path B angle (assumed to be 90 degrees minus one specified for Path A)
* @param pathA true if using Path A
* @return factor, e.g. 1.0 for 45 degrees, sqrt(3) for 60 degrees, etc.
*/
public static double getStageGeometricShiftFactor(double angle, final boolean pathA) {
//double angle = 1.0; // TODO: props_.getPropValueFloat(Devices.Keys.PLUGIN, Properties.Keys.PLUGIN_STAGESCAN_ANGLE_PATHA);
if (angle < 1) { // case when property not defined
angle = 45.0;
//angle = ASIdiSPIM.oSPIM ? 60.0 : 45.0;
}

/***
* Compute fractional size when viewed from above for overview image based on user-specified angle
* e.g. with diSPIM, angle is 45 degrees so factor is cos(45 degrees) = 1/sqrt(2), for oSPIM would be cos(60 degrees) = 0.5, etc.
* if pathA is false then we compute based on Path B angle (assumed to be 90 degrees minus one specified for Path A)
* @param pathA true if using Path A
* @return factor, e.g. 1/sqrt(2) for 45 degrees, 0.5 for 60 degrees, etc.
*/
public static double getStageTopViewCompressFactor(boolean pathA) {
double angle = 1.0; // TODO: props_.getPropValueFloat(Devices.Keys.PLUGIN, Properties.Keys.PLUGIN_STAGESCAN_ANGLE_PATHA);
if (angle < 1) { // case when property not defined
angle = 45.0;
//angle = ASIdiSPIM.oSPIM ? 60.0 : 45.0;
}
if (!pathA) {
angle = 90.0 - angle;
}
return Math.cos(angle/180.0*Math.PI);
if (!pathA) {
angle = 90.0 - angle;
}
return Math.tan(angle/180.0*Math.PI);
}

/***
* Compute how far we need to move the stage relative to the Z-step size (orthogonal to image) based on user-specified angle
* e.g. with diSPIM, angle is 45 degrees so go 1/cos(45deg) = 1.41x faster, with oSPIM, angle is 60 degrees so go 1/cos(60deg) = 2x faster
* if pathA is false then we compute based on Path B angle (assumed to be 90 degrees minus one specified for Path A)
* @param pathA true if using Path A
* @return factor, e.g. 1.41 for 45 degrees, 2 for 60 degrees, etc.
*/
public static double getStageGeometricSpeedFactor(boolean pathA) {
return 1/(getStageTopViewCompressFactor(pathA));
/***
* Compute fractional size when viewed from above for overview image based on user-specified angle
* e.g. with diSPIM, angle is 45 degrees so factor is cos(45 degrees) = 1/sqrt(2), for oSPIM would be cos(60 degrees) = 0.5, etc.
* if pathA is false then we compute based on Path B angle (assumed to be 90 degrees minus one specified for Path A)
* @param pathA true if using Path A
* @return factor, e.g. 1/sqrt(2) for 45 degrees, 0.5 for 60 degrees, etc.
*/
public static double getStageTopViewCompressFactor(double angle, final boolean pathA) {
//double angle = 1.0; // TODO: props_.getPropValueFloat(Devices.Keys.PLUGIN, Properties.Keys.PLUGIN_STAGESCAN_ANGLE_PATHA);
if (angle < 1) { // case when property not defined
angle = 45.0;
//angle = ASIdiSPIM.oSPIM ? 60.0 : 45.0;
}
if (!pathA) {
angle = 90.0 - angle;
}
return Math.cos(angle/180.0*Math.PI);
}

/***
* Compute how far we need to move the stage relative to the Z-step size (orthogonal to image) based on user-specified angle
* e.g. with diSPIM, angle is 45 degrees so go 1/cos(45deg) = 1.41x faster, with oSPIM, angle is 60 degrees so go 1/cos(60deg) = 2x faster
* if pathA is false then we compute based on Path B angle (assumed to be 90 degrees minus one specified for Path A)
* @param pathA true if using Path A
* @return factor, e.g. 1.41 for 45 degrees, 2 for 60 degrees, etc.
*/
public static double getStageGeometricSpeedFactor(final double angle, final boolean pathA) {
return 1/getStageTopViewCompressFactor(angle, pathA);
}
}
Loading