diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR.py b/pylabrobot/liquid_handling/backends/hamilton/STAR.py index 8bdcebbaff..db2b962bf8 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR.py @@ -7317,6 +7317,54 @@ async def clld_probe_z_height_using_channel( return result_in_mm + async def request_tip_len_on_channel( + self, + channel_idx: int, # 0-based indexing of channels! + ) -> float: + """ + Measures the length of the tip attached to the specified pipetting channel. + Checks if a tip is present on the given channel. If present, moves all channels + to THE safe Z position, 334.3 mm, measures the tip bottom Z-coordinate, and calculates + the total tip length. Supports tips of lengths 50.4 mm, 59.9 mm, and 95.1 mm. + Raises an error if the tip length is unsupported or if no tip is present. + Parameters: + channel_idx: Index of the pipetting channel (0-based). + Returns: + The measured tip length in millimeters. + Raises: + ValueError: If no tip is present on the channel or if the tip length is unsupported. + """ + + # Check there is a tip on the channel + all_channel_occupancy = await self.request_tip_presence() + if not all_channel_occupancy[channel_idx]: + raise ValueError(f"No tip present on channel {channel_idx}") + + # Level all channels + await self.move_all_channels_in_z_safety() + known_top_position_channel_head = 334.3 # mm + fitting_depth_of_all_standard_channel_tips = 8 # mm + unknown_offset_for_all_tips = 0.4 # mm + + # Request z-coordinate of channel+tip bottom + tip_bottom_z_coordinate = await self.request_z_pos_channel_n( + pipetting_channel_index=channel_idx + ) + + total_tip_len = round( + known_top_position_channel_head + - ( + tip_bottom_z_coordinate + - fitting_depth_of_all_standard_channel_tips + - unknown_offset_for_all_tips + ), + 1, + ) + + if total_tip_len in [50.4, 59.9, 95.1]: # 50ul, 300ul, 1000ul + return total_tip_len + raise ValueError(f"Tip of length {total_tip_len} not yet supported") + async def ztouch_probe_z_height_using_channel( self, channel_idx: int, # 0-based indexing of channels!