Pipetting
Basic Pipetting
Aspirating and dispensing liquid with Hamilton and Agilent Bravo liquid handlers.
In this guide a source reservoir, a destination plate, and a tip rack are set up on the deck. Tips are picked up, liquid is aspirated from the source, dispensed into the destination, and tips are discarded.
Prerequisites
- A running liquid handler connector connected to the UniteLabs platform
- A tip rack, a source container (trough or reservoir), and a destination plate
- Basic understanding of tip handling (See Tip Handling)
Connect to the Device
from unitelabs.sdk import AsyncApiClient
from unitelabs.liquid_handling.hamilton import MicrolabSTAR
client = AsyncApiClient()
hamilton = MicrolabSTAR(
name="Microlab STAR",
client=client,
)
await hamilton.initialize()
from unitelabs.sdk import AsyncApiClient
from unitelabs.liquid_handling.agilent import Bravo
client = AsyncApiClient()
bravo = Bravo(
name="Bravo",
client=client,
)
await bravo.configure()
await bravo.initialize()
await bravo.activate()
Arrange the Deck
Hamilton uses carriers placed at track positions. This example uses a tip carrier, a plate carrier with a 96-well plate, and a trough filled with water.
from unitelabs.labware import PredefinedLiquids, Standard96Plate, StandardTrough
from unitelabs.labware.hamilton import (
PLT_CAR_L5MD_A00,
TIP_CAR_480_A00,
HamiltonTip_300,
HamiltonTipRack_300,
)
# Tips
tip_carrier = TIP_CAR_480_A00()
tip_rack = HamiltonTipRack_300(filled_with=HamiltonTip_300)
tip_carrier[0] = tip_rack
hamilton.deck.add(tip_carrier, track=7)
# Source and destination
plate_carrier = PLT_CAR_L5MD_A00()
plate = Standard96Plate()
trough = StandardTrough()
trough.containers[0].add_liquid(PredefinedLiquids.WATER, 150_000)
plate_carrier[0] = plate
plate_carrier[1] = trough
hamilton.deck.add(plate_carrier, track=1)
The Bravo deck has nine numbered locations. Place each labware type at a location.
from unitelabs.labware.agilent.tips import AgilentTipRack_250, AgilentTip_250
from unitelabs.labware.plates import Standard96Plate
from unitelabs.labware.agilent.troughs import Agilent_DW_Reservoir
from unitelabs.labware.liquids import PredefinedLiquids
tip_rack = AgilentTipRack_250(identifier="TipRack_96LT_250uL")
tip_rack.fill(AgilentTip_250)
source_reservoir = Agilent_DW_Reservoir(identifier="SourceReservoir_300mL")
source_reservoir.container.add_liquid(PredefinedLiquids.WATER, 100_000.0)
dest_plate = Standard96Plate(identifier="DestinationPlate_96Well")
bravo.deck.add(tip_rack, location=1)
bravo.deck.add(source_reservoir, location=4)
bravo.deck.add(dest_plate, location=5)
Pick Up Tips
await hamilton.pipettes.pick_up_tips_from(channels=range(8), rack=tip_rack)
await bravo.pipette_head.pick_up_tips_from(rack=tip_rack, press_depth=5.8)
Aspirate
Aspirate using a predefined liquid class that controls flow rates and volume correction.
from unitelabs.labware.hamilton import LiquidClass
liquid_class = LiquidClass.HamiltonTip_300_Water_DispenseJet_Empty()
await hamilton.pipettes.aspirate(
source=trough,
channels=range(8),
volume=100,
liquid_class=liquid_class,
)
Check the current volume held in a channel after aspiration:
current_volume = await hamilton.pipettes[0].current_volume()
print(f"{current_volume} µl") # e.g. 104.9 µl
Aspirate without specifying a liquid class; the SDK auto-selects one based on tip type and volume.
await bravo.pipette_head.aspirate(
plate=source_reservoir,
volume=100,
)
To use a specific liquid class, pass it explicitly:
from unitelabs.labware.agilent import BravoLiquidClasses
liquid_classes = BravoLiquidClasses()
await bravo.pipette_head.aspirate(
plate=source_reservoir,
volume=100,
liquid_class=liquid_classes.OQ_96LT_water_highVol,
)
Dispense
await hamilton.pipettes.dispense(
target=plate["A1":"H1"],
channels=range(8),
volume=100,
liquid_class=liquid_class,
)
await bravo.pipette_head.dispense(
plate=dest_plate,
volume=100,
)
Discard Tips
await hamilton.pipettes.discard_tips(channels=range(8))
# Discard to empty location 3
await bravo.pipette_head.discard_tips(bravo.deck[3])