diff --git a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py index dda8ffe98a..20e5196357 100644 --- a/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py +++ b/pylabrobot/liquid_handling/backends/hamilton/STAR_tests.py @@ -6,7 +6,8 @@ from pylabrobot.liquid_handling.standard import Pickup, GripDirection from pylabrobot.liquid_handling.liquid_classes.hamilton.star import ( StandardVolumeFilter_Water_DispenseSurface, - StandardVolumeFilter_Water_DispenseJet_Empty) + StandardVolumeFilter_Water_DispenseJet_Empty, + HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty) from pylabrobot.liquid_handling.parameter_sets.star import STARParameterSet from pylabrobot.plate_reading import PlateReader from pylabrobot.plate_reading.plate_reader_tests import MockPlateReaderBackend @@ -491,7 +492,6 @@ async def test_dispense_single_resource(self): hlc = StandardVolumeFilter_Water_DispenseJet_Empty ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=5, jet=[True]*5, blow_out=[True]*5) - print(ps.make_disp_kwargs()) corrected_vol = hlc.compute_corrected_volume(10) with no_volume_tracking(): await self.lh.dispense([self.bb]*5, vols=[corrected_vol]*5, liquid_height=[1]*5, @@ -513,10 +513,12 @@ async def test_single_channel_dispense(self): self.lh.update_head_state({0: self.tip_rack.get_tip("A1")}) assert self.plate.lid is not None self.plate.lid.unassign() + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=1, + jet=[True]*1, blow_out=[True]*1) + corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], - jet=[True], blow_out=[True]) + await self.lh.dispense(self.plate["A1"], vols=[corrected_vol], **ps.make_disp_kwargs()) self._assert_command_sent_once( "C0DSid0002dm1 1&tm1 0&xp02983 00000&yp1457 0000&zx1866 1866&lp2000 2000&zl1866 1866&" "po0100 0100&ip0000 0000&it0 0&fp0000 0000&zu0032 0032&zr06180 06180&th2450te2450" @@ -530,9 +532,12 @@ async def test_multi_channel_dispense(self): # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() + hlc = StandardVolumeFilter_Water_DispenseJet_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc, num_channels=2, + jet=[True]*2, blow_out=[True]*2) + corrected_vol = hlc.compute_corrected_volume(100) with no_volume_tracking(): - corrected_vol = self.hlc.compute_corrected_volume(100) - await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, jet=[True]*2, blow_out=[True]*2) + await self.lh.dispense(self.plate["A1:B1"], vols=[corrected_vol]*2, **ps.make_disp_kwargs()) self._assert_command_sent_once( "C0DSid0002dm1 1 1&tm1 1 0&xp02983 02983 00000&yp1457 1367 0000&zx1866 1866 1866&lp2000 2000 " @@ -580,8 +585,10 @@ async def test_core_96_aspirate(self): # TODO: Hamilton liquid classes assert self.plate.lid is not None self.plate.lid.unassign() - corrected_volume = self.hlc.compute_corrected_volume(100) # need different liquid class - await self.lh.aspirate96(self.plate, volume=corrected_volume) + hlc = HighVolumeFilter_96COREHead1000ul_Water_DispenseSurface_Empty + ps = STARParameterSet.from_hamilton_liquid_class(hlc) + corrected_volume = hlc.compute_corrected_volume(100) # need different liquid class + await self.lh.aspirate96(self.plate, volume=corrected_volume, **ps.make_asp96_kwargs()) # volume used to be 01072, but that was generated using a non-core liquid class. self._assert_command_sent_once( diff --git a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py index 967d3ab8cc..c35e423258 100644 --- a/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py +++ b/pylabrobot/liquid_handling/liquid_classes/hamilton/base.py @@ -114,3 +114,25 @@ def serialize(self) -> Dict[str, Any]: def copy(self) -> "HamiltonLiquidClass": return HamiltonLiquidClass(**self.serialize()) + + def create_asp_kwargs(self, num_channels: int): + return { + "flow_rates": [self.aspiration_flow_rate] * num_channels, + "mix_speed": [self.aspiration_mix_flow_rate] * num_channels, + "transport_air_volume": [self.aspiration_air_transport_volume] * num_channels, + "blow_out_air_volume": [self.aspiration_blow_out_volume] * num_channels, + "swap_speed": [self.aspiration_swap_speed] * num_channels, + "settling_time": [self.aspiration_settling_time] * num_channels, + "clot_detection_height": [self.aspiration_clot_retract_height] * num_channels, + } + + def create_disp_kwargs(self, num_channels: int): + return { + "flow_rates": [self.dispense_flow_rate] * num_channels, + "mix_speed": [self.dispense_mix_flow_rate] * num_channels, + "transport_air_volume": [self.dispense_air_transport_volume] * num_channels, + "blow_out_air_volume": [self.dispense_blow_out_volume] * num_channels, + "swap_speed": [self.dispense_swap_speed] * num_channels, + "settling_time": [self.dispense_settling_time] * num_channels, + "stop_back_volume": [self.dispense_stop_back_volume] * num_channels, + } diff --git a/pylabrobot/liquid_handling/parameter_sets/star.py b/pylabrobot/liquid_handling/parameter_sets/star.py index d32e4da7ab..618e069fe6 100644 --- a/pylabrobot/liquid_handling/parameter_sets/star.py +++ b/pylabrobot/liquid_handling/parameter_sets/star.py @@ -38,7 +38,7 @@ class STARParameterSet(ParameterSet): dispense_stop_back_volumes: Optional[list[float]] dispense_lld_modes: Optional[list[STAR.LLDMode]] - def make_asp_kwargs(self) -> dict[str, float]: + def make_asp_kwargs(self) -> dict[str, list[float]]: return { "jet": self.aspiration_jet, "blow_out": self.aspiration_blow_out, @@ -52,7 +52,7 @@ def make_asp_kwargs(self) -> dict[str, float]: "lld_mode": self.aspiration_lld_modes, } - def make_disp_kwargs(self) -> dict[str, float]: + def make_disp_kwargs(self) -> dict[str, list[float]]: return { "jet": self.dispense_jet, "blow_out": self.dispense_blow_out, @@ -106,7 +106,7 @@ def from_hamilton_liquid_class( dispense_blow_out=[blow_out] * num_channels, dispense_jet=[jet] * num_channels, dispense_flow_rates=[hlc.dispense_flow_rate] * num_channels, - dispense_mix_speeds=[hlc.dispense_mode] * num_channels, + dispense_mix_speeds=[hlc.dispense_mix_flow_rate] * num_channels, dispense_swap_speeds=[hlc.dispense_swap_speed] * num_channels, dispense_settling_times=[hlc.dispense_settling_time] * num_channels, dispense_stop_back_volumes=[hlc.dispense_stop_back_volume] * num_channels,