Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pylabrobot/hamilton/liquid_class_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
DISPENSE_CLASS_ATTRIBUTES: Dict[str, Callable[[HamiltonLiquidClass], float]] = {
"flow_rates": lambda hlc: hlc.dispense_flow_rate,
"transport_air_volumes": lambda hlc: hlc.dispense_air_transport_volume,
"cut_off_speeds": lambda hlc: hlc.dispense_stop_flow_rate,
"stop_back_volumes": lambda hlc: hlc.dispense_stop_back_volume,
"blow_out_air_volumes": lambda hlc: hlc.dispense_blow_out_volume,
"settling_times": lambda hlc: hlc.dispense_settling_time,
Expand Down
3 changes: 2 additions & 1 deletion pylabrobot/hamilton/star/driver/features/head96.py
Original file line number Diff line number Diff line change
Expand Up @@ -2730,7 +2730,7 @@ async def dispense(
bottom when None.
transport_air_volume: air pushed out before the liquid, in uL. The class's, else 0.0, when
None.
cut_off_speed: the flow the dispense ends at, in uL/s. 5.0 when None.
cut_off_speed: the flow the dispense ends at, in uL/s. The class's, else 5.0, when None.
stop_back_volume: drawn back after the dispense, in uL. The class's, else 0.0, when None.
surface_following_distance: how far the tips follow the rising surface, in mm.
auto_surface_following: follow by how far the dispensed liquid raises the surface found, or
Expand Down Expand Up @@ -2800,6 +2800,7 @@ def by_class(name: str, given: Optional[float]) -> Optional[float]:

flow_rate = by_class("flow_rates", flow_rate)
transport_air = by_class("transport_air_volumes", transport_air_volume) or 0.0
cut_off_speed = by_class("cut_off_speeds", cut_off_speed)
stop_back = by_class("stop_back_volumes", stop_back_volume) or 0.0
blow_out_air = by_class("blow_out_air_volumes", blow_out_air_volume) or 0.0
settling_time = by_class("settling_times", settling_time)
Expand Down
12 changes: 12 additions & 0 deletions pylabrobot/hamilton/star/driver/features/head_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,18 @@ async def test_capacitive_dispense_into_a_plate_books_each_well(self):
others = {w.tracker.get_used_volume() for w in self.plate.get_all_items()[1:]}
self.assertEqual(others, {200.0})

async def test_the_cut_off_speed_is_the_class_s_unless_given(self):
from pylabrobot.hamilton.star.liquid_classes import get_star_liquid_class
from pylabrobot.resources.liquid import Liquid

jet = get_star_liquid_class(300.0, True, True, True, Liquid.WATER, True, True)
assert jet is not None and jet.dispense_stop_flow_rate != 5.0
await self.head.aspirate(self.plate, piston_volume=150.0)
await self.head.dispense(self.plate, 30.0, jet=True, blow_out=True)
self.assertEqual(self.sent[1][1]["cut_off_speed"], round(jet.dispense_stop_flow_rate * 10))
await self.head.dispense(self.plate, 30.0, jet=True, blow_out=True, cut_off_speed=4.5)
self.assertEqual(self.sent[2][1]["cut_off_speed"], 45)

async def test_no_liquid_under_capacitive_raises_and_the_head_goes_up(self):
with self.assertRaises(RuntimeError):
await self.head.aspirate(self.trough, piston_volume=20.0, lld_mode=LLDMode.CAPACITIVE)
Expand Down
4 changes: 2 additions & 2 deletions pylabrobot/hamilton/star/driver/features/pipettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6897,7 +6897,7 @@ async def dispense(
cavity bottom plus the offset's z when None.
transport_air_volumes: air drawn after each dispense, in uL, pushed out ahead of the next.
The class's, else 0.0, when None.
cut_off_speeds: the flow each dispense ends at, in uL/s. 5.0 when None.
cut_off_speeds: the flow each dispense ends at, in uL/s. The class's, else 5.0, when None.
stop_back_volumes: drawn back after each dispense, in uL. The class's, else 0.0, when None.
surface_following_distances: how far each tip follows the rising surface, in mm. 0.0 when
None.
Expand Down Expand Up @@ -7004,7 +7004,7 @@ def by_class(name: str, given: Optional[Sequence[Any]]) -> Optional[List[Any]]:
per_container_settings = {
"flow_rates": by_class("flow_rates", flow_rates),
"transport_air_volumes": by_class("transport_air_volumes", transport_air_volumes),
"cut_off_speeds": per_container("cut_off_speeds", cut_off_speeds, n),
"cut_off_speeds": by_class("cut_off_speeds", cut_off_speeds),
"stop_back_volumes": by_class("stop_back_volumes", stop_back_volumes),
"blow_out_air_volumes": by_class("blow_out_air_volumes", blow_out_air_volumes),
"immersion_depths": per_container("immersion_depths", immersion_depths, n),
Expand Down
19 changes: 19 additions & 0 deletions pylabrobot/hamilton/star/driver/features/pipettes_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1746,6 +1746,25 @@ async def test_300_and_1000_uL_tips_draw_and_dispense_by_their_class(self):
):
self.assertEqual(self._field(sent[2], name), [round(value * 10)] * 2, name)

async def test_the_cut_off_speed_is_the_class_s_unless_given(self):
from pylabrobot.hamilton.star.liquid_classes import get_star_liquid_class
from pylabrobot.resources.hamilton import hamilton_96_tiprack_1000uL
from pylabrobot.resources.liquid import Liquid

driver, plate, sent = await self._channels_carrying(hamilton_96_tiprack_1000uL)
pipettes = driver.pipettes
assert pipettes is not None
jet = get_star_liquid_class(1000.0, False, True, False, Liquid.WATER, True, True)
assert jet is not None and jet.dispense_stop_flow_rate != 5.0
wells = [plate.get_well("A1"), plate.get_well("B1")]
await pipettes.aspirate(wells, piston_volumes=[300.0, 300.0], liquid_heights=[3.0, 3.0])
await pipettes.dispense(wells, [50.0, 50.0], jet=[True, True], blow_out=[True, True])
self.assertEqual(self._field(sent[1], "ss"), [round(jet.dispense_stop_flow_rate * 10)] * 2)
await pipettes.dispense(
wells, [50.0, 50.0], jet=[True, True], blow_out=[True, True], cut_off_speeds=[4.5, 4.5]
)
self.assertEqual(self._field(sent[2], "ss"), [45, 45])

async def test_a_50_uL_tip_has_no_class_without_blow_out(self):
from pylabrobot.resources.hamilton import hamilton_96_tiprack_50uL

Expand Down
Loading