opentrons 8.4.0a3__py2.py3-none-any.whl → 8.4.0a5__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.

Files changed (42) hide show
  1. opentrons/legacy_commands/commands.py +83 -2
  2. opentrons/legacy_commands/helpers.py +59 -1
  3. opentrons/legacy_commands/types.py +30 -0
  4. opentrons/protocol_api/core/engine/instrument.py +182 -115
  5. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +6 -14
  6. opentrons/protocol_api/core/engine/transfer_components_executor.py +30 -25
  7. opentrons/protocol_api/core/instrument.py +8 -4
  8. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +9 -30
  9. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +8 -4
  10. opentrons/protocol_api/core/well.py +1 -1
  11. opentrons/protocol_api/instrument_context.py +144 -73
  12. opentrons/protocol_api/labware.py +26 -44
  13. opentrons/protocol_api/protocol_context.py +18 -16
  14. opentrons/protocol_engine/commands/__init__.py +38 -38
  15. opentrons/protocol_engine/commands/aspirate_while_tracking.py +38 -65
  16. opentrons/protocol_engine/commands/command_unions.py +33 -33
  17. opentrons/protocol_engine/commands/dispense_while_tracking.py +36 -72
  18. opentrons/protocol_engine/commands/labware_handling_common.py +6 -1
  19. opentrons/protocol_engine/commands/liquid_probe.py +1 -2
  20. opentrons/protocol_engine/commands/move_to_well.py +5 -11
  21. opentrons/protocol_engine/commands/{evotip_dispense.py → pressure_dispense.py} +27 -27
  22. opentrons/protocol_engine/commands/{evotip_seal_pipette.py → seal_pipette_to_tip.py} +32 -27
  23. opentrons/protocol_engine/commands/{evotip_unseal_pipette.py → unseal_pipette_from_tip.py} +22 -22
  24. opentrons/protocol_engine/execution/pipetting.py +1 -0
  25. opentrons/protocol_engine/labware_offset_standardization.py +22 -1
  26. opentrons/protocol_engine/resources/deck_configuration_provider.py +8 -4
  27. opentrons/protocol_engine/state/frustum_helpers.py +12 -4
  28. opentrons/protocol_engine/state/geometry.py +121 -72
  29. opentrons/protocol_engine/state/update_types.py +1 -1
  30. opentrons/protocol_engine/state/wells.py +1 -1
  31. opentrons/protocol_engine/types/__init__.py +6 -0
  32. opentrons/protocol_engine/types/well_position.py +18 -1
  33. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +1 -1
  34. opentrons/protocols/labware.py +23 -18
  35. opentrons/util/logging_config.py +94 -25
  36. opentrons/util/logging_queue_handler.py +61 -0
  37. {opentrons-8.4.0a3.dist-info → opentrons-8.4.0a5.dist-info}/METADATA +4 -4
  38. {opentrons-8.4.0a3.dist-info → opentrons-8.4.0a5.dist-info}/RECORD +42 -41
  39. {opentrons-8.4.0a3.dist-info → opentrons-8.4.0a5.dist-info}/LICENSE +0 -0
  40. {opentrons-8.4.0a3.dist-info → opentrons-8.4.0a5.dist-info}/WHEEL +0 -0
  41. {opentrons-8.4.0a3.dist-info → opentrons-8.4.0a5.dist-info}/entry_points.txt +0 -0
  42. {opentrons-8.4.0a3.dist-info → opentrons-8.4.0a5.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,18 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING, List, Union, overload
2
+ from typing import TYPE_CHECKING, List, Sequence, Union, overload
3
3
 
4
4
 
5
- from .helpers import stringify_location, stringify_disposal_location, listify
5
+ from .helpers import (
6
+ stringify_location,
7
+ stringify_disposal_location,
8
+ stringify_well_list,
9
+ listify,
10
+ )
6
11
  from . import types as command_types
7
12
 
8
13
  from opentrons.types import Location
9
14
  from opentrons.protocol_api.disposal_locations import TrashBin, WasteChute
15
+ from opentrons.protocol_api._liquid import LiquidClass
10
16
 
11
17
  if TYPE_CHECKING:
12
18
  from opentrons.protocol_api import InstrumentContext
@@ -317,6 +323,81 @@ def move_to_disposal_location(
317
323
  }
318
324
 
319
325
 
326
+ def transfer_with_liquid_class(
327
+ instrument: InstrumentContext,
328
+ liquid_class: LiquidClass,
329
+ volume: float,
330
+ source: Union[Well, Sequence[Well], Sequence[Sequence[Well]]],
331
+ destination: Union[Well, Sequence[Well], Sequence[Sequence[Well]]],
332
+ ) -> command_types.TransferWithLiquidClassCommand:
333
+ text = (
334
+ "Transferring "
335
+ + f"{volume} uL of {liquid_class.display_name} liquid class from "
336
+ + f"{stringify_well_list(source)} to {stringify_well_list(destination)}"
337
+ )
338
+ return {
339
+ "name": command_types.TRANSFER_WITH_LIQUID_CLASS,
340
+ "payload": {
341
+ "instrument": instrument,
342
+ "liquid_class": liquid_class,
343
+ "volume": volume,
344
+ "source": source,
345
+ "destination": destination,
346
+ "text": text,
347
+ },
348
+ }
349
+
350
+
351
+ def distribute_with_liquid_class(
352
+ instrument: InstrumentContext,
353
+ liquid_class: LiquidClass,
354
+ volume: float,
355
+ source: Union[Well, Sequence[Well], Sequence[Sequence[Well]]],
356
+ destination: Union[Well, Sequence[Well], Sequence[Sequence[Well]]],
357
+ ) -> command_types.DistributeWithLiquidClassCommand:
358
+ text = (
359
+ "Distributing "
360
+ + f"{volume} uL of {liquid_class.display_name} liquid class from "
361
+ + f"{stringify_well_list(source)} to {stringify_well_list(destination)}"
362
+ )
363
+ return {
364
+ "name": command_types.DISTRIBUTE_WITH_LIQUID_CLASS,
365
+ "payload": {
366
+ "instrument": instrument,
367
+ "liquid_class": liquid_class,
368
+ "volume": volume,
369
+ "source": source,
370
+ "destination": destination,
371
+ "text": text,
372
+ },
373
+ }
374
+
375
+
376
+ def consolidate_with_liquid_class(
377
+ instrument: InstrumentContext,
378
+ liquid_class: LiquidClass,
379
+ volume: float,
380
+ source: Union[Well, Sequence[Well], Sequence[Sequence[Well]]],
381
+ destination: Union[Well, Sequence[Well], Sequence[Sequence[Well]]],
382
+ ) -> command_types.ConsolidateWithLiquidClassCommand:
383
+ text = (
384
+ "Consolidating "
385
+ + f"{volume} uL of {liquid_class.display_name} liquid class from "
386
+ + f"{stringify_well_list(source)} to {stringify_well_list(destination)}"
387
+ )
388
+ return {
389
+ "name": command_types.CONSOLIDATE_WITH_LIQUID_CLASS,
390
+ "payload": {
391
+ "instrument": instrument,
392
+ "liquid_class": liquid_class,
393
+ "volume": volume,
394
+ "source": source,
395
+ "destination": destination,
396
+ "text": text,
397
+ },
398
+ }
399
+
400
+
320
401
  def seal(
321
402
  instrument: InstrumentContext,
322
403
  location: Well,
@@ -1,4 +1,4 @@
1
- from typing import List, Union
1
+ from typing import List, Union, Sequence
2
2
 
3
3
  from opentrons.protocol_api.labware import Well, Labware
4
4
  from opentrons.protocol_api.module_contexts import ModuleContext
@@ -48,6 +48,64 @@ def stringify_disposal_location(location: Union[TrashBin, WasteChute]) -> str:
48
48
  return "Waste Chute"
49
49
 
50
50
 
51
+ def _group_wells_by_labware(wells: List[Well]) -> List[List[Well]]:
52
+ wells_by_labware: List[List[Well]] = []
53
+ sub_list = []
54
+ active_parent_labware = None
55
+ for well in wells:
56
+ if well.parent == active_parent_labware:
57
+ sub_list.append(well)
58
+ else:
59
+ active_parent_labware = well.parent
60
+ if sub_list:
61
+ wells_by_labware.append(sub_list)
62
+ sub_list = [well]
63
+ if sub_list:
64
+ wells_by_labware.append(sub_list)
65
+
66
+ return wells_by_labware
67
+
68
+
69
+ def _stringify_multiple_wells_for_labware(wells: List[Well]) -> str:
70
+ if len(wells) == 0:
71
+ return ""
72
+ elif len(wells) == 1:
73
+ return str(wells[0])
74
+ # TODO(jbl 2025-04-10) this logic can be improved to more intelligently group wells
75
+ elif len(wells) < 9: # At most we'll print out a full column's worth of well
76
+ return ", ".join([well.well_name for well in wells[:-1]]) + f", {wells[-1]}"
77
+ else: # Otherwise print the first and last three
78
+ return (
79
+ ", ".join([well.well_name for well in wells[:3]])
80
+ + ", ... "
81
+ + ", ".join([well.well_name for well in wells[-3:-1]])
82
+ + f", {wells[-1]}"
83
+ )
84
+
85
+
86
+ def stringify_well_list(
87
+ wells: Union[Well, Sequence[Well], Sequence[Sequence[Well]]]
88
+ ) -> str:
89
+ """Takes an arbitrary sequence of wells and returns a string representation of each well, associated by labware."""
90
+ if isinstance(wells, Well):
91
+ well_list = [wells]
92
+ elif len(wells) == 0:
93
+ well_list = []
94
+ elif isinstance(wells, list) and isinstance(wells[0], list):
95
+ well_list = [well for sub_well_list in wells for well in sub_well_list]
96
+ elif isinstance(wells, list):
97
+ well_list = wells
98
+ else:
99
+ return ""
100
+
101
+ return "; ".join(
102
+ [
103
+ _stringify_multiple_wells_for_labware(wells_by_labware)
104
+ for wells_by_labware in _group_wells_by_labware(well_list)
105
+ ]
106
+ )
107
+
108
+
51
109
  def _stringify_labware_movement_location(
52
110
  location: Union[
53
111
  DeckLocation, OffDeckType, Labware, ModuleContext, WasteChute, TrashBin
@@ -8,6 +8,7 @@ if TYPE_CHECKING:
8
8
  from opentrons.protocol_api import InstrumentContext
9
9
  from opentrons.protocol_api.labware import Well
10
10
  from opentrons.protocol_api.disposal_locations import TrashBin, WasteChute
11
+ from opentrons.protocol_api._liquid import LiquidClass
11
12
 
12
13
  from opentrons.types import Location
13
14
 
@@ -43,6 +44,9 @@ TOUCH_TIP: Final = "command.TOUCH_TIP"
43
44
  RETURN_TIP: Final = "command.RETURN_TIP"
44
45
  MOVE_TO: Final = "command.MOVE_TO"
45
46
  MOVE_TO_DISPOSAL_LOCATION: Final = "command.MOVE_TO_DISPOSAL_LOCATION"
47
+ TRANSFER_WITH_LIQUID_CLASS: Final = "command.TRANSFER_WITH_LIQUID_CLASS"
48
+ DISTRIBUTE_WITH_LIQUID_CLASS: Final = "command.DISTRIBUTE_WITH_LIQUID_CLASS"
49
+ CONSOLIDATE_WITH_LIQUID_CLASS: Final = "command.CONSOLIDATE_WITH_LIQUID_CLASS"
46
50
  SEAL: Final = "command.SEAL"
47
51
  UNSEAL: Final = "command.UNSEAL"
48
52
  PRESSURIZE: Final = "command.PRESSURIZE"
@@ -540,6 +544,28 @@ class MoveLabwareCommandPayload(TextOnlyPayload):
540
544
  pass
541
545
 
542
546
 
547
+ class LiquidClassCommandPayload(TextOnlyPayload, SingleInstrumentPayload):
548
+ liquid_class: LiquidClass
549
+ volume: float
550
+ source: Union[Well, Sequence[Well], Sequence[Sequence[Well]]]
551
+ destination: Union[Well, Sequence[Well], Sequence[Sequence[Well]]]
552
+
553
+
554
+ class TransferWithLiquidClassCommand(TypedDict):
555
+ name: Literal["command.TRANSFER_WITH_LIQUID_CLASS"]
556
+ payload: LiquidClassCommandPayload
557
+
558
+
559
+ class DistributeWithLiquidClassCommand(TypedDict):
560
+ name: Literal["command.DISTRIBUTE_WITH_LIQUID_CLASS"]
561
+ payload: LiquidClassCommandPayload
562
+
563
+
564
+ class ConsolidateWithLiquidClassCommand(TypedDict):
565
+ name: Literal["command.CONSOLIDATE_WITH_LIQUID_CLASS"]
566
+ payload: LiquidClassCommandPayload
567
+
568
+
543
569
  class SealCommandPayload(TextOnlyPayload):
544
570
  instrument: InstrumentContext
545
571
  location: Union[None, Location, Well]
@@ -622,6 +648,9 @@ Command = Union[
622
648
  MoveToCommand,
623
649
  MoveToDisposalLocationCommand,
624
650
  MoveLabwareCommand,
651
+ TransferWithLiquidClassCommand,
652
+ DistributeWithLiquidClassCommand,
653
+ ConsolidateWithLiquidClassCommand,
625
654
  SealCommand,
626
655
  UnsealCommand,
627
656
  PressurizeCommand,
@@ -674,6 +703,7 @@ CommandPayload = Union[
674
703
  MoveToCommandPayload,
675
704
  MoveToDisposalLocationCommandPayload,
676
705
  MoveLabwareCommandPayload,
706
+ LiquidClassCommandPayload,
677
707
  SealCommandPayload,
678
708
  UnsealCommandPayload,
679
709
  PressurizeCommandPayload,