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.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

@@ -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 MustHomeError, TipNotEmptyError
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
- # _validate_tip_attached in pipetting.py is a private method so we're using
123
- # get_is_ready_to_aspirate as an indirect way to throw a TipNotAttachedError if appropriate
124
- self._pipetting.get_is_ready_to_aspirate(pipette_id=pipette_id)
125
-
126
- if self._pipetting.get_is_empty(pipette_id=pipette_id) is False:
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="This operation requires a tip with no liquid in it."
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
- self._state_view.pipettes.get_nozzle_layout_type(pipette_id)
307
- == NozzleConfigurationType.SINGLE
308
- and self._state_view.pipettes.get_channels(pipette_id) == 96
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 or drop-tip and there is no tip attached.
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.0a7
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.0a7
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.0a7 ; extra == 'flex-hardware'
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.0a7 ; extra == 'ot2-hardware'
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=I95WqfD9U9B6hm1m39fshq6Ad7uipMYXuTISLJhVM9M,9318
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=9iAPL-cc_gcST-cGQ-fC2FV54Qm4DnGRtS5Du9ERKgA,14769
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=AWVJXR9R91KvQWeRhVGXyoPzCDhLmGtyyRwqBAqjv8E,15405
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=PK57-a2A5wkRwRW0OaEAPVeioN38aCOo9iZrByxT-I4,37350
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.0a7.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
504
- opentrons-8.0.0a7.dist-info/METADATA,sha256=t9_kvk6apuDByc7BPI8F4cM_TSe62ivSF71v5mpv0yQ,4990
505
- opentrons-8.0.0a7.dist-info/WHEEL,sha256=_4XEmVmaBFWtekSGrbfOGNjC2I5lUr0lZSRblBllIFA,109
506
- opentrons-8.0.0a7.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
507
- opentrons-8.0.0a7.dist-info/top_level.txt,sha256=wk6whpbMZdBQpcK0Fg0YVfUGrAgVOFON7oQAhOMGMW8,10
508
- opentrons-8.0.0a7.dist-info/RECORD,,
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,,