Skip to content

Commit

Permalink
papi resin tip command name and doc updates
Browse files Browse the repository at this point in the history
  • Loading branch information
CaseyBatten committed Jan 27, 2025
1 parent ebdfe93 commit 4396fa5
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 38 deletions.
9 changes: 7 additions & 2 deletions api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2325,11 +2325,16 @@ def set_working_volume(
instrument.working_volume = tip_volume

async def tip_drop_moves(
self, mount: Union[top_types.Mount, OT3Mount], home_after: bool = False, ignore_plunger: Optional[bool] = False
self,
mount: Union[top_types.Mount, OT3Mount],
home_after: bool = False,
ignore_plunger: Optional[bool] = False,
) -> None:
realmount = OT3Mount.from_mount(mount)
if ignore_plunger is False:
await self._move_to_plunger_bottom(realmount, rate=1.0, check_current_vol=False)
await self._move_to_plunger_bottom(
realmount, rate=1.0, check_current_vol=False
)

if self.gantry_load == GantryLoad.HIGH_THROUGHPUT:
spec = self._pipette_handler.plan_ht_drop_tip()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ async def pick_up_tip(
...

async def tip_drop_moves(
self, mount: MountArgType, home_after: bool = True, ignore_plunger: Optional[bool] = False,
self,
mount: MountArgType,
home_after: bool = True,
ignore_plunger: Optional[bool] = False,
) -> None:
...

Expand Down
2 changes: 1 addition & 1 deletion api/src/opentrons/legacy_commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def unseal(
}


def pressurize(
def resin_tip_dispense(
instrument: InstrumentContext,
volume: float,
flow_rate: float,
Expand Down
58 changes: 42 additions & 16 deletions api/src/opentrons/protocol_api/instrument_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -1714,7 +1714,7 @@ def move_to(
return self

@requires_version(2, 22)
def seal(
def resin_tip_seal(
self,
location: Union[labware.Well, labware.Labware],
) -> InstrumentContext:
Expand All @@ -1724,7 +1724,7 @@ def seal(
tip will perform a `pick up` action but there will be no tip tracking
associated with the pipette.
See :ref:`seal` for examples.
See :ref:`resin_tip_seal` for examples.
:param location: A location containing resin tips, must be a Labware or a Well.
Expand All @@ -1748,7 +1748,7 @@ def seal(
return self

@requires_version(2, 22)
def unseal(
def resin_tip_unseal(
self,
location: Union[labware.Well, labware.Labware],
home_after: Optional[bool] = None,
Expand All @@ -1757,11 +1757,20 @@ def unseal(
The location provided should be a valid location to drop resin tips.
See :ref:`unseal` for examples.
See :ref:`resin_tip_unseal` for examples.
:param location: A location containing that can accept tips.
:type location: :py:class:`~.types.Location`
:param home_after:
Whether to home the pipette after dropping the tip. If not specified
defaults to ``True`` on a Flex. The plunger will not home on an unseal.
When ``False``, the pipette does not home its plunger. This can save a few
seconds, but is not recommended. Homing helps the robot track the pipette's
position.
"""
if isinstance(location, labware.Labware):
well = location.wells()[0]
Expand All @@ -1782,24 +1791,39 @@ def unseal(
return self

@requires_version(2, 22)
def evotip_dispense(
def resin_tip_dispense(
self,
location: types.Location,
volume: float,
flow_rate: float,
rate: float,
push_out: Optional[float] = None,
) -> InstrumentContext:
"""Seal resin tips onto the pipette.
"""Dispense a volume from resin tips into a labware.
The location provided should contain resin tips. Sealing the
tip will perform a `pick up` action but there will be no tip tracking
associated with the pipette.
The location provided should contain resin tips labware as well as a
receptical for dispensed liquid. Dispensing from tip will perform a
`dispense` action of the specified volume at a desired flow rate.
See :ref:`seal` for examples.
See :ref:`resin_tip_dispense` for examples.
:param location: A location containing resin tips.
:type location: :py:class:`~.types.Location`
:param volume: The volume, in µL, that the pipette will prepare to handle.
:type volume: float
:param rate: How quickly a pipette dispenses liquid. The speed in µL/s is
calculated as ``rate`` multiplied by :py:attr:`flow_rate.dispense
<flow_rate>`. If not specified, defaults to 1.0. See
:ref:`new-plunger-flow-rates`.
:type rate: float
:param push_out: Continue past the plunger bottom to help ensure all liquid
leaves the tip. Measured in µL. The default value is ``None``.
See :ref:`push-out-dispense` for details.
:type push_out: float
"""
well: Optional[labware.Well] = None
last_location = self._get_last_location_by_api_version()
Expand Down Expand Up @@ -1827,21 +1851,23 @@ def evotip_dispense(
z=self._well_bottom_clearances.dispense
)
else:
raise RuntimeError("A well must be specified when using `evotip_dispense`.")
raise RuntimeError(
"A well must be specified when using `resin_tip_dispense`."
)

with publisher.publish_context(
broker=self.broker,
command=cmds.pressurize(
command=cmds.resin_tip_dispense(
instrument=self,
volume=volume,
flow_rate=flow_rate,
flow_rate=rate,
),
):
self._core.evotip_dispense(
move_to_location,
well_core=well._core,
volume=volume,
flow_rate=flow_rate,
flow_rate=rate,
push_out=push_out,
)
return self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ async def execute(self, params: EvotipDispenseParams) -> _ExecuteReturn:
pipetting=self._pipetting,
model_utils=self._model_utils,
)


if (
isinstance(current_location, CurrentWell)
Expand Down
33 changes: 24 additions & 9 deletions api/src/opentrons/protocol_engine/commands/evotip_seal_pipette.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@

if TYPE_CHECKING:
from ..state.state import StateView
from ..execution import MovementHandler, TipHandler, GantryMover, PipettingHandler, Had
from ..execution import (
MovementHandler,
TipHandler,
GantryMover,
PipettingHandler,
Had,
)
from ..notes import CommandNoteAdder


Expand Down Expand Up @@ -144,7 +150,10 @@ async def relative_pickup_tip(

# Drive mount down for press-fit
await self._gantry_mover.move_axes(
axis_map={mount_axis: press_distance}, speed=10.0, relative_move=True, _expect_stalls=True
axis_map={mount_axis: press_distance},
speed=10.0,
relative_move=True,
_expect_stalls=True,
)
# retract cam : 11.05
await self._gantry_mover.move_axes(
Expand Down Expand Up @@ -175,7 +184,9 @@ async def relative_pickup_tip(
)

# Lower tip presence
await self._gantry_mover.move_axes(axis_map={mount_axis: 2}, speed=10, relative_move=True)
await self._gantry_mover.move_axes(
axis_map={mount_axis: 2}, speed=10, relative_move=True
)
await self._gantry_mover.move_axes(
axis_map={MotorAxis.AXIS_96_CHANNEL_CAM: ejector_push_mm},
speed=5.5,
Expand All @@ -190,7 +201,9 @@ async def relative_pickup_tip(
# cache_tip
if self._state_view.config.use_virtual_pipettes is False:
self._tip_handler.cache_tip(pipette_id, tip_geometry)
self._hardware_api.hardware_instruments[mount.to_hw_mount()].set_current_volume(current_volume)
self._hardware_api.hardware_instruments[
mount.to_hw_mount()
].set_current_volume(current_volume)

async def execute(
self, params: EvotipSealPipetteParams
Expand Down Expand Up @@ -226,9 +239,9 @@ async def execute(
)
maximum_volume = self._state_view.pipettes.get_maximum_volume(pipette_id)
if self._state_view.pipettes.get_mount(pipette_id) == MountType.LEFT:
self._hardware_api.home(axes = [Axis.P_L])
self._hardware_api.home(axes=[Axis.P_L])
else:
self._hardware_api.home(axes = [Axis.P_R])
self._hardware_api.home(axes=[Axis.P_R])

# Begin relative pickup steps for the resin tips

Expand Down Expand Up @@ -267,9 +280,11 @@ async def execute(
pipette_id=pipette_id,
tip_geometry=tip_geometry,
)


state_update.set_fluid_aspirated(pipette_id=pipette_id, fluid=AspiratedFluid(kind=FluidKind.LIQUID, volume=maximum_volume))

state_update.set_fluid_aspirated(
pipette_id=pipette_id,
fluid=AspiratedFluid(kind=FluidKind.LIQUID, volume=maximum_volume),
)
return SuccessData(
public=EvotipSealPipetteResult(
tipVolume=tip_geometry.volume,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class EvotipUnsealPipetteParams(PipetteIdMixin):
homeAfter: Optional[bool] = Field(
None,
description=(
"Whether to home this pipette's plunger after dropping the tip."
"Whether to home this pipette after dropping the tip."
" You should normally leave this unspecified to let the robot choose"
" a safe default depending on its hardware."
),
Expand Down Expand Up @@ -120,14 +120,14 @@ async def execute(self, params: EvotipUnsealPipetteParams) -> _ExecuteReturn:
)
if isinstance(move_result, DefinedErrorData):
return move_result

# Move to an appropriate position
mount = self._state_view.pipettes.get_mount(pipette_id)

mount_axis = MotorAxis.LEFT_Z if mount == MountType.LEFT else MotorAxis.RIGHT_Z
await self._gantry_mover.move_axes(
axis_map={mount_axis: -14}, speed=10, relative_move=True
)
axis_map={mount_axis: -14}, speed=10, relative_move=True
)

await self._tip_handler.drop_tip(
pipette_id=pipette_id,
Expand Down
4 changes: 3 additions & 1 deletion api/src/opentrons/protocol_engine/execution/tip_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ async def drop_tip(
else:
kwargs = {}

await self._hardware_api.tip_drop_moves(mount=hw_mount, ignore_plunger=ignore_plunger, **kwargs)
await self._hardware_api.tip_drop_moves(
mount=hw_mount, ignore_plunger=ignore_plunger, **kwargs
)

if do_not_ignore_tip_presence:
# Allow TipNotAttachedError to propagate.
Expand Down
6 changes: 4 additions & 2 deletions api/src/opentrons/protocol_engine/state/pipettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,10 @@ def _update_aspirated(
self, update: update_types.PipetteAspiratedFluidUpdate
) -> None:
if self._state.pipette_contents_by_id[update.pipette_id] is None:
self._state.pipette_contents_by_id[update.pipette_id] = fluid_stack.FluidStack()

self._state.pipette_contents_by_id[
update.pipette_id
] = fluid_stack.FluidStack()

self._fluid_stack_log_if_empty(update.pipette_id).add_fluid(update.fluid)

def _update_ejected(self, update: update_types.PipetteEjectedFluidUpdate) -> None:
Expand Down

0 comments on commit 4396fa5

Please sign in to comment.