Skip to content

Add container no-go zones with spread-aware channel distribution#953

Open
BioCam wants to merge 20 commits intoPyLabRobot:mainfrom
BioCam:create-no_go_zones
Open

Add container no-go zones with spread-aware channel distribution#953
BioCam wants to merge 20 commits intoPyLabRobot:mainfrom
BioCam:create-no_go_zones

Conversation

@BioCam
Copy link
Collaborator

@BioCam BioCam commented Mar 23, 2026

Adds automatic pipette collision avoidance for containers with internal obstructions (divider walls, support beams) by introducing no-go zones on the Container resource level.

The Problem

Hamilton troughs (60mL, 120mL, 200mL) have internal support structures that pipette tips can collide with during multi-channel operations.
Previously this was handled by runtime warnings telling users to manually use spread="custom"- no actual collision avoidance existed.

PR Content/Solution

  • no_go_zones attribute on Container and all subclasses - defines obstructed cuboid regions
  • Automatic channel distribution across compartments created by no-go zones during aspirate/dispense
  • Respects the user's spread parameter: "wide" spreads channels apart within compartments, "tight" packs at minimum spacing, "custom" bypasses no-go zones entirely
  • Measured no-go zone data for Hamilton 60mL, 120mL (3 tapered beams), and 200mL troughs
  • Tutorial notebook with real-world examples, dimensional breakdowns, and visualizations

Visualization examples

51c0bac1-73cf-4200-bd3d-de615e5b843c 5452020d-f31d-40fc-b829-241d151c22ad 28f52b8a-c00b-4cee-a281-b6beacf4e535-1

BioCam and others added 13 commits March 23, 2026 10:03
Containers can now declare cuboid no-go zones where tips must not be
positioned (e.g. center divider walls in troughs). Each zone is a
Tuple[Coordinate, Coordinate] representing (front_left_bottom, back_right_top).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change MIN_SPACING_EDGE from 1.0 to 2.0mm
- Add n==1 early return to _get_centers_with_margin
- Add _get_compartments: splits container Y axis by no-go zones
- Add center_channels_in_compartments: distributes channels across
  compartments center-out/back-first with per-pair spacing support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add get_channel_spacings() to LiquidHandlerBackend (default 9mm)
- Override in STARBackend with per-pair spacing from hardware config
- LiquidHandler.aspirate/dispense use center_channels_in_compartments
  for multi-channel ops on containers with no-go zones
- Remove hardcoded 5.5mm odd-span offset from STAR_backend
- Single-channel operations are unaffected (skip no-go logic)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 60mL: 1 center divider at Y=44-46mm
- 120mL: 3 support beams evenly spaced
- Remove runtime warnings (no longer needed with automatic avoidance)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests cover: default empty zones, storage, serialization, multiple zones,
center-out/back-first distribution, 2/4/6 channel spreading, and
impossible-fit edge case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Interactive notebook documenting the no-go zone feature with
visualizations for Hamilton troughs, custom containers, edge cases,
and end-to-end simulation via STARChatterboxBackend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces container-level “no-go zones” to enable automatic multichannel offset distribution that avoids internal obstructions (e.g., divider walls/support beams), and wires that logic through LiquidHandler so aspirate/dispense can respect spread while avoiding collisions.

Changes:

  • Add no_go_zones to Container (and subclasses) serialization/deserialization and update related resource tests.
  • Implement compartment-based channel offset computation from no_go_zones, integrated into LiquidHandler for single-resource multi-channel aspirate/dispense.
  • Add backend API get_channel_spacings() (default + STAR override) and integration/unit tests; update Hamilton trough definitions and user guide to include the new feature.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pylabrobot/resources/container.py Adds no_go_zones attribute + serialization support on Container.
pylabrobot/resources/container_tests.py Adds unit tests for storing/serializing no_go_zones and compartment centering behavior.
pylabrobot/resources/well.py Plumbs no_go_zones through Well construction.
pylabrobot/resources/well_tests.py Updates well serialization expectation to include no_go_zones.
pylabrobot/resources/tube.py Plumbs no_go_zones through Tube construction.
pylabrobot/resources/trough.py Plumbs no_go_zones through Trough construction.
pylabrobot/resources/trash.py Plumbs no_go_zones through Trash construction.
pylabrobot/resources/petri_dish.py Plumbs no_go_zones through PetriDish construction.
pylabrobot/resources/petri_dish_tests.py Updates petri dish serialization expectation to include no_go_zones.
pylabrobot/resources/hamilton/troughs.py Adds measured trough no_go_zones and removes prior runtime warning-based guidance.
pylabrobot/liquid_handling/utils.py Implements compartment computation + channel distribution across compartments.
pylabrobot/liquid_handling/liquid_handler.py Integrates new offset logic into aspirate/dispense via _compute_spread_offsets().
pylabrobot/liquid_handling/liquid_handler_tests.py Adds integration tests validating end-to-end no-go-zone behavior through LiquidHandler.
pylabrobot/liquid_handling/backends/backend.py Adds backend hook get_channel_spacings() with a default implementation.
pylabrobot/liquid_handling/backends/hamilton/STAR_backend.py Removes old odd-channel divider shift, updates docs, and overrides get_channel_spacings().
docs/user_guide/00_liquid-handling/_liquid-handling.rst Adds the new tutorial notebook to the user guide toctree.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

BioCam and others added 7 commits March 23, 2026 20:43
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.

2 participants