opentrons 8.4.0a5__py2.py3-none-any.whl → 8.4.0a6__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/protocol_api/instrument_context.py +1 -1
- opentrons/protocol_engine/execution/tip_handler.py +68 -27
- opentrons/protocol_engine/state/frustum_helpers.py +1 -1
- opentrons/protocol_engine/state/geometry.py +2 -1
- {opentrons-8.4.0a5.dist-info → opentrons-8.4.0a6.dist-info}/METADATA +4 -4
- {opentrons-8.4.0a5.dist-info → opentrons-8.4.0a6.dist-info}/RECORD +10 -10
- {opentrons-8.4.0a5.dist-info → opentrons-8.4.0a6.dist-info}/LICENSE +0 -0
- {opentrons-8.4.0a5.dist-info → opentrons-8.4.0a6.dist-info}/WHEEL +0 -0
- {opentrons-8.4.0a5.dist-info → opentrons-8.4.0a6.dist-info}/entry_points.txt +0 -0
- {opentrons-8.4.0a5.dist-info → opentrons-8.4.0a6.dist-info}/top_level.txt +0 -0
|
@@ -2654,7 +2654,7 @@ class InstrumentContext(publisher.CommandPublisher):
|
|
|
2654
2654
|
def measure_liquid_height(self, well: labware.Well) -> LiquidTrackingType:
|
|
2655
2655
|
"""Check the height of the liquid within a well.
|
|
2656
2656
|
|
|
2657
|
-
:returns: The height, in mm, of the liquid from the
|
|
2657
|
+
:returns: The height, in mm, of the liquid from the bottom of the well.
|
|
2658
2658
|
"""
|
|
2659
2659
|
self._raise_if_pressure_not_supported_by_pipette()
|
|
2660
2660
|
loc = well.top()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Tip pickup and drop procedures."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional, Dict
|
|
3
|
+
from typing import Optional, Dict, Tuple
|
|
4
4
|
from typing_extensions import Protocol as TypingProtocol
|
|
5
5
|
|
|
6
6
|
from opentrons.hardware_control import HardwareControlAPI
|
|
@@ -201,6 +201,18 @@ async def _available_for_nozzle_layout( # noqa: C901
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
|
|
204
|
+
def tip_on_left_side_96(back_left_nozzle: str) -> bool:
|
|
205
|
+
"""Return if there is a tip on the left edge of the 96 channel."""
|
|
206
|
+
left_most_column = int(back_left_nozzle[1:])
|
|
207
|
+
return left_most_column == 1
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def tip_on_right_side_96(front_right_nozzle: str) -> bool:
|
|
211
|
+
"""Return if there is a tip on the left edge of the 96 channel."""
|
|
212
|
+
right_most_column = int(front_right_nozzle[1:])
|
|
213
|
+
return right_most_column == 12
|
|
214
|
+
|
|
215
|
+
|
|
204
216
|
class HardwareTipHandler(TipHandler):
|
|
205
217
|
"""Pick up and drop tips, using the Hardware API."""
|
|
206
218
|
|
|
@@ -237,6 +249,50 @@ class HardwareTipHandler(TipHandler):
|
|
|
237
249
|
channels, style, primary_nozzle, front_right_nozzle, back_left_nozzle
|
|
238
250
|
)
|
|
239
251
|
|
|
252
|
+
def get_tip_presence_config(
|
|
253
|
+
self, pipette_id: str
|
|
254
|
+
) -> Tuple[bool, Optional[InstrumentProbeType]]:
|
|
255
|
+
"""Return the supported settings for tip presence on a given pipette depending on it's current nozzle map."""
|
|
256
|
+
follow_singular_sensor = None
|
|
257
|
+
|
|
258
|
+
unsupported_layout_types_96 = [NozzleConfigurationType.SINGLE]
|
|
259
|
+
# NOTE: (09-20-2024) Current on multi-channel pipettes, utilizing less than 4 nozzles risks false positives on the tip presence sensor
|
|
260
|
+
supported_partial_nozzle_minimum = 4
|
|
261
|
+
|
|
262
|
+
nozzle_configuration = self._state_view.pipettes.get_nozzle_configuration(
|
|
263
|
+
pipette_id=pipette_id
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
match self._state_view.pipettes.get_channels(pipette_id):
|
|
267
|
+
case 1:
|
|
268
|
+
tip_presence_supported = True
|
|
269
|
+
case 8:
|
|
270
|
+
tip_presence_supported = (
|
|
271
|
+
nozzle_configuration.tip_count >= supported_partial_nozzle_minimum
|
|
272
|
+
)
|
|
273
|
+
case 96:
|
|
274
|
+
tip_presence_supported = (
|
|
275
|
+
nozzle_configuration.configuration
|
|
276
|
+
not in unsupported_layout_types_96
|
|
277
|
+
and nozzle_configuration.tip_count
|
|
278
|
+
>= supported_partial_nozzle_minimum
|
|
279
|
+
)
|
|
280
|
+
if (
|
|
281
|
+
nozzle_configuration.configuration != NozzleConfigurationType.FULL
|
|
282
|
+
and tip_presence_supported
|
|
283
|
+
):
|
|
284
|
+
use_left = tip_on_left_side_96(nozzle_configuration.back_left)
|
|
285
|
+
use_right = tip_on_right_side_96(nozzle_configuration.front_right)
|
|
286
|
+
if not (use_left and use_right):
|
|
287
|
+
if use_left:
|
|
288
|
+
follow_singular_sensor = InstrumentProbeType.PRIMARY
|
|
289
|
+
else:
|
|
290
|
+
follow_singular_sensor = InstrumentProbeType.SECONDARY
|
|
291
|
+
case _:
|
|
292
|
+
raise ValueError("Unknown pipette type.")
|
|
293
|
+
|
|
294
|
+
return (tip_presence_supported, follow_singular_sensor)
|
|
295
|
+
|
|
240
296
|
async def pick_up_tip(
|
|
241
297
|
self,
|
|
242
298
|
pipette_id: str,
|
|
@@ -266,9 +322,18 @@ class HardwareTipHandler(TipHandler):
|
|
|
266
322
|
await self._hardware_api.tip_pickup_moves(
|
|
267
323
|
mount=hw_mount, presses=None, increment=None
|
|
268
324
|
)
|
|
269
|
-
|
|
325
|
+
|
|
326
|
+
tip_presence_supported, follow_singular_sensor = self.get_tip_presence_config(
|
|
327
|
+
pipette_id
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
if do_not_ignore_tip_presence and tip_presence_supported:
|
|
270
331
|
try:
|
|
271
|
-
await self.verify_tip_presence(
|
|
332
|
+
await self.verify_tip_presence(
|
|
333
|
+
pipette_id,
|
|
334
|
+
TipPresenceStatus.PRESENT,
|
|
335
|
+
follow_singular_sensor=follow_singular_sensor,
|
|
336
|
+
)
|
|
272
337
|
except TipNotAttachedError as e:
|
|
273
338
|
raise PickUpTipTipNotAttachedError(tip_geometry=tip_geometry) from e
|
|
274
339
|
|
|
@@ -350,30 +415,6 @@ class HardwareTipHandler(TipHandler):
|
|
|
350
415
|
follow_singular_sensor: Optional[InstrumentProbeType] = None,
|
|
351
416
|
) -> None:
|
|
352
417
|
"""See documentation on abstract base class."""
|
|
353
|
-
nozzle_configuration = self._state_view.pipettes.get_nozzle_configuration(
|
|
354
|
-
pipette_id=pipette_id
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
# Configuration metrics by which tip presence checking is ignored
|
|
358
|
-
unsupported_pipette_types = [8, 96]
|
|
359
|
-
unsupported_layout_types = [
|
|
360
|
-
NozzleConfigurationType.SINGLE,
|
|
361
|
-
NozzleConfigurationType.COLUMN,
|
|
362
|
-
]
|
|
363
|
-
# NOTE: (09-20-2024) Current on multi-channel pipettes, utilizing less than 4 nozzles risks false positives on the tip presence sensor
|
|
364
|
-
supported_partial_nozzle_minimum = 4
|
|
365
|
-
|
|
366
|
-
if (
|
|
367
|
-
nozzle_configuration is not None
|
|
368
|
-
and self._state_view.pipettes.get_channels(pipette_id)
|
|
369
|
-
in unsupported_pipette_types
|
|
370
|
-
and nozzle_configuration.configuration in unsupported_layout_types
|
|
371
|
-
and len(nozzle_configuration.map_store) < supported_partial_nozzle_minimum
|
|
372
|
-
):
|
|
373
|
-
# 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.
|
|
374
|
-
# 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
|
|
375
|
-
# for presses with 100% success is below the minimum average achieved press distance for a given multi channel pipette in that configuration.
|
|
376
|
-
return
|
|
377
418
|
try:
|
|
378
419
|
ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
|
|
379
420
|
hw_mount = self._get_hw_mount(pipette_id)
|
|
@@ -371,7 +371,7 @@ def find_volume_at_well_height(
|
|
|
371
371
|
max_height = volumetric_capacity[-1][0]
|
|
372
372
|
if target_height < 0 or target_height > max_height:
|
|
373
373
|
raise InvalidLiquidHeightFound(
|
|
374
|
-
"Invalid target height {target_height} mm; max well height is {max_height} mm."
|
|
374
|
+
f"Invalid target height {target_height} mm; max well height is {max_height} mm."
|
|
375
375
|
)
|
|
376
376
|
# volumes in volumetric_capacity are relative to each frustum,
|
|
377
377
|
# so we have to find the volume of all the full sections enclosed
|
|
@@ -7,6 +7,7 @@ from numpy.typing import NDArray
|
|
|
7
7
|
from typing import Optional, List, Tuple, Union, cast, TypeVar, Dict, Set
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from functools import cached_property
|
|
10
|
+
from math import isclose
|
|
10
11
|
|
|
11
12
|
from opentrons.types import (
|
|
12
13
|
Point,
|
|
@@ -487,7 +488,7 @@ class GeometryView:
|
|
|
487
488
|
raise OperationLocationNotInWellError(
|
|
488
489
|
f"Specifying {well_location.origin} with an offset of {well_location.offset} results in an operation location that could be below the bottom of the well"
|
|
489
490
|
)
|
|
490
|
-
elif z_offset < 0:
|
|
491
|
+
elif z_offset < 0 and not isclose(z_offset, 0, abs_tol=0.0000001):
|
|
491
492
|
if isinstance(well_location, LiquidHandlingWellLocation):
|
|
492
493
|
raise OperationLocationNotInWellError(
|
|
493
494
|
f"Specifying {well_location.origin} with an offset of {well_location.offset} and a volume offset of {well_location.volumeOffset} results in an operation location below the bottom of the well"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: opentrons
|
|
3
|
-
Version: 8.4.
|
|
3
|
+
Version: 8.4.0a6
|
|
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.4.
|
|
24
|
+
Requires-Dist: opentrons-shared-data (==8.4.0a6)
|
|
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)
|
|
@@ -35,9 +35,9 @@ Requires-Dist: pyusb (==1.2.1)
|
|
|
35
35
|
Requires-Dist: packaging (>=21.0)
|
|
36
36
|
Requires-Dist: importlib-metadata (>=1.0) ; python_version < "3.8"
|
|
37
37
|
Provides-Extra: flex-hardware
|
|
38
|
-
Requires-Dist: opentrons-hardware[flex] (==8.4.
|
|
38
|
+
Requires-Dist: opentrons-hardware[flex] (==8.4.0a6) ; extra == 'flex-hardware'
|
|
39
39
|
Provides-Extra: ot2-hardware
|
|
40
|
-
Requires-Dist: opentrons-hardware (==8.4.
|
|
40
|
+
Requires-Dist: opentrons-hardware (==8.4.0a6) ; extra == 'ot2-hardware'
|
|
41
41
|
|
|
42
42
|
.. _Full API Documentation: http://docs.opentrons.com
|
|
43
43
|
|
|
@@ -228,7 +228,7 @@ opentrons/protocol_api/config.py,sha256=r9lyvXjagTX_g3q5FGURPpcz2IA9sSF7Oa_1mKx-
|
|
|
228
228
|
opentrons/protocol_api/create_protocol_context.py,sha256=wwsZje0L__oDnu1Yrihau320_f-ASloR9eL1QCtkOh8,7612
|
|
229
229
|
opentrons/protocol_api/deck.py,sha256=94vFceg1SC1bAGd7TvC1ZpYwnJR-VlzurEZ6jkacYeg,8910
|
|
230
230
|
opentrons/protocol_api/disposal_locations.py,sha256=NRiSGmDR0LnbyEkWSOM-o64uR2fUoB1NWJG7Y7SsJSs,7920
|
|
231
|
-
opentrons/protocol_api/instrument_context.py,sha256=
|
|
231
|
+
opentrons/protocol_api/instrument_context.py,sha256=ycUSiRkVbkplN54rxxPu7BtHF4xtMaGc8tdjvTDsE8A,117900
|
|
232
232
|
opentrons/protocol_api/labware.py,sha256=1m1y7h70bBBqW60LjiCPQWwFfVXzY_goJrB773yUN0A,60407
|
|
233
233
|
opentrons/protocol_api/module_contexts.py,sha256=3tVXj6Q7n-WuTJPU_dvIQLzzGv1P-jsMuDtMVpuhAf8,48291
|
|
234
234
|
opentrons/protocol_api/module_validation_and_errors.py,sha256=XL_m72P8rcvGO2fynY7UzXLcpGuI6X4s0V6Xf735Iyc,1464
|
|
@@ -425,7 +425,7 @@ opentrons/protocol_engine/execution/run_control.py,sha256=ksvI2zkguC4G3lR3HJgAF8
|
|
|
425
425
|
opentrons/protocol_engine/execution/status_bar.py,sha256=tR7CHS_y1ARQxcSKDO4YFU2cqVQhePzalmzsyH8b23A,970
|
|
426
426
|
opentrons/protocol_engine/execution/thermocycler_movement_flagger.py,sha256=Ouljgjtm7-sCXwDcpfbir84dAZh5y89DNiuKedYimyg,6790
|
|
427
427
|
opentrons/protocol_engine/execution/thermocycler_plate_lifter.py,sha256=j33nYV8rkeAYUOau8wFIyJVWjWkjyildleYHCysez-o,3375
|
|
428
|
-
opentrons/protocol_engine/execution/tip_handler.py,sha256=
|
|
428
|
+
opentrons/protocol_engine/execution/tip_handler.py,sha256=Ouunj3KVqz-UMbkjFIbJJr2zpfgcUht_r4_60uHEx3M,19731
|
|
429
429
|
opentrons/protocol_engine/notes/__init__.py,sha256=G0bIQswsov7MrJU0ArrOaWcOTxJU9BCUmNR3LRoNg-Q,311
|
|
430
430
|
opentrons/protocol_engine/notes/notes.py,sha256=A5C9xHExlS9GAK7o_mYiKJgibBm6EEgHQ4PJor0IET0,1993
|
|
431
431
|
opentrons/protocol_engine/resources/__init__.py,sha256=yvGFYpmLoxHYQff_IwiaEH9viZUfal5D5K91UjYLwwY,805
|
|
@@ -449,8 +449,8 @@ opentrons/protocol_engine/state/commands.py,sha256=aoON_C5DbiIEPxOGATvwCsSG9eHsF
|
|
|
449
449
|
opentrons/protocol_engine/state/config.py,sha256=7jSGxC6Vqj1eA8fqZ2I3zjlxVXg8pxvcBYMztRIx9Mg,1515
|
|
450
450
|
opentrons/protocol_engine/state/files.py,sha256=w8xxxg8HY0RqKKEGSfHWfrjV54Gb02O3dwtisJ-9j8E,1753
|
|
451
451
|
opentrons/protocol_engine/state/fluid_stack.py,sha256=uwkf0qYk1UX5iU52xmk-e3yLPK8OG-TtMCcBqrkVFpM,5932
|
|
452
|
-
opentrons/protocol_engine/state/frustum_helpers.py,sha256=
|
|
453
|
-
opentrons/protocol_engine/state/geometry.py,sha256=
|
|
452
|
+
opentrons/protocol_engine/state/frustum_helpers.py,sha256=uRBLLR75Z_PnfVd-U7gPF3NeOALR3TgLNCojgxB4z0o,17343
|
|
453
|
+
opentrons/protocol_engine/state/geometry.py,sha256=PoqaC_Vmw2hF_H4u5ONgbJig8J52gIyI7ExwvZgtfCg,97701
|
|
454
454
|
opentrons/protocol_engine/state/labware.py,sha256=rehy7R1HIhxx3DTtTHIKxqHoBQJ_1tDhhiculMJeIy8,57556
|
|
455
455
|
opentrons/protocol_engine/state/liquid_classes.py,sha256=u_z75UYdiFAKG0yB3mr1il4T3qaS0Sotq8sL7KLODP8,2990
|
|
456
456
|
opentrons/protocol_engine/state/liquids.py,sha256=NoesktcQdJUjIVmet1uqqJPf-rzbo4SGemXwQC295W0,2338
|
|
@@ -583,9 +583,9 @@ opentrons/util/linal.py,sha256=IlKAP9HkNBBgULeSf4YVwSKHdx9jnCjSr7nvDvlRALg,5753
|
|
|
583
583
|
opentrons/util/logging_config.py,sha256=7et4YYuQdWdq_e50U-8vFS_QyNBRgdnqPGAQJm8qrIo,9954
|
|
584
584
|
opentrons/util/logging_queue_handler.py,sha256=ZsSJwy-oV8DXwpYiZisQ1PbYwmK2cOslD46AcyJ1E4I,2484
|
|
585
585
|
opentrons/util/performance_helpers.py,sha256=ew7H8XD20iS6-2TJAzbQeyzStZkkE6PzHt_Adx3wbZQ,5172
|
|
586
|
-
opentrons-8.4.
|
|
587
|
-
opentrons-8.4.
|
|
588
|
-
opentrons-8.4.
|
|
589
|
-
opentrons-8.4.
|
|
590
|
-
opentrons-8.4.
|
|
591
|
-
opentrons-8.4.
|
|
586
|
+
opentrons-8.4.0a6.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
587
|
+
opentrons-8.4.0a6.dist-info/METADATA,sha256=aOK9mh9j_G3EODbbtkFFhGtWd-YxxGSyue8zEHQrfyM,5084
|
|
588
|
+
opentrons-8.4.0a6.dist-info/WHEEL,sha256=qUzzGenXXuJTzyjFah76kDVqDvnk-YDzY00svnrl84w,109
|
|
589
|
+
opentrons-8.4.0a6.dist-info/entry_points.txt,sha256=fTa6eGCYkvOtv0ov-KVE8LLGetgb35LQLF9x85OWPVw,106
|
|
590
|
+
opentrons-8.4.0a6.dist-info/top_level.txt,sha256=wk6whpbMZdBQpcK0Fg0YVfUGrAgVOFON7oQAhOMGMW8,10
|
|
591
|
+
opentrons-8.4.0a6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|