opentrons 8.3.2__py2.py3-none-any.whl → 8.4.0__py2.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/calibration_storage/ot2/mark_bad_calibration.py +2 -0
- opentrons/calibration_storage/ot2/tip_length.py +6 -6
- opentrons/config/advanced_settings.py +9 -11
- opentrons/config/feature_flags.py +0 -4
- opentrons/config/reset.py +7 -2
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/async_serial.py +4 -0
- opentrons/drivers/asyncio/communication/errors.py +41 -8
- opentrons/drivers/asyncio/communication/serial_connection.py +36 -10
- opentrons/drivers/flex_stacker/__init__.py +9 -3
- opentrons/drivers/flex_stacker/abstract.py +140 -15
- opentrons/drivers/flex_stacker/driver.py +593 -47
- opentrons/drivers/flex_stacker/errors.py +64 -0
- opentrons/drivers/flex_stacker/simulator.py +222 -24
- opentrons/drivers/flex_stacker/types.py +211 -15
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/execute.py +4 -2
- opentrons/hardware_control/api.py +5 -0
- opentrons/hardware_control/backends/flex_protocol.py +4 -0
- opentrons/hardware_control/backends/ot3controller.py +12 -1
- opentrons/hardware_control/backends/ot3simulator.py +3 -0
- opentrons/hardware_control/backends/subsystem_manager.py +8 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +10 -6
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +59 -6
- opentrons/hardware_control/modules/__init__.py +12 -1
- opentrons/hardware_control/modules/absorbance_reader.py +11 -9
- opentrons/hardware_control/modules/flex_stacker.py +498 -0
- opentrons/hardware_control/modules/heater_shaker.py +12 -10
- opentrons/hardware_control/modules/magdeck.py +5 -1
- opentrons/hardware_control/modules/tempdeck.py +5 -1
- opentrons/hardware_control/modules/thermocycler.py +15 -14
- opentrons/hardware_control/modules/types.py +191 -1
- opentrons/hardware_control/modules/utils.py +3 -0
- opentrons/hardware_control/motion_utilities.py +20 -0
- opentrons/hardware_control/ot3api.py +145 -15
- opentrons/hardware_control/protocols/liquid_handler.py +47 -1
- opentrons/hardware_control/types.py +6 -0
- opentrons/legacy_commands/commands.py +102 -5
- opentrons/legacy_commands/helpers.py +74 -1
- opentrons/legacy_commands/types.py +33 -2
- opentrons/protocol_api/__init__.py +2 -0
- opentrons/protocol_api/_liquid.py +39 -8
- opentrons/protocol_api/_liquid_properties.py +20 -19
- opentrons/protocol_api/_transfer_liquid_validation.py +91 -0
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/deck_conflict.py +11 -1
- opentrons/protocol_api/core/engine/instrument.py +1356 -107
- opentrons/protocol_api/core/engine/labware.py +8 -4
- opentrons/protocol_api/core/engine/load_labware_params.py +68 -10
- opentrons/protocol_api/core/engine/module_core.py +118 -2
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +6 -14
- opentrons/protocol_api/core/engine/protocol.py +253 -11
- opentrons/protocol_api/core/engine/stringify.py +19 -8
- opentrons/protocol_api/core/engine/transfer_components_executor.py +858 -0
- opentrons/protocol_api/core/engine/well.py +73 -5
- opentrons/protocol_api/core/instrument.py +71 -21
- opentrons/protocol_api/core/labware.py +6 -2
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +7 -3
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +76 -49
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +8 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +36 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +27 -2
- opentrons/protocol_api/core/legacy/load_info.py +4 -12
- opentrons/protocol_api/core/legacy/module_geometry.py +6 -1
- opentrons/protocol_api/core/legacy/well_geometry.py +3 -3
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +73 -23
- opentrons/protocol_api/core/module.py +43 -0
- opentrons/protocol_api/core/protocol.py +33 -0
- opentrons/protocol_api/core/well.py +23 -2
- opentrons/protocol_api/instrument_context.py +454 -150
- opentrons/protocol_api/labware.py +98 -50
- opentrons/protocol_api/module_contexts.py +140 -0
- opentrons/protocol_api/protocol_context.py +163 -19
- opentrons/protocol_api/validation.py +51 -41
- opentrons/protocol_engine/__init__.py +21 -2
- opentrons/protocol_engine/actions/actions.py +5 -5
- opentrons/protocol_engine/clients/sync_client.py +6 -0
- opentrons/protocol_engine/commands/__init__.py +66 -36
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +0 -1
- opentrons/protocol_engine/commands/air_gap_in_place.py +3 -2
- opentrons/protocol_engine/commands/aspirate.py +6 -2
- opentrons/protocol_engine/commands/aspirate_in_place.py +3 -1
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +210 -0
- opentrons/protocol_engine/commands/blow_out.py +2 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +4 -1
- opentrons/protocol_engine/commands/command_unions.py +102 -33
- opentrons/protocol_engine/commands/configure_for_volume.py +3 -0
- opentrons/protocol_engine/commands/dispense.py +3 -1
- opentrons/protocol_engine/commands/dispense_in_place.py +3 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +23 -1
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +106 -0
- opentrons/protocol_engine/commands/flex_stacker/close_latch.py +72 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +15 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +161 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +164 -0
- opentrons/protocol_engine/commands/flex_stacker/open_latch.py +70 -0
- opentrons/protocol_engine/commands/flex_stacker/prepare_shuttle.py +112 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +394 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +190 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +291 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +27 -13
- opentrons/protocol_engine/commands/load_labware.py +42 -39
- opentrons/protocol_engine/commands/load_lid.py +21 -13
- opentrons/protocol_engine/commands/load_lid_stack.py +130 -47
- opentrons/protocol_engine/commands/load_module.py +18 -17
- opentrons/protocol_engine/commands/load_pipette.py +3 -0
- opentrons/protocol_engine/commands/move_labware.py +139 -20
- opentrons/protocol_engine/commands/move_to_well.py +5 -11
- opentrons/protocol_engine/commands/pick_up_tip.py +5 -2
- opentrons/protocol_engine/commands/pipetting_common.py +159 -8
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +15 -5
- opentrons/protocol_engine/commands/{evotip_dispense.py → pressure_dispense.py} +33 -34
- opentrons/protocol_engine/commands/reload_labware.py +6 -19
- opentrons/protocol_engine/commands/{evotip_seal_pipette.py → seal_pipette_to_tip.py} +97 -76
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +3 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +6 -1
- opentrons/protocol_engine/commands/{evotip_unseal_pipette.py → unseal_pipette_from_tip.py} +31 -40
- opentrons/protocol_engine/errors/__init__.py +10 -0
- opentrons/protocol_engine/errors/exceptions.py +62 -0
- opentrons/protocol_engine/execution/equipment.py +123 -106
- opentrons/protocol_engine/execution/labware_movement.py +8 -6
- opentrons/protocol_engine/execution/pipetting.py +235 -25
- opentrons/protocol_engine/execution/tip_handler.py +82 -32
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/protocol_engine.py +22 -13
- opentrons/protocol_engine/resources/deck_configuration_provider.py +98 -2
- opentrons/protocol_engine/resources/deck_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_data_provider.py +32 -12
- opentrons/protocol_engine/resources/labware_validation.py +7 -5
- opentrons/protocol_engine/slot_standardization.py +11 -23
- opentrons/protocol_engine/state/addressable_areas.py +84 -46
- opentrons/protocol_engine/state/frustum_helpers.py +36 -14
- opentrons/protocol_engine/state/geometry.py +892 -227
- opentrons/protocol_engine/state/labware.py +252 -55
- opentrons/protocol_engine/state/module_substates/__init__.py +4 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +68 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +22 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +13 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +20 -0
- opentrons/protocol_engine/state/modules.py +210 -67
- opentrons/protocol_engine/state/pipettes.py +54 -0
- opentrons/protocol_engine/state/state.py +1 -1
- opentrons/protocol_engine/state/tips.py +14 -0
- opentrons/protocol_engine/state/update_types.py +180 -25
- opentrons/protocol_engine/state/wells.py +55 -9
- opentrons/protocol_engine/types/__init__.py +300 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +72 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +111 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +33 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +131 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +301 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/extract_labware_definitions.py +7 -3
- opentrons/protocol_reader/file_format_validator.py +5 -3
- opentrons/protocol_runner/json_translator.py +4 -2
- opentrons/protocol_runner/legacy_command_mapper.py +6 -2
- opentrons/protocol_runner/run_orchestrator.py +4 -1
- opentrons/protocols/advanced_control/transfers/common.py +48 -1
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +204 -0
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +16 -3
- opentrons/protocols/labware.py +27 -23
- opentrons/protocols/models/__init__.py +0 -21
- opentrons/simulate.py +4 -2
- opentrons/types.py +20 -7
- opentrons/util/logging_config.py +94 -25
- opentrons/util/logging_queue_handler.py +61 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/METADATA +4 -4
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/RECORD +192 -151
- opentrons/calibration_storage/ot2/models/defaults.py +0 -0
- opentrons/calibration_storage/ot3/models/defaults.py +0 -0
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_engine/types.py +0 -1311
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/LICENSE +0 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/WHEEL +0 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/top_level.txt +0 -0
|
@@ -209,6 +209,10 @@ class LegacyProtocolCore(
|
|
|
209
209
|
bundled_defs=self._bundled_labware,
|
|
210
210
|
extra_defs=self._extra_labware,
|
|
211
211
|
)
|
|
212
|
+
# For type checking. This should always pass because
|
|
213
|
+
# opentrons.protocol_api.core.legacy should only load labware with schema 2.
|
|
214
|
+
assert labware_def["schemaVersion"] == 2
|
|
215
|
+
|
|
212
216
|
labware_core = LegacyLabwareCore(
|
|
213
217
|
definition=labware_def,
|
|
214
218
|
parent=parent,
|
|
@@ -307,6 +311,25 @@ class LegacyProtocolCore(
|
|
|
307
311
|
"""Move labware to new location."""
|
|
308
312
|
raise APIVersionError(api_element="Labware movement")
|
|
309
313
|
|
|
314
|
+
def move_lid(
|
|
315
|
+
self,
|
|
316
|
+
source_location: Union[DeckSlotName, StagingSlotName, LegacyLabwareCore],
|
|
317
|
+
new_location: Union[
|
|
318
|
+
DeckSlotName,
|
|
319
|
+
StagingSlotName,
|
|
320
|
+
LegacyLabwareCore,
|
|
321
|
+
OffDeckType,
|
|
322
|
+
WasteChute,
|
|
323
|
+
TrashBin,
|
|
324
|
+
],
|
|
325
|
+
use_gripper: bool,
|
|
326
|
+
pause_for_manual_move: bool,
|
|
327
|
+
pick_up_offset: Optional[Tuple[float, float, float]],
|
|
328
|
+
drop_offset: Optional[Tuple[float, float, float]],
|
|
329
|
+
) -> LegacyLabwareCore | None:
|
|
330
|
+
"""Move lid to new location."""
|
|
331
|
+
raise APIVersionError(api_element="Lid movement")
|
|
332
|
+
|
|
310
333
|
def load_module(
|
|
311
334
|
self,
|
|
312
335
|
model: ModuleModel,
|
|
@@ -505,6 +528,19 @@ class LegacyProtocolCore(
|
|
|
505
528
|
"""Load a Stack of Lids to a given location, creating a Lid Stack."""
|
|
506
529
|
raise APIVersionError(api_element="Lid stack")
|
|
507
530
|
|
|
531
|
+
def load_labware_to_flex_stacker_hopper(
|
|
532
|
+
self,
|
|
533
|
+
module_core: legacy_module_core.LegacyModuleCore,
|
|
534
|
+
load_name: str,
|
|
535
|
+
quantity: int,
|
|
536
|
+
label: Optional[str],
|
|
537
|
+
namespace: Optional[str],
|
|
538
|
+
version: Optional[int],
|
|
539
|
+
lid: Optional[str],
|
|
540
|
+
) -> None:
|
|
541
|
+
"""Load labware to a Flex stacker hopper."""
|
|
542
|
+
raise APIVersionError(api_element="Flex stacker")
|
|
543
|
+
|
|
508
544
|
def get_module_cores(self) -> List[legacy_module_core.LegacyModuleCore]:
|
|
509
545
|
"""Get loaded module cores."""
|
|
510
546
|
return self._module_cores
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"""Legacy Well core implementation."""
|
|
2
|
-
from typing import Optional
|
|
2
|
+
from typing import Optional, Union
|
|
3
3
|
|
|
4
4
|
from opentrons_shared_data.labware.constants import WELL_NAME_PATTERN
|
|
5
5
|
|
|
6
6
|
from opentrons.protocols.api_support.util import APIVersionError
|
|
7
7
|
|
|
8
|
-
from opentrons.types import Point
|
|
8
|
+
from opentrons.types import Point, Mount
|
|
9
|
+
|
|
10
|
+
from opentrons.protocol_engine.types.liquid_level_detection import (
|
|
11
|
+
SimulatedProbeResult,
|
|
12
|
+
LiquidTrackingType,
|
|
13
|
+
)
|
|
9
14
|
|
|
10
15
|
from .well_geometry import WellGeometry
|
|
11
16
|
from ..well import AbstractWellCore
|
|
@@ -106,6 +111,10 @@ class LegacyWellCore(AbstractWellCore):
|
|
|
106
111
|
"""Get the coordinate of the well's center."""
|
|
107
112
|
return self._geometry.center()
|
|
108
113
|
|
|
114
|
+
def get_meniscus(self) -> Union[Point, SimulatedProbeResult]:
|
|
115
|
+
"""Get the coordinate of the well's center."""
|
|
116
|
+
raise APIVersionError(api_element="Getting a meniscus")
|
|
117
|
+
|
|
109
118
|
def load_liquid(
|
|
110
119
|
self,
|
|
111
120
|
liquid: Liquid,
|
|
@@ -118,6 +127,22 @@ class LegacyWellCore(AbstractWellCore):
|
|
|
118
127
|
"""Gets point in deck coordinates based on percentage of the radius of each axis."""
|
|
119
128
|
return self._geometry.from_center_cartesian(x, y, z)
|
|
120
129
|
|
|
130
|
+
def estimate_liquid_height_after_pipetting(
|
|
131
|
+
self,
|
|
132
|
+
mount: Mount | str,
|
|
133
|
+
operation_volume: float,
|
|
134
|
+
) -> LiquidTrackingType:
|
|
135
|
+
"""Estimate what the liquid height will be after pipetting, without raising an error."""
|
|
136
|
+
return 0.0
|
|
137
|
+
|
|
138
|
+
def current_liquid_height(self) -> LiquidTrackingType:
|
|
139
|
+
"""Get the current liquid height."""
|
|
140
|
+
return 0.0
|
|
141
|
+
|
|
142
|
+
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
143
|
+
"""Get the current well volume."""
|
|
144
|
+
return 0.0
|
|
145
|
+
|
|
121
146
|
# TODO(mc, 2022-10-28): is this used and/or necessary?
|
|
122
147
|
def __repr__(self) -> str:
|
|
123
148
|
"""Use the well's display name as its repr."""
|
|
@@ -7,7 +7,7 @@ It's only for internal Opentrons use.
|
|
|
7
7
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from typing import Optional, Union
|
|
10
|
-
from opentrons_shared_data.labware.types import
|
|
10
|
+
from opentrons_shared_data.labware.types import LabwareDefinition2
|
|
11
11
|
|
|
12
12
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
13
13
|
from opentrons.hardware_control.modules.types import ModuleModel
|
|
@@ -18,13 +18,11 @@ from opentrons.types import Mount, DeckSlotName
|
|
|
18
18
|
class LabwareLoadInfo:
|
|
19
19
|
"""Information about a successful labware load.
|
|
20
20
|
|
|
21
|
-
:meta private:
|
|
22
|
-
|
|
23
21
|
This is a separate class from the main user-facing `Labware` class
|
|
24
22
|
because this is easier to construct in unit tests.
|
|
25
23
|
"""
|
|
26
24
|
|
|
27
|
-
labware_definition:
|
|
25
|
+
labware_definition: LabwareDefinition2
|
|
28
26
|
|
|
29
27
|
# todo(mm, 2021-10-11): Namespace, load name, and version can be derived from the
|
|
30
28
|
# definition. Should they be removed from here?
|
|
@@ -47,10 +45,7 @@ class LabwareLoadInfo:
|
|
|
47
45
|
|
|
48
46
|
@dataclass(frozen=True)
|
|
49
47
|
class InstrumentLoadInfo:
|
|
50
|
-
"""Like `LabwareLoadInfo`, but for instruments (pipettes).
|
|
51
|
-
|
|
52
|
-
:meta private:
|
|
53
|
-
"""
|
|
48
|
+
"""Like `LabwareLoadInfo`, but for instruments (pipettes)."""
|
|
54
49
|
|
|
55
50
|
instrument_load_name: str
|
|
56
51
|
mount: Mount
|
|
@@ -59,10 +54,7 @@ class InstrumentLoadInfo:
|
|
|
59
54
|
|
|
60
55
|
@dataclass(frozen=True)
|
|
61
56
|
class ModuleLoadInfo:
|
|
62
|
-
"""Like `LabwareLoadInfo`, but for hardware modules.
|
|
63
|
-
|
|
64
|
-
:meta private:
|
|
65
|
-
"""
|
|
57
|
+
"""Like `LabwareLoadInfo`, but for hardware modules."""
|
|
66
58
|
|
|
67
59
|
requested_model: ModuleModel
|
|
68
60
|
loaded_model: ModuleModel
|
|
@@ -273,8 +273,13 @@ class ThermocyclerGeometry(ModuleGeometry):
|
|
|
273
273
|
LegacyLabwareCore,
|
|
274
274
|
)
|
|
275
275
|
|
|
276
|
-
# Block first three columns from being accessed
|
|
277
276
|
definition = labware._core.get_definition()
|
|
277
|
+
|
|
278
|
+
# For type checking. This should always pass because
|
|
279
|
+
# opentrons.protocol_api.core.legacy should only load labware with schema 2.
|
|
280
|
+
assert definition["schemaVersion"] == 2
|
|
281
|
+
|
|
282
|
+
# Block first three columns from being accessed
|
|
278
283
|
definition["ordering"] = definition["ordering"][2::]
|
|
279
284
|
return Labware(
|
|
280
285
|
core=LegacyLabwareCore(definition, super().location),
|
|
@@ -4,9 +4,9 @@ from typing import Optional, cast, TYPE_CHECKING
|
|
|
4
4
|
|
|
5
5
|
from opentrons.types import Point
|
|
6
6
|
from opentrons_shared_data.labware.types import (
|
|
7
|
-
WellDefinition,
|
|
8
|
-
CircularWellDefinition,
|
|
9
|
-
RectangularWellDefinition,
|
|
7
|
+
WellDefinition2 as WellDefinition,
|
|
8
|
+
CircularWellDefinition2 as CircularWellDefinition,
|
|
9
|
+
RectangularWellDefinition2 as RectangularWellDefinition,
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING, Optional, Union, List
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Union, List, Tuple, Literal
|
|
5
5
|
|
|
6
6
|
from opentrons import types
|
|
7
7
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
@@ -23,6 +23,9 @@ from opentrons_shared_data.errors.exceptions import (
|
|
|
23
23
|
UnexpectedTipAttachError,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
+
from opentrons.protocol_engine.types import LiquidTrackingType
|
|
27
|
+
|
|
28
|
+
from ..legacy.legacy_labware_core import LegacyLabwareCore
|
|
26
29
|
from ...disposal_locations import TrashBin, WasteChute
|
|
27
30
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
28
31
|
from opentrons.protocol_api._liquid import LiquidClass
|
|
@@ -42,7 +45,9 @@ _PRE_2_2_TIP_DROP_HEIGHT_MM = 10
|
|
|
42
45
|
"""In PAPIv2.1 and below, tips are always dropped 10 mm from the bottom of the well."""
|
|
43
46
|
|
|
44
47
|
|
|
45
|
-
class LegacyInstrumentCoreSimulator(
|
|
48
|
+
class LegacyInstrumentCoreSimulator(
|
|
49
|
+
AbstractInstrument[LegacyWellCore, LegacyLabwareCore]
|
|
50
|
+
):
|
|
46
51
|
"""A simulation of an instrument context."""
|
|
47
52
|
|
|
48
53
|
def __init__(
|
|
@@ -84,7 +89,9 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
84
89
|
def set_default_speed(self, speed: float) -> None:
|
|
85
90
|
self._default_speed = speed
|
|
86
91
|
|
|
87
|
-
def air_gap_in_place(
|
|
92
|
+
def air_gap_in_place(
|
|
93
|
+
self, volume: float, flow_rate: float, correction_volume: Optional[float] = None
|
|
94
|
+
) -> None:
|
|
88
95
|
assert False, "Air gap tracking only available in API version 2.22 and later"
|
|
89
96
|
|
|
90
97
|
def aspirate(
|
|
@@ -95,7 +102,8 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
95
102
|
rate: float,
|
|
96
103
|
flow_rate: float,
|
|
97
104
|
in_place: bool,
|
|
98
|
-
|
|
105
|
+
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
106
|
+
correction_volume: Optional[float] = None,
|
|
99
107
|
) -> None:
|
|
100
108
|
if self.get_current_volume() == 0:
|
|
101
109
|
# Make sure we're at the top of the labware and clear of any
|
|
@@ -137,7 +145,8 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
137
145
|
flow_rate: float,
|
|
138
146
|
in_place: bool,
|
|
139
147
|
push_out: Optional[float],
|
|
140
|
-
|
|
148
|
+
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
149
|
+
correction_volume: Optional[float] = None,
|
|
141
150
|
) -> None:
|
|
142
151
|
if isinstance(location, (TrashBin, WasteChute)):
|
|
143
152
|
raise APIVersionError(
|
|
@@ -177,7 +186,10 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
177
186
|
radius: float,
|
|
178
187
|
z_offset: float,
|
|
179
188
|
speed: float,
|
|
189
|
+
mm_from_edge: Optional[float] = None,
|
|
180
190
|
) -> None:
|
|
191
|
+
if mm_from_edge is not None:
|
|
192
|
+
raise APIVersionError(api_element="mm_from_edge argument")
|
|
181
193
|
self.move_to(location)
|
|
182
194
|
|
|
183
195
|
def pick_up_tip(
|
|
@@ -286,7 +298,7 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
286
298
|
|
|
287
299
|
def resin_tip_unseal(
|
|
288
300
|
self,
|
|
289
|
-
location: types.Location,
|
|
301
|
+
location: types.Location | None,
|
|
290
302
|
well_core: WellCore,
|
|
291
303
|
) -> None:
|
|
292
304
|
raise APIVersionError(api_element="Unsealing resin tips.")
|
|
@@ -313,6 +325,7 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
313
325
|
force_direct: bool = False,
|
|
314
326
|
minimum_z_height: Optional[float] = None,
|
|
315
327
|
speed: Optional[float] = None,
|
|
328
|
+
check_for_movement_conflicts: bool = False, # Not used in this implementation
|
|
316
329
|
) -> None:
|
|
317
330
|
"""Simulation of only the motion planning portion of move_to."""
|
|
318
331
|
if isinstance(location, (TrashBin, WasteChute)):
|
|
@@ -365,6 +378,9 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
365
378
|
def get_current_volume(self) -> float:
|
|
366
379
|
return self._pipette_dict["current_volume"]
|
|
367
380
|
|
|
381
|
+
def get_has_clean_tip(self) -> bool:
|
|
382
|
+
return False
|
|
383
|
+
|
|
368
384
|
def get_available_volume(self) -> float:
|
|
369
385
|
return self._pipette_dict["available_volume"]
|
|
370
386
|
|
|
@@ -498,29 +514,51 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
498
514
|
"""This will never be called because it was added in API 2.15."""
|
|
499
515
|
pass
|
|
500
516
|
|
|
501
|
-
def
|
|
517
|
+
def transfer_with_liquid_class(
|
|
502
518
|
self,
|
|
503
519
|
liquid_class: LiquidClass,
|
|
504
|
-
pipette_load_name: str,
|
|
505
|
-
tiprack_uri: str,
|
|
506
|
-
) -> str:
|
|
507
|
-
"""This will never be called because it was added in .."""
|
|
508
|
-
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
509
|
-
assert False, "load_liquid_class is not supported in legacy context"
|
|
510
|
-
|
|
511
|
-
def transfer_liquid(
|
|
512
|
-
self,
|
|
513
|
-
liquid_class_id: str,
|
|
514
520
|
volume: float,
|
|
515
|
-
source: List[LegacyWellCore],
|
|
516
|
-
dest: List[LegacyWellCore],
|
|
521
|
+
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
522
|
+
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
517
523
|
new_tip: TransferTipPolicyV2,
|
|
518
|
-
|
|
524
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
525
|
+
starting_tip: Optional[LegacyWellCore],
|
|
526
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
527
|
+
return_tip: bool,
|
|
519
528
|
) -> None:
|
|
520
|
-
"""
|
|
521
|
-
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
529
|
+
"""This will never be called because it was added in API 2.23."""
|
|
522
530
|
assert False, "transfer_liquid is not supported in legacy context"
|
|
523
531
|
|
|
532
|
+
def distribute_with_liquid_class(
|
|
533
|
+
self,
|
|
534
|
+
liquid_class: LiquidClass,
|
|
535
|
+
volume: float,
|
|
536
|
+
source: Tuple[types.Location, LegacyWellCore],
|
|
537
|
+
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
538
|
+
new_tip: Literal[TransferTipPolicyV2.NEVER, TransferTipPolicyV2.ONCE],
|
|
539
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
540
|
+
starting_tip: Optional[LegacyWellCore],
|
|
541
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
542
|
+
return_tip: bool,
|
|
543
|
+
) -> None:
|
|
544
|
+
"""This will never be called because it was added in API 2.23."""
|
|
545
|
+
assert False, "distribute_liquid is not supported in legacy context"
|
|
546
|
+
|
|
547
|
+
def consolidate_with_liquid_class(
|
|
548
|
+
self,
|
|
549
|
+
liquid_class: LiquidClass,
|
|
550
|
+
volume: float,
|
|
551
|
+
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
552
|
+
dest: Tuple[types.Location, LegacyWellCore],
|
|
553
|
+
new_tip: Literal[TransferTipPolicyV2.NEVER, TransferTipPolicyV2.ONCE],
|
|
554
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
555
|
+
starting_tip: Optional[LegacyWellCore],
|
|
556
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
557
|
+
return_tip: bool,
|
|
558
|
+
) -> None:
|
|
559
|
+
"""This will never be called because it was added in API 2.23."""
|
|
560
|
+
assert False, "consolidate_liquid is not supported in legacy context"
|
|
561
|
+
|
|
524
562
|
def get_active_channels(self) -> int:
|
|
525
563
|
"""This will never be called because it was added in API 2.16."""
|
|
526
564
|
assert False, "get_active_channels only supported in API 2.16 & later"
|
|
@@ -549,7 +587,7 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
549
587
|
|
|
550
588
|
def liquid_probe_without_recovery(
|
|
551
589
|
self, well_core: WellCore, loc: types.Location
|
|
552
|
-
) ->
|
|
590
|
+
) -> LiquidTrackingType:
|
|
553
591
|
"""This will never be called because it was added in API 2.20."""
|
|
554
592
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
555
593
|
|
|
@@ -559,3 +597,15 @@ class LegacyInstrumentCoreSimulator(AbstractInstrument[LegacyWellCore]):
|
|
|
559
597
|
def nozzle_configuration_valid_for_lld(self) -> bool:
|
|
560
598
|
"""Check if the nozzle configuration currently supports LLD."""
|
|
561
599
|
return False
|
|
600
|
+
|
|
601
|
+
def get_minimum_liquid_sense_height(self) -> float:
|
|
602
|
+
return 0.0
|
|
603
|
+
|
|
604
|
+
def estimate_liquid_height(
|
|
605
|
+
self,
|
|
606
|
+
well_core: LegacyWellCore,
|
|
607
|
+
starting_liquid_height: float,
|
|
608
|
+
operation_volume: float,
|
|
609
|
+
) -> float:
|
|
610
|
+
"""This will never be called because it was added in API 2.21."""
|
|
611
|
+
assert False, "estimate_liquid_height only supported in API 2.21 & later"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Core module control interfaces."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from abc import ABC, abstractmethod
|
|
@@ -379,3 +380,45 @@ class AbstractAbsorbanceReaderCore(AbstractModuleCore):
|
|
|
379
380
|
@abstractmethod
|
|
380
381
|
def is_lid_on(self) -> bool:
|
|
381
382
|
"""Return True if the Absorbance Reader's lid is currently closed."""
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
class AbstractFlexStackerCore(AbstractModuleCore):
|
|
386
|
+
"""Core control interface for an attached Flex Stacker."""
|
|
387
|
+
|
|
388
|
+
MODULE_TYPE: ClassVar = ModuleType.FLEX_STACKER
|
|
389
|
+
|
|
390
|
+
@abstractmethod
|
|
391
|
+
def get_serial_number(self) -> str:
|
|
392
|
+
"""Get the module's unique hardware serial number."""
|
|
393
|
+
|
|
394
|
+
@abstractmethod
|
|
395
|
+
def retrieve(self) -> None:
|
|
396
|
+
"""Release a labware from the hopper to the staging slot."""
|
|
397
|
+
|
|
398
|
+
@abstractmethod
|
|
399
|
+
def store(self) -> None:
|
|
400
|
+
"""Store a labware in the stacker hopper."""
|
|
401
|
+
|
|
402
|
+
@abstractmethod
|
|
403
|
+
def fill(self, message: str, count: int | None) -> None:
|
|
404
|
+
"""Pause the protocol to allow for filling the stacker."""
|
|
405
|
+
|
|
406
|
+
@abstractmethod
|
|
407
|
+
def empty(self, message: str) -> None:
|
|
408
|
+
"""Pause the protocol to allow for emptying the stacker."""
|
|
409
|
+
|
|
410
|
+
@abstractmethod
|
|
411
|
+
def set_stored_labware(
|
|
412
|
+
self,
|
|
413
|
+
main_load_name: str,
|
|
414
|
+
main_namespace: str | None,
|
|
415
|
+
main_version: int | None,
|
|
416
|
+
lid_load_name: str | None,
|
|
417
|
+
lid_namespace: str | None,
|
|
418
|
+
lid_version: int | None,
|
|
419
|
+
adapter_load_name: str | None,
|
|
420
|
+
adapter_namespace: str | None,
|
|
421
|
+
adapter_version: int | None,
|
|
422
|
+
count: int | None,
|
|
423
|
+
) -> None:
|
|
424
|
+
"""Configure the kind of labware that the stacker stores."""
|
|
@@ -111,6 +111,20 @@ class AbstractProtocol(
|
|
|
111
111
|
"""Load an individual lid labware using its identifying parameters. Must be loaded on a labware."""
|
|
112
112
|
...
|
|
113
113
|
|
|
114
|
+
@abstractmethod
|
|
115
|
+
def load_labware_to_flex_stacker_hopper(
|
|
116
|
+
self,
|
|
117
|
+
module_core: ModuleCoreType,
|
|
118
|
+
load_name: str,
|
|
119
|
+
quantity: int,
|
|
120
|
+
label: Optional[str],
|
|
121
|
+
namespace: Optional[str],
|
|
122
|
+
version: Optional[int],
|
|
123
|
+
lid: Optional[str],
|
|
124
|
+
) -> None:
|
|
125
|
+
"""Load one or more labware with or without a lid to the flex stacker hopper."""
|
|
126
|
+
...
|
|
127
|
+
|
|
114
128
|
@abstractmethod
|
|
115
129
|
def move_labware(
|
|
116
130
|
self,
|
|
@@ -131,6 +145,25 @@ class AbstractProtocol(
|
|
|
131
145
|
) -> None:
|
|
132
146
|
...
|
|
133
147
|
|
|
148
|
+
@abstractmethod
|
|
149
|
+
def move_lid(
|
|
150
|
+
self,
|
|
151
|
+
source_location: Union[DeckSlotName, StagingSlotName, LabwareCoreType],
|
|
152
|
+
new_location: Union[
|
|
153
|
+
DeckSlotName,
|
|
154
|
+
StagingSlotName,
|
|
155
|
+
LabwareCoreType,
|
|
156
|
+
OffDeckType,
|
|
157
|
+
WasteChute,
|
|
158
|
+
TrashBin,
|
|
159
|
+
],
|
|
160
|
+
use_gripper: bool,
|
|
161
|
+
pause_for_manual_move: bool,
|
|
162
|
+
pick_up_offset: Optional[Tuple[float, float, float]],
|
|
163
|
+
drop_offset: Optional[Tuple[float, float, float]],
|
|
164
|
+
) -> LabwareCoreType | None:
|
|
165
|
+
...
|
|
166
|
+
|
|
134
167
|
@abstractmethod
|
|
135
168
|
def load_module(
|
|
136
169
|
self,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Abstract interface for Well core implementations."""
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from typing import TypeVar, Optional
|
|
4
|
+
from typing import TypeVar, Optional, Union
|
|
5
5
|
|
|
6
|
-
from opentrons.types import Point
|
|
6
|
+
from opentrons.types import Point, Mount
|
|
7
|
+
from opentrons.protocol_engine.types import LiquidTrackingType
|
|
7
8
|
|
|
8
9
|
from .._liquid import Liquid
|
|
9
10
|
|
|
@@ -71,6 +72,10 @@ class AbstractWellCore(ABC):
|
|
|
71
72
|
def get_center(self) -> Point:
|
|
72
73
|
"""Get the coordinate of the well's center."""
|
|
73
74
|
|
|
75
|
+
@abstractmethod
|
|
76
|
+
def get_meniscus(self) -> Union[Point, LiquidTrackingType]:
|
|
77
|
+
"""Get the coordinate of the well's meniscus."""
|
|
78
|
+
|
|
74
79
|
@abstractmethod
|
|
75
80
|
def load_liquid(
|
|
76
81
|
self,
|
|
@@ -83,5 +88,21 @@ class AbstractWellCore(ABC):
|
|
|
83
88
|
def from_center_cartesian(self, x: float, y: float, z: float) -> Point:
|
|
84
89
|
"""Gets point in deck coordinates based on percentage of the radius of each axis."""
|
|
85
90
|
|
|
91
|
+
@abstractmethod
|
|
92
|
+
def estimate_liquid_height_after_pipetting(
|
|
93
|
+
self,
|
|
94
|
+
mount: Mount | str,
|
|
95
|
+
operation_volume: float,
|
|
96
|
+
) -> LiquidTrackingType:
|
|
97
|
+
"""Estimate what the liquid height will be after pipetting, without raising an error."""
|
|
98
|
+
|
|
99
|
+
@abstractmethod
|
|
100
|
+
def current_liquid_height(self) -> LiquidTrackingType:
|
|
101
|
+
"""Get the current liquid height."""
|
|
102
|
+
|
|
103
|
+
@abstractmethod
|
|
104
|
+
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
105
|
+
"""Get the current volume within a well."""
|
|
106
|
+
|
|
86
107
|
|
|
87
108
|
WellCoreType = TypeVar("WellCoreType", bound=AbstractWellCore)
|