Skip to content

Commit

Permalink
fix(shared-data): Re-apply update tip overlap values for Flex Pipettes (
Browse files Browse the repository at this point in the history
#15147) (#15284)

This is #15147 again but this time outside the context of an extremely
imminent release.

While this code needs to be merged, we should carefully consider how we
do so. We can't ship this until we can separate this behavior by API
level so that customers who may have tuned in offsets based on the old
incorrect tip offsets won't have their protocols invalidated - this data
needs to be loaded by API level.

Closes EXEC-452

---------

Co-authored-by: Carlos-fernandez <[email protected]>
  • Loading branch information
sfoster1 and Carlos-fernandez authored Jun 5, 2024
1 parent 085c140 commit 1754667
Show file tree
Hide file tree
Showing 26 changed files with 258 additions and 8 deletions.
8 changes: 6 additions & 2 deletions api/src/opentrons/protocol_api/core/engine/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from opentrons.protocol_api._nozzle_layout import NozzleLayout
from opentrons.hardware_control.nozzle_manager import NozzleConfigurationType
from opentrons.hardware_control.nozzle_manager import NozzleMap
from . import deck_conflict
from . import deck_conflict, overlap_versions

from ..instrument import AbstractInstrument
from .well import WellCore
Expand Down Expand Up @@ -745,7 +745,11 @@ def set_flow_rate(

def configure_for_volume(self, volume: float) -> None:
self._engine_client.configure_for_volume(
pipette_id=self._pipette_id, volume=volume, tip_overlap_version="v0"
pipette_id=self._pipette_id,
volume=volume,
tip_overlap_version=overlap_versions.overlap_for_api_version(
self._protocol_core.api_version
),
)

def prepare_to_aspirate(self) -> None:
Expand Down
16 changes: 16 additions & 0 deletions api/src/opentrons/protocol_api/core/engine/overlap_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Mappings between API versions and overlap versions."""
from functools import lru_cache
from typing_extensions import Final
from opentrons.protocols.api_support.types import APIVersion

_OVERLAP_VERSION_MAP: Final = {APIVersion(2, 0): "v0", APIVersion(2, 19): "v1"}


@lru_cache(1)
def overlap_for_api_version(api_version: APIVersion) -> str:
"""Get the overlap version for a specific API version."""
defined = list(reversed(sorted(_OVERLAP_VERSION_MAP.keys())))
for version in defined:
if version <= api_version:
return _OVERLAP_VERSION_MAP[version]
return _OVERLAP_VERSION_MAP[APIVersion(2, 0)]
9 changes: 6 additions & 3 deletions api/src/opentrons/protocol_api/core/engine/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@
MagneticBlockCore,
)
from .exceptions import InvalidModuleLocationError
from . import load_labware_params
from . import deck_conflict
from . import load_labware_params, deck_conflict, overlap_versions

if TYPE_CHECKING:
from ...labware import Labware
Expand Down Expand Up @@ -499,7 +498,11 @@ def load_instrument(
"""
engine_mount = MountType[mount.name]
load_result = self._engine_client.load_pipette(
instrument_name, engine_mount, tip_overlap_version="v0"
instrument_name,
engine_mount,
tip_overlap_version=overlap_versions.overlap_for_api_version(
self._api_version
),
)

return InstrumentCore(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
from opentrons.protocols.api_support.types import APIVersion
from opentrons.types import Location, Mount, MountType, Point

from ... import versions_below, versions_at_or_above


@pytest.fixture
def mock_engine_client(decoy: Decoy) -> EngineClient:
Expand Down Expand Up @@ -1173,15 +1175,37 @@ def test_is_tip_tracking_available(
assert subject.is_tip_tracking_available() == expected_result


def test_configure_for_volume(
@pytest.mark.parametrize("version", versions_below(APIVersion(2, 19), flex_only=False))
def test_configure_for_volume_pre_219(
decoy: Decoy,
mock_engine_client: EngineClient,
mock_protocol_core: ProtocolCore,
subject: InstrumentCore,
version: APIVersion,
) -> None:
"""Configure_for_volume should specify overlap version."""
decoy.when(mock_protocol_core.api_version).then_return(version)
subject.configure_for_volume(123.0)
decoy.verify(
mock_engine_client.configure_for_volume(
pipette_id=subject.pipette_id, volume=123.0, tip_overlap_version="v0"
)
)


@pytest.mark.parametrize("version", versions_at_or_above(APIVersion(2, 19)))
def test_configure_for_volume_post_219(
decoy: Decoy,
mock_engine_client: EngineClient,
mock_protocol_core: ProtocolCore,
subject: InstrumentCore,
version: APIVersion,
) -> None:
"""Configure_for_volume should specify overlap version."""
decoy.when(mock_protocol_core.api_version).then_return(version)
subject.configure_for_volume(123.0)
decoy.verify(
mock_engine_client.configure_for_volume(
pipette_id=subject.pipette_id, volume=123.0, tip_overlap_version="v1"
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Test the tip overlap selection logic in the API core."""
import pytest

from opentrons.protocol_api.core.engine.overlap_versions import overlap_for_api_version
from opentrons.protocols.api_support.types import APIVersion

from ... import versions_below, versions_at_or_above


@pytest.mark.parametrize(
"api_version", versions_below(APIVersion(2, 19), flex_only=False)
)
def test_all_below_219_use_v0(api_version: APIVersion) -> None:
"""Versions below 2.19 should use v0."""
assert overlap_for_api_version(api_version) == "v0"


@pytest.mark.parametrize("api_version", versions_at_or_above(APIVersion(2, 19)))
def test_all_above_219_use_v1(api_version: APIVersion) -> None:
"""Versions above 2.19 should use v1."""
assert overlap_for_api_version(api_version) == "v1"


def test_future_api_version_uses_v1() -> None:
"""Future versions should use v1."""
assert overlap_for_api_version(APIVersion(2, 99)) == "v1"
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
STANDARD_OT3_DECK,
)

from ... import versions_below, versions_at_or_above


@pytest.fixture(scope="session")
def ot2_standard_deck_def() -> DeckDefinitionV5:
Expand Down Expand Up @@ -235,7 +237,10 @@ def test_get_slot_item_empty(
assert subject.get_slot_item(DeckSlotName.SLOT_1) is None


def test_load_instrument(
@pytest.mark.parametrize(
"api_version", versions_below(APIVersion(2, 19), flex_only=False)
)
def test_load_instrument_pre_219(
decoy: Decoy,
mock_sync_hardware_api: SyncHardwareAPI,
mock_engine_client: EngineClient,
Expand Down Expand Up @@ -268,6 +273,40 @@ def test_load_instrument(
assert result.pipette_id == "cool-pipette"


@pytest.mark.parametrize("api_version", versions_at_or_above(APIVersion(2, 19)))
def test_load_instrument_post_219(
decoy: Decoy,
mock_sync_hardware_api: SyncHardwareAPI,
mock_engine_client: EngineClient,
subject: ProtocolCore,
) -> None:
"""It should issue a LoadPipette command."""
decoy.when(
mock_engine_client.load_pipette(
pipette_name=PipetteNameType.P300_SINGLE,
mount=MountType.LEFT,
tip_overlap_version="v1",
)
).then_return(commands.LoadPipetteResult(pipetteId="cool-pipette"))

decoy.when(
mock_engine_client.state.pipettes.get_flow_rates("cool-pipette")
).then_return(
FlowRates(
default_aspirate={"1.1": 22},
default_dispense={"3.3": 44},
default_blow_out={"5.5": 66},
),
)

result = subject.load_instrument(
instrument_name=PipetteNameType.P300_SINGLE, mount=Mount.LEFT
)

assert isinstance(result, InstrumentCore)
assert result.pipette_id == "cool-pipette"


def test_load_labware(
decoy: Decoy,
mock_engine_client: EngineClient,
Expand Down
19 changes: 19 additions & 0 deletions shared-data/js/__tests__/pipettes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ describe('pipette data accessors', () => {
'opentrons/opentrons_flex_96_filtertiprack_200ul/1': 10.5,
'opentrons/opentrons_flex_96_filtertiprack_50ul/1': 10.5,
},
v1: {
default: 10.5,
'opentrons/opentrons_flex_96_tiprack_1000ul/1': 9.65,
'opentrons/opentrons_flex_96_tiprack_200ul/1': 9.76,
'opentrons/opentrons_flex_96_tiprack_50ul/1': 10.09,
'opentrons/opentrons_flex_96_filtertiprack_1000ul/1': 9.65,
'opentrons/opentrons_flex_96_filtertiprack_200ul/1': 9.76,
'opentrons/opentrons_flex_96_filtertiprack_50ul/1': 10.09,
},
},
defaultTipracks: [
'opentrons/opentrons_flex_96_tiprack_1000ul/1',
Expand Down Expand Up @@ -156,6 +165,11 @@ describe('pipette data accessors', () => {
[tiprackFilter50uL]: 10.5,
[tiprack50uL]: 10.5,
},
v1: {
default: 10.5,
[tiprackFilter50uL]: 10.09,
[tiprack50uL]: 10.09,
},
},
defaultTipracks: [tiprack50uL, tiprackFilter50uL],
maxVolume: 50,
Expand Down Expand Up @@ -206,6 +220,11 @@ describe('pipette data accessors', () => {
[tiprackFilter50uL]: 10.5,
[tiprack50uL]: 10.5,
},
v1: {
default: 10.5,
[tiprackFilter50uL]: 10.09,
[tiprack50uL]: 10.09,
},
},
defaultTipracks: [tiprack50uL, tiprackFilter50uL],
maxVolume: 30,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,15 @@
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 10.1,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.05,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.17
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.42,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 9.67,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 9.42,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 9.67
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 10.1,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.05,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.17
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.42,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 9.67,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 9.42,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 9.67
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.05,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.05
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 9.27
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.05,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.05
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 9.27
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.05,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.05
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 9.27
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.05,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.05
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 9.27,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 9.27
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.5
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.16,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 10.21,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.74,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.21,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 9.74,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.16
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.5
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.16,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 10.21,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.74,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.21,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 9.74,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.16
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.5,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 10.5,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 10.5
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.16,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 10.21,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.74
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,15 @@
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.5
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 9.65,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.76,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.09,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 9.65,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 9.76,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.09
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,15 @@
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 10.5,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.5
},
"v1": {
"default": 10.5,
"opentrons/opentrons_flex_96_tiprack_1000ul/1": 9.65,
"opentrons/opentrons_flex_96_tiprack_200ul/1": 9.76,
"opentrons/opentrons_flex_96_tiprack_50ul/1": 10.09,
"opentrons/opentrons_flex_96_filtertiprack_1000ul/1": 9.65,
"opentrons/opentrons_flex_96_filtertiprack_200ul/1": 9.76,
"opentrons/opentrons_flex_96_filtertiprack_50ul/1": 10.09
}
}
}
Loading

0 comments on commit 1754667

Please sign in to comment.