Tip Inventory Consolidation#
Enable tip tracking so PLR keeps track of where the tips are.
from pylabrobot.resources import set_tip_tracking
set_tip_tracking(True)
use_channels = [0, 1, 2, 3, 4, 5, 6, 7]
Example LH setup#
For this notebook, we will use Hamilton STAR as an example but all robots should be supported.
%load_ext autoreload
%autoreload 2
from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling import STARBackend
from pylabrobot.resources import STARDeck
backend = STARBackend()
deck = STARDeck()
lh = LiquidHandler(backend=backend, deck=deck)
await lh.setup()
from pylabrobot.resources import HTF, TIP_CAR_480_A00
tip_carrier = TIP_CAR_480_A00(name="tip_carrier")
tip_carrier[0] = tr0 = HTF(name="tr0", with_tips=True)
tip_carrier[1] = tr1 = HTF(name="tr1", with_tips=False)
deck.assign_child_resource(tip_carrier, rails=10)
Setting up the visualizer#
Let’s use the visualizer to see the state of the deck.
from pylabrobot.visualizer import Visualizer
visualizer = Visualizer(lh)
await visualizer.setup()
It should look like this:
Randomization#
To simulate a deck in the worst scenario, we completely randomize the state of the two tip racks. This serves as a stress test for the tip inventory consolidation algorithm. In more realistic runs, tip access is likely more structured.
import random
random.seed(42)
n = 48 # Number of tips to transfer
batch_size = len(use_channels)
# Randomly select n tip spots from source and target racks
source_tip_spots = [tr0.get_item(i) for i in sorted(random.sample(range(tr0.num_items), n))]
target_tip_spots = [tr1.get_item(i) for i in sorted(random.sample(range(tr1.num_items), n))]
for i in range(0, n, batch_size):
await lh.pick_up_tips(source_tip_spots[i:i + batch_size], use_channels=use_channels)
await lh.drop_tips(target_tip_spots[i:i + batch_size], use_channels=use_channels)
After randomization, the visualizer should look like this:
Probing tip presence (optional)#
Because we enabled tip tracking, PLR knows exactly where the tips are. In some runs, when tip tracking was not enabled, we would not know where the tips are.
Luckily, we can automatically detect where tips exist on the deck using “pickup probing”. This means that we can use the robot to pick up tips and see if it succeeds or fails (error). If it succeeds, we know that the tip is present at that location. If it fails, we know that the tip is not present at that location.
Below we “forget” the state of the tips, by telling it both tip racks are full, and then use probing to detect where the tips are. After that, we update the state of the tips again (back to the original state).
tr0.fill()
tr1.fill()
Now the visualizer should look like this:
import pylabrobot.resources.functional as F
result = await lh.probe_tip_inventory(F.get_all_tip_spots([tr0, tr1]), use_channels=use_channels)
for ts_name, has_tip in result.items():
tracker = lh.deck.get_resource(ts_name).tracker
if has_tip and not tracker.has_tip:
tracker.add_tip(lh.get_item(ts_name).make_tip(), commit=True)
elif not has_tip and tracker.has_tip:
tracker.remove_tip(commit=True)
Consolidating tip racks#
await lh.consolidate_tip_inventory([tr0, tr1], use_channels=use_channels)
And we’re back to neatly sorted tip racks!