Skip to content

fix(resources): align a lidded plate on a plate adapter by its wells - #1533

Open
MaxFreedomPollard wants to merge 1 commit into
PyLabRobot:mainfrom
MaxFreedomPollard:fix/plate-adapter-lidded-plate
Open

MaxFreedomPollard wants to merge 1 commit into
PyLabRobot:mainfrom
MaxFreedomPollard:fix/plate-adapter-lidded-plate

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Contributor

Problem

A plate that carries a lid cannot be put on a PlateAdapter:

from pylabrobot.resources import alpaqua_96_plateadapter_magnum_flx, cor_96_wellplate_360uL_Fb

magnet = alpaqua_96_plateadapter_magnum_flx(name="magnet")
plate = cor_96_wellplate_360uL_Fb(name="plate", with_lid=True)
magnet.assign_child_resource(plate)
# ValueError: well spacing has to be uniform

PlateAdapter.compute_plate_location reads the plate's well grid from every child of the plate (pylabrobot/resources/plate_adapter.py:128-129):

x_locations = sorted(set(well_n.location.x for well_n in resource.children))  # type: ignore
y_locations = sorted(set(well_n.location.y for well_n in resource.children))  # type: ignore

A lid is a child of its plate too. On a plate with the same footprint it is seated at x = 0, y = 0, so for the plate in the test below the x locations come out as [0, 9.5, 18.5, ...] instead of [9.5, 18.5, ...]. calculate_well_spacing then finds a step that is not the well pitch and raises.

PlateAdapter.assign_child_resource, the legacy LiquidHandler.move_plate and lib.pick_and_place.get_place_location (used by the v1 STAR and Prep) all call compute_plate_location. So a lidded plate fails on every plate adapter in the library (Alpaqua MAGNUM FLX, Hamilton 182531 and 188182, Sergi 1047, Thermo MicroAmp base), both when the deck is built and when the plate is moved onto an adapter.

Fix

Read the grid from resource.get_wells(). The well size (lines 145-146) comes from the first of those wells instead of the plate's first child.

Tests

TestComputePlateLocation.test_lid_is_not_taken_for_a_well in plate_adapter_tests.py works out where a 96 well plate goes on the adapter, puts a lid on the plate, and checks that the location stays the same. Against the unfixed plate_adapter.py it fails with ValueError: well spacing has to be uniform. With the fix it passes.

Verification

  • With the library definitions, cor_96_wellplate_360uL_Fb(with_lid=True) assigned to each of the five plate adapters lands where the same plate without a lid does. LiquidHandler.move_plate of the lidded plate onto the Alpaqua magnet (chatterbox backend, STARlet deck) also works, and so does get_place_location for the same move. On main every one of these raises the ValueError above.
  • Full suite without the browser-driven pylabrobot/visualizer3D tests (python -m pytest --ignore=pylabrobot/visualizer3D): 5544 passed, 29 skipped, 1365 subtests passed.
  • make lint and make format-check with the pinned ruff 0.15.4: "All checks passed!", "1078 files already formatted".
  • mypy 1.18.2 on the two changed Python files: "Success: no issues found in 2 source files". typos reports nothing on the changed files.

There is a CHANGELOG.md entry under Unreleased / Fixed.

🤖 Generated with Claude Code

PlateAdapter.compute_plate_location builds the plate's well grid from
every child of the plate. A lid is a child too, so its location joins the
well x and y locations, the spacing check sees a step that is not the
well pitch, and the call raises ValueError("well spacing has to be
uniform"). PlateAdapter.assign_child_resource, LiquidHandler.move_plate
and lib.pick_and_place.get_place_location all go through it, so a plate
carrying a lid cannot be put on any plate adapter.

The grid and the well size are read from plate.get_wells().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxFreedomPollard
MaxFreedomPollard requested a review from a team as a code owner October 23, 2026 00:55

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant