Skip to content

Commit

Permalink
Merge pull request #91 from nicost/tags
Browse files Browse the repository at this point in the history
Add tags in events that will be added to metadata.
  • Loading branch information
henrypinkard authored Jun 6, 2023
2 parents 386b491 + bc9cae0 commit 3173e2b
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 19 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.27.0</version>
<version>0.28.0</version>
<packaging>jar</packaging>
<name>AcqEngJ</name>
<description>Java-based Acquisition engine for Micro-Manager</description>
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/micromanager/acqj/internal/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import mmcorej.org.json.JSONException;
import org.micromanager.acqj.api.AcquisitionAPI;
import org.micromanager.acqj.main.AcquisitionEvent;
import org.micromanager.acqj.api.AcquisitionHook;
Expand Down Expand Up @@ -534,6 +535,12 @@ private void acquireImages(final AcquisitionEvent event) throws HardwareControlE
//add metadata
AcqEngMetadata.addImageMetadata(ti.tags, correspondingEvent,
currentTime - correspondingEvent.acquisition_.getStartTime_ms(), exposure);
try {
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);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/micromanager/acqj/main/AcqEngMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ public class AcqEngMetadata {
public static final String CORE_XYSTAGE = "Core-XYStage";
public static final String CORE_FOCUS = "Core-Focus";
public static final String AXES = "Axes";

public static final String CHANNEL_AXIS = "channel";
public static final String TIME_AXIS = "time";
public static final String Z_AXIS = "z";
public static final String TAGS = "tags";

private static final String ACQUISITION_EVENT = "Event";


Expand Down
54 changes: 41 additions & 13 deletions src/main/java/org/micromanager/acqj/main/Acquisition.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
//
package org.micromanager.acqj.main;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.Consumer;

Expand Down Expand Up @@ -156,11 +158,35 @@ public void addToImageMetadata(JSONObject tags) {
}
}

/**
* Add provided tags (Key-Value pairs of type String) to the Tagged Image tags.
* These will appear as JSONObjects under the key:
* {@link org.micromanager.acqj.main.AcqEngMetadata#TAGS "Tags"}.
*
* @param tags Tagged Image tags
* @param moreTags User-provided tags as Key-Value pairs
*/
public void addTagsToTaggedImage(JSONObject tags, HashMap<String, String> moreTags)
throws JSONException {
if (moreTags.isEmpty()) {
return;
}
JSONObject moreTagsObject = new JSONObject();
for (Map.Entry<String, String> entry : moreTags.entrySet()) {
try {
moreTagsObject.put(entry.getKey(), entry.getValue());
} catch (JSONException e) {
e.printStackTrace();
}
}
tags.put(AcqEngMetadata.TAGS, moreTagsObject);
}

@Override
public Future submitEventIterator(Iterator<AcquisitionEvent> evt) {
if (!started_) {
start();
}
}
return Engine.getInstance().submitEventIterator(evt);
}

Expand Down Expand Up @@ -283,19 +309,21 @@ public void waitForCompletion() {
* 3) Initialize data sink.
*/
protected void initialize() {
JSONObject summaryMetadata = AcqEngMetadata.makeSummaryMD(this);
addToSummaryMetadata(summaryMetadata);
if (core_ != null) {
JSONObject summaryMetadata = AcqEngMetadata.makeSummaryMD(this);
addToSummaryMetadata(summaryMetadata);

try {
// Make a local in copy in case something else modifies it
summaryMetadata_ = new JSONObject(summaryMetadata.toString());
} catch (JSONException ex) {
System.err.print("Couldn't copy summaary metadata");
ex.printStackTrace();
}
if (dataSink_ != null) {
//It could be null if not using saving and viewing and diverting with custom processor
dataSink_.initialize(this, summaryMetadata);
try {
// Make a local in copy in case something else modifies it
summaryMetadata_ = new JSONObject(summaryMetadata.toString());
} catch (JSONException ex) {
System.err.print("Couldn't copy summaary metadata");
ex.printStackTrace();
}
if (dataSink_ != null) {
//It could be null if not using saving and viewing and diverting with custom processor
dataSink_.initialize(this, summaryMetadata);
}
}
}

Expand Down
44 changes: 40 additions & 4 deletions src/main/java/org/micromanager/acqj/main/AcquisitionEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import mmcorej.org.json.JSONArray;
Expand Down Expand Up @@ -64,6 +66,8 @@ enum SpecialFlag {
private HashMap<String, Double> stageCoordinates_ = new HashMap<String, Double>();
// Mapping from device names to axis names
private HashMap<String, String> stageDeviceNamesToAxisNames_ = new HashMap<String, String>();
// tags to be added to the acquired image
private final HashMap<String, String> tags_ = new HashMap<String, String>();

//Option to not acquire an image for SLM events
private Boolean acquireImage_ = null;
Expand Down Expand Up @@ -142,6 +146,7 @@ public AcquisitionEvent copy() {
e.acquireImage_ = acquireImage_;
e.properties_ = new TreeSet<ThreeTuple>(this.properties_);
e.camera_ = camera_;
e.setTags(tags_);
return e;
}

Expand Down Expand Up @@ -213,6 +218,14 @@ private static JSONObject eventToJSON(AcquisitionEvent e) {
json.put("camera", e.camera_);
}

if (e.getTags() != null) {
JSONObject jsonTags = new JSONObject();
for (Map.Entry<String, String> entry : e.getTags().entrySet()) {
jsonTags.put(entry.getKey(), entry.getValue());
}
json.put("tags", jsonTags);
}

//TODO: galvo
//TODO: more support for imperative API calls (i.e. SLM set image)
//Arbitrary extra properties
Expand All @@ -223,7 +236,7 @@ private static JSONObject eventToJSON(AcquisitionEvent e) {
prop.put(t.prop);
prop.put(t.val);
props.put(prop);
}
}
if (props.length() > 0) {
json.put("properties", props);
}
Expand Down Expand Up @@ -318,6 +331,17 @@ private static AcquisitionEvent eventFromJSON(JSONObject json, AcquisitionAPI ac
event.camera_ = json.getString("camera");
}

if (json.has("tags")) {
HashMap<String, String> tags = new HashMap<>();
JSONObject jsonTags = json.getJSONObject("tags");
Iterator<String> keys = jsonTags.keys();
while (keys.hasNext()) {
String key = keys.next();
tags.put(key, jsonTags.getString(key));
}
event.setTags(tags);
}

//TODO: galvo, etc (i.e. other aspects of imperative API)


Expand Down Expand Up @@ -434,9 +458,9 @@ public void setProperty(String device, String property, String value) {
}

/**
* Set the minimum start time in ms relative to when the acq started
* Set the minimum start time in ms relative to when the acq started.
*
* @param l
* @param l Minimum start time in ms.
*/
public void setMinimumStartTime(Long l) {
miniumumStartTime_ms_ = l;
Expand Down Expand Up @@ -544,7 +568,7 @@ public Double getZPosition() {
}

/**
* get the minimum start timein system time
* Get the minimum start time in system time.
*
* @return
*/
Expand Down Expand Up @@ -621,6 +645,18 @@ public void setY(double y) {
yPosition_ = y;
}

public void setTags(HashMap<String, String> tags) {
tags_.clear();
if (tags != null) {
tags_.putAll(tags);
}
}
public HashMap<String, String> getTags () {
HashMap<String, String> tags = new HashMap<>(tags_.size());
tags.putAll(tags_);
return tags;
}


//For debugging
@Override
Expand Down
41 changes: 41 additions & 0 deletions tests/org/micromanager/acqj/main/TestAcquisitionEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.micromanager.acqj.main;

import java.util.HashMap;
import mmcorej.org.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import org.micromanager.acqj.example.BlackHoleDataSink;

public class TestAcquisitionEvent {
@Test
public void testSetupIsSane() {
Assert.assertTrue("must be true", true);
}

@Test
public void testEventSerialization() {
BlackHoleDataSink bhds = new BlackHoleDataSink();
Acquisition acq = new Acquisition(bhds);
AcquisitionEvent event = new AcquisitionEvent(acq);
final int z = 2;
event.setZ(z, z * 0.5);
final int t = 3;
event.setTimeIndex(t);
final long minimumStartTime = 892567265;
event.setMinimumStartTime(minimumStartTime);
HashMap<String, String> tags = new HashMap<>();
tags.put("test", "test");
tags.put("test2", "test2");

JSONObject eventSerial = event.toJSON();
AcquisitionEvent eventCopy = AcquisitionEvent.fromJSON(eventSerial, acq);

Assert.assertTrue(eventCopy.getZIndex() == z);
Assert.assertEquals(eventCopy.getZPosition(), z * 0.5, 0.0000001);
Assert.assertTrue(eventCopy.getTIndex() == t);
Assert.assertEquals(eventCopy.getMinimumStartTimeAbsolute(), minimumStartTime, 2000);
Assert.assertEquals(eventCopy.getTags().get("test"), event.getTags().get("test"));
Assert.assertEquals(eventCopy.getTags().get("test2"), event.getTags().get("test2"));
}
}

0 comments on commit 3173e2b

Please sign in to comment.