From b7b9b21b96f76fabfbaa432a4d7b0ea5321a8de1 Mon Sep 17 00:00:00 2001 From: Henry Pinkard <7969470+henrypinkard@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:17:35 -0400 Subject: [PATCH] fix terminology to fix tests --- src/exengine/events/detector_events.py | 37 +++++++++++-------- src/exengine/events/multi_d_events.py | 8 ++-- .../test/test_multi_d_events_function.py | 16 ++++---- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/exengine/events/detector_events.py b/src/exengine/events/detector_events.py index 9e47cc4..04e4a2e 100644 --- a/src/exengine/events/detector_events.py +++ b/src/exengine/events/detector_events.py @@ -17,7 +17,7 @@ class DataAcquired(Notification[DataCoordinates]): class ReadoutData(Stoppable, DataProducing, ExecutorEvent): """ - Readout one or more pieces of data (e.g. images) and associated metadata from a Detector device (e.g. a camera) + Readout one or more blocks of data (e.g. images) and associated metadata from a Detector device (e.g. a camera) Args: data_coordinate_iterator (Iterable[DataCoordinates]): An iterator or list of DataCoordinates objects, which @@ -25,10 +25,10 @@ class ReadoutData(Stoppable, DataProducing, ExecutorEvent): elements (or indefinitely if num_images is None) detector (Union[Detector, str]): The Detector object to read data from. Can be the object itself, or the name of the object in the ExecutionEngine's device registry. - number (int): The number of pieces of data (e.g. images) to read out. If None, the readout will continue until - the data_coordinate_iterator is exhausted or the camera is stopped and no more images are available. - stop_on_empty (bool): If True, the readout will stop when the detector is stopped when there is not an - image available to read + num_blocks (int): The number of pieces of data (e.g. images) to read out. If None, the readout will continue until + the data_coordinate_iterator is exhausted or the Detector is stopped and no more images are available. + stop_on_empty (bool): If True, the readout will stop when the detector is stopped when there is no data + available to read data_handler (DataHandler): The DataHandler object that will handle the data read out by this event """ notification_types = [DataAcquired] @@ -37,11 +37,11 @@ def __init__(self, data_coordinates_iterator: Union[DataCoordinatesIterator, Iterable[DataCoordinates], Iterable[Dict[str, Union[int, str]]]], detector: Optional[Union[Detector, str]] = None, data_handler: DataHandler = None, - number: int = None, + num_blocks: int = None, stop_on_empty: bool = False): super().__init__(data_coordinates_iterator=data_coordinates_iterator, data_handler=data_handler) self.detector = detector # TODO: why does IDE not like this type hint? - self.number = number + self.num_blocks = num_blocks self.stop_on_empty = stop_on_empty @@ -51,7 +51,7 @@ def execute(self) -> None: else ExecutionEngine.get_device(self.detector)) # TODO a more efficient way to do this is with callbacks from the camera # but this is not currently implemented, at least for Micro-Manager cameras - image_counter = itertools.count() if self.number is None else range(self.number) + image_counter = itertools.count() if self.num_blocks is None else range(self.num_blocks) for image_number, image_coordinates in zip(image_counter, self.data_coordinate_iterator): while True: # check if event.stop has been called @@ -69,20 +69,27 @@ def execute(self) -> None: class StartCapture(ExecutorEvent): """ - Special device instruction that captures images from a camera + Special device instruction that captures images from a Detector device (e.g. a camera) """ - def __init__(self, num_images: int, detector: Optional[Detector] = None): + def __init__(self, num_blocks: int, detector: Optional[Detector] = None): + """ + Args: + num_blocks (int): The of pieces of data to capture (i.e. images on a camera) + detector (Union[Detector, str]): The Detector object to capture images from. Can be the object itself, + or the name of the object in the ExecutionEngine's device registry. If None, it will be inferred at + runtime + """ super().__init__() - self.num_images = num_images + self.num_blocks = num_blocks self.detector = detector def execute(self): """ - Capture images from the camera + Capture images from the detector """ try: - self.detector.arm(self.num_images) + self.detector.arm(self.num_blocks) self.detector.start() except Exception as e: self.detector.stop() @@ -90,7 +97,7 @@ def execute(self): class StartContinuousCapture(ExecutorEvent): """ - Tell data-producing device to start capturing images continuously, until a stop signal is received + Tell Detector device to start capturing images continuously, until a stop signal is received """ def __init__(self, camera: Optional[Detector] = None): @@ -110,7 +117,7 @@ def execute(self): class StopCapture(ExecutorEvent): """ - Tell data-producing device to start capturing images continuously, until a stop signal is received + Tell Detector device to start capturing data continuously, until a stop signal is received """ def __init__(self, camera: Optional[Detector] = None): diff --git a/src/exengine/events/multi_d_events.py b/src/exengine/events/multi_d_events.py index 17fbbcb..e4a45fb 100644 --- a/src/exengine/events/multi_d_events.py +++ b/src/exengine/events/multi_d_events.py @@ -149,7 +149,7 @@ def generate_events(event_list, order, coords=None): # )) # Add StartCapture event - new_event_list.append(StartCapture(detector=camera, num_images=total_sequence_length)) + new_event_list.append(StartCapture(detector=camera, num_blocks=total_sequence_length)) # Create data coordinates for ReadoutImages axes_names = {"t": "time", "z": "z", "c": "channel", "p": "position"} @@ -165,7 +165,7 @@ def generate_events(event_list, order, coords=None): new_event_list.append(ReadoutData( detector=camera, - number=total_sequence_length, + num_blocks=total_sequence_length, data_coordinates_iterator=coords_iterator )) @@ -219,8 +219,8 @@ def generate_events(event_list, order, coords=None): if sequence is None: # Non-sequenced case: Add StartCapture and ReadoutImages events num_images = 1 - event_set.append(StartCapture(detector=camera, num_images=num_images)) - event_set.append(ReadoutData(detector=camera, number=num_images, + event_set.append(StartCapture(detector=camera, num_blocks=num_images)) + event_set.append(ReadoutData(detector=camera, num_blocks=num_images, data_coordinates_iterator=[DataCoordinates(**coords)])) final_events.append(event_set) diff --git a/src/exengine/events/test/test_multi_d_events_function.py b/src/exengine/events/test/test_multi_d_events_function.py index 8ee8cd7..c16897b 100644 --- a/src/exengine/events/test/test_multi_d_events_function.py +++ b/src/exengine/events/test/test_multi_d_events_function.py @@ -32,7 +32,7 @@ def test_sequenced_z_stack(): assert isinstance(events[0], SetTriggerable1DPositionsEvent) assert isinstance(events[1], StartCapture) assert isinstance(events[2], ReadoutData) - assert events[1].number == 6 # 6 z-positions + assert events[1].num_blocks == 6 # 6 z-positions def test_sequenced_timelapse(): @@ -58,11 +58,11 @@ def test_sequenced_timelapse(): # Check the SetTriggerablePropertySequencesEvent # Check the StartCapture event - assert events[0].number == num_time_points + assert events[0].num_blocks == num_time_points # Check the ReadoutImages event readout_event = events[1] - assert readout_event.number == num_time_points + assert readout_event.num_blocks == num_time_points # Check the data coordinate iterator coords = list(readout_event.data_coordinate_iterator) @@ -95,7 +95,7 @@ def test_sequenced_channels(): assert isinstance(events[0], SetTriggerablePropertySequencesEvent) assert isinstance(events[1], StartCapture) assert isinstance(events[2], ReadoutData) - assert events[1].number == 3 # 3 channels + assert events[1].num_blocks == 3 # 3 channels # TODO: implement channels in multi d @@ -148,7 +148,7 @@ def test_sequenced_channels_and_z_stack_zc_order(): assert isinstance(events[3], ReadoutData) # Check if the number of images is correct (6 z-positions * 2 channels) - assert events[2].number == 12 + assert events[2].num_blocks == 12 # Check if the number of z-positions is correct assert len(events[0].positions) == 12 @@ -190,7 +190,7 @@ def test_sequenced_channels_and_z_stack_cz_order(): assert isinstance(events[1], SetTriggerable1DPositionsEvent) or isinstance(events[0], SetTriggerable1DPositionsEvent) assert isinstance(events[2], StartCapture) assert isinstance(events[3], ReadoutData) - assert events[2].number == 12 + assert events[2].num_blocks == 12 expected_channel_sequence = ['DAPI'] * 6 + ['FITC'] * 6 assert events[1].property_sequences[0][2] == expected_channel_sequence @@ -220,7 +220,7 @@ def test_sequenced_time_channels_and_z_stack_tzc_order(): assert isinstance(events[0], SetTriggerablePropertySequencesEvent) or isinstance(events[0], SetTriggerable1DPositionsEvent) assert isinstance(events[1], SetTriggerable1DPositionsEvent) or isinstance(events[1], SetTriggerablePropertySequencesEvent) assert isinstance(events[2], StartCapture) - assert events[2].number == 24 # 3 time points * 4 z-positions * 2 channels + assert events[2].num_blocks == 24 # 3 time points * 4 z-positions * 2 channels expected_z_sequence = np.array([0, 0, 2, 2, 4, 4, 6, 6, 0, 0, 2, 2, 4, 4, 6, 6, 0, 0, 2, 2, 4, 4, 6, 6]) @@ -257,7 +257,7 @@ def test_sequenced_channels_and_positions(): assert isinstance(events[0], SetTriggerablePropertySequencesEvent) # Channel assert isinstance(events[1], StartCapture) assert isinstance(events[2], ReadoutData) - assert events[1].number == 6 # 2 channels * 3 positions + assert events[1].num_blocks == 6 # 2 channels * 3 positions expected_channel_sequence = ['DAPI', 'FITC'] * 3 # Repeats for each position assert events[0].property_sequences[0][2] == expected_channel_sequence