Hi everyone,
PLR normally uses a consistent resource definition scheme, assigning child resources to parent resources at specific locations.
These locations mark the left-front-bottom of a cuboid that encompasses the entire child resource.
This is what I found for all Hamilton-specific and general resource definitions in the PLR Resource Library.
However, this does not appear to be the case for resources in the pylabrobot/resources/opentrons/
folder (or at least the couple I looked into).
Everything on pylabrobot:main
Example 1
from pylabrobot.resources import (
Porvair_6_reservoir_47ml_Vb, # Plate contributed by me
agilent_1_reservoir_290ml # Plate from Opentrons folder
)
Porvair_6_reservoir_47ml_Vb(name="test")
>>> Plate(name=test, size_x=127.0, size_y=86.0, size_z=44, location=None)
Porvair_6_reservoir_47ml_Vb(name="test").children
>>> [Well(name=test_well_0_0, location=(009.300, 005.700, 002.240), size_x=16.8, size_y=70.8, size_z=42.5, category=well),
>>> Well(name=test_well_1_0, location=(027.800, 005.700, 002.240), size_x=16.8, size_y=70.8, size_z=42.5, category=well),
>>> Well(name=test_well_2_0, location=(046.300, 005.700, 002.240), size_x=16.8, size_y=70.8, size_z=42.5, category=well),
>>> Well(name=test_well_3_0, location=(064.800, 005.700, 002.240), size_x=16.8, size_y=70.8, size_z=42.5, category=well),
>>> Well(name=test_well_4_0, location=(083.300, 005.700, 002.240), size_x=16.8, size_y=70.8, size_z=42.5, category=well),
>>> Well(name=test_well_5_0, location=(101.800, 005.700, 002.240), size_x=16.8, size_y=70.8, size_z=42.5, category=well)]
agilent_1_reservoir_290ml(name="test")
>>> Plate(name=test, size_x=127.76, size_y=85.57, size_z=44.04, location=None)
agilent_1_reservoir_290ml(name="test").children
>>> [Well(name=test_A1, location=(063.880, 042.785, 004.820), size_x=108, size_y=72, size_z=39.22, category=well)]
→ The Opentrons-defined and -extracted PLR definition believes that the well/reservoir starts in the center of the plate.
→ All standard commands without synthetic offsets will crash.
Example 2
I thought that maybe this is just a single wrongly defined import from the Opentrons library and looked further.
To properly compare I looked for Opentrons library plates that have a similar counterpart in the remaining PLR Resource Library:
- I recently contributed the definition to
Cos_6_MWP_16800ul_Fb
, Costar cat no.: 3516 - The Opentrons library has a similar predefined plate:
corning_6_wellplate_16point8ml_flat
, Costar cat no.: 3335
from pylabrobot.resources import (
Cos_6_MWP_16800ul_Fb, # Plate contributed by me
corning_6_wellplate_16point8ml_flat # Plate from Opentrons folder
)
Cos_6_MWP_16800ul_Fb(name="test")
>>> Plate(name=test, size_x=127.0, size_y=86.0, >>> size_z=19.85, location=None)
Cos_6_MWP_16800ul_Fb(name="test").children
>>> [Well(name=test_well_0_0, location=(007.000, 043.900, 000.300), size_x=35.0, size_y=35.0, size_z=17.5, category=well),
>>> Well(name=test_well_0_1, location=(007.000, 005.450, 000.300), size_x=35.0, size_y=35.0, size_z=17.5, category=well),
>>> Well(name=test_well_1_0, location=(045.450, 043.900, 000.300), size_x=35.0, size_y=35.0, size_z=17.5, category=well),
>>> Well(name=test_well_1_1, location=(045.450, 005.450, 000.300), size_x=35.0, size_y=35.0, size_z=17.5, category=well),
>>> Well(name=test_well_2_0, location=(083.900, 043.900, 000.300), size_x=35.0, size_y=35.0, size_z=17.5, category=well),
>>> Well(name=test_well_2_1, location=(083.900, 005.450, 000.300), size_x=35.0, size_y=35.0, size_z=17.5, category=well),
>>> Lid(name=test_lid, location=(000.000, 000.000, 017.850), size_x=127.0, size_y=86.0, size_z=2, category=lid)]
corning_6_wellplate_16point8ml_flat(name="test").children
>>> Plate(name=test, size_x=127.76, size_y=85.47, size_z=20.27, location=None)
corning_6_wellplate_16point8ml_flat(name="test").children
>>> [Well(name=test_A1, location=(024.760, 062.280, 002.870), size_x=25.053, size_y=25.053, size_z=17.4, category=well),
>>> Well(name=test_B1, location=(024.760, 023.160, 002.870), size_x=25.053, size_y=25.053, size_z=17.4, category=well),
>>> Well(name=test_A2, location=(063.880, 062.280, 002.870), size_x=25.053, size_y=25.053, size_z=17.4, category=well),
>>> Well(name=test_B2, location=(063.880, 023.160, 002.870), size_x=25.053, size_y=25.053, size_z=17.4, category=well),
>>> Well(name=test_A3, location=(103.000, 062.280, 002.870), size_x=25.053, size_y=25.053, size_z=17.4, category=well),
>>> Well(name=test_B3, location=(103.000, 023.160, 002.870), size_x=25.053, size_y=25.053, size_z=17.4, category=well)]
→ It is now clear that multiple plates that have been imported from the Opentrons library are not correctly defined in PLR.
There appear to be multiple discrepancies also when comparing the PLR Opentrons definition to the Opentrons library website entry itself:
- The wells’ diameters have not been correctly transferred into the PLR_well.size_x / y
- Opentrons uses as different grid-offset system - based on the first well’s center (see Opentrons Labware Creator), while PLR uses one based on the first well’s edges - which can explain some of these differences.
I wondered whether this was on purpose?
Does PLR require resources to be defined differently for Opentrons machines?