opentrons 8.3.1a1__py2.py3-none-any.whl → 8.4.0a1__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.
- 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 +19 -3
- opentrons/legacy_commands/helpers.py +15 -0
- opentrons/legacy_commands/types.py +3 -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 +1233 -65
- 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/protocol.py +253 -11
- opentrons/protocol_api/core/engine/stringify.py +19 -8
- opentrons/protocol_api/core/engine/transfer_components_executor.py +853 -0
- opentrons/protocol_api/core/engine/well.py +60 -5
- opentrons/protocol_api/core/instrument.py +65 -19
- 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 +69 -21
- 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 +25 -1
- 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 +67 -21
- opentrons/protocol_api/core/module.py +43 -0
- opentrons/protocol_api/core/protocol.py +33 -0
- opentrons/protocol_api/core/well.py +21 -1
- opentrons/protocol_api/instrument_context.py +246 -123
- opentrons/protocol_api/labware.py +75 -11
- opentrons/protocol_api/module_contexts.py +140 -0
- opentrons/protocol_api/protocol_context.py +156 -16
- 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 +30 -0
- 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 +237 -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 +69 -0
- 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 +240 -0
- opentrons/protocol_engine/commands/drop_tip.py +23 -1
- opentrons/protocol_engine/commands/evotip_dispense.py +6 -7
- opentrons/protocol_engine/commands/evotip_seal_pipette.py +24 -29
- opentrons/protocol_engine/commands/evotip_unseal_pipette.py +1 -7
- 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 +288 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
- opentrons/protocol_engine/commands/labware_handling_common.py +24 -0
- opentrons/protocol_engine/commands/liquid_probe.py +21 -12
- 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/pick_up_tip.py +5 -2
- opentrons/protocol_engine/commands/pipetting_common.py +154 -7
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +17 -2
- opentrons/protocol_engine/commands/reload_labware.py +6 -19
- 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/errors/__init__.py +8 -0
- opentrons/protocol_engine/errors/exceptions.py +50 -0
- opentrons/protocol_engine/execution/equipment.py +123 -106
- opentrons/protocol_engine/execution/labware_movement.py +8 -6
- opentrons/protocol_engine/execution/pipetting.py +233 -26
- opentrons/protocol_engine/execution/tip_handler.py +14 -5
- opentrons/protocol_engine/labware_offset_standardization.py +173 -0
- opentrons/protocol_engine/protocol_engine.py +22 -13
- opentrons/protocol_engine/resources/deck_configuration_provider.py +94 -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 +26 -10
- opentrons/protocol_engine/state/geometry.py +683 -100
- 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 +178 -52
- 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 +54 -8
- opentrons/protocol_engine/types/__init__.py +292 -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 +110 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +108 -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 +137 -0
- opentrons/protocol_engine/types/location.py +193 -0
- opentrons/protocol_engine/types/module.py +269 -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 +107 -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 +5 -6
- opentrons/protocols/models/__init__.py +0 -21
- opentrons/simulate.py +4 -2
- opentrons/types.py +15 -6
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/METADATA +4 -4
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/RECORD +188 -148
- 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.1a1.dist-info → opentrons-8.4.0a1.dist-info}/LICENSE +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/WHEEL +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/top_level.txt +0 -0
|
@@ -1,13 +1,18 @@
|
|
|
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
|
|
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
|
+
)
|
|
11
16
|
|
|
12
17
|
from . import point_calculations
|
|
13
18
|
from . import stringify
|
|
@@ -44,17 +49,27 @@ class WellCore(AbstractWellCore):
|
|
|
44
49
|
@property
|
|
45
50
|
def diameter(self) -> Optional[float]:
|
|
46
51
|
"""Get the well's diameter, if circular."""
|
|
47
|
-
return
|
|
52
|
+
return (
|
|
53
|
+
self._definition.diameter if self._definition.shape == "circular" else None
|
|
54
|
+
)
|
|
48
55
|
|
|
49
56
|
@property
|
|
50
57
|
def length(self) -> Optional[float]:
|
|
51
58
|
"""Get the well's length, if rectangular."""
|
|
52
|
-
return
|
|
59
|
+
return (
|
|
60
|
+
self._definition.xDimension
|
|
61
|
+
if self._definition.shape == "rectangular"
|
|
62
|
+
else None
|
|
63
|
+
)
|
|
53
64
|
|
|
54
65
|
@property
|
|
55
66
|
def width(self) -> Optional[float]:
|
|
56
67
|
"""Get the well's width, if rectangular."""
|
|
57
|
-
return
|
|
68
|
+
return (
|
|
69
|
+
self._definition.yDimension
|
|
70
|
+
if self._definition.shape == "rectangular"
|
|
71
|
+
else None
|
|
72
|
+
)
|
|
58
73
|
|
|
59
74
|
@property
|
|
60
75
|
def depth(self) -> float:
|
|
@@ -125,6 +140,14 @@ class WellCore(AbstractWellCore):
|
|
|
125
140
|
well_location=WellLocation(origin=WellOrigin.CENTER),
|
|
126
141
|
)
|
|
127
142
|
|
|
143
|
+
def get_meniscus(self) -> Union[Point, SimulatedProbeResult]:
|
|
144
|
+
"""Get the coordinate of the well's meniscus."""
|
|
145
|
+
current_liquid_height = self.current_liquid_height()
|
|
146
|
+
if isinstance(current_liquid_height, float):
|
|
147
|
+
return self.get_bottom(z_offset=current_liquid_height)
|
|
148
|
+
else:
|
|
149
|
+
return current_liquid_height
|
|
150
|
+
|
|
128
151
|
def load_liquid(
|
|
129
152
|
self,
|
|
130
153
|
liquid: Liquid,
|
|
@@ -155,3 +178,35 @@ class WellCore(AbstractWellCore):
|
|
|
155
178
|
y_ratio=y,
|
|
156
179
|
z_ratio=z,
|
|
157
180
|
)
|
|
181
|
+
|
|
182
|
+
def estimate_liquid_height_after_pipetting(
|
|
183
|
+
self,
|
|
184
|
+
operation_volume: float,
|
|
185
|
+
) -> LiquidTrackingType:
|
|
186
|
+
"""Return an estimate of liquid height after pipetting without raising an error."""
|
|
187
|
+
labware_id = self.labware_id
|
|
188
|
+
well_name = self._name
|
|
189
|
+
starting_liquid_height = self.current_liquid_height()
|
|
190
|
+
projected_final_height = self._engine_client.state.geometry.get_well_height_after_liquid_handling_no_error(
|
|
191
|
+
labware_id=labware_id,
|
|
192
|
+
well_name=well_name,
|
|
193
|
+
initial_height=starting_liquid_height,
|
|
194
|
+
volume=operation_volume,
|
|
195
|
+
)
|
|
196
|
+
return projected_final_height
|
|
197
|
+
|
|
198
|
+
def current_liquid_height(self) -> LiquidTrackingType:
|
|
199
|
+
"""Return the current liquid height within a well."""
|
|
200
|
+
labware_id = self.labware_id
|
|
201
|
+
well_name = self._name
|
|
202
|
+
return self._engine_client.state.geometry.get_meniscus_height(
|
|
203
|
+
labware_id=labware_id, well_name=well_name
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
207
|
+
"""Return the current volume in a well."""
|
|
208
|
+
labware_id = self.labware_id
|
|
209
|
+
well_name = self._name
|
|
210
|
+
return self._engine_client.state.geometry.get_current_well_volume(
|
|
211
|
+
labware_id=labware_id, well_name=well_name
|
|
212
|
+
)
|
|
@@ -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
|
|
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.liquid_level_detection 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
|
|
|
@@ -239,10 +252,18 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
239
252
|
def get_current_volume(self) -> float:
|
|
240
253
|
...
|
|
241
254
|
|
|
255
|
+
@abstractmethod
|
|
256
|
+
def get_has_clean_tip(self) -> bool:
|
|
257
|
+
...
|
|
258
|
+
|
|
242
259
|
@abstractmethod
|
|
243
260
|
def get_available_volume(self) -> float:
|
|
244
261
|
...
|
|
245
262
|
|
|
263
|
+
@abstractmethod
|
|
264
|
+
def get_minimum_liquid_sense_height(self) -> float:
|
|
265
|
+
...
|
|
266
|
+
|
|
246
267
|
@abstractmethod
|
|
247
268
|
def get_hardware_state(self) -> PipetteDict:
|
|
248
269
|
"""Get the current state of the pipette hardware as a dictionary."""
|
|
@@ -338,29 +359,54 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
338
359
|
...
|
|
339
360
|
|
|
340
361
|
@abstractmethod
|
|
341
|
-
def
|
|
362
|
+
def transfer_liquid(
|
|
342
363
|
self,
|
|
343
364
|
liquid_class: LiquidClass,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
365
|
+
volume: float,
|
|
366
|
+
source: List[Tuple[types.Location, WellCoreType]],
|
|
367
|
+
dest: List[Tuple[types.Location, WellCoreType]],
|
|
368
|
+
new_tip: TransferTipPolicyV2,
|
|
369
|
+
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
370
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
371
|
+
return_tip: bool,
|
|
372
|
+
) -> None:
|
|
373
|
+
"""Transfer a liquid from source to dest according to liquid class properties."""
|
|
374
|
+
...
|
|
348
375
|
|
|
349
|
-
|
|
376
|
+
@abstractmethod
|
|
377
|
+
def distribute_liquid(
|
|
378
|
+
self,
|
|
379
|
+
liquid_class: LiquidClass,
|
|
380
|
+
volume: float,
|
|
381
|
+
source: Tuple[types.Location, WellCoreType],
|
|
382
|
+
dest: List[Tuple[types.Location, WellCoreType]],
|
|
383
|
+
new_tip: TransferTipPolicyV2,
|
|
384
|
+
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
385
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
386
|
+
return_tip: bool,
|
|
387
|
+
) -> None:
|
|
388
|
+
"""
|
|
389
|
+
Distribute a liquid from single source to multiple destinations
|
|
390
|
+
according to liquid class properties.
|
|
350
391
|
"""
|
|
351
392
|
...
|
|
352
393
|
|
|
353
394
|
@abstractmethod
|
|
354
|
-
def
|
|
395
|
+
def consolidate_liquid(
|
|
355
396
|
self,
|
|
356
|
-
|
|
397
|
+
liquid_class: LiquidClass,
|
|
357
398
|
volume: float,
|
|
358
|
-
source: List[WellCoreType],
|
|
359
|
-
dest:
|
|
399
|
+
source: List[Tuple[types.Location, WellCoreType]],
|
|
400
|
+
dest: Tuple[types.Location, WellCoreType],
|
|
360
401
|
new_tip: TransferTipPolicyV2,
|
|
361
|
-
|
|
402
|
+
tip_racks: List[Tuple[types.Location, LabwareCoreType]],
|
|
403
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
404
|
+
return_tip: bool,
|
|
362
405
|
) -> None:
|
|
363
|
-
"""
|
|
406
|
+
"""
|
|
407
|
+
Consolidate liquid from multiple sources to a single destination
|
|
408
|
+
using the specified liquid class properties.
|
|
409
|
+
"""
|
|
364
410
|
...
|
|
365
411
|
|
|
366
412
|
@abstractmethod
|
|
@@ -388,7 +434,7 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
388
434
|
@abstractmethod
|
|
389
435
|
def liquid_probe_without_recovery(
|
|
390
436
|
self, well_core: WellCoreType, loc: types.Location
|
|
391
|
-
) ->
|
|
437
|
+
) -> LiquidTrackingType:
|
|
392
438
|
"""Do a liquid probe to find the level of the liquid in the well."""
|
|
393
439
|
...
|
|
394
440
|
|
|
@@ -397,4 +443,4 @@ class AbstractInstrument(ABC, Generic[WellCoreType]):
|
|
|
397
443
|
"""Check if the nozzle configuration currently supports LLD."""
|
|
398
444
|
|
|
399
445
|
|
|
400
|
-
InstrumentCoreType = TypeVar("InstrumentCoreType", bound=AbstractInstrument[Any])
|
|
446
|
+
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
|
|
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.liquid_level_detection 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.
|
|
@@ -486,6 +500,10 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
486
500
|
"""Get the current volume."""
|
|
487
501
|
return self.get_hardware_state()["current_volume"]
|
|
488
502
|
|
|
503
|
+
def get_has_clean_tip(self) -> bool:
|
|
504
|
+
"""Get if has a clean tip, only used with LLD and engine commands."""
|
|
505
|
+
return False
|
|
506
|
+
|
|
489
507
|
def get_available_volume(self) -> float:
|
|
490
508
|
"""Get the available volume."""
|
|
491
509
|
return self.get_hardware_state()["available_volume"]
|
|
@@ -606,28 +624,47 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
606
624
|
"""This will never be called because it was added in API 2.16."""
|
|
607
625
|
pass
|
|
608
626
|
|
|
609
|
-
def
|
|
627
|
+
def transfer_liquid(
|
|
610
628
|
self,
|
|
611
629
|
liquid_class: LiquidClass,
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
630
|
+
volume: float,
|
|
631
|
+
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
632
|
+
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
633
|
+
new_tip: TransferTipPolicyV2,
|
|
634
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
635
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
636
|
+
return_tip: bool,
|
|
637
|
+
) -> None:
|
|
638
|
+
"""This will never be called because it was added in API 2.23"""
|
|
639
|
+
assert False, "transfer_liquid is not supported in legacy context"
|
|
618
640
|
|
|
619
|
-
def
|
|
641
|
+
def distribute_liquid(
|
|
620
642
|
self,
|
|
621
|
-
|
|
643
|
+
liquid_class: LiquidClass,
|
|
622
644
|
volume: float,
|
|
623
|
-
source:
|
|
624
|
-
dest: List[LegacyWellCore],
|
|
645
|
+
source: Tuple[types.Location, LegacyWellCore],
|
|
646
|
+
dest: List[Tuple[types.Location, LegacyWellCore]],
|
|
625
647
|
new_tip: TransferTipPolicyV2,
|
|
626
|
-
|
|
648
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
649
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
650
|
+
return_tip: bool,
|
|
627
651
|
) -> None:
|
|
628
|
-
"""This will never be called because it was added in
|
|
629
|
-
|
|
630
|
-
|
|
652
|
+
"""This will never be called because it was added in API 2.23"""
|
|
653
|
+
assert False, "distribute_liquid is not supported in legacy context"
|
|
654
|
+
|
|
655
|
+
def consolidate_liquid(
|
|
656
|
+
self,
|
|
657
|
+
liquid_class: LiquidClass,
|
|
658
|
+
volume: float,
|
|
659
|
+
source: List[Tuple[types.Location, LegacyWellCore]],
|
|
660
|
+
dest: Tuple[types.Location, LegacyWellCore],
|
|
661
|
+
new_tip: TransferTipPolicyV2,
|
|
662
|
+
tip_racks: List[Tuple[types.Location, LegacyLabwareCore]],
|
|
663
|
+
trash_location: Union[types.Location, TrashBin, WasteChute],
|
|
664
|
+
return_tip: bool,
|
|
665
|
+
) -> None:
|
|
666
|
+
"""This will never be called because it was added in API 2.23."""
|
|
667
|
+
assert False, "consolidate_liquid is not supported in legacy context"
|
|
631
668
|
|
|
632
669
|
def get_active_channels(self) -> int:
|
|
633
670
|
"""This will never be called because it was added in API 2.16."""
|
|
@@ -657,7 +694,7 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
657
694
|
|
|
658
695
|
def liquid_probe_without_recovery(
|
|
659
696
|
self, well_core: WellCore, loc: types.Location
|
|
660
|
-
) ->
|
|
697
|
+
) -> LiquidTrackingType:
|
|
661
698
|
"""This will never be called because it was added in API 2.20."""
|
|
662
699
|
assert False, "liquid_probe_without_recovery only supported in API 2.20 & later"
|
|
663
700
|
|
|
@@ -667,3 +704,14 @@ class LegacyInstrumentCore(AbstractInstrument[LegacyWellCore]):
|
|
|
667
704
|
def nozzle_configuration_valid_for_lld(self) -> bool:
|
|
668
705
|
"""Check if the nozzle configuration currently supports LLD."""
|
|
669
706
|
return False
|
|
707
|
+
|
|
708
|
+
def get_minimum_liquid_sense_height(self) -> float:
|
|
709
|
+
return 0.0
|
|
710
|
+
|
|
711
|
+
def estimate_liquid_height(
|
|
712
|
+
self,
|
|
713
|
+
well_core: LegacyWellCore,
|
|
714
|
+
starting_liquid_height: float,
|
|
715
|
+
operation_volume: float,
|
|
716
|
+
) -> float:
|
|
717
|
+
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]:
|
|
@@ -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,5 +1,5 @@
|
|
|
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
|
|
|
@@ -7,6 +7,11 @@ from opentrons.protocols.api_support.util import APIVersionError
|
|
|
7
7
|
|
|
8
8
|
from opentrons.types import Point
|
|
9
9
|
|
|
10
|
+
from opentrons.protocol_engine.types.liquid_level_detection import (
|
|
11
|
+
SimulatedProbeResult,
|
|
12
|
+
LiquidTrackingType,
|
|
13
|
+
)
|
|
14
|
+
|
|
10
15
|
from .well_geometry import WellGeometry
|
|
11
16
|
from ..well import AbstractWellCore
|
|
12
17
|
from ..._liquid import Liquid
|
|
@@ -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,21 @@ 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
|
+
operation_volume: float,
|
|
133
|
+
) -> LiquidTrackingType:
|
|
134
|
+
"""Estimate what the liquid height will be after pipetting, without raising an error."""
|
|
135
|
+
return 0.0
|
|
136
|
+
|
|
137
|
+
def current_liquid_height(self) -> LiquidTrackingType:
|
|
138
|
+
"""Get the current liquid height."""
|
|
139
|
+
return 0.0
|
|
140
|
+
|
|
141
|
+
def get_liquid_volume(self) -> LiquidTrackingType:
|
|
142
|
+
"""Get the current well volume."""
|
|
143
|
+
return 0.0
|
|
144
|
+
|
|
121
145
|
# TODO(mc, 2022-10-28): is this used and/or necessary?
|
|
122
146
|
def __repr__(self) -> str:
|
|
123
147
|
"""Use the well's display name as its repr."""
|