Skip to content

Commit ab0e965

Browse files
authored
Add tip inventory probe function (#573)
1 parent 8312791 commit ab0e965

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

pylabrobot/liquid_handling/liquid_handler.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import warnings
1212
from typing import (
1313
Any,
14+
Awaitable,
1415
Callable,
1516
Dict,
1617
List,
@@ -82,6 +83,12 @@
8283
logger = logging.getLogger("pylabrobot")
8384

8485

86+
TipPresenceProbingMethod = Callable[
87+
[List[TipSpot], Optional[List[int]]],
88+
Awaitable[Dict[str, bool]],
89+
]
90+
91+
8592
def check_contaminated(liquid_history_tip, liquid_history_well):
8693
"""Helper function used to check if adding a liquid to the container
8794
would result in cross contamination"""
@@ -2411,3 +2418,49 @@ async def probe_tip_presence_via_pickup(
24112418
print(f"Warning: drop_tips failed for cluster at x={cluster[0][0].location.x}: {e}")
24122419

24132420
return {ts.name: flag for ts, flag in zip(tip_spots, presence_flags)}
2421+
2422+
async def probe_tip_inventory(
2423+
self,
2424+
tip_spots: List[TipSpot],
2425+
probing_fn: Optional[TipPresenceProbingMethod] = None,
2426+
use_channels: Optional[List[int]] = None,
2427+
) -> Dict[str, bool]:
2428+
"""Probe the presence of tips in multiple tip spots.
2429+
2430+
The provided ``probing_fn`` is used for probing batches of tip spots. The
2431+
default uses :meth:`probe_tip_presence_via_pickup`.
2432+
2433+
Examples:
2434+
Probe all tip spots in one or more tip racks.
2435+
2436+
>>> import pylabrobot.resources.functional as F
2437+
>>> spots = F.get_all_tip_spots([tip_rack_1, tip_rack_2])
2438+
>>> presence = await lh.probe_tip_inventory(spots)
2439+
2440+
Args:
2441+
tip_spots:
2442+
Tip spots to probe for presence of a tip.
2443+
probing_fn:
2444+
Function used to probe a batch of tip spots. Must accept ``tip_spots`` and
2445+
``use_channels`` and return a mapping of tip spot names to boolean flags.
2446+
2447+
Returns:
2448+
Mapping from tip spot names to whether a tip is present.
2449+
"""
2450+
2451+
if probing_fn is None:
2452+
probing_fn = self.probe_tip_presence_via_pickup
2453+
2454+
results: Dict[str, bool] = {}
2455+
2456+
num_channels = self.backend.num_channels
2457+
if use_channels is None:
2458+
use_channels = list(range(num_channels))
2459+
2460+
for i in range(0, len(tip_spots), num_channels):
2461+
subset = tip_spots[i : i + num_channels]
2462+
use_channels = list(range(len(subset)))
2463+
batch_result = await probing_fn(subset, use_channels)
2464+
results.update(batch_result)
2465+
2466+
return results

0 commit comments

Comments
 (0)