Skill Tracer
Skills › Scientific Agent Skills › pylabrobot › resources.md

resources.md

248 lines · skills/pylabrobot/references/resources.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Resources, decks, state, and serialization
2
3Verified against **PyLabRobot 0.2.2** on **2026-10-01**.
4

Resources, decks, state, and serialization

Verified against PyLabRobot 0.2.2 on 2026-10-01.

Raw lines 1 to 4
5## Resource model
6
7PyLabRobot represents a workcell as a resource tree. Typical nodes are:
8
9- `LiquidHandler` / `Deck`
10- carriers, adapters, sites, and modules
11- `Plate`, `TipRack`, reservoirs, tube racks, and `Trash`
12- `Well`, `TipSpot`, and `Tip`
14Every resource has a unique name, dimensions in millimetres, an optional
15location relative to its parent, and parent/child relationships. Names are how
16`Deck.get_resource(name)` resolves nested resources, so duplicates are unsafe.
18```python
19from pylabrobot.resources import Coordinate, Resource
21resource = Resource(
22 name="fixture",
23 size_x=100.0,
24 size_y=50.0,
25 size_z=20.0,
27parent.assign_child_resource(
28 resource,
29 location=Coordinate(x=10.0, y=20.0, z=0.0),
31```
33The coordinate origin and usable envelope depend on the parent/deck definition.
34Do not copy coordinates across robots, carriers, adapters, or labware revisions.

Resource model

PyLabRobot represents a workcell as a resource tree. Typical nodes are:

  • LiquidHandler / Deck
  • carriers, adapters, sites, and modules
  • Plate, TipRack, reservoirs, tube racks, and Trash
  • Well, TipSpot, and Tip

Every resource has a unique name, dimensions in millimetres, an optional location relative to its parent, and parent/child relationships. Names are how Deck.get_resource(name) resolves nested resources, so duplicates are unsafe.

from pylabrobot.resources import Coordinate, Resource

resource = Resource(
    name="fixture",
    size_x=100.0,
    size_y=50.0,
    size_z=20.0,
)
parent.assign_child_resource(
    resource,
    location=Coordinate(x=10.0, y=20.0, z=0.0),
)

The coordinate origin and usable envelope depend on the parent/deck definition. Do not copy coordinates across robots, carriers, adapters, or labware revisions.

Raw lines 5 to 35
36## Use stable built-in definitions
38Stable 0.2.2 exports vendor/model resource factories. The Hamilton getting
39started tutorial uses:
41```python
42from pylabrobot.resources import (
43 cor_96_wellplate_360uL_Fb,
44 PLT_CAR_L5AC_A00,
45 TIP_CAR_480_A00,
46 hamilton_96_tiprack_1000uL_filter,
48from pylabrobot.resources.hamilton import STARLetDeck
49```
51Names are case-sensitive. Old examples such as `Cos_96_DW_1mL` may not identify
52the intended current factory. Search the installed 0.2.2 resource namespace or
53stable resource docs and verify manufacturer, catalog number, dimensions,
54bottom geometry, capacity, lid/adapter, and revision.
56Carrier sites are commonly assigned before the carrier is placed on the deck:
58```python
59tip_carrier = TIP_CAR_480_A00(name="tip_carrier")
60tip_carrier[0] = tips = hamilton_96_tiprack_1000uL_filter(name="tips")
62plate_carrier = PLT_CAR_L5AC_A00(name="plate_carrier")
63plate_carrier[0] = plate = cor_96_wellplate_360uL_Fb(name="plate")
65deck = STARLetDeck()
66deck.assign_child_resource(tip_carrier, rails=3)
67deck.assign_child_resource(plate_carrier, rails=15)
68```
70Rail placement is Hamilton-specific. Other decks use their own sites,
71coordinates, fixtures, and constraints.

Use stable built-in definitions

Stable 0.2.2 exports vendor/model resource factories. The Hamilton getting started tutorial uses:

from pylabrobot.resources import (
    cor_96_wellplate_360uL_Fb,
    PLT_CAR_L5AC_A00,
    TIP_CAR_480_A00,
    hamilton_96_tiprack_1000uL_filter,
)
from pylabrobot.resources.hamilton import STARLetDeck

Names are case-sensitive. Old examples such as Cos_96_DW_1mL may not identify the intended current factory. Search the installed 0.2.2 resource namespace or stable resource docs and verify manufacturer, catalog number, dimensions, bottom geometry, capacity, lid/adapter, and revision.

Carrier sites are commonly assigned before the carrier is placed on the deck:

tip_carrier = TIP_CAR_480_A00(name="tip_carrier")
tip_carrier[0] = tips = hamilton_96_tiprack_1000uL_filter(name="tips")

plate_carrier = PLT_CAR_L5AC_A00(name="plate_carrier")
plate_carrier[0] = plate = cor_96_wellplate_360uL_Fb(name="plate")

deck = STARLetDeck()
deck.assign_child_resource(tip_carrier, rails=3)
deck.assign_child_resource(plate_carrier, rails=15)

Rail placement is Hamilton-specific. Other decks use their own sites, coordinates, fixtures, and constraints.

Raw lines 36 to 72
73## Plates, wells, tip racks, and tips
75Stable accessors include:
77```python
78well = plate.get_well("A1")
79wells = plate.get_wells(["A1", "B1"])
80selected_wells = plate["A1"] # list[Well], even for one identifier
81tip_spot = tips.get_item("A1")
82selected_tip_spots = tips["A1"] # list[TipSpot]
83tip = tip_spot.get_tip()
84```
86Relevant stable constructors/attributes include:
88- `Well(..., max_volume=..., height_volume_data=...)`
89- `Tip(has_filter, total_tip_length, maximal_volume, fitting_depth, ...)`
90- `TipRack(..., with_tips=True)`
91- `TipSpot(..., make_tip=...)`
93`Tip.maximal_volume` is only one compatibility dimension. Also validate fitting,
94length, filter, head/tool, pickup/drop geometry, rack model, and vendor support.
96Well capacity is geometric bookkeeping. Usable aspiration volume is smaller
97when dead volume, well shape, tilt, liquid properties, required immersion, or
98assay constraints apply. `height_volume_data` supports interpolation for
99definitions that provide it; it is not a sensor and is only as accurate as the
100definition/calibration.

Plates, wells, tip racks, and tips

Stable accessors include:

well = plate.get_well("A1")
wells = plate.get_wells(["A1", "B1"])
selected_wells = plate["A1"]  # list[Well], even for one identifier
tip_spot = tips.get_item("A1")
selected_tip_spots = tips["A1"]  # list[TipSpot]
tip = tip_spot.get_tip()

Relevant stable constructors/attributes include:

  • Well(..., max_volume=..., height_volume_data=...)
  • Tip(has_filter, total_tip_length, maximal_volume, fitting_depth, ...)
  • TipRack(..., with_tips=True)
  • TipSpot(..., make_tip=...)

Tip.maximal_volume is only one compatibility dimension. Also validate fitting, length, filter, head/tool, pickup/drop geometry, rack model, and vendor support.

Well capacity is geometric bookkeeping. Usable aspiration volume is smaller when dead volume, well shape, tilt, liquid properties, required immersion, or assay constraints apply. height_volume_data supports interpolation for definitions that provide it; it is not a sensor and is only as accurate as the definition/calibration.

Raw lines 73 to 101
102## Coordinate and collision checks
104For every resource, verify:
1061. Dimensions and units (`mm`).
1072. Location relative to the correct parent and absolute location on the deck.
1083. Orientation/rotation, lid, adapter, nesting, and stacking height.
1094. Static overlap with neighboring resources.
1105. Dynamic envelopes for channels, tips, grippers, arms, doors, trays, buckets,
111 cables, tubing, and manually handled items.
1126. Manufacturing tolerance, calibration, teaching, and clearance margin.
114Hamilton deck assignment performs collision checks and exposes an
115`ignore_collision` escape hatch. Do not set `ignore_collision=True` to make a
116layout pass. Resolve the definition or placement and repeat physical review.
117Generic resource assignment alone is not a complete collision or motion check.
118Released 0.2.2 takes `rails=`; the newer documentation may use `track=`, which
119is not a keyword in this release.
121The bundled checker provides an independent deterministic screen:
123```bash
124python3 skills/pylabrobot/scripts/check_deck_geometry.py \
125 --input tests/pylabrobot/fixtures/protocol_manifest.json
126```
128It checks deck bounds and pairwise axis-aligned box overlap. It intentionally
129does not claim to model rotation, motion, lids, tubing, cables, tolerances, or
130vendor firmware paths.

Coordinate and collision checks

For every resource, verify:

  1. Dimensions and units (mm).
  2. Location relative to the correct parent and absolute location on the deck.
  3. Orientation/rotation, lid, adapter, nesting, and stacking height.
  4. Static overlap with neighboring resources.
  5. Dynamic envelopes for channels, tips, grippers, arms, doors, trays, buckets, cables, tubing, and manually handled items.
  6. Manufacturing tolerance, calibration, teaching, and clearance margin.

Hamilton deck assignment performs collision checks and exposes an ignore_collision escape hatch. Do not set ignore_collision=True to make a layout pass. Resolve the definition or placement and repeat physical review. Generic resource assignment alone is not a complete collision or motion check. Released 0.2.2 takes rails=; the newer documentation may use track=, which is not a keyword in this release.

The bundled checker provides an independent deterministic screen:

python3 skills/pylabrobot/scripts/check_deck_geometry.py \
  --input tests/pylabrobot/fixtures/protocol_manifest.json

It checks deck bounds and pairwise axis-aligned box overlap. It intentionally does not claim to model rotation, motion, lids, tubing, cables, tolerances, or vendor firmware paths.

Raw lines 102 to 131
Runs code python3 skills/pylabrobot/scripts/check_deck_geometry.py :124
132## Tip and volume state
134```python
135from pylabrobot.resources import set_tip_tracking, set_volume_tracking
137set_tip_tracking(True)
138set_volume_tracking(True)
140tips.fill()
141tips.get_item("A1").tracker.has_tip
142plate.get_well("A1").tracker.set_volume(200.0)
143plate.get_well("A1").tracker.get_used_volume()
144plate.get_well("A1").tracker.get_free_volume()
145```
147Trackers model expected software state and operation history. They do not
148physically detect tips, liquid, liquid identity, clogs, seals, lids, or
149misloaded labware. Reconcile tracker state against a trusted preparation record
150and the physical deck before any live run.
152Keep these separate:
154- maximum geometric well volume;
155- declared initial volume;
156- minimum dead/residual volume;
157- transfer amount;
158- maximum tip volume and currently held tip volume;
159- destination headspace;
160- physical liquid-level detection, if a particular backend supports it.

Tip and volume state

from pylabrobot.resources import set_tip_tracking, set_volume_tracking

set_tip_tracking(True)
set_volume_tracking(True)

tips.fill()
tips.get_item("A1").tracker.has_tip
plate.get_well("A1").tracker.set_volume(200.0)
plate.get_well("A1").tracker.get_used_volume()
plate.get_well("A1").tracker.get_free_volume()

Trackers model expected software state and operation history. They do not physically detect tips, liquid, liquid identity, clogs, seals, lids, or misloaded labware. Reconcile tracker state against a trusted preparation record and the physical deck before any live run.

Keep these separate:

  • maximum geometric well volume;
  • declared initial volume;
  • minimum dead/residual volume;
  • transfer amount;
  • maximum tip volume and currently held tip volume;
  • destination headspace;
  • physical liquid-level detection, if a particular backend supports it.
Raw lines 132 to 161
162## Definition and state serialization
164Verified 0.2.2 methods include:
166```python
167resource.save("deck.json", indent=2)
168loaded = Resource.load_from_json_file("deck.json")
170state = resource.serialize_all_state()
171resource.load_all_state(state)
172resource.save_state_to_file("state.json", indent=2)
173resource.load_state_from_file("state.json")
174```
176Only deserialize an allowlisted **resource-only** tree. Machine serialization
177also contains a backend and may reconstruct it; `allow_marshal=False` is not a
178ban on hardware backend construction. Never load an unreviewed `LiquidHandler`
179or device node while claiming an offline resource import.
181`Resource.serialize()` stores a definition; `serialize_state()` and
182`serialize_all_state()` store tracker/resource state. Keep definition and state
183with protocol version, PyLabRobot version, checksums, device/deck identity, and
184preparation metadata.
186Treat serialized files as untrusted input:
188- accept only bounded UTF-8 JSON from an approved local path;
189- reject duplicate/unknown keys and non-finite values;
190- never load arbitrary Python, pickle, plugins, or user-selected classes;
191- keep `Resource.deserialize(..., allow_marshal=False)` at its safe default;
192- validate names, resource types, dimensions, locations, capacities, and state
193 against an allowlist before constructing a workcell;
194- do not let a saved state replace physical deck reconciliation.
196The bundled tools do not deserialize PyLabRobot classes. They use a small,
197strict manifest schema:
199- `assets/protocol-manifest.schema.json`
200- `tests/pylabrobot/fixtures/protocol_manifest.json`
202The Python validator adds bounds and cross-field checks beyond the documentation
203schema:
205```bash
206python3 skills/pylabrobot/scripts/validate_manifest.py \
207 --input tests/pylabrobot/fixtures/protocol_manifest.json
208```
210Inputs must remain under the current working directory, be regular non-symlink
211files, use the expected extension, stay under 2 MB, and have at most 64 JSON
212nesting levels. Every transferred-to well needs an explicit starting volume,
213including `0.0` for an intentionally empty destination. The validator never
214assumes an undeclared destination is empty.

Definition and state serialization

Verified 0.2.2 methods include:

resource.save("deck.json", indent=2)
loaded = Resource.load_from_json_file("deck.json")

state = resource.serialize_all_state()
resource.load_all_state(state)
resource.save_state_to_file("state.json", indent=2)
resource.load_state_from_file("state.json")

Only deserialize an allowlisted resource-only tree. Machine serialization also contains a backend and may reconstruct it; allow_marshal=False is not a ban on hardware backend construction. Never load an unreviewed LiquidHandler or device node while claiming an offline resource import.

Resource.serialize() stores a definition; serialize_state() and serialize_all_state() store tracker/resource state. Keep definition and state with protocol version, PyLabRobot version, checksums, device/deck identity, and preparation metadata.

Treat serialized files as untrusted input:

  • accept only bounded UTF-8 JSON from an approved local path;
  • reject duplicate/unknown keys and non-finite values;
  • never load arbitrary Python, pickle, plugins, or user-selected classes;
  • keep Resource.deserialize(..., allow_marshal=False) at its safe default;
  • validate names, resource types, dimensions, locations, capacities, and state against an allowlist before constructing a workcell;
  • do not let a saved state replace physical deck reconciliation.

The bundled tools do not deserialize PyLabRobot classes. They use a small, strict manifest schema:

  • assets/protocol-manifest.schema.json
  • tests/pylabrobot/fixtures/protocol_manifest.json

The Python validator adds bounds and cross-field checks beyond the documentation schema:

python3 skills/pylabrobot/scripts/validate_manifest.py \
  --input tests/pylabrobot/fixtures/protocol_manifest.json

Inputs must remain under the current working directory, be regular non-symlink files, use the expected extension, stay under 2 MB, and have at most 64 JSON nesting levels. Every transferred-to well needs an explicit starting volume, including 0.0 for an intentionally empty destination. The validator never assumes an undeclared destination is empty.

Raw lines 162 to 215
Runs code python3 skills/pylabrobot/scripts/validate_manifest.py :206
216## Custom labware
218Do not invent a `Plate` or `Well` from nominal SBS footprint alone. Obtain and
219review:
221- exact manufacturer/catalog/revision;
222- external dimensions, skirt and flange, nesting/stacking, lid and adapter;
223- well centres, pitch, top/bottom geometry, depth, material thickness, and
224 height/volume behavior;
225- robot-specific pickup, gripping, carrier/site, and clearance data;
226- empirical calibration and acceptance results.
228Use upstream's current resource-definition contributor tooling and tests. Keep
229custom definitions versioned and independently reviewed before commissioning.

Custom labware

Do not invent a Plate or Well from nominal SBS footprint alone. Obtain and review:

  • exact manufacturer/catalog/revision;
  • external dimensions, skirt and flange, nesting/stacking, lid and adapter;
  • well centres, pitch, top/bottom geometry, depth, material thickness, and height/volume behavior;
  • robot-specific pickup, gripping, carrier/site, and clearance data;
  • empirical calibration and acceptance results.

Use upstream's current resource-definition contributor tooling and tests. Keep custom definitions versioned and independently reviewed before commissioning.

Raw lines 216 to 230
231## Sources
233Checked **2026-10-01**:
235- [Hosted resource management](https://docs.pylabrobot.org/stable/resources/introduction.html)
236 and [hosted resources API](https://docs.pylabrobot.org/stable/api/pylabrobot.resources.html)
237 — development resource guide; release signatures verified from the wheel.
238- [Hosted Hamilton tutorial](https://docs.pylabrobot.org/stable/user_guide/00_liquid-handling/hamilton-star/basic.html)
239 — verified factories, carrier sites, rails, and deck summary.
240- [Hosted tracker guide](https://docs.pylabrobot.org/stable/user_guide/machine-agnostic-features/using-trackers.html)
241 — tip/volume state and errors.
242- [released 0.2.2 resources source](https://pypi.org/project/PyLabRobot/0.2.2/#files)
243 — constructor, serialization, tracker, and collision signatures; released
244 2026-07-30.
245- [Release review](review.md) — `height_volume_data` remains supported;
246 `Plate.stacking_z_height` and `plate_type` round-trip in 0.2.2 even though the
247 changelog lists stacking under `Unreleased`. Native tests confirm bare-plate
248 stacking height and resource/state round trips.

Sources

Checked 2026-10-01:

  • Hosted resource management and hosted resources API — development resource guide; release signatures verified from the wheel.
  • Hosted Hamilton tutorial — verified factories, carrier sites, rails, and deck summary.
  • Hosted tracker guide — tip/volume state and errors.
  • released 0.2.2 resources source — constructor, serialization, tracker, and collision signatures; released 2026-07-30.
  • Release review — height_volume_data remains supported; Plate.stacking_z_height and plate_type round-trip in 0.2.2 even though the changelog lists stacking under Unreleased. Native tests confirm bare-plate stacking height and resource/state round trips.
Raw lines 231 to 248