Skip to content

Commit

Permalink
Papi refactor to eliminate calculations prior to PE execution
Browse files Browse the repository at this point in the history
  • Loading branch information
pmoegenburg committed Oct 16, 2024
1 parent 7fe0451 commit fc0572f
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 17 deletions.
5 changes: 3 additions & 2 deletions api/src/opentrons/protocol_api/core/engine/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,8 @@ def aspirate(
labware_id=labware_id,
well_name=well_name,
absolute_point=location.point,
is_meniscus=is_meniscus,
)
if is_meniscus:
well_location.volumeOffset = "operationVolume"
pipette_movement_conflict.check_safe_for_pipette_movement(
engine_state=self._engine_client.state,
pipette_id=self._pipette_id,
Expand Down Expand Up @@ -183,6 +182,7 @@ def dispense(
flow_rate: float,
in_place: bool,
push_out: Optional[float],
is_meniscus: Optional[bool] = None,
) -> None:
"""Dispense a given volume of liquid into the specified location.
Args:
Expand Down Expand Up @@ -242,6 +242,7 @@ def dispense(
labware_id=labware_id,
well_name=well_name,
absolute_point=location.point,
is_meniscus=is_meniscus,
)
pipette_movement_conflict.check_safe_for_pipette_movement(
engine_state=self._engine_client.state,
Expand Down
1 change: 1 addition & 0 deletions api/src/opentrons/protocol_api/core/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def dispense(
flow_rate: float,
in_place: bool,
push_out: Optional[float],
is_meniscus: Optional[bool] = None,
) -> None:
"""Dispense a given volume of liquid into the specified location.
Args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def dispense(
flow_rate: float,
in_place: bool,
push_out: Optional[float],
is_meniscus: Optional[bool] = None,
) -> None:
"""Dispense a given volume of liquid into the specified location.
Args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def dispense(
flow_rate: float,
in_place: bool,
push_out: Optional[float],
is_meniscus: Optional[bool] = None,
) -> None:
if isinstance(location, (TrashBin, WasteChute)):
raise APIVersionError(
Expand Down
3 changes: 3 additions & 0 deletions api/src/opentrons/protocol_api/instrument_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ def dispense( # noqa: C901
)
)
well: Optional[labware.Well] = None
is_meniscus: Optional[bool] = None
last_location = self._get_last_location_by_api_version()

try:
Expand All @@ -405,6 +406,7 @@ def dispense( # noqa: C901
well = target.well
if target.location:
move_to_location = target.location
is_meniscus = target.is_meniscus
elif well.parent._core.is_fixed_trash():
move_to_location = target.well.top()
else:
Expand Down Expand Up @@ -449,6 +451,7 @@ def dispense( # noqa: C901
flow_rate=flow_rate,
in_place=False,
push_out=push_out,
is_meniscus=is_meniscus if is_meniscus is not None else None,
)
return self

Expand Down
6 changes: 2 additions & 4 deletions api/src/opentrons/protocol_api/labware.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,11 @@ def meniscus(self, z: float = 0.0) -> Location:
"""
:param z: An offset on the z-axis, in mm. Positive offsets are higher and
negative offsets are lower.
:return: A :py:class:`~opentrons.types.Location` corresponding to the
absolute position of the meniscus-center of the well, plus the ``z`` offset
(if specified).
:return: A :py:class:`~opentrons.types.Location` that holds the ``z`` offset in its point.z field.
:meta private:
"""
return Location(self._core.get_meniscus(z_offset=z), self, True)
return Location(point=Point(x=0, y=0, z=z), labware=self, is_meniscus=True)

@requires_version(2, 8)
def from_center_cartesian(self, x: float, y: float, z: float) -> Point:
Expand Down
18 changes: 12 additions & 6 deletions api/src/opentrons/protocol_engine/state/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,20 @@ def get_relative_liquid_handling_well_location(
labware_id: str,
well_name: str,
absolute_point: Point,
is_meniscus: Optional[bool] = None,
) -> LiquidHandlingWellLocation:
"""Given absolute position, get relative location of a well in a labware."""
well_absolute_point = self.get_well_position(labware_id, well_name)
delta = absolute_point - well_absolute_point

return LiquidHandlingWellLocation(
offset=WellOffset(x=delta.x, y=delta.y, z=delta.z)
)
if is_meniscus:
return LiquidHandlingWellLocation(
origin=WellOrigin.MENISCUS,
offset=WellOffset(x=0, y=0, z=absolute_point.z),
)
else:
well_absolute_point = self.get_well_position(labware_id, well_name)
delta = absolute_point - well_absolute_point
return LiquidHandlingWellLocation(
offset=WellOffset(x=delta.x, y=delta.y, z=delta.z)
)

def get_relative_pick_up_tip_well_location(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,10 @@ def test_aspirate_from_well(

decoy.when(
mock_engine_client.state.geometry.get_relative_liquid_handling_well_location(
labware_id="123abc", well_name="my cool well", absolute_point=Point(1, 2, 3)
labware_id="123abc",
well_name="my cool well",
absolute_point=Point(1, 2, 3),
is_meniscus=None,
)
).then_return(
LiquidHandlingWellLocation(
Expand Down Expand Up @@ -727,7 +730,10 @@ def test_dispense_to_well(

decoy.when(
mock_engine_client.state.geometry.get_relative_liquid_handling_well_location(
labware_id="123abc", well_name="my cool well", absolute_point=Point(1, 2, 3)
labware_id="123abc",
well_name="my cool well",
absolute_point=Point(1, 2, 3),
is_meniscus=None,
)
).then_return(
LiquidHandlingWellLocation(
Expand Down
5 changes: 2 additions & 3 deletions api/tests/opentrons/protocol_api/test_well.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,11 @@ def test_well_center(decoy: Decoy, mock_well_core: WellCore, subject: Well) -> N

def test_well_meniscus(decoy: Decoy, mock_well_core: WellCore, subject: Well) -> None:
"""It should get a Location representing the meniscus of the well."""
decoy.when(mock_well_core.get_meniscus(z_offset=4.2)).then_return(Point(1, 2, 3))

result = subject.meniscus(4.2)

assert isinstance(result, Location)
assert result.point == Point(1, 2, 3)
assert result.point == Point(0, 0, 4.2)
assert result.is_meniscus is True
assert result.labware.as_well() is subject


Expand Down

0 comments on commit fc0572f

Please sign in to comment.