opentrons 8.6.0a12__py3-none-any.whl → 8.7.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/_version.py +2 -2
- opentrons/hardware_control/backends/ot3controller.py +22 -13
- opentrons/hardware_control/backends/ot3simulator.py +1 -1
- opentrons/hardware_control/ot3api.py +1 -1
- opentrons/protocol_api/core/engine/_default_liquid_class_versions.py +54 -0
- opentrons/protocol_api/core/engine/protocol.py +11 -2
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +1 -1
- opentrons/protocol_api/core/protocol.py +1 -1
- opentrons/protocol_api/labware.py +36 -2
- opentrons/protocol_api/module_contexts.py +100 -13
- opentrons/protocol_api/protocol_context.py +162 -12
- opentrons/protocol_api/validation.py +4 -0
- opentrons/protocol_engine/commands/command_unions.py +2 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +13 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +20 -2
- opentrons/protocol_engine/execution/labware_movement.py +5 -11
- opentrons/protocol_engine/state/labware.py +66 -0
- opentrons/protocol_engine/types/__init__.py +2 -0
- opentrons/protocol_engine/types/labware.py +9 -0
- opentrons/protocols/api_support/definitions.py +1 -1
- {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/METADATA +4 -4
- {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/RECORD +25 -24
- {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/WHEEL +0 -0
- {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.6.0a12.dist-info → opentrons-8.7.0a0.dist-info}/licenses/LICENSE +0 -0
opentrons/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '8.
|
|
32
|
-
__version_tuple__ = version_tuple = (8,
|
|
31
|
+
__version__ = version = '8.7.0a0'
|
|
32
|
+
__version_tuple__ = version_tuple = (8, 7, 0, 'a0')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -686,9 +686,9 @@ class OT3Controller(FlexBackend):
|
|
|
686
686
|
return (
|
|
687
687
|
MoveGroupRunner(
|
|
688
688
|
move_groups=[move_group],
|
|
689
|
-
ignore_stalls=
|
|
690
|
-
|
|
691
|
-
|
|
689
|
+
ignore_stalls=(
|
|
690
|
+
True if not self._feature_flags.stall_detection_enabled else False
|
|
691
|
+
),
|
|
692
692
|
),
|
|
693
693
|
False,
|
|
694
694
|
)
|
|
@@ -712,9 +712,9 @@ class OT3Controller(FlexBackend):
|
|
|
712
712
|
return (
|
|
713
713
|
MoveGroupRunner(
|
|
714
714
|
move_groups=[tip_motor_move_group],
|
|
715
|
-
ignore_stalls=
|
|
716
|
-
|
|
717
|
-
|
|
715
|
+
ignore_stalls=(
|
|
716
|
+
True if not self._feature_flags.stall_detection_enabled else False
|
|
717
|
+
),
|
|
718
718
|
),
|
|
719
719
|
True,
|
|
720
720
|
)
|
|
@@ -939,9 +939,9 @@ class OT3Controller(FlexBackend):
|
|
|
939
939
|
|
|
940
940
|
runner = MoveGroupRunner(
|
|
941
941
|
move_groups=[move_group],
|
|
942
|
-
ignore_stalls=
|
|
943
|
-
|
|
944
|
-
|
|
942
|
+
ignore_stalls=(
|
|
943
|
+
True if not self._feature_flags.stall_detection_enabled else False
|
|
944
|
+
),
|
|
945
945
|
)
|
|
946
946
|
try:
|
|
947
947
|
positions = await runner.run(can_messenger=self._messenger)
|
|
@@ -976,9 +976,9 @@ class OT3Controller(FlexBackend):
|
|
|
976
976
|
move_group = self._build_tip_action_group(origin, targets)
|
|
977
977
|
runner = MoveGroupRunner(
|
|
978
978
|
move_groups=[move_group],
|
|
979
|
-
ignore_stalls=
|
|
980
|
-
|
|
981
|
-
|
|
979
|
+
ignore_stalls=(
|
|
980
|
+
True if not self._feature_flags.stall_detection_enabled else False
|
|
981
|
+
),
|
|
982
982
|
)
|
|
983
983
|
try:
|
|
984
984
|
positions = await runner.run(can_messenger=self._messenger)
|
|
@@ -1777,7 +1777,16 @@ class OT3Controller(FlexBackend):
|
|
|
1777
1777
|
expected_grip_width + grip_width_uncertainty_wider
|
|
1778
1778
|
)
|
|
1779
1779
|
current_gripper_position = jaw_width
|
|
1780
|
-
|
|
1780
|
+
log.info(
|
|
1781
|
+
f"Checking gripper position: current {jaw_width}; max error {max_allowed_grip_error}; hard limits {hard_limit_lower}, {hard_limit_upper}; expected {expected_gripper_position_min}, {expected_grip_width}, {expected_gripper_position_max}; uncertainty {grip_width_uncertainty_narrower}, {grip_width_uncertainty_wider}"
|
|
1782
|
+
)
|
|
1783
|
+
if (
|
|
1784
|
+
isclose(current_gripper_position, hard_limit_lower)
|
|
1785
|
+
# this odd check handles internal backlash that can lead the position to read as if
|
|
1786
|
+
# the gripper has overshot its lower bound; this is physically impossible and an
|
|
1787
|
+
# artifact of the gearing, so it always indicates a hard stop
|
|
1788
|
+
or current_gripper_position < hard_limit_lower
|
|
1789
|
+
):
|
|
1781
1790
|
raise FailedGripperPickupError(
|
|
1782
1791
|
message="Failed to grip: jaws all the way closed",
|
|
1783
1792
|
details={
|
|
@@ -1480,8 +1480,8 @@ class OT3API(
|
|
|
1480
1480
|
grip_width_uncertainty_narrower,
|
|
1481
1481
|
gripper.jaw_width,
|
|
1482
1482
|
gripper.max_allowed_grip_error,
|
|
1483
|
-
gripper.max_jaw_width,
|
|
1484
1483
|
gripper.min_jaw_width,
|
|
1484
|
+
gripper.max_jaw_width,
|
|
1485
1485
|
)
|
|
1486
1486
|
|
|
1487
1487
|
def gripper_jaw_can_home(self) -> bool:
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""The versions of standard liquid classes that the Protocol API should load by default."""
|
|
2
|
+
|
|
3
|
+
from typing import TypeAlias
|
|
4
|
+
from opentrons.protocols.api_support.types import APIVersion
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
DefaultLiquidClassVersions: TypeAlias = dict[APIVersion, dict[str, int]]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# This:
|
|
11
|
+
#
|
|
12
|
+
# {
|
|
13
|
+
# APIVersion(2, 100): {
|
|
14
|
+
# "foo_liquid": 3,
|
|
15
|
+
# },
|
|
16
|
+
# APIVersion(2, 105): {
|
|
17
|
+
# "foo_liquid": 7
|
|
18
|
+
# }
|
|
19
|
+
# }
|
|
20
|
+
#
|
|
21
|
+
# Means this:
|
|
22
|
+
#
|
|
23
|
+
# apiLevels name Default liquid class version
|
|
24
|
+
# ---------------------------------------------------------------
|
|
25
|
+
# <2.100 foo_liquid 1
|
|
26
|
+
# >=2.100,<2.105 foo_liquid 3
|
|
27
|
+
# >=2.105 foo_liquid 7
|
|
28
|
+
# [any] [anything else] 1
|
|
29
|
+
DEFAULT_LIQUID_CLASS_VERSIONS: DefaultLiquidClassVersions = {
|
|
30
|
+
APIVersion(2, 26): {
|
|
31
|
+
"water": 2,
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_liquid_class_version(
|
|
37
|
+
api_version: APIVersion,
|
|
38
|
+
liquid_class_name: str,
|
|
39
|
+
) -> int:
|
|
40
|
+
"""Return what version of a liquid class the Protocol API should load by default."""
|
|
41
|
+
default_lc_versions_newest_to_oldest = sorted(
|
|
42
|
+
DEFAULT_LIQUID_CLASS_VERSIONS.items(), key=lambda kv: kv[0], reverse=True
|
|
43
|
+
)
|
|
44
|
+
for (
|
|
45
|
+
breakpoint_api_version,
|
|
46
|
+
breakpoint_liquid_class_versions,
|
|
47
|
+
) in default_lc_versions_newest_to_oldest:
|
|
48
|
+
if (
|
|
49
|
+
api_version >= breakpoint_api_version
|
|
50
|
+
and liquid_class_name in breakpoint_liquid_class_versions
|
|
51
|
+
):
|
|
52
|
+
return breakpoint_liquid_class_versions[liquid_class_name]
|
|
53
|
+
|
|
54
|
+
return 1
|
|
@@ -78,7 +78,12 @@ from .module_core import (
|
|
|
78
78
|
FlexStackerCore,
|
|
79
79
|
)
|
|
80
80
|
from .exceptions import InvalidModuleLocationError
|
|
81
|
-
from . import
|
|
81
|
+
from . import (
|
|
82
|
+
load_labware_params,
|
|
83
|
+
deck_conflict,
|
|
84
|
+
overlap_versions,
|
|
85
|
+
_default_liquid_class_versions,
|
|
86
|
+
)
|
|
82
87
|
from opentrons.protocol_engine.resources import labware_validation
|
|
83
88
|
|
|
84
89
|
if TYPE_CHECKING:
|
|
@@ -1068,8 +1073,12 @@ class ProtocolCore(
|
|
|
1068
1073
|
display_color=(liquid.displayColor.root if liquid.displayColor else None),
|
|
1069
1074
|
)
|
|
1070
1075
|
|
|
1071
|
-
def get_liquid_class(self, name: str, version: int) -> LiquidClass:
|
|
1076
|
+
def get_liquid_class(self, name: str, version: Optional[int]) -> LiquidClass:
|
|
1072
1077
|
"""Get an instance of a built-in liquid class."""
|
|
1078
|
+
if version is None:
|
|
1079
|
+
version = _default_liquid_class_versions.get_liquid_class_version(
|
|
1080
|
+
self._api_version, name
|
|
1081
|
+
)
|
|
1073
1082
|
try:
|
|
1074
1083
|
# Check if we have already loaded this liquid class' definition
|
|
1075
1084
|
liquid_class_def = self._liquid_class_def_cache[(name, version)]
|
|
@@ -599,7 +599,7 @@ class LegacyProtocolCore(
|
|
|
599
599
|
"""Define a liquid to load into a well."""
|
|
600
600
|
assert False, "define_liquid only supported on engine core"
|
|
601
601
|
|
|
602
|
-
def get_liquid_class(self, name: str, version: int) -> LiquidClass:
|
|
602
|
+
def get_liquid_class(self, name: str, version: Optional[int]) -> LiquidClass:
|
|
603
603
|
"""Get an instance of a built-in liquid class."""
|
|
604
604
|
assert False, "define_liquid_class is only supported on engine core"
|
|
605
605
|
|
|
@@ -297,7 +297,7 @@ class AbstractProtocol(
|
|
|
297
297
|
"""Define a liquid to load into a well."""
|
|
298
298
|
|
|
299
299
|
@abstractmethod
|
|
300
|
-
def get_liquid_class(self, name: str, version: int) -> LiquidClass:
|
|
300
|
+
def get_liquid_class(self, name: str, version: Optional[int]) -> LiquidClass:
|
|
301
301
|
"""Get an instance of a built-in liquid class."""
|
|
302
302
|
|
|
303
303
|
@abstractmethod
|
|
@@ -640,6 +640,9 @@ class Labware:
|
|
|
640
640
|
lid: Optional[str] = None,
|
|
641
641
|
namespace: Optional[str] = None,
|
|
642
642
|
version: Optional[int] = None,
|
|
643
|
+
*,
|
|
644
|
+
lid_namespace: Optional[str] = None,
|
|
645
|
+
lid_version: Optional[int] = None,
|
|
643
646
|
) -> Labware:
|
|
644
647
|
"""Load a compatible labware onto the labware using its load parameters.
|
|
645
648
|
|
|
@@ -650,6 +653,24 @@ class Labware:
|
|
|
650
653
|
|
|
651
654
|
:returns: The initialized and loaded labware object.
|
|
652
655
|
"""
|
|
656
|
+
if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
|
|
657
|
+
if lid_namespace is not None:
|
|
658
|
+
raise APIVersionError(
|
|
659
|
+
api_element="The `lid_namespace` parameter",
|
|
660
|
+
until_version=str(
|
|
661
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
662
|
+
),
|
|
663
|
+
current_version=str(self._api_version),
|
|
664
|
+
)
|
|
665
|
+
if lid_version is not None:
|
|
666
|
+
raise APIVersionError(
|
|
667
|
+
api_element="The `lid_version` parameter",
|
|
668
|
+
until_version=str(
|
|
669
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
670
|
+
),
|
|
671
|
+
current_version=str(self._api_version),
|
|
672
|
+
)
|
|
673
|
+
|
|
653
674
|
labware_core = self._protocol_core.load_labware(
|
|
654
675
|
load_name=name,
|
|
655
676
|
label=label,
|
|
@@ -674,11 +695,24 @@ class Labware:
|
|
|
674
695
|
until_version="2.23",
|
|
675
696
|
current_version=f"{self._api_version}",
|
|
676
697
|
)
|
|
698
|
+
if (
|
|
699
|
+
self._api_version
|
|
700
|
+
< validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
701
|
+
):
|
|
702
|
+
checked_lid_namespace = namespace
|
|
703
|
+
checked_lid_version = version
|
|
704
|
+
else:
|
|
705
|
+
# This is currently impossible to reach because of the
|
|
706
|
+
# `if self._api_version < validation.validation.LID_STACK_VERSION_GATE`
|
|
707
|
+
# check above. This is here for now in case that check is removed in
|
|
708
|
+
# the future, and for symmetry with the other labware load methods.
|
|
709
|
+
checked_lid_namespace = lid_namespace
|
|
710
|
+
checked_lid_version = lid_version
|
|
677
711
|
self._protocol_core.load_lid(
|
|
678
712
|
load_name=lid,
|
|
679
713
|
location=labware_core,
|
|
680
|
-
namespace=
|
|
681
|
-
version=
|
|
714
|
+
namespace=checked_lid_namespace,
|
|
715
|
+
version=checked_lid_version,
|
|
682
716
|
)
|
|
683
717
|
|
|
684
718
|
return labware
|
|
@@ -123,7 +123,7 @@ class ModuleContext(CommandPublisher):
|
|
|
123
123
|
|
|
124
124
|
return core.geometry.add_labware(labware)
|
|
125
125
|
|
|
126
|
-
def load_labware(
|
|
126
|
+
def load_labware( # noqa: C901
|
|
127
127
|
self,
|
|
128
128
|
name: str,
|
|
129
129
|
label: Optional[str] = None,
|
|
@@ -131,6 +131,11 @@ class ModuleContext(CommandPublisher):
|
|
|
131
131
|
version: Optional[int] = None,
|
|
132
132
|
adapter: Optional[str] = None,
|
|
133
133
|
lid: Optional[str] = None,
|
|
134
|
+
*,
|
|
135
|
+
adapter_namespace: Optional[str] = None,
|
|
136
|
+
adapter_version: Optional[int] = None,
|
|
137
|
+
lid_namespace: Optional[str] = None,
|
|
138
|
+
lid_version: Optional[int] = None,
|
|
134
139
|
) -> Labware:
|
|
135
140
|
"""Load a labware onto the module using its load parameters.
|
|
136
141
|
|
|
@@ -142,7 +147,11 @@ class ModuleContext(CommandPublisher):
|
|
|
142
147
|
:returns: The initialized and loaded labware object.
|
|
143
148
|
|
|
144
149
|
.. versionadded:: 2.1
|
|
145
|
-
The
|
|
150
|
+
The ``label``, ``namespace``, and ``version`` parameters.
|
|
151
|
+
|
|
152
|
+
.. versionadded:: 2.26
|
|
153
|
+
The ``adapter_namespace``, ``adapter_version``,
|
|
154
|
+
``lid_namespace``, and ``lid_version`` parameters.
|
|
146
155
|
"""
|
|
147
156
|
if self._api_version < APIVersion(2, 1) and (
|
|
148
157
|
label is not None or namespace is not None or version != 1
|
|
@@ -152,6 +161,40 @@ class ModuleContext(CommandPublisher):
|
|
|
152
161
|
"are trying to utilize new load_labware parameters in 2.1"
|
|
153
162
|
)
|
|
154
163
|
|
|
164
|
+
if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
|
|
165
|
+
if adapter_namespace is not None:
|
|
166
|
+
raise APIVersionError(
|
|
167
|
+
api_element="The `adapter_namespace` parameter",
|
|
168
|
+
until_version=str(
|
|
169
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
170
|
+
),
|
|
171
|
+
current_version=str(self._api_version),
|
|
172
|
+
)
|
|
173
|
+
if adapter_version is not None:
|
|
174
|
+
raise APIVersionError(
|
|
175
|
+
api_element="The `adapter_version` parameter",
|
|
176
|
+
until_version=str(
|
|
177
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
178
|
+
),
|
|
179
|
+
current_version=str(self._api_version),
|
|
180
|
+
)
|
|
181
|
+
if lid_namespace is not None:
|
|
182
|
+
raise APIVersionError(
|
|
183
|
+
api_element="The `lid_namespace` parameter",
|
|
184
|
+
until_version=str(
|
|
185
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
186
|
+
),
|
|
187
|
+
current_version=str(self._api_version),
|
|
188
|
+
)
|
|
189
|
+
if lid_version is not None:
|
|
190
|
+
raise APIVersionError(
|
|
191
|
+
api_element="The `lid_version` parameter",
|
|
192
|
+
until_version=str(
|
|
193
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
194
|
+
),
|
|
195
|
+
current_version=str(self._api_version),
|
|
196
|
+
)
|
|
197
|
+
|
|
155
198
|
load_location: Union[ModuleCore, LabwareCore]
|
|
156
199
|
if adapter is not None:
|
|
157
200
|
if self._api_version < APIVersion(2, 15):
|
|
@@ -160,9 +203,21 @@ class ModuleContext(CommandPublisher):
|
|
|
160
203
|
until_version="2.15",
|
|
161
204
|
current_version=f"{self._api_version}",
|
|
162
205
|
)
|
|
206
|
+
|
|
207
|
+
if (
|
|
208
|
+
self._api_version
|
|
209
|
+
< validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
210
|
+
):
|
|
211
|
+
checked_adapter_namespace = namespace
|
|
212
|
+
checked_adapter_version = None
|
|
213
|
+
else:
|
|
214
|
+
checked_adapter_namespace = adapter_namespace
|
|
215
|
+
checked_adapter_version = adapter_version
|
|
216
|
+
|
|
163
217
|
loaded_adapter = self.load_adapter(
|
|
164
218
|
name=adapter,
|
|
165
|
-
namespace=
|
|
219
|
+
namespace=checked_adapter_namespace,
|
|
220
|
+
version=checked_adapter_version,
|
|
166
221
|
)
|
|
167
222
|
load_location = loaded_adapter._core
|
|
168
223
|
else:
|
|
@@ -193,11 +248,22 @@ class ModuleContext(CommandPublisher):
|
|
|
193
248
|
until_version="2.23",
|
|
194
249
|
current_version=f"{self._api_version}",
|
|
195
250
|
)
|
|
251
|
+
|
|
252
|
+
if (
|
|
253
|
+
self._api_version
|
|
254
|
+
< validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
255
|
+
):
|
|
256
|
+
checked_lid_namespace = namespace
|
|
257
|
+
checked_lid_version = None
|
|
258
|
+
else:
|
|
259
|
+
checked_lid_namespace = lid_namespace
|
|
260
|
+
checked_lid_version = lid_version
|
|
261
|
+
|
|
196
262
|
self._protocol_core.load_lid(
|
|
197
263
|
load_name=lid,
|
|
198
264
|
location=labware_core,
|
|
199
|
-
namespace=
|
|
200
|
-
version=
|
|
265
|
+
namespace=checked_lid_namespace,
|
|
266
|
+
version=checked_lid_version,
|
|
201
267
|
)
|
|
202
268
|
|
|
203
269
|
if isinstance(self._core, LegacyModuleCore):
|
|
@@ -1330,6 +1396,11 @@ class FlexStackerContext(ModuleContext):
|
|
|
1330
1396
|
lid: str | None = None,
|
|
1331
1397
|
count: int | None = None,
|
|
1332
1398
|
stacking_offset_z: float | None = None,
|
|
1399
|
+
*,
|
|
1400
|
+
adapter_namespace: str | None = None,
|
|
1401
|
+
adapter_version: int | None = None,
|
|
1402
|
+
lid_namespace: str | None = None,
|
|
1403
|
+
lid_version: int | None = None,
|
|
1333
1404
|
) -> None:
|
|
1334
1405
|
"""Configure the type and starting quantity of labware the Flex Stacker will store during a protocol. This is the only type of labware you'll be able to store in the Stacker until it's reconfigured.
|
|
1335
1406
|
|
|
@@ -1338,6 +1409,7 @@ class FlexStackerContext(ModuleContext):
|
|
|
1338
1409
|
:param str load_name: A string to use for looking up a labware definition.
|
|
1339
1410
|
You can find the ``load_name`` for any Opentrons-verified labware on the
|
|
1340
1411
|
`Labware Library <https://labware.opentrons.com>`__.
|
|
1412
|
+
|
|
1341
1413
|
:param str namespace: The namespace that the labware definition belongs to.
|
|
1342
1414
|
If unspecified, the API will automatically search two namespaces:
|
|
1343
1415
|
|
|
@@ -1348,19 +1420,34 @@ class FlexStackerContext(ModuleContext):
|
|
|
1348
1420
|
You might need to specify an explicit ``namespace`` if you have a custom
|
|
1349
1421
|
definition whose ``load_name`` is the same as an Opentrons-verified
|
|
1350
1422
|
definition, and you want to explicitly choose one or the other.
|
|
1423
|
+
|
|
1351
1424
|
:param version: The version of the labware definition. You should normally
|
|
1352
1425
|
leave this unspecified to let the method choose a version
|
|
1353
1426
|
automatically.
|
|
1427
|
+
|
|
1354
1428
|
:param adapter: An adapter to load the labware on top of. Accepts the same
|
|
1355
|
-
values as the ``load_name`` parameter of :py:meth:`.load_adapter`.
|
|
1356
|
-
|
|
1357
|
-
|
|
1429
|
+
values as the ``load_name`` parameter of :py:meth:`.load_adapter`.
|
|
1430
|
+
|
|
1431
|
+
:param adapter_namespace: Applies to ``adapter`` the same way that ``namespace``
|
|
1432
|
+
applies to ``load_name``.
|
|
1433
|
+
|
|
1434
|
+
:param adapter_version: Applies to ``adapter`` the same way that ``version``
|
|
1435
|
+
applies to ``load_name``.
|
|
1436
|
+
|
|
1358
1437
|
:param lid: A lid to load the on top of the main labware. Accepts the same
|
|
1359
1438
|
values as the ``load_name`` parameter of :py:meth:`~.ProtocolContext.load_lid_stack`. The
|
|
1360
1439
|
lid will use the same namespace as the labware, and the API will
|
|
1361
1440
|
choose the lid's version automatically.
|
|
1441
|
+
|
|
1442
|
+
:param lid_namespace: Applies to ``lid`` the same way that ``namespace``
|
|
1443
|
+
applies to ``load_name``.
|
|
1444
|
+
|
|
1445
|
+
:param lid_version: Applies to ``lid`` the same way that ``version``
|
|
1446
|
+
applies to ``load_name``.
|
|
1447
|
+
|
|
1362
1448
|
:param count: The number of labware that the Flex Stacker should store. If not specified, this will be the maximum amount of this kind of
|
|
1363
1449
|
labware that the Flex Stacker is capable of storing.
|
|
1450
|
+
|
|
1364
1451
|
:param stacking_offset_z: Stacking ``z`` offset in mm of stored labware. If specified, this overrides the
|
|
1365
1452
|
calculated value in the labware definition.
|
|
1366
1453
|
|
|
@@ -1378,18 +1465,18 @@ class FlexStackerContext(ModuleContext):
|
|
|
1378
1465
|
- Labware on adapter: the adapter (bottom side) of the upper labware unit overlaps with the top side of the labware below.
|
|
1379
1466
|
- Labware with lid: the labware (bottom side) of the upper labware unit overlaps with the lid (top side) of the unit below.
|
|
1380
1467
|
- Labware with lid and adapter: the adapter (bottom side) of the upper labware unit overlaps with the lid (top side) of the unit below.
|
|
1381
|
-
|
|
1382
1468
|
"""
|
|
1469
|
+
|
|
1383
1470
|
self._core.set_stored_labware(
|
|
1384
1471
|
main_load_name=load_name,
|
|
1385
1472
|
main_namespace=namespace,
|
|
1386
1473
|
main_version=version,
|
|
1387
1474
|
lid_load_name=lid,
|
|
1388
|
-
lid_namespace=
|
|
1389
|
-
lid_version=
|
|
1475
|
+
lid_namespace=lid_namespace,
|
|
1476
|
+
lid_version=lid_version,
|
|
1390
1477
|
adapter_load_name=adapter,
|
|
1391
|
-
adapter_namespace=
|
|
1392
|
-
adapter_version=
|
|
1478
|
+
adapter_namespace=adapter_namespace,
|
|
1479
|
+
adapter_version=adapter_version,
|
|
1393
1480
|
count=count,
|
|
1394
1481
|
stacking_offset_z=stacking_offset_z,
|
|
1395
1482
|
)
|
|
@@ -405,7 +405,7 @@ class ProtocolContext(CommandPublisher):
|
|
|
405
405
|
)
|
|
406
406
|
|
|
407
407
|
@requires_version(2, 0)
|
|
408
|
-
def load_labware(
|
|
408
|
+
def load_labware( # noqa: C901
|
|
409
409
|
self,
|
|
410
410
|
load_name: str,
|
|
411
411
|
location: Union[DeckLocation, OffDeckType],
|
|
@@ -414,6 +414,11 @@ class ProtocolContext(CommandPublisher):
|
|
|
414
414
|
version: Optional[int] = None,
|
|
415
415
|
adapter: Optional[str] = None,
|
|
416
416
|
lid: Optional[str] = None,
|
|
417
|
+
*,
|
|
418
|
+
adapter_namespace: Optional[str] = None,
|
|
419
|
+
adapter_version: Optional[int] = None,
|
|
420
|
+
lid_namespace: Optional[str] = None,
|
|
421
|
+
lid_version: Optional[int] = None,
|
|
417
422
|
) -> Labware:
|
|
418
423
|
"""Load a labware onto a location.
|
|
419
424
|
|
|
@@ -454,18 +459,52 @@ class ProtocolContext(CommandPublisher):
|
|
|
454
459
|
:param version: The version of the labware definition. You should normally
|
|
455
460
|
leave this unspecified to let ``load_labware()`` choose a version
|
|
456
461
|
automatically.
|
|
457
|
-
:param adapter: An adapter to load the labware on top of. Accepts the same
|
|
458
|
-
values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
|
|
459
|
-
adapter will use the same namespace as the labware, and the API will
|
|
460
|
-
choose the adapter's version automatically.
|
|
461
462
|
|
|
462
|
-
|
|
463
|
+
:param adapter: The load name of an adapter to load the labware on top of. Accepts
|
|
464
|
+
the same values as the ``load_name`` parameter of :py:meth:`.load_adapter`.
|
|
465
|
+
|
|
466
|
+
.. versionadded:: 2.15
|
|
467
|
+
|
|
468
|
+
:param adapter_namespace: The namespace of the adapter being loaded.
|
|
469
|
+
Applies to ``adapter`` the same way that ``namespace`` applies to ``load_name``.
|
|
470
|
+
|
|
471
|
+
.. versionchanged:: 2.26
|
|
472
|
+
``adapter_namespace`` may now be specified explicitly.
|
|
473
|
+
Also, when you've specified ``namespace`` but not ``adapter_namespace``,
|
|
474
|
+
``adapter_namespace`` will now independently follow the same search rules
|
|
475
|
+
described in ``namespace``. Formerly, it took ``namespace``'s exact value.
|
|
476
|
+
|
|
477
|
+
:param adapter_version: The version of the adapter being loaded.
|
|
478
|
+
Applies to ``adapter`` the same way that ``version`` applies to ``load_name``.
|
|
479
|
+
|
|
480
|
+
.. versionchanged:: 2.26
|
|
481
|
+
``adapter_version`` may now be specified explicitly. Also, when it's unspecified,
|
|
482
|
+
the algorithm to select a version automatically has improved to avoid
|
|
483
|
+
selecting versions that do not exist.
|
|
484
|
+
|
|
463
485
|
:param lid: A lid to load on the top of the main labware. Accepts the same
|
|
464
486
|
values as the ``load_name`` parameter of :py:meth:`.load_lid_stack`. The
|
|
465
487
|
lid will use the same namespace as the labware, and the API will
|
|
466
488
|
choose the lid's version automatically.
|
|
467
489
|
|
|
468
|
-
|
|
490
|
+
.. versionadded:: 2.23
|
|
491
|
+
|
|
492
|
+
:param lid_namespace: The namespace of the lid being loaded.
|
|
493
|
+
Applies to ``lid`` the same way that ``namespace`` applies to ``load_name``.
|
|
494
|
+
|
|
495
|
+
.. versionchanged:: 2.26
|
|
496
|
+
``lid_namespace`` may now be specified explicitly.
|
|
497
|
+
Also, when you've specified ``namespace`` but not ``lid_namespace``,
|
|
498
|
+
``lid_namespace`` will now independently follow the same search rules
|
|
499
|
+
described in ``namespace``. Formerly, it took ``namespace``'s exact value.
|
|
500
|
+
|
|
501
|
+
:param lid_version: The version of the adapter being loaded.
|
|
502
|
+
Applies to ``lid`` the same way that ``version`` applies to ``load_name``.
|
|
503
|
+
|
|
504
|
+
.. versionchanged:: 2.26
|
|
505
|
+
``lid_version`` may now be specified explicitly. Also, when it's unspecified,
|
|
506
|
+
the algorithm to select a version automatically has improved to avoid
|
|
507
|
+
selecting versions that do not exist.
|
|
469
508
|
"""
|
|
470
509
|
|
|
471
510
|
if isinstance(location, OffDeckType) and self._api_version < APIVersion(2, 15):
|
|
@@ -475,6 +514,40 @@ class ProtocolContext(CommandPublisher):
|
|
|
475
514
|
current_version=f"{self._api_version}",
|
|
476
515
|
)
|
|
477
516
|
|
|
517
|
+
if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
|
|
518
|
+
if adapter_namespace is not None:
|
|
519
|
+
raise APIVersionError(
|
|
520
|
+
api_element="The `adapter_namespace` parameter",
|
|
521
|
+
until_version=str(
|
|
522
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
523
|
+
),
|
|
524
|
+
current_version=str(self._api_version),
|
|
525
|
+
)
|
|
526
|
+
if adapter_version is not None:
|
|
527
|
+
raise APIVersionError(
|
|
528
|
+
api_element="The `adapter_version` parameter",
|
|
529
|
+
until_version=str(
|
|
530
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
531
|
+
),
|
|
532
|
+
current_version=str(self._api_version),
|
|
533
|
+
)
|
|
534
|
+
if lid_namespace is not None:
|
|
535
|
+
raise APIVersionError(
|
|
536
|
+
api_element="The `lid_namespace` parameter",
|
|
537
|
+
until_version=str(
|
|
538
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
539
|
+
),
|
|
540
|
+
current_version=str(self._api_version),
|
|
541
|
+
)
|
|
542
|
+
if lid_version is not None:
|
|
543
|
+
raise APIVersionError(
|
|
544
|
+
api_element="The `lid_version` parameter",
|
|
545
|
+
until_version=str(
|
|
546
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
547
|
+
),
|
|
548
|
+
current_version=str(self._api_version),
|
|
549
|
+
)
|
|
550
|
+
|
|
478
551
|
load_name = validation.ensure_lowercase_name(load_name)
|
|
479
552
|
load_location: Union[OffDeckType, DeckSlotName, StagingSlotName, LabwareCore]
|
|
480
553
|
if adapter is not None:
|
|
@@ -484,10 +557,22 @@ class ProtocolContext(CommandPublisher):
|
|
|
484
557
|
until_version="2.15",
|
|
485
558
|
current_version=f"{self._api_version}",
|
|
486
559
|
)
|
|
560
|
+
|
|
561
|
+
if (
|
|
562
|
+
self._api_version
|
|
563
|
+
< validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
564
|
+
):
|
|
565
|
+
checked_adapter_namespace = namespace
|
|
566
|
+
checked_adapter_version = None
|
|
567
|
+
else:
|
|
568
|
+
checked_adapter_namespace = adapter_namespace
|
|
569
|
+
checked_adapter_version = adapter_version
|
|
570
|
+
|
|
487
571
|
loaded_adapter = self.load_adapter(
|
|
488
572
|
load_name=adapter,
|
|
489
573
|
location=location,
|
|
490
|
-
namespace=
|
|
574
|
+
namespace=checked_adapter_namespace,
|
|
575
|
+
version=checked_adapter_version,
|
|
491
576
|
)
|
|
492
577
|
load_location = loaded_adapter._core
|
|
493
578
|
elif isinstance(location, OffDeckType):
|
|
@@ -512,11 +597,22 @@ class ProtocolContext(CommandPublisher):
|
|
|
512
597
|
until_version=f"{validation.LID_STACK_VERSION_GATE}",
|
|
513
598
|
current_version=f"{self._api_version}",
|
|
514
599
|
)
|
|
600
|
+
|
|
601
|
+
if (
|
|
602
|
+
self._api_version
|
|
603
|
+
< validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
604
|
+
):
|
|
605
|
+
checked_lid_namespace = namespace
|
|
606
|
+
checked_lid_version = version
|
|
607
|
+
else:
|
|
608
|
+
checked_lid_namespace = lid_namespace
|
|
609
|
+
checked_lid_version = lid_version
|
|
610
|
+
|
|
515
611
|
self._core.load_lid(
|
|
516
612
|
load_name=lid,
|
|
517
613
|
location=labware_core,
|
|
518
|
-
namespace=
|
|
519
|
-
version=
|
|
614
|
+
namespace=checked_lid_namespace,
|
|
615
|
+
version=checked_lid_version,
|
|
520
616
|
)
|
|
521
617
|
|
|
522
618
|
labware = Labware(
|
|
@@ -1377,6 +1473,7 @@ class ProtocolContext(CommandPublisher):
|
|
|
1377
1473
|
def get_liquid_class(
|
|
1378
1474
|
self,
|
|
1379
1475
|
name: str,
|
|
1476
|
+
version: Optional[int] = None,
|
|
1380
1477
|
) -> LiquidClass:
|
|
1381
1478
|
"""
|
|
1382
1479
|
Get an instance of an Opentrons-verified liquid class for use in a Flex protocol.
|
|
@@ -1386,12 +1483,14 @@ class ProtocolContext(CommandPublisher):
|
|
|
1386
1483
|
- ``"water"``: an Opentrons-verified liquid class based on deionized water.
|
|
1387
1484
|
- ``"glycerol_50"``: an Opentrons-verified liquid class for viscous liquid. Based on 50% glycerol.
|
|
1388
1485
|
- ``"ethanol_80"``: an Opentrons-verified liquid class for volatile liquid. Based on 80% ethanol.
|
|
1486
|
+
:param version: The version of the liquid class to retrieve. If left unspecified, the latest definition for the
|
|
1487
|
+
protocol's API version will be loaded.
|
|
1389
1488
|
|
|
1390
1489
|
:raises: ``LiquidClassDefinitionDoesNotExist``: if the specified liquid class does not exist.
|
|
1391
1490
|
|
|
1392
1491
|
:returns: A new LiquidClass object.
|
|
1393
1492
|
"""
|
|
1394
|
-
return self._core.get_liquid_class(name=name, version=
|
|
1493
|
+
return self._core.get_liquid_class(name=name, version=version)
|
|
1395
1494
|
|
|
1396
1495
|
@requires_version(2, 24)
|
|
1397
1496
|
def define_liquid_class(
|
|
@@ -1461,6 +1560,9 @@ class ProtocolContext(CommandPublisher):
|
|
|
1461
1560
|
adapter: Optional[str] = None,
|
|
1462
1561
|
namespace: Optional[str] = None,
|
|
1463
1562
|
version: Optional[int] = None,
|
|
1563
|
+
*,
|
|
1564
|
+
adapter_namespace: Optional[str] = None,
|
|
1565
|
+
adapter_version: Optional[int] = None,
|
|
1464
1566
|
) -> Labware:
|
|
1465
1567
|
"""
|
|
1466
1568
|
Load a stack of Opentrons Tough Auto-Sealing Lids onto a valid deck location or adapter.
|
|
@@ -1468,13 +1570,17 @@ class ProtocolContext(CommandPublisher):
|
|
|
1468
1570
|
:param str load_name: A string to use for looking up a lid definition.
|
|
1469
1571
|
You can find the ``load_name`` for any compatible lid on the Opentrons
|
|
1470
1572
|
`Labware Library <https://labware.opentrons.com>`_.
|
|
1573
|
+
|
|
1471
1574
|
:param location: Either a :ref:`deck slot <deck-slots>`,
|
|
1472
1575
|
like ``1``, ``"1"``, or ``"D1"``, or a valid Opentrons Adapter.
|
|
1576
|
+
|
|
1473
1577
|
:param int quantity: The quantity of lids to be loaded in the stack.
|
|
1578
|
+
|
|
1474
1579
|
:param adapter: An adapter to load the lid stack on top of. Accepts the same
|
|
1475
1580
|
values as the ``load_name`` parameter of :py:meth:`.load_adapter`. The
|
|
1476
1581
|
adapter will use the same namespace as the lid labware, and the API will
|
|
1477
1582
|
choose the adapter's version automatically.
|
|
1583
|
+
|
|
1478
1584
|
:param str namespace: The namespace that the lid labware definition belongs to.
|
|
1479
1585
|
If unspecified, the API will automatically search two namespaces:
|
|
1480
1586
|
|
|
@@ -1490,6 +1596,21 @@ class ProtocolContext(CommandPublisher):
|
|
|
1490
1596
|
leave this unspecified to let ``load_lid_stack()`` choose a version
|
|
1491
1597
|
automatically.
|
|
1492
1598
|
|
|
1599
|
+
:param adapter_namespace: The namespace of the adapter being loaded.
|
|
1600
|
+
Applies to ``adapter`` the same way that ``namespace`` applies to ``load_name``.
|
|
1601
|
+
|
|
1602
|
+
.. versionchanged:: 2.26
|
|
1603
|
+
``adapter_namespace`` may now be specified explicitly.
|
|
1604
|
+
Also, when you've specified ``namespace`` but not ``adapter_namespace``,
|
|
1605
|
+
``adapter_namespace`` will now independently follow the same search rules
|
|
1606
|
+
described in ``namespace``. Formerly, it took ``namespace``'s exact value.
|
|
1607
|
+
|
|
1608
|
+
:param adapter_version: The version of the adapter being loaded.
|
|
1609
|
+
Applies to ``adapter`` the same way that ``version`` applies to ``load_name``.
|
|
1610
|
+
|
|
1611
|
+
.. versionadded:: 2.26
|
|
1612
|
+
``adapter_version`` may now be specified explicitly.
|
|
1613
|
+
|
|
1493
1614
|
:return: The initialized and loaded labware object representing the lid stack.
|
|
1494
1615
|
|
|
1495
1616
|
.. versionadded:: 2.23
|
|
@@ -1502,6 +1623,24 @@ class ProtocolContext(CommandPublisher):
|
|
|
1502
1623
|
current_version=f"{self._api_version}",
|
|
1503
1624
|
)
|
|
1504
1625
|
|
|
1626
|
+
if self._api_version < validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE:
|
|
1627
|
+
if adapter_namespace is not None:
|
|
1628
|
+
raise APIVersionError(
|
|
1629
|
+
api_element="The `adapter_namespace` parameter",
|
|
1630
|
+
until_version=str(
|
|
1631
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
1632
|
+
),
|
|
1633
|
+
current_version=str(self._api_version),
|
|
1634
|
+
)
|
|
1635
|
+
if adapter_version is not None:
|
|
1636
|
+
raise APIVersionError(
|
|
1637
|
+
api_element="The `adapter_version` parameter",
|
|
1638
|
+
until_version=str(
|
|
1639
|
+
validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
1640
|
+
),
|
|
1641
|
+
current_version=str(self._api_version),
|
|
1642
|
+
)
|
|
1643
|
+
|
|
1505
1644
|
load_location: Union[DeckSlotName, StagingSlotName, LabwareCore]
|
|
1506
1645
|
if isinstance(location, Labware):
|
|
1507
1646
|
load_location = location._core
|
|
@@ -1514,10 +1653,21 @@ class ProtocolContext(CommandPublisher):
|
|
|
1514
1653
|
if isinstance(load_location, DeckSlotName) or isinstance(
|
|
1515
1654
|
load_location, StagingSlotName
|
|
1516
1655
|
):
|
|
1656
|
+
if (
|
|
1657
|
+
self._api_version
|
|
1658
|
+
< validation.NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE
|
|
1659
|
+
):
|
|
1660
|
+
checked_adapter_namespace = namespace
|
|
1661
|
+
checked_adapter_version = None
|
|
1662
|
+
else:
|
|
1663
|
+
checked_adapter_namespace = adapter_namespace
|
|
1664
|
+
checked_adapter_version = adapter_version
|
|
1665
|
+
|
|
1517
1666
|
loaded_adapter = self.load_adapter(
|
|
1518
1667
|
load_name=adapter,
|
|
1519
1668
|
location=load_location.value,
|
|
1520
|
-
namespace=
|
|
1669
|
+
namespace=checked_adapter_namespace,
|
|
1670
|
+
version=checked_adapter_version,
|
|
1521
1671
|
)
|
|
1522
1672
|
load_location = loaded_adapter._core
|
|
1523
1673
|
else:
|
|
@@ -62,6 +62,10 @@ LID_STACK_VERSION_GATE = APIVersion(2, 23)
|
|
|
62
62
|
# The first APIVersion where Python protocols can use the Flex Stacker module.
|
|
63
63
|
FLEX_STACKER_VERSION_GATE = APIVersion(2, 23)
|
|
64
64
|
|
|
65
|
+
# The first APIVersion where various "multi labware load" methods allow you to specify
|
|
66
|
+
# the namespace and version of adapters and lids separately from the main labware.
|
|
67
|
+
NAMESPACE_VERSION_ADAPTER_LID_VERSION_GATE = APIVersion(2, 26)
|
|
68
|
+
|
|
65
69
|
|
|
66
70
|
class InvalidPipetteMountError(ValueError):
|
|
67
71
|
"""An error raised when attempting to load pipettes on an invalid mount."""
|
|
@@ -20,6 +20,7 @@ from .flex_stacker.common import (
|
|
|
20
20
|
FlexStackerHopperError,
|
|
21
21
|
FlexStackerLabwareRetrieveError,
|
|
22
22
|
FlexStackerShuttleOccupiedError,
|
|
23
|
+
FlexStackerLabwareStoreError,
|
|
23
24
|
)
|
|
24
25
|
|
|
25
26
|
from . import absorbance_reader
|
|
@@ -948,6 +949,7 @@ CommandDefinedErrorData = Union[
|
|
|
948
949
|
DefinedErrorData[FlexStackerHopperError],
|
|
949
950
|
DefinedErrorData[FlexStackerLabwareRetrieveError],
|
|
950
951
|
DefinedErrorData[FlexStackerShuttleOccupiedError],
|
|
952
|
+
DefinedErrorData[FlexStackerLabwareStoreError],
|
|
951
953
|
]
|
|
952
954
|
|
|
953
955
|
|
|
@@ -148,6 +148,19 @@ class FlexStackerLabwareRetrieveError(ErrorOccurrence):
|
|
|
148
148
|
errorInfo: FailedLabware
|
|
149
149
|
|
|
150
150
|
|
|
151
|
+
class FlexStackerLabwareStoreError(ErrorOccurrence):
|
|
152
|
+
"""Returned when the labware was not able to get to the shuttle."""
|
|
153
|
+
|
|
154
|
+
isDefined: bool = True
|
|
155
|
+
errorType: Literal[
|
|
156
|
+
"flexStackerLabwareStoreFailed"
|
|
157
|
+
] = "flexStackerLabwareStoreFailed"
|
|
158
|
+
|
|
159
|
+
errorCode: str = ErrorCodes.STACKER_SHUTTLE_LABWARE_FAILED.value.code
|
|
160
|
+
detail: str = ErrorCodes.STACKER_SHUTTLE_LABWARE_FAILED.value.detail
|
|
161
|
+
errorInfo: FailedLabware
|
|
162
|
+
|
|
163
|
+
|
|
151
164
|
class FlexStackerShuttleOccupiedError(ErrorOccurrence):
|
|
152
165
|
"""Returned when the Flex Stacker Shuttle is occupied when it shouldn't be."""
|
|
153
166
|
|
|
@@ -10,6 +10,7 @@ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
|
|
|
10
10
|
from opentrons_shared_data.errors.exceptions import (
|
|
11
11
|
FlexStackerStallError,
|
|
12
12
|
FlexStackerShuttleMissingError,
|
|
13
|
+
FlexStackerShuttleLabwareError,
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
from ..command import (
|
|
@@ -22,6 +23,7 @@ from ..command import (
|
|
|
22
23
|
from ..flex_stacker.common import (
|
|
23
24
|
FlexStackerStallOrCollisionError,
|
|
24
25
|
FlexStackerShuttleError,
|
|
26
|
+
FlexStackerLabwareStoreError,
|
|
25
27
|
labware_locations_for_group,
|
|
26
28
|
labware_location_base_sequence,
|
|
27
29
|
primary_location_sequence,
|
|
@@ -115,7 +117,8 @@ class StoreResult(BaseModel):
|
|
|
115
117
|
_ExecuteReturn = Union[
|
|
116
118
|
SuccessData[StoreResult],
|
|
117
119
|
DefinedErrorData[FlexStackerStallOrCollisionError]
|
|
118
|
-
| DefinedErrorData[FlexStackerShuttleError]
|
|
120
|
+
| DefinedErrorData[FlexStackerShuttleError]
|
|
121
|
+
| DefinedErrorData[FlexStackerLabwareStoreError],
|
|
119
122
|
]
|
|
120
123
|
|
|
121
124
|
|
|
@@ -180,7 +183,7 @@ class StoreImpl(AbstractCommandImpl[StoreParams, _ExecuteReturn]):
|
|
|
180
183
|
)
|
|
181
184
|
return labware_ids[0], None, lid_id
|
|
182
185
|
|
|
183
|
-
async def execute(self, params: StoreParams) -> _ExecuteReturn:
|
|
186
|
+
async def execute(self, params: StoreParams) -> _ExecuteReturn: # noqa: C901
|
|
184
187
|
"""Execute the labware storage command."""
|
|
185
188
|
stacker_state = self._state_view.modules.get_flex_stacker_substate(
|
|
186
189
|
params.moduleId
|
|
@@ -250,6 +253,21 @@ class StoreImpl(AbstractCommandImpl[StoreParams, _ExecuteReturn]):
|
|
|
250
253
|
errorInfo={"labwareId": primary_id},
|
|
251
254
|
),
|
|
252
255
|
)
|
|
256
|
+
except FlexStackerShuttleLabwareError as e:
|
|
257
|
+
return DefinedErrorData(
|
|
258
|
+
public=FlexStackerLabwareStoreError(
|
|
259
|
+
id=self._model_utils.generate_id(),
|
|
260
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
261
|
+
wrappedErrors=[
|
|
262
|
+
ErrorOccurrence.from_failed(
|
|
263
|
+
id=self._model_utils.generate_id(),
|
|
264
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
265
|
+
error=e,
|
|
266
|
+
)
|
|
267
|
+
],
|
|
268
|
+
errorInfo={"labwareId": primary_id},
|
|
269
|
+
),
|
|
270
|
+
)
|
|
253
271
|
|
|
254
272
|
id_list = [
|
|
255
273
|
id for id in (primary_id, maybe_adapter_id, maybe_lid_id) if id is not None
|
|
@@ -234,23 +234,17 @@ class LabwareMovementHandler:
|
|
|
234
234
|
# we only want to check position after the gripper has opened and
|
|
235
235
|
# should be holding labware
|
|
236
236
|
if holding_labware:
|
|
237
|
-
|
|
238
|
-
labware_definition=labware_definition
|
|
239
|
-
)
|
|
240
|
-
well_bbox = self._state_store.labware.get_well_bbox(
|
|
237
|
+
grip_specs = self._state_store.labware.get_gripper_width_specs(
|
|
241
238
|
labware_definition=labware_definition
|
|
242
239
|
)
|
|
240
|
+
|
|
243
241
|
# todo(mm, 2024-09-26): This currently raises a lower-level 2015 FailedGripperPickupError.
|
|
244
242
|
# Convert this to a higher-level 3001 LabwareDroppedError or 3002 LabwareNotPickedUpError,
|
|
245
243
|
# depending on what waypoint we're at, to propagate a more specific error code to users.
|
|
246
244
|
ot3api.raise_error_if_gripper_pickup_failed(
|
|
247
|
-
expected_grip_width=
|
|
248
|
-
grip_width_uncertainty_wider=
|
|
249
|
-
|
|
250
|
-
),
|
|
251
|
-
grip_width_uncertainty_narrower=abs(
|
|
252
|
-
min(well_bbox.y - labware_bbox.y, 0)
|
|
253
|
-
),
|
|
245
|
+
expected_grip_width=grip_specs.targetY,
|
|
246
|
+
grip_width_uncertainty_wider=grip_specs.uncertaintyWider,
|
|
247
|
+
grip_width_uncertainty_narrower=grip_specs.uncertaintyNarrower,
|
|
254
248
|
)
|
|
255
249
|
await ot3api.move_to(
|
|
256
250
|
mount=gripper_mount, abs_position=waypoint_data.position
|
|
@@ -46,6 +46,7 @@ from ..types import (
|
|
|
46
46
|
AddressableAreaLocation,
|
|
47
47
|
NonStackedLocation,
|
|
48
48
|
Dimensions,
|
|
49
|
+
GripSpecs,
|
|
49
50
|
LabwareOffset,
|
|
50
51
|
LabwareOffsetVector,
|
|
51
52
|
LabwareOffsetLocationSequence,
|
|
@@ -1430,3 +1431,68 @@ class LabwareView:
|
|
|
1430
1431
|
):
|
|
1431
1432
|
return Dimensions(0, 0, 0)
|
|
1432
1433
|
return Dimensions(max_x - min_x, max_y - min_y, max_z)
|
|
1434
|
+
|
|
1435
|
+
def _gripper_uncertainty_narrower(
|
|
1436
|
+
self, labware_bbox: Dimensions, well_bbox: Dimensions, target_grip_width: float
|
|
1437
|
+
) -> float:
|
|
1438
|
+
"""Most narrower the gripper can be than the target while still likely gripping successfully.
|
|
1439
|
+
|
|
1440
|
+
This number can't just be the 0, because that is not going to be accurate if the labware is
|
|
1441
|
+
skirted - the dimensions are a full bounding box including the skirt, and the labware is
|
|
1442
|
+
narrower than that at the point where it is gripped. The general heuristic is that we can't
|
|
1443
|
+
get to the wells; but some labware don't have wells, so we need alternate values.
|
|
1444
|
+
|
|
1445
|
+
The number will be interpreted relative to the target width, which is (for now) the labware
|
|
1446
|
+
outer bounding box.
|
|
1447
|
+
|
|
1448
|
+
TODO: This should be a number looked up from the definition.
|
|
1449
|
+
"""
|
|
1450
|
+
if well_bbox.y == 0:
|
|
1451
|
+
# This labware has no wells; use a fixed minimum
|
|
1452
|
+
return 5
|
|
1453
|
+
if well_bbox.y > labware_bbox.y:
|
|
1454
|
+
# This labware has a very odd definition with wells outside its dimensions.
|
|
1455
|
+
# Return the smaller value.
|
|
1456
|
+
return 0
|
|
1457
|
+
# An ok heuristic for successful grip is if we don't get all the way to the wells.
|
|
1458
|
+
return target_grip_width - well_bbox.y
|
|
1459
|
+
|
|
1460
|
+
def _gripper_uncertainty_wider(
|
|
1461
|
+
self, labware_bbox: Dimensions, well_bbox: Dimensions, target_grip_width: float
|
|
1462
|
+
) -> float:
|
|
1463
|
+
"""Most wider the gripper can be than the target while still likely gripping successfully.
|
|
1464
|
+
|
|
1465
|
+
This can be a lot closer to 0, since the bounding box of the labware will certainly be the
|
|
1466
|
+
widest point (if it's defined without error), but since there might be error in the
|
|
1467
|
+
definition we allow some slop.
|
|
1468
|
+
|
|
1469
|
+
The number will be interpreted relative to the target width, which is (for now) the labware
|
|
1470
|
+
outer bounding box.
|
|
1471
|
+
|
|
1472
|
+
TODO: This should be a number looked up from the definition.
|
|
1473
|
+
"""
|
|
1474
|
+
# This will be 0 unless the wells are wider than the labware
|
|
1475
|
+
return max(well_bbox.y - target_grip_width, 0)
|
|
1476
|
+
|
|
1477
|
+
def get_gripper_width_specs(
|
|
1478
|
+
self, labware_definition: LabwareDefinition
|
|
1479
|
+
) -> GripSpecs:
|
|
1480
|
+
"""Get the target and bounds for a successful grip of this labware."""
|
|
1481
|
+
outer_bounds = self.get_dimensions(labware_definition=labware_definition)
|
|
1482
|
+
well_bounds = self.get_well_bbox(labware_definition=labware_definition)
|
|
1483
|
+
narrower = self._gripper_uncertainty_narrower(
|
|
1484
|
+
labware_bbox=outer_bounds,
|
|
1485
|
+
well_bbox=well_bounds,
|
|
1486
|
+
target_grip_width=outer_bounds.y,
|
|
1487
|
+
)
|
|
1488
|
+
wider = self._gripper_uncertainty_wider(
|
|
1489
|
+
labware_bbox=outer_bounds,
|
|
1490
|
+
well_bbox=well_bounds,
|
|
1491
|
+
target_grip_width=outer_bounds.y,
|
|
1492
|
+
)
|
|
1493
|
+
return GripSpecs(
|
|
1494
|
+
# TODO: This should be a number looked up from the definition.
|
|
1495
|
+
targetY=outer_bounds.y,
|
|
1496
|
+
uncertaintyNarrower=narrower,
|
|
1497
|
+
uncertaintyWider=wider,
|
|
1498
|
+
)
|
|
@@ -102,6 +102,7 @@ from .labware import (
|
|
|
102
102
|
LoadedLabware,
|
|
103
103
|
LabwareParentDefinition,
|
|
104
104
|
LabwareWellId,
|
|
105
|
+
GripSpecs,
|
|
105
106
|
)
|
|
106
107
|
from .liquid import HexColor, EmptyLiquidId, LiquidId, Liquid, FluidKind, AspiratedFluid
|
|
107
108
|
from .labware_offset_location import (
|
|
@@ -257,6 +258,7 @@ __all__ = [
|
|
|
257
258
|
"LabwareOffsetVector",
|
|
258
259
|
"LabwareParentDefinition",
|
|
259
260
|
"LabwareWellId",
|
|
261
|
+
"GripSpecs",
|
|
260
262
|
# Liquids
|
|
261
263
|
"HexColor",
|
|
262
264
|
"EmptyLiquidId",
|
|
@@ -23,6 +23,15 @@ from .module import ModuleDefinition
|
|
|
23
23
|
from .deck_configuration import DeckLocationDefinition
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class GripSpecs:
|
|
28
|
+
"""Data for how a labware should be gripped."""
|
|
29
|
+
|
|
30
|
+
uncertaintyWider: float
|
|
31
|
+
uncertaintyNarrower: float
|
|
32
|
+
targetY: float
|
|
33
|
+
|
|
34
|
+
|
|
26
35
|
class OverlapOffset(Vec3f):
|
|
27
36
|
"""Offset representing overlap space of one labware on top of another labware or module."""
|
|
28
37
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opentrons
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.7.0a0
|
|
4
4
|
Summary: The Opentrons API is a simple framework designed to make writing automated biology lab protocols easy.
|
|
5
5
|
Project-URL: opentrons.com, https://www.opentrons.com
|
|
6
6
|
Project-URL: Source Code On Github, https://github.com/Opentrons/opentrons/tree/edge/api
|
|
@@ -24,7 +24,7 @@ Requires-Dist: click<9,>=8.0.0
|
|
|
24
24
|
Requires-Dist: importlib-metadata>=1.0; python_version < '3.8'
|
|
25
25
|
Requires-Dist: jsonschema<4.18.0,>=3.0.1
|
|
26
26
|
Requires-Dist: numpy<2,>=1.20.0
|
|
27
|
-
Requires-Dist: opentrons-shared-data==8.
|
|
27
|
+
Requires-Dist: opentrons-shared-data==8.7.0a0
|
|
28
28
|
Requires-Dist: packaging>=21.0
|
|
29
29
|
Requires-Dist: pydantic-settings<3,>=2
|
|
30
30
|
Requires-Dist: pydantic<3,>=2.0.0
|
|
@@ -32,6 +32,6 @@ Requires-Dist: pyserial>=3.5
|
|
|
32
32
|
Requires-Dist: pyusb==1.2.1
|
|
33
33
|
Requires-Dist: typing-extensions<5,>=4.0.0
|
|
34
34
|
Provides-Extra: flex-hardware
|
|
35
|
-
Requires-Dist: opentrons-hardware[flex]==8.
|
|
35
|
+
Requires-Dist: opentrons-hardware[flex]==8.7.0a0; extra == 'flex-hardware'
|
|
36
36
|
Provides-Extra: ot2-hardware
|
|
37
|
-
Requires-Dist: opentrons-hardware==8.
|
|
37
|
+
Requires-Dist: opentrons-hardware==8.7.0a0; extra == 'ot2-hardware'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
opentrons/__init__.py,sha256=TQ_Ca_zzAM3iLzAysWKkFkQHG8-imihxDPQbLCYrf-E,4533
|
|
2
|
-
opentrons/_version.py,sha256=
|
|
2
|
+
opentrons/_version.py,sha256=d3ve2LJJuyjX8J_41fIn96U4XlDfRGAll6nNIi4dBwY,712
|
|
3
3
|
opentrons/execute.py,sha256=Y88qICDiHWQjU0L4Ou7DI5OXXu7zZcdkUvNUYmZqIfc,29282
|
|
4
4
|
opentrons/legacy_broker.py,sha256=XnuEBBlrHCThc31RFW2UR0tGqctqWZ-CZ9vSC4L9whU,1553
|
|
5
5
|
opentrons/ordered_set.py,sha256=g-SB3qA14yxHu9zjGyc2wC7d2TUCBE6fKZlHAtbPzI8,4082
|
|
@@ -105,7 +105,7 @@ opentrons/hardware_control/module_control.py,sha256=0mmVH9fiZWNyc33ilCpJHajX1Dfh
|
|
|
105
105
|
opentrons/hardware_control/motion_utilities.py,sha256=7VG60YQ9MSMAZ0hO-q-kRAdkcebzrx7uIPtc6FMCViE,10311
|
|
106
106
|
opentrons/hardware_control/nozzle_manager.py,sha256=dqD8XlYsOu0PFFyxvmsMypBB52Gi6x-VIwhykV7JhuU,16868
|
|
107
107
|
opentrons/hardware_control/ot3_calibration.py,sha256=vHB17U-FBzytvM8QeEu5kRYPo8lFwAo31ZEpiU4yf_0,45000
|
|
108
|
-
opentrons/hardware_control/ot3api.py,sha256=
|
|
108
|
+
opentrons/hardware_control/ot3api.py,sha256=1vPsaNPmtjsJI1EJF8JPKOd2Bj2GDJLvmKU8eMKGhi8,127869
|
|
109
109
|
opentrons/hardware_control/pause_manager.py,sha256=wmNmraimE2yZQVqCxX_rtQHUWRzpzyQEaym9fLMgyww,888
|
|
110
110
|
opentrons/hardware_control/poller.py,sha256=rx6Q-UxbUIj3ek69IlYenFh7BFuasszRO-GzzhRPuHQ,3885
|
|
111
111
|
opentrons/hardware_control/robot_calibration.py,sha256=ilszGjZPspKiEk8MQPaHm2B-ljeisAYflKl8UyQ_D0U,7155
|
|
@@ -119,8 +119,8 @@ opentrons/hardware_control/backends/controller.py,sha256=MOVMq9s1rY_jHhajHB1hQ1M
|
|
|
119
119
|
opentrons/hardware_control/backends/errors.py,sha256=ZiVP16exHMTWWOajxffnXEqI6NNfeTw-4RkhXE0EBJA,249
|
|
120
120
|
opentrons/hardware_control/backends/estop_state.py,sha256=_GYjI6OaD3CZNduWV2_RVeOtQ4K_Fg-SP8yU01ENhCY,6554
|
|
121
121
|
opentrons/hardware_control/backends/flex_protocol.py,sha256=3S-OHbAnOSTF5PxzhMxD0TdEfxurLwecBrDkedl2O3s,13185
|
|
122
|
-
opentrons/hardware_control/backends/ot3controller.py,sha256=
|
|
123
|
-
opentrons/hardware_control/backends/ot3simulator.py,sha256=
|
|
122
|
+
opentrons/hardware_control/backends/ot3controller.py,sha256=w0LMGu0WWkGd4cEWaqlhMk1NQFHg1-Di83s5_KrKP3U,71374
|
|
123
|
+
opentrons/hardware_control/backends/ot3simulator.py,sha256=CtYnb7NpqIc1TNK91hI0UaK4OyaIecFDczsb-T7DX_w,30387
|
|
124
124
|
opentrons/hardware_control/backends/ot3utils.py,sha256=HYlIZRGmLqudS1mIt0Io2LxQ1BrLrxVFQCjqudbTUWU,22374
|
|
125
125
|
opentrons/hardware_control/backends/simulator.py,sha256=q_9PQlBdOyCa9sj2gLqYWZ-fG9v4mddDAiScL-yHCXY,17549
|
|
126
126
|
opentrons/hardware_control/backends/status_bar_state.py,sha256=E8z9dCJDI3Nb4qfUA5y2_PrE2jSYzZJQVkk75UqY5ZE,9287
|
|
@@ -234,24 +234,25 @@ opentrons/protocol_api/create_protocol_context.py,sha256=wwsZje0L__oDnu1Yrihau32
|
|
|
234
234
|
opentrons/protocol_api/deck.py,sha256=94vFceg1SC1bAGd7TvC1ZpYwnJR-VlzurEZ6jkacYeg,8910
|
|
235
235
|
opentrons/protocol_api/disposal_locations.py,sha256=NRiSGmDR0LnbyEkWSOM-o64uR2fUoB1NWJG7Y7SsJSs,7920
|
|
236
236
|
opentrons/protocol_api/instrument_context.py,sha256=dOg04iqYnNMJ7XnlHBX3tTGiEahc-7feIuErcevRdwY,141216
|
|
237
|
-
opentrons/protocol_api/labware.py,sha256=
|
|
238
|
-
opentrons/protocol_api/module_contexts.py,sha256=
|
|
237
|
+
opentrons/protocol_api/labware.py,sha256=ZGukS0oE6vOltolNx9ZFXj_HFhm5BRaTnS0tJUKxGsE,63061
|
|
238
|
+
opentrons/protocol_api/module_contexts.py,sha256=cPyay45R3SeBckC4fk8txuC7DZoCSeoVSp1ALCMNipQ,63292
|
|
239
239
|
opentrons/protocol_api/module_validation_and_errors.py,sha256=ljst-M_KK78GnyG3pyZ_6yoYkMY3HORS1QyQyWrme-U,2250
|
|
240
|
-
opentrons/protocol_api/protocol_context.py,sha256=
|
|
240
|
+
opentrons/protocol_api/protocol_context.py,sha256=2F-awiZGGNwwdu2xxkjrVDCuemJaV3z4bSIBZoXVVlY,77105
|
|
241
241
|
opentrons/protocol_api/robot_context.py,sha256=D6ZdpFX30VTtVUDHitsVjabJQXD5TxOV9_Z6sik1LvE,11891
|
|
242
|
-
opentrons/protocol_api/validation.py,sha256=
|
|
242
|
+
opentrons/protocol_api/validation.py,sha256=jFJcw_ixifViupEFaGrjEcuHyNIHG1gvo-n2jSqGnok,29227
|
|
243
243
|
opentrons/protocol_api/core/__init__.py,sha256=-g74o8OtBB0LmmOvwkRvPgrHt7fF7T8FRHDj-x_-Onk,736
|
|
244
244
|
opentrons/protocol_api/core/common.py,sha256=Ne7D4yBC3qywy35jIAC_1xI8HQwYt0HjPRXqIcyP06M,1276
|
|
245
245
|
opentrons/protocol_api/core/core_map.py,sha256=NX06HEDi5Obmaz0Xwwc_dikH0M-bTnZcfnSdMLdQqms,2074
|
|
246
246
|
opentrons/protocol_api/core/instrument.py,sha256=ZlEv60tzH5jxP0Wh9eyTc_28ju75RsllkQufMwYdIio,13985
|
|
247
247
|
opentrons/protocol_api/core/labware.py,sha256=-ZOjkalikXCV3ptehKCNaWGAdKxIdwne8LRFQW9NAm4,4290
|
|
248
248
|
opentrons/protocol_api/core/module.py,sha256=D8d9Xs_AgI53i8POkK2deUiu92V93Wt9-HG4FDKrHnE,15833
|
|
249
|
-
opentrons/protocol_api/core/protocol.py,sha256=
|
|
249
|
+
opentrons/protocol_api/core/protocol.py,sha256=Jru2lRuPtgdzpZiuhU6VV6UGN2wbjCSoWm_CAbOVPiU,8695
|
|
250
250
|
opentrons/protocol_api/core/robot.py,sha256=QMAqj5Oqq3_IhTDyUF4jpWI4j2LRPP9crUiaYD_RUv4,1385
|
|
251
251
|
opentrons/protocol_api/core/well.py,sha256=Lf89YYEyq-ahRSRIFJw42vxIP8Fw6kzIUh9K1HEijUQ,3487
|
|
252
252
|
opentrons/protocol_api/core/well_grid.py,sha256=BU28DKaBgEU_JdZ6pEzrwNxmuh6TkO4zlg7Pq1Rf5Xk,1516
|
|
253
253
|
opentrons/protocol_api/core/engine/__init__.py,sha256=B_5T7zgkWDb1mXPg4NbT-wBkQaK-WVokMMnJRNu7xiM,582
|
|
254
254
|
opentrons/protocol_api/core/engine/_default_labware_versions.py,sha256=hLKAp33c_eNLpvT5qUt8AOYy6PHhM_JnkdOXaMl80jA,7541
|
|
255
|
+
opentrons/protocol_api/core/engine/_default_liquid_class_versions.py,sha256=MCPKf-7fAULQ4oPVYxiyKHr4AYRAevwA9uhkdur3-kQ,1513
|
|
255
256
|
opentrons/protocol_api/core/engine/deck_conflict.py,sha256=j3AJ-sYr5e-06UgeGueUldx9B3fn7AhN738kJxZO_vw,14693
|
|
256
257
|
opentrons/protocol_api/core/engine/exceptions.py,sha256=aZgNrmYEeuPZm21nX_KZYtvyjv5h_zPjxxgPkEV7_bw,725
|
|
257
258
|
opentrons/protocol_api/core/engine/instrument.py,sha256=lDrCqOZm7ceu1E50EYiSh7qTDMci5cgw4bM-AvLyMjE,98890
|
|
@@ -261,7 +262,7 @@ opentrons/protocol_api/core/engine/module_core.py,sha256=qxxcqpH-A4Zil9hHDxnvh4H
|
|
|
261
262
|
opentrons/protocol_api/core/engine/overlap_versions.py,sha256=PyGvQtQUg1wzNtkuGZtxwXm019PoIjq7em2JiWaxbXc,675
|
|
262
263
|
opentrons/protocol_api/core/engine/pipette_movement_conflict.py,sha256=x54RIYtkL1rdzvkSp2JgusLY3EEvY8bX3OwipeVKdsE,15511
|
|
263
264
|
opentrons/protocol_api/core/engine/point_calculations.py,sha256=C2eF0fvJQGMqQv3DzNhc1-m8HTAXTyTsHPJEPrEUEmo,2502
|
|
264
|
-
opentrons/protocol_api/core/engine/protocol.py,sha256=
|
|
265
|
+
opentrons/protocol_api/core/engine/protocol.py,sha256=MQNMYNII1OxwaQGsKbOgVtmEH54mjDahzD-WHst9MH8,46247
|
|
265
266
|
opentrons/protocol_api/core/engine/robot.py,sha256=bzUt23NG-clD-9-QFsV_6nm3fMgSmvYEG9DyyZI1xgw,5366
|
|
266
267
|
opentrons/protocol_api/core/engine/stringify.py,sha256=GwFgEhFMk-uPfFQhQG_2mkaf4cxaItiY8RW7rZwiooQ,2794
|
|
267
268
|
opentrons/protocol_api/core/engine/transfer_components_executor.py,sha256=mR59C-e6IHSZthlbQEwmRnh5ye8lhr6a0Qp5CNNi9n8,45211
|
|
@@ -273,7 +274,7 @@ opentrons/protocol_api/core/legacy/labware_offset_provider.py,sha256=2DLIby9xmUr
|
|
|
273
274
|
opentrons/protocol_api/core/legacy/legacy_instrument_core.py,sha256=mEX2Kmx8vBag7ndk4pCIssKkH9C-FEk0xphDyogCLGQ,27023
|
|
274
275
|
opentrons/protocol_api/core/legacy/legacy_labware_core.py,sha256=ksal6uzzGcMFEE3Ko2H9cbG8b8u4IprzejkkxdBHwHQ,8579
|
|
275
276
|
opentrons/protocol_api/core/legacy/legacy_module_core.py,sha256=CFCuXN1g5zE2IXD1I09vkngBlOdDzQjuIaNlJ5tVXnQ,23231
|
|
276
|
-
opentrons/protocol_api/core/legacy/legacy_protocol_core.py,sha256=
|
|
277
|
+
opentrons/protocol_api/core/legacy/legacy_protocol_core.py,sha256=Owj8Vx3ysQEarPH81PcCpAA0MnVegMkjWXNz5-nRIqg,23712
|
|
277
278
|
opentrons/protocol_api/core/legacy/legacy_well_core.py,sha256=wxeiPBqaS8YQwRpDGwF7ykJ0s2y3bExwVGpNbUZMmFg,5560
|
|
278
279
|
opentrons/protocol_api/core/legacy/load_info.py,sha256=r-WaH5ZJb3TRCp_zvbMMh0P4BhbZM8HsBs1K_pU98dk,1857
|
|
279
280
|
opentrons/protocol_api/core/legacy/module_geometry.py,sha256=lvWFHZ81-JFw-1VZUW1R3yUIb59xpXT6H3jwlRintRo,21082
|
|
@@ -305,7 +306,7 @@ opentrons/protocol_engine/commands/aspirate_while_tracking.py,sha256=d8-UBiXmBZ1
|
|
|
305
306
|
opentrons/protocol_engine/commands/blow_out.py,sha256=3gboq4x5S8fq7j4ZZGNClXFDlOjcdW1v2g58GPdhaPI,4338
|
|
306
307
|
opentrons/protocol_engine/commands/blow_out_in_place.py,sha256=jm2XXyJfIP9-AAFwXhD59_13nX18-i6QqpLGb-lK7sI,3391
|
|
307
308
|
opentrons/protocol_engine/commands/command.py,sha256=1hWH_KWg_WDL4R4VXe1ZH2vO6pYt5SA-ZpuPPF1oV5E,10149
|
|
308
|
-
opentrons/protocol_engine/commands/command_unions.py,sha256=
|
|
309
|
+
opentrons/protocol_engine/commands/command_unions.py,sha256=_2iINXrl9yc3H8X-AF8YBhYZQHLU0RHFEfl0MwE2H2w,27550
|
|
309
310
|
opentrons/protocol_engine/commands/comment.py,sha256=-6o07x-MZ6-IvZas84OVFmqF0gAbbKWJZIlGVYThCqM,1638
|
|
310
311
|
opentrons/protocol_engine/commands/configure_for_volume.py,sha256=wLt7-zJfKrRZhz9E0J9Xu_eayDMVPl8utdUYDMwgzFw,3615
|
|
311
312
|
opentrons/protocol_engine/commands/configure_nozzle_layout.py,sha256=M_s5Ee03a7sSnbvkibDHzEqZwkca0y8J7F60EnSEq7A,3849
|
|
@@ -364,12 +365,12 @@ opentrons/protocol_engine/commands/calibration/calibrate_module.py,sha256=5QZ5zL
|
|
|
364
365
|
opentrons/protocol_engine/commands/calibration/calibrate_pipette.py,sha256=YMH2MJ7RI0Nf7xjoXJLPlCuMCs5_Stj8zLj-oHcfnDk,3278
|
|
365
366
|
opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py,sha256=Y5UI4zcnhhVdfQOYh1N07jkBiVChD0kS_H_ow7_qiCA,5311
|
|
366
367
|
opentrons/protocol_engine/commands/flex_stacker/__init__.py,sha256=IJLskKdZZOGUA1eOm2e3fiP1C9GyTdbTS6uY6Hc4nUk,1369
|
|
367
|
-
opentrons/protocol_engine/commands/flex_stacker/common.py,sha256=
|
|
368
|
+
opentrons/protocol_engine/commands/flex_stacker/common.py,sha256=QHBtKawQxWssm6nSmtIpuJCH6BFlT54k4XQTBNSU8mY,35249
|
|
368
369
|
opentrons/protocol_engine/commands/flex_stacker/empty.py,sha256=1R0AwQtLn_wfuFH0Og2yAngJU8T_XLqf0a__9CqZQy0,11492
|
|
369
370
|
opentrons/protocol_engine/commands/flex_stacker/fill.py,sha256=3qhAQxJfaSp4EAFGIUotkrJVuOvdFrwzmkMCa2v6khA,10866
|
|
370
371
|
opentrons/protocol_engine/commands/flex_stacker/retrieve.py,sha256=kh9Lh-FW-RrXmV4RS8txmTYPfPDKhQhjW0UXr8k0vhc,12763
|
|
371
372
|
opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py,sha256=5VdqCcBdIHmpWqIJN3rCKeZ6IKwfxAdQTXMTD-KL-5w,12484
|
|
372
|
-
opentrons/protocol_engine/commands/flex_stacker/store.py,sha256=
|
|
373
|
+
opentrons/protocol_engine/commands/flex_stacker/store.py,sha256=Ed49qEUc16wo643PztZLYNPhVuLNZbx0lALSvpRYwDk,13632
|
|
373
374
|
opentrons/protocol_engine/commands/heater_shaker/__init__.py,sha256=ImAPrYSUvP8tI7obvoHmrJbjwLldgGNTnFYRgfXj8hI,2757
|
|
374
375
|
opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py,sha256=Q7sqFtzUD8wclRLL2PLWjnClIeLtJsiMCobStvzoJKc,2847
|
|
375
376
|
opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py,sha256=UYeGrTmnGtfw22p0agefI2ZnpukKlIgFcmJv9v58Xnc,2755
|
|
@@ -426,7 +427,7 @@ opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.p
|
|
|
426
427
|
opentrons/protocol_engine/execution/gantry_mover.py,sha256=LFTPmzuGRuP6IspgXxIEyJIXV0tHkc4UWDDjWFCClYo,26477
|
|
427
428
|
opentrons/protocol_engine/execution/hardware_stopper.py,sha256=ZlhVYEdFfuKqp5slZBkustXcRPy5fJsw2rmfYzHuJkQ,6127
|
|
428
429
|
opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py,sha256=BSFLzSSeELAYZCrCUfJZx5DdlrwU06Ur92TYd0T-hzM,9084
|
|
429
|
-
opentrons/protocol_engine/execution/labware_movement.py,sha256=
|
|
430
|
+
opentrons/protocol_engine/execution/labware_movement.py,sha256=0QnTf98CpYItP1icvNpwUeIa2LUWk4w7yBCUVJw-64g,12656
|
|
430
431
|
opentrons/protocol_engine/execution/movement.py,sha256=ZU4K4OHnzZYCZbk3RwfSOC6C3T2jtBlvYMppJhJSF08,12749
|
|
431
432
|
opentrons/protocol_engine/execution/pipetting.py,sha256=cnJYbLiJ2QD1xziD8dkRm0mZG3xOk00klW8Ff8rgSG4,22199
|
|
432
433
|
opentrons/protocol_engine/execution/queue_worker.py,sha256=LM753TrQzJoKUSIrtcaHDOWLe58zcpx-fUOLVpyDlHM,3302
|
|
@@ -463,7 +464,7 @@ opentrons/protocol_engine/state/files.py,sha256=w8xxxg8HY0RqKKEGSfHWfrjV54Gb02O3
|
|
|
463
464
|
opentrons/protocol_engine/state/fluid_stack.py,sha256=uwkf0qYk1UX5iU52xmk-e3yLPK8OG-TtMCcBqrkVFpM,5932
|
|
464
465
|
opentrons/protocol_engine/state/geometry.py,sha256=o8tefXS_Jekdt82dW4HHVJSnsxCsTFJuG6ogtri2wTY,104065
|
|
465
466
|
opentrons/protocol_engine/state/inner_well_math_utils.py,sha256=UhemsPpcuKwVc-iGXI2-v--miOGNunAnAVznJTVADlQ,20598
|
|
466
|
-
opentrons/protocol_engine/state/labware.py,sha256=
|
|
467
|
+
opentrons/protocol_engine/state/labware.py,sha256=vwagsqSBAIkVj4eupu0pIK6F3idnqqoRWDjVbp4ZwKQ,62977
|
|
467
468
|
opentrons/protocol_engine/state/liquid_classes.py,sha256=u_z75UYdiFAKG0yB3mr1il4T3qaS0Sotq8sL7KLODP8,2990
|
|
468
469
|
opentrons/protocol_engine/state/liquids.py,sha256=NoesktcQdJUjIVmet1uqqJPf-rzbo4SGemXwQC295W0,2338
|
|
469
470
|
opentrons/protocol_engine/state/modules.py,sha256=SM_6j3YfZV4ZXWTGjwxQIVH-jtHEI-YFuJtoMyPBReo,61599
|
|
@@ -482,7 +483,7 @@ opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py,sha2
|
|
|
482
483
|
opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py,sha256=IJ5zpufz5WSRbJqHOAi-WroDxpsRZz-GvwznIL4v7VQ,2468
|
|
483
484
|
opentrons/protocol_engine/state/module_substates/temperature_module_substate.py,sha256=w9h6EBM1YY8SeUOlUz5-nW1Zoyce8-zua8Z6mX4sDNg,2310
|
|
484
485
|
opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py,sha256=fLt2jMsbnfe8Q25vAjloxLBGdx8sotqM34VxbwfegpE,5167
|
|
485
|
-
opentrons/protocol_engine/types/__init__.py,sha256=
|
|
486
|
+
opentrons/protocol_engine/types/__init__.py,sha256=8zInoWjiYEAir1Frq1ESEdFYj17aBH4zXjxL4odPLR0,8376
|
|
486
487
|
opentrons/protocol_engine/types/automatic_tip_selection.py,sha256=I_B3iWei1Sl7F7IrMKqOn4S12heZXRnfKvtCTUXIMyM,1118
|
|
487
488
|
opentrons/protocol_engine/types/command_annotations.py,sha256=5A4k_R_4A2_nGl0K85SKwNlnKA09fUhEIe_mdU55yro,1843
|
|
488
489
|
opentrons/protocol_engine/types/deck_configuration.py,sha256=3dhkk3Z_PrJvqb26brkEdlyzMAGih_UopoEzu9k6SRk,2422
|
|
@@ -490,7 +491,7 @@ opentrons/protocol_engine/types/execution.py,sha256=6g_NvlF4niXjFQwDjkmTgKx-N6I8
|
|
|
490
491
|
opentrons/protocol_engine/types/hardware_passthrough.py,sha256=tpTE3XHbRjXWQqY0rgosIfcOAGHqMkOpIU3IpIXgdAA,534
|
|
491
492
|
opentrons/protocol_engine/types/instrument.py,sha256=sqiY6OKYgI0ViQ2UsuYMkL9MI6OpvdgLzC1mvclrp2M,984
|
|
492
493
|
opentrons/protocol_engine/types/instrument_sensors.py,sha256=CGcChvuxpRXVJHLZP_wd1ej3XDD9x1S9biugMAnk0tM,1449
|
|
493
|
-
opentrons/protocol_engine/types/labware.py,sha256=
|
|
494
|
+
opentrons/protocol_engine/types/labware.py,sha256=huIKtzEmWJcWuyKq5jN_3Ra4QXRDUbaK2Ck0O3vV5zU,4615
|
|
494
495
|
opentrons/protocol_engine/types/labware_movement.py,sha256=BEZIDc-6YhU9LRACi0ozroIxuOIq-tngvrFE22uufjs,577
|
|
495
496
|
opentrons/protocol_engine/types/labware_offset_location.py,sha256=gXOmIHLD1Hk6OhfhmV9Uf2HN0rIKD6syWSPfYehB9QQ,4237
|
|
496
497
|
opentrons/protocol_engine/types/labware_offset_vector.py,sha256=2M_q0vSjOyjujt-0NY9NM0asQS27MHYElcFgoKCAZAY,377
|
|
@@ -541,7 +542,7 @@ opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py,sha256=w
|
|
|
541
542
|
opentrons/protocols/api_support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
542
543
|
opentrons/protocols/api_support/constants.py,sha256=pI_zJ8oORr6FUOaF508ttll3KOIYqRRgcwVFwnqZuqc,262
|
|
543
544
|
opentrons/protocols/api_support/deck_type.py,sha256=cBxm-IQqFyL1QtYTMGtLXOlyuh-67xWgnJSP6rkg8oc,3942
|
|
544
|
-
opentrons/protocols/api_support/definitions.py,sha256=
|
|
545
|
+
opentrons/protocols/api_support/definitions.py,sha256=Sg0LIzkncnqTPz-e6EtLxdPmEVhogKkmDv3lTpGfmdI,727
|
|
545
546
|
opentrons/protocols/api_support/instrument.py,sha256=xbgFKbJU_gL1QjbH_mgGHJx2USQIQisjEkBHiFfYEqA,5712
|
|
546
547
|
opentrons/protocols/api_support/labware_like.py,sha256=JArK3XIYSMzDJTnpsVg9KNcMBEaRLMllmbV4ZtcI02s,7701
|
|
547
548
|
opentrons/protocols/api_support/tip_tracker.py,sha256=ztngh5wGworD77ycKHm3_f9EqjT24VFXIAARAGcCPns,7407
|
|
@@ -594,8 +595,8 @@ opentrons/util/linal.py,sha256=IlKAP9HkNBBgULeSf4YVwSKHdx9jnCjSr7nvDvlRALg,5753
|
|
|
594
595
|
opentrons/util/logging_config.py,sha256=7et4YYuQdWdq_e50U-8vFS_QyNBRgdnqPGAQJm8qrIo,9954
|
|
595
596
|
opentrons/util/logging_queue_handler.py,sha256=ZsSJwy-oV8DXwpYiZisQ1PbYwmK2cOslD46AcyJ1E4I,2484
|
|
596
597
|
opentrons/util/performance_helpers.py,sha256=ew7H8XD20iS6-2TJAzbQeyzStZkkE6PzHt_Adx3wbZQ,5172
|
|
597
|
-
opentrons-8.
|
|
598
|
-
opentrons-8.
|
|
599
|
-
opentrons-8.
|
|
600
|
-
opentrons-8.
|
|
601
|
-
opentrons-8.
|
|
598
|
+
opentrons-8.7.0a0.dist-info/METADATA,sha256=U7gGnD5DR1XRNN5e9BqM9v9_NnJFeqsqVZI51jyMnoM,1607
|
|
599
|
+
opentrons-8.7.0a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
600
|
+
opentrons-8.7.0a0.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
|
|
601
|
+
opentrons-8.7.0a0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
602
|
+
opentrons-8.7.0a0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|