Skip to content

Commit d91c783

Browse files
rickwierengaclaude
andcommitted
Add liquid handling capabilities
LiquidHandlingCapability: faithful port of legacy LiquidHandler frontend with tip tracking (commit/rollback), volume tracking, ChannelizedError handling, tip presence probing, can_pick_up_tip validation, spread modes, BlowOutVolumeError, and convenience methods (return_tips, discard_tips, transfer, move_tips, use_channels, use_tips). BackendParams passed through all backend calls and composition methods with operation-specific names. Head96Capability: 96-head operations with tip tracking (commit/rollback), volume tracking, partial tip pickup, single-container (trough) support, container size validation, and convenience methods (return_tips, discard_tips, stamp). State serialization on both capabilities. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1a7b3ec commit d91c783

9 files changed

Lines changed: 2088 additions & 667 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from .pip_backend import PIPBackend
2+
from .errors import ChannelizedError, NoChannelError
3+
from .head96 import Head96Capability
4+
from .head96_backend import Head96Backend
5+
from .pip import PIP
6+
from .standard import (
7+
Aspiration,
8+
Dispense,
9+
DropTipRack,
10+
Mix,
11+
MultiHeadAspirationContainer,
12+
MultiHeadAspirationPlate,
13+
MultiHeadDispenseContainer,
14+
MultiHeadDispensePlate,
15+
Pickup,
16+
PickupTipRack,
17+
TipDrop,
18+
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""Errors for liquid handling operations."""
2+
3+
from typing import Dict
4+
5+
6+
class NoChannelError(Exception):
7+
"""Raised when no channel is available."""
8+
9+
10+
class BlowOutVolumeError(Exception):
11+
"""Raised when blow-out air volume is invalid."""
12+
13+
14+
class ChannelizedError(Exception):
15+
"""Raised by multi-channel operations. Contains per-channel errors."""
16+
17+
def __init__(self, errors: Dict[int, Exception], **kwargs):
18+
self.errors = errors
19+
self.kwargs = kwargs
20+
21+
def __str__(self) -> str:
22+
kwarg_string = ", ".join([f"{k}={v}" for k, v in self.kwargs.items()])
23+
return f"ChannelizedError(errors={self.errors}, {kwarg_string})"
24+
25+
def __len__(self) -> int:
26+
return len(self.errors)

0 commit comments

Comments
 (0)