UniteLabs
Concepts

Tips and Tip Tracking

How the SDK models tips as tracked, lifecycle-managed resources, and why independent-channel heads and monolithic 96-heads work differently.

Tips are consumables, but the SDK models them as tracked resources with a lifecycle. Every tip has a state — sitting in a rack, mounted on a channel, holding liquid, discarded — and every pipetting call validates that state before executing. Aspirating without a tip raises; dropping a tip that was never picked up raises. This is not a convenience, it is what makes simulation meaningful and what catches protocol errors before any liquid moves.

Two head models

Pipetting heads come in two kinds, and which kind you have shapes every tip-handling call:

  • Independent channels — the Hamilton channel head. Each channel holds one tip independently. You specify which channels pick up from which spots, and channels can have different tips (or no tip) at the same time.
  • Monolithic 96-heads — the Bravo head and the Hamilton CoRe 96 head. All active nozzles act as a unit. Partial pickups work by aligning the head's A1 nozzle with a specific rack position via well_offset=(row, col); only nozzles that overlap a filled spot actually pick up tips, so an offset that overlaps already-consumed spots skips them rather than failing. Partial pickup on the Hamilton CoRe 96 head is currently unsupported, as it requires a special adapter.

This difference cascades through aspirate, dispense, and mix. Channel-based heads specify channels=[0, 1, 2, 3]; 96-heads specify well_offset. The same logical operation — "pick up four tips" — has different call shapes because the hardware has different primitives.

The tip state machine

Every tip moves through a small number of states:

in rack  →  picked up  →  aspirating / dispensing  →  dropped / discarded
  • In rack: a tip sits in a TipSpot on a TipRack. The rack tracks which spots are filled.
  • Picked up: a channel or nozzle holds the tip. The SDK records which tip is where.
  • Aspirating / dispensing: the tip contains liquid. Its container tracks the current volume.
  • Dropped / discarded: the tip is returned to a rack spot (put_down_tips() or return_tips()) or sent to the trash (discard_tips()). The channel is empty again.

Running against a mock catches violations of this machine before they reach hardware: trying to aspirate with no tip, dropping to a rack spot that is already occupied, discarding a tip that is not held. See Simulation for the full validation scope.

Tip racks as inventory

A TipRack is an inventory, not just a grid. It tracks which spots are filled and exposes a next_tips() method to return the next available tips in column-major order — so you do not have to remember which spots you have already consumed. This pairs with the tip state machine: once picked up, a tip is no longer "available" from the rack until it is returned. Similarly, first_spots() returns the next empty spots in column-major order.

Inventory operations

Tips presence in a rack can be modified programmatically, for example in order to represent physical instrument state at the beginning of a workflow.

  • TipRack(filled_with=TipType, filled_at=indices) initializes rack filled with tips on specified spots (or all spots if filled_at omitted)
  • tip_rack.fill(labware, spots) adds tips to empty spots
  • tip_rack.clear(spots) removes tips from tip rack spots

Tip properties matter

A tip is not generic. Each tip type declares:

  • A maximum volume (how much liquid it can hold)
  • An air volume model (transport air, blowout air) used by the liquid class
  • A fitting depth (how far it seats onto the nozzle)

Liquid classes are typed by tip — a Bravo AgilentTip_250 class will not work on a different tip type. When protocols move between tip types, liquid class selection has to move with them.

Version note: Tip names changed in Labware SDK v0.22.0 / LHSDK v0.22.0. Previous names such as StandardTip, LT250Tip, and HighVolumeTip are deprecated but still work with a warning. See the Tips and Tip Racks guide for the current naming.

Where to go next