Skip to content

feat(api): store and use disposal locations in the location cache#18268

Merged
jbleon95 merged 9 commits into
edgefrom
disposal_locations_location_cache_support
May 8, 2025
Merged

feat(api): store and use disposal locations in the location cache#18268
jbleon95 merged 9 commits into
edgefrom
disposal_locations_location_cache_support

Conversation

@jbleon95
Copy link
Copy Markdown
Contributor

@jbleon95 jbleon95 commented May 5, 2025

Overview

Closes AUTH-1629.

This PR adds support to the location cache to store TrashBin and WasteChute objects, as well as using those in InstrumentContext.dispense, InstrumentContext.blow_out and InstrumentContext.air_gap if you have last accessed a trash bin or waste chute and call those without arguments. air_gap does not take a location argument, but previously would raise an error if not over a well. This was left over from when trashes were labware, and there is no reason to not allow an air gap if over a trash.

In addition to using this, we are now storing it after you move_to, dispense or blow_out into a trash or waste chute. While storing is being done unconditionally, we will still return None if below api version 2.24. This maintains bug and error compatibility with previous versions.

Test Plan and Hands on Testing

Tested the following protocol works and passes analysis

requirements = {
    "robotType": "Flex",
    "apiLevel": "2.24"
}

metadata = {
    "protocolName":'Trash last location',
}

def run(protocol_context):
    tiprack = protocol_context.load_labware("opentrons_flex_96_tiprack_50ul", "C2")
    trash = protocol_context.load_trash_bin('A3')
    waste_chute = protocol_context.load_waste_chute()
    arma_plate = protocol_context.load_labware("armadillo_96_wellplate_200ul_pcr_full_skirt", "D1")
    pipette = protocol_context.load_instrument("flex_1channel_50", "left", tip_racks=[tiprack])

    pipette.pick_up_tip()
    pipette.aspirate(40, arma_plate['A1'].bottom(z=1))

    pipette.move_to(trash)
    pipette.air_gap()
    pipette.dispense()
    pipette.blow_out()

    pipette.aspirate(40, arma_plate['A1'].bottom(z=1))

    pipette.move_to(waste_chute)
    pipette.air_gap()
    pipette.dispense()
    pipette.blow_out()

    pipette.drop_tip()

Changelog

  • Store TrashBin and WasteChute when accessed by move_to, dispense and blow_out
  • Allow dispense and blow_out to be called without location argument if already over a disposal location
  • Allow air_gap to be used if moved over a disposal location

Review requests

Risk assessment

Low-medium, touches some public facing code but new behavior is gated by version checks.

@jbleon95 jbleon95 requested review from ddcc4, ecormany and sanni-t May 5, 2025 21:52
@jbleon95 jbleon95 requested a review from a team as a code owner May 5, 2025 21:52
Copy link
Copy Markdown
Member

@sanni-t sanni-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Glad it wasn't too gnarly to add disposal locations to cache!

Behavior of the ``volume`` parameter.

.. versionchanged:: 2.24
Can dispense over trash bin or waste chute implicitly.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should elaborate this to explain that dispense no longer needs an explicit trash location if pipette was already moved over a trash previously.

:returns: This instance.

.. versionchanged:: 2.24
Can blow out over trash bin or waste chute implicitly.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

if last_location is None or isinstance(
last_location, (TrashBin, WasteChute)
):
raise RuntimeError("No valid current location cache present")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise RuntimeError("No valid current location cache present")
raise RuntimeError(f"Cached location of {last_location} is not valid for touch tip.")

isinstance(last_location, types.Location)
and not last_location.labware.is_well
):
raise RuntimeError("No previous valid location cached to perform air gap")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe update this error message with a similar one as touch tip suggestion? Helps to actually see the cached location in error message


Raises:
NoLocationError: The is no input location and no cached loaction.
NoLocationError: The is no input location and no cached location.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NoLocationError: The is no input location and no cached location.
NoLocationError: There is no input location and no cached location.

😝

mock_protocol_core: ProtocolCore,
subject: InstrumentCore,
) -> None:
"""It should move the pipette to a trash."""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""It should move the pipette to a trash."""
"""It should move the pipette to a trash and update cached location.""" ?

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 23.56%. Comparing base (fb57f35) to head (3bf9bc8).
Report is 1 commits behind head on edge.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             edge   #18268   +/-   ##
=======================================
  Coverage   23.56%   23.56%           
=======================================
  Files        3059     3059           
  Lines      256332   256332           
  Branches    30109    30109           
=======================================
  Hits        60416    60416           
  Misses     195902   195902           
  Partials       14       14           
Flag Coverage Δ
protocol-designer 19.06% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

if not loc or not loc.labware.is_well:
raise RuntimeError("No previous Well cached to perform air gap")
target = loc.labware.as_well().top(height)
last_location = self._protocol_core.get_last_location()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to use _get_last_location_by_api_version() that you defined below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we were to make this change we'd call get_last_location using a mount argument, which we have not been doing here. That may be more technically correct, but this is what has been in the code and changing it without a version check would potentially break or change the behavior of older protocols, and changing that is slightly out of scope for this PR.

if self.api_version < APIVersion(2, 24) and isinstance(
last_location, (TrashBin, WasteChute)
):
last_location = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to use _get_last_location_by_api_version() that you defined below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Sorry, I don't know why Github sent out a duplicate comment here!)

)
return last_location if isinstance(last_location, types.Location) else None
else:
return self._protocol_core.get_last_location()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this return (before version 2.14)? Could this be a trashbin/wastechute?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calls get_last_location without a mount argument. We can get away without checking the type because that core will be the legacy core and that will not return a trash bin or waste chute.

and isinstance(last_location, types.Location)
and isinstance(last_location.labware, labware.Well)
):
self.move_to(last_location.labware.top())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the pipette should not move during configure_for_volume() if the pipette is in the trash/wastechute?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main concern for configure_for_volume is accidentally aspirating liquid if the configuration is done while the tip is submerged in liquid. This is not a valid concern if the tip is over a trash bin or waste chute.

if self.api_version < APIVersion(2, 24) and isinstance(
last_location, (TrashBin, WasteChute)
):
last_location = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Sorry, I don't know why Github sent out a duplicate comment here!)

def location_cache(self) -> Optional[Union[Location, TrashBin, WasteChute]]:
"""The cache used by the robot to determine where it last was.

.. versionchanged:: 2.24
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've hidden this reference entry, but this is a good addition for internal documentation.

Comment on lines +665 to +666
If previously moved to, dispensed or blown out into a trash bin or waste chute,
you do not need to include location if blowing out into that disposal location.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are a little wordy, but accurate and not as vague as the previous wording with "implicitly". If you feel like one more commit:

Suggested change
If previously moved to, dispensed or blown out into a trash bin or waste chute,
you do not need to include location if blowing out into that disposal location.
``location`` is no longer required if the pipette just moved to, dispensed, or blew out into a trash bin or waste chute.

Otherwise :shipit:

@jbleon95 jbleon95 merged commit c751947 into edge May 8, 2025
24 checks passed
@jbleon95 jbleon95 deleted the disposal_locations_location_cache_support branch May 8, 2025 19:03
ddcc4 pushed a commit that referenced this pull request May 16, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects
ddcc4 pushed a commit that referenced this pull request May 16, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 17, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 19, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 19, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 19, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 20, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 20, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 22, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 23, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 24, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 24, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 29, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 29, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
ddcc4 pushed a commit that referenced this pull request May 29, 2025
…8268)

Adds support to the location cache to store and use trash bin and waste chute objects

(cherry picked from commit c751947)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants