Skip to content

Commit

Permalink
Merge pull request #101 from henrypinkard/main
Browse files Browse the repository at this point in the history
add timeout to acquisition events
  • Loading branch information
henrypinkard authored Aug 19, 2023
2 parents 4ecfeef + ec9613d commit 380e74b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.micro-manager.acqengj</groupId>
<artifactId>AcqEngJ</artifactId>
<version>0.30.0</version>
<version>0.31.0</version>
<packaging>jar</packaging>
<name>AcqEngJ</name>
<description>Java-based Acquisition engine for Micro-Manager</description>
Expand Down
46 changes: 37 additions & 9 deletions src/main/java/org/micromanager/acqj/internal/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.lang.Double;
import java.util.concurrent.TimeoutException;

import mmcorej.CMMCore;
import mmcorej.Configuration;
import mmcorej.DoubleVector;
Expand Down Expand Up @@ -336,7 +338,13 @@ private void executeAcquisitionEvent(AcquisitionEvent event) throws InterruptedE
if (event.acquisition_.isDebugMode()) {
core_.logMessage("acquiring image(s)" );
}
acquireImages(event);
try {
acquireImages(event, hardwareSequencesInProgress);
} catch (TimeoutException e) {
// Don't abort on a timeout
// TODO: this could probably be an option to the acquisition in the future
System.err.println("Timeout while acquiring images");
}

// if the acquisition was aborted, make sure everything shuts down properly
abortIfRequested(event, hardwareSequencesInProgress);
Expand All @@ -361,7 +369,8 @@ private void executeAcquisitionEvent(AcquisitionEvent event) throws InterruptedE
* @param event
* @throws HardwareControlException
*/
private void acquireImages(final AcquisitionEvent event) throws HardwareControlException {
private void acquireImages(final AcquisitionEvent event,
HardwareSequences hardwareSequencesInProgress) throws HardwareControlException, TimeoutException {
FutureTask<Void> future = null;
try {
if (event.getSequence() != null && event.getSequence().size() > 1) {
Expand Down Expand Up @@ -453,9 +462,16 @@ private void acquireImages(final AcquisitionEvent event) throws HardwareControlE
if (event.acquisition_.isDebugMode()) {
core_.logMessage("images acquired, copying from core" );
}
long startCopyTime = System.currentTimeMillis();
// Loop through and collect all acquired images. There will be
// (# of images in sequence) x (# of camera channels) of them
boolean timeout = false;
for (int i = 0; i < (event.getSequence() == null ? 1 : event.getSequence().size()); i++) {
if (timeout) {
// Cancel the rest of the sequence
stopHardwareSequences(hardwareSequencesInProgress);
break;
}
double exposure;

try {
Expand Down Expand Up @@ -486,9 +502,18 @@ private void acquireImages(final AcquisitionEvent event) throws HardwareControlE
if (!core_.isSequenceRunning() && core_.getRemainingImageCount() == 0) {
throw new RuntimeException("Expected images did not arrive in circular buffer");
}
// check it timeout has been exceeded
if (event.getSequence().get(i).getTimeout_ms() != null) {
if (System.currentTimeMillis() - startCopyTime > event.getSequence().get(i).getTimeout_ms()) {
timeout = true;
break;
}
}
}
} else {
try {
// TODO: probably there should be a timeout here too, but I'm
// not sure the snapImage system supports it (as opposed to sequences)
ti = core_.getTaggedImage(camIndex);
cameraName = core_.getCameraDevice();
} catch (Exception e) {
Expand All @@ -502,7 +527,10 @@ private void acquireImages(final AcquisitionEvent event) throws HardwareControlE
throw e;
}
}
//Doesnt seem to be a version in the API in which you dont have to do this
if (timeout) {
break;
}
// Doesnt seem to be a version in the API in which you dont have to do this
int actualCamIndex = camIndex;
if (ti.tags.has("Multi Camera-CameraChannelIndex")) {
try {
Expand Down Expand Up @@ -531,21 +559,18 @@ private void acquireImages(final AcquisitionEvent event) throws HardwareControlE
// multi camera adapter or just using the default camera
correspondingEvent = multiCamAdapterCameraEventLists.get(actualCamIndex).remove(0);
}

}
//add metadata
// add standard metadata
AcqEngMetadata.addImageMetadata(ti.tags, correspondingEvent,
currentTime - correspondingEvent.acquisition_.getStartTime_ms(), exposure);
// add user metadata specified in the event
try {
correspondingEvent.acquisition_.addTagsToTaggedImage(ti.tags,
correspondingEvent.getTags());
correspondingEvent.acquisition_.addTagsToTaggedImage(ti.tags, correspondingEvent.getTags());
} catch (JSONException jse) {
core_.logMessage("Error adding tags to image metadata", false);
}
correspondingEvent.acquisition_.addToImageMetadata(ti.tags);

correspondingEvent.acquisition_.addToOutput(ti);

}
}
if (future != null) {
Expand All @@ -559,6 +584,9 @@ private void acquireImages(final AcquisitionEvent event) throws HardwareControlE
core_.logMessage("Exception during future execution");
}
}
if (timeout) {
throw new TimeoutException("Timeout waiting for images to arrive in circular buffer");
}
}

private void abortIfRequested(AcquisitionEvent event,
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/micromanager/acqj/main/AcquisitionEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum SpecialFlag {

// If null, use Core-camera, otherwise, use this camera
private String camera_ = null;
private Double timeout_ms_ = null;

private String configGroup_, configPreset_ = null;
private Double exposure_ = null; //leave null to keep exposaure unchanged
Expand Down Expand Up @@ -151,6 +152,7 @@ public AcquisitionEvent copy() {
e.acquireImage_ = acquireImage_;
e.properties_ = new TreeSet<ThreeTuple>(this.properties_);
e.camera_ = camera_;
e.timeout_ms_ = timeout_ms_;
e.setTags(tags_);
return e;
}
Expand Down Expand Up @@ -186,6 +188,10 @@ private static JSONObject eventToJSON(AcquisitionEvent e) {
json.put("slm_pattern", e.slmImage_);
}

if (e.timeout_ms_ != null) {
json.put("timeout_ms", e.timeout_ms_);
}

//Coordinate indices
JSONObject axes = new JSONObject();
for (String axis : e.axisPositions_.keySet()) {
Expand Down Expand Up @@ -280,6 +286,10 @@ private static AcquisitionEvent eventFromJSON(JSONObject json, AcquisitionAPI ac
event.miniumumStartTime_ms_ = (long) (json.getDouble("min_start_time") * 1000);
}

if (json.has("timeout")) {
event.timeout_ms_ = json.getDouble("timeout");
}

// Config group (usually this is a channel, but doesnt have to be)
if (json.has("config_group")) {
event.configGroup_ = json.getJSONArray("config_group").getString(0);
Expand All @@ -289,6 +299,10 @@ private static AcquisitionEvent eventFromJSON(JSONObject json, AcquisitionAPI ac
event.exposure_ = json.getDouble("exposure");
}

if (json.has("timeout_ms")) {
event.slmImage_ = json.getDouble("timeout_ms");
}

if (json.has("stage_positions")) {
JSONArray stagePositions = json.getJSONArray("stage_positions");
for (int i = 0; i < stagePositions.length(); i++) {
Expand Down Expand Up @@ -513,6 +527,10 @@ public Object getAxisPosition(String label) {
return axisPositions_.get(label);
}

public Double getTimeout_ms() {
return timeout_ms_;
}

public void setTimeIndex(int index) {
setAxisPosition(AcqEngMetadata.TIME_AXIS, index);
}
Expand Down

0 comments on commit 380e74b

Please sign in to comment.