Acquisitions
The Acquisition
class is a flexible abstraction built to support a multitude of microscopy experiments. Its essential functions are to parse a set of instructions from the user known as “acquisition events”, control the microscope hardware according to these, and efficiently retrieve, save, and provide access to image data from the camera(s). Each of these functionalities can be further modified and/or customized in a variety of ways.
The following shows a minimal example of using Acquisition
class to acquire a sequence of 5 images from the camera and save them to disk:
from pycromanager import Acquisition, multi_d_acquisition_events
with Acquisition(directory='/path/to/saving/dir', name='acquisition_name') as acq:
events = multi_d_acquisition_events(num_time_points=5)
acq.acquire(events)
The data will be displayed in the default image viewer as it is acquired, and it can be also be accessed through the Dataset
class:
dataset = acq.get_dataset()
img = dataset.read_image(time=0) # a numpy array
Standard Multi-Dimensional Acquisitions
In Micro-Manager/Pycro-Manager, “multi-dimensional acquisitions” refer to experiments where images are systematically collected across various combinations of time, z-stack, channel, and xy position axes (non-standard axes outside of these four require additional customization, as described further below). Pycro-Manager provides the multi_d_acquisition_events
function for generating the instructions (acquisition events) to acquire this type of data.
The following shows an example of acquiring a single z-stack:
from pycromanager import Acquisition, multi_d_acquisition_events
with Acquisition(directory='/path/to/saving/dir', name='acquisition_name') as acq:
# Generate the events for a single z-stack
events = multi_d_acquisition_events(z_start=0, z_end=10, z_step=0.5)
acq.acquire(events)
In addition to z-stacks, this function can also be used to do timelapses, different channels, and multiple XY stage positions. This example shows how to run a multi-channel timelapse with z-stacks:
with Acquisition(directory='/path/to/saving/dir', name='acquisition_name') as acq:
events = multi_d_acquisition_events(
num_time_points=4, time_interval_s=0,
channel_group='Channel', channels=['DAPI', 'FITC'],
z_start=0, z_end=6, z_step=0.4,
order='tcz')
acq.acquire(events)
More information on this function can be found in the MDA Tutorial
Special types of Acquisitions
In addition to the regular Acquisition
class, Pycro-manager provides a few special types of Acquisitions, with features designed for specific applications.
XYTiledAcquisition
can be used to image samples that are larger than a single field of view by moving around an XY stage and capturing multiple images, then stitching them together into a single contiguous image. It uses a special, multi-resolution file format to facilitate efficient visualization of the data at multiple scalesAn
ExploreAcquisition
is a special type ofXYTiledAcquisition
that provides a user interface for moving around a XY and Z stage and telling the microscope where to ImageThe
MagellanAcquisition
is a special type ofXYTiledAcquisition
for controlling the Micro-magellan plugin. This plugin provides additional features for mapping samples, defining parts of the sample to image, and collecting specialized 3D datasets.
Hardware sequencing
An important function of the acquisition engine underlying Pycro-Manager is to enable hardware sequencing. In hardware sequencing, multiple images are captured without the computer and hardware having to communicate between each one. In certain cases, this can dramatically increase the speed with which data is acquired. For high-performance applications, hardware sequencing is essential to speed and sufficiently precise synchronization between different hardware components.
The Using an external master clock for hardware control of a stage-scanning high NA oblique plane microscope tutorial shows an example of this in action.
Pycro-manager acquisitions will automatically try to use hardware sequencing when the following conditions are met:
there are no delays requested between successive image
Any hardware that changes positions between successive images also supports being sent a sequence of instructions that it can execute at once
The events to be sequenced over were all submitted to
acq.acquire()
in a single call.
If an acquisition hook is being used and hardware sequencing is engaged, the event
that gets passed to the hook will not being a single python dict
, but instead a list
of dict
objects representing a sequence of events. It will also only be called once, for the whole sequence, instead of once for each event.
If desired, hardware sequencing can be turned off by submitting events for acquisition one at a time. For a list of acquisition events called events
:
with Acquisition(directory='/path/to/saving/dir', name='acquisition_name') as acq:
# Create a list of events
events = multi_d_acquisition_events(num_time_points=10)
# but submit them one at a time so sequencing doesn't occur
for event in events:
acq.acquire(event)
Customizing Acquisitions
While executing the Acquisition
code, several operations are taking place concurrently: events are being interpreted and queued for execution, hardware is being controlled and monitored, and images are being retrieved and saved. To ensure efficient execution, these operations are performed in parallel wherever feasible.
To tailor an Acquisition
to your needs, you may need to interact with specific parts of this process. For this, Pycro-manager provides dedicated APIs, each designed to enable customization for a specific piece of the acquisition process:
Creating Custom Acquisition Events tells the
Acquisition
what to acquire and how to acquire it.Acquisition hooks allow alterations to the standard progression of hardware control through injecting custom user code.
Image processors allow modification/processing of image data prior to saving/displaying, or for images to be rerouted to custom endpoints instead of being saved to disk.
The figure below shows an overview of what happens behind the scenes during an acquisition and where the each API fits. Each color represents a distinct thread that is operating asynchronously from the others.