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)