opentrons 8.0.0a7__py2.py3-none-any.whl → 8.0.0a9__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/protocol_engine/commands/liquid_probe.py +27 -7
- opentrons/protocol_engine/execution/pipetting.py +0 -11
- opentrons/protocol_engine/execution/tip_handler.py +21 -4
- opentrons/protocol_engine/state/pipettes.py +1 -1
- {opentrons-8.0.0a7.dist-info → opentrons-8.0.0a9.dist-info}/METADATA +4 -4
- {opentrons-8.0.0a7.dist-info → opentrons-8.0.0a9.dist-info}/RECORD +10 -10
- {opentrons-8.0.0a7.dist-info → opentrons-8.0.0a9.dist-info}/LICENSE +0 -0
- {opentrons-8.0.0a7.dist-info → opentrons-8.0.0a9.dist-info}/WHEEL +0 -0
- {opentrons-8.0.0a7.dist-info → opentrons-8.0.0a9.dist-info}/entry_points.txt +0 -0
- {opentrons-8.0.0a7.dist-info → opentrons-8.0.0a9.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
|
-
from opentrons.protocol_engine.errors.exceptions import
|
|
5
|
+
from opentrons.protocol_engine.errors.exceptions import (
|
|
6
|
+
MustHomeError,
|
|
7
|
+
PipetteNotReadyToAspirateError,
|
|
8
|
+
TipNotEmptyError,
|
|
9
|
+
)
|
|
6
10
|
from opentrons.types import MountType
|
|
7
11
|
from opentrons_shared_data.errors.exceptions import (
|
|
8
12
|
PipetteLiquidNotFoundError,
|
|
@@ -32,6 +36,7 @@ from ..errors.error_occurrence import ErrorOccurrence
|
|
|
32
36
|
if TYPE_CHECKING:
|
|
33
37
|
from ..execution import MovementHandler, PipettingHandler
|
|
34
38
|
from ..resources import ModelUtils
|
|
39
|
+
from ..state import StateView
|
|
35
40
|
|
|
36
41
|
|
|
37
42
|
LiquidProbeCommandType = Literal["liquidProbe"]
|
|
@@ -92,11 +97,13 @@ class LiquidProbeImplementation(
|
|
|
92
97
|
|
|
93
98
|
def __init__(
|
|
94
99
|
self,
|
|
100
|
+
state_view: StateView,
|
|
95
101
|
movement: MovementHandler,
|
|
96
102
|
pipetting: PipettingHandler,
|
|
97
103
|
model_utils: ModelUtils,
|
|
98
104
|
**kwargs: object,
|
|
99
105
|
) -> None:
|
|
106
|
+
self._state_view = state_view
|
|
100
107
|
self._movement = movement
|
|
101
108
|
self._pipetting = pipetting
|
|
102
109
|
self._model_utils = model_utils
|
|
@@ -112,6 +119,8 @@ class LiquidProbeImplementation(
|
|
|
112
119
|
the pipette.
|
|
113
120
|
TipNotEmptyError: as an undefined error, if the tip starts with liquid
|
|
114
121
|
in it.
|
|
122
|
+
PipetteNotReadyToAspirateError: as an undefined error, if the plunger is not
|
|
123
|
+
in a safe position to do the liquid probe.
|
|
115
124
|
MustHomeError: as an undefined error, if the plunger is not in a valid
|
|
116
125
|
position.
|
|
117
126
|
"""
|
|
@@ -119,13 +128,21 @@ class LiquidProbeImplementation(
|
|
|
119
128
|
labware_id = params.labwareId
|
|
120
129
|
well_name = params.wellName
|
|
121
130
|
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
# May raise TipNotAttachedError.
|
|
132
|
+
aspirated_volume = self._state_view.pipettes.get_aspirated_volume(pipette_id)
|
|
133
|
+
|
|
134
|
+
if aspirated_volume is None:
|
|
135
|
+
# Theoretically, we could avoid raising an error by automatically preparing
|
|
136
|
+
# to aspirate above the well like AspirateImplementation does. However, the
|
|
137
|
+
# only way for this to happen is if someone tries to do a liquid probe with
|
|
138
|
+
# a tip that's previously held liquid, which they should avoid anyway.
|
|
139
|
+
raise PipetteNotReadyToAspirateError(
|
|
140
|
+
"The pipette cannot probe liquid because of a previous blow out."
|
|
141
|
+
" The plunger must be reset while the tip is somewhere away from liquid."
|
|
142
|
+
)
|
|
143
|
+
elif aspirated_volume != 0:
|
|
127
144
|
raise TipNotEmptyError(
|
|
128
|
-
message="
|
|
145
|
+
message="The pipette cannot probe for liquid when the tip has liquid in it."
|
|
129
146
|
)
|
|
130
147
|
|
|
131
148
|
if await self._movement.check_for_valid_position(mount=MountType.LEFT) is False:
|
|
@@ -182,11 +199,13 @@ class TryLiquidProbeImplementation(
|
|
|
182
199
|
|
|
183
200
|
def __init__(
|
|
184
201
|
self,
|
|
202
|
+
state_view: StateView,
|
|
185
203
|
movement: MovementHandler,
|
|
186
204
|
pipetting: PipettingHandler,
|
|
187
205
|
model_utils: ModelUtils,
|
|
188
206
|
**kwargs: object,
|
|
189
207
|
) -> None:
|
|
208
|
+
self._state_view = state_view
|
|
190
209
|
self._movement = movement
|
|
191
210
|
self._pipetting = pipetting
|
|
192
211
|
self._model_utils = model_utils
|
|
@@ -203,6 +222,7 @@ class TryLiquidProbeImplementation(
|
|
|
203
222
|
# Otherwise, we return the result or propagate the exception unchanged.
|
|
204
223
|
|
|
205
224
|
original_impl = LiquidProbeImplementation(
|
|
225
|
+
state_view=self._state_view,
|
|
206
226
|
movement=self._movement,
|
|
207
227
|
pipetting=self._pipetting,
|
|
208
228
|
model_utils=self._model_utils,
|
|
@@ -29,9 +29,6 @@ _VOLUME_ROUNDING_ERROR_TOLERANCE = 1e-9
|
|
|
29
29
|
class PipettingHandler(TypingProtocol):
|
|
30
30
|
"""Liquid handling commands."""
|
|
31
31
|
|
|
32
|
-
def get_is_empty(self, pipette_id: str) -> bool:
|
|
33
|
-
"""Get whether a pipette has an aspirated volume equal to 0."""
|
|
34
|
-
|
|
35
32
|
def get_is_ready_to_aspirate(self, pipette_id: str) -> bool:
|
|
36
33
|
"""Get whether a pipette is ready to aspirate."""
|
|
37
34
|
|
|
@@ -81,10 +78,6 @@ class HardwarePipettingHandler(PipettingHandler):
|
|
|
81
78
|
self._state_view = state_view
|
|
82
79
|
self._hardware_api = hardware_api
|
|
83
80
|
|
|
84
|
-
def get_is_empty(self, pipette_id: str) -> bool:
|
|
85
|
-
"""Get whether a pipette has an aspirated volume equal to 0."""
|
|
86
|
-
return self._state_view.pipettes.get_aspirated_volume(pipette_id) == 0
|
|
87
|
-
|
|
88
81
|
def get_is_ready_to_aspirate(self, pipette_id: str) -> bool:
|
|
89
82
|
"""Get whether a pipette is ready to aspirate."""
|
|
90
83
|
hw_pipette = self._state_view.pipettes.get_hardware_pipette(
|
|
@@ -236,10 +229,6 @@ class VirtualPipettingHandler(PipettingHandler):
|
|
|
236
229
|
"""Initialize a PipettingHandler instance."""
|
|
237
230
|
self._state_view = state_view
|
|
238
231
|
|
|
239
|
-
def get_is_empty(self, pipette_id: str) -> bool:
|
|
240
|
-
"""Get whether a pipette has an aspirated volume equal to 0."""
|
|
241
|
-
return self._state_view.pipettes.get_aspirated_volume(pipette_id) == 0
|
|
242
|
-
|
|
243
232
|
def get_is_ready_to_aspirate(self, pipette_id: str) -> bool:
|
|
244
233
|
"""Get whether a pipette is ready to aspirate."""
|
|
245
234
|
return self._state_view.pipettes.get_aspirated_volume(pipette_id) is not None
|
|
@@ -302,12 +302,29 @@ class HardwareTipHandler(TipHandler):
|
|
|
302
302
|
This function will raise an exception if the specified tip presence status
|
|
303
303
|
isn't matched.
|
|
304
304
|
"""
|
|
305
|
+
nozzle_configuration = (
|
|
306
|
+
self._state_view.pipettes.state.nozzle_configuration_by_id[pipette_id]
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Configuration metrics by which tip presence checking is ignored
|
|
310
|
+
unsupported_pipette_types = [8, 96]
|
|
311
|
+
unsupported_layout_types = [
|
|
312
|
+
NozzleConfigurationType.SINGLE,
|
|
313
|
+
NozzleConfigurationType.COLUMN,
|
|
314
|
+
]
|
|
315
|
+
# NOTE: (09-20-2024) Current on multi-channel pipettes, utilizing less than 4 nozzles risks false positives on the tip presence sensor
|
|
316
|
+
supported_partial_nozzle_minimum = 4
|
|
317
|
+
|
|
305
318
|
if (
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
319
|
+
nozzle_configuration is not None
|
|
320
|
+
and self._state_view.pipettes.get_channels(pipette_id)
|
|
321
|
+
in unsupported_pipette_types
|
|
322
|
+
and nozzle_configuration.configuration in unsupported_layout_types
|
|
323
|
+
and len(nozzle_configuration.map_store) < supported_partial_nozzle_minimum
|
|
309
324
|
):
|
|
310
|
-
# Tip presence sensing is not supported for single tip pick up on the 96ch Flex Pipette
|
|
325
|
+
# Tip presence sensing is not supported for single tip pick up on the 96ch Flex Pipette, nor with single and some partial layous of the 8ch Flex Pipette.
|
|
326
|
+
# This is due in part to a press distance tolerance which creates a risk case for false positives. In the case of single tip, the mechanical tolerance
|
|
327
|
+
# for presses with 100% success is below the minimum average achieved press distance for a given multi channel pipette in that configuration.
|
|
311
328
|
return
|
|
312
329
|
try:
|
|
313
330
|
ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
|
|
@@ -611,7 +611,7 @@ class PipetteView(HasState[PipetteState]):
|
|
|
611
611
|
|
|
612
612
|
Returns:
|
|
613
613
|
The volume the pipette has aspirated.
|
|
614
|
-
None, after blow-out and the plunger is in an unsafe position
|
|
614
|
+
None, after blow-out and the plunger is in an unsafe position.
|
|
615
615
|
|
|
616
616
|
Raises:
|
|
617
617
|
PipetteNotLoadedError: pipette ID does not exist.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: opentrons
|
|
3
|
-
Version: 8.0.
|
|
3
|
+
Version: 8.0.0a9
|
|
4
4
|
Summary: The Opentrons API is a simple framework designed to make writing automated biology lab protocols easy.
|
|
5
5
|
Author: Opentrons
|
|
6
6
|
Author-email: engineering@opentrons.com
|
|
@@ -21,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
21
21
|
Classifier: Topic :: Scientific/Engineering
|
|
22
22
|
Requires-Python: >=3.10
|
|
23
23
|
License-File: ../LICENSE
|
|
24
|
-
Requires-Dist: opentrons-shared-data ==8.0.
|
|
24
|
+
Requires-Dist: opentrons-shared-data ==8.0.0a9
|
|
25
25
|
Requires-Dist: aionotify ==0.3.1
|
|
26
26
|
Requires-Dist: anyio <4.0.0,>=3.6.1
|
|
27
27
|
Requires-Dist: jsonschema <4.18.0,>=3.0.1
|
|
@@ -33,9 +33,9 @@ Requires-Dist: click <9,>=8.0.0
|
|
|
33
33
|
Requires-Dist: packaging >=21.0
|
|
34
34
|
Requires-Dist: importlib-metadata >=1.0 ; python_version < "3.8"
|
|
35
35
|
Provides-Extra: flex-hardware
|
|
36
|
-
Requires-Dist: opentrons-hardware[flex] ==8.0.
|
|
36
|
+
Requires-Dist: opentrons-hardware[flex] ==8.0.0a9 ; extra == 'flex-hardware'
|
|
37
37
|
Provides-Extra: ot2-hardware
|
|
38
|
-
Requires-Dist: opentrons-hardware ==8.0.
|
|
38
|
+
Requires-Dist: opentrons-hardware ==8.0.0a9 ; extra == 'ot2-hardware'
|
|
39
39
|
|
|
40
40
|
.. _Full API Documentation: http://docs.opentrons.com
|
|
41
41
|
|
|
@@ -296,7 +296,7 @@ opentrons/protocol_engine/commands/generate_command_schema.py,sha256=w5RsTJV4HtF
|
|
|
296
296
|
opentrons/protocol_engine/commands/get_tip_presence.py,sha256=Jh1tDMGe8HWL0a1uq1E-RuSuAFZuME0F6RFrB2yRuUo,2539
|
|
297
297
|
opentrons/protocol_engine/commands/hash_command_params.py,sha256=obWy4TbVH97SyhNqrSD6iP1wgZ20JoaH1rilZCjXxIs,1530
|
|
298
298
|
opentrons/protocol_engine/commands/home.py,sha256=3FtygvsJUUQryFQpAXTOfrjJ_rNkOJJa25VzpRSrPfA,2766
|
|
299
|
-
opentrons/protocol_engine/commands/liquid_probe.py,sha256=
|
|
299
|
+
opentrons/protocol_engine/commands/liquid_probe.py,sha256=mVrRFvNI28wXauiRMVXAW493wvb5rq66gdfYMwdEpms,10197
|
|
300
300
|
opentrons/protocol_engine/commands/load_labware.py,sha256=yHCdamAKoIMOAZKH1ROx2W8-xwlhvjOWusVo9tarj9E,6623
|
|
301
301
|
opentrons/protocol_engine/commands/load_liquid.py,sha256=fPaETCUB1LRL6wga-uKJARzN3uDB7JjX9k8hV5a5wpY,2371
|
|
302
302
|
opentrons/protocol_engine/commands/load_module.py,sha256=tfNgKRUHyawoxfyM6amQScqN2JAerXCtf46M_lml1rY,7544
|
|
@@ -371,14 +371,14 @@ opentrons/protocol_engine/execution/hardware_stopper.py,sha256=kjvinwg6uPc3lDNlL
|
|
|
371
371
|
opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py,sha256=FMqiJjE2L6Ru3x3zTCntT9ts7o_Q4wExrcQb03xZd9I,9287
|
|
372
372
|
opentrons/protocol_engine/execution/labware_movement.py,sha256=x-oZWh4p9QO6AhFxYo-68Ubv7wqnfIFteWsjkdutLg4,9832
|
|
373
373
|
opentrons/protocol_engine/execution/movement.py,sha256=MaLBVcca3C90kRvedRToNZvOe92tYQ-x5oFynN1K0Po,10902
|
|
374
|
-
opentrons/protocol_engine/execution/pipetting.py,sha256=
|
|
374
|
+
opentrons/protocol_engine/execution/pipetting.py,sha256=gtWiIUlxlRfEkiT6ztAwiu3_hUzudY-ZQWu3iOZUzos,14233
|
|
375
375
|
opentrons/protocol_engine/execution/queue_worker.py,sha256=3bVTnwOur8mgwLKVATAzKCYWxwrYajHRmykr9PbhTZc,2706
|
|
376
376
|
opentrons/protocol_engine/execution/rail_lights.py,sha256=eiJT6oI_kFk7rFuFkZzISZiLNnpf7Kkh86Kyk9wQ_Jo,590
|
|
377
377
|
opentrons/protocol_engine/execution/run_control.py,sha256=vWLSRdkds2CrtsJ0IU9hX-oTsNPrXJ5RZ9cq7ekO80c,1138
|
|
378
378
|
opentrons/protocol_engine/execution/status_bar.py,sha256=tR7CHS_y1ARQxcSKDO4YFU2cqVQhePzalmzsyH8b23A,970
|
|
379
379
|
opentrons/protocol_engine/execution/thermocycler_movement_flagger.py,sha256=if_jbmszy2MFMJCEMwt_fP_h0T1OBnHrQyI4jtUygvY,6784
|
|
380
380
|
opentrons/protocol_engine/execution/thermocycler_plate_lifter.py,sha256=SPzuiyNNB05YPb_czPr8KmnvBwmXTszvngW1CX3HVd4,3309
|
|
381
|
-
opentrons/protocol_engine/execution/tip_handler.py,sha256=
|
|
381
|
+
opentrons/protocol_engine/execution/tip_handler.py,sha256=SoZ4bEMWWDwFcwkL3tbZYxVTntVaTISJjrfu3DzNHdE,16484
|
|
382
382
|
opentrons/protocol_engine/notes/__init__.py,sha256=JRh7fKZ4XLUSQOZeI853MYkAZpKvp34RY8yDAHzcEbk,197
|
|
383
383
|
opentrons/protocol_engine/notes/notes.py,sha256=RlLpfElzIa_p51ECCug7Fueq2VHRUeBTtnk-2zQerp0,1419
|
|
384
384
|
opentrons/protocol_engine/resources/__init__.py,sha256=-tuKcd2Fn3YKWDX-tDqgZYv5MOSekGqHaHSoE1XDY3M,745
|
|
@@ -403,7 +403,7 @@ opentrons/protocol_engine/state/liquids.py,sha256=W7cf-mmVaZ3aNyiormFEy79aSvU__Q
|
|
|
403
403
|
opentrons/protocol_engine/state/modules.py,sha256=bylqsYZyVjrnx6BUhDjJb-TofnqPNk0EUYV8j12UINE,50673
|
|
404
404
|
opentrons/protocol_engine/state/motion.py,sha256=nh0UGOVvmpYynOchGJkVLTyIyiJ9CszRTUvp4Czr_GI,13955
|
|
405
405
|
opentrons/protocol_engine/state/move_types.py,sha256=zSQj_qYHBi7_-wrpaZBKmX_O-wNZCpLZkCzagOwI-zY,2132
|
|
406
|
-
opentrons/protocol_engine/state/pipettes.py,sha256=
|
|
406
|
+
opentrons/protocol_engine/state/pipettes.py,sha256=F026AaXUPe5VcNQ__C91y_qHhvbPWI7d17tKgYacaVc,37309
|
|
407
407
|
opentrons/protocol_engine/state/state.py,sha256=jx044yBfXFV1YO5aqXhJmy7iFx-tXEQ5rIl3lMcrY04,13562
|
|
408
408
|
opentrons/protocol_engine/state/state_summary.py,sha256=8VCxEOBeUflx8IBYUYtgNdwcwgdVZv3R8rSfzsbai7U,923
|
|
409
409
|
opentrons/protocol_engine/state/tips.py,sha256=gU2GsmaWPDyIIjWHj3KXv6NqxphfOd4eeNxF40hm5ok,22621
|
|
@@ -500,9 +500,9 @@ opentrons/util/helpers.py,sha256=3hr801bWGbxEcOFAS7f-iOhmnUhoK5qahbB8SIvaCfY,165
|
|
|
500
500
|
opentrons/util/linal.py,sha256=IlKAP9HkNBBgULeSf4YVwSKHdx9jnCjSr7nvDvlRALg,5753
|
|
501
501
|
opentrons/util/logging_config.py,sha256=g3TdzDKa1pL_N3eKhRYCdqPaZYe_hpLV-e8llObTcT4,5657
|
|
502
502
|
opentrons/util/performance_helpers.py,sha256=ew7H8XD20iS6-2TJAzbQeyzStZkkE6PzHt_Adx3wbZQ,5172
|
|
503
|
-
opentrons-8.0.
|
|
504
|
-
opentrons-8.0.
|
|
505
|
-
opentrons-8.0.
|
|
506
|
-
opentrons-8.0.
|
|
507
|
-
opentrons-8.0.
|
|
508
|
-
opentrons-8.0.
|
|
503
|
+
opentrons-8.0.0a9.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
504
|
+
opentrons-8.0.0a9.dist-info/METADATA,sha256=X9jHd468ULxCHBHVUUg4xfI2oTPaIEHoi2Ka7xoGdg4,4990
|
|
505
|
+
opentrons-8.0.0a9.dist-info/WHEEL,sha256=_4XEmVmaBFWtekSGrbfOGNjC2I5lUr0lZSRblBllIFA,109
|
|
506
|
+
opentrons-8.0.0a9.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
|
|
507
|
+
opentrons-8.0.0a9.dist-info/top_level.txt,sha256=wk6whpbMZdBQpcK0Fg0YVfUGrAgVOFON7oQAhOMGMW8,10
|
|
508
|
+
opentrons-8.0.0a9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|