From a48a9c01d3f25e5cee48acb447e1908e5e2ba4fe Mon Sep 17 00:00:00 2001
From: Russell Anderson <5637107+rpanderson@users.noreply.github.com>
Date: Mon, 15 Jun 2020 13:15:48 +1000
Subject: [PATCH 1/2] Example connection table and labscript experiment script
 for RemoteBLACS and IMAQdxCamera

---
 .../connection_table_IMAQdx_remote.py         | 40 +++++++++++++++
 .../example_IMAQdx_remote.py                  | 51 +++++++++++++++++++
 2 files changed, 91 insertions(+)
 create mode 100644 labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/connection_table_IMAQdx_remote.py
 create mode 100644 labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/example_IMAQdx_remote.py

diff --git a/labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/connection_table_IMAQdx_remote.py b/labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/connection_table_IMAQdx_remote.py
new file mode 100644
index 0000000..5bc412f
--- /dev/null
+++ b/labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/connection_table_IMAQdx_remote.py
@@ -0,0 +1,40 @@
+from labscript import start, stop, add_time_marker, Trigger, RemoteBLACS
+from labscript_devices.DummyPseudoclock.labscript_devices import DummyPseudoclock
+from labscript_devices.DummyIntermediateDevice import DummyIntermediateDevice
+from labscript_devices.IMAQdxCamera.labscript_devices import IMAQdxCamera
+
+# Use a virtual ('dummy') device for the psuedoclock
+DummyPseudoclock(name='pseudoclock')
+
+# An output of this DummyPseudoclock is its 'clockline' attribute, which we use
+# to trigger children devices
+DummyIntermediateDevice(name='intermediate_device', parent_device=pseudoclock.clockline)
+
+# Instantiate a labscript.Trigger instance used to trigger the camera exposure
+# This will be specified as the camera's parent device later
+Trigger(
+    name='camera_trigger', parent_device=intermediate_device, connection='port0/line0'
+)
+
+# On the host specified below, start the RemoteBLACS server by running the following:
+# $ python - m labscript_utils.remote
+RemoteBLACS(name='test_remote', host='localhost')
+
+# We then initiate an IMAQdxCamera using this RemoteBLACS instance
+# using mock=True to bypass any attempts to commmunicate with an
+# actual camera, and generate fake data at the end of the shot
+IMAQdxCamera(
+    name='camera',
+    parent_device=camera_trigger,
+    connection='trigger',
+    serial_number=0xDEADBEEF,
+    worker=test_remote,
+    mock=True,
+)
+
+# Begin issuing labscript primitives
+# start() elicits the commencement of the shot
+start()
+
+# Stop the experiment shot with stop()
+stop(1.0)
diff --git a/labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/example_IMAQdx_remote.py b/labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/example_IMAQdx_remote.py
new file mode 100644
index 0000000..d0a3a61
--- /dev/null
+++ b/labscript_profile/default_profile/userlib/labscriptlib/example_apparatus/example_IMAQdx_remote.py
@@ -0,0 +1,51 @@
+from labscript import start, stop, add_time_marker, Trigger, RemoteBLACS
+from labscript_devices.DummyPseudoclock.labscript_devices import DummyPseudoclock
+from labscript_devices.DummyIntermediateDevice import DummyIntermediateDevice
+from labscript_devices.IMAQdxCamera.labscript_devices import IMAQdxCamera
+
+# Use a virtual ('dummy') device for the psuedoclock
+DummyPseudoclock(name='pseudoclock')
+
+# An output of this DummyPseudoclock is its 'clockline' attribute, which we use
+# to trigger children devices
+DummyIntermediateDevice(name='intermediate_device', parent_device=pseudoclock.clockline)
+
+# Instantiate a labscript.Trigger instance used to trigger the camera exposure
+# This will be specified as the camera's parent device later
+Trigger(
+    name='camera_trigger', parent_device=intermediate_device, connection='port0/line0'
+)
+
+# On the host specified below, start the RemoteBLACS server by running the following:
+# $ python - m labscript_utils.remote
+RemoteBLACS(name='test_remote', host='localhost')
+
+# We then initiate an IMAQdxCamera using this RemoteBLACS instance
+# using mock=True to bypass any attempts to commmunicate with an
+# actual camera, and generate fake data at the end of the shot
+IMAQdxCamera(
+    name='camera',
+    parent_device=camera_trigger,
+    connection='trigger',
+    serial_number=0xDEADBEEF,
+    worker=test_remote,
+    mock=True,
+)
+
+# Begin issuing labscript primitives
+# A timing variable t is used for convenience
+# start() elicits the commencement of the shot
+t = 0
+add_time_marker(t, "Start", verbose=True)
+start()
+
+t += 1
+add_time_marker(t, "Exposure: 'before' image", verbose=True)
+camera.expose(t, name='comparison', frametype='before', trigger_duration=0.2)
+
+t += 0.5
+add_time_marker(t, "Exposure: 'after' image", verbose=True)
+camera.expose(t, name='comparison', frametype='after', trigger_duration=0.2)
+
+t += 0.5
+stop(t)

From 66d0be49b78d52fe0c870b2a335185c59d04826e Mon Sep 17 00:00:00 2001
From: Russell Anderson <5637107+rpanderson@users.noreply.github.com>
Date: Mon, 15 Jun 2020 13:37:23 +1000
Subject: [PATCH 2/2] lyse analysis script demonstrating some Run methods for
 example_IMAQdx_remote

---
 .../example_IMAQdx_remote.py                  | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 labscript_profile/default_profile/userlib/analysislib/example_apparatus/example_IMAQdx_remote.py

diff --git a/labscript_profile/default_profile/userlib/analysislib/example_apparatus/example_IMAQdx_remote.py b/labscript_profile/default_profile/userlib/analysislib/example_apparatus/example_IMAQdx_remote.py
new file mode 100644
index 0000000..e4c30b7
--- /dev/null
+++ b/labscript_profile/default_profile/userlib/analysislib/example_apparatus/example_IMAQdx_remote.py
@@ -0,0 +1,46 @@
+import lyse
+from pathlib import Path
+import matplotlib.pyplot as plt
+
+# Is this script being run from within an interactive lyse session?
+if lyse.spinning_top:
+    # If so, use the filepath of the current shot
+    h5_path = lyse.path
+else:
+    # If not, get the filepath of the last shot of the lyse DataFrame
+    df = lyse.data()
+    h5_path = df.filepath.iloc[-1]
+
+# Instantiate a lyse.Run object for this shot
+run = lyse.Run(h5_path)
+
+# Get a dictionary of the global variables used in this shot
+run_globals = run.get_globals()
+
+# Extract the images 'before' and 'after' generated from camera.expose
+before, after = run.get_images('camera', 'comparison', 'before', 'after')
+
+# Compute the difference of the two images, after casting them to signed integers
+# (otherwise negative differences wrap to 2**16 - 1 - diff)
+diff = after.astype('int16') - before.astype('int16')
+
+# Plot the row-wise mean of each image
+plt.plot(before.mean(axis=0), label='before')
+plt.plot(after.mean(axis=0), label='after')
+plt.xlabel('pixel coordinate (column)')
+plt.ylabel('counts')
+
+# Label the plot with a unique string representing the shot
+plt.title(Path(run.h5_path).name)
+
+# Plot adornments
+plt.legend(loc='lower left')
+plt.grid()
+
+# Show the plot
+plt.show()
+
+# Compute a result based on the image processing and save it to the 'results' group of
+# the shot file
+result = diff.std()
+run.save_result('foobar', result)