From 53b3131c7cb1144d08999c8a4cabf56d4b3b51b3 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Fri, 21 Jun 2024 13:17:55 -0400 Subject: [PATCH 01/12] feat(api): change liquid_probe to respect min well height Add logic to liquid_probe_in_place that will not go to the very bottom of the well, but stop slightly above it(as specified by the well's minimum height) fix EXEC-576 --- .../protocol_engine/execution/pipetting.py | 3 +- .../protocol_engine/state/labware.py | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/api/src/opentrons/protocol_engine/execution/pipetting.py b/api/src/opentrons/protocol_engine/execution/pipetting.py index 05a217b45ee..53c0945de6a 100644 --- a/api/src/opentrons/protocol_engine/execution/pipetting.py +++ b/api/src/opentrons/protocol_engine/execution/pipetting.py @@ -177,8 +177,9 @@ async def liquid_probe_in_place( ) well_def = self._state_view.labware.get_well_definition(labware_id, well_name) well_depth = well_def.depth + well_min_height = self._state_view.labware.get_well_min_height(labware_id, well_name) z_pos = await self._hardware_api.liquid_probe( - mount=hw_pipette.mount, max_z_dist=well_depth + mount=hw_pipette.mount, max_z_dist=well_depth-well_min_height ) return float(z_pos) diff --git a/api/src/opentrons/protocol_engine/state/labware.py b/api/src/opentrons/protocol_engine/state/labware.py index e9750a652b4..03a088529e3 100644 --- a/api/src/opentrons/protocol_engine/state/labware.py +++ b/api/src/opentrons/protocol_engine/state/labware.py @@ -412,6 +412,42 @@ def get_should_center_pipette_on_target_well(self, labware_id: str) -> bool: len(self.get_definition(labware_id).wells) == 1 or len(self.get_definition(labware_id).wells) >= 96 ) + + def get_well_min_height( + self, labware_id: str, well_name: str + ) -> float: + """Get's the minimum distance that a liquid probe must stop + away from the bottom of a well. + + Args: + labware_id: Labware identifier. + well_name: Name of well in labware. + + Returns: + A single float representing the distance, in millimeters. + """ + well_definition = self.get_definition(labware_id) + try: + height_reqs = well_definition.liquidProbeParameters.minimumHeight + if len(height_reqs) == 0: + #TODO: find out what to actually do here + return 0.5 + if len(height_reqs) == 1: + return height_reqs[0].value + default_val = 0.5 + for entry in height_reqs: + if well_name in entry.applicableWells: + return entry.value + if entry.applicableWells == []: + default_val = entry.value + #No explicit height for this well, return default + return default_val + except AttributeError as e: #No liquidProbeParameters defined for this labware + #TODO: find out what to actually do here + return 0 + # raise errors.HardwareNotSupportedError( + # f"Labware {labware_id} does not have specifications for minimum height." + # ) from e def get_well_definition( self, From f498b755623eb622d57fcdae9b32a9ea9f01f2e7 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Fri, 21 Jun 2024 13:27:51 -0400 Subject: [PATCH 02/12] Change default values for min_height --- .../protocol_engine/execution/pipetting.py | 6 +++-- .../protocol_engine/state/labware.py | 24 +++++++------------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/api/src/opentrons/protocol_engine/execution/pipetting.py b/api/src/opentrons/protocol_engine/execution/pipetting.py index 53c0945de6a..aa05274774d 100644 --- a/api/src/opentrons/protocol_engine/execution/pipetting.py +++ b/api/src/opentrons/protocol_engine/execution/pipetting.py @@ -177,9 +177,11 @@ async def liquid_probe_in_place( ) well_def = self._state_view.labware.get_well_definition(labware_id, well_name) well_depth = well_def.depth - well_min_height = self._state_view.labware.get_well_min_height(labware_id, well_name) + well_min_height = self._state_view.labware.get_well_min_height( + labware_id, well_name + ) z_pos = await self._hardware_api.liquid_probe( - mount=hw_pipette.mount, max_z_dist=well_depth-well_min_height + mount=hw_pipette.mount, max_z_dist=well_depth - well_min_height ) return float(z_pos) diff --git a/api/src/opentrons/protocol_engine/state/labware.py b/api/src/opentrons/protocol_engine/state/labware.py index 03a088529e3..08f17932704 100644 --- a/api/src/opentrons/protocol_engine/state/labware.py +++ b/api/src/opentrons/protocol_engine/state/labware.py @@ -412,10 +412,8 @@ def get_should_center_pipette_on_target_well(self, labware_id: str) -> bool: len(self.get_definition(labware_id).wells) == 1 or len(self.get_definition(labware_id).wells) >= 96 ) - - def get_well_min_height( - self, labware_id: str, well_name: str - ) -> float: + + def get_well_min_height(self, labware_id: str, well_name: str) -> float: """Get's the minimum distance that a liquid probe must stop away from the bottom of a well. @@ -427,27 +425,23 @@ def get_well_min_height( A single float representing the distance, in millimeters. """ well_definition = self.get_definition(labware_id) + default_val = 0 try: height_reqs = well_definition.liquidProbeParameters.minimumHeight if len(height_reqs) == 0: - #TODO: find out what to actually do here - return 0.5 + return default_val if len(height_reqs) == 1: return height_reqs[0].value - default_val = 0.5 for entry in height_reqs: if well_name in entry.applicableWells: return entry.value - if entry.applicableWells == []: + if ( + entry.applicableWells == [] + ): # A "custom" default value will have "applicableWells" set to [] default_val = entry.value - #No explicit height for this well, return default return default_val - except AttributeError as e: #No liquidProbeParameters defined for this labware - #TODO: find out what to actually do here - return 0 - # raise errors.HardwareNotSupportedError( - # f"Labware {labware_id} does not have specifications for minimum height." - # ) from e + except AttributeError as e: # will occur when well does not have liquidProbeParameters + return default_val def get_well_definition( self, From 1c40bd39e4ffdd501760c67c50910f601f9a0715 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Mon, 24 Jun 2024 09:10:35 -0400 Subject: [PATCH 03/12] lint --- .../protocol_engine/state/labware.py | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/api/src/opentrons/protocol_engine/state/labware.py b/api/src/opentrons/protocol_engine/state/labware.py index 08f17932704..b078379a0f0 100644 --- a/api/src/opentrons/protocol_engine/state/labware.py +++ b/api/src/opentrons/protocol_engine/state/labware.py @@ -424,24 +424,26 @@ def get_well_min_height(self, labware_id: str, well_name: str) -> float: Returns: A single float representing the distance, in millimeters. """ - well_definition = self.get_definition(labware_id) - default_val = 0 - try: - height_reqs = well_definition.liquidProbeParameters.minimumHeight - if len(height_reqs) == 0: - return default_val - if len(height_reqs) == 1: - return height_reqs[0].value - for entry in height_reqs: - if well_name in entry.applicableWells: - return entry.value - if ( - entry.applicableWells == [] - ): # A "custom" default value will have "applicableWells" set to [] - default_val = entry.value + labware_definition = self.get_definition(labware_id) + default_val = 0.0 + if ( + labware_definition.liquidProbeParameters is None + or labware_definition.liquidProbeParameters.minimumHeight is None + ): return default_val - except AttributeError as e: # will occur when well does not have liquidProbeParameters + height_reqs = labware_definition.liquidProbeParameters.minimumHeight + if len(height_reqs) == 0: return default_val + if len(height_reqs) == 1: + return float(height_reqs[0]["value"]) + for entry in height_reqs: + if well_name in entry["applicableWells"]: + return float(entry["value"]) + if ( + entry["applicableWells"] == [] + ): # A "custom" default value will have "applicableWells" set to [] + default_val = float(entry["value"]) + return default_val def get_well_definition( self, From 16631b0a3389fd7e39396345146b8d42cc494515 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Mon, 24 Jun 2024 09:20:57 -0400 Subject: [PATCH 04/12] lint 2 --- api/src/opentrons/protocol_engine/state/labware.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/opentrons/protocol_engine/state/labware.py b/api/src/opentrons/protocol_engine/state/labware.py index b078379a0f0..5a57ff6b6ff 100644 --- a/api/src/opentrons/protocol_engine/state/labware.py +++ b/api/src/opentrons/protocol_engine/state/labware.py @@ -414,8 +414,7 @@ def get_should_center_pipette_on_target_well(self, labware_id: str) -> bool: ) def get_well_min_height(self, labware_id: str, well_name: str) -> float: - """Get's the minimum distance that a liquid probe must stop - away from the bottom of a well. + """Get's the minimum distance that a liquid probe must stop away from the bottom of a well. Args: labware_id: Labware identifier. From b84143d2f9c1794dc840bd1cad13700e4c1a9c1b Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Mon, 24 Jun 2024 14:59:08 -0400 Subject: [PATCH 05/12] changed schemas for pipettes --- .../2/geometry/eight_channel/p1000/3_0.json | 14 ++++++++++ .../2/geometry/eight_channel/p1000/3_3.json | 14 ++++++++++ .../2/geometry/eight_channel/p1000/3_4.json | 14 ++++++++++ .../2/geometry/eight_channel/p1000/3_5.json | 14 ++++++++++ .../2/geometry/eight_channel/p50/3_0.json | 6 ++++ .../2/geometry/eight_channel/p50/3_3.json | 6 ++++ .../2/geometry/eight_channel/p50/3_4.json | 6 ++++ .../2/geometry/eight_channel/p50/3_5.json | 6 ++++ .../ninety_six_channel/p1000/3_0.json | 14 ++++++++++ .../ninety_six_channel/p1000/3_3.json | 14 ++++++++++ .../ninety_six_channel/p1000/3_4.json | 14 ++++++++++ .../ninety_six_channel/p1000/3_5.json | 14 ++++++++++ .../ninety_six_channel/p1000/3_6.json | 14 ++++++++++ .../2/geometry/single_channel/p1000/3_0.json | 14 ++++++++++ .../2/geometry/single_channel/p1000/3_3.json | 14 ++++++++++ .../2/geometry/single_channel/p1000/3_4.json | 14 ++++++++++ .../2/geometry/single_channel/p1000/3_5.json | 14 ++++++++++ .../2/geometry/single_channel/p1000/3_6.json | 14 ++++++++++ .../2/geometry/single_channel/p1000/3_7.json | 14 ++++++++++ .../2/geometry/single_channel/p50/3_0.json | 6 ++++ .../2/geometry/single_channel/p50/3_3.json | 6 ++++ .../2/geometry/single_channel/p50/3_4.json | 6 ++++ .../2/geometry/single_channel/p50/3_5.json | 6 ++++ .../2/geometry/single_channel/p50/3_6.json | 6 ++++ .../schemas/2/pipetteGeometrySchema.json | 28 +++++++++++++++++++ 25 files changed, 292 insertions(+) diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_0.json index bc0e3637326..bc76a2669d5 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_0.json @@ -37,5 +37,19 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_3.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_3.json index bc0e3637326..bc76a2669d5 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_3.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_3.json @@ -37,5 +37,19 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_4.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_4.json index bc0e3637326..bc76a2669d5 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_4.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_4.json @@ -37,5 +37,19 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_5.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_5.json index bc0e3637326..bc76a2669d5 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_5.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/3_5.json @@ -37,5 +37,19 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_0.json index fbda0a2ede3..9bbd489e296 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_0.json @@ -37,5 +37,11 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_3.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_3.json index fbda0a2ede3..9bbd489e296 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_3.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_3.json @@ -37,5 +37,11 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_4.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_4.json index fbda0a2ede3..9bbd489e296 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_4.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_4.json @@ -37,5 +37,11 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_5.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_5.json index fbda0a2ede3..9bbd489e296 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_5.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/3_5.json @@ -37,5 +37,11 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_0.json b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_0.json index da209a72907..b0c41b25661 100644 --- a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_0.json +++ b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_0.json @@ -291,5 +291,19 @@ "H10": [45.0, -88.5, -259.15], "H11": [54.0, -88.5, -259.15], "H12": [63.0, -88.5, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_3.json b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_3.json index da209a72907..b0c41b25661 100644 --- a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_3.json +++ b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_3.json @@ -291,5 +291,19 @@ "H10": [45.0, -88.5, -259.15], "H11": [54.0, -88.5, -259.15], "H12": [63.0, -88.5, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_4.json b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_4.json index da209a72907..b0c41b25661 100644 --- a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_4.json +++ b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_4.json @@ -291,5 +291,19 @@ "H10": [45.0, -88.5, -259.15], "H11": [54.0, -88.5, -259.15], "H12": [63.0, -88.5, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_5.json b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_5.json index da209a72907..b0c41b25661 100644 --- a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_5.json +++ b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_5.json @@ -291,5 +291,19 @@ "H10": [45.0, -88.5, -259.15], "H11": [54.0, -88.5, -259.15], "H12": [63.0, -88.5, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_6.json b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_6.json index da209a72907..b0c41b25661 100644 --- a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_6.json +++ b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/3_6.json @@ -291,5 +291,19 @@ "H10": [45.0, -88.5, -259.15], "H11": [54.0, -88.5, -259.15], "H12": [63.0, -88.5, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_0.json index a1b2135a278..b30d15ddb66 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_0.json @@ -10,5 +10,19 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_3.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_3.json index a1b2135a278..b30d15ddb66 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_3.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_3.json @@ -10,5 +10,19 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_4.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_4.json index a1b2135a278..b30d15ddb66 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_4.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_4.json @@ -10,5 +10,19 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_5.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_5.json index a1b2135a278..b30d15ddb66 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_5.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_5.json @@ -10,5 +10,19 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_6.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_6.json index a1b2135a278..b30d15ddb66 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_6.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_6.json @@ -10,5 +10,19 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_7.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_7.json index a1b2135a278..b30d15ddb66 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_7.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/3_7.json @@ -10,5 +10,19 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t200": { + "minHeight": 0.5, + "minVolume": 0 + }, + "t1000": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_0.json index ca5180c4415..b40f6957277 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_0.json @@ -10,5 +10,11 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_3.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_3.json index ca5180c4415..b40f6957277 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_3.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_3.json @@ -10,5 +10,11 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_4.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_4.json index ca5180c4415..b40f6957277 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_4.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_4.json @@ -10,5 +10,11 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_5.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_5.json index ca5180c4415..b40f6957277 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_5.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_5.json @@ -10,5 +10,11 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_6.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_6.json index ca5180c4415..b40f6957277 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_6.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/3_6.json @@ -10,5 +10,11 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [-8.0, -22.0, -259.15] + }, + "lldSettings": { + "t50": { + "minHeight": 0.5, + "minVolume": 0 + } } } diff --git a/shared-data/pipette/schemas/2/pipetteGeometrySchema.json b/shared-data/pipette/schemas/2/pipetteGeometrySchema.json index 0591d3261a6..2ebaac051e0 100644 --- a/shared-data/pipette/schemas/2/pipetteGeometrySchema.json +++ b/shared-data/pipette/schemas/2/pipetteGeometrySchema.json @@ -84,6 +84,34 @@ "patternProperties": { "[A-Z]+[0-9]+": { "$ref": "#/definitions/xyzArray" } } + }, + "lldSettings": { + "type": "object", + "description": "Minimum space requirements for Liquid Level Detection to work properly", + "additionalProperties": false, + "properties": { + "t50": { + "type": "object", + "properties": { + "height": { "type": "number" }, + "volume": { "type": "number" } + } + }, + "t200": { + "type": "object", + "properties": { + "height": { "type": "number" }, + "volume": { "type": "number" } + } + }, + "t1000": { + "type": "object", + "properties": { + "height": { "type": "number" }, + "volume": { "type": "number" } + } + } + } } } } From fff6196efe727ef9c7bac7ad2d0385a7f4c6ad18 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Mon, 24 Jun 2024 15:47:34 -0400 Subject: [PATCH 06/12] Remove old well min height calculation --- .../protocol_engine/state/labware.py | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/api/src/opentrons/protocol_engine/state/labware.py b/api/src/opentrons/protocol_engine/state/labware.py index 5a57ff6b6ff..e9750a652b4 100644 --- a/api/src/opentrons/protocol_engine/state/labware.py +++ b/api/src/opentrons/protocol_engine/state/labware.py @@ -413,37 +413,6 @@ def get_should_center_pipette_on_target_well(self, labware_id: str) -> bool: or len(self.get_definition(labware_id).wells) >= 96 ) - def get_well_min_height(self, labware_id: str, well_name: str) -> float: - """Get's the minimum distance that a liquid probe must stop away from the bottom of a well. - - Args: - labware_id: Labware identifier. - well_name: Name of well in labware. - - Returns: - A single float representing the distance, in millimeters. - """ - labware_definition = self.get_definition(labware_id) - default_val = 0.0 - if ( - labware_definition.liquidProbeParameters is None - or labware_definition.liquidProbeParameters.minimumHeight is None - ): - return default_val - height_reqs = labware_definition.liquidProbeParameters.minimumHeight - if len(height_reqs) == 0: - return default_val - if len(height_reqs) == 1: - return float(height_reqs[0]["value"]) - for entry in height_reqs: - if well_name in entry["applicableWells"]: - return float(entry["value"]) - if ( - entry["applicableWells"] == [] - ): # A "custom" default value will have "applicableWells" set to [] - default_val = float(entry["value"]) - return default_val - def get_well_definition( self, labware_id: str, From a68f8bac658633d6e2f8b4137f59b5a1caedd993 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Tue, 25 Jun 2024 11:29:31 -0400 Subject: [PATCH 07/12] initial draft of changes --- .../opentrons/hardware_control/dev_types.py | 1 + .../protocol_engine/execution/pipetting.py | 6 ++--- .../resources/pipette_data_provider.py | 4 ++++ .../protocol_engine/state/pipettes.py | 24 ++++++++++++++++++- .../schemas/2/pipetteGeometrySchema.json | 12 +++++----- .../pipette/pipette_definition.py | 2 +- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/api/src/opentrons/hardware_control/dev_types.py b/api/src/opentrons/hardware_control/dev_types.py index 6eb459fef0f..c851faf5a25 100644 --- a/api/src/opentrons/hardware_control/dev_types.py +++ b/api/src/opentrons/hardware_control/dev_types.py @@ -98,6 +98,7 @@ class PipetteDict(InstrumentDict): supported_tips: Dict[PipetteTipType, SupportedTipsDefinition] pipette_bounding_box_offsets: PipetteBoundingBoxOffsetDefinition current_nozzle_map: NozzleMap + lld_settings: Dict[str, Dict[str, float]] class PipetteStateDict(TypedDict): diff --git a/api/src/opentrons/protocol_engine/execution/pipetting.py b/api/src/opentrons/protocol_engine/execution/pipetting.py index aa05274774d..88a6448267e 100644 --- a/api/src/opentrons/protocol_engine/execution/pipetting.py +++ b/api/src/opentrons/protocol_engine/execution/pipetting.py @@ -177,11 +177,9 @@ async def liquid_probe_in_place( ) well_def = self._state_view.labware.get_well_definition(labware_id, well_name) well_depth = well_def.depth - well_min_height = self._state_view.labware.get_well_min_height( - labware_id, well_name - ) + lld_min_height = self._state_view.pipettes.get_current_tip_lld_settings(pipette_id=pipette_id) z_pos = await self._hardware_api.liquid_probe( - mount=hw_pipette.mount, max_z_dist=well_depth - well_min_height + mount=hw_pipette.mount, max_z_dist=well_depth - lld_min_height ) return float(z_pos) diff --git a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py index e29976d3fc4..47091165794 100644 --- a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py +++ b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py @@ -40,6 +40,7 @@ class LoadedStaticPipetteData: nozzle_map: NozzleMap back_left_corner_offset: Point front_right_corner_offset: Point + pipette_lld_settings: Dict[str, Dict[str, float]] class VirtualPipetteDataProvider: @@ -240,6 +241,7 @@ def _get_virtual_pipette_static_config_by_model( # noqa: C901 front_right_corner_offset=Point( pip_front_right[0], pip_front_right[1], pip_front_right[2] ), + pipette_lld_settings=config.pipette_lld_settings ) def get_virtual_pipette_static_config( @@ -282,4 +284,6 @@ def get_pipette_static_config(pipette_dict: PipetteDict) -> LoadedStaticPipetteD front_right_corner_offset=Point( front_right_offset[0], front_right_offset[1], front_right_offset[2] ), + pipette_lld_settings=pipette_dict["lld_settings"] + ) diff --git a/api/src/opentrons/protocol_engine/state/pipettes.py b/api/src/opentrons/protocol_engine/state/pipettes.py index d1153e9a51e..77c05737c7f 100644 --- a/api/src/opentrons/protocol_engine/state/pipettes.py +++ b/api/src/opentrons/protocol_engine/state/pipettes.py @@ -97,6 +97,13 @@ class PipetteBoundingBoxOffsets: back_left_corner: Point front_right_corner: Point + +@dataclass(frozen=True) +class PipetteLldSettings: + """Minimum liquid requirements for Liquid Level Detection to work properly.""" + t50: Optional[Dict[str, float]] + t200: Optional[Dict[str, float]] + t1000: Optional[Dict[str, float]] @dataclass(frozen=True) @@ -118,6 +125,7 @@ class StaticPipetteConfig: pipette_bounding_box_offsets: PipetteBoundingBoxOffsets bounding_nozzle_offsets: BoundingNozzlesOffsets default_nozzle_map: NozzleMap + lld_settings: PipetteLldSettings @dataclass @@ -151,7 +159,7 @@ def __init__(self) -> None: movement_speed_by_id={}, static_config_by_id={}, flow_rates_by_id={}, - nozzle_configuration_by_id={}, + nozzle_configuration_by_id={} ) def handle_action(self, action: Action) -> None: @@ -197,6 +205,7 @@ def _handle_command( # noqa: C901 front_right_offset=config.nozzle_map.front_right_nozzle_offset, ), default_nozzle_map=config.nozzle_map, + lld_settings=config.lld_settings ) self._state.flow_rates_by_id[private_result.pipette_id] = config.flow_rates self._state.nozzle_configuration_by_id[ @@ -617,6 +626,19 @@ def get_available_volume(self, pipette_id: str) -> Optional[float]: current_volume = self.get_aspirated_volume(pipette_id) return max(0.0, working_volume - current_volume) if current_volume else None + + + def get_pipette_lld_settings(self, pipette_id: str) -> Dict[str, float]: + return self.get_config(pipette_id).lld_settings + + def get_current_tip_lld_settings(self, pipette_id: str) -> float: + """Get the liquid level settings for the current pipette and tip""" + attached_tip = self.get_attached_tip(pipette_id) + lld_settings = self.get_lld_settings(pipette_id) + if None in {attached_tip, lld_settings, lld_settings[attached_tip], lld_settings[attached_tip]['minHeight']}: + return 0 + return lld_settings[attached_tip]['minHeight'] + def validate_tip_state(self, pipette_id: str, expected_has_tip: bool) -> None: """Validate that a pipette's tip state matches expectations.""" diff --git a/shared-data/pipette/schemas/2/pipetteGeometrySchema.json b/shared-data/pipette/schemas/2/pipetteGeometrySchema.json index 2ebaac051e0..a9a263b45f5 100644 --- a/shared-data/pipette/schemas/2/pipetteGeometrySchema.json +++ b/shared-data/pipette/schemas/2/pipetteGeometrySchema.json @@ -93,22 +93,22 @@ "t50": { "type": "object", "properties": { - "height": { "type": "number" }, - "volume": { "type": "number" } + "minHeight": { "type": "number" }, + "minVolume": { "type": "number" } } }, "t200": { "type": "object", "properties": { - "height": { "type": "number" }, - "volume": { "type": "number" } + "minHeight": { "type": "number" }, + "minVolume": { "type": "number" } } }, "t1000": { "type": "object", "properties": { - "height": { "type": "number" }, - "volume": { "type": "number" } + "minHeight": { "type": "number" }, + "minVolume": { "type": "number" } } } } diff --git a/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py b/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py index 95aa35f8b4a..d82b783a8c4 100644 --- a/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py +++ b/shared-data/python/opentrons_shared_data/pipette/pipette_definition.py @@ -354,7 +354,6 @@ class PipettePhysicalPropertiesDefinition(BaseModel): description="The distance the high throughput tip motors will travel to check tip status.", alias="tipPresenceCheckDistanceMM", ) - end_tip_action_retract_distance_mm: float = Field( default=0.0, description="The distance to move the head up after a tip drop or pickup.", @@ -436,6 +435,7 @@ class PipetteGeometryDefinition(BaseModel): ) ordered_columns: List[PipetteColumnDefinition] = Field(..., alias="orderedColumns") ordered_rows: List[PipetteRowDefinition] = Field(..., alias="orderedRows") + lld_settings: Dict[str, Dict[str, float]] = Field(..., alias="lldSettings") @validator("nozzle_map", pre=True) def check_nonempty_strings( From a11887f4e707f20ddbe0553883f3986d6eae3988 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Tue, 25 Jun 2024 13:32:59 -0400 Subject: [PATCH 08/12] lint. still need to make new test cases --- .../protocol_engine/execution/pipetting.py | 4 +- .../resources/pipette_data_provider.py | 5 +-- .../protocol_engine/state/pipettes.py | 37 +++++++++---------- .../commands/test_configure_for_volume.py | 1 + .../commands/test_load_pipette.py | 2 + .../execution/test_equipment_handler.py | 1 + .../resources/test_pipette_data_provider.py | 10 +++++ .../state/test_geometry_view.py | 1 + .../state/test_pipette_store.py | 2 + .../state/test_pipette_view.py | 7 ++++ .../protocol_engine/state/test_tip_state.py | 17 +++++++++ 11 files changed, 64 insertions(+), 23 deletions(-) diff --git a/api/src/opentrons/protocol_engine/execution/pipetting.py b/api/src/opentrons/protocol_engine/execution/pipetting.py index 88a6448267e..9a421c363e8 100644 --- a/api/src/opentrons/protocol_engine/execution/pipetting.py +++ b/api/src/opentrons/protocol_engine/execution/pipetting.py @@ -177,7 +177,9 @@ async def liquid_probe_in_place( ) well_def = self._state_view.labware.get_well_definition(labware_id, well_name) well_depth = well_def.depth - lld_min_height = self._state_view.pipettes.get_current_tip_lld_settings(pipette_id=pipette_id) + lld_min_height = self._state_view.pipettes.get_current_tip_lld_settings( + pipette_id=pipette_id + ) z_pos = await self._hardware_api.liquid_probe( mount=hw_pipette.mount, max_z_dist=well_depth - lld_min_height ) diff --git a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py index 47091165794..5f1372f85b2 100644 --- a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py +++ b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py @@ -241,7 +241,7 @@ def _get_virtual_pipette_static_config_by_model( # noqa: C901 front_right_corner_offset=Point( pip_front_right[0], pip_front_right[1], pip_front_right[2] ), - pipette_lld_settings=config.pipette_lld_settings + pipette_lld_settings=config.lld_settings, ) def get_virtual_pipette_static_config( @@ -284,6 +284,5 @@ def get_pipette_static_config(pipette_dict: PipetteDict) -> LoadedStaticPipetteD front_right_corner_offset=Point( front_right_offset[0], front_right_offset[1], front_right_offset[2] ), - pipette_lld_settings=pipette_dict["lld_settings"] - + pipette_lld_settings=pipette_dict["lld_settings"], ) diff --git a/api/src/opentrons/protocol_engine/state/pipettes.py b/api/src/opentrons/protocol_engine/state/pipettes.py index 77c05737c7f..9491d033c38 100644 --- a/api/src/opentrons/protocol_engine/state/pipettes.py +++ b/api/src/opentrons/protocol_engine/state/pipettes.py @@ -97,13 +97,6 @@ class PipetteBoundingBoxOffsets: back_left_corner: Point front_right_corner: Point - -@dataclass(frozen=True) -class PipetteLldSettings: - """Minimum liquid requirements for Liquid Level Detection to work properly.""" - t50: Optional[Dict[str, float]] - t200: Optional[Dict[str, float]] - t1000: Optional[Dict[str, float]] @dataclass(frozen=True) @@ -125,7 +118,7 @@ class StaticPipetteConfig: pipette_bounding_box_offsets: PipetteBoundingBoxOffsets bounding_nozzle_offsets: BoundingNozzlesOffsets default_nozzle_map: NozzleMap - lld_settings: PipetteLldSettings + lld_settings: Dict[str, Dict[str, float]] @dataclass @@ -159,7 +152,7 @@ def __init__(self) -> None: movement_speed_by_id={}, static_config_by_id={}, flow_rates_by_id={}, - nozzle_configuration_by_id={} + nozzle_configuration_by_id={}, ) def handle_action(self, action: Action) -> None: @@ -205,7 +198,7 @@ def _handle_command( # noqa: C901 front_right_offset=config.nozzle_map.front_right_nozzle_offset, ), default_nozzle_map=config.nozzle_map, - lld_settings=config.lld_settings + lld_settings=config.pipette_lld_settings, ) self._state.flow_rates_by_id[private_result.pipette_id] = config.flow_rates self._state.nozzle_configuration_by_id[ @@ -626,19 +619,25 @@ def get_available_volume(self, pipette_id: str) -> Optional[float]: current_volume = self.get_aspirated_volume(pipette_id) return max(0.0, working_volume - current_volume) if current_volume else None - - - def get_pipette_lld_settings(self, pipette_id: str) -> Dict[str, float]: + + def get_pipette_lld_settings(self, pipette_id: str) -> Dict[str, Dict[str, float]]: + """Get the liquid level settings for all possible tips for a single pipette.""" return self.get_config(pipette_id).lld_settings - + def get_current_tip_lld_settings(self, pipette_id: str) -> float: - """Get the liquid level settings for the current pipette and tip""" + """Get the liquid level settings for pipette and its current tip.""" attached_tip = self.get_attached_tip(pipette_id) - lld_settings = self.get_lld_settings(pipette_id) - if None in {attached_tip, lld_settings, lld_settings[attached_tip], lld_settings[attached_tip]['minHeight']}: + if attached_tip is None or attached_tip.volume is None: + return 0 + lld_settings = self.get_pipette_lld_settings(pipette_id) + tipVolume = str(attached_tip.volume) + if None in { + lld_settings, + lld_settings[tipVolume], + lld_settings[tipVolume]["minHeight"], + }: return 0 - return lld_settings[attached_tip]['minHeight'] - + return float(lld_settings[tipVolume]["minHeight"]) def validate_tip_state(self, pipette_id: str, expected_has_tip: bool) -> None: """Validate that a pipette's tip state matches expectations.""" diff --git a/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py b/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py index 0bd683fc1fe..7fd957f6fc6 100644 --- a/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py +++ b/api/tests/opentrons/protocol_engine/commands/test_configure_for_volume.py @@ -50,6 +50,7 @@ async def test_configure_for_volume_implementation( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI), back_left_corner_offset=Point(10, 20, 30), front_right_corner_offset=Point(40, 50, 60), + pipette_lld_settings={}, ) decoy.when( diff --git a/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py b/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py index cb1913da0bb..cda9c95db34 100644 --- a/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py +++ b/api/tests/opentrons/protocol_engine/commands/test_load_pipette.py @@ -46,6 +46,7 @@ async def test_load_pipette_implementation( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ) data = LoadPipetteParams( pipetteName=PipetteNameType.P300_SINGLE, @@ -106,6 +107,7 @@ async def test_load_pipette_implementation_96_channel( nozzle_map=get_default_nozzle_map(PipetteNameType.P1000_96), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ) decoy.when( diff --git a/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py b/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py index 1177894e977..ca785c69570 100644 --- a/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py +++ b/api/tests/opentrons/protocol_engine/execution/test_equipment_handler.py @@ -144,6 +144,7 @@ def loaded_static_pipette_data( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ) diff --git a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py index 37fc0635c3f..5c8c6961fd6 100644 --- a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py +++ b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py @@ -58,6 +58,7 @@ def test_get_virtual_pipette_static_config( nozzle_map=result.nozzle_map, back_left_corner_offset=Point(0, 0, 10.45), front_right_corner_offset=Point(0, 0, 10.45), + pipette_lld_settings={}, ) @@ -86,6 +87,7 @@ def test_configure_virtual_pipette_for_volume( nozzle_map=result1.nozzle_map, back_left_corner_offset=Point(-8.0, -22.0, -259.15), front_right_corner_offset=Point(-8.0, -22.0, -259.15), + pipette_lld_settings={}, ) subject_instance.configure_virtual_pipette_for_volume( "my-pipette", 1, result1.model @@ -111,6 +113,7 @@ def test_configure_virtual_pipette_for_volume( nozzle_map=result2.nozzle_map, back_left_corner_offset=Point(-8.0, -22.0, -259.15), front_right_corner_offset=Point(-8.0, -22.0, -259.15), + pipette_lld_settings={}, ) @@ -139,6 +142,7 @@ def test_load_virtual_pipette_by_model_string( nozzle_map=result.nozzle_map, back_left_corner_offset=Point(-16.0, 43.15, 35.52), front_right_corner_offset=Point(16.0, -43.15, 35.52), + pipette_lld_settings={}, ) @@ -225,6 +229,11 @@ def test_get_pipette_static_config( backLeftCorner=[10, 20, 30], frontRightCorner=[40, 50, 60], ), + "lld_settings": { + "t50": {"minHeight": 0.5, "minVolume": 0}, + "t200": {"minHeight": 0.5, "minVolume": 0}, + "t1000": {"minHeight": 0.5, "minVolume": 0}, + }, } result = subject.get_pipette_static_config(pipette_dict) @@ -253,4 +262,5 @@ def test_get_pipette_static_config( nozzle_map=dummy_nozzle_map, back_left_corner_offset=Point(10, 20, 30), front_right_corner_offset=Point(40, 50, 60), + pipette_lld_settings={}, ) diff --git a/api/tests/opentrons/protocol_engine/state/test_geometry_view.py b/api/tests/opentrons/protocol_engine/state/test_geometry_view.py index 82cf971595e..58a4a49940e 100644 --- a/api/tests/opentrons/protocol_engine/state/test_geometry_view.py +++ b/api/tests/opentrons/protocol_engine/state/test_geometry_view.py @@ -2078,6 +2078,7 @@ def test_get_next_drop_tip_location( back_left_corner=Point(x=10, y=20, z=30), front_right_corner=Point(x=40, y=50, z=60), ), + lld_settings={}, ) ) decoy.when(mock_pipette_view.get_mount("pip-123")).then_return(pipette_mount) diff --git a/api/tests/opentrons/protocol_engine/state/test_pipette_store.py b/api/tests/opentrons/protocol_engine/state/test_pipette_store.py index d1b4ac29f7c..19d950c471d 100644 --- a/api/tests/opentrons/protocol_engine/state/test_pipette_store.py +++ b/api/tests/opentrons/protocol_engine/state/test_pipette_store.py @@ -748,6 +748,7 @@ def test_add_pipette_config( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -774,6 +775,7 @@ def test_add_pipette_config( back_left_corner=Point(x=1, y=2, z=3), front_right_corner=Point(x=4, y=5, z=6), ), + lld_settings={}, ) assert subject.state.flow_rates_by_id["pipette-id"].default_aspirate == {"a": 1.0} assert subject.state.flow_rates_by_id["pipette-id"].default_dispense == {"b": 2.0} diff --git a/api/tests/opentrons/protocol_engine/state/test_pipette_view.py b/api/tests/opentrons/protocol_engine/state/test_pipette_view.py index 8c27360ebad..53d14533b91 100644 --- a/api/tests/opentrons/protocol_engine/state/test_pipette_view.py +++ b/api/tests/opentrons/protocol_engine/state/test_pipette_view.py @@ -276,6 +276,7 @@ def test_get_pipette_working_volume( bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), pipette_bounding_box_offsets=_SAMPLE_PIPETTE_BOUNDING_BOX_OFFSETS, + lld_settings={}, ) }, ) @@ -306,6 +307,7 @@ def test_get_pipette_working_volume_raises_if_tip_volume_is_none( bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), pipette_bounding_box_offsets=_SAMPLE_PIPETTE_BOUNDING_BOX_OFFSETS, + lld_settings={}, ) }, ) @@ -345,6 +347,7 @@ def test_get_pipette_available_volume( bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), pipette_bounding_box_offsets=_SAMPLE_PIPETTE_BOUNDING_BOX_OFFSETS, + lld_settings={}, ), "pipette-id-none": StaticPipetteConfig( min_volume=1, @@ -360,6 +363,7 @@ def test_get_pipette_available_volume( bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), pipette_bounding_box_offsets=_SAMPLE_PIPETTE_BOUNDING_BOX_OFFSETS, + lld_settings={}, ), }, ) @@ -471,6 +475,7 @@ def test_get_static_config( bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), pipette_bounding_box_offsets=_SAMPLE_PIPETTE_BOUNDING_BOX_OFFSETS, + lld_settings={}, ) subject = get_pipette_view( @@ -521,6 +526,7 @@ def test_get_nominal_tip_overlap( bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), pipette_bounding_box_offsets=_SAMPLE_PIPETTE_BOUNDING_BOX_OFFSETS, + lld_settings={}, ) subject = get_pipette_view(static_config_by_id={"pipette-id": config}) @@ -781,6 +787,7 @@ def test_get_nozzle_bounds_at_location( default_nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE), bounding_nozzle_offsets=_SAMPLE_NOZZLE_BOUNDS_OFFSETS, pipette_bounding_box_offsets=bounding_box_offsets, + lld_settings={}, ) }, ) diff --git a/api/tests/opentrons/protocol_engine/state/test_tip_state.py b/api/tests/opentrons/protocol_engine/state/test_tip_state.py index dfd693822c3..3572f81567f 100644 --- a/api/tests/opentrons/protocol_engine/state/test_tip_state.py +++ b/api/tests/opentrons/protocol_engine/state/test_tip_state.py @@ -148,6 +148,7 @@ def test_get_next_tip_returns_none( nozzle_map=get_default_nozzle_map(PipetteNameType.P1000_96), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -208,6 +209,7 @@ def test_get_next_tip_returns_first_tip( nozzle_map=get_default_nozzle_map(pipette_name_type), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -262,6 +264,7 @@ def test_get_next_tip_used_starting_tip( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -350,6 +353,7 @@ def test_get_next_tip_skips_picked_up_tip( nozzle_map=get_default_nozzle_map(pipette_name_type), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -404,6 +408,7 @@ def test_get_next_tip_with_starting_tip( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -478,6 +483,7 @@ def test_get_next_tip_with_starting_tip_8_channel( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI_GEN2), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -553,6 +559,7 @@ def test_get_next_tip_with_1_channel_followed_by_8_channel( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -584,6 +591,7 @@ def test_get_next_tip_with_1_channel_followed_by_8_channel( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI_GEN2), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -659,6 +667,7 @@ def test_get_next_tip_with_starting_tip_out_of_tips( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -734,6 +743,7 @@ def test_get_next_tip_with_column_and_starting_tip( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI_GEN2), back_left_corner_offset=Point(0, 0, 0), front_right_corner_offset=Point(0, 0, 0), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -786,6 +796,7 @@ def test_reset_tips( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) @@ -838,6 +849,7 @@ def test_handle_pipette_config_action( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -921,6 +933,7 @@ def test_drop_tip( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -1047,6 +1060,7 @@ def test_active_channels( nozzle_map=nozzle_map, back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -1112,6 +1126,7 @@ def test_next_tip_uses_active_channels( nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -1197,6 +1212,7 @@ def test_next_tip_automatic_tip_tracking_with_partial_configurations( nozzle_map=get_default_nozzle_map(PipetteNameType.P1000_96), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( @@ -1355,6 +1371,7 @@ def test_next_tip_automatic_tip_tracking_tiprack_limits( nozzle_map=get_default_nozzle_map(PipetteNameType.P1000_96), back_left_corner_offset=Point(x=1, y=2, z=3), front_right_corner_offset=Point(x=4, y=5, z=6), + pipette_lld_settings={}, ), ) subject.handle_action( From bbb820ba9bb3465968988578654edc623801e5ee Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Wed, 26 Jun 2024 10:08:12 -0400 Subject: [PATCH 09/12] trying to get generic tests to pass --- api/src/opentrons/hardware_control/dev_types.py | 2 +- .../instruments/ot2/pipette_handler.py | 2 ++ .../instruments/ot3/pipette_handler.py | 2 ++ shared-data/js/__tests__/pipettes.test.ts | 14 ++++++++++++++ .../2/geometry/eight_channel/p10/1_0.json | 3 ++- .../2/geometry/eight_channel/p10/1_3.json | 3 ++- .../2/geometry/eight_channel/p10/1_4.json | 3 ++- .../2/geometry/eight_channel/p10/1_5.json | 3 ++- .../2/geometry/eight_channel/p10/1_6.json | 3 ++- .../2/geometry/eight_channel/p1000/1_0.json | 3 ++- .../2/geometry/eight_channel/p20/2_0.json | 3 ++- .../2/geometry/eight_channel/p20/2_1.json | 3 ++- .../2/geometry/eight_channel/p300/1_0.json | 3 ++- .../2/geometry/eight_channel/p300/1_3.json | 3 ++- .../2/geometry/eight_channel/p300/1_4.json | 3 ++- .../2/geometry/eight_channel/p300/1_5.json | 3 ++- .../2/geometry/eight_channel/p300/2_0.json | 3 ++- .../2/geometry/eight_channel/p300/2_1.json | 3 ++- .../2/geometry/eight_channel/p50/1_0.json | 3 ++- .../2/geometry/eight_channel/p50/1_3.json | 3 ++- .../2/geometry/eight_channel/p50/1_4.json | 3 ++- .../2/geometry/eight_channel/p50/1_5.json | 3 ++- .../2/geometry/ninety_six_channel/p1000/1_0.json | 3 ++- .../2/geometry/single_channel/p10/1_0.json | 3 ++- .../2/geometry/single_channel/p10/1_3.json | 3 ++- .../2/geometry/single_channel/p10/1_4.json | 3 ++- .../2/geometry/single_channel/p10/1_5.json | 3 ++- .../2/geometry/single_channel/p1000/1_0.json | 3 ++- .../2/geometry/single_channel/p1000/1_3.json | 3 ++- .../2/geometry/single_channel/p1000/1_4.json | 3 ++- .../2/geometry/single_channel/p1000/1_5.json | 3 ++- .../2/geometry/single_channel/p1000/2_0.json | 3 ++- .../2/geometry/single_channel/p1000/2_1.json | 3 ++- .../2/geometry/single_channel/p1000/2_2.json | 3 ++- .../2/geometry/single_channel/p20/2_0.json | 3 ++- .../2/geometry/single_channel/p20/2_1.json | 3 ++- .../2/geometry/single_channel/p20/2_2.json | 3 ++- .../2/geometry/single_channel/p300/1_0.json | 3 ++- .../2/geometry/single_channel/p300/1_3.json | 3 ++- .../2/geometry/single_channel/p300/1_4.json | 3 ++- .../2/geometry/single_channel/p300/1_5.json | 3 ++- .../2/geometry/single_channel/p300/2_0.json | 3 ++- .../2/geometry/single_channel/p300/2_1.json | 3 ++- .../2/geometry/single_channel/p50/1_0.json | 3 ++- .../2/geometry/single_channel/p50/1_3.json | 3 ++- .../2/geometry/single_channel/p50/1_4.json | 3 ++- .../2/geometry/single_channel/p50/1_5.json | 3 ++- 47 files changed, 105 insertions(+), 44 deletions(-) diff --git a/api/src/opentrons/hardware_control/dev_types.py b/api/src/opentrons/hardware_control/dev_types.py index c851faf5a25..f8ee7c0dfac 100644 --- a/api/src/opentrons/hardware_control/dev_types.py +++ b/api/src/opentrons/hardware_control/dev_types.py @@ -98,7 +98,7 @@ class PipetteDict(InstrumentDict): supported_tips: Dict[PipetteTipType, SupportedTipsDefinition] pipette_bounding_box_offsets: PipetteBoundingBoxOffsetDefinition current_nozzle_map: NozzleMap - lld_settings: Dict[str, Dict[str, float]] + lld_settings: Optional[Dict[str, Dict[str, float]]] class PipetteStateDict(TypedDict): diff --git a/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py b/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py index 2f098bc9df0..cac038a1f4f 100644 --- a/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py +++ b/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py @@ -219,6 +219,7 @@ def get_attached_instrument(self, mount: MountType) -> PipetteDict: "default_dispense_flow_rates", "back_compat_names", "supported_tips", + "lld_settings" ] instr_dict = instr.as_dict() @@ -258,6 +259,7 @@ def get_attached_instrument(self, mount: MountType) -> PipetteDict: result[ "pipette_bounding_box_offsets" ] = instr.config.pipette_bounding_box_offsets + result["lld_settings"] = instr.config.lld_settings return cast(PipetteDict, result) @property diff --git a/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py b/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py index 8133eb081c9..8753d33beaa 100644 --- a/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py +++ b/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py @@ -235,6 +235,7 @@ def get_attached_instrument(self, mount: OT3Mount) -> PipetteDict: "default_dispense_flow_rates", "back_compat_names", "supported_tips", + "lld_settings" ] instr_dict = instr.as_dict() @@ -279,6 +280,7 @@ def get_attached_instrument(self, mount: OT3Mount) -> PipetteDict: result[ "pipette_bounding_box_offsets" ] = instr.config.pipette_bounding_box_offsets + result["lld_settings"] = instr.config.lld_settings return cast(PipetteDict, result) @property diff --git a/shared-data/js/__tests__/pipettes.test.ts b/shared-data/js/__tests__/pipettes.test.ts index 4b045ee48a4..a24b9e48d61 100644 --- a/shared-data/js/__tests__/pipettes.test.ts +++ b/shared-data/js/__tests__/pipettes.test.ts @@ -158,6 +158,20 @@ describe('pipette data accessors', () => { backLeftCorner: [-8, -22, -259.15], frontRightCorner: [-8, -22, -259.15], }, + lldSettings: { + t50: { + minHeight: 0.5, + minVolume: 0 + }, + t200: { + minHeight: 0.5, + minVolume: 0 + }, + t1000: { + minHeight: 0.5, + minVolume: 0 + } + } } as PipetteV2Specs expect(getPipetteSpecsV2('p1000_single_flex')).toStrictEqual( mockP1000Specs diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_0.json index 10b93dfcaaa..eca64bcc383 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_0.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_3.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_3.json index 10b93dfcaaa..eca64bcc383 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_3.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_4.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_4.json index 10b93dfcaaa..eca64bcc383 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_4.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_5.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_5.json index 10b93dfcaaa..eca64bcc383 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_5.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_6.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_6.json index 10b93dfcaaa..eca64bcc383 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_6.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p10/1_6.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/1_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/1_0.json index bc0e3637326..d598b8b289e 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p1000/1_0.json @@ -37,5 +37,6 @@ "F1": [-8.0, -61.0, -259.15], "G1": [-8.0, -70.0, -259.15], "H1": [-8.0, -79.0, -259.15] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_0.json index e416638c4dc..4a4b2e008ec 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_0.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 19.4], "G1": [0.0, -22.5, 19.4], "H1": [0.0, -31.5, 19.4] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_1.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_1.json index e416638c4dc..4a4b2e008ec 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_1.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p20/2_1.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 19.4], "G1": [0.0, -22.5, 19.4], "H1": [0.0, -31.5, 19.4] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_0.json index b888f3138b0..ef55316f83d 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_0.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_3.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_3.json index b888f3138b0..ef55316f83d 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_3.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_4.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_4.json index b888f3138b0..ef55316f83d 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_4.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_5.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_5.json index b888f3138b0..ef55316f83d 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/1_5.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_0.json index 713a907d1d1..c5997e31b6d 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_0.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 35.52], "G1": [0.0, -22.5, 35.52], "H1": [0.0, -31.5, 35.52] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_1.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_1.json index 713a907d1d1..c5997e31b6d 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_1.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p300/2_1.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 35.52], "G1": [0.0, -22.5, 35.52], "H1": [0.0, -31.5, 35.52] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_0.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_0.json index 691af1c0d2c..9d40fce93ea 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_0.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_3.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_3.json index 691af1c0d2c..9d40fce93ea 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_3.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_4.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_4.json index 691af1c0d2c..9d40fce93ea 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_4.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_5.json b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_5.json index 691af1c0d2c..9d40fce93ea 100644 --- a/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/eight_channel/p50/1_5.json @@ -37,5 +37,6 @@ "F1": [0.0, -13.5, 0.8], "G1": [0.0, -22.5, 0.8], "H1": [0.0, -31.5, 0.8] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/1_0.json b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/1_0.json index da209a72907..8b8ea364999 100644 --- a/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/ninety_six_channel/p1000/1_0.json @@ -291,5 +291,6 @@ "H10": [45.0, -88.5, -259.15], "H11": [54.0, -88.5, -259.15], "H12": [63.0, -88.5, -259.15] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_0.json index b85709722a0..cb47066c4b9 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 12.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_3.json b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_3.json index b85709722a0..cb47066c4b9 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_3.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 12.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_4.json b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_4.json index b85709722a0..cb47066c4b9 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_4.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 12.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_5.json b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_5.json index b85709722a0..cb47066c4b9 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p10/1_5.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 12.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_0.json index 0260e1b2c7a..a072c322a4b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 45.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_3.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_3.json index 0260e1b2c7a..a072c322a4b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_3.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 45.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_4.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_4.json index 0260e1b2c7a..a072c322a4b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_4.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 45.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_5.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_5.json index 0260e1b2c7a..a072c322a4b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/1_5.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 45.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_0.json index 1d8f41607bf..ccb2a50b97b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 50.14] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_1.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_1.json index 1d8f41607bf..ccb2a50b97b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_1.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_1.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 50.14] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_2.json b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_2.json index 1d8f41607bf..ccb2a50b97b 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_2.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p1000/2_2.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 50.14] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_0.json index 5f34bea0e3c..2bd492481db 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 10.45] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_1.json b/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_1.json index 5f34bea0e3c..2bd492481db 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_1.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_1.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 10.45] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_2.json b/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_2.json index 5f34bea0e3c..2bd492481db 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_2.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p20/2_2.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 10.45] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_0.json index c800c98b9bb..2baf8679f7c 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_3.json b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_3.json index c800c98b9bb..2baf8679f7c 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_3.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_4.json b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_4.json index c800c98b9bb..2baf8679f7c 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_4.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_5.json b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_5.json index c800c98b9bb..2baf8679f7c 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p300/1_5.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_0.json index 0068dc51390..3c8c92499a2 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 29.45] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_1.json b/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_1.json index 0068dc51390..3c8c92499a2 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_1.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p300/2_1.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 29.45] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_0.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_0.json index 85bc6700fd3..9aadf814228 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_0.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_0.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_3.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_3.json index 85bc6700fd3..9aadf814228 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_3.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_3.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_4.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_4.json index 85bc6700fd3..9aadf814228 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_4.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_4.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } diff --git a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_5.json b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_5.json index 85bc6700fd3..9aadf814228 100644 --- a/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_5.json +++ b/shared-data/pipette/definitions/2/geometry/single_channel/p50/1_5.json @@ -10,5 +10,6 @@ "orderedColumns": [{ "key": "1", "orderedNozzles": ["A1"] }], "nozzleMap": { "A1": [0.0, 0.0, 25.0] - } + }, + "lldSettings": {} } From fe834016ff53d761f2c1d0adc1d14664e2e7d662 Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Wed, 26 Jun 2024 10:32:56 -0400 Subject: [PATCH 10/12] lint --- .../instruments/ot2/pipette_handler.py | 2 +- .../instruments/ot3/pipette_handler.py | 2 +- .../resources/pipette_data_provider.py | 2 +- .../opentrons/protocol_engine/state/pipettes.py | 16 +++++++++------- shared-data/js/__tests__/pipettes.test.ts | 10 +++++----- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py b/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py index cac038a1f4f..b2927266ea2 100644 --- a/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py +++ b/api/src/opentrons/hardware_control/instruments/ot2/pipette_handler.py @@ -219,7 +219,7 @@ def get_attached_instrument(self, mount: MountType) -> PipetteDict: "default_dispense_flow_rates", "back_compat_names", "supported_tips", - "lld_settings" + "lld_settings", ] instr_dict = instr.as_dict() diff --git a/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py b/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py index 8753d33beaa..3d30477ae2e 100644 --- a/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py +++ b/api/src/opentrons/hardware_control/instruments/ot3/pipette_handler.py @@ -235,7 +235,7 @@ def get_attached_instrument(self, mount: OT3Mount) -> PipetteDict: "default_dispense_flow_rates", "back_compat_names", "supported_tips", - "lld_settings" + "lld_settings", ] instr_dict = instr.as_dict() diff --git a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py index 5f1372f85b2..5b311830fd2 100644 --- a/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py +++ b/api/src/opentrons/protocol_engine/resources/pipette_data_provider.py @@ -40,7 +40,7 @@ class LoadedStaticPipetteData: nozzle_map: NozzleMap back_left_corner_offset: Point front_right_corner_offset: Point - pipette_lld_settings: Dict[str, Dict[str, float]] + pipette_lld_settings: Optional[Dict[str, Dict[str, float]]] class VirtualPipetteDataProvider: diff --git a/api/src/opentrons/protocol_engine/state/pipettes.py b/api/src/opentrons/protocol_engine/state/pipettes.py index 9491d033c38..c69893d61b4 100644 --- a/api/src/opentrons/protocol_engine/state/pipettes.py +++ b/api/src/opentrons/protocol_engine/state/pipettes.py @@ -118,7 +118,7 @@ class StaticPipetteConfig: pipette_bounding_box_offsets: PipetteBoundingBoxOffsets bounding_nozzle_offsets: BoundingNozzlesOffsets default_nozzle_map: NozzleMap - lld_settings: Dict[str, Dict[str, float]] + lld_settings: Optional[Dict[str, Dict[str, float]]] @dataclass @@ -620,7 +620,9 @@ def get_available_volume(self, pipette_id: str) -> Optional[float]: return max(0.0, working_volume - current_volume) if current_volume else None - def get_pipette_lld_settings(self, pipette_id: str) -> Dict[str, Dict[str, float]]: + def get_pipette_lld_settings( + self, pipette_id: str + ) -> Optional[Dict[str, Dict[str, float]]]: """Get the liquid level settings for all possible tips for a single pipette.""" return self.get_config(pipette_id).lld_settings @@ -631,11 +633,11 @@ def get_current_tip_lld_settings(self, pipette_id: str) -> float: return 0 lld_settings = self.get_pipette_lld_settings(pipette_id) tipVolume = str(attached_tip.volume) - if None in { - lld_settings, - lld_settings[tipVolume], - lld_settings[tipVolume]["minHeight"], - }: + if ( + lld_settings is None + or lld_settings[tipVolume] is None + or lld_settings[tipVolume]["minHeight"] is None + ): return 0 return float(lld_settings[tipVolume]["minHeight"]) diff --git a/shared-data/js/__tests__/pipettes.test.ts b/shared-data/js/__tests__/pipettes.test.ts index a24b9e48d61..dd7a6baa8bb 100644 --- a/shared-data/js/__tests__/pipettes.test.ts +++ b/shared-data/js/__tests__/pipettes.test.ts @@ -161,17 +161,17 @@ describe('pipette data accessors', () => { lldSettings: { t50: { minHeight: 0.5, - minVolume: 0 + minVolume: 0, }, t200: { minHeight: 0.5, - minVolume: 0 + minVolume: 0, }, t1000: { minHeight: 0.5, - minVolume: 0 - } - } + minVolume: 0, + }, + }, } as PipetteV2Specs expect(getPipetteSpecsV2('p1000_single_flex')).toStrictEqual( mockP1000Specs From 716650d61a652b4222d49440187fa83aef060ecc Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Wed, 26 Jun 2024 11:15:40 -0400 Subject: [PATCH 11/12] passing generic tests now. i hope? --- .../resources/test_pipette_data_provider.py | 10 +++++++--- .../__snapshots__/fixtureGeneration.test.ts.snap | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py index 5c8c6961fd6..cf363c58eaa 100644 --- a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py +++ b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py @@ -87,7 +87,7 @@ def test_configure_virtual_pipette_for_volume( nozzle_map=result1.nozzle_map, back_left_corner_offset=Point(-8.0, -22.0, -259.15), front_right_corner_offset=Point(-8.0, -22.0, -259.15), - pipette_lld_settings={}, + pipette_lld_settings={"t50": {"minHeight": 0.5, "minVolume": 0.0}}, ) subject_instance.configure_virtual_pipette_for_volume( "my-pipette", 1, result1.model @@ -113,7 +113,7 @@ def test_configure_virtual_pipette_for_volume( nozzle_map=result2.nozzle_map, back_left_corner_offset=Point(-8.0, -22.0, -259.15), front_right_corner_offset=Point(-8.0, -22.0, -259.15), - pipette_lld_settings={}, + pipette_lld_settings={"t50": {"minHeight": 0.5, "minVolume": 0.0}}, ) @@ -262,5 +262,9 @@ def test_get_pipette_static_config( nozzle_map=dummy_nozzle_map, back_left_corner_offset=Point(10, 20, 30), front_right_corner_offset=Point(40, 50, 60), - pipette_lld_settings={}, + pipette_lld_settings={ + "t50": {"minHeight": 0.5, "minVolume": 0}, + "t200": {"minHeight": 0.5, "minVolume": 0}, + "t1000": {"minHeight": 0.5, "minVolume": 0} + }, ) diff --git a/step-generation/src/__tests__/__snapshots__/fixtureGeneration.test.ts.snap b/step-generation/src/__tests__/__snapshots__/fixtureGeneration.test.ts.snap index 1c1d9d85f27..f5da59bff1b 100644 --- a/step-generation/src/__tests__/__snapshots__/fixtureGeneration.test.ts.snap +++ b/step-generation/src/__tests__/__snapshots__/fixtureGeneration.test.ts.snap @@ -9659,6 +9659,7 @@ exports[`snapshot tests > makeContext 1`] = ` }, }, }, + "lldSettings": {}, "model": "p1000", "nozzleMap": { "A1": [ @@ -12286,6 +12287,7 @@ exports[`snapshot tests > makeContext 1`] = ` }, }, }, + "lldSettings": {}, "model": "p10", "nozzleMap": { "A1": [ @@ -13930,6 +13932,7 @@ exports[`snapshot tests > makeContext 1`] = ` }, }, }, + "lldSettings": {}, "model": "p10", "nozzleMap": { "A1": [ @@ -15299,6 +15302,7 @@ exports[`snapshot tests > makeContext 1`] = ` }, }, }, + "lldSettings": {}, "model": "p300", "nozzleMap": { "A1": [ @@ -17034,6 +17038,7 @@ exports[`snapshot tests > makeContext 1`] = ` }, }, }, + "lldSettings": {}, "model": "p300", "nozzleMap": { "A1": [ From 7696d85196d2e06eced6628c2013d2f6d4f37b3c Mon Sep 17 00:00:00 2001 From: aaron-kulkarni Date: Wed, 26 Jun 2024 11:19:53 -0400 Subject: [PATCH 12/12] final lint change. probably. --- .../protocol_engine/resources/test_pipette_data_provider.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py index cf363c58eaa..8b9c00a9eca 100644 --- a/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py +++ b/api/tests/opentrons/protocol_engine/resources/test_pipette_data_provider.py @@ -265,6 +265,6 @@ def test_get_pipette_static_config( pipette_lld_settings={ "t50": {"minHeight": 0.5, "minVolume": 0}, "t200": {"minHeight": 0.5, "minVolume": 0}, - "t1000": {"minHeight": 0.5, "minVolume": 0} - }, + "t1000": {"minHeight": 0.5, "minVolume": 0}, + }, )