Adaptive Acquisitions
Pycro-Manager’s Acquisition class allows the acquisition process to be modified based on acquired data. This enables dynamic, responsive experiments, also known as “smart microscopy”.
This API is designed to provide both performance and easily understandable code. Parallelization is essential for many smart microscopy experiments, which require simultaneous hardware control, image acquisition, and data processing. However, the logic of an experiment is more easily understood as a sequence of decisions and actions. The API bridges this gap, enabling that looks like a single sequential script but takes advantage of parallelizing operations when possible.
Unlike simple acquisitions where all events are sent in a single Acquisition.submit(...) call, adaptive acquisitions require multiple submit calls. Events are submitted, they produce images, those images are analyzed, and based on this analysis, new events are created.
The key object in adaptive microscopy is the AcquisitionFuture. Any time an event or events are submitted, an AcquisitionFuture is returned. The AcquisitionFuture can be used to access specific data as soon as it is ready.
This example shows an experiment which alternates between fast and slow time-lapses based on image analysis:
Example: Alternating Time-lapses
from pycromanager import Acquisition, multi_d_acquisition_events
def analyze_image(image):
# Placeholder for image analysis
return image.max() > threshold
with Acquisition(directory='/path/to/save', name='adaptive_acq') as acq:
for loop_index in range(10): # Run 10 adaptive cycles
# Acquire a single image
event = {'axes': {'loop_index': loop_index}}
future = acq.submit(event)
# Wait for the image and analyze it
image = future.await_image_saved(event['axes'])
if analyze_image(image):
# Fast time-lapse: 100 images, 1 second apart
events = multi_d_acquisition_events(num_time_points=100, time_interval_s=1)
else:
# Slow time-lapse: 5 images, 20 seconds apart
events = multi_d_acquisition_events(num_time_points=5, time_interval_s=20)
# Add the loop index to the events so that successive timelapses have unique axes
for event in events:
event['axes']['loop_index'] = loop_index
acq.submit(events)
Additional Features
Awaiting Multiple Images
The
AcquisitionFuturecan wait for multiple images simultaneously, only returning when all images are saved:future = acq.submit(events) images = future.await_image_saved([{'time': 2}, {'time': 3}, {'time': 4}])
This is useful when analysis requires multiple images, such as 3D image processing on a Z-stack.
Awaiting Specific Execution Milestones
Specific execution milestones can be awaited:
from pycromanager import AcqNotification future = acq.submit(events) future.await_execution(milestone=AcqNotification.Hardware.POST_HARDWARE, axes={'time': 1})
For further information, see the Adaptive acquisition API