Hi all, I’m back with an update on this question. If you’d rather I move it to a new thread, let me know.
In short, this worked quite well for using the span-8, but I wanted to try to do essentially the same thing with the CO-RE 96 head. I made some corresponding modifications to the commands, and am testing now. However, I get the timeout error pasted below.
One detail that might be relevant: You’ll notice the timeout error occurs on the third plate (of four). Before I noticed that the mixing speed arg for the aspirate_plate command (speed_of_homogenization
) is different than for aspirate (homogenization_speed
), I had kept the span-8 verbiage. In that case, the timeout error occurred on the first of the four plates, rather than the third. Notably the default mixing speed in that case was used, which is much slower than the requested 400 uL/s. In both cases, it occurs at the same point, which is just after finishing the “error” plate and before proceeding to the next plate.
Function definition and error trace
async def mix_plates(vol):
await lh.dispense_plate(lh.get_resource('plate1'), volume=vol)
await lh.aspirate_plate(lh.get_resource('plate1'), volume=0,
homogenization_volume = 8000, homogenization_cycles = 4,
speed_of_homogenization = 4000)
await lh.aspirate_plate(lh.get_resource('plate2'), volume=0,
homogenization_volume = 8000, homogenization_cycles = 4,
speed_of_homogenization = 4000)
await lh.aspirate_plate(lh.get_resource('plate3'), volume=0,
homogenization_volume = 8000, homogenization_cycles = 4,
speed_of_homogenization = 4000)
await lh.aspirate_plate(lh.get_resource('plate4'), volume=0,
homogenization_volume = 8000, homogenization_cycles = 4,
speed_of_homogenization = 4000)
await lh.drop_tips96(lh.get_resource('tips_01'))
Error trace
---------------------------------------------------------------------------
TimeoutError Traceback (most recent call last)
Cell In[45], line 2
1 ## Run it
----> 2 await cycles(num_cycles)
Cell In[42], line 18, in cycles(cycles)
17 vol = 0
---> 18 await mix_plates(vol)
Cell In[40], line 46, in mix_plates(vol)
40 await lh.aspirate_plate(lh.get_resource('plate1'), volume=0,
41 homogenization_volume = 8000, homogenization_cycles = 4,
42 speed_of_homogenization = 4000)
43 await lh.aspirate_plate(lh.get_resource('plate2'), volume=0,
44 homogenization_volume = 8000, homogenization_cycles = 4,
45 speed_of_homogenization = 4000)
---> 46 await lh.aspirate_plate(lh.get_resource('plate3'), volume=0,
47 homogenization_volume = 8000, homogenization_cycles = 4,
48 speed_of_homogenization = 4000)
49 await lh.aspirate_plate(lh.get_resource('plate4'), volume=0,
50 homogenization_volume = 8000, homogenization_cycles = 4,
51 speed_of_homogenization = 4000)
52 await lh.drop_tips96(lh.get_resource('tips_01'))
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py:1154, in LiquidHandler.aspirate_plate(self, plate, volume, flow_rate, end_delay, **backend_kwargs)
1143 if plate.num_items_x == 12 and plate.num_items_y == 8:
1144 aspiration_plate = AspirationPlate(
1145 resource=plate,
1146 volume=volume,
(...)
1152 liquids=liquids,
1153 )
-> 1154 await self.backend.aspirate96(aspiration=aspiration_plate, **backend_kwargs)
1155 self._trigger_callback(
1156 "aspirate_plate",
1157 liquid_handler=self,
(...)
1160 **backend_kwargs,
1161 )
1162 else:
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py:61, in need_iswap_parked.<locals>.wrapper(self, *args, **kwargs)
58 if self.iswap_installed and not self.iswap_parked:
59 await self.park_iswap()
---> 61 result = await method(self, *args, **kwargs) # pylint: disable=not-callable
63 return result
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py:2058, in STAR.aspirate96(self, aspiration, blow_out_air_volume, use_lld, liquid_height, air_transport_retract_dist, aspiration_type, minimum_traverse_height_at_beginning_of_a_command, minimal_end_height, lld_search_height, maximum_immersion_depth, tube_2nd_section_height_measured_from_zm, tube_2nd_section_ratio, immersion_depth, immersion_depth_direction, liquid_surface_sink_distance_at_the_end_of_aspiration, transport_air_volume, pre_wetting_volume, gamma_lld_sensitivity, swap_speed, settling_time, homogenization_volume, homogenization_cycles, homogenization_position_from_liquid_surface, surface_following_distance_during_homogenization, speed_of_homogenization, limit_curve_index)
2049 if blow_out_air_volume is not None and blow_out_air_volume > 0:
2050 await self.aspirate_core_96(
2051 x_position=int(position.x * 10),
2052 y_positions=int(position.y * 10),
(...)
2055 aspiration_volumes=int(blow_out_air_volume * 10)
2056 )
-> 2058 return await self.aspirate_core_96(
2059 x_position=int(position.x * 10),
2060 x_direction=0,
2061 y_positions=int(position.y * 10),
2062 aspiration_type=aspiration_type,
2063
2064 minimum_traverse_height_at_beginning_of_a_command=
2065 minimum_traverse_height_at_beginning_of_a_command,
2066 minimal_end_height=minimal_end_height,
2067 lld_search_height=lld_search_height,
2068 liquid_surface_at_function_without_lld=liquid_surface_at_function_without_lld,
2069 pull_out_distance_to_take_transport_air_in_function_without_lld=
2070 pull_out_distance_to_take_transport_air_in_function_without_lld,
2071 maximum_immersion_depth=maximum_immersion_depth,
2072 tube_2nd_section_height_measured_from_zm=tube_2nd_section_height_measured_from_zm,
2073 tube_2nd_section_ratio=tube_2nd_section_ratio,
2074 immersion_depth=immersion_depth,
2075 immersion_depth_direction=immersion_depth_direction,
2076 liquid_surface_sink_distance_at_the_end_of_aspiration=
2077 liquid_surface_sink_distance_at_the_end_of_aspiration,
2078 aspiration_volumes=aspiration_volumes,
2079 aspiration_speed=flow_rate,
2080 transport_air_volume=transport_air_volume,
2081 blow_out_air_volume=0,
2082 pre_wetting_volume=pre_wetting_volume,
2083 lld_mode=int(use_lld),
2084 gamma_lld_sensitivity=gamma_lld_sensitivity,
2085 swap_speed=swap_speed,
2086 settling_time=settling_time,
2087 homogenization_volume=homogenization_volume,
2088 homogenization_cycles=homogenization_cycles,
2089 homogenization_position_from_liquid_surface=
2090 homogenization_position_from_liquid_surface,
2091 surface_following_distance_during_homogenization=
2092 surface_following_distance_during_homogenization,
2093 speed_of_homogenization=speed_of_homogenization,
2094 channel_pattern=channel_pattern,
2095 limit_curve_index=limit_curve_index,
2096 tadm_algorithm=False,
2097 recording_mode=0,
2098 )
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py:4895, in STAR.aspirate_core_96(self, aspiration_type, x_position, x_direction, y_positions, minimum_traverse_height_at_beginning_of_a_command, minimal_end_height, lld_search_height, liquid_surface_at_function_without_lld, pull_out_distance_to_take_transport_air_in_function_without_lld, maximum_immersion_depth, tube_2nd_section_height_measured_from_zm, tube_2nd_section_ratio, immersion_depth, immersion_depth_direction, liquid_surface_sink_distance_at_the_end_of_aspiration, aspiration_volumes, aspiration_speed, transport_air_volume, blow_out_air_volume, pre_wetting_volume, lld_mode, gamma_lld_sensitivity, swap_speed, settling_time, homogenization_volume, homogenization_cycles, homogenization_position_from_liquid_surface, surface_following_distance_during_homogenization, speed_of_homogenization, channel_pattern, limit_curve_index, tadm_algorithm, recording_mode)
4892 channel_pattern_bin_str = reversed(["1" if x else "0" for x in channel_pattern])
4893 channel_pattern_hex = hex(int("".join(channel_pattern_bin_str), 2)).upper()[2:]
-> 4895 return await self.send_command(
4896 module="C0",
4897 command="EA",
4898 aa=aspiration_type,
4899 xs=f"{x_position:05}",
4900 xd=x_direction,
4901 yh=f"{y_positions:04}",
4902 zh=f"{minimum_traverse_height_at_beginning_of_a_command:04}",
4903 ze=f"{minimal_end_height:04}",
4904 lz=f"{lld_search_height:04}",
4905 zt=f"{liquid_surface_at_function_without_lld:04}",
4906 pp=f"{pull_out_distance_to_take_transport_air_in_function_without_lld:04}",
4907 zm=f"{maximum_immersion_depth:04}",
4908 zv=f"{tube_2nd_section_height_measured_from_zm:04}",
4909 zq=f"{tube_2nd_section_ratio:05}",
4910 iw=f"{immersion_depth:03}",
4911 ix=immersion_depth_direction,
4912 fh=f"{liquid_surface_sink_distance_at_the_end_of_aspiration:03}",
4913 af=f"{aspiration_volumes:05}",
4914 ag=f"{aspiration_speed:04}",
4915 vt=f"{transport_air_volume:03}",
4916 bv=f"{blow_out_air_volume:05}",
4917 wv=f"{pre_wetting_volume:05}",
4918 cm=lld_mode,
4919 cs=gamma_lld_sensitivity,
4920 bs=f"{swap_speed:04}",
4921 wh=f"{settling_time:02}",
4922 hv=f"{homogenization_volume:05}",
4923 hc=f"{homogenization_cycles:02}",
4924 hp=f"{homogenization_position_from_liquid_surface:03}",
4925 mj=f"{surface_following_distance_during_homogenization:03}",
4926 hs=f"{speed_of_homogenization:04}",
4927 cw=channel_pattern_hex,
4928 cr=f"{limit_curve_index:03}",
4929 cj=tadm_algorithm,
4930 cx=recording_mode,
4931 )
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py:1172, in STAR.send_command(self, module, command, tip_pattern, write_timeout, read_timeout, wait, fmt, **kwargs)
1158 async def send_command(
1159 self,
1160 module: str,
(...)
1167 **kwargs
1168 ):
1169 """ Send a command to the machine. Parse the response if `fmt != ""`, else return the raw
1170 response. """
-> 1172 resp = await super().send_command(
1173 module=module,
1174 command=command,
1175 tip_pattern=tip_pattern,
1176 write_timeout=write_timeout,
1177 read_timeout=read_timeout,
1178 wait=wait,
1179 **kwargs
1180 )
1181 if fmt != "":
1182 parsed = parse_star_fw_string(resp, fmt)
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/base.py:191, in HamiltonLiquidHandler.send_command(self, module, command, tip_pattern, write_timeout, read_timeout, wait, **kwargs)
170 """ Send a firmware command to the Hamilton machine.
171
172 Args:
(...)
186 A dictionary containing the parsed response, or None if no response was read within `timeout`.
187 """
189 cmd, id_ = self._assemble_command(module=module, command=command, tip_pattern=tip_pattern,
190 **kwargs)
--> 191 return await self._write_and_read_command(id_=id_, cmd=cmd, write_timeout=write_timeout,
192 read_timeout=read_timeout, wait=wait)
File ~/Documents/Lab/PyLabRobot/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/base.py:215, in HamiltonLiquidHandler._write_and_read_command(self, id_, cmd, write_timeout, read_timeout, wait)
213 fut = loop.create_future()
214 self._start_reading(id_, loop, fut, cmd, read_timeout)
--> 215 result = await fut
216 return cast(dict, result)
TimeoutError: Timeout while waiting for response to command C0EAid0048aa0xs02530xd0yh3380zh2450ze2450lz1999zt1881pp0100zm1269zv0032zq06180iw000ix0fh000af00000ag2500vt050bv00000wv00050cm0cs1bs0020wh10hv08000hc04hp000mj000hs4000cwFFFFFFFFFFFFFFFFFFFFFFFFcr000cj0cx0.