Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): add innner well geometry to labware definitions #15975

Merged
merged 11 commits into from
Aug 14, 2024
29 changes: 29 additions & 0 deletions api/tests/opentrons/protocol_runner/test_json_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
Group,
Metadata1,
WellDefinition,
BoundedSection,
RectangularCrossSection,
InnerLabwareGeometry,
SphericalSegment,
)
from opentrons_shared_data.protocol.models import (
protocol_schema_v6,
Expand Down Expand Up @@ -685,6 +689,31 @@ def _load_labware_definition_data() -> LabwareDefinition:
},
dimensions=Dimensions(yDimension=85.5, zDimension=100, xDimension=127.75),
cornerOffsetFromSlot=CornerOffsetFromSlot(x=0, y=0, z=0),
innerWellGeometry=InnerLabwareGeometry(
frusta=[
BoundedSection(
geometry=RectangularCrossSection(
shape="rectangular",
xDimension=7.6,
yDimension=8.5,
),
topHeight=45,
),
BoundedSection(
geometry=RectangularCrossSection(
shape="rectangular",
xDimension=5.6,
yDimension=6.5,
),
topHeight=20,
),
],
bottomShape=SphericalSegment(
shape="spherical",
radius_of_curvature=6,
depth=10,
),
),
brand=BrandData(brand="foo"),
metadata=Metadata(
displayName="Foo 8 Well Plate 33uL",
Expand Down
SyntaxColoring marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,55 @@ class Config:
)


class CircularCrossSection(BaseModel):
shape: Literal["circular"] = Field(..., description="Denote shape as circular")
diameter: _NonNegativeNumber = Field(
..., description="The diameter of a circular cross section of a well"
)


class RectangularCrossSection(BaseModel):
shape: Literal["rectangular"] = Field(
..., description="Denote shape as rectangular"
)
xDimension: Optional[_NonNegativeNumber] = Field(
None,
description="x dimension of a subsection of wells",
)
yDimension: Optional[_NonNegativeNumber] = Field(
None,
description="y dimension of a subsection of wells",
)


class SphericalSegment(BaseModel):
shape: Literal["spherical"] = Field(..., description="Denote shape as spherical")
radius_of_curvature: _NonNegativeNumber = Field(
...,
description="radius of curvature of bottom subsection of wells",
)
depth: _NonNegativeNumber = Field(
..., description="The depth of a spherical bottom of a well"
)


TopCrossSection = Union[CircularCrossSection, RectangularCrossSection]
BottomShape = Union[CircularCrossSection, RectangularCrossSection, SphericalSegment]


class BoundedSection(BaseModel):
geometry: TopCrossSection = Field(
...,
description="Geometrical information needed to calculate the volume of a subsection of a well",
discriminator="shape",
)
topHeight: _NonNegativeNumber = Field(
...,
description="The height at the top of a bounded subsection of a well, relative to the bottom"
"of the well",
)


class Metadata1(BaseModel):
"""
Metadata specific to a grid of wells in a labware
Expand Down Expand Up @@ -252,6 +301,18 @@ class Group(BaseModel):
)


class InnerLabwareGeometry(BaseModel):
frusta: List[BoundedSection] = Field(
...,
description="A list of all of the sections of the well that have a contiguous shape",
)
bottomShape: BottomShape = Field(
...,
description="The shape at the bottom of the well: either a spherical segment or a cross-section",
discriminator="shape",
)


class LabwareDefinition(BaseModel):
schemaVersion: Literal[1, 2] = Field(
..., description="Which schema version a labware is using"
Expand Down Expand Up @@ -326,3 +387,7 @@ class LabwareDefinition(BaseModel):
default_factory=None,
description="Force, in Newtons, with which the gripper should grip the labware.",
)
innerWellGeometry: Optional[InnerLabwareGeometry] = Field(
None,
description="A list of bounded sections describing the geometry of the inside of the wells.",
)
35 changes: 34 additions & 1 deletion shared-data/python/opentrons_shared_data/labware/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
types in this file by and large require the use of typing_extensions.
this module shouldn't be imported unless typing.TYPE_CHECKING is true.
"""
from typing import Dict, List, NewType, Union
from typing import Dict, List, NewType, Union, Optional
from typing_extensions import Literal, TypedDict


Expand Down Expand Up @@ -37,6 +37,7 @@

Circular = Literal["circular"]
Rectangular = Literal["rectangular"]
Spherical = Literal["spherical"]
WellShape = Union[Circular, Rectangular]


Expand Down Expand Up @@ -117,6 +118,37 @@ class WellGroup(TypedDict, total=False):
brand: LabwareBrandData


class CircularCrossSection(TypedDict):
shape: Circular
diameter: float


class RectangularCrossSection(TypedDict):
shape: Rectangular
xDimension: float
yDimension: float


class SphericalSegment(TypedDict):
shape: Spherical
radius_of_curvature: float
depth: float


TopCrossSection = Union[CircularCrossSection, RectangularCrossSection]
BottomShape = Union[CircularCrossSection, RectangularCrossSection, SphericalSegment]


class BoundedSection(TypedDict):
geometry: TopCrossSection
topHeight: float


class InnerLabwareGeometry(TypedDict):
frusta: List[BoundedSection]
bottomShape: BottomShape


class _RequiredLabwareDefinition(TypedDict):
schemaVersion: Literal[2]
version: int
Expand All @@ -138,3 +170,4 @@ class LabwareDefinition(_RequiredLabwareDefinition, total=False):
gripperOffsets: Dict[str, GripperOffsets]
gripForce: float
gripHeightFromLabwareBottom: float
caila-marashaj marked this conversation as resolved.
Show resolved Hide resolved
innerWellGeometry: Optional[InnerLabwareGeometry]
Loading