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(step-generation): py command generation for mix() #17833

Open
wants to merge 7 commits into
base: edge
Choose a base branch
from

Conversation

jerader
Copy link
Collaborator

@jerader jerader commented Mar 20, 2025

closes AUTH-1097

Overview

this PR introduces the py command generation for mix()! It is emitted only if there are acceptable args. Meaning no aspirate delay, no dispense delay.

TODO: figure out the flow rates! user can specify both aspirate and dispense flow rates but mix can only use one. how do we know which one to use?

Test Plan and Hands on Testing

Review the code and smoke test

here is an example i made that passes analysis for the different variations of commands

from contextlib import nullcontext as pd_step
from opentrons import protocol_api, types

metadata = {
    "protocolName": "test mixing",
    "created": "2025-03-20T17:54:17.554Z",
    "lastModified": "2025-03-20T17:55:04.093Z",
    "protocolDesigner": "8.4.3",
    "source": "Protocol Designer",
}

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

def run(protocol: protocol_api.ProtocolContext):
    # Load Labware:
    tip_rack_1 = protocol.load_labware(
        "opentrons_flex_96_tiprack_50ul",
        "C2",
        namespace="opentrons",
        version=1,
    )
    reservoir_1 = protocol.load_labware(
        "axygen_1_reservoir_90ml",
        "D1",
        namespace="opentrons",
        version=2,
    )

    # Load Pipettes:
    pipette_left = protocol.load_instrument("flex_1channel_50", "left", tip_racks=[tip_rack_1])

    # Load Trash Bins:
    trash_bin_1 = protocol.load_trash_bin("A3")

    # PROTOCOL STEPS

    # Step 1: NO MIX SINCE DELAY IS SET
    pipette_left.pick_up_tip(location=tip_rack_1)
    pipette_left.configure_for_volume(10)
    pipette_left.aspirate(
        volume=10,
        location=reservoir_1["A1"].bottom(z=1),
        rate=35 / pipette_left.flow_rate.aspirate,
    )
    protocol.delay(seconds=10)
    pipette_left.dispense(
        volume=10,
        location=reservoir_1["A1"].bottom(z=1),
        rate=57 / pipette_left.flow_rate.dispense,
    )
    protocol.delay(seconds=10)
    pipette_left.aspirate(
        volume=10,
        location=reservoir_1["A1"].bottom(z=1),
        rate=35 / pipette_left.flow_rate.aspirate,
    )
    protocol.delay(seconds=10)
    pipette_left.dispense(
        volume=10,
        location=reservoir_1["A1"].bottom(z=1),
        rate=57 / pipette_left.flow_rate.dispense,
    )
    protocol.delay(seconds=10)
    pipette_left.drop_tip()

    # Step 2: MIX SINCE DELAY IS NOT SET
    pipette_left.pick_up_tip(location=tip_rack_1)
    pipette_left.configure_for_volume(10)
    pipette_left.flow_rate.aspirate = 35
    pipette_left.flow_rate.dispense = 57
    pipette_left.mix(
        repetitions=2,
        volume=10,
        location=reservoir_1["A1"].bottom(z=1),
    )
    pipette_left.flow_rate.blow_out = 57
    pipette_left.blow_out(trash_bin_1)
    pipette_left.touch_tip(
        reservoir_1["A1"],
        v_offset=-1,
    )
    pipette_left.drop_tip()

Changelog

  • py command for mix() in the mixUtil
  • add test cases for the different py command variations
  • extend util to include invariant context and plug into all usages of the util

Risk assessment

low, behind a ff

Copy link

codecov bot commented Mar 20, 2025

Codecov Report

Attention: Patch coverage is 98.80952% with 1 line in your changes missing coverage. Please review.

Project coverage is 63.24%. Comparing base (c7bcbad) to head (4439db3).
Report is 9 commits behind head on edge.

Files with missing lines Patch % Lines
...ration/src/commandCreators/compound/consolidate.ts 66.66% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             edge   #17833       +/-   ##
===========================================
+ Coverage   23.41%   63.24%   +39.83%     
===========================================
  Files        2891     2891               
  Lines      222561   223631     +1070     
  Branches    19013    19545      +532     
===========================================
+ Hits        52115   141438    +89323     
+ Misses     170435    82008    -88427     
- Partials       11      185      +174     
Flag Coverage Δ
protocol-designer 19.06% <90.47%> (+0.20%) ⬆️
step-generation 4.37% <98.80%> (-0.02%) ⬇️

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

Files with missing lines Coverage Δ
shared-data/command/types/index.ts 100.00% <100.00%> (ø)
...eration/src/commandCreators/compound/distribute.ts 93.30% <100.00%> (-1.30%) ⬇️
...tep-generation/src/commandCreators/compound/mix.ts 88.56% <100.00%> (+1.69%) ⬆️
...eneration/src/commandCreators/compound/transfer.ts 95.14% <100.00%> (-1.03%) ⬇️
...ration/src/commandCreators/compound/consolidate.ts 94.63% <66.66%> (-1.02%) ⬇️

... and 1696 files with indirect coverage changes

🚀 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.

repetitions=2,
volume=5,
location=mockPythonName["A1"].bottom(z=3.2),
rate=(2.1 / mockPythonName.flow_rate.aspirate) + (2.2 / mockPythonName.flow_rate.dispense),
Copy link
Collaborator Author

@jerader jerader Mar 20, 2025

Choose a reason for hiding this comment

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

need to figure out how to show both flow rates or if we have to remove one?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

okay discussed with jeremy in standup and actually we can just define it above the mix()

like this

mockPythonName.mix(
    repetitions=2,
    volume=5,
    location=mockPythonName["C1"].bottom(z=3.2),
)

@jerader jerader marked this pull request as ready for review March 20, 2025 18:26
@jerader jerader requested a review from a team as a code owner March 20, 2025 18:26
@jerader jerader requested a review from ddcc4 March 20, 2025 18:26
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.

1 participant