Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/resources/library/vwr.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Company page: [Wikipedia](https://en.wikipedia.org/wiki/VWR_International)
| Description | Image | PLR definition |
|--------------------|--------------------|--------------------|
| 'VWRReagentReservoirs25mL'<br>Part no.: 89094<br>[manufacturer website](https://us.vwr.com/store/product/4694822/vwr-disposable-pipetting-reservoirs)<br>Polystyrene Reservoirs | ![](img/vwr/VWRReagentReservoirs25mL.jpg) | `VWRReagentReservoirs25mL` |
| 'VWR_1_troughplate_195000uL_Ub'<br>Part no.: 77575-302<br>[manufacturer website](https://www.avantorsciences.com/us/en/product/47763965/vwr-multi-channel-polypropylene-reagent-reservoirs?isCatNumSearch=true&searchedCatalogNumber=77575-302)<br>Polypropylene multi-channel reagent reservoirs | ![](img/vwr/VWR_1_troughplate_195000uL_Ub.jpg) | `VWR_1_troughplate_195000uL_Ub` |

## Plates

Expand Down
14 changes: 12 additions & 2 deletions pylabrobot/liquid_handling/liquid_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ def _check_containers(self, resources: Sequence[Resource]):
@need_setup_finished
async def aspirate(
self,
resources: Sequence[Container],
resources: Union[Container, Sequence[Container]],
vols: List[float],
use_channels: Optional[List[int]] = None,
flow_rates: Optional[List[Optional[float]]] = None,
Expand Down Expand Up @@ -901,6 +901,9 @@ async def aspirate(
ValueError: If all channels are `None`.
"""

if isinstance(resources, Container):
resources = [resources]

self._log_command(
"aspirate",
resources=resources,
Expand Down Expand Up @@ -946,6 +949,8 @@ async def aspirate(
("liquid_height", liquid_height),
("blow_out_air_volume", blow_out_air_volume),
]:
if n == "resources" and len(p) == 1:
continue
if len(p) != len(use_channels):
raise ValueError(
f"Length of {n} must match length of use_channels: {len(p)} != {len(use_channels)}"
Expand Down Expand Up @@ -1029,7 +1034,7 @@ async def aspirate(
@need_setup_finished
async def dispense(
self,
resources: Sequence[Container],
resources: Union[Container, Sequence[Container]],
vols: List[float],
use_channels: Optional[List[int]] = None,
flow_rates: Optional[List[Optional[float]]] = None,
Expand Down Expand Up @@ -1092,6 +1097,9 @@ async def dispense(
ValueError: If all channels are `None`.
"""

if isinstance(resources, Container):
resources = [resources]

self._log_command(
"dispense",
resources=resources,
Expand Down Expand Up @@ -1159,6 +1167,8 @@ async def dispense(
("liquid_height", liquid_height),
("blow_out_air_volume", blow_out_air_volume),
]:
if n == "resources" and len(p) == 1:
continue
if len(p) != len(use_channels):
raise ValueError(
f"Length of {n} must match length of use_channels: {len(p)} != {len(use_channels)}"
Expand Down
37 changes: 37 additions & 0 deletions pylabrobot/liquid_handling/liquid_handler_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
ResourceNotFoundError,
ResourceStack,
TipRack,
VWR_1_trough_195000uL_Ub,
nest_1_troughplate_195000uL_Vb,
no_tip_tracking,
set_tip_tracking,
Expand Down Expand Up @@ -56,7 +57,9 @@
Drop,
DropTipRack,
GripDirection,
MultiHeadAspirationContainer,
MultiHeadAspirationPlate,
MultiHeadDispenseContainer,
MultiHeadDispensePlate,
Pickup,
ResourcePickup,
Expand Down Expand Up @@ -634,6 +637,40 @@ async def test_aspirate_dispense96(self):
)
)

async def test_aspirate_dispense96_vwr_trough(self):
trough = VWR_1_trough_195000uL_Ub(name="vwr_trough")
self.deck.assign_child_resource(trough, location=Coordinate(300, 100, 0))

await self.lh.pick_up_tips96(self.tip_rack)
await self.lh.aspirate96(trough, volume=10)
await self.lh.dispense96(trough, volume=10)

tips = [self.lh.head96[i].get_tip() for i in range(96)]
self.backend.aspirate96.assert_called_with(
aspiration=MultiHeadAspirationContainer(
container=trough,
offset=Coordinate.zero(),
tips=tips,
volume=10,
flow_rate=None,
liquid_height=None,
blow_out_air_volume=None,
mix=None,
)
)
self.backend.dispense96.assert_called_with(
dispense=MultiHeadDispenseContainer(
container=trough,
offset=Coordinate.zero(),
tips=tips,
volume=10,
flow_rate=None,
liquid_height=None,
blow_out_air_volume=None,
mix=None,
)
)

async def test_dispense96_with_quadrant_well_list(self):
plate_384 = Revvity_384_wellplate_28ul_Ub(name="plate_384")
self.deck.assign_child_resource(plate_384, location=Coordinate(400, 100, 0))
Expand Down
2 changes: 1 addition & 1 deletion pylabrobot/resources/vwr/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .plates import VWR_1_troughplate_195000uL_Ub, VWR_96_wellplate_2mL_Vb
from .troughs import VWRReagentReservoirs25mL
from .troughs import VWR_1_trough_195000uL_Ub, VWRReagentReservoirs25mL
34 changes: 33 additions & 1 deletion pylabrobot/resources/vwr/troughs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
from pylabrobot.resources.trough import Trough
from pylabrobot.resources.height_volume_functions import (
compute_height_from_volume_rectangle,
compute_volume_from_height_rectangle,
)
from pylabrobot.resources.trough import Trough, TroughBottomType


def VWR_1_trough_195000uL_Ub(name: str) -> Trough:
"""VWR NA Cat. No. 77575-302"""

inner_width = 127.76 - (14.38 - 8.9 / 2) * 2
inner_length = 85.48 - (11.24 - 8.9 / 2) * 2

return Trough(
name=name,
size_x=127.76, # from spec
size_y=85.48, # from spec
size_z=31.4, # from spec
material_z_thickness=3.55, # from spec
max_volume=195000, # from spec 195 mL
model=VWR_1_trough_195000uL_Ub.__name__,
bottom_type=TroughBottomType.U,
compute_height_from_volume=lambda liquid_volume: compute_height_from_volume_rectangle(
liquid_volume,
inner_length,
inner_width,
),
compute_volume_from_height=lambda liquid_height: compute_volume_from_height_rectangle(
liquid_height,
inner_length,
inner_width,
),
)


def VWRReagentReservoirs25mL(name: str) -> Trough:
Expand Down
Loading