Skip to content

Commit

Permalink
refactor(api): split up protocol engine types (#17338)
Browse files Browse the repository at this point in the history
This was getting _quite_ unwieldy. Let's split it into multiple files.
We can change what the names of the files are later if we want because
nothing is poking through and importing them individually (except each
other).

## review
seem like a good idea?

## test
automated tests should handle this
  • Loading branch information
sfoster1 authored Jan 23, 2025
1 parent 577ae43 commit 1a87665
Show file tree
Hide file tree
Showing 24 changed files with 1,710 additions and 1,328 deletions.
1,328 changes: 0 additions & 1,328 deletions api/src/opentrons/protocol_engine/types.py

This file was deleted.

252 changes: 252 additions & 0 deletions api/src/opentrons/protocol_engine/types/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
"""Public protocol engine value types and models."""

from __future__ import annotations


from opentrons_shared_data.pipette.types import LabwareUri
from opentrons.hardware_control.modules import ModuleType


from .run_time_parameters import (
NumberParameter,
BooleanParameter,
EnumParameter,
CSVParameter,
RunTimeParameter,
PrimitiveRunTimeParamValuesType,
CSVRunTimeParamFilesType,
CSVRuntimeParamPaths,
FileInfo,
EnumChoice,
)

from .command_annotations import (
SecondOrderCommandAnnotation,
CustomCommandAnnotation,
CommandAnnotation,
)
from .partial_tip_configuration import (
AllNozzleLayoutConfiguration,
SingleNozzleLayoutConfiguration,
RowNozzleLayoutConfiguration,
ColumnNozzleLayoutConfiguration,
QuadrantNozzleLayoutConfiguration,
NozzleLayoutConfigurationType,
PRIMARY_NOZZLE_LITERAL,
)
from .automatic_tip_selection import NextTipInfo, NoTipReason, NoTipAvailable
from .instrument_sensors import InstrumentSensorId, TipPresenceStatus
from .deck_configuration import (
AddressableOffsetVector,
PotentialCutoutFixture,
AreaType,
AddressableArea,
DeckConfigurationType,
DeckType,
)
from .liquid_class import LiquidClassRecord, LiquidClassRecordWithId
from .module import (
ModuleModel,
TemperatureModuleModel,
MagneticModuleModel,
ThermocyclerModuleModel,
HeaterShakerModuleModel,
MagneticBlockModel,
AbsorbanceReaderModel,
FlexStackerModuleModel,
ModuleDimensions,
ModuleCalibrationPoint,
ModuleDefinition,
LoadedModule,
SpeedRange,
TemperatureRange,
HeaterShakerLatchStatus,
HeaterShakerMovementRestrictors,
ABSMeasureMode,
ModuleOffsetVector,
ModuleOffsetData,
)
from .location import (
DeckSlotLocation,
StagingSlotLocation,
AddressableAreaLocation,
ModuleLocation,
OnLabwareLocation,
OFF_DECK_LOCATION,
SYSTEM_LOCATION,
LabwareLocation,
OnDeckLabwareLocation,
NonStackedLocation,
DeckPoint,
)
from .labware import (
OverlapOffset,
LabwareOffset,
LabwareOffsetCreate,
LoadedLabware,
)
from .liquid import HexColor, EmptyLiquidId, LiquidId, Liquid, FluidKind, AspiratedFluid
from .labware_offset_location import LabwareOffsetLocation
from .labware_offset_vector import LabwareOffsetVector
from .well_position import (
WellOrigin,
PickUpTipWellOrigin,
DropTipWellOrigin,
WellOffset,
WellLocation,
LiquidHandlingWellLocation,
PickUpTipWellLocation,
DropTipWellLocation,
)
from .instrument import (
LoadedPipette,
CurrentAddressableArea,
CurrentWell,
CurrentPipetteLocation,
InstrumentOffsetVector,
)
from .execution import EngineStatus, PostRunHardwareState
from .liquid_level_detection import (
LoadedVolumeInfo,
ProbedHeightInfo,
ProbedVolumeInfo,
WellInfoSummary,
WellLiquidInfo,
)
from .liquid_handling import FlowRates
from .labware_movement import LabwareMovementStrategy, LabwareMovementOffsetData
from .tip import TipGeometry
from .hardware_passthrough import MovementAxis, MotorAxis
from .util import Vec3f, Dimensions

__all__ = [
# Runtime parameters
"NumberParameter",
"BooleanParameter",
"EnumParameter",
"EnumChoice",
"CSVParameter",
"PrimitiveRunTimeParamValuesType",
"CSVRunTimeParamFilesType",
"CSVRuntimeParamPaths",
"FileInfo",
"RunTimeParameter",
# Command annotations
"SecondOrderCommandAnnotation",
"CustomCommandAnnotation",
"CommandAnnotation",
# Partial tip handling
"AllNozzleLayoutConfiguration",
"SingleNozzleLayoutConfiguration",
"RowNozzleLayoutConfiguration",
"ColumnNozzleLayoutConfiguration",
"QuadrantNozzleLayoutConfiguration",
"NozzleLayoutConfigurationType",
"PRIMARY_NOZZLE_LITERAL",
# Automatic tip selection
"NextTipInfo",
"NoTipReason",
"NoTipAvailable",
# Instrument sensors
"InstrumentSensorId",
"TipPresenceStatus",
# Deck configuration
"AddressableOffsetVector",
"PotentialCutoutFixture",
"AreaType",
"AddressableArea",
"DeckConfigurationType",
"DeckType",
# Liquid classes
"LiquidClassRecord",
"LiquidClassRecordWithId",
# Modules
"ModuleModel",
"ModuleType",
"TemperatureModuleModel",
"MagneticModuleModel",
"ThermocyclerModuleModel",
"HeaterShakerModuleModel",
"MagneticBlockModel",
"AbsorbanceReaderModel",
"FlexStackerModuleModel",
"ModuleDimensions",
"ModuleCalibrationPoint",
"ModuleDefinition",
"LoadedModule",
"SpeedRange",
"TemperatureRange",
"HeaterShakerLatchStatus",
"HeaterShakerMovementRestrictors",
"ABSMeasureMode",
"ModuleOffsetVector",
"ModuleOffsetData",
# Locations of things on deck
"DeckSlotLocation",
"StagingSlotLocation",
"AddressableAreaLocation",
"ModuleLocation",
"OnLabwareLocation",
"OFF_DECK_LOCATION",
"SYSTEM_LOCATION",
"LabwareLocation",
"OnDeckLabwareLocation",
"NonStackedLocation",
"DeckPoint",
# Labware offset location
"LabwareOffsetLocation",
# Labware offset vector
"LabwareOffsetVector",
# Labware
"OverlapOffset",
"LabwareOffset",
"LabwareOffsetCreate",
"LoadedLabware",
"LabwareOffsetVector",
# Liquids
"HexColor",
"EmptyLiquidId",
"LiquidId",
"Liquid",
"FluidKind",
"AspiratedFluid",
# Well locations
"WellOrigin",
"PickUpTipWellOrigin",
"DropTipWellOrigin",
"WellOffset",
"WellLocation",
"LiquidHandlingWellLocation",
"PickUpTipWellLocation",
"DropTipWellLocation",
# Execution
"EngineStatus",
"PostRunHardwareState",
# Instruments
"LoadedPipette",
"CurrentAddressableArea",
"CurrentWell",
"CurrentPipetteLocation",
"InstrumentOffsetVector",
# Liquid level detection types
"LoadedVolumeInfo",
"ProbedHeightInfo",
"ProbedVolumeInfo",
"WellInfoSummary",
"WellLiquidInfo",
# Liquid handling
"FlowRates",
# Labware movement
"LabwareMovementStrategy",
"LabwareMovementOffsetData",
# Tips
"TipGeometry",
# Hardware passthrough
"MovementAxis",
"MotorAxis",
# Utility types
"Vec3f",
"Dimensions",
# Convenience re-export
"LabwareUri",
]
39 changes: 39 additions & 0 deletions api/src/opentrons/protocol_engine/types/automatic_tip_selection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Protocol engine types dealing with automatic tip selection."""
from enum import Enum
from typing import Optional

from pydantic import (
BaseModel,
Field,
)


class NextTipInfo(BaseModel):
"""Next available tip labware and well name data."""

labwareId: str = Field(
...,
description="The labware ID of the tip rack where the next available tip(s) are located.",
)
tipStartingWell: str = Field(
..., description="The (starting) well name of the next available tip(s)."
)


class NoTipReason(Enum):
"""The cause of no tip being available for a pipette and tip rack(s)."""

NO_AVAILABLE_TIPS = "noAvailableTips"
STARTING_TIP_WITH_PARTIAL = "startingTipWithPartial"
INCOMPATIBLE_CONFIGURATION = "incompatibleConfiguration"


class NoTipAvailable(BaseModel):
"""No available next tip data."""

noTipReason: NoTipReason = Field(
..., description="The reason why no next available tip could be provided."
)
message: Optional[str] = Field(
None, description="Optional message explaining why a tip wasn't available."
)
53 changes: 53 additions & 0 deletions api/src/opentrons/protocol_engine/types/command_annotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Protocol Engine types dealing with command annotations."""

from typing import List, Literal, Dict, Any, Optional, Union
from pydantic import (
ConfigDict,
BaseModel,
Field,
)


class BaseCommandAnnotation(BaseModel):
"""Optional annotations for protocol engine commands."""

commandKeys: List[str] = Field(
..., description="Command keys to which this annotation applies"
)
annotationType: str = Field(
..., description="The type of annotation (for machine parsing)"
)


class SecondOrderCommandAnnotation(BaseCommandAnnotation):
"""Annotates a group of atomic commands which were the direct result of a second order command.
Examples of second order commands would be transfer, consolidate, mix, etc.
"""

annotationType: Literal["secondOrderCommand"] = "secondOrderCommand"
params: Dict[str, Any] = Field(
...,
description="Key value pairs of the parameters passed to the second order command that this annotates.",
)
machineReadableName: str = Field(
...,
description="The name of the second order command in the form that the generating software refers to it",
)
userSpecifiedName: Optional[str] = Field(
None, description="The optional user-specified name of the second order command"
)
userSpecifiedDescription: Optional[str] = Field(
None,
description="The optional user-specified description of the second order command",
)


class CustomCommandAnnotation(BaseCommandAnnotation):
"""Annotates a group of atomic commands in some manner that Opentrons software does not anticipate or originate."""

annotationType: Literal["custom"] = "custom"
model_config = ConfigDict(extra="allow")


CommandAnnotation = Union[SecondOrderCommandAnnotation, CustomCommandAnnotation]
Loading

0 comments on commit 1a87665

Please sign in to comment.