Skip to content

Commit

Permalink
fix(api): Revert #14371 Addition of Cutout Fixtures to slot height ch…
Browse files Browse the repository at this point in the history
…ecks (#14400)

This reverts commit 4c77160 due to bug found.
  • Loading branch information
CaseyBatten authored Jan 31, 2024
1 parent 3308ae5 commit ececee3
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 125 deletions.
28 changes: 0 additions & 28 deletions api/src/opentrons/protocol_engine/state/addressable_areas.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
AreaNotInDeckConfigurationError,
SlotDoesNotExistError,
AddressableAreaDoesNotExistError,
CutoutDoesNotExistError,
)
from ..resources import deck_configuration_provider
from ..types import (
Expand Down Expand Up @@ -139,9 +138,6 @@ def _get_conflicting_addressable_areas_error_string(
"cutoutD2": DeckSlotName.SLOT_D2,
"cutoutD3": DeckSlotName.SLOT_D3,
}
DECK_SLOT_TO_CUTOUT_MAP = {
deck_slot: cutout for cutout, deck_slot in CUTOUT_TO_DECK_SLOT_MAP.items()
}


class AddressableAreaStore(HasState[AddressableAreaState], HandlesActions):
Expand Down Expand Up @@ -466,30 +462,6 @@ def get_addressable_area_center(self, addressable_area_name: str) -> Point:
z=position.z,
)

def get_fixture_by_deck_slot_name(
self, slot_name: DeckSlotName
) -> Optional[PotentialCutoutFixture]:
"""Get the Potential Cutout Fixture of a fixture currently loaded into a specific Deck Slot."""
deck_config = self.state.deck_configuration
potential_fixtures = self.state.potential_cutout_fixtures_by_cutout_id
if deck_config:
slot_cutout_id = DECK_SLOT_TO_CUTOUT_MAP[slot_name]
slot_cutout_fixture_id = None
# This will only ever be one under current assumptions
for cutout_id, cutout_fixture_id in deck_config:
if cutout_id == slot_cutout_id:
slot_cutout_fixture_id = cutout_fixture_id
break
if slot_cutout_fixture_id is None:
raise CutoutDoesNotExistError(
f"No Cutout was found in the Deck that matched provided slot {slot_name}."
)

for fixture in potential_fixtures[slot_cutout_id]:
if fixture.cutout_fixture_id == slot_cutout_fixture_id:
return fixture
return None

def get_fixture_height(self, cutout_fixture_name: str) -> float:
"""Get the z height of a cutout fixture."""
cutout_fixture = deck_configuration_provider.get_cutout_fixture(
Expand Down
23 changes: 3 additions & 20 deletions api/src/opentrons/protocol_engine/state/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
OnDeckLabwareLocation,
AddressableAreaLocation,
AddressableOffsetVector,
PotentialCutoutFixture,
)
from .config import Config
from .labware import LabwareView
Expand Down Expand Up @@ -167,10 +166,6 @@ def get_highest_z_in_slot(self, slot: DeckSlotLocation) -> float:
elif isinstance(slot_item, LoadedLabware):
# get stacked heights of all labware in the slot
return self.get_highest_z_of_labware_stack(slot_item.id)
elif isinstance(slot_item, PotentialCutoutFixture):
return self._addressable_areas.get_fixture_height(
slot_item.cutout_fixture_id
)
else:
return 0

Expand Down Expand Up @@ -692,33 +687,21 @@ def get_extra_waypoints(

def get_slot_item(
self, slot_name: Union[DeckSlotName, StagingSlotName]
) -> Union[LoadedLabware, LoadedModule, PotentialCutoutFixture, None]:
) -> Union[LoadedLabware, LoadedModule, None]:
"""Get the item present in a deck slot, if any."""
maybe_labware = self._labware.get_by_slot(
slot_name=slot_name,
)

if isinstance(slot_name, DeckSlotName):
maybe_fixture = self._addressable_areas.get_fixture_by_deck_slot_name(
slot_name
)
# Ignore generic single slot fixtures
if maybe_fixture and maybe_fixture.cutout_fixture_id in {
"singleLeftSlot",
"singleCenterSlot",
"singleRightSlot",
}:
maybe_fixture = None

maybe_module = self._modules.get_by_slot(
slot_name=slot_name,
)
else:
# Modules and fixtures can't be loaded on staging slots
maybe_fixture = None
# Modules can't be loaded on staging slots
maybe_module = None

return maybe_labware or maybe_module or maybe_fixture or None
return maybe_labware or maybe_module or None

@staticmethod
def get_slot_column(slot_name: DeckSlotName) -> int:
Expand Down
77 changes: 0 additions & 77 deletions api/tests/opentrons/protocol_api/core/engine/test_deck_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,83 +454,6 @@ def test_deck_conflict_raises_for_bad_partial_96_channel_move(
)


@pytest.mark.parametrize(
("robot_type", "deck_type"),
[("OT-3 Standard", DeckType.OT3_STANDARD)],
)
@pytest.mark.parametrize(
["destination_well_point", "expected_raise"],
[
(
Point(x=100, y=100, z=10),
pytest.raises(
deck_conflict.PartialTipMovementNotAllowedError,
match="Moving to destination-labware in slot D2 with pipette column A1 nozzle configuration will result in collision with items in deck slot D3.",
),
),
],
)
def test_deck_conflict_raises_for_bad_partial_96_channel_move_with_fixtures(
decoy: Decoy,
mock_state_view: StateView,
destination_well_point: Point,
expected_raise: ContextManager[Any],
) -> None:
"""It should raise an error when moving to locations adjacent to fixtures with restrictions for partial tip 96-channel movement.
Test premise:
- we are using a pipette configured for COLUMN nozzle layout with primary nozzle A1
- there's a waste chute with in D3
- we are checking for conflicts when moving to column A12 of a labware in D2.
"""
decoy.when(mock_state_view.pipettes.get_channels("pipette-id")).then_return(96)
decoy.when(
mock_state_view.labware.get_display_name("destination-labware-id")
).then_return("destination-labware")
decoy.when(
mock_state_view.pipettes.get_nozzle_layout_type("pipette-id")
).then_return(NozzleConfigurationType.COLUMN)
decoy.when(mock_state_view.pipettes.get_primary_nozzle("pipette-id")).then_return(
"A1"
)
decoy.when(
mock_state_view.geometry.get_well_position(
labware_id="destination-labware-id",
well_name="A12",
well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)),
)
).then_return(destination_well_point)
decoy.when(
mock_state_view.geometry.get_ancestor_slot_name("destination-labware-id")
).then_return(DeckSlotName.SLOT_D2)
decoy.when(
mock_state_view.addressable_areas.get_fixture_height(
"wasteChuteRightAdapterNoCover"
)
).then_return(124.5)
decoy.when(
mock_state_view.geometry.get_highest_z_in_slot(
DeckSlotLocation(slotName=DeckSlotName.SLOT_D3)
)
).then_return(
mock_state_view.addressable_areas.get_fixture_height(
"wasteChuteRightAdapterNoCover"
)
)
decoy.when(mock_state_view.pipettes.get_attached_tip("pipette-id")).then_return(
TipGeometry(length=10, diameter=100, volume=0)
)

with expected_raise:
deck_conflict.check_safe_for_pipette_movement(
engine_state=mock_state_view,
pipette_id="pipette-id",
labware_id="destination-labware-id",
well_name="A12",
well_location=WellLocation(origin=WellOrigin.TOP, offset=WellOffset(z=10)),
)


@pytest.mark.parametrize(
("robot_type", "deck_type"),
[("OT-3 Standard", DeckType.OT3_STANDARD)],
Expand Down

0 comments on commit ececee3

Please sign in to comment.