Skip to content

Commit

Permalink
updated setting and getting liquid info and linted
Browse files Browse the repository at this point in the history
  • Loading branch information
pmoegenburg committed Oct 22, 2024
1 parent 77f28d3 commit 52bc91e
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 24 deletions.
34 changes: 26 additions & 8 deletions api/src/opentrons/protocol_engine/state/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from opentrons.types import Point, DeckSlotName, StagingSlotName, MountType

from opentrons_shared_data.labware.constants import WELL_NAME_PATTERN
from opentrons_shared_data.labware.labware_definition import InnerWellGeometry
from opentrons_shared_data.deck.types import CutoutFixture
from opentrons_shared_data.pipette import PIPETTE_X_SPAN
from opentrons_shared_data.pipette.types import ChannelCount
Expand Down Expand Up @@ -1372,6 +1371,7 @@ def get_well_offset_adjustment(
Distance is with reference to the well bottom.
"""
# refactor? Consider how many conversions are being done
initial_handling_height = self.get_well_handling_height(
labware_id=labware_id,
well_name=well_name,
Expand Down Expand Up @@ -1401,15 +1401,32 @@ def get_meniscus_height(
well_name: str,
) -> float:
"""Returns stored meniscus height in specified well."""
meniscus_height = self._wells.get_last_measured_liquid_height(
labware_id=labware_id, well_name=well_name
)
if meniscus_height is None:
raise errors.LiquidHeightUnknownError(
"Must liquid probe before specifying WellOrigin.MENISCUS."
(
loaded_volume_info,
probed_height_info,
probed_volume_info,
) = self._wells.get_well_liquid_info(labware_id=labware_id, well_name=well_name)
if probed_height_info:
assert probed_height_info.height is not None
return probed_height_info.height
elif loaded_volume_info:
assert loaded_volume_info.volume is not None
return self.get_well_height_at_volume(
labware_id=labware_id,
well_name=well_name,
volume=loaded_volume_info.volume,
)
elif probed_volume_info:
assert probed_volume_info.volume is not None
return self.get_well_height_at_volume(
labware_id=labware_id,
well_name=well_name,
volume=probed_volume_info.volume,
)
else:
return meniscus_height
raise errors.LiquidHeightUnknownError(
"Must LiquidProbe or LoadLiquid before specifying WellOrigin.MENISCUS."
)

def get_well_handling_height(
self,
Expand Down Expand Up @@ -1474,6 +1491,7 @@ def validate_dispense_volume_into_well(
volume: float,
) -> None:
"""Raise InvalidDispenseVolumeError if planned dispense volume will overflow well."""
# update this (or where it's used)? Consider how many conversions are being done
well_def = self._labware.get_well_definition(labware_id, well_name)
well_volumetric_capacity = well_def.totalLiquidVolume
if well_location.origin == WellOrigin.MENISCUS:
Expand Down
6 changes: 3 additions & 3 deletions api/src/opentrons/protocol_engine/state/update_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def set_pipette_location(
new_well_name: str,
new_deck_point: DeckPoint,
) -> None:
"""Schedule a pipette's location to be set to a well."""
pass

@overload
def set_pipette_location(
Expand All @@ -253,10 +253,9 @@ def set_pipette_location(
new_addressable_area_name: str,
new_deck_point: DeckPoint,
) -> None:
"""Schedule a pipette's location to be set to an addressable area."""
pass

def set_pipette_location( # noqa: D102
def set_pipette_location(
self,
*,
pipette_id: str,
Expand All @@ -265,6 +264,7 @@ def set_pipette_location( # noqa: D102
new_addressable_area_name: str | NoChangeType = NO_CHANGE,
new_deck_point: DeckPoint,
) -> None:
"""Schedule a pipette's location to be set to a well or an addressable area."""
if new_addressable_area_name != NO_CHANGE:
self.pipette_location = PipetteLocationUpdate(
pipette_id=pipette_id,
Expand Down
22 changes: 16 additions & 6 deletions api/src/opentrons/protocol_engine/state/wells.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
"""Basic well data state and store."""
from dataclasses import dataclass
from typing import Dict, List, Optional
from opentrons.protocol_engine.actions.actions import (
FailCommandAction,
SucceedCommandAction,
)
from typing import Dict, List, Optional, Tuple

from opentrons.protocol_engine.types import (
ProbedHeightInfo,
ProbedVolumeInfo,
Expand Down Expand Up @@ -71,7 +68,7 @@ def _set_operated_liquid(self, state_update: update_types.StateUpdate) -> None:
if state_update.operated_liquid != update_types.NO_CHANGE:
labware_id = state_update.operated_liquid.labware_id
well_name = state_update.operated_liquid.well_name
# clear well probed_height info? Update types.py docstring
del self._state.probed_heights[labware_id][well_name]
prev_loaded_vol_info = self._state.loaded_volumes[labware_id][well_name]
if prev_loaded_vol_info.volume:
self._state.loaded_volumes[labware_id][well_name] = LoadedVolumeInfo(
Expand Down Expand Up @@ -157,3 +154,16 @@ def has_measured_liquid_height(self, labware_id: str, well_name: str) -> bool:
return bool(self._state.probed_heights[labware_id][well_name].height)
except KeyError:
return False

def get_well_liquid_info(
self, labware_id: str, well_name: str
) -> Tuple[
Optional[LoadedVolumeInfo],
Optional[ProbedHeightInfo],
Optional[ProbedVolumeInfo],
]:
"""Return all the liquid info for a well."""
loaded_volume_info = self._state.loaded_volumes[labware_id][well_name]
probed_height_info = self._state.probed_heights[labware_id][well_name]
probed_volume_info = self._state.probed_volumes[labware_id][well_name]
return loaded_volume_info, probed_height_info, probed_volume_info
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
LoadLiquidParams,
)
from opentrons.protocol_engine.state.state import StateView
from opentrons.protocol_engine.resources.model_utils import ModelUtils


@pytest.fixture
Expand All @@ -18,9 +19,11 @@ def mock_state_view(decoy: Decoy) -> StateView:


@pytest.fixture
def subject(mock_state_view: StateView) -> LoadLiquidImplementation:
def subject(
mock_state_view: StateView, model_utils: ModelUtils
) -> LoadLiquidImplementation:
"""Load liquid implementation test subject."""
return LoadLiquidImplementation(state_view=mock_state_view)
return LoadLiquidImplementation(state_view=mock_state_view, model_utils=model_utils)


async def test_load_liquid_implementation(
Expand Down
4 changes: 2 additions & 2 deletions api/tests/opentrons/protocol_engine/state/test_well_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ def test_handles_liquid_probe_success(subject: WellStore) -> None:
SucceedCommandAction(private_result=None, command=liquid_probe)
)

assert len(subject.state.measured_liquid_heights) == 1
assert len(subject.state.probed_heights) == 1

assert subject.state.measured_liquid_heights[labware_id][well_name].height == 0.5
assert subject.state.probed_heights[labware_id][well_name].height == 0.5
10 changes: 7 additions & 3 deletions api/tests/opentrons/protocol_engine/state/test_well_view.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Well view tests."""
from datetime import datetime
from opentrons.protocol_engine.types import LiquidHeightInfo
from opentrons.protocol_engine.types import ProbedHeightInfo
import pytest
from opentrons.protocol_engine.state.wells import WellState, WellView

Expand All @@ -10,8 +10,12 @@ def subject() -> WellView:
"""Get a well view test subject."""
labware_id = "labware-id"
well_name = "well-name"
height_info = LiquidHeightInfo(height=0.5, last_measured=datetime.now())
state = WellState(measured_liquid_heights={labware_id: {well_name: height_info}})
height_info = ProbedHeightInfo(height=0.5, last_probed=datetime.now())
state = WellState(
loaded_volumes={},
probed_heights={labware_id: {well_name: height_info}},
probed_volumes={},
)

return WellView(state)

Expand Down

0 comments on commit 52bc91e

Please sign in to comment.