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
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
"""ProtocolEngine-based Well core implementations."""
|
|
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
|
+
from opentrons.types import Point, Mount, MountType
|
|
7
|
+
|
|
6
8
|
from opentrons.protocol_engine import WellLocation, WellOrigin, WellOffset
|
|
7
9
|
from opentrons.protocol_engine import commands as cmd
|
|
8
10
|
from opentrons.protocol_engine.clients import SyncClient as EngineClient
|
|
9
11
|
from opentrons.protocols.api_support.util import UnsupportedAPIError
|
|
10
|
-
from opentrons.types import
|
|
12
|
+
from opentrons.protocol_engine.types.liquid_level_detection import (
|
|
13
|
+
SimulatedProbeResult,
|
|
14
|
+
LiquidTrackingType,
|
|
15
|
+
)
|
|
16
|
+
from opentrons.protocol_engine.errors import PipetteNotAttachedError
|
|
11
17
|
|
|
12
18
|
from . import point_calculations
|
|
13
19
|
from . import stringify
|
|
@@ -44,17 +50,27 @@ class WellCore(AbstractWellCore):
|
|
|
44
50
|
@property
|
|
45
51
|
def diameter(self) -> Optional[float]:
|
|
46
52
|
"""Get the well's diameter, if circular."""
|
|
47
|
-
return
|
|
53
|
+
return (
|
|
54
|
+
self._definition.diameter if self._definition.shape == "circular" else None
|
|
55
|
+
)
|
|
48
56
|
|
|
49
57
|
@property
|
|
50
58
|
def length(self) -> Optional[float]:
|
|
51
59
|
"""Get the well's length, if rectangular."""
|
|
52
|
-
return
|
|
60
|
+
return (
|
|
61
|
+
self._definition.xDimension
|
|
62
|
+
if self._definition.shape == "rectangular"
|
|
63
|
+
else None
|
|
64
|
+
)
|
|
53
65
|
|
|
54
66
|
@property
|
|
55
67
|
def width(self) -> Optional[float]:
|
|
56
68
|
"""Get the well's width, if rectangular."""
|
|
57
|
-
return
|
|
69
|
+
return (
|
|
70
|
+
self._definition.yDimension
|
|
71
|
+
if self._definition.shape == "rectangular"
|
|
72
|
+
else None
|
|
73
|
+
)
|
|
58
74
|
|
|
59
75
|
@property
|
|
60
76
|
def depth(self) -> float:
|
|
@@ -125,6 +141,14 @@ class WellCore(AbstractWellCore):
|
|
|
125
141
|
well_location=WellLocation(origin=WellOrigin.CENTER),
|
|
126
142
|
)
|
|
127
143
|
|
|
144
|
+
def get_meniscus(self) -> Union[Point, SimulatedProbeResult]:
|
|
145
|
+
"""Get the coordinate of the well's meniscus."""
|
|
146
|
+
current_liquid_height = self.current_liquid_height()
|
|
147
|
+
if isinstance(current_liquid_height, float):
|
|
148
|
+
return self.get_bottom(z_offset=current_liquid_height)
|
|
149
|
+
else:
|
|
150
|
+
return current_liquid_height
|
|
151
|
+
|
|
128
152
|
def load_liquid(
|
|
129
153
|
self,
|
|
130
154
|
liquid: Liquid,
|
|
@@ -155,3 +179,47 @@ class WellCore(AbstractWellCore):
|
|
|
155
179
|
y_ratio=y,
|
|
156
180
|
z_ratio=z,
|
|
157
181
|
)
|
|
182
|
+
|
|
183
|
+
def estimate_liquid_height_after_pipetting(
|
|
184
|
+
self,
|
|
185
|
+
mount: Mount | str,
|
|
186
|
+
operation_volume: float,
|
|
187
|
+
) -> LiquidTrackingType:
|
|
188
|
+
"""Return an estimate of liquid height after pipetting without raising an error."""
|
|
189
|
+
labware_id = self.labware_id
|
|
190
|
+
well_name = self._name
|
|
191
|
+
if isinstance(mount, Mount):
|
|
192
|
+
mount_type = MountType.from_hw_mount(mount)
|
|
193
|
+
else:
|
|
194
|
+
mount_type = MountType(mount)
|
|
195
|
+
pipette_from_mount = self._engine_client.state.pipettes.get_by_mount(mount_type)
|
|
196
|
+
if pipette_from_mount is None:
|
|
197
|
+
raise PipetteNotAttachedError(f"No pipette present on mount {mount}")
|
|
198
|
+
pipette_id = pipette_from_mount.id
|
|
199
|
+
starting_liquid_height = self.current_liquid_height()
|
|
200
|
+
projected_final_height = (
|
|
201
|
+
self._engine_client.state.geometry.get_well_height_after_liquid_handling(
|
|
202
|
+
labware_id=labware_id,
|
|
203
|
+
well_name=well_name,
|
|
204
|
+
pipette_id=pipette_id,
|
|
205
|
+
initial_height=starting_liquid_height,
|
|
206
|
+
volume=operation_volume,
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
return projected_final_height
|
|
210
|
+
|
|
211
|
+
def current_liquid_height(self) -> LiquidTrackingType:
|
|
212
|
+
"""Return the current liquid height within a well."""
|
|
213
|
+
labware_id = self.labware_id
|
|
214
|
+
well_name = self._name
|
|
215
|
+
return self._engine_client.state.geometry.get_meniscus_height(
|
|
216
|
+
labware_id=labware_id, well_name=well_name
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
220
|
+
"""Return the current volume in a well."""
|
|
221
|
+
labware_id = self.labware_id
|
|
222
|
+
well_name = self._name
|
|
223
|
+
return self._engine_client.state.geometry.get_current_well_volume(
|
|
224
|
+
labware_id=labware_id, well_name=well_name
|
|
225
|
+
)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from abc import abstractmethod, ABC
|
|
6
|
-
from typing import Any, Generic, Optional, TypeVar, Union, List
|
|
6
|
+
from typing import Any, Generic, Optional, TypeVar, Union, List, Tuple, Literal
|
|
7
7
|
|
|
8
8
|
from opentrons import types
|
|
9
9
|
from opentrons.hardware_control.dev_types import PipetteDict
|
|
@@ -11,11 +11,14 @@ from opentrons.protocols.api_support.util import FlowRates
|
|
|
11
11
|
from opentrons.protocols.advanced_control.transfers.common import TransferTipPolicyV2
|
|
12
12
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
13
13
|
from opentrons.protocol_api._liquid import LiquidClass
|
|
14
|
+
from opentrons.protocol_engine.types import LiquidTrackingType
|
|
15
|
+
|
|
14
16
|
from ..disposal_locations import TrashBin, WasteChute
|
|
15
17
|
from .well import WellCoreType
|
|
18
|
+
from .labware import LabwareCoreType
|
|
16
19
|
|
|
17
20
|
|
|
18
|
-
class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
21
|
+
class AbstractInstrument(ABC, Generic[WellCoreType, LabwareCoreType]):
|
|
19
22
|
@abstractmethod
|
|
20
23
|
def get_default_speed(self) -> float:
|
|
21
24
|
...
|
|
@@ -25,11 +28,14 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
25
28
|
...
|
|
26
29
|
|
|
27
30
|
@abstractmethod
|
|
28
|
-
def air_gap_in_place(
|
|
31
|
+
def air_gap_in_place(
|
|
32
|
+
self, volume: float, flow_rate: float, correction_volume: Optional[float] = None
|
|
33
|
+
) -> None:
|
|
29
34
|
"""Aspirate a given volume of air from the current location of the pipette.
|
|
30
35
|
Args:
|
|
31
36
|
volume: The volume of air to aspirate, in microliters.
|
|
32
37
|
flow_rate: The flow rate of air into the pipette, in microliters.
|
|
38
|
+
correction_volume: The correction volume in uL.
|
|
33
39
|
"""
|
|
34
40
|
|
|
35
41
|
@abstractmethod
|
|
@@ -41,7 +47,8 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
41
47
|
rate: float,
|
|
42
48
|
flow_rate: float,
|
|
43
49
|
in_place: bool,
|
|
44
|
-
|
|
50
|
+
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
51
|
+
correction_volume: Optional[float] = None,
|
|
45
52
|
) -> None:
|
|
46
53
|
"""Aspirate a given volume of liquid from the specified location.
|
|
47
54
|
Args:
|
|
@@ -51,6 +58,8 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
51
58
|
rate: The rate for how quickly to aspirate.
|
|
52
59
|
flow_rate: The flow rate in µL/s to aspirate at.
|
|
53
60
|
in_place: Whether this is in-place.
|
|
61
|
+
meniscus_tracking: Optional data about where to aspirate from.
|
|
62
|
+
correction_volume: The correction volume in uL
|
|
54
63
|
"""
|
|
55
64
|
...
|
|
56
65
|
|
|
@@ -64,7 +73,8 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
64
73
|
flow_rate: float,
|
|
65
74
|
in_place: bool,
|
|
66
75
|
push_out: Optional[float],
|
|
67
|
-
|
|
76
|
+
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
77
|
+
correction_volume: Optional[float] = None,
|
|
68
78
|
) -> None:
|
|
69
79
|
"""Dispense a given volume of liquid into the specified location.
|
|
70
80
|
Args:
|
|
@@ -75,6 +85,8 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
75
85
|
flow_rate: The flow rate in µL/s to dispense at.
|
|
76
86
|
in_place: Whether this is in-place.
|
|
77
87
|
push_out: The amount to push the plunger below bottom position.
|
|
88
|
+
correction_volume: The correction volume in uL
|
|
89
|
+
meniscus_tracking: Optional data about where to dispense from.
|
|
78
90
|
"""
|
|
79
91
|
...
|
|
80
92
|
|
|
@@ -102,6 +114,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
102
114
|
radius: float,
|
|
103
115
|
z_offset: float,
|
|
104
116
|
speed: float,
|
|
117
|
+
mm_from_edge: Optional[float] = None,
|
|
105
118
|
) -> None:
|
|
106
119
|
...
|
|
107
120
|
|
|
@@ -177,6 +190,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
177
190
|
force_direct: bool,
|
|
178
191
|
minimum_z_height: Optional[float],
|
|
179
192
|
speed: Optional[float],
|
|
193
|
+
check_for_movement_conflicts: bool,
|
|
180
194
|
) -> None:
|
|
181
195
|
...
|
|
182
196
|
|
|
@@ -192,7 +206,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
192
206
|
@abstractmethod
|
|
193
207
|
def resin_tip_unseal(
|
|
194
208
|
self,
|
|
195
|
-
location: types.Location,
|
|
209
|
+
location: types.Location | None,
|
|
196
210
|
well_core: WellCoreType,
|
|
197
211
|
) -> None:
|
|
198
212
|
...
|
|
@@ -239,10 +253,18 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
239
253
|
def get_current_volume(self) -> float:
|
|
240
254
|
...
|
|
241
255
|
|
|
256
|
+
@abstractmethod
|
|
257
|
+
def get_has_clean_tip(self) -> bool:
|
|
258
|
+
...
|
|
259
|
+
|
|
242
260
|
@abstractmethod
|
|
243
261
|
def get_available_volume(self) -> float:
|
|
244
262
|
...
|
|
245
263
|
|
|
264
|
+
@abstractmethod
|
|
265
|
+
def get_minimum_liquid_sense_height(self) -> float:
|
|
266
|
+
...
|
|
267
|
+
|
|
246
268
|
@abstractmethod
|
|
247
269
|
def get_hardware_state(self) -> PipetteDict:
|
|
248
270
|
"""Get the current state of the pipette hardware as a dictionary."""
|
|
@@ -338,29 +360,57 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
338
360
|
...
|
|
339
361
|
|
|
340
362
|
@abstractmethod
|
|
341
|
-
def
|
|
363
|
+
def transfer_with_liquid_class(
|
|
342
364
|
self,
|
|
343
365
|
liquid_class: LiquidClass,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
366
|
+
volume: float,
|
|
367
|
+
source: List[Tuple[types.Location, WellCoreType]],
|
|
368
|
+
dest: List[Tuple[types.Location, WellCoreType]],
|
|
369
|
+
new_tip: TransferTipPolicyV2,
|
|
370
|
+
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
371
|
+
starting_tip: Optional[WellCoreType],
|
|
372
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
373
|
+
return_tip: bool,
|
|
374
|
+
) -> None:
|
|
375
|
+
"""Transfer a liquid from source to dest according to liquid class properties."""
|
|
376
|
+
...
|
|
348
377
|
|
|
349
|
-
|
|
378
|
+
@abstractmethod
|
|
379
|
+
def distribute_with_liquid_class(
|
|
380
|
+
self,
|
|
381
|
+
liquid_class: LiquidClass,
|
|
382
|
+
volume: float,
|
|
383
|
+
source: Tuple[types.Location, WellCoreType],
|
|
384
|
+
dest: List[Tuple[types.Location, WellCoreType]],
|
|
385
|
+
new_tip: Literal[TransferTipPolicyV2.NEVER, TransferTipPolicyV2.ONCE],
|
|
386
|
+
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
387
|
+
starting_tip: Optional[WellCoreType],
|
|
388
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
389
|
+
return_tip: bool,
|
|
390
|
+
) -> None:
|
|
391
|
+
"""
|
|
392
|
+
Distribute a liquid from single source to multiple destinations
|
|
393
|
+
according to liquid class properties.
|
|
350
394
|
"""
|
|
351
395
|
...
|
|
352
396
|
|
|
353
397
|
@abstractmethod
|
|
354
|
-
def
|
|
398
|
+
def consolidate_with_liquid_class(
|
|
355
399
|
self,
|
|
356
|
-
|
|
400
|
+
liquid_class: LiquidClass,
|
|
357
401
|
volume: float,
|
|
358
|
-
source: List[WellCoreType],
|
|
359
|
-
dest:
|
|
360
|
-
new_tip: TransferTipPolicyV2,
|
|
361
|
-
|
|
402
|
+
source: List[Tuple[types.Location, WellCoreType]],
|
|
403
|
+
dest: Tuple[types.Location, WellCoreType],
|
|
404
|
+
new_tip: Literal[TransferTipPolicyV2.NEVER, TransferTipPolicyV2.ONCE],
|
|
405
|
+
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
406
|
+
starting_tip: Optional[WellCoreType],
|
|
407
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
408
|
+
return_tip: bool,
|
|
362
409
|
) -> None:
|
|
363
|
-
"""
|
|
410
|
+
"""
|
|
411
|
+
Consolidate liquid from multiple sources to a single destination
|
|
412
|
+
using the specified liquid class properties.
|
|
413
|
+
"""
|
|
364
414
|
...
|
|
365
415
|
|
|
366
416
|
@abstractmethod
|
|
@@ -388,7 +438,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
388
438
|
@abstractmethod
|
|
389
439
|
def liquid_probe_without_recovery(
|
|
390
440
|
self, well_core: WellCoreType, loc: types.Location
|
|
391
|
-
) ->
|
|
441
|
+
) -> LiquidTrackingType:
|
|
392
442
|
"""Do a liquid probe to find the level of the liquid in the well."""
|
|
393
443
|
...
|
|
394
444
|
|
|
@@ -397,4 +447,4 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
397
447
|
"""Check if the nozzle configuration currently supports LLD."""
|
|
398
448
|
|
|
399
449
|
|
|
400
|
-
InstrumentCoreType = TypeVar("InstrumentCoreType", bound=AbstractInstrument[Any])
|
|
450
|
+
InstrumentCoreType = TypeVar("InstrumentCoreType", bound=AbstractInstrument[Any, Any])
|
|
@@ -7,7 +7,8 @@ from typing import Any, Generic, List, NamedTuple, Optional, TypeVar, Dict
|
|
|
7
7
|
|
|
8
8
|
from opentrons_shared_data.labware.types import (
|
|
9
9
|
LabwareUri,
|
|
10
|
-
|
|
10
|
+
LabwareParameters2,
|
|
11
|
+
LabwareParameters3,
|
|
11
12
|
LabwareDefinition as LabwareDefinitionDict,
|
|
12
13
|
)
|
|
13
14
|
|
|
@@ -17,6 +18,9 @@ from .._liquid import Liquid
|
|
|
17
18
|
from .well import WellCoreType
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
_LabwareParametersDict = LabwareParameters2 | LabwareParameters3
|
|
22
|
+
|
|
23
|
+
|
|
20
24
|
class LabwareLoadParams(NamedTuple):
|
|
21
25
|
"""Unique load parameters of a labware."""
|
|
22
26
|
|
|
@@ -75,7 +79,7 @@ class AbstractLabware(ABC, Generic[WellCoreType]):
|
|
|
75
79
|
"""Get the labware's definition as a plain dictionary."""
|
|
76
80
|
|
|
77
81
|
@abstractmethod
|
|
78
|
-
def get_parameters(self) ->
|
|
82
|
+
def get_parameters(self) -> _LabwareParametersDict:
|
|
79
83
|
"""Get the labware's definition's `parameters` field as a plain dictionary."""
|
|
80
84
|
|
|
81
85
|
@abstractmethod
|
|
@@ -3,7 +3,11 @@ from dataclasses import dataclass
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
from opentrons.hardware_control.modules import ModuleModel as HardwareModuleModel
|
|
6
|
-
from opentrons.protocol_engine import
|
|
6
|
+
from opentrons.protocol_engine import (
|
|
7
|
+
ProtocolEngine,
|
|
8
|
+
LegacyLabwareOffsetLocation,
|
|
9
|
+
ModuleModel,
|
|
10
|
+
)
|
|
7
11
|
from opentrons.types import DeckSlotName, Point
|
|
8
12
|
|
|
9
13
|
from ..labware import LabwareLoadParams
|
|
@@ -81,9 +85,9 @@ class LabwareOffsetProvider(AbstractLabwareOffsetProvider):
|
|
|
81
85
|
|
|
82
86
|
See the parent class for param details.
|
|
83
87
|
"""
|
|
84
|
-
offset = self._labware_view.
|
|
88
|
+
offset = self._labware_view.find_applicable_labware_offset_by_legacy_location(
|
|
85
89
|
definition_uri=load_params.as_uri(),
|
|
86
|
-
location=
|
|
90
|
+
location=LegacyLabwareOffsetLocation(
|
|
87
91
|
slotName=deck_slot,
|
|
88
92
|
moduleModel=(
|
|
89
93
|
None
|
|
@@ -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 import CriticalPoint
|
|
@@ -22,9 +22,12 @@ from opentrons.protocols.geometry import planning
|
|
|
22
22
|
from opentrons.protocol_api._nozzle_layout import NozzleLayout
|
|
23
23
|
from opentrons.protocol_api._liquid import LiquidClass
|
|
24
24
|
|
|
25
|
+
from opentrons.protocol_engine.types import LiquidTrackingType
|
|
26
|
+
|
|
25
27
|
from ...disposal_locations import TrashBin, WasteChute
|
|
26
28
|
from ..instrument import AbstractInstrument
|
|
27
29
|
from .legacy_well_core import LegacyWellCore
|
|
30
|
+
from .legacy_labware_core import LegacyLabwareCore
|
|
28
31
|
from .legacy_module_core import LegacyThermocyclerCore, LegacyHeaterShakerCore
|
|
29
32
|
|
|
30
33
|
if TYPE_CHECKING:
|
|
@@ -37,7 +40,7 @@ _PRE_2_2_TIP_DROP_HEIGHT_MM = 10
|
|
|
37
40
|
"""In PAPIv2.1 and below, tips are always dropped 10 mm from the bottom of the well."""
|
|
38
41
|
|
|
39
42
|
|
|
40
|
-
class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
43
|
+
class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore, LegacyLabwareCore]):
|
|
41
44
|
"""Implementation of the InstrumentContext interface."""
|
|
42
45
|
|
|
43
46
|
def __init__(
|
|
@@ -73,7 +76,9 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
73
76
|
"""Sets the speed at which the robot's gantry moves."""
|
|
74
77
|
self._default_speed = speed
|
|
75
78
|
|
|
76
|
-
def air_gap_in_place(
|
|
79
|
+
def air_gap_in_place(
|
|
80
|
+
self, volume: float, flow_rate: float, correction_volume: Optional[float] = None
|
|
81
|
+
) -> None:
|
|
77
82
|
assert False, "Air gap tracking only available in API version 2.22 and later"
|
|
78
83
|
|
|
79
84
|
def aspirate(
|
|
@@ -84,7 +89,8 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
84
89
|
rate: float,
|
|
85
90
|
flow_rate: float,
|
|
86
91
|
in_place: bool,
|
|
87
|
-
|
|
92
|
+
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
93
|
+
correction_volume: Optional[float] = None,
|
|
88
94
|
) -> None:
|
|
89
95
|
"""Aspirate a given volume of liquid from the specified location.
|
|
90
96
|
Args:
|
|
@@ -94,6 +100,8 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
94
100
|
rate: The rate in µL/s to aspirate at.
|
|
95
101
|
flow_rate: Not used in this core.
|
|
96
102
|
in_place: Whether we should move_to location.
|
|
103
|
+
correction_volume: Not used in this core
|
|
104
|
+
meniscus_tracking: Optional data about where to aspirate from.
|
|
97
105
|
"""
|
|
98
106
|
if self.get_current_volume() == 0:
|
|
99
107
|
# Make sure we're at the top of the labware and clear of any
|
|
@@ -127,7 +135,8 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
127
135
|
flow_rate: float,
|
|
128
136
|
in_place: bool,
|
|
129
137
|
push_out: Optional[float],
|
|
130
|
-
|
|
138
|
+
meniscus_tracking: Optional[types.MeniscusTrackingTarget] = None,
|
|
139
|
+
correction_volume: Optional[float] = None,
|
|
131
140
|
) -> None:
|
|
132
141
|
"""Dispense a given volume of liquid into the specified location.
|
|
133
142
|
Args:
|
|
@@ -137,7 +146,9 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
137
146
|
rate: The rate in µL/s to dispense at.
|
|
138
147
|
flow_rate: Not used in this core.
|
|
139
148
|
in_place: Whether we should move_to location.
|
|
149
|
+
correction_volume: Not used in this core.
|
|
140
150
|
push_out: The amount to push the plunger below bottom position.
|
|
151
|
+
meniscus_tracking: Optional data about where to dispense from.
|
|
141
152
|
"""
|
|
142
153
|
if isinstance(location, (TrashBin, WasteChute)):
|
|
143
154
|
raise APIVersionError(
|
|
@@ -179,11 +190,14 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
179
190
|
radius: float,
|
|
180
191
|
z_offset: float,
|
|
181
192
|
speed: float,
|
|
193
|
+
mm_from_edge: Optional[float] = None,
|
|
182
194
|
) -> None:
|
|
183
195
|
"""
|
|
184
196
|
Touch the pipette tip to the sides of a well, with the intent of
|
|
185
197
|
removing left-over droplets
|
|
186
198
|
"""
|
|
199
|
+
if mm_from_edge is not None:
|
|
200
|
+
raise APIVersionError(api_element="mm_from_edge argument")
|
|
187
201
|
# TODO al 20201110 - build_edges relies on where being a Well. This is
|
|
188
202
|
# an unpleasant compromise until refactoring build_edges to support
|
|
189
203
|
# LegacyWellCore.
|
|
@@ -318,7 +332,7 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
318
332
|
|
|
319
333
|
def resin_tip_unseal(
|
|
320
334
|
self,
|
|
321
|
-
location: types.Location,
|
|
335
|
+
location: types.Location | None,
|
|
322
336
|
well_core: WellCore,
|
|
323
337
|
) -> None:
|
|
324
338
|
raise APIVersionError(api_element="Unsealing resin tips.")
|
|
@@ -353,6 +367,7 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
353
367
|
force_direct: bool = False,
|
|
354
368
|
minimum_z_height: Optional[float] = None,
|
|
355
369
|
speed: Optional[float] = None,
|
|
370
|
+
check_for_movement_conflicts: bool = False,
|
|
356
371
|
) -> None:
|
|
357
372
|
"""Move the instrument.
|
|
358
373
|
|
|
@@ -362,6 +377,7 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
362
377
|
force_direct: Force a direct movement instead of an arc.
|
|
363
378
|
minimum_z_height: Set a minimum travel height for a movement arc.
|
|
364
379
|
speed: Override the travel speed in mm/s.
|
|
380
|
+
check_for_movement_conflicts: Not used in legacy implementation
|
|
365
381
|
|
|
366
382
|
Raises:
|
|
367
383
|
LabwareHeightError: An item on the deck is taller than
|
|
@@ -424,32 +440,6 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
424
440
|
location=location, mount=location_cache_mount
|
|
425
441
|
)
|
|
426
442
|
|
|
427
|
-
def evotip_seal(
|
|
428
|
-
self,
|
|
429
|
-
location: types.Location,
|
|
430
|
-
well_core: LegacyWellCore,
|
|
431
|
-
in_place: Optional[bool] = False,
|
|
432
|
-
) -> None:
|
|
433
|
-
"""This will never be called because it was added in API 2.22."""
|
|
434
|
-
assert False, "evotip_seal only supported in API 2.22 & later"
|
|
435
|
-
|
|
436
|
-
def evotip_unseal(
|
|
437
|
-
self, location: types.Location, well_core: WellCore, home_after: Optional[bool]
|
|
438
|
-
) -> None:
|
|
439
|
-
"""This will never be called because it was added in API 2.22."""
|
|
440
|
-
assert False, "evotip_unseal only supported in API 2.22 & later"
|
|
441
|
-
|
|
442
|
-
def evotip_dispense(
|
|
443
|
-
self,
|
|
444
|
-
location: types.Location,
|
|
445
|
-
well_core: WellCore,
|
|
446
|
-
volume: Optional[float] = None,
|
|
447
|
-
flow_rate: Optional[float] = None,
|
|
448
|
-
push_out: Optional[float] = None,
|
|
449
|
-
) -> None:
|
|
450
|
-
"""This will never be called because it was added in API 2.22."""
|
|
451
|
-
assert False, "evotip_dispense only supported in API 2.22 & later"
|
|
452
|
-
|
|
453
443
|
def get_mount(self) -> types.Mount:
|
|
454
444
|
"""Get the mount this pipette is attached to."""
|
|
455
445
|
return self._mount
|
|
@@ -486,6 +476,10 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
486
476
|
"""Get the current volume."""
|
|
487
477
|
return self.get_hardware_state()["current_volume"]
|
|
488
478
|
|
|
479
|
+
def get_has_clean_tip(self) -> bool:
|
|
480
|
+
"""Get if has a clean tip, only used with LLD and engine commands."""
|
|
481
|
+
return False
|
|
482
|
+
|
|
489
483
|
def get_available_volume(self) -> float:
|
|
490
484
|
"""Get the available volume."""
|
|
491
485
|
return self.get_hardware_state()["available_volume"]
|
|
@@ -606,29 +600,51 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
606
600
|
"""This will never be called because it was added in API 2.16."""
|
|
607
601
|
pass
|
|
608
602
|
|
|
609
|
-
def
|
|
603
|
+
def transfer_with_liquid_class(
|
|
610
604
|
self,
|
|
611
605
|
liquid_class: LiquidClass,
|
|
612
|
-
pipette_load_name: str,
|
|
613
|
-
tiprack_uri: str,
|
|
614
|
-
) -> str:
|
|
615
|
-
"""This will never be called because it was added in .."""
|
|
616
|
-
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
617
|
-
assert False, "load_liquid_class is not supported in legacy context"
|
|
618
|
-
|
|
619
|
-
def transfer_liquid(
|
|
620
|
-
self,
|
|
621
|
-
liquid_class_id: str,
|
|
622
606
|
volume: float,
|
|
623
|
-
source: List[LegacyWellCore],
|
|
624
|
-
dest: List[LegacyWellCore],
|
|
607
|
+
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
608
|
+
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
625
609
|
new_tip: TransferTipPolicyV2,
|
|
626
|
-
|
|
610
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
611
|
+
starting_tip: Optional[LegacyWellCore],
|
|
612
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
613
|
+
return_tip: bool,
|
|
627
614
|
) -> None:
|
|
628
|
-
"""This will never be called because it was added in
|
|
629
|
-
# TODO(spp, 2024-11-20): update the docstring and error to include API version
|
|
615
|
+
"""This will never be called because it was added in API 2.23"""
|
|
630
616
|
assert False, "transfer_liquid is not supported in legacy context"
|
|
631
617
|
|
|
618
|
+
def distribute_with_liquid_class(
|
|
619
|
+
self,
|
|
620
|
+
liquid_class: LiquidClass,
|
|
621
|
+
volume: float,
|
|
622
|
+
source: Tuple[types.Location, LegacyWellCore],
|
|
623
|
+
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
624
|
+
new_tip: Literal[TransferTipPolicyV2.NEVER, TransferTipPolicyV2.ONCE],
|
|
625
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
626
|
+
starting_tip: Optional[LegacyWellCore],
|
|
627
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
628
|
+
return_tip: bool,
|
|
629
|
+
) -> None:
|
|
630
|
+
"""This will never be called because it was added in API 2.23"""
|
|
631
|
+
assert False, "distribute_liquid is not supported in legacy context"
|
|
632
|
+
|
|
633
|
+
def consolidate_with_liquid_class(
|
|
634
|
+
self,
|
|
635
|
+
liquid_class: LiquidClass,
|
|
636
|
+
volume: float,
|
|
637
|
+
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
638
|
+
dest: Tuple[types.Location, LegacyWellCore],
|
|
639
|
+
new_tip: Literal[TransferTipPolicyV2.NEVER, TransferTipPolicyV2.ONCE],
|
|
640
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
641
|
+
starting_tip: Optional[LegacyWellCore],
|
|
642
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
643
|
+
return_tip: bool,
|
|
644
|
+
) -> None:
|
|
645
|
+
"""This will never be called because it was added in API 2.23."""
|
|
646
|
+
assert False, "consolidate_liquid is not supported in legacy context"
|
|
647
|
+
|
|
632
648
|
def get_active_channels(self) -> int:
|
|
633
649
|
"""This will never be called because it was added in API 2.16."""
|
|
634
650
|
assert False, "get_active_channels only supported in API 2.16 & later"
|
|
@@ -657,7 +673,7 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
657
673
|
|
|
658
674
|
def liquid_probe_without_recovery(
|
|
659
675
|
self, well_core: WellCore, loc: types.Location
|
|
660
|
-
) ->
|
|
676
|
+
) -> LiquidTrackingType:
|
|
661
677
|
"""This will never be called because it was added in API 2.20."""
|
|
662
678
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
663
679
|
|
|
@@ -667,3 +683,14 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
667
683
|
def nozzle_configuration_valid_for_lld(self) -> bool:
|
|
668
684
|
"""Check if the nozzle configuration currently supports LLD."""
|
|
669
685
|
return False
|
|
686
|
+
|
|
687
|
+
def get_minimum_liquid_sense_height(self) -> float:
|
|
688
|
+
return 0.0
|
|
689
|
+
|
|
690
|
+
def estimate_liquid_height(
|
|
691
|
+
self,
|
|
692
|
+
well_core: LegacyWellCore,
|
|
693
|
+
starting_liquid_height: float,
|
|
694
|
+
operation_volume: float,
|
|
695
|
+
) -> float:
|
|
696
|
+
return 0.0
|
|
@@ -6,7 +6,7 @@ from opentrons.protocols.api_support.tip_tracker import TipTracker
|
|
|
6
6
|
|
|
7
7
|
from opentrons.types import DeckSlotName, Location, Point, NozzleMapInterface
|
|
8
8
|
|
|
9
|
-
from opentrons_shared_data.labware.types import
|
|
9
|
+
from opentrons_shared_data.labware.types import LabwareParameters2, LabwareDefinition2
|
|
10
10
|
|
|
11
11
|
from ..._liquid import Liquid
|
|
12
12
|
from ..labware import AbstractLabware, LabwareLoadParams
|
|
@@ -36,7 +36,11 @@ class LegacyLabwareCore(AbstractLabware[LegacyWellCore]):
|
|
|
36
36
|
|
|
37
37
|
def __init__(
|
|
38
38
|
self,
|
|
39
|
-
|
|
39
|
+
# We need labware schema 2, specifically, because schema 3 changes how positions
|
|
40
|
+
# are calculated, and we don't attempt to handle that here in
|
|
41
|
+
# `opentrons.protocol_api.core.legacy`. We do handle it in
|
|
42
|
+
# `opentrons.protocol_api.core.engine` and `opentrons.protocol_engine`.
|
|
43
|
+
definition: LabwareDefinition2,
|
|
40
44
|
parent: Location,
|
|
41
45
|
label: Optional[str] = None,
|
|
42
46
|
) -> None:
|
|
@@ -106,10 +110,10 @@ class LegacyLabwareCore(AbstractLabware[LegacyWellCore]):
|
|
|
106
110
|
def set_name(self, new_name: str) -> None:
|
|
107
111
|
self._name = new_name
|
|
108
112
|
|
|
109
|
-
def get_definition(self) ->
|
|
113
|
+
def get_definition(self) -> LabwareDefinition2:
|
|
110
114
|
return self._definition
|
|
111
115
|
|
|
112
|
-
def get_parameters(self) ->
|
|
116
|
+
def get_parameters(self) -> LabwareParameters2:
|
|
113
117
|
return self._parameters
|
|
114
118
|
|
|
115
119
|
def get_quirks(self) -> List[str]:
|