Skip to content

Commit e4aa953

Browse files
committed
automatic immersion_depth_direction
1 parent cbfbb08 commit e4aa953

File tree

2 files changed

+66
-7
lines changed

2 files changed

+66
-7
lines changed

docs/user_guide/00_liquid-handling/hamilton-star/star_lld.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,30 @@ The `lld_mode` parameter is a list, so you can specify a different LLD mode for
2222
The `lld_mode` parameter is only available when using the `STAR` backend.
2323
```
2424

25+
## Going into or out of the liquid
26+
27+
You can use the `immersion_depth` backend kwarg to move the tip with respect to the found liquid surface. A positive value means to go deeper into the liquid, a negative value means to go above the liquid.
28+
29+
Going 1mm below the liquid for aspiration:
30+
31+
```python
32+
await lh.aspirate(
33+
[tube],
34+
vols=[300],
35+
lld_mode=[STARBackend.LLDMode.GAMMA],
36+
immersion_depth=[1])
37+
```
38+
39+
Going 1mm above the liquid for dispens:
40+
41+
```python
42+
await lh.dispense(
43+
[tube],
44+
vols=[300],
45+
lld_mode=[STARBackend.LLDMode.GAMMA],
46+
immersion_depth=[-1])
47+
```
48+
2549
## Catching errors
2650

2751
All channelized pipetting operations raise a `ChannelizedError` exception when an error occurs, so that we can have specific error handling for each channel.

pylabrobot/liquid_handling/backends/hamilton/STAR_backend.py

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,14 @@ async def aspirate(
17181718
"https://docs.pylabrobot.org/user_guide/00_liquid-handling/mixing.html"
17191719
)
17201720

1721+
if immersion_depth_direction is not None:
1722+
warnings.warn(
1723+
"The immersion_depth_direction parameter is deprecated and will be removed in the future. "
1724+
"Use positive values for immersion_depth to move into the liquid, and negative values to move "
1725+
"out of the liquid.",
1726+
DeprecationWarning,
1727+
)
1728+
17211729
x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels)
17221730

17231731
n = len(ops)
@@ -1782,9 +1790,10 @@ async def aspirate(
17821790
second_section_height = _fill_in_defaults(second_section_height, [3.2] * n)
17831791
second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n)
17841792
minimum_height = _fill_in_defaults(minimum_height, well_bottoms)
1785-
# TODO: I think minimum height should be the minimum height of the well
17861793
immersion_depth = _fill_in_defaults(immersion_depth, [0.0] * n)
1787-
immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n)
1794+
immersion_depth_direction = immersion_depth_direction or [
1795+
0 if (id_ >= 0) else 1 for id_ in immersion_depth
1796+
]
17881797
surface_following_distance = _fill_in_defaults(surface_following_distance, [0.0] * n)
17891798
flow_rates = [
17901799
op.flow_rate or (hlc.aspiration_flow_rate if hlc is not None else 100.0)
@@ -2014,6 +2023,14 @@ async def dispense(
20142023
"https://docs.pylabrobot.org/user_guide/00_liquid-handling/mixing.html"
20152024
)
20162025

2026+
if immersion_depth_direction is not None:
2027+
warnings.warn(
2028+
"The immersion_depth_direction parameter is deprecated and will be removed in the future. "
2029+
"Use positive values for immersion_depth to move into the liquid, and negative values to move "
2030+
"out of the liquid.",
2031+
DeprecationWarning,
2032+
)
2033+
20172034
x_positions, y_positions, channels_involved = self._ops_to_fw_positions(ops, use_channels)
20182035

20192036
n = len(ops)
@@ -2078,7 +2095,9 @@ async def dispense(
20782095
second_section_ratio = _fill_in_defaults(second_section_ratio, [618.0] * n)
20792096
minimum_height = _fill_in_defaults(minimum_height, well_bottoms)
20802097
immersion_depth = _fill_in_defaults(immersion_depth, [0.0] * n)
2081-
immersion_depth_direction = _fill_in_defaults(immersion_depth_direction, [0] * n)
2098+
immersion_depth_direction = immersion_depth_direction or [
2099+
0 if (id_ >= 0) else 1 for id_ in immersion_depth
2100+
]
20822101
surface_following_distance = _fill_in_defaults(surface_following_distance, [0.0] * n)
20832102
flow_rates = [
20842103
op.flow_rate or (hlc.dispense_flow_rate if hlc is not None else 120.0)
@@ -2272,7 +2291,7 @@ async def aspirate96(
22722291
tube_2nd_section_height_measured_from_zm: float = 3.2,
22732292
tube_2nd_section_ratio: float = 618.0,
22742293
immersion_depth: float = 0,
2275-
immersion_depth_direction: int = 0,
2294+
immersion_depth_direction: Optional[int] = None,
22762295
liquid_surface_sink_distance_at_the_end_of_aspiration: float = 0,
22772296
transport_air_volume: float = 5.0,
22782297
pre_wetting_volume: float = 5.0,
@@ -2335,6 +2354,14 @@ async def aspirate96(
23352354
"https://docs.pylabrobot.org/user_guide/00_liquid-handling/mixing.html"
23362355
)
23372356

2357+
if immersion_depth_direction is not None:
2358+
warnings.warn(
2359+
"The immersion_depth_direction parameter is deprecated and will be removed in the future. "
2360+
"Use positive values for immersion_depth to move into the liquid, and negative values to move "
2361+
"out of the liquid.",
2362+
DeprecationWarning,
2363+
)
2364+
23382365
assert self.core96_head_installed, "96 head must be installed"
23392366

23402367
# get the first well and tip as representatives
@@ -2438,7 +2465,7 @@ async def aspirate96(
24382465
tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10),
24392466
tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10),
24402467
immersion_depth=round(immersion_depth * 10),
2441-
immersion_depth_direction=immersion_depth_direction,
2468+
immersion_depth_direction=immersion_depth_direction or (0 if (immersion_depth >= 0) else 1),
24422469
liquid_surface_sink_distance_at_the_end_of_aspiration=round(
24432470
liquid_surface_sink_distance_at_the_end_of_aspiration * 10
24442471
),
@@ -2479,7 +2506,7 @@ async def dispense96(
24792506
tube_2nd_section_height_measured_from_zm: float = 3.2,
24802507
tube_2nd_section_ratio: float = 618.0,
24812508
immersion_depth: float = 0,
2482-
immersion_depth_direction: int = 0,
2509+
immersion_depth_direction: Optional[int] = None,
24832510
liquid_surface_sink_distance_at_the_end_of_dispense: float = 0,
24842511
transport_air_volume: float = 5.0,
24852512
gamma_lld_sensitivity: int = 1,
@@ -2536,6 +2563,14 @@ async def dispense96(
25362563
"https://docs.pylabrobot.org/user_guide/00_liquid-handling/mixing.html"
25372564
)
25382565

2566+
if immersion_depth_direction is not None:
2567+
warnings.warn(
2568+
"The immersion_depth_direction parameter is deprecated and will be removed in the future. "
2569+
"Use positive values for immersion_depth to move into the liquid, and negative values to move "
2570+
"out of the liquid.",
2571+
DeprecationWarning,
2572+
)
2573+
25392574
assert self.core96_head_installed, "96 head must be installed"
25402575

25412576
# get the first well and tip as representatives
@@ -2628,7 +2663,7 @@ async def dispense96(
26282663
tube_2nd_section_height_measured_from_zm=round(tube_2nd_section_height_measured_from_zm * 10),
26292664
tube_2nd_section_ratio=round(tube_2nd_section_ratio * 10),
26302665
immersion_depth=round(immersion_depth * 10),
2631-
immersion_depth_direction=immersion_depth_direction,
2666+
immersion_depth_direction=immersion_depth_direction or (0 if (immersion_depth >= 0) else 1),
26322667
liquid_surface_sink_distance_at_the_end_of_dispense=round(
26332668
liquid_surface_sink_distance_at_the_end_of_dispense * 10
26342669
),

0 commit comments

Comments
 (0)