From 6d04d599da761539651890383615175cf9b010ce Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 7 Dec 2023 09:06:51 -0800 Subject: [PATCH 01/30] test: add testing protocols for deck configuration --- ...or_DroppingLabwareInWasteChuteWithCover.py | 34 ++++ ...6_AnalysisError_FixtureUsesMiddleColumn.py | 30 +++ ...AnalysisError_TrashBinInStagingAreaCol3.py | 32 ++++ ...AnalysisError_TrashBinInStagingAreaCol4.py | 31 +++ ...6_AnalysisError_ModuleInStagingAreaCol3.py | 32 ++++ ...6_AnalysisError_ModuleInStagingAreaCol4.py | 31 +++ ...PER_HS_TM_TC_MB_2_16_DeckConfiguration1.py | 178 ++++++++++++++++++ ...C_MB_2_16_DeckConfiguration1_NoFixtures.py | 142 ++++++++++++++ ...TC_MB_2_16_DeckConfiguration1_NoModules.py | 151 +++++++++++++++ ..._DeckConfiguration1_NoModulesNoFixtures.py | 114 +++++++++++ 10 files changed, 775 insertions(+) create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py new file mode 100644 index 00000000000..d9026c90099 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py @@ -0,0 +1,34 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", + "apiLevel": "2.16", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +THERMOCYCLER_NAME = "thermocycler module gen2" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +TEMPERATURE_MODULE_NAME = "temperature module gen2" + +USING_GRIPPER = True + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + waste_chute = ctx.load_waste_chute(cover=True) + ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=True) + + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py new file mode 100644 index 00000000000..35357b7f09b --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py @@ -0,0 +1,30 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Fixture Uses Middle Column", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +THERMOCYCLER_NAME = "thermocycler module gen2" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +TEMPERATURE_MODULE_NAME = "temperature module gen2" + +USING_GRIPPER = True + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + trash_bin_1 = ctx.load_trash_bin("C2") + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py new file mode 100644 index 00000000000..958d93ce66e --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py @@ -0,0 +1,32 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", + "apiLevel": "2.16", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +THERMOCYCLER_NAME = "thermocycler module gen2" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +TEMPERATURE_MODULE_NAME = "temperature module gen2" + +USING_GRIPPER = True + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + tip_rack_96 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area + trash_bin_1 = ctx.load_trash_bin("C3") + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py new file mode 100644 index 00000000000..0b42c2cb499 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py @@ -0,0 +1,31 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", + "apiLevel": "2.16", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +THERMOCYCLER_NAME = "thermocycler module gen2" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +TEMPERATURE_MODULE_NAME = "temperature module gen2" + +USING_GRIPPER = True + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + trash_bin_1 = ctx.load_trash_bin("C4") + diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py new file mode 100644 index 00000000000..a51c132434e --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py @@ -0,0 +1,32 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", + "apiLevel": "2.16", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +THERMOCYCLER_NAME = "thermocycler module gen2" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +TEMPERATURE_MODULE_NAME = "temperature module gen2" + +USING_GRIPPER = True + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, "B4") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py new file mode 100644 index 00000000000..9854d1321a6 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py @@ -0,0 +1,31 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", + "apiLevel": "2.16", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +THERMOCYCLER_NAME = "thermocycler module gen2" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +TEMPERATURE_MODULE_NAME = "temperature module gen2" + +USING_GRIPPER = True + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B4") + diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py new file mode 100644 index 00000000000..e699b8ba61e --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py @@ -0,0 +1,178 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Deck Configuration 1", + "author": "Derek Maggio ", + +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +STARTING_VOL = 100 +TEMPERATURE_MODULE_NAME = "temperature module gen2" +THERMOCYCLER_NAME = "thermocycler module gen2" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +TRANSFER_VOL = 10 +USING_GRIPPER = True + +TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_2 = "D2" + +def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: + return tiprack['A1'] + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + trash_bin_1 = ctx.load_trash_bin("C1") + trash_bin_2 = ctx.load_trash_bin("D1") + waste_chute = ctx.load_waste_chute() + + ############### + ### MODULES ### + ############### + thermocycler = ctx.load_module(THERMOCYCLER_NAME) # A1 & B1 + magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "A2") + # heater_shaker = ctx.load_module(HEATER_SHAKER_NAME, "A3") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + + ####################### + ### MODULE ADAPTERS ### + ####################### + + temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") + # heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") + + ############### + ### LABWARE ### + ############### + + pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + + tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) + tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) + tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + tip_rack_96_staging_area_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area + tip_rack_96_staging_area_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area + + tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_staging_area_1, tip_rack_96_staging_area_2, tip_rack_96_3, tip_rack_96_4] + + ########################## + ### PIPETTE DEFINITION ### + ########################## + + pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + + ######################## + ### LOAD SOME LIQUID ### + ######################## + + water = ctx.define_liquid( + name="water", + description="High Quality H₂O", + display_color="#42AB2D" + ) + + acetone = ctx.define_liquid( + name="acetone", + description="C₃H₆O", + display_color="#38588a" + ) + + [ + well.load_liquid( + liquid=water if i % 2 == 0 else acetone, + volume=STARTING_VOL + ) + for i, column in enumerate(pcr_plate_1.columns()) + for well in column + ] + + ######################## + ### MOVE SOME LIQUID ### + ######################## + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(trash_bin_1) + + ################################## + ### THROW AWAY EMPTY TIP RACKS ### + ################################## + + ctx.move_labware(tip_rack_96_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(tip_rack_96_2, waste_chute, use_gripper=USING_GRIPPER) + + ################################### + ### MOVE STAGING AREA TIP RACKS ### + ################################### + + ctx.move_labware(tip_rack_96_staging_area_1, TIP_RACK_LOCATION_1, use_gripper=USING_GRIPPER) + ctx.move_labware(tip_rack_96_staging_area_2, TIP_RACK_LOCATION_2, use_gripper=USING_GRIPPER) + + ############################# + ### MOVE SOME MORE LIQUID ### + ############################# + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(trash_bin_2) + + ################################## + ### THROW AWAY EMPTY TIP RACKS ### + ################################## + + ctx.move_labware(tip_rack_96_staging_area_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(tip_rack_96_staging_area_2, waste_chute, use_gripper=USING_GRIPPER) + + ############################### + ### MOVE OFF DECK TIP RACKS ### + ############################### + + ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + ############################ + ### PUT STUFF ON MODULES ### + ############################ + + thermocycler.open_lid() + ctx.move_labware(pcr_plate_2, thermocycler, use_gripper=USING_GRIPPER) + ctx.move_labware(pcr_plate_2, magnetic_block, use_gripper=USING_GRIPPER) + # ctx.move_labware(pcr_plate_2, heater_shaker_adapter, use_gripper=USING_GRIPPER) + ctx.move_labware(pcr_plate_2, temperature_module_adapter, use_gripper=USING_GRIPPER) + + ########################################## + ### MAKE THIS PROTOCOL TOTALLY USELESS ### + ########################################## + + ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) \ No newline at end of file diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py new file mode 100644 index 00000000000..1c60b566713 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py @@ -0,0 +1,142 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Deck Configuration 1 - No Fixtures", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +STARTING_VOL = 100 +TEMPERATURE_MODULE_NAME = "temperature module gen2" +THERMOCYCLER_NAME = "thermocycler module gen2" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +TRANSFER_VOL = 10 +USING_GRIPPER = True +TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_2 = "D2" + +def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: + return tiprack['A1'] + +def run(ctx: protocol_api.ProtocolContext) -> None: + + + ############### + ### MODULES ### + ############### + thermocycler = ctx.load_module(THERMOCYCLER_NAME) # A1 & B1 + magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "A2") + # heater_shaker = ctx.load_module(HEATER_SHAKER_NAME, "A3") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + + ####################### + ### MODULE ADAPTERS ### + ####################### + + temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") + # heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") + + + ############### + ### LABWARE ### + ############### + + pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + + tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) + tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) + tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_3, tip_rack_96_4] + + ########################## + ### PIPETTE DEFINITION ### + ########################## + + pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + + ######################## + ### LOAD SOME LIQUID ### + ######################## + + water = ctx.define_liquid( + name="water", + description="High Quality H₂O", + display_color="#42AB2D" + ) + + acetone = ctx.define_liquid( + name="acetone", + description="C₃H₆O", + display_color="#38588a" + ) + + [ + well.load_liquid( + liquid=water if i % 2 == 0 else acetone, + volume=STARTING_VOL + ) + for i, column in enumerate(pcr_plate_1.columns()) + for well in column + ] + + ######################## + ### MOVE SOME LIQUID ### + ######################## + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + ################################## + ### THROW AWAY EMPTY TIP RACKS ### + ################################## + + ctx.move_labware(tip_rack_96_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(tip_rack_96_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + + ############################### + ### MOVE OFF DECK TIP RACKS ### + ############################### + + ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + + ############################ + ### PUT STUFF ON MODULES ### + ############################ + + thermocycler.open_lid() + ctx.move_labware(pcr_plate_2, thermocycler, use_gripper=USING_GRIPPER) + ctx.move_labware(pcr_plate_2, magnetic_block, use_gripper=USING_GRIPPER) + # ctx.move_labware(pcr_plate_2, heater_shaker_adapter, use_gripper=USING_GRIPPER) + ctx.move_labware(pcr_plate_2, temperature_module_adapter, use_gripper=USING_GRIPPER) + + ########################################## + ### MAKE THIS PROTOCOL TOTALLY USELESS ### + ########################################## + + ctx.move_labware(pcr_plate_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) \ No newline at end of file diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py new file mode 100644 index 00000000000..971f71d692e --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py @@ -0,0 +1,151 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Deck Configuration 1 - No Modules", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +STARTING_VOL = 100 +TEMPERATURE_MODULE_NAME = "temperature module gen2" +THERMOCYCLER_NAME = "thermocycler module gen2" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +TRANSFER_VOL = 10 +USING_GRIPPER = True +TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_2 = "D2" + +def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: + return tiprack['A1'] + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + trash_bin_1 = ctx.load_trash_bin("C1") + trash_bin_2 = ctx.load_trash_bin("D1") + waste_chute = ctx.load_waste_chute() + + ############### + ### LABWARE ### + ############### + + pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + + tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) + tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) + tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + tip_rack_96_staging_area_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area + tip_rack_96_staging_area_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area + + tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_staging_area_1, tip_rack_96_staging_area_2, tip_rack_96_3, tip_rack_96_4] + + ########################## + ### PIPETTE DEFINITION ### + ########################## + + pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + + ######################## + ### LOAD SOME LIQUID ### + ######################## + + water = ctx.define_liquid( + name="water", + description="High Quality H₂O", + display_color="#42AB2D" + ) + + acetone = ctx.define_liquid( + name="acetone", + description="C₃H₆O", + display_color="#38588a" + ) + + [ + well.load_liquid( + liquid=water if i % 2 == 0 else acetone, + volume=STARTING_VOL + ) + for i, column in enumerate(pcr_plate_1.columns()) + for well in column + ] + + ######################## + ### MOVE SOME LIQUID ### + ######################## + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(trash_bin_1) + + ################################## + ### THROW AWAY EMPTY TIP RACKS ### + ################################## + + ctx.move_labware(tip_rack_96_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(tip_rack_96_2, waste_chute, use_gripper=USING_GRIPPER) + + ################################### + ### MOVE STAGING AREA TIP RACKS ### + ################################### + + ctx.move_labware(tip_rack_96_staging_area_1, TIP_RACK_LOCATION_1, use_gripper=USING_GRIPPER) + ctx.move_labware(tip_rack_96_staging_area_2, TIP_RACK_LOCATION_2, use_gripper=USING_GRIPPER) + + ############################# + ### MOVE SOME MORE LIQUID ### + ############################# + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(trash_bin_2) + + ################################## + ### THROW AWAY EMPTY TIP RACKS ### + ################################## + + ctx.move_labware(tip_rack_96_staging_area_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(tip_rack_96_staging_area_2, waste_chute, use_gripper=USING_GRIPPER) + + ############################### + ### MOVE OFF DECK TIP RACKS ### + ############################### + + ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + + ########################################## + ### MAKE THIS PROTOCOL TOTALLY USELESS ### + ########################################## + + ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) \ No newline at end of file diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py new file mode 100644 index 00000000000..2f431bc29b0 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py @@ -0,0 +1,114 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Deck Configuration 1 - No Modules or Fixtures", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +STARTING_VOL = 100 +TEMPERATURE_MODULE_NAME = "temperature module gen2" +THERMOCYCLER_NAME = "thermocycler module gen2" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +TRANSFER_VOL = 10 +USING_GRIPPER = True +TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_2 = "D2" + +def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: + return tiprack['A1'] + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ############### + ### LABWARE ### + ############### + + pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + + tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) + tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) + tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_3, tip_rack_96_4] + + ########################## + ### PIPETTE DEFINITION ### + ########################## + + pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + + ######################## + ### LOAD SOME LIQUID ### + ######################## + + water = ctx.define_liquid( + name="water", + description="High Quality H₂O", + display_color="#42AB2D" + ) + + acetone = ctx.define_liquid( + name="acetone", + description="C₃H₆O", + display_color="#38588a" + ) + + [ + well.load_liquid( + liquid=water if i % 2 == 0 else acetone, + volume=STARTING_VOL + ) + for i, column in enumerate(pcr_plate_1.columns()) + for well in column + ] + + ######################## + ### MOVE SOME LIQUID ### + ######################## + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + ################################## + ### THROW AWAY EMPTY TIP RACKS ### + ################################## + + ctx.move_labware(tip_rack_96_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(tip_rack_96_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + + ############################### + ### MOVE OFF DECK TIP RACKS ### + ############################### + + ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.return_tip() + + ########################################## + ### MAKE THIS PROTOCOL TOTALLY USELESS ### + ########################################## + + ctx.move_labware(pcr_plate_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) \ No newline at end of file From fe568d83c390eb05cdb2f8cf7d458e2cfc16bc81 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 7 Dec 2023 09:08:12 -0800 Subject: [PATCH 02/30] chore: formatting --- ...or_DroppingLabwareInWasteChuteWithCover.py | 4 +- ...6_AnalysisError_FixtureUsesMiddleColumn.py | 3 +- ...AnalysisError_TrashBinInStagingAreaCol3.py | 3 +- ...AnalysisError_TrashBinInStagingAreaCol4.py | 3 +- ...6_AnalysisError_ModuleInStagingAreaCol3.py | 3 +- ...6_AnalysisError_ModuleInStagingAreaCol4.py | 3 +- ...PER_HS_TM_TC_MB_2_16_DeckConfiguration1.py | 37 +++++++++---------- ...C_MB_2_16_DeckConfiguration1_NoFixtures.py | 28 ++++---------- ...TC_MB_2_16_DeckConfiguration1_NoModules.py | 36 +++++++++--------- ..._DeckConfiguration1_NoModulesNoFixtures.py | 25 ++++--------- 10 files changed, 56 insertions(+), 89 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py index d9026c90099..0cea6c0a8f4 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py @@ -26,9 +26,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - + pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") waste_chute = ctx.load_waste_chute(cover=True) ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=True) - - diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py index 35357b7f09b..9af6ea16903 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py @@ -25,6 +25,5 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - - trash_bin_1 = ctx.load_trash_bin("C2") + trash_bin_1 = ctx.load_trash_bin("C2") diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py index 958d93ce66e..ec4a0ea65d0 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py @@ -26,7 +26,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - + tip_rack_96 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area trash_bin_1 = ctx.load_trash_bin("C3") - diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py index 0b42c2cb499..d861b977196 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py @@ -26,6 +26,5 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - - trash_bin_1 = ctx.load_trash_bin("C4") + trash_bin_1 = ctx.load_trash_bin("C4") diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py index a51c132434e..1c09f404047 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py @@ -26,7 +26,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - + tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, "B4") temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") - diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py index 9854d1321a6..727b5343004 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py @@ -26,6 +26,5 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - - temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B4") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B4") diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py index e699b8ba61e..cfacfb086de 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py @@ -3,7 +3,6 @@ metadata = { "protocolName": "QA Protocol - Deck Configuration 1", "author": "Derek Maggio ", - } requirements = { @@ -24,15 +23,17 @@ TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" + def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: - return tiprack['A1'] + return tiprack["A1"] + def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - + trash_bin_1 = ctx.load_trash_bin("C1") trash_bin_2 = ctx.load_trash_bin("D1") waste_chute = ctx.load_waste_chute() @@ -67,35 +68,31 @@ def run(ctx: protocol_api.ProtocolContext) -> None: tip_rack_96_staging_area_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area tip_rack_96_staging_area_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area - tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_staging_area_1, tip_rack_96_staging_area_2, tip_rack_96_3, tip_rack_96_4] + tip_racks = [ + tip_rack_96_1, + tip_rack_96_2, + tip_rack_96_staging_area_1, + tip_rack_96_staging_area_2, + tip_rack_96_3, + tip_rack_96_4, + ] ########################## ### PIPETTE DEFINITION ### ########################## - pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) ######################## ### LOAD SOME LIQUID ### ######################## - water = ctx.define_liquid( - name="water", - description="High Quality H₂O", - display_color="#42AB2D" - ) + water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") - acetone = ctx.define_liquid( - name="acetone", - description="C₃H₆O", - display_color="#38588a" - ) + acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") [ - well.load_liquid( - liquid=water if i % 2 == 0 else acetone, - volume=STARTING_VOL - ) + well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) for i, column in enumerate(pcr_plate_1.columns()) for well in column ] @@ -175,4 +172,4 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ########################################## ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) \ No newline at end of file + ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py index 1c60b566713..23be4f1fadf 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py @@ -22,11 +22,12 @@ TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" + def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: - return tiprack['A1'] + return tiprack["A1"] -def run(ctx: protocol_api.ProtocolContext) -> None: +def run(ctx: protocol_api.ProtocolContext) -> None: ############### ### MODULES ### @@ -43,7 +44,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") # heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") - ############### ### LABWARE ### ############### @@ -62,29 +62,18 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### PIPETTE DEFINITION ### ########################## - pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) ######################## ### LOAD SOME LIQUID ### ######################## - water = ctx.define_liquid( - name="water", - description="High Quality H₂O", - display_color="#42AB2D" - ) + water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") - acetone = ctx.define_liquid( - name="acetone", - description="C₃H₆O", - display_color="#38588a" - ) + acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") [ - well.load_liquid( - liquid=water if i % 2 == 0 else acetone, - volume=STARTING_VOL - ) + well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) for i, column in enumerate(pcr_plate_1.columns()) for well in column ] @@ -123,7 +112,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") pipette_96_channel.return_tip() - ############################ ### PUT STUFF ON MODULES ### ############################ @@ -139,4 +127,4 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ########################################## ctx.move_labware(pcr_plate_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) - ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) \ No newline at end of file + ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py index 971f71d692e..ca5ae3a5b24 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py @@ -22,15 +22,17 @@ TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" + def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: - return tiprack['A1'] + return tiprack["A1"] + def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - + trash_bin_1 = ctx.load_trash_bin("C1") trash_bin_2 = ctx.load_trash_bin("D1") waste_chute = ctx.load_waste_chute() @@ -50,35 +52,31 @@ def run(ctx: protocol_api.ProtocolContext) -> None: tip_rack_96_staging_area_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area tip_rack_96_staging_area_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area - tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_staging_area_1, tip_rack_96_staging_area_2, tip_rack_96_3, tip_rack_96_4] + tip_racks = [ + tip_rack_96_1, + tip_rack_96_2, + tip_rack_96_staging_area_1, + tip_rack_96_staging_area_2, + tip_rack_96_3, + tip_rack_96_4, + ] ########################## ### PIPETTE DEFINITION ### ########################## - pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) ######################## ### LOAD SOME LIQUID ### ######################## - water = ctx.define_liquid( - name="water", - description="High Quality H₂O", - display_color="#42AB2D" - ) + water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") - acetone = ctx.define_liquid( - name="acetone", - description="C₃H₆O", - display_color="#38588a" - ) + acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") [ - well.load_liquid( - liquid=water if i % 2 == 0 else acetone, - volume=STARTING_VOL - ) + well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) for i, column in enumerate(pcr_plate_1.columns()) for well in column ] @@ -148,4 +146,4 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ########################################## ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) \ No newline at end of file + ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py index 2f431bc29b0..a9412317539 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py @@ -22,8 +22,10 @@ TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" + def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: - return tiprack['A1'] + return tiprack["A1"] + def run(ctx: protocol_api.ProtocolContext) -> None: @@ -45,29 +47,18 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### PIPETTE DEFINITION ### ########################## - pipette_96_channel = ctx.load_instrument('flex_96channel_1000', mount="left", tip_racks=tip_racks) + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) ######################## ### LOAD SOME LIQUID ### ######################## - water = ctx.define_liquid( - name="water", - description="High Quality H₂O", - display_color="#42AB2D" - ) + water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") - acetone = ctx.define_liquid( - name="acetone", - description="C₃H₆O", - display_color="#38588a" - ) + acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") [ - well.load_liquid( - liquid=water if i % 2 == 0 else acetone, - volume=STARTING_VOL - ) + well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) for i, column in enumerate(pcr_plate_1.columns()) for well in column ] @@ -111,4 +102,4 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ########################################## ctx.move_labware(pcr_plate_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) - ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) \ No newline at end of file + ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) From e2ef8ac4ce799cdf44fa21da372b824439f63218 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Fri, 8 Dec 2023 06:39:05 -0800 Subject: [PATCH 03/30] chore: fix tip rack adapters and add better var names --- ...or_DroppingLabwareInWasteChuteWithCover.py | 4 +- ...6_AnalysisError_ModuleInStagingAreaCol3.py | 2 +- ...PER_HS_TM_TC_MB_2_16_DeckConfiguration1.py | 95 ++++++++++--------- ...C_MB_2_16_DeckConfiguration1_NoFixtures.py | 61 ++++++------ ...TC_MB_2_16_DeckConfiguration1_NoModules.py | 77 +++++++-------- ..._DeckConfiguration1_NoModulesNoFixtures.py | 53 ++++++----- 6 files changed, 154 insertions(+), 138 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py index 0cea6c0a8f4..1c66a7665b1 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py @@ -27,6 +27,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### FIXTURES ### ################ - pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") waste_chute = ctx.load_waste_chute(cover=True) - ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=True) + ctx.move_labware(src_pcr_plate, waste_chute, use_gripper=True) diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py index 1c09f404047..f5e61c86343 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py @@ -27,5 +27,5 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### FIXTURES ### ################ - tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, "B4") + on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "B4") temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py index cfacfb086de..f53a32fdbb3 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py @@ -20,7 +20,7 @@ TRANSFER_VOL = 10 USING_GRIPPER = True -TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" @@ -57,24 +57,29 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### LABWARE ### ############### - pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) - tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) - tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_1 = on_deck_tip_rack_1.parent - tip_rack_96_staging_area_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area - tip_rack_96_staging_area_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area + on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_2 = on_deck_tip_rack_2.parent + + off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") + staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") tip_racks = [ - tip_rack_96_1, - tip_rack_96_2, - tip_rack_96_staging_area_1, - tip_rack_96_staging_area_2, - tip_rack_96_3, - tip_rack_96_4, + on_deck_tip_rack_1, + on_deck_tip_rack_2, + staging_area_tip_rack_1, + staging_area_tip_rack_2, + off_deck_tip_rack_1, + off_deck_tip_rack_2, ] ########################## @@ -93,7 +98,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: [ well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(pcr_plate_1.columns()) + for i, column in enumerate(src_pcr_plate.columns()) for well in column ] @@ -101,60 +106,62 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### MOVE SOME LIQUID ### ######################## - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") - pipette_96_channel.drop_tip(waste_chute) + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.drop_tip(waste_chute) + - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") - pipette_96_channel.drop_tip(trash_bin_1) + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.drop_tip(trash_bin_1) + ################################## ### THROW AWAY EMPTY TIP RACKS ### ################################## - ctx.move_labware(tip_rack_96_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(tip_rack_96_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) ################################### ### MOVE STAGING AREA TIP RACKS ### ################################### - ctx.move_labware(tip_rack_96_staging_area_1, TIP_RACK_LOCATION_1, use_gripper=USING_GRIPPER) - ctx.move_labware(tip_rack_96_staging_area_2, TIP_RACK_LOCATION_2, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_1, tip_rack_adapter_1, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_2, tip_rack_adapter_2, use_gripper=USING_GRIPPER) ############################# ### MOVE SOME MORE LIQUID ### ############################# - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(trash_bin_2) ################################## ### THROW AWAY EMPTY TIP RACKS ### ################################## - ctx.move_labware(tip_rack_96_staging_area_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(tip_rack_96_staging_area_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) ############################### ### MOVE OFF DECK TIP RACKS ### ############################### - ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) - ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_1, tip_rack_adapter_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) ############################ @@ -162,14 +169,14 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ############################ thermocycler.open_lid() - ctx.move_labware(pcr_plate_2, thermocycler, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, magnetic_block, use_gripper=USING_GRIPPER) - # ctx.move_labware(pcr_plate_2, heater_shaker_adapter, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, temperature_module_adapter, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, thermocycler, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, magnetic_block, use_gripper=USING_GRIPPER) + # ctx.move_labware(dest_pcr_plate, heater_shaker_adapter, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, temperature_module_adapter, use_gripper=USING_GRIPPER) ########################################## ### MAKE THIS PROTOCOL TOTALLY USELESS ### ########################################## - ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(src_pcr_plate, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, waste_chute, use_gripper=USING_GRIPPER) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py index 23be4f1fadf..b83d7b7aa7e 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py @@ -48,15 +48,18 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### LABWARE ### ############### - pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) - tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) - tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_1 = on_deck_tip_rack_1.parent + + on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_2 = on_deck_tip_rack_2.parent + off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_3, tip_rack_96_4] + tip_racks = [on_deck_tip_rack_1, on_deck_tip_rack_2, off_deck_tip_rack_1, off_deck_tip_rack_2] ########################## ### PIPETTE DEFINITION ### @@ -74,7 +77,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: [ well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(pcr_plate_1.columns()) + for i, column in enumerate(src_pcr_plate.columns()) for well in column ] @@ -82,34 +85,34 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### MOVE SOME LIQUID ### ######################## - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() - ################################## - ### THROW AWAY EMPTY TIP RACKS ### - ################################## + ##################################### + ### MOVE EMPTY TIP RACKS OFF DECK ### + ##################################### - ctx.move_labware(tip_rack_96_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) - ctx.move_labware(tip_rack_96_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) ############################### ### MOVE OFF DECK TIP RACKS ### ############################### - ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) - ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_1, tip_rack_adapter_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() ############################ @@ -117,14 +120,14 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ############################ thermocycler.open_lid() - ctx.move_labware(pcr_plate_2, thermocycler, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, magnetic_block, use_gripper=USING_GRIPPER) - # ctx.move_labware(pcr_plate_2, heater_shaker_adapter, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, temperature_module_adapter, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, thermocycler, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, magnetic_block, use_gripper=USING_GRIPPER) + # ctx.move_labware(dest_pcr_plate, heater_shaker_adapter, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, temperature_module_adapter, use_gripper=USING_GRIPPER) ########################################## ### MAKE THIS PROTOCOL TOTALLY USELESS ### ########################################## - ctx.move_labware(pcr_plate_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) - ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(src_pcr_plate, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py index ca5ae3a5b24..abb6cbfe0fb 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py @@ -41,24 +41,27 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### LABWARE ### ############### - pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) - tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) - tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_1 = on_deck_tip_rack_1.parent - tip_rack_96_staging_area_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area - tip_rack_96_staging_area_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area + on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_2 = on_deck_tip_rack_2.parent + off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area + staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") # Staging Area tip_racks = [ - tip_rack_96_1, - tip_rack_96_2, - tip_rack_96_staging_area_1, - tip_rack_96_staging_area_2, - tip_rack_96_3, - tip_rack_96_4, + on_deck_tip_rack_1, + on_deck_tip_rack_2, + staging_area_tip_rack_1, + staging_area_tip_rack_2, + off_deck_tip_rack_1, + off_deck_tip_rack_2, ] ########################## @@ -77,7 +80,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: [ well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(pcr_plate_1.columns()) + for i, column in enumerate(src_pcr_plate.columns()) for well in column ] @@ -85,65 +88,65 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### MOVE SOME LIQUID ### ######################## - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(trash_bin_1) ################################## ### THROW AWAY EMPTY TIP RACKS ### ################################## - ctx.move_labware(tip_rack_96_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(tip_rack_96_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) ################################### ### MOVE STAGING AREA TIP RACKS ### ################################### - ctx.move_labware(tip_rack_96_staging_area_1, TIP_RACK_LOCATION_1, use_gripper=USING_GRIPPER) - ctx.move_labware(tip_rack_96_staging_area_2, TIP_RACK_LOCATION_2, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_1, tip_rack_adapter_1, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_2, tip_rack_adapter_2, use_gripper=USING_GRIPPER) ############################# ### MOVE SOME MORE LIQUID ### ############################# - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_staging_area_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(trash_bin_2) ################################## ### THROW AWAY EMPTY TIP RACKS ### ################################## - ctx.move_labware(tip_rack_96_staging_area_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(tip_rack_96_staging_area_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) ############################### ### MOVE OFF DECK TIP RACKS ### ############################### - ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) - ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_1, tip_rack_adapter_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.drop_tip(waste_chute) ########################################## ### MAKE THIS PROTOCOL TOTALLY USELESS ### ########################################## - ctx.move_labware(pcr_plate_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(pcr_plate_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(src_pcr_plate, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, waste_chute, use_gripper=USING_GRIPPER) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py index a9412317539..17fda1aeb0d 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py @@ -33,15 +33,18 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### LABWARE ### ############### - pcr_plate_1 = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - pcr_plate_2 = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - tip_rack_96_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1) - tip_rack_96_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2) - tip_rack_96_3 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - tip_rack_96_4 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_1 = on_deck_tip_rack_1.parent - tip_racks = [tip_rack_96_1, tip_rack_96_2, tip_rack_96_3, tip_rack_96_4] + on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_2 = on_deck_tip_rack_2.parent + off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + tip_racks = [on_deck_tip_rack_1, on_deck_tip_rack_2, off_deck_tip_rack_1, off_deck_tip_rack_2] ########################## ### PIPETTE DEFINITION ### @@ -59,7 +62,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: [ well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(pcr_plate_1.columns()) + for i, column in enumerate(src_pcr_plate.columns()) for well in column ] @@ -67,39 +70,39 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### MOVE SOME LIQUID ### ######################## - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() - ################################## - ### THROW AWAY EMPTY TIP RACKS ### - ################################## + ##################################### + ### MOVE EMPTY TIP RACKS OFF DECK ### + ##################################### - ctx.move_labware(tip_rack_96_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) - ctx.move_labware(tip_rack_96_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) ############################### ### MOVE OFF DECK TIP RACKS ### ############################### - ctx.move_labware(tip_rack_96_3, TIP_RACK_LOCATION_1, use_gripper=not USING_GRIPPER) - ctx.move_labware(tip_rack_96_4, TIP_RACK_LOCATION_2, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_1, tip_rack_adapter_1, use_gripper=not USING_GRIPPER) + ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_3)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() - pipette_96_channel.pick_up_tip(default_well(tip_rack_96_4)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(pcr_plate_1), default_well(pcr_plate_2), new_tip="never") + pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) + pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") pipette_96_channel.return_tip() ########################################## ### MAKE THIS PROTOCOL TOTALLY USELESS ### ########################################## - ctx.move_labware(pcr_plate_1, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) - ctx.move_labware(pcr_plate_2, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(src_pcr_plate, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) + ctx.move_labware(dest_pcr_plate, protocol_api.OFF_DECK, use_gripper=not USING_GRIPPER) From a4cf6e81506a108480590cce0dcbe3efe3750e92 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Fri, 8 Dec 2023 06:39:17 -0800 Subject: [PATCH 04/30] test: smoke init --- ...P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py new file mode 100644 index 00000000000..61f094edd0c --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py @@ -0,0 +1,140 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Deck Configuration 1", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +STARTING_VOL = 100 +TEMPERATURE_MODULE_NAME = "temperature module gen2" +THERMOCYCLER_NAME = "thermocycler module gen2" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +TRANSFER_VOL = 10 +USING_GRIPPER = True + + +LABWARE_MOVEMENT_DECK_SLOT_1 = "D1" +LABWARE_MOVEMENT_DECK_SLOT_2 = "B3" +LABWARE_MOVEMENT_STAGING_AREA_SLOT_3 = "C3" +LABWARE_MOVEMENT_STAGING_AREA_SLOT_4 = "A4" + +TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_2 = "D2" + + +def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: + return tiprack["A1"] + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + trash_bin_1 = ctx.load_trash_bin("C1") + waste_chute = ctx.load_waste_chute() + + ############### + ### MODULES ### + ############### + thermocycler = ctx.load_module(THERMOCYCLER_NAME) # A1 & B1 + magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "A2") + heater_shaker = ctx.load_module(HEATER_SHAKER_NAME, "A3") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + + modules = [thermocycler, heater_shaker, magnetic_block, temperature_module] + + ####################### + ### MODULE ADAPTERS ### + ####################### + + temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") + # heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") + + ############### + ### LABWARE ### + ############### + + source_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") + + on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_1 = on_deck_tip_rack_1.parent + + on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + tip_rack_adapter_2 = on_deck_tip_rack_2.parent + off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") + staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") + + tip_racks = [ + on_deck_tip_rack_1, + on_deck_tip_rack_2, + staging_area_tip_rack_1, + staging_area_tip_rack_2, + off_deck_tip_rack_1, + off_deck_tip_rack_2, + ] + + ########################## + ### PIPETTE DEFINITION ### + ########################## + + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) + + ######################## + ### LOAD SOME LIQUID ### + ######################## + + water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") + + acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") + + [ + well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) + for i, column in enumerate(source_pcr_plate.columns()) + for well in column + ] + + ################################ + ### GRIPPER LABWARE MOVEMENT ### + ################################ + + # Testing the following iterations of labware movement: + # Deck -> Deck + # Deck -> Staging Area Slot 3 + # Deck -> Staging Area Slot 4 + # Deck -> Each Module + + # Staging Area Slot 3 -> Staging Area Slot 4 + # Staging Area Slot 3 -> Each Module + # Staging Area Slot 3 -> Deck + + # Staging Area Slot 4 -> Staging Area Slot 3 + # Staging Area Slot 4 -> Each Module + # Staging Area Slot 4 -> Deck + + # Module -> Staging Area Slot 3 + # Module -> Staging Area Slot 4 + # Module -> Deck + # Module -> Other Module + + module_to_module_iterations = [ + (modules[i], modules[j]) + for i in range(modules) + for j in range(modules) + if i != j + ] + + for starting_loc, ending_loc in module_to_module_iterations: + ctx. \ No newline at end of file From 92833d89d23eacfe3507037cb43b4d60ccc57e9b Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Fri, 8 Dec 2023 06:39:58 -0800 Subject: [PATCH 05/30] chore: formatting --- ...PER_HS_TM_TC_MB_2_16_DeckConfiguration1.py | 53 +++++++++++-------- ...C_MB_2_16_DeckConfiguration1_NoFixtures.py | 18 +++++-- ...TC_MB_2_16_DeckConfiguration1_NoModules.py | 24 ++++++--- ..._DeckConfiguration1_NoModulesNoFixtures.py | 16 ++++-- ...P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py | 13 ++--- 5 files changed, 79 insertions(+), 45 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py index f53a32fdbb3..a677697aa92 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py @@ -20,7 +20,7 @@ TRANSFER_VOL = 10 USING_GRIPPER = True -TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" @@ -60,18 +60,19 @@ def run(ctx: protocol_api.ProtocolContext) -> None: src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") tip_rack_adapter_1 = on_deck_tip_rack_1.parent - on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_2 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_2 = on_deck_tip_rack_2.parent off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") - staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") + staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") + staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") tip_racks = [ on_deck_tip_rack_1, @@ -106,40 +107,46 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### MOVE SOME LIQUID ### ######################## - pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") - pipette_96_channel.drop_tip(waste_chute) - + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) + pipette_96_channel.drop_tip(waste_chute) - pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") - pipette_96_channel.drop_tip(trash_bin_1) - + pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) + pipette_96_channel.drop_tip(trash_bin_1) ################################## ### THROW AWAY EMPTY TIP RACKS ### ################################## - ctx.move_labware(on_deck_tip_rack_1, waste_chute, use_gripper=USING_GRIPPER) - ctx.move_labware(on_deck_tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_1, waste_chute, use_gripper=USING_GRIPPER) + ctx.move_labware(on_deck_tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) ################################### ### MOVE STAGING AREA TIP RACKS ### ################################### - ctx.move_labware(staging_area_tip_rack_1, tip_rack_adapter_1, use_gripper=USING_GRIPPER) - ctx.move_labware(staging_area_tip_rack_2, tip_rack_adapter_2, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_1, tip_rack_adapter_1, use_gripper=USING_GRIPPER) + ctx.move_labware(staging_area_tip_rack_2, tip_rack_adapter_2, use_gripper=USING_GRIPPER) ############################# ### MOVE SOME MORE LIQUID ### ############################# pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(trash_bin_2) ################################## @@ -157,11 +164,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) ############################ diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py index b83d7b7aa7e..b8f7467bb21 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py @@ -53,7 +53,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") tip_rack_adapter_1 = on_deck_tip_rack_1.parent - + on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") tip_rack_adapter_2 = on_deck_tip_rack_2.parent off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) @@ -86,11 +86,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ######################## pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() ##################################### @@ -108,11 +112,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() ############################ diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py index abb6cbfe0fb..ce70cb64c33 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py @@ -89,11 +89,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ######################## pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(trash_bin_1) ################################## @@ -115,11 +119,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ############################# pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) pipette_96_channel.pick_up_tip(default_well(staging_area_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(trash_bin_2) ################################## @@ -137,11 +145,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.drop_tip(waste_chute) ########################################## diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py index 17fda1aeb0d..fe96b2e75a0 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py @@ -71,11 +71,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ######################## pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() pipette_96_channel.pick_up_tip(default_well(on_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() ##################################### @@ -93,11 +97,15 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ctx.move_labware(off_deck_tip_rack_2, tip_rack_adapter_2, use_gripper=not USING_GRIPPER) pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_1)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() pipette_96_channel.pick_up_tip(default_well(off_deck_tip_rack_2)) - pipette_96_channel.transfer(TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never") + pipette_96_channel.transfer( + TRANSFER_VOL, default_well(src_pcr_plate), default_well(dest_pcr_plate), new_tip="never" + ) pipette_96_channel.return_tip() ########################################## diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py index 61f094edd0c..53650b09f98 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py @@ -26,7 +26,7 @@ LABWARE_MOVEMENT_STAGING_AREA_SLOT_3 = "C3" LABWARE_MOVEMENT_STAGING_AREA_SLOT_4 = "A4" -TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" @@ -129,12 +129,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: # Module -> Deck # Module -> Other Module - module_to_module_iterations = [ - (modules[i], modules[j]) - for i in range(modules) - for j in range(modules) - if i != j - ] + module_to_module_iterations = [(modules[i], modules[j]) for i in range(modules) for j in range(modules) if i != j] - for starting_loc, ending_loc in module_to_module_iterations: - ctx. \ No newline at end of file + # for starting_loc, ending_loc in module_to_module_iterations: + # ctx. From 3200e27b62aa13d2ef92dc6eb2c47fd9ccf8f8f5 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Fri, 8 Dec 2023 09:44:47 -0800 Subject: [PATCH 06/30] test: add mega protocol (WIP) --- ...6_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py new file mode 100644 index 00000000000..536535975ec --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py @@ -0,0 +1,266 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - MEGAAA PROTOCOL - LETS BREAK, I MEAN TEST, EVERYTHING!!!!!", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +HEATER_SHAKER_NAME = "heaterShakerModuleV1" +MAGNETIC_BLOCK_NAME = "magneticBlockV1" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +STARTING_VOL = 100 +TEMPERATURE_MODULE_NAME = "temperature module gen2" +THERMOCYCLER_NAME = "thermocycler module gen2" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +TRANSFER_VOL = 10 +USING_GRIPPER = True +RESET_AFTER_EACH_MOVE = True +DONT_RESET_AFTER_EACH_MOVE = False + + +LABWARE_MOVEMENT_DECK_SLOT_1 = "D1" +LABWARE_MOVEMENT_DECK_SLOT_2 = "B3" +LABWARE_MOVEMENT_STAGING_AREA_SLOT_3 = "C3" +LABWARE_MOVEMENT_STAGING_AREA_SLOT_4 = "A4" + +TIP_RACK_LOCATION_1 = "C3" +TIP_RACK_LOCATION_2 = "D2" + +# NO STAGING AREA IN ROW A or B because of modules + +# A1 - B1: Thermocycler +# C1: Trash Bin +# D1: EMPTY +# A2: Magnetic Block +# B2: Source PCR Plate +# C2: EMPTY for now, will load from off deck - Dest PCR Plate +# D2: Tip Rack 2 +# A3: Heater-Shaker +# B3: Temperature Module +# C3: Tip Rack 1 +# D3: EMPTY +# A4: EMPTY +# B4: EMPTY +# C4: EMPTY for now, will load from off deck - Staging Area Tip Rack 1 +# D4: EMPTY for now, will load from off deck - Staging Area Tip Rack 2 + + +def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: + return tiprack["A1"] + + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + trash_bin_1 = ctx.load_trash_bin("C1") + waste_chute = ctx.load_waste_chute() + + ############### + ### MODULES ### + ############### + thermocycler = ctx.load_module(THERMOCYCLER_NAME) # A1 & B1 + magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "A2") + heater_shaker = ctx.load_module(HEATER_SHAKER_NAME, "A3") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + + thermocycler.open_lid() + heater_shaker.open_labware_latch() + + modules = [thermocycler, heater_shaker, magnetic_block, temperature_module] + + ####################### + ### MODULE ADAPTERS ### + ####################### + + temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") + heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") + + adapters = [temperature_module_adapter, heater_shaker_adapter] + + ############### + ### LABWARE ### + ############### + + source_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, protocol_api.OFF_DECK) + + on_deck_tip_rack_1 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_1, adapter="opentrons_flex_96_tiprack_adapter" + ) + tip_rack_adapter_1 = on_deck_tip_rack_1.parent + + on_deck_tip_rack_2 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter" + ) + tip_rack_adapter_2 = on_deck_tip_rack_2.parent + + off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + + tip_racks = [ + on_deck_tip_rack_1, + on_deck_tip_rack_2, + # staging_area_tip_rack_1, + # staging_area_tip_rack_2, + off_deck_tip_rack_1, + off_deck_tip_rack_2, + ] + + ########################## + ### PIPETTE DEFINITION ### + ########################## + + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) + + ######################## + ### LOAD SOME LIQUID ### + ######################## + + water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") + + acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") + + [ + well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) + for i, column in enumerate(source_pcr_plate.columns()) + for well in column + ] + + ################################ + ### GRIPPER LABWARE MOVEMENT ### + ################################ + + # This tests moving the labware with the gripper all around the deck. + # It will perform 2 types of movements: + # Moving to a sequence of locations + # Moving to a sequence of locations with a reset to the original labware location after each move + + # Iterations: + # Deck -> Deck + # Deck -> Staging Area Slot 3 + # Deck -> Staging Area Slot 4 + # Deck -> Each Module + + # Staging Area Slot 3 -> Staging Area Slot 4 + # Staging Area Slot 3 -> Each Module + # Staging Area Slot 3 -> Deck + + # Staging Area Slot 4 -> Staging Area Slot 4 + # Staging Area Slot 4 -> Staging Area Slot 3 + # Staging Area Slot 4 -> Each Module + # Staging Area Slot 4 -> Deck + + # Module -> Staging Area Slot 3 + # Module -> Staging Area Slot 4 + # Module -> Deck + # Module -> Other Module + + def run_moves(labware, move_sequences, reset_location, use_gripper): + def move_to_locations(labware_to_move, move_locations, reset_after_each_move, use_gripper, reset_location): + def reset_labware(): + ctx.comment( + f"Moving {labware_to_move.name} back to {reset_location.__str__} from {labware_to_move.parent.__str__}" + ) + ctx.move_labware(labware_to_move, reset_location, use_gripper=use_gripper) + + if len(move_locations) == 0: + return + + for location in move_locations: + ctx.comment( + f"Moving {labware_to_move.name} from {labware_to_move.parent.__str__} to {location.__str__}" + ) + ctx.move_labware(labware_to_move, location, use_gripper=use_gripper) + + if reset_after_each_move: + reset_labware() + + if not reset_after_each_move: + reset_labware() + + for move_sequence in move_sequences: + move_to_locations(labware, move_sequence, RESET_AFTER_EACH_MOVE, use_gripper, reset_location) + move_to_locations(labware, move_sequence, DONT_RESET_AFTER_EACH_MOVE, use_gripper, reset_location) + + def test_gripper_moves(): + def deck_moves(pcr_plate, reset_location): + + # Deck -> Deck + deck_move_sequence = [ + ["D1", "C2"], # Deck Moves + ["D3"], # Staging Area Slot 3 Moves + ["C4", "D4"], # Staging Area Slot 4 Moves + [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves + ] + + run_moves(pcr_plate, deck_move_sequence, reset_location, USING_GRIPPER) + + def staging_area_slot_3_moves(labware, reset_location): + + staging_area_slot_3_move_sequence = [ + ["D1", "C2", "B2"], # Deck Moves + [], # Don't have Staging Area Slot 3 open + ["C4", "D4"], # Staging Area Slot 4 Moves + [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves + ] + + run_moves(labware, staging_area_slot_3_move_sequence, reset_location, USING_GRIPPER) + + def staging_area_slot_4_moves(labware, reset_location): + + staging_area_slot_4_move_sequence = [ + ["D1", "C2", "B2"], # Deck Moves + ["D3"], # Staging Area Slot 3 Moves + ["D4"], # Staging Area Slot 4 Moves + [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves + ] + + run_moves(labware, staging_area_slot_4_move_sequence, reset_location, USING_GRIPPER) + + def module_moves(labware, module_locations): + + module_move_sequence = [ + ["D1", "C2", "B2"], # Deck Moves + ["D3"], # Staging Area Slot 3 Moves + ["C4", "D4"], # Staging Area Slot 4 Moves + ] + + for module_starting_location in module_locations: + labware_move_to_locations = module_locations.copy() + labware_move_to_locations.remove(module_starting_location) + all_sequences = module_move_sequence.copy() + all_sequences.append(labware_move_to_locations) + ctx.move_labware(source_pcr_plate, module_starting_location, use_gripper=USING_GRIPPER) + run_moves(labware, all_sequences, module_starting_location, USING_GRIPPER) + + DECK_MOVE_RESET_LOCATION = "B2" + STAGING_AREA_SLOT_3_RESET_LOCATION = "D3" + STAGING_AREA_SLOT_4_RESET_LOCATION = "C4" + + deck_moves(source_pcr_plate, DECK_MOVE_RESET_LOCATION) + + ctx.move_labware(source_pcr_plate, STAGING_AREA_SLOT_3_RESET_LOCATION, use_gripper=USING_GRIPPER) + staging_area_slot_3_moves(source_pcr_plate, STAGING_AREA_SLOT_3_RESET_LOCATION) + + ctx.move_labware(source_pcr_plate, STAGING_AREA_SLOT_4_RESET_LOCATION, use_gripper=USING_GRIPPER) + staging_area_slot_4_moves(source_pcr_plate, STAGING_AREA_SLOT_4_RESET_LOCATION) + + module_locations = [thermocycler, magnetic_block] + adapters + module_moves(source_pcr_plate, module_locations) + + def test_manual_moves(): + # In C4 currently + ctx.move_labware(source_pcr_plate, "D4", use_gripper=not USING_GRIPPER) + + test_gripper_moves() + test_manual_moves() From 18478e205e40e8481a1a0298ac00bd7df72fbfcb Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Mon, 11 Dec 2023 15:48:26 -0800 Subject: [PATCH 07/30] test: rework to support partial tip add pipetting --- ...6_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py | 197 ++++++++++-------- 1 file changed, 115 insertions(+), 82 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py index 536535975ec..fff7441048a 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py @@ -10,6 +10,17 @@ "apiLevel": "2.16", } +############# +### FLAGS ### +############# + +# prefer to move off deck, instead of waste chute disposal, if possible +PREFER_MOVE_OFF_DECK = True + +################# +### CONSTANTS ### +################# + HEATER_SHAKER_NAME = "heaterShakerModuleV1" MAGNETIC_BLOCK_NAME = "magneticBlockV1" PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" @@ -22,33 +33,9 @@ RESET_AFTER_EACH_MOVE = True DONT_RESET_AFTER_EACH_MOVE = False - -LABWARE_MOVEMENT_DECK_SLOT_1 = "D1" -LABWARE_MOVEMENT_DECK_SLOT_2 = "B3" -LABWARE_MOVEMENT_STAGING_AREA_SLOT_3 = "C3" -LABWARE_MOVEMENT_STAGING_AREA_SLOT_4 = "A4" - TIP_RACK_LOCATION_1 = "C3" TIP_RACK_LOCATION_2 = "D2" -# NO STAGING AREA IN ROW A or B because of modules - -# A1 - B1: Thermocycler -# C1: Trash Bin -# D1: EMPTY -# A2: Magnetic Block -# B2: Source PCR Plate -# C2: EMPTY for now, will load from off deck - Dest PCR Plate -# D2: Tip Rack 2 -# A3: Heater-Shaker -# B3: Temperature Module -# C3: Tip Rack 1 -# D3: EMPTY -# A4: EMPTY -# B4: EMPTY -# C4: EMPTY for now, will load from off deck - Staging Area Tip Rack 1 -# D4: EMPTY for now, will load from off deck - Staging Area Tip Rack 2 - def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: return tiprack["A1"] @@ -60,22 +47,20 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### FIXTURES ### ################ - trash_bin_1 = ctx.load_trash_bin("C1") + trash_bin = ctx.load_trash_bin("B3") waste_chute = ctx.load_waste_chute() ############### ### MODULES ### ############### thermocycler = ctx.load_module(THERMOCYCLER_NAME) # A1 & B1 - magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "A2") + magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "C1") heater_shaker = ctx.load_module(HEATER_SHAKER_NAME, "A3") - temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "D1") thermocycler.open_lid() heater_shaker.open_labware_latch() - modules = [thermocycler, heater_shaker, magnetic_block, temperature_module] - ####################### ### MODULE ADAPTERS ### ####################### @@ -89,31 +74,21 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### LABWARE ### ############### - source_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, protocol_api.OFF_DECK) + source_reservoir = ctx.load_labware("nest_1_reservoir_290ml", "D2") + dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - on_deck_tip_rack_1 = ctx.load_labware( - TIPRACK_96_NAME, TIP_RACK_LOCATION_1, adapter="opentrons_flex_96_tiprack_adapter" + tip_rack_1 = ctx.load_labware( + TIPRACK_96_NAME, "A2", adapter="opentrons_flex_96_tiprack_adapter" ) - tip_rack_adapter_1 = on_deck_tip_rack_1.parent - - on_deck_tip_rack_2 = ctx.load_labware( - TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter" - ) - tip_rack_adapter_2 = on_deck_tip_rack_2.parent - - off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) + tip_rack_adapter = tip_rack_1.parent + + tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "C3") + tip_rack_3 = ctx.load_labware(TIPRACK_96_NAME, "C4") tip_racks = [ - on_deck_tip_rack_1, - on_deck_tip_rack_2, - # staging_area_tip_rack_1, - # staging_area_tip_rack_2, - off_deck_tip_rack_1, - off_deck_tip_rack_2, + tip_rack_1, + tip_rack_2, + tip_rack_3, ] ########################## @@ -132,7 +107,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: [ well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(source_pcr_plate.columns()) + for i, column in enumerate(source_reservoir.columns()) for well in column ] @@ -157,7 +132,7 @@ def run(ctx: protocol_api.ProtocolContext) -> None: # Staging Area Slot 4 -> Staging Area Slot 4 # Staging Area Slot 4 -> Staging Area Slot 3 - # Staging Area Slot 4 -> Each Module + # Staging Area Slot 4 -> Each ModuleSTAGING_AREA_SLOT_3_RESET_LOCATION # Staging Area Slot 4 -> Deck # Module -> Staging Area Slot 3 @@ -165,21 +140,18 @@ def run(ctx: protocol_api.ProtocolContext) -> None: # Module -> Deck # Module -> Other Module + def get_disposal_preference(): + return (protocol_api.OFF_DECK, not USING_GRIPPER) if PREFER_MOVE_OFF_DECK else (waste_chute, USING_GRIPPER) + def run_moves(labware, move_sequences, reset_location, use_gripper): def move_to_locations(labware_to_move, move_locations, reset_after_each_move, use_gripper, reset_location): def reset_labware(): - ctx.comment( - f"Moving {labware_to_move.name} back to {reset_location.__str__} from {labware_to_move.parent.__str__}" - ) ctx.move_labware(labware_to_move, reset_location, use_gripper=use_gripper) if len(move_locations) == 0: return for location in move_locations: - ctx.comment( - f"Moving {labware_to_move.name} from {labware_to_move.parent.__str__} to {location.__str__}" - ) ctx.move_labware(labware_to_move, location, use_gripper=use_gripper) if reset_after_each_move: @@ -194,11 +166,9 @@ def reset_labware(): def test_gripper_moves(): def deck_moves(pcr_plate, reset_location): - - # Deck -> Deck deck_move_sequence = [ - ["D1", "C2"], # Deck Moves - ["D3"], # Staging Area Slot 3 Moves + ["B2"], # Deck Moves + ["C3"], # Staging Area Slot 3 Moves ["C4", "D4"], # Staging Area Slot 4 Moves [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves ] @@ -206,9 +176,8 @@ def deck_moves(pcr_plate, reset_location): run_moves(pcr_plate, deck_move_sequence, reset_location, USING_GRIPPER) def staging_area_slot_3_moves(labware, reset_location): - staging_area_slot_3_move_sequence = [ - ["D1", "C2", "B2"], # Deck Moves + ["B2", "C2"], # Deck Moves [], # Don't have Staging Area Slot 3 open ["C4", "D4"], # Staging Area Slot 4 Moves [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves @@ -219,9 +188,9 @@ def staging_area_slot_3_moves(labware, reset_location): def staging_area_slot_4_moves(labware, reset_location): staging_area_slot_4_move_sequence = [ - ["D1", "C2", "B2"], # Deck Moves - ["D3"], # Staging Area Slot 3 Moves - ["D4"], # Staging Area Slot 4 Moves + ["C2", "B2"], # Deck Moves + ["C3"], # Staging Area Slot 3 Moves + ["C4"], # Staging Area Slot 4 Moves [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves ] @@ -230,8 +199,8 @@ def staging_area_slot_4_moves(labware, reset_location): def module_moves(labware, module_locations): module_move_sequence = [ - ["D1", "C2", "B2"], # Deck Moves - ["D3"], # Staging Area Slot 3 Moves + ["C2", "B2"], # Deck Moves + ["C3"], # Staging Area Slot 3 Moves ["C4", "D4"], # Staging Area Slot 4 Moves ] @@ -240,27 +209,91 @@ def module_moves(labware, module_locations): labware_move_to_locations.remove(module_starting_location) all_sequences = module_move_sequence.copy() all_sequences.append(labware_move_to_locations) - ctx.move_labware(source_pcr_plate, module_starting_location, use_gripper=USING_GRIPPER) + ctx.move_labware(labware, module_starting_location, use_gripper=USING_GRIPPER) run_moves(labware, all_sequences, module_starting_location, USING_GRIPPER) - DECK_MOVE_RESET_LOCATION = "B2" - STAGING_AREA_SLOT_3_RESET_LOCATION = "D3" - STAGING_AREA_SLOT_4_RESET_LOCATION = "C4" + DECK_MOVE_RESET_LOCATION = "C2" + STAGING_AREA_SLOT_3_RESET_LOCATION = "C3" + STAGING_AREA_SLOT_4_RESET_LOCATION = "D4" - deck_moves(source_pcr_plate, DECK_MOVE_RESET_LOCATION) + deck_moves(dest_pcr_plate, DECK_MOVE_RESET_LOCATION) - ctx.move_labware(source_pcr_plate, STAGING_AREA_SLOT_3_RESET_LOCATION, use_gripper=USING_GRIPPER) - staging_area_slot_3_moves(source_pcr_plate, STAGING_AREA_SLOT_3_RESET_LOCATION) + ctx.move_labware(dest_pcr_plate, STAGING_AREA_SLOT_3_RESET_LOCATION, use_gripper=USING_GRIPPER) + staging_area_slot_3_moves(dest_pcr_plate, STAGING_AREA_SLOT_3_RESET_LOCATION) - ctx.move_labware(source_pcr_plate, STAGING_AREA_SLOT_4_RESET_LOCATION, use_gripper=USING_GRIPPER) - staging_area_slot_4_moves(source_pcr_plate, STAGING_AREA_SLOT_4_RESET_LOCATION) + ctx.move_labware(dest_pcr_plate, STAGING_AREA_SLOT_4_RESET_LOCATION, use_gripper=USING_GRIPPER) + staging_area_slot_4_moves(dest_pcr_plate, STAGING_AREA_SLOT_4_RESET_LOCATION) module_locations = [thermocycler, magnetic_block] + adapters - module_moves(source_pcr_plate, module_locations) + module_moves(dest_pcr_plate, module_locations) def test_manual_moves(): # In C4 currently - ctx.move_labware(source_pcr_plate, "D4", use_gripper=not USING_GRIPPER) - - test_gripper_moves() + ctx.move_labware(source_reservoir, "D4", use_gripper=not USING_GRIPPER) + + def test_pipetting(): + + def test_partial_tip_pickup_usage(): + pipette_96_channel.configure_nozzle_layout(style=protocol_api.COLUMN, start="A12") + for i in range(1, 13): + pipette_96_channel.pick_up_tip(tip_rack_2[f"A{i}"]) + + pipette_96_channel.aspirate(5, source_reservoir["A1"]) + pipette_96_channel.touch_tip() + + pipette_96_channel.dispense(5, dest_pcr_plate[f"A{i}"]) + pipette_96_channel.drop_tip(trash_bin) + + # leave this dropping in waste chute, do not use get_disposal_preference + # want to test partial drop + ctx.move_labware(tip_rack_2, waste_chute, use_gripper=USING_GRIPPER) + + def test_full_tip_rack_usage(): + pipette_96_channel.configure_nozzle_layout(style=protocol_api.ALL, start="A1") + pipette_96_channel.pick_up_tip(tip_rack_1["A1"]) + + pipette_96_channel.aspirate(5, source_reservoir["A1"]) + pipette_96_channel.touch_tip() + + # Waiting for https://opentrons.atlassian.net/browse/RQA-2056 + # pipette_96_channel.air_gap(height=30) + + pipette_96_channel.blow_out(waste_chute) + + pipette_96_channel.aspirate(10, source_reservoir["A1"]) + pipette_96_channel.touch_tip() + + pipette_96_channel.dispense(10, dest_pcr_plate["A1"]) + pipette_96_channel.mix(repetitions=5, volume=15) + pipette_96_channel.return_tip() + + ctx.move_labware(tip_rack_1, get_disposal_preference()[0], use_gripper=get_disposal_preference()[1]) + ctx.move_labware(tip_rack_3, tip_rack_adapter, use_gripper=USING_GRIPPER) + + pipette_96_channel.pick_up_tip(tip_rack_3["A1"]) + pipette_96_channel.transfer( + volume=10, + source=source_reservoir["A1"], + dest=dest_pcr_plate["A1"], + new_tip="never", + touch_tip=True, + blow_out=True, + blowout_location="trash", + mix_before=(3, 5), + mix_after=(1, 5), + ) + pipette_96_channel.return_tip() + + ctx.move_labware(tip_rack_3, get_disposal_preference()[0], use_gripper=get_disposal_preference()[1]) + + test_partial_tip_pickup_usage() + test_full_tip_rack_usage() + test_manual_moves() + test_pipetting() + test_gripper_moves() + + +# Cannot test in this protocol + # - Waste Chute w/ Lid + From a662255634313a4f3b4f98c5c53565ebc4f813e3 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 08:14:49 -0800 Subject: [PATCH 08/30] test: Add module usage --- ...6_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py index fff7441048a..ddf7b5cfacd 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py @@ -232,7 +232,6 @@ def test_manual_moves(): ctx.move_labware(source_reservoir, "D4", use_gripper=not USING_GRIPPER) def test_pipetting(): - def test_partial_tip_pickup_usage(): pipette_96_channel.configure_nozzle_layout(style=protocol_api.COLUMN, start="A12") for i in range(1, 13): @@ -288,10 +287,53 @@ def test_full_tip_rack_usage(): test_partial_tip_pickup_usage() test_full_tip_rack_usage() - - test_manual_moves() - test_pipetting() - test_gripper_moves() + + def test_module_usage(): + def test_thermocycler(): + thermocycler.close_lid() + + thermocycler.set_block_temperature( + 75.0, + hold_time_seconds=5.0 + ) + thermocycler.set_lid_temperature(80.0) + thermocycler.deactivate() + + def test_heater_shaker(): + heater_shaker.open_labware_latch() + heater_shaker.close_labware_latch() + + heater_shaker.set_target_temperature(75.0) + heater_shaker.set_and_wait_for_shake_speed(1000) + heater_shaker.wait_for_temperature() + + heater_shaker.deactivate_heater() + heater_shaker.deactivate_shaker() + + def test_temperature_module(): + temperature_module.set_temperature(80) + temperature_module.set_temperature(10) + temperature_module.deactivate() + + def test_magnetic_block(): + pass + + test_thermocycler() + test_heater_shaker() + test_temperature_module() + test_magnetic_block() + + + ################################################################################################### + ### THE ORDER OF THESE FUNCTION CALLS MATTER. CHANGING THEM WILL CAUSE THE PROTOCOL NOT TO WORK ### + ################################################################################################### + test_pipetting() + test_gripper_moves() + test_module_usage() + test_manual_moves() + ################################################################################################### + ### THE ORDER OF THESE FUNCTION CALLS MATTER. CHANGING THEM WILL CAUSE THE PROTOCOL NOT TO WORK ### + ################################################################################################### # Cannot test in this protocol From 19d6e0e5f183a14cc8514dcb345ebdf9aca6e9aa Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 08:16:09 -0800 Subject: [PATCH 09/30] chore: docs --- ...6_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py | 118 +++++++++++++----- 1 file changed, 90 insertions(+), 28 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py index ddf7b5cfacd..3d9e84bdbe7 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py @@ -115,37 +115,48 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### GRIPPER LABWARE MOVEMENT ### ################################ - # This tests moving the labware with the gripper all around the deck. - # It will perform 2 types of movements: - # Moving to a sequence of locations - # Moving to a sequence of locations with a reset to the original labware location after each move - - # Iterations: - # Deck -> Deck - # Deck -> Staging Area Slot 3 - # Deck -> Staging Area Slot 4 - # Deck -> Each Module - - # Staging Area Slot 3 -> Staging Area Slot 4 - # Staging Area Slot 3 -> Each Module - # Staging Area Slot 3 -> Deck - - # Staging Area Slot 4 -> Staging Area Slot 4 - # Staging Area Slot 4 -> Staging Area Slot 3 - # Staging Area Slot 4 -> Each ModuleSTAGING_AREA_SLOT_3_RESET_LOCATION - # Staging Area Slot 4 -> Deck - - # Module -> Staging Area Slot 3 - # Module -> Staging Area Slot 4 - # Module -> Deck - # Module -> Other Module - def get_disposal_preference(): + """ + Get the disposal preference based on the PREFER_MOVE_OFF_DECK flag. + + Returns: + tuple: A tuple containing the disposal preference. The first element is the location preference, + either `protocol_api.OFF_DECK` or `waste_chute`. The second element is a boolean indicating + whether the gripper is being used or not. + """ return (protocol_api.OFF_DECK, not USING_GRIPPER) if PREFER_MOVE_OFF_DECK else (waste_chute, USING_GRIPPER) def run_moves(labware, move_sequences, reset_location, use_gripper): + """ + Perform a series of moves for a given labware using specified move sequences. + + Will perform 2 versions of the moves: + 1. Moves to each location in the sequence, resetting to the reset location after each move. + 2. Moves to each location in the sequence, resetting to the reset location after all moves. + + Args: + labware (str): The labware to be moved. + move_sequences (list): A list of move sequences, where each sequence is a list of locations. + reset_location (str): The location to reset the labware after each move sequence. + use_gripper (bool): Flag indicating whether to use the gripper during the moves. + """ + def move_to_locations(labware_to_move, move_locations, reset_after_each_move, use_gripper, reset_location): + """ + Move the labware to the specified locations. + + Args: + labware_to_move (str): The labware to be moved. + move_locations (list): A list of locations to move the labware to. + reset_after_each_move (bool): Flag indicating whether to reset the labware after each move. + use_gripper (bool): Flag indicating whether to use the gripper during the moves. + reset_location (str): The location to reset the labware after each move sequence. + """ + def reset_labware(): + """ + Reset the labware to the reset location. + """ ctx.move_labware(labware_to_move, reset_location, use_gripper=use_gripper) if len(move_locations) == 0: @@ -162,10 +173,33 @@ def reset_labware(): for move_sequence in move_sequences: move_to_locations(labware, move_sequence, RESET_AFTER_EACH_MOVE, use_gripper, reset_location) - move_to_locations(labware, move_sequence, DONT_RESET_AFTER_EACH_MOVE, use_gripper, reset_location) + move_to_locations(labware, move_sequence, not RESET_AFTER_EACH_MOVE, use_gripper, reset_location) + def test_gripper_moves(): - def deck_moves(pcr_plate, reset_location): + """ + Function to test the movement of the gripper in various locations. + + This function contains several helper functions to perform the movement of labware using a gripper. + Each function performs a sequence of moves, starting with a specific location on the deck. + + Args: + None + + Returns: + None + """ + def deck_moves(labware, reset_location): + """ + Function to perform the movement of labware, with the inital position being on the deck. + + Args: + pcr_plate (str): The labware to be moved on the deck. + reset_location (str): The reset location on the deck. + + Returns: + None + """ deck_move_sequence = [ ["B2"], # Deck Moves ["C3"], # Staging Area Slot 3 Moves @@ -173,9 +207,19 @@ def deck_moves(pcr_plate, reset_location): [thermocycler, temperature_module_adapter, heater_shaker_adapter, magnetic_block], # Module Moves ] - run_moves(pcr_plate, deck_move_sequence, reset_location, USING_GRIPPER) + run_moves(labware, deck_move_sequence, reset_location, USING_GRIPPER) def staging_area_slot_3_moves(labware, reset_location): + """ + Function to perform the movement of labware, with the inital position being on staging area slot 3. + + Args: + labware (str): The labware to be moved in staging area slot 3. + reset_location (str): The reset location in staging area slot 3. + + Returns: + None + """ staging_area_slot_3_move_sequence = [ ["B2", "C2"], # Deck Moves [], # Don't have Staging Area Slot 3 open @@ -186,7 +230,16 @@ def staging_area_slot_3_moves(labware, reset_location): run_moves(labware, staging_area_slot_3_move_sequence, reset_location, USING_GRIPPER) def staging_area_slot_4_moves(labware, reset_location): + """ + Function to perform the movement of labware, with the inital position being on staging area slot 4. + + Args: + labware (str): The labware to be moved in staging area slot 4. + reset_location (str): The reset location in staging area slot 4. + Returns: + None + """ staging_area_slot_4_move_sequence = [ ["C2", "B2"], # Deck Moves ["C3"], # Staging Area Slot 3 Moves @@ -197,7 +250,16 @@ def staging_area_slot_4_moves(labware, reset_location): run_moves(labware, staging_area_slot_4_move_sequence, reset_location, USING_GRIPPER) def module_moves(labware, module_locations): + """ + Function to perform the movement of labware, with the inital position being on a module. + + Args: + labware (str): The labware to be moved with modules. + module_locations (list): The locations of the modules. + Returns: + None + """ module_move_sequence = [ ["C2", "B2"], # Deck Moves ["C3"], # Staging Area Slot 3 Moves From e0a415810210cc3b9a77af0a5b96c344b764eaf9 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 08:16:52 -0800 Subject: [PATCH 10/30] chore: cleanup constants --- ...6_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py index 3d9e84bdbe7..33d2b6cd9a1 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py @@ -1,3 +1,4 @@ + from opentrons import protocol_api metadata = { @@ -21,24 +22,22 @@ ### CONSTANTS ### ################# +HEATER_SHAKER_ADAPTER_NAME = "opentrons_96_pcr_adapter" HEATER_SHAKER_NAME = "heaterShakerModuleV1" MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -STARTING_VOL = 100 +TEMPERATURE_MODULE_ADAPTER_NAME = "opentrons_96_well_aluminum_block" TEMPERATURE_MODULE_NAME = "temperature module gen2" THERMOCYCLER_NAME = "thermocycler module gen2" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -TRANSFER_VOL = 10 -USING_GRIPPER = True -RESET_AFTER_EACH_MOVE = True -DONT_RESET_AFTER_EACH_MOVE = False -TIP_RACK_LOCATION_1 = "C3" -TIP_RACK_LOCATION_2 = "D2" +PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" +RESERVOIR_NAME = "nest_1_reservoir_290ml" +TIPRACK_96_ADAPTER_NAME = "opentrons_flex_96_tiprack_adapter" +TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" +PIPETTE_96_CHANNEL_NAME = "flex_96channel_1000" -def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: - return tiprack["A1"] +USING_GRIPPER = True +RESET_AFTER_EACH_MOVE = True def run(ctx: protocol_api.ProtocolContext) -> None: @@ -65,8 +64,8 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### MODULE ADAPTERS ### ####################### - temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") - heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") + temperature_module_adapter = temperature_module.load_adapter(TEMPERATURE_MODULE_ADAPTER_NAME) + heater_shaker_adapter = heater_shaker.load_adapter(HEATER_SHAKER_ADAPTER_NAME) adapters = [temperature_module_adapter, heater_shaker_adapter] @@ -74,11 +73,11 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### LABWARE ### ############### - source_reservoir = ctx.load_labware("nest_1_reservoir_290ml", "D2") + source_reservoir = ctx.load_labware(RESERVOIR_NAME, "D2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") tip_rack_1 = ctx.load_labware( - TIPRACK_96_NAME, "A2", adapter="opentrons_flex_96_tiprack_adapter" + TIPRACK_96_NAME, "A2", adapter=TIPRACK_96_ADAPTER_NAME ) tip_rack_adapter = tip_rack_1.parent @@ -95,21 +94,14 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ### PIPETTE DEFINITION ### ########################## - pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) + pipette_96_channel = ctx.load_instrument(PIPETTE_96_CHANNEL_NAME, mount="left", tip_racks=tip_racks) ######################## ### LOAD SOME LIQUID ### ######################## water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") - - acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") - - [ - well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(source_reservoir.columns()) - for well in column - ] + source_reservoir.wells_by_name()["A1"].load_liquid(liquid=water, volume=29000) ################################ ### GRIPPER LABWARE MOVEMENT ### From 91883ec651bab9fd099adee4755fefe743f52c63 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 08:22:11 -0800 Subject: [PATCH 11/30] chore: formatting --- ...6_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py index 33d2b6cd9a1..62897449cdd 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py @@ -1,4 +1,3 @@ - from opentrons import protocol_api metadata = { @@ -76,11 +75,9 @@ def run(ctx: protocol_api.ProtocolContext) -> None: source_reservoir = ctx.load_labware(RESERVOIR_NAME, "D2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - tip_rack_1 = ctx.load_labware( - TIPRACK_96_NAME, "A2", adapter=TIPRACK_96_ADAPTER_NAME - ) + tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "A2", adapter=TIPRACK_96_ADAPTER_NAME) tip_rack_adapter = tip_rack_1.parent - + tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "C3") tip_rack_3 = ctx.load_labware(TIPRACK_96_NAME, "C4") @@ -121,7 +118,7 @@ def get_disposal_preference(): def run_moves(labware, move_sequences, reset_location, use_gripper): """ Perform a series of moves for a given labware using specified move sequences. - + Will perform 2 versions of the moves: 1. Moves to each location in the sequence, resetting to the reset location after each move. 2. Moves to each location in the sequence, resetting to the reset location after all moves. @@ -167,7 +164,6 @@ def reset_labware(): move_to_locations(labware, move_sequence, RESET_AFTER_EACH_MOVE, use_gripper, reset_location) move_to_locations(labware, move_sequence, not RESET_AFTER_EACH_MOVE, use_gripper, reset_location) - def test_gripper_moves(): """ Function to test the movement of the gripper in various locations. @@ -181,6 +177,7 @@ def test_gripper_moves(): Returns: None """ + def deck_moves(labware, reset_location): """ Function to perform the movement of labware, with the inital position being on the deck. @@ -304,7 +301,7 @@ def test_partial_tip_pickup_usage(): def test_full_tip_rack_usage(): pipette_96_channel.configure_nozzle_layout(style=protocol_api.ALL, start="A1") pipette_96_channel.pick_up_tip(tip_rack_1["A1"]) - + pipette_96_channel.aspirate(5, source_reservoir["A1"]) pipette_96_channel.touch_tip() @@ -345,11 +342,8 @@ def test_full_tip_rack_usage(): def test_module_usage(): def test_thermocycler(): thermocycler.close_lid() - - thermocycler.set_block_temperature( - 75.0, - hold_time_seconds=5.0 - ) + + thermocycler.set_block_temperature(75.0, hold_time_seconds=5.0) thermocycler.set_lid_temperature(80.0) thermocycler.deactivate() @@ -377,19 +371,17 @@ def test_magnetic_block(): test_temperature_module() test_magnetic_block() - ################################################################################################### ### THE ORDER OF THESE FUNCTION CALLS MATTER. CHANGING THEM WILL CAUSE THE PROTOCOL NOT TO WORK ### ################################################################################################### - test_pipetting() - test_gripper_moves() - test_module_usage() - test_manual_moves() + test_pipetting() + test_gripper_moves() + test_module_usage() + test_manual_moves() ################################################################################################### ### THE ORDER OF THESE FUNCTION CALLS MATTER. CHANGING THEM WILL CAUSE THE PROTOCOL NOT TO WORK ### ################################################################################################### # Cannot test in this protocol - # - Waste Chute w/ Lid - +# - Waste Chute w/ Lid From 5dc16d0d41531f5cacfaf48ab1580898a9dbcc1f Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 09:15:56 -0800 Subject: [PATCH 12/30] chore: remove smoke protocol --- ...P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py | 135 ------------------ 1 file changed, 135 deletions(-) delete mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py deleted file mode 100644 index 53650b09f98..00000000000 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py +++ /dev/null @@ -1,135 +0,0 @@ -from opentrons import protocol_api - -metadata = { - "protocolName": "QA Protocol - Deck Configuration 1", - "author": "Derek Maggio ", -} - -requirements = { - "robotType": "OT-3", - "apiLevel": "2.16", -} - -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -STARTING_VOL = 100 -TEMPERATURE_MODULE_NAME = "temperature module gen2" -THERMOCYCLER_NAME = "thermocycler module gen2" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -TRANSFER_VOL = 10 -USING_GRIPPER = True - - -LABWARE_MOVEMENT_DECK_SLOT_1 = "D1" -LABWARE_MOVEMENT_DECK_SLOT_2 = "B3" -LABWARE_MOVEMENT_STAGING_AREA_SLOT_3 = "C3" -LABWARE_MOVEMENT_STAGING_AREA_SLOT_4 = "A4" - -TIP_RACK_LOCATION_1 = "C3" -TIP_RACK_LOCATION_2 = "D2" - - -def default_well(tiprack: protocol_api.labware) -> protocol_api.labware.Well: - return tiprack["A1"] - - -def run(ctx: protocol_api.ProtocolContext) -> None: - - ################ - ### FIXTURES ### - ################ - - trash_bin_1 = ctx.load_trash_bin("C1") - waste_chute = ctx.load_waste_chute() - - ############### - ### MODULES ### - ############### - thermocycler = ctx.load_module(THERMOCYCLER_NAME) # A1 & B1 - magnetic_block = ctx.load_module(MAGNETIC_BLOCK_NAME, "A2") - heater_shaker = ctx.load_module(HEATER_SHAKER_NAME, "A3") - temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") - - modules = [thermocycler, heater_shaker, magnetic_block, temperature_module] - - ####################### - ### MODULE ADAPTERS ### - ####################### - - temperature_module_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") - # heater_shaker_adapter = heater_shaker.load_adapter("opentrons_96_pcr_adapter") - - ############### - ### LABWARE ### - ############### - - source_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") - tip_rack_adapter_1 = on_deck_tip_rack_1.parent - - on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") - tip_rack_adapter_2 = on_deck_tip_rack_2.parent - off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) - staging_area_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "C4") - staging_area_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, "D4") - - tip_racks = [ - on_deck_tip_rack_1, - on_deck_tip_rack_2, - staging_area_tip_rack_1, - staging_area_tip_rack_2, - off_deck_tip_rack_1, - off_deck_tip_rack_2, - ] - - ########################## - ### PIPETTE DEFINITION ### - ########################## - - pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=tip_racks) - - ######################## - ### LOAD SOME LIQUID ### - ######################## - - water = ctx.define_liquid(name="water", description="High Quality H₂O", display_color="#42AB2D") - - acetone = ctx.define_liquid(name="acetone", description="C₃H₆O", display_color="#38588a") - - [ - well.load_liquid(liquid=water if i % 2 == 0 else acetone, volume=STARTING_VOL) - for i, column in enumerate(source_pcr_plate.columns()) - for well in column - ] - - ################################ - ### GRIPPER LABWARE MOVEMENT ### - ################################ - - # Testing the following iterations of labware movement: - # Deck -> Deck - # Deck -> Staging Area Slot 3 - # Deck -> Staging Area Slot 4 - # Deck -> Each Module - - # Staging Area Slot 3 -> Staging Area Slot 4 - # Staging Area Slot 3 -> Each Module - # Staging Area Slot 3 -> Deck - - # Staging Area Slot 4 -> Staging Area Slot 3 - # Staging Area Slot 4 -> Each Module - # Staging Area Slot 4 -> Deck - - # Module -> Staging Area Slot 3 - # Module -> Staging Area Slot 4 - # Module -> Deck - # Module -> Other Module - - module_to_module_iterations = [(modules[i], modules[j]) for i in range(modules) for j in range(modules) if i != j] - - # for starting_loc, ending_loc in module_to_module_iterations: - # ctx. From 4b0f46ade92cd1e6c3ac6ff0b2f811ea11037cd0 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 13:00:20 -0800 Subject: [PATCH 13/30] test: start adding failure cases --- app-testing/automation/data/protocol_files.py | 4 ++ app-testing/automation/data/protocols.py | 40 +++++++++++++++++++ ...or_DroppingLabwareInWasteChuteWithCover.py | 32 --------------- ...6_AnalysisError_FixtureUsesMiddleColumn.py | 18 +-------- ...AnalysisError_TrashBinInStagingAreaCol3.py | 25 ++++-------- ...AnalysisError_TrashBinInStagingAreaCol4.py | 15 +------ ..._2_16_AnalysisError_DropTipsWithNoTrash.py | 26 ++++++++++++ ...6_AnalysisError_ModuleInStagingAreaCol3.py | 26 +++++------- ...6_AnalysisError_ModuleInStagingAreaCol4.py | 15 +------ 9 files changed, 95 insertions(+), 106 deletions(-) delete mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py diff --git a/app-testing/automation/data/protocol_files.py b/app-testing/automation/data/protocol_files.py index 277d31ea3dc..260620f1f29 100644 --- a/app-testing/automation/data/protocol_files.py +++ b/app-testing/automation/data/protocol_files.py @@ -38,4 +38,8 @@ "OT3_P1000MLeft_P50MRight_HS_TM_MM_TC_2_15_ABR4_Illumina_DNA_Prep_24x", "OT3_P1000SRight_None_2_15_ABR_Simple_Normalize_Long_Right", "OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2", + "OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", + "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", + "OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash" ] diff --git a/app-testing/automation/data/protocols.py b/app-testing/automation/data/protocols.py index 139739b784d..d746634396a 100644 --- a/app-testing/automation/data/protocols.py +++ b/app-testing/automation/data/protocols.py @@ -329,3 +329,43 @@ class Protocols: app_error=False, robot_error=False, ) + + OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Fixture Uses Middle Column", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="InvalidTrashBinLocationError [line 15]: Invalid location for trash bin: C2. Valid slots: Any slot in column 1 or 3.", # noqa: E501 + ) + + OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Trash Bin Staging Area Column 3", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ProtocolCommandFailedError [line 21]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Trash Bin in C3, not compatible with one or more of the following fixtures: Slot C4", # noqa: E501 + ) + + OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Trash Bin Staging Area Column 4", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ValueError [line 19]: Staging areas not permitted for trash bin.", # noqa: E501 + ) + + OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Drop Tips With No Trash", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="NoTrashDefinedError [line 24]: Error 4000 GENERAL_ERROR (NoTrashDefinedError): No trash container has been defined in this protocol.", # noqa: E501 + ) diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py deleted file mode 100644 index 1c66a7665b1..00000000000 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DroppingLabwareInWasteChuteWithCover.py +++ /dev/null @@ -1,32 +0,0 @@ -from opentrons import protocol_api - -metadata = { - "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", - "apiLevel": "2.16", - "author": "Derek Maggio ", -} - -requirements = { - "robotType": "OT-3", - "apiLevel": "2.16", -} - -THERMOCYCLER_NAME = "thermocycler module gen2" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -TEMPERATURE_MODULE_NAME = "temperature module gen2" - -USING_GRIPPER = True - - -def run(ctx: protocol_api.ProtocolContext) -> None: - - ################ - ### FIXTURES ### - ################ - - src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") - waste_chute = ctx.load_waste_chute(cover=True) - ctx.move_labware(src_pcr_plate, waste_chute, use_gripper=True) diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py index 9af6ea16903..3ab076aaa59 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py @@ -1,7 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Fixture Uses Middle Column", + "protocolName": "QA Protocol - Analysis Error - Fixture Uses Middle Column", "author": "Derek Maggio ", } @@ -10,20 +10,6 @@ "apiLevel": "2.16", } -THERMOCYCLER_NAME = "thermocycler module gen2" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -TEMPERATURE_MODULE_NAME = "temperature module gen2" - -USING_GRIPPER = True - def run(ctx: protocol_api.ProtocolContext) -> None: - - ################ - ### FIXTURES ### - ################ - - trash_bin_1 = ctx.load_trash_bin("C2") + ctx.load_trash_bin("C2") diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py index ec4a0ea65d0..122b2a0fc03 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py @@ -1,8 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", - "apiLevel": "2.16", + "protocolName": "QA Protocol - Analysis Error - Trash Bin Staging Area Column 3", "author": "Derek Maggio ", } @@ -11,21 +10,13 @@ "apiLevel": "2.16", } -THERMOCYCLER_NAME = "thermocycler module gen2" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -TEMPERATURE_MODULE_NAME = "temperature module gen2" - -USING_GRIPPER = True - def run(ctx: protocol_api.ProtocolContext) -> None: - ################ - ### FIXTURES ### - ################ - - tip_rack_96 = ctx.load_labware(TIPRACK_96_NAME, "C4") # Staging Area - trash_bin_1 = ctx.load_trash_bin("C3") + ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area + tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "D3", adapter="opentrons_flex_96_tiprack_adapter") + ctx.load_trash_bin("C3") + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) + pipette_96_channel.pick_up_tip() + pipette_96_channel.drop_tip() + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py index d861b977196..28d42124553 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py @@ -1,8 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", - "apiLevel": "2.16", + "protocolName": "QA Protocol - Analysis Error - Trash Bin Staging Area Column 4", "author": "Derek Maggio ", } @@ -11,20 +10,10 @@ "apiLevel": "2.16", } -THERMOCYCLER_NAME = "thermocycler module gen2" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -TEMPERATURE_MODULE_NAME = "temperature module gen2" - -USING_GRIPPER = True - - def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - trash_bin_1 = ctx.load_trash_bin("C4") + ctx.load_trash_bin("C4") diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py new file mode 100644 index 00000000000..51a074db195 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py @@ -0,0 +1,26 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Drop Tips with no Trash", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ################ + ### FIXTURES ### + ################ + + ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area + tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "D3", adapter="opentrons_flex_96_tiprack_adapter") + ctx.load_module("temperature module gen2", "C3") + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) + pipette_96_channel.pick_up_tip() + pipette_96_channel.drop_tip() + + diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py index f5e61c86343..4e13c978fe5 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py @@ -1,8 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", - "apiLevel": "2.16", + "protocolName": "QA Protocol - Analysis Error - Module In Staging Area Column 3", "author": "Derek Maggio ", } @@ -11,21 +10,18 @@ "apiLevel": "2.16", } -THERMOCYCLER_NAME = "thermocycler module gen2" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -TEMPERATURE_MODULE_NAME = "temperature module gen2" - -USING_GRIPPER = True - - def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, "B4") - temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B3") + ctx.load_waste_chute() + ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area + tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A1", adapter="opentrons_flex_96_tiprack_adapter") + temp_module = ctx.load_module("temperature module gen2", "C3") + temp_module.deactivate() + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) + pipette_96_channel.pick_up_tip() + pipette_96_channel.drop_tip() + + diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py index 727b5343004..b78ddc50378 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py @@ -1,8 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Invalid Deck Configuration 1 - Module In Staging Area Column 4", - "apiLevel": "2.16", + "protocolName": "QA Protocol - Analysis Error - Module In Staging Area Column 4", "author": "Derek Maggio ", } @@ -11,20 +10,10 @@ "apiLevel": "2.16", } -THERMOCYCLER_NAME = "thermocycler module gen2" -MAGNETIC_BLOCK_NAME = "magneticBlockV1" -PCR_PLATE_96_NAME = "nest_96_wellplate_100ul_pcr_full_skirt" -TIPRACK_96_NAME = "opentrons_flex_96_tiprack_1000ul" -HEATER_SHAKER_NAME = "heaterShakerModuleV1" -TEMPERATURE_MODULE_NAME = "temperature module gen2" - -USING_GRIPPER = True - - def run(ctx: protocol_api.ProtocolContext) -> None: ################ ### FIXTURES ### ################ - temperature_module = ctx.load_module(TEMPERATURE_MODULE_NAME, "B4") + ctx.load_module("temperature module gen2", "B4") From 7ee381248531ac7b35050a378105c698bf892ba6 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Tue, 12 Dec 2023 13:11:16 -0800 Subject: [PATCH 14/30] chore: copy and pasted wrong --- app-testing/automation/data/protocol_files.py | 2 +- app-testing/automation/data/protocols.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app-testing/automation/data/protocol_files.py b/app-testing/automation/data/protocol_files.py index 260620f1f29..2de8e2e936c 100644 --- a/app-testing/automation/data/protocol_files.py +++ b/app-testing/automation/data/protocol_files.py @@ -41,5 +41,5 @@ "OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", - "OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash" + "OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash" ] diff --git a/app-testing/automation/data/protocols.py b/app-testing/automation/data/protocols.py index d746634396a..197f12f8d11 100644 --- a/app-testing/automation/data/protocols.py +++ b/app-testing/automation/data/protocols.py @@ -360,10 +360,10 @@ class Protocols: app_analysis_error="ValueError [line 19]: Staging areas not permitted for trash bin.", # noqa: E501 ) - OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( - file_name="OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash", + OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( + file_name="OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash", file_extension="py", - protocol_name="QA Protocol - Analysis Error - Drop Tips With No Trash", + protocol_name="QA Protocol - Analysis Error - Drop Tips with no Trash", robot="OT-3", app_error=True, robot_error=False, From bba59da2cd42a72c28e62e43c2bf99eb00e5eec1 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Wed, 13 Dec 2023 08:16:55 -0800 Subject: [PATCH 15/30] test: add more failure cases --- app-testing/Makefile | 4 +++ app-testing/automation/data/protocol_files.py | 25 +++++++------ app-testing/automation/data/protocols.py | 36 +++++++++++++++++-- ...2_16_AnalysisError_DropTipsWithNoTrash.py} | 1 - ...alysisError_ModuleAndWasteChuteConflict.py | 25 +++++++++++++ ...6_AnalysisError_ModuleInStagingAreaCol3.py | 5 +-- 6 files changed, 77 insertions(+), 19 deletions(-) rename app-testing/files/protocols/py/{OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py => OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py} (93%) create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py diff --git a/app-testing/Makefile b/app-testing/Makefile index f9c3770b66a..d037804ed74 100644 --- a/app-testing/Makefile +++ b/app-testing/Makefile @@ -34,6 +34,10 @@ format: test-ci: pipenv run python -m pytest -m "emulated_alpha" +.PHONY: test-protocol-analysis +test-protocol-analysis: + pipenv run python -m pytest tests/protocol_analyze_test.py + .PHONY: setup setup: pipenv install diff --git a/app-testing/automation/data/protocol_files.py b/app-testing/automation/data/protocol_files.py index 2de8e2e936c..8789aa06529 100644 --- a/app-testing/automation/data/protocol_files.py +++ b/app-testing/automation/data/protocol_files.py @@ -2,7 +2,11 @@ from typing import Literal names = Literal[ + "OT2_None_None_2_12_Python310SyntaxRobotAnalysisOnlyError", + "OT2_None_None_2_13_PythonSyntaxError", "OT2_P1000SLeft_None_6_1_SimpleTransfer", + "OT2_P10S_P300M_TC1_TM_MM_2_11_Swift", + "OT2_P20S_None_2_7_Walkthrough", "OT2_P20S_P300M_HS_6_1_HS_WithCollision_Error", "OT2_P20S_P300M_NoMods_6_1_TransferReTransferLiquid", "OT2_P20SRight_None_6_1_SimpleTransferError", @@ -11,23 +15,26 @@ "OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40", "OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40Error", "OT2_P300M_P20S_NoMod_6_1_MixTransferManyLiquids", - "OT2_P300M_P300S_HS_6_1_HS_NormalUseWithTransfer", - "OT2_P300SG1_None_5_2_6_Gen1PipetteSimple", - "OT2_P300SLeft_MM_TM_TM_5_2_6_MOAMTemps", - "OT2_None_None_2_12_Python310SyntaxRobotAnalysisOnlyError", - "OT2_None_None_2_13_PythonSyntaxError", - "OT2_P10S_P300M_TC1_TM_MM_2_11_Swift", - "OT2_P20S_None_2_7_Walkthrough", "OT2_P300M_P20S_None_2_12_FailOnRun", "OT2_P300M_P20S_TC_HS_TM_2_13_SmokeTestV3", "OT2_P300M_P20S_TC_HS_TM_2_14_SmokeTestV3", "OT2_P300M_P20S_TC_HS_TM_2_15_SmokeTestV3", "OT2_P300M_P20S_TC_MM_TM_2_13_Smoke620Release", + "OT2_P300M_P300S_HS_6_1_HS_NormalUseWithTransfer", "OT2_P300MLeft_MM_TM_2_4_Zymo", "OT2_P300S_Thermocycler_Moam_Error", "OT2_P300S_Twinning_Error", + "OT2_P300SG1_None_5_2_6_Gen1PipetteSimple", + "OT2_P300SLeft_MM_TM_TM_5_2_6_MOAMTemps", "OT2_P300SLeft_MM1_MM_2_2_EngageMagHeightFromBase", "OT2_P300SLeft_MM1_MM_TM_2_3_Mix", + "OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", + "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", + "OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash", + "OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3", + "OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4", + "OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict", "OT3_P100_96_HS_TM_2_15_Quick_Zymo_RNA_Bacteria", "OT3_P1000_96_HS_TM_MM_2_15_ABR5_6_HDQ_Bacteria_ParkTips_96_channel", "OT3_P1000_96_HS_TM_MM_2_15_MagMaxRNACells96Ch", @@ -38,8 +45,4 @@ "OT3_P1000MLeft_P50MRight_HS_TM_MM_TC_2_15_ABR4_Illumina_DNA_Prep_24x", "OT3_P1000SRight_None_2_15_ABR_Simple_Normalize_Long_Right", "OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2", - "OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", - "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", - "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", - "OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash" ] diff --git a/app-testing/automation/data/protocols.py b/app-testing/automation/data/protocols.py index 197f12f8d11..0dd19c8e7c6 100644 --- a/app-testing/automation/data/protocols.py +++ b/app-testing/automation/data/protocols.py @@ -360,12 +360,42 @@ class Protocols: app_analysis_error="ValueError [line 19]: Staging areas not permitted for trash bin.", # noqa: E501 ) - OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( - file_name="OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash", + OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash", file_extension="py", protocol_name="QA Protocol - Analysis Error - Drop Tips with no Trash", robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="NoTrashDefinedError [line 24]: Error 4000 GENERAL_ERROR (NoTrashDefinedError): No trash container has been defined in this protocol.", # noqa: E501 + app_analysis_error="NoTrashDefinedError [line 23]: Error 4000 GENERAL_ERROR (NoTrashDefinedError): No trash container has been defined in this protocol.", # noqa: E501 + ) + + OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3: Protocol = Protocol( + file_name="OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Module In Staging Area Column 3", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="InvalidModuleError [line 19]: Error 4000 GENERAL_ERROR (InvalidModuleError): Cannot use temperature module in C3, not compatible with one or more of the following fixtures: Slot C4", # noqa: E501 + ) + + OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4: Protocol = Protocol( + file_name="OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Module In Staging Area Column 4", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ValueError [line 19]: Cannot load a module onto a staging slot.", # noqa: E501 + ) + + OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Module and Waste Chute Conflict", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="InvalidModuleError [line 18]: Error 4000 GENERAL_ERROR (InvalidModuleError): Cannot use temperature module in C4, not compatible with one or more of the following fixtures: Waste Chute", # noqa: E501 ) diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py similarity index 93% rename from app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py rename to app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py index 51a074db195..7bfd422daba 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_DropTipsWithNoTrash.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py @@ -18,7 +18,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "D3", adapter="opentrons_flex_96_tiprack_adapter") - ctx.load_module("temperature module gen2", "C3") pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) pipette_96_channel.pick_up_tip() pipette_96_channel.drop_tip() diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py new file mode 100644 index 00000000000..cfad5843d3a --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py @@ -0,0 +1,25 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Module and Waste Chute Conflict", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +def run(ctx: protocol_api.ProtocolContext) -> None: + + ctx.load_waste_chute() + + tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A1", adapter="opentrons_flex_96_tiprack_adapter") + + temp_module = ctx.load_module("temperature module gen2", "D3") + temp_module.deactivate() + + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) + pipette_96_channel.pick_up_tip() + pipette_96_channel.drop_tip() + \ No newline at end of file diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py index 4e13c978fe5..a2391f6f340 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py @@ -17,11 +17,8 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ################ ctx.load_waste_chute() ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area - tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A1", adapter="opentrons_flex_96_tiprack_adapter") temp_module = ctx.load_module("temperature module gen2", "C3") temp_module.deactivate() - pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) - pipette_96_channel.pick_up_tip() - pipette_96_channel.drop_tip() + From 695ebc7cabaf50534b82ccd9fb844aedb8a53f14 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 14 Dec 2023 15:04:26 -0800 Subject: [PATCH 16/30] chore: include used protocol --- ...C_HS_TM_2_16_aspirateDispenseMix0Volume.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py diff --git a/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py b/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py new file mode 100644 index 00000000000..a41bf53872d --- /dev/null +++ b/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py @@ -0,0 +1,73 @@ +"""Smoke Test v3.0 """ +from opentrons import protocol_api + +metadata = { + "protocolName": "API 2.16 Aspirate Dispense Mix 0 Volume", + "author": "Opentrons Engineering ", + "source": "Software Testing Team", +} + +requirements = {"robotType": "OT-2", "apiLevel": "2.16"} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + """This method is run by the protocol engine.""" + + ctx.set_rail_lights(True) + + # deck positions + tips_300ul_position = "5" + tips_20ul_position = "4" + dye_source_position = "3" + logo_position = "2" + + # 300ul tips + tips_300ul = [ + ctx.load_labware( + load_name="opentrons_96_tiprack_300ul", + location=tips_300ul_position, + label="300ul tips", + ) + ] + + # 20ul tips + tips_20ul = [ + ctx.load_labware( + load_name="opentrons_96_tiprack_20ul", + location=tips_20ul_position, + label="20ul tips", + ) + ] + + # pipettes + ctx.load_instrument(instrument_name="p300_multi_gen2", mount="left", tip_racks=tips_300ul) + + pipette_right = ctx.load_instrument(instrument_name="p20_single_gen2", mount="right", tip_racks=tips_20ul) + + dye_container = ctx.load_labware( + load_name="nest_12_reservoir_15ml", + location=dye_source_position, + label="dye container", + ) + + + # >= 2.14 define_liquid and load_liquid + water = ctx.define_liquid( + name="water", description="H₂O", display_color="#42AB2D" + ) # subscript 2 https://www.compart.com/en/unicode/U+2082 + + dye_container.wells_by_name()["A1"].load_liquid(liquid=water, volume=20) + + pipette_right.pick_up_tip() + + # >= 2.15: Aspirate everything, then dispense everything + # < 2.15: Aspirate nothing, then dispense everything(Which in this case means nothing) + # pipette_right.aspirate(volume=0, location=dye_container.wells_by_name()["A1"]) + # pipette_right.dispense(location=dye_container.wells_by_name()["A1"]) + + # >= 2.15: Aspirate everything, dispense everything, mix everything + # < 2.15: Aspirate everything, dispense nothing, mix nothing + pipette_right.aspirate(volume=20, location=dye_container.wells_by_name()["A1"]) + pipette_right.dispense(volume=0, location=dye_container.wells_by_name()["A1"]) + pipette_right.mix(volume=0, location=dye_container.wells_by_name()["A1"]) + \ No newline at end of file From c3c7e70c5d17b5a13debdea0b03d82abe98cbd15 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Fri, 15 Dec 2023 08:57:41 -0800 Subject: [PATCH 17/30] fix: still close out error popout if assertion error --- app-testing/tests/protocol_analyze_test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app-testing/tests/protocol_analyze_test.py b/app-testing/tests/protocol_analyze_test.py index f513820e07c..3172344232d 100644 --- a/app-testing/tests/protocol_analyze_test.py +++ b/app-testing/tests/protocol_analyze_test.py @@ -80,8 +80,12 @@ def test_analyses( assert error_link is not None, "No analysis error but was expecting one." protocol_landing.base.click_webelement(error_link) error_details = protocol_landing.get_popout_error().text - assert error_details == protocol.app_analysis_error - protocol_landing.click_popout_close() + try: + assert error_details == protocol.app_analysis_error + except AssertionError: + raise + finally: + protocol_landing.click_popout_close() else: error_link = protocol_landing.get_error_details_safe() From 6ae10dffa29b8c964e1f97d90e44621908377828 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Fri, 15 Dec 2023 13:18:20 -0800 Subject: [PATCH 18/30] chore: Add 2.16 Smoke --- ...T2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py | 356 ++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py diff --git a/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py b/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py new file mode 100644 index 00000000000..11c7933ddb7 --- /dev/null +++ b/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py @@ -0,0 +1,356 @@ +"""Smoke Test v3.0 """ +# https://opentrons.atlassian.net/projects/RQA?selectedItem=com.atlassian.plugins.atlassian-connect-plugin:com.kanoah.test-manager__main-project-page#!/testCase/QB-T497 +from opentrons import protocol_api + +metadata = { + "protocolName": "🛠️ 2.16 Smoke Test V3 🪄", + "author": "Opentrons Engineering ", + "source": "Software Testing Team", + "description": ("Description of the protocol that is longish \n has \n returns and \n emoji 😊 ⬆️ "), +} + +requirements = {"robotType": "OT-2", "apiLevel": "2.16"} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + """This method is run by the protocol engine.""" + + ctx.set_rail_lights(True) + ctx.comment(f"Let there be light! {ctx.rail_lights_on} 🌠🌠🌠") + ctx.comment(f"Is the door is closed? {ctx.door_closed} 🚪🚪🚪") + ctx.comment(f"Is this a simulation? {ctx.is_simulating()} 🔮🔮🔮") + ctx.comment(f"Running against API Version: {ctx.api_version}") + + # deck positions + tips_300ul_position = "5" + tips_20ul_position = "4" + dye_source_position = "3" + logo_position = "2" + temperature_position = "9" + custom_lw_position = "6" + hs_position = "1" + + # Thermocycler has a default position that covers Slots 7, 8, 10, and 11. + # This is the only valid location for the Thermocycler on the OT-2 deck. + # This position is a default parameter when declaring the TC so you do not need to specify. + + # 300ul tips + tips_300ul = [ + ctx.load_labware( + load_name="opentrons_96_tiprack_300ul", + location=tips_300ul_position, + label="300ul tips", + ) + ] + + # 20ul tips + tips_20ul = [ + ctx.load_labware( + load_name="opentrons_96_tiprack_20ul", + location=tips_20ul_position, + label="20ul tips", + ) + ] + + # pipettes + pipette_left = ctx.load_instrument(instrument_name="p300_multi_gen2", mount="left", tip_racks=tips_300ul) + + pipette_right = ctx.load_instrument(instrument_name="p20_single_gen2", mount="right", tip_racks=tips_20ul) + + # modules https://docs.opentrons.com/v2/new_modules.html#available-modules + hs_module = ctx.load_module("heaterShakerModuleV1", hs_position) + temperature_module = ctx.load_module("temperature module gen2", temperature_position) + thermocycler_module = ctx.load_module("thermocycler module gen2") + + # module labware + temp_adapter = temperature_module.load_adapter("opentrons_96_well_aluminum_block") + temp_plate = temp_adapter.load_labware( + "nest_96_wellplate_100ul_pcr_full_skirt", + label="Temperature-Controlled plate", + ) + hs_plate = hs_module.load_labware(name="nest_96_wellplate_100ul_pcr_full_skirt", adapter="opentrons_96_pcr_adapter") + tc_plate = thermocycler_module.load_labware("nest_96_wellplate_100ul_pcr_full_skirt") + + # A 2.14 difference, no params specified, still should find it. + custom_labware = ctx.load_labware( + "cpx_4_tuberack_100ul", + custom_lw_position, + label="4 custom tubes", + ) + + # create plates and pattern list + logo_destination_plate = ctx.load_labware( + load_name="nest_96_wellplate_100ul_pcr_full_skirt", + location=logo_position, + label="logo destination", + ) + + dye_container = ctx.load_labware( + load_name="nest_12_reservoir_15ml", + location=dye_source_position, + label="dye container", + ) + + dye_source = dye_container.wells_by_name()["A2"] + + # Well Location set-up + dye_destination_wells = [ + logo_destination_plate.wells_by_name()["C7"], + logo_destination_plate.wells_by_name()["D6"], + logo_destination_plate.wells_by_name()["D7"], + logo_destination_plate.wells_by_name()["D8"], + logo_destination_plate.wells_by_name()["E5"], + ] + + # >= 2.14 define_liquid and load_liquid + water = ctx.define_liquid( + name="water", description="H₂O", display_color="#42AB2D" + ) # subscript 2 https://www.compart.com/en/unicode/U+2082 + + acetone = ctx.define_liquid( + name="acetone", description="C₃H₆O", display_color="#38588a" + ) # subscript 3 https://www.compart.com/en/unicode/U+2083 + # subscript 6 https://www.compart.com/en/unicode/U+2086 + + dye_container.wells_by_name()["A1"].load_liquid(liquid=water, volume=4000) + dye_container.wells_by_name()["A2"].load_liquid(liquid=water, volume=2000) + dye_container.wells_by_name()["A5"].load_liquid(liquid=acetone, volume=555.55555) + + # 2 different liquids in the same well + dye_container.wells_by_name()["A8"].load_liquid(liquid=water, volume=900.00) + dye_container.wells_by_name()["A8"].load_liquid(liquid=acetone, volume=1001.11) + + hs_module.close_labware_latch() + + pipette_right.pick_up_tip() + + ################################## + # Manual Deck State Modification # + ################################## + + # -------------------------- # + # Added in API version: 2.15 # + # -------------------------- # + + # Putting steps for this at beginning of protocol so you can do the manual stuff + # then walk away to let the rest of the protocol execute + + # The test flow is as follows: + # 1. Remove the existing PCR plate from slot 2 + # 2. Move the reservoir from slot 3 to slot 2 + # 3. Pickup P20 tip, move pipette to reservoir A1 in slot 2 + # 4. Pause and ask user to validate that the tip is in the middle of reservoir A1 in slot 2 + # 5. Move the reservoir back to slot 3 from slot 2 + # 6. Move pipette to reservoir A1 in slot 3 + # 7. Pause and ask user to validate that the tip is in the middle of reservoir A1 in slot 3 + # 8. Move custom labware from slot 6 to slot 2 + # 9. Move pipette to well A1 in slot 2 + # 10. Pause and ask user to validate that the tip is in the middle of well A1 in slot 2 + # 11. Move the custom labware back to slot 6 from slot 2 + # 12. Move pipette to well A1 in slot 6 + # 13. Pause and ask user to validate that the tip is in the middle of well A1 in slot 6 + # 14. Move the offdeck PCR plate back to slot 2 + # 15. Move pipette to well A1 in slot 2 + # 16. Pause and ask user to validate that the tip is in the middle of well A1 in slot 2 + + # In effect, nothing will actually change to the protocol, + # but we will be able to test that the UI responds appropriately. + + # Note: + # logo_destination_plate is a nest_96_wellplate_100ul_pcr_full_skirt - starting position is slot 2 + # dye_container is a nest_12_reservoir_15ml - starting position is slot 3 + + # Step 1 + ctx.move_labware( + labware=logo_destination_plate, + new_location=protocol_api.OFF_DECK, + ) + + # Step 2 + ctx.move_labware(labware=dye_container, new_location="2") + + # Step 3 + pipette_right.move_to(location=dye_container.wells_by_name()["A1"].top()) + + # Step 4 + ctx.pause("Is the pipette tip in the middle of reservoir A1 in slot 2?") + + # Step 5 + ctx.move_labware(labware=dye_container, new_location="3") + + # Step 6 + pipette_right.move_to(location=dye_container.wells_by_name()["A1"].top()) + + # Step 7 + ctx.pause("Is the pipette tip in the middle of reservoir A1 in slot 3?") + + # Step 8 + ctx.move_labware(labware=custom_labware, new_location="2") + + # Step 9 + pipette_right.move_to(location=custom_labware.wells_by_name()["A1"].top()) + + # Step 10 + ctx.pause("Is the pipette tip in the middle of custom labware A1 in slot 2?") + + # Step 11 + ctx.move_labware(labware=custom_labware, new_location="6") + + # Step 12 + pipette_right.move_to(location=custom_labware.wells_by_name()["A1"].top()) + + # Step 13 + ctx.pause("Is the pipette tip in the middle of custom labware A1 in slot 6?") + + # Step 14 + ctx.move_labware(labware=logo_destination_plate, new_location="2") + + # Step 15 + pipette_right.move_to(location=logo_destination_plate.wells_by_name()["A1"].top()) + + # Step 16 + ctx.pause("Is the pipette tip in the middle of well A1 in slot 2?") + + ####################### + # prepare_to_aspirate # + ####################### + + # -------------------------- # + # Added in API version: 2.16 # + # -------------------------- # + + pipette_right.prepare_to_aspirate() + pipette_right.move_to(dye_container.wells_by_name()["A1"].bottom(z=2)) + ctx.pause("Testing prepare_to_aspirate - watch pipette until next pause.\n The pipette should only move up out of the well after it has aspirated.") + pipette_right.aspirate(10, dye_container.wells_by_name()["A1"].bottom(z=2)) + ctx.pause("Did the pipette move up out of the well, only once, after aspirating?") + pipette_right.dispense(10, dye_container.wells_by_name()["A1"].bottom(z=2)) + + ######################################### + # protocol_context.fixed_trash property # + ######################################### + + # ---------------------------- # + # Changed in API version: 2.16 # + # ---------------------------- # + + pipette_right.move_to(ctx.fixed_trash) + ctx.pause("Is the pipette over the trash? Pipette will home after this pause.") + ctx.home() + + ############################################### + # instrument_context.trash_container property # + ############################################### + + # ---------------------------- # + # Changed in API version: 2.16 # + # ---------------------------- # + + pipette_right.move_to(pipette_right.trash_container) + ctx.pause("Is the pipette over the trash?") + + # Distribute dye + pipette_right.distribute( + volume=18, + source=dye_source, + dest=dye_destination_wells, + new_tip="never", + ) + pipette_right.drop_tip() + + # transfer + transfer_destinations = [ + logo_destination_plate.wells_by_name()["A11"], + logo_destination_plate.wells_by_name()["B11"], + logo_destination_plate.wells_by_name()["C11"], + ] + pipette_right.pick_up_tip() + pipette_right.transfer( + volume=60, + source=dye_container.wells_by_name()["A2"], + dest=transfer_destinations, + new_tip="never", + touch_tip=True, + blow_out=True, + blowout_location="destination well", + mix_before=(3, 20), + mix_after=(1, 20), + mix_touch_tip=True, + ) + + # consolidate + pipette_right.consolidate( + volume=20, + source=transfer_destinations, + dest=dye_container.wells_by_name()["A5"], + new_tip="never", + touch_tip=False, + blow_out=True, + blowout_location="destination well", + mix_before=(3, 20), + ) + + # well to well + pipette_right.return_tip() + pipette_right.pick_up_tip() + pipette_right.aspirate(volume=5, location=logo_destination_plate.wells_by_name()["A11"]) + pipette_right.air_gap(volume=10) + ctx.delay(seconds=3) + pipette_right.dispense(volume=5, location=logo_destination_plate.wells_by_name()["H11"]) + + # move to + pipette_right.move_to(logo_destination_plate.wells_by_name()["E12"].top()) + pipette_right.move_to(logo_destination_plate.wells_by_name()["E11"].bottom()) + pipette_right.blow_out() + # touch tip + # pipette ends in the middle of the well as of 6.3.0 in all touch_tip + pipette_right.touch_tip(location=logo_destination_plate.wells_by_name()["H1"]) + ctx.pause("Is the pipette tip in the middle of the well?") + pipette_right.return_tip() + + # Play with the modules + temperature_module.await_temperature(25) + + hs_module.set_and_wait_for_shake_speed(466) + ctx.delay(seconds=5) + + hs_module.set_and_wait_for_temperature(38) + + thermocycler_module.open_lid() + thermocycler_module.close_lid() + thermocycler_module.set_lid_temperature(38) # 37 is the minimum + thermocycler_module.set_block_temperature(temperature=28, hold_time_seconds=5) + thermocycler_module.deactivate_block() + thermocycler_module.deactivate_lid() + thermocycler_module.open_lid() + + hs_module.deactivate_shaker() + + # dispense to modules + + # to temperature module + pipette_right.pick_up_tip() + pipette_right.aspirate(volume=15, location=dye_source) + pipette_right.dispense(volume=15, location=temp_plate.well(0)) + pipette_right.drop_tip() + + # to heater shaker + pipette_left.pick_up_tip() + pipette_left.aspirate(volume=50, location=dye_source) + pipette_left.dispense(volume=50, location=hs_plate.well(0)) + hs_module.set_and_wait_for_shake_speed(350) + ctx.delay(seconds=5) + hs_module.deactivate_shaker() + + # to custom labware + # This labware does not EXIST!!!! so... + # Use tip rack lid to catch dye on wet run + pipette_right.pick_up_tip() + pipette_right.aspirate(volume=10, location=dye_source, rate=2.0) + pipette_right.dispense(volume=10, location=custom_labware.well(3), rate=1.5) + pipette_right.drop_tip() + + # to thermocycler + pipette_left.aspirate(volume=75, location=dye_source) + pipette_left.dispense(volume=60, location=tc_plate.wells_by_name()["A6"]) + pipette_left.drop_tip() From 5a93af9f517e62447352cb5fb786f332080cff5f Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Mon, 18 Dec 2023 07:03:06 -0800 Subject: [PATCH 19/30] chore: Add more failure cases --- app-testing/automation/data/protocol_files.py | 8 +++-- app-testing/automation/data/protocols.py | 34 +++++++++++++++---- ...16_AnalysisError_AccessToFixedTrashProp.py | 16 +++++++++ ..._AnalysisError_OT2PipetteInFlexProtocol.py | 25 ++++++++++++++ ...2_16_AnalysisError_DropTipsWithNoTrash.py} | 0 ...6_AnalysisError_DropLabwareIntoTrashBin.py | 21 ++++++++++++ ...nalysisError_TrashBinInStagingAreaCol3.py} | 0 ...lysisError_ModuleAndWasteChuteConflict.py} | 0 app-testing/tests/protocol_analyze_test.py | 12 +++++-- 9 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py rename app-testing/files/protocols/py/{OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py => OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py} (100%) create mode 100644 app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py rename app-testing/files/protocols/py/{OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py => OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py} (100%) rename app-testing/files/protocols/py/{OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py => OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py} (100%) diff --git a/app-testing/automation/data/protocol_files.py b/app-testing/automation/data/protocol_files.py index 8789aa06529..f3d33826604 100644 --- a/app-testing/automation/data/protocol_files.py +++ b/app-testing/automation/data/protocol_files.py @@ -28,13 +28,14 @@ "OT2_P300SLeft_MM_TM_TM_5_2_6_MOAMTemps", "OT2_P300SLeft_MM1_MM_2_2_EngageMagHeightFromBase", "OT2_P300SLeft_MM1_MM_TM_2_3_Mix", + "OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp", "OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", - "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + "OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", - "OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash", + "OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash", "OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3", "OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4", - "OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict", + "OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict", "OT3_P100_96_HS_TM_2_15_Quick_Zymo_RNA_Bacteria", "OT3_P1000_96_HS_TM_MM_2_15_ABR5_6_HDQ_Bacteria_ParkTips_96_channel", "OT3_P1000_96_HS_TM_MM_2_15_MagMaxRNACells96Ch", @@ -45,4 +46,5 @@ "OT3_P1000MLeft_P50MRight_HS_TM_MM_TC_2_15_ABR4_Illumina_DNA_Prep_24x", "OT3_P1000SRight_None_2_15_ABR_Simple_Normalize_Long_Right", "OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2", + "OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin" ] diff --git a/app-testing/automation/data/protocols.py b/app-testing/automation/data/protocols.py index 0dd19c8e7c6..ed528607213 100644 --- a/app-testing/automation/data/protocols.py +++ b/app-testing/automation/data/protocols.py @@ -340,8 +340,8 @@ class Protocols: app_analysis_error="InvalidTrashBinLocationError [line 15]: Invalid location for trash bin: C2. Valid slots: Any slot in column 1 or 3.", # noqa: E501 ) - OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3: Protocol = Protocol( - file_name="OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3: Protocol = Protocol( + file_name="OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", file_extension="py", protocol_name="QA Protocol - Analysis Error - Trash Bin Staging Area Column 3", robot="OT-3", @@ -360,8 +360,8 @@ class Protocols: app_analysis_error="ValueError [line 19]: Staging areas not permitted for trash bin.", # noqa: E501 ) - OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( - file_name="OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash", + OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( + file_name="OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash", file_extension="py", protocol_name="QA Protocol - Analysis Error - Drop Tips with no Trash", robot="OT-3", @@ -390,12 +390,32 @@ class Protocols: app_analysis_error="ValueError [line 19]: Cannot load a module onto a staging slot.", # noqa: E501 ) - OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict: Protocol = Protocol( - file_name="OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict", + OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict: Protocol = Protocol( + file_name="OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict", file_extension="py", protocol_name="QA Protocol - Analysis Error - Module and Waste Chute Conflict", robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="InvalidModuleError [line 18]: Error 4000 GENERAL_ERROR (InvalidModuleError): Cannot use temperature module in C4, not compatible with one or more of the following fixtures: Waste Chute", # noqa: E501 + app_analysis_error="ProtocolCommandFailedError [line 24]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Waste Chute, not compatible with one or more of the following fixtures: Slot D3", # noqa: E501 + ) + + OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Access to Fixed Trash Property", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="APIVersionError [line 15]: Fixed Trash is not supported on Flex protocols in API Version 2.16 and above.", # noqa: E501 + ) + + OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin: Protocol = Protocol( + file_name="OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Drop Labware in Trash Bin", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ProtocolCommandFailedError [line 19]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Slot C3, not compatible with one or more of the following fixtures: Trash Bin in C3", # noqa: E501 ) diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py new file mode 100644 index 00000000000..556407453f5 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py @@ -0,0 +1,16 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Access to Fixed Trash Property", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + ctx.fixed_trash + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py new file mode 100644 index 00000000000..32e91fb0fa9 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py @@ -0,0 +1,25 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Access to Fixed Trash Property", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + tips_300ul = [ + ctx.load_labware( + load_name="opentrons_96_tiprack_300ul", + location="A1", + label="300ul tips", + ) + ] + pipette_left = ctx.load_instrument(instrument_name="p300_multi_gen2", mount="left", tip_racks=tips_300ul) + pipette_left.pick_up_tip() + + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py b/app-testing/files/protocols/py/OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py similarity index 100% rename from app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_DropTipsWithNoTrash.py rename to app-testing/files/protocols/py/OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py new file mode 100644 index 00000000000..d35967f2b0a --- /dev/null +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py @@ -0,0 +1,21 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Drop Labware in Trash Bin", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + +def run(ctx: protocol_api.ProtocolContext) -> None: + trash_bin = ctx.load_trash_bin("C3") + tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A1", adapter="opentrons_flex_96_tiprack_adapter") + pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) + pipette_96_channel.pick_up_tip() + pipette_96_channel.drop_tip(trash_bin) + ctx.move_labware(tip_rack, "C3", use_gripper=True) + + diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py similarity index 100% rename from app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py rename to app-testing/files/protocols/py/OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py b/app-testing/files/protocols/py/OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py similarity index 100% rename from app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_ModuleAndWasteChuteConflict.py rename to app-testing/files/protocols/py/OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py diff --git a/app-testing/tests/protocol_analyze_test.py b/app-testing/tests/protocol_analyze_test.py index 3172344232d..4ce64c2d646 100644 --- a/app-testing/tests/protocol_analyze_test.py +++ b/app-testing/tests/protocol_analyze_test.py @@ -12,13 +12,19 @@ from selenium.webdriver.chrome.webdriver import WebDriver -def _what_protocols() -> list[(Protocol)]: +def _what_protocols() -> list[Protocol]: """Use the environment variable to select which protocols are used in the test.""" protocols: Protocols = Protocols() protocols_to_test: str = os.getenv("APP_ANALYSIS_TEST_PROTOCOLS", "upload_protocol") - tests: list[(Protocol)] = [] + tests: list[Protocol] = [] for protocol_name in [x.strip() for x in protocols_to_test.split(",")]: - tests.append((getattr(protocols, protocol_name))) + protocol = getattr(protocols, protocol_name) + tests.append( + pytest.param( + protocol, + id=protocol.protocol_name, + ) + ) return tests From 78349d5536280fe872ae8274e12aecc0b9ca2e3b Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Mon, 18 Dec 2023 07:31:23 -0800 Subject: [PATCH 20/30] chore: add air gap back in to smoke --- ...ol.py => OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py} | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename app-testing/files/protocols/py/{OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py => OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py} (99%) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py similarity index 99% rename from app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py rename to app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py index 62897449cdd..c6c5f72108d 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_MegaProtocol.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py @@ -93,6 +93,8 @@ def run(ctx: protocol_api.ProtocolContext) -> None: pipette_96_channel = ctx.load_instrument(PIPETTE_96_CHANNEL_NAME, mount="left", tip_racks=tip_racks) + assert isinstance(pipette_96_channel.trash_container, protocol_api.TrashBin) + ######################## ### LOAD SOME LIQUID ### ######################## @@ -305,8 +307,7 @@ def test_full_tip_rack_usage(): pipette_96_channel.aspirate(5, source_reservoir["A1"]) pipette_96_channel.touch_tip() - # Waiting for https://opentrons.atlassian.net/browse/RQA-2056 - # pipette_96_channel.air_gap(height=30) + pipette_96_channel.air_gap(height=30) pipette_96_channel.blow_out(waste_chute) @@ -378,6 +379,7 @@ def test_magnetic_block(): test_gripper_moves() test_module_usage() test_manual_moves() + ################################################################################################### ### THE ORDER OF THESE FUNCTION CALLS MATTER. CHANGING THEM WILL CAUSE THE PROTOCOL NOT TO WORK ### ################################################################################################### From 3a086649d919797a09d213c3e9a9ff5df02f1758 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Mon, 18 Dec 2023 07:33:05 -0800 Subject: [PATCH 21/30] chore: add blowout to trash bin --- .../py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py index c6c5f72108d..932fba22f31 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke.py @@ -311,6 +311,12 @@ def test_full_tip_rack_usage(): pipette_96_channel.blow_out(waste_chute) + pipette_96_channel.aspirate(5, source_reservoir["A1"]) + pipette_96_channel.touch_tip() + + pipette_96_channel.air_gap(height=30) + pipette_96_channel.blow_out(trash_bin) + pipette_96_channel.aspirate(10, source_reservoir["A1"]) pipette_96_channel.touch_tip() From ff3dd4575f9d66b7273744175ce16281fc7dda84 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:15:19 -0800 Subject: [PATCH 22/30] chore: add checking for extra protocols to print protocols script --- app-testing/print_protocols.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app-testing/print_protocols.py b/app-testing/print_protocols.py index c129fd0cb80..eb5bc7bc366 100644 --- a/app-testing/print_protocols.py +++ b/app-testing/print_protocols.py @@ -13,14 +13,17 @@ rich.print(Panel("What are actually defined?")) protocols = Protocols() props = [prop for prop in dir(protocols) if "__" not in prop] -rich.print(", ".join(props)) +rich.print(",\n".join(props)) possible = set(stems) actual = set(props) -out = possible - actual +missing_protocols = possible - actual +orphan_protocols = actual - possible rich.print(Panel("Are all protocols mapped?")) -if len(out) == 0: +if len(missing_protocols) == 0 and len(orphan_protocols) == 0: rich.print("🥳 everything is mapped.") else: - rich.print("The below protocols need mapped:") - rich.print(out) + rich.print("The below protocols need to be mapped in protocols.py:") + rich.print(missing_protocols) + rich.print("\nThe below protocols are mapped in protocols.py, but don't exist in the protocols dir:") + rich.print(orphan_protocols) From a101d10df9fc59f05bbfe132a662c1a3df66596b Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:18:52 -0800 Subject: [PATCH 23/30] feat: add support for expected test failure --- app-testing/automation/data/protocol.py | 2 ++ app-testing/tests/protocol_analyze_test.py | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app-testing/automation/data/protocol.py b/app-testing/automation/data/protocol.py index e8ef4db3bf6..7301b3aebe2 100644 --- a/app-testing/automation/data/protocol.py +++ b/app-testing/automation/data/protocol.py @@ -24,6 +24,8 @@ class Protocol(BaseModel): instruments: Optional[list[str]] = Field(description="list of instruments that will show in the app", default=None) modules: Optional[list[module_types]] = Field(description="list of modules that will show in the app", default=None) description: Optional[str] = Field(description="Details about this protocol", default=None) + expected_test_failure: bool = Field(description="Is this test expected to fail", default=False) + expected_test_reason: Optional[str] = Field(description="Reason test is failing", default=False) @property def file_path(self) -> Path: diff --git a/app-testing/tests/protocol_analyze_test.py b/app-testing/tests/protocol_analyze_test.py index 4ce64c2d646..5573ca98fdb 100644 --- a/app-testing/tests/protocol_analyze_test.py +++ b/app-testing/tests/protocol_analyze_test.py @@ -17,14 +17,23 @@ def _what_protocols() -> list[Protocol]: protocols: Protocols = Protocols() protocols_to_test: str = os.getenv("APP_ANALYSIS_TEST_PROTOCOLS", "upload_protocol") tests: list[Protocol] = [] - for protocol_name in [x.strip() for x in protocols_to_test.split(",")]: + for protocol_name in [x.strip() for x in protocols_to_test.split(",") if len(x.strip()) > 0]: protocol = getattr(protocols, protocol_name) tests.append( - pytest.param( - protocol, - id=protocol.protocol_name, - ) + # https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest-param + pytest.param( + protocol, + id=protocol.protocol_name, + # https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest-mark-xfail + marks=pytest.mark.xfail( + condition=protocol.expected_test_failure, + reason=protocol.expected_test_reason, + raises=AssertionError, + run=True, + strict=True, + ), ) + ) return tests @@ -98,6 +107,7 @@ def test_analyses( if error_link is not None: protocol_landing.base.click_webelement(error_link) error_details = protocol_landing.get_popout_error().text + protocol_landing.click_popout_close() raise AssertionError(f"Unexpected analysis error: {error_details}") # Verifying elements on Protocol Landing Page From 23e4af062517d821e98fd22660b937bfbe562c5d Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:35:55 -0800 Subject: [PATCH 24/30] chore: type ignore pytest.param weirdness --- app-testing/tests/protocol_analyze_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app-testing/tests/protocol_analyze_test.py b/app-testing/tests/protocol_analyze_test.py index 5573ca98fdb..53530e46579 100644 --- a/app-testing/tests/protocol_analyze_test.py +++ b/app-testing/tests/protocol_analyze_test.py @@ -21,7 +21,9 @@ def _what_protocols() -> list[Protocol]: protocol = getattr(protocols, protocol_name) tests.append( # https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest-param - pytest.param( + # pytest.param returns a special ParamterSet type. But when pytest runs + # the test, it will be a Protocol type. Don't feel like fighting mypy. + pytest.param( # type: ignore[arg-type] protocol, id=protocol.protocol_name, # https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest-mark-xfail From 68bf38cf0ee96ce1f484e840d34aeab359390016 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:36:27 -0800 Subject: [PATCH 25/30] chore: add protocol to test volume=0 in aspirate, mix, dispense methods --- ...M_P20S_2_16_aspirateDispenseMix0Volume.py} | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) rename app-testing/files/protocols/py/{OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py => OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume.py} (55%) diff --git a/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py b/app-testing/files/protocols/py/OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume.py similarity index 55% rename from app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py rename to app-testing/files/protocols/py/OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume.py index a41bf53872d..caa4233b1a2 100644 --- a/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_aspirateDispenseMix0Volume.py +++ b/app-testing/files/protocols/py/OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume.py @@ -2,7 +2,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "API 2.16 Aspirate Dispense Mix 0 Volume", + "protocolName": "QA Protocol - API 2.16 - Aspirate Dispense Mix with 0 Volume", "author": "Opentrons Engineering ", "source": "Software Testing Team", } @@ -10,6 +10,15 @@ requirements = {"robotType": "OT-2", "apiLevel": "2.16"} +def perform_check( + method_sig: str, + actual: float, + expected: float, +): + """Perform a check on the pipette's current volume.""" + assert actual == expected, f"pipette volume after {method_sig} is {actual} instead of {expected}" + + def run(ctx: protocol_api.ProtocolContext) -> None: """This method is run by the protocol engine.""" @@ -19,7 +28,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: tips_300ul_position = "5" tips_20ul_position = "4" dye_source_position = "3" - logo_position = "2" # 300ul tips tips_300ul = [ @@ -50,8 +58,6 @@ def run(ctx: protocol_api.ProtocolContext) -> None: label="dye container", ) - - # >= 2.14 define_liquid and load_liquid water = ctx.define_liquid( name="water", description="H₂O", display_color="#42AB2D" ) # subscript 2 https://www.compart.com/en/unicode/U+2082 @@ -59,15 +65,43 @@ def run(ctx: protocol_api.ProtocolContext) -> None: dye_container.wells_by_name()["A1"].load_liquid(liquid=water, volume=20) pipette_right.pick_up_tip() - - # >= 2.15: Aspirate everything, then dispense everything - # < 2.15: Aspirate nothing, then dispense everything(Which in this case means nothing) - # pipette_right.aspirate(volume=0, location=dye_container.wells_by_name()["A1"]) - # pipette_right.dispense(location=dye_container.wells_by_name()["A1"]) - - # >= 2.15: Aspirate everything, dispense everything, mix everything - # < 2.15: Aspirate everything, dispense nothing, mix nothing + + # Testing that volume=0 is a no-op + # In API versions previous to 2.16, volume=0 would use the pipette's entire volume + + # Aspirate nothing, then dispense everything (Which in this case means nothing) + pipette_right.aspirate(volume=0, location=dye_container.wells_by_name()["A1"]) + perform_check( + method_sig="aspirate(volume=0)", + actual=pipette_right.current_volume, + expected=0.0, + ) + + pipette_right.dispense(location=dye_container.wells_by_name()["A1"]) + perform_check( + method_sig="dispense(volume=0)", + actual=pipette_right.current_volume, + expected=0.0, + ) + + # Aspirate full pipette volume, dispense nothing, mix nothing pipette_right.aspirate(volume=20, location=dye_container.wells_by_name()["A1"]) + perform_check( + method_sig="aspirate(volume=20)", + actual=pipette_right.current_volume, + expected=20.0, + ) + pipette_right.dispense(volume=0, location=dye_container.wells_by_name()["A1"]) + perform_check( + method_sig="dispense(volume=0)", + actual=pipette_right.current_volume, + expected=20.0, + ) + pipette_right.mix(volume=0, location=dye_container.wells_by_name()["A1"]) - \ No newline at end of file + perform_check( + method_sig="mix(volume=0)", + actual=pipette_right.current_volume, + expected=20.0, + ) From de56f470fdabba24ec94077fd793a92f65fdd3a2 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:37:36 -0800 Subject: [PATCH 26/30] chore: minor protocol cleanup --- ...T2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py | 4 +++- ...16_AnalysisError_AccessToFixedTrashProp.py | 1 - ...None_2_16_AnalysisError_TrashBinInCol2.py} | 2 +- ...AnalysisError_TrashBinInStagingAreaCol3.py | 16 ++++++++++++++ ...AnalysisError_TrashBinInStagingAreaCol4.py | 8 ++----- ...6_AnalysisError_ModuleInStagingAreaCol3.py | 10 ++------- ...6_AnalysisError_ModuleInStagingAreaCol4.py | 8 ++----- ..._2_16_AnalysisError_DropTipsWithNoTrash.py | 3 +-- ...6_AnalysisError_DropLabwareIntoTrashBin.py | 3 +-- ...PER_HS_TM_TC_MB_2_16_DeckConfiguration1.py | 4 +++- ...C_MB_2_16_DeckConfiguration1_NoFixtures.py | 8 +++++-- ...TC_MB_2_16_DeckConfiguration1_NoModules.py | 8 +++++-- ..._DeckConfiguration1_NoModulesNoFixtures.py | 8 +++++-- ...AnalysisError_TrashBinInStagingAreaCol3.py | 22 ------------------- ...alysisError_ModuleAndWasteChuteConflict.py | 2 +- ...AnalysisError_OT2PipetteInFlexProtocol.py} | 4 +--- ...ght_None_2_15_ABRKAPALibraryQuantLongv2.py | 2 -- 17 files changed, 51 insertions(+), 62 deletions(-) rename app-testing/files/protocols/py/{OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py => OT3_None_None_2_16_AnalysisError_TrashBinInCol2.py} (76%) create mode 100644 app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py delete mode 100644 app-testing/files/protocols/py/OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py rename app-testing/files/protocols/py/{OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py => OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py} (85%) diff --git a/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py b/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py index 11c7933ddb7..b642a18e18f 100644 --- a/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py +++ b/app-testing/files/protocols/py/OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3.py @@ -221,7 +221,9 @@ def run(ctx: protocol_api.ProtocolContext) -> None: pipette_right.prepare_to_aspirate() pipette_right.move_to(dye_container.wells_by_name()["A1"].bottom(z=2)) - ctx.pause("Testing prepare_to_aspirate - watch pipette until next pause.\n The pipette should only move up out of the well after it has aspirated.") + ctx.pause( + "Testing prepare_to_aspirate - watch pipette until next pause.\n The pipette should only move up out of the well after it has aspirated." + ) pipette_right.aspirate(10, dye_container.wells_by_name()["A1"].bottom(z=2)) ctx.pause("Did the pipette move up out of the well, only once, after aspirating?") pipette_right.dispense(10, dye_container.wells_by_name()["A1"].bottom(z=2)) diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py index 556407453f5..35ebce46e97 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp.py @@ -13,4 +13,3 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ctx.fixed_trash - diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInCol2.py similarity index 76% rename from app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py rename to app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInCol2.py index 3ab076aaa59..70703b3f3f3 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInCol2.py @@ -1,7 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Analysis Error - Fixture Uses Middle Column", + "protocolName": "QA Protocol - Analysis Error - Trash Bin in Column 2", "author": "Derek Maggio ", } diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py new file mode 100644 index 00000000000..eb4cabec5a8 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py @@ -0,0 +1,16 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Trash Bin in Staging Area Column 3", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area + ctx.load_trash_bin("C3") diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py index 28d42124553..b1852ff672d 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py +++ b/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4.py @@ -1,7 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Analysis Error - Trash Bin Staging Area Column 4", + "protocolName": "QA Protocol - Analysis Error - Trash Bin in Staging Area Column 4", "author": "Derek Maggio ", } @@ -10,10 +10,6 @@ "apiLevel": "2.16", } -def run(ctx: protocol_api.ProtocolContext) -> None: - - ################ - ### FIXTURES ### - ################ +def run(ctx: protocol_api.ProtocolContext) -> None: ctx.load_trash_bin("C4") diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py index a2391f6f340..d45c4938b53 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3.py @@ -1,7 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Analysis Error - Module In Staging Area Column 3", + "protocolName": "QA Protocol - Analysis Error - Module in Staging Area Column 3", "author": "Derek Maggio ", } @@ -10,15 +10,9 @@ "apiLevel": "2.16", } -def run(ctx: protocol_api.ProtocolContext) -> None: - ################ - ### FIXTURES ### - ################ +def run(ctx: protocol_api.ProtocolContext) -> None: ctx.load_waste_chute() ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area temp_module = ctx.load_module("temperature module gen2", "C3") temp_module.deactivate() - - - diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py index b78ddc50378..eaaf8d1555e 100644 --- a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4.py @@ -1,7 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Analysis Error - Module In Staging Area Column 4", + "protocolName": "QA Protocol - Analysis Error - Module in Staging Area Column 4", "author": "Derek Maggio ", } @@ -10,10 +10,6 @@ "apiLevel": "2.16", } -def run(ctx: protocol_api.ProtocolContext) -> None: - - ################ - ### FIXTURES ### - ################ +def run(ctx: protocol_api.ProtocolContext) -> None: ctx.load_module("temperature module gen2", "B4") diff --git a/app-testing/files/protocols/py/OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py b/app-testing/files/protocols/py/OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py index 7bfd422daba..b05ceee8976 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash.py @@ -10,6 +10,7 @@ "apiLevel": "2.16", } + def run(ctx: protocol_api.ProtocolContext) -> None: ################ @@ -21,5 +22,3 @@ def run(ctx: protocol_api.ProtocolContext) -> None: pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) pipette_96_channel.pick_up_tip() pipette_96_channel.drop_tip() - - diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py index d35967f2b0a..35add4bee67 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin.py @@ -10,6 +10,7 @@ "apiLevel": "2.16", } + def run(ctx: protocol_api.ProtocolContext) -> None: trash_bin = ctx.load_trash_bin("C3") tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "A1", adapter="opentrons_flex_96_tiprack_adapter") @@ -17,5 +18,3 @@ def run(ctx: protocol_api.ProtocolContext) -> None: pipette_96_channel.pick_up_tip() pipette_96_channel.drop_tip(trash_bin) ctx.move_labware(tip_rack, "C3", use_gripper=True) - - diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py index a677697aa92..529f23becb6 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1.py @@ -60,7 +60,9 @@ def run(ctx: protocol_api.ProtocolContext) -> None: src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_1 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_1, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_1 = on_deck_tip_rack_1.parent on_deck_tip_rack_2 = ctx.load_labware( diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py index b8f7467bb21..80450b34cd7 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures.py @@ -51,10 +51,14 @@ def run(ctx: protocol_api.ProtocolContext) -> None: src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_1 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_1, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_1 = on_deck_tip_rack_1.parent - on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_2 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_2 = on_deck_tip_rack_2.parent off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py index ce70cb64c33..6b751f1d0e9 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules.py @@ -44,10 +44,14 @@ def run(ctx: protocol_api.ProtocolContext) -> None: src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_1 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_1, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_1 = on_deck_tip_rack_1.parent - on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_2 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_2 = on_deck_tip_rack_2.parent off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py index fe96b2e75a0..b809f034447 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures.py @@ -36,10 +36,14 @@ def run(ctx: protocol_api.ProtocolContext) -> None: src_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "B2") dest_pcr_plate = ctx.load_labware(PCR_PLATE_96_NAME, "C2") - on_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_1, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_1 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_1, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_1 = on_deck_tip_rack_1.parent - on_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, TIP_RACK_LOCATION_2, "opentrons_flex_96_tiprack_adapter") + on_deck_tip_rack_2 = ctx.load_labware( + TIPRACK_96_NAME, TIP_RACK_LOCATION_2, adapter="opentrons_flex_96_tiprack_adapter" + ) tip_rack_adapter_2 = on_deck_tip_rack_2.parent off_deck_tip_rack_1 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) off_deck_tip_rack_2 = ctx.load_labware(TIPRACK_96_NAME, protocol_api.OFF_DECK) diff --git a/app-testing/files/protocols/py/OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py b/app-testing/files/protocols/py/OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py deleted file mode 100644 index 122b2a0fc03..00000000000 --- a/app-testing/files/protocols/py/OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3.py +++ /dev/null @@ -1,22 +0,0 @@ -from opentrons import protocol_api - -metadata = { - "protocolName": "QA Protocol - Analysis Error - Trash Bin Staging Area Column 3", - "author": "Derek Maggio ", -} - -requirements = { - "robotType": "OT-3", - "apiLevel": "2.16", -} - - -def run(ctx: protocol_api.ProtocolContext) -> None: - - ctx.load_labware("nest_1_reservoir_290ml", "C4") # Implicitly define a Staging Area - tip_rack = ctx.load_labware("opentrons_flex_96_tiprack_1000ul", "D3", adapter="opentrons_flex_96_tiprack_adapter") - ctx.load_trash_bin("C3") - pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) - pipette_96_channel.pick_up_tip() - pipette_96_channel.drop_tip() - diff --git a/app-testing/files/protocols/py/OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py b/app-testing/files/protocols/py/OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py index cfad5843d3a..0c5fb7cd509 100644 --- a/app-testing/files/protocols/py/OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py +++ b/app-testing/files/protocols/py/OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict.py @@ -10,6 +10,7 @@ "apiLevel": "2.16", } + def run(ctx: protocol_api.ProtocolContext) -> None: ctx.load_waste_chute() @@ -22,4 +23,3 @@ def run(ctx: protocol_api.ProtocolContext) -> None: pipette_96_channel = ctx.load_instrument("flex_96channel_1000", mount="left", tip_racks=[tip_rack]) pipette_96_channel.pick_up_tip() pipette_96_channel.drop_tip() - \ No newline at end of file diff --git a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py b/app-testing/files/protocols/py/OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py similarity index 85% rename from app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py rename to app-testing/files/protocols/py/OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py index 32e91fb0fa9..fbe5b9cd652 100644 --- a/app-testing/files/protocols/py/OT3_None_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py +++ b/app-testing/files/protocols/py/OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol.py @@ -1,7 +1,7 @@ from opentrons import protocol_api metadata = { - "protocolName": "QA Protocol - Analysis Error - Access to Fixed Trash Property", + "protocolName": "QA Protocol - Analysis Error - OT-2 Pipette in Flex Protocol", "author": "Derek Maggio ", } @@ -21,5 +21,3 @@ def run(ctx: protocol_api.ProtocolContext) -> None: ] pipette_left = ctx.load_instrument(instrument_name="p300_multi_gen2", mount="left", tip_racks=tips_300ul) pipette_left.pick_up_tip() - - diff --git a/app-testing/files/protocols/py/OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2.py b/app-testing/files/protocols/py/OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2.py index 9f20f53101b..f22de72e0b0 100644 --- a/app-testing/files/protocols/py/OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2.py +++ b/app-testing/files/protocols/py/OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2.py @@ -1,7 +1,5 @@ from opentrons import protocol_api -from opentrons import types - import inspect metadata = { From c71723ac0926120078a55eb738fc7d63a2943414 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:38:12 -0800 Subject: [PATCH 27/30] test: Add new protocol tests also update names and spacing --- app-testing/automation/data/protocols.py | 158 +++++++++++++++++++++-- 1 file changed, 144 insertions(+), 14 deletions(-) diff --git a/app-testing/automation/data/protocols.py b/app-testing/automation/data/protocols.py index ed528607213..9e3894ff190 100644 --- a/app-testing/automation/data/protocols.py +++ b/app-testing/automation/data/protocols.py @@ -20,6 +20,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P20S_P300M_HS_6_1_HS_WithCollision_Error: Protocol = Protocol( file_name="OT2_P20S_P300M_HS_6_1_HS_WithCollision_Error", file_extension="json", @@ -29,6 +30,7 @@ class Protocols: robot_error=False, description="""This protocol gives an error in PD.8-Channel pipette cannot access labware8-Channel pipettes cannot access labware or tip racks to the left or right of a Heater-Shaker GEN1 module. Move labware to a different slot to access it with an 8-Channel pipette.If you export it anyway there are NOT analysis errors in the app side analysis.TODO on if there are robot side analysis errors but do not expect them?""", # noqa: E501 ) + OT2_P20S_P300M_NoMods_6_1_TransferReTransferLiquid: Protocol = Protocol( file_name="OT2_P20S_P300M_NoMods_6_1_TransferReTransferLiquid", file_extension="json", @@ -47,6 +49,7 @@ class Protocols: app_analysis_error="Cannot aspirate more than pipette max volume", robot_analysis_error="?", ) + OT2_P300M_P20S_HS_6_1_Smoke620release: Protocol = Protocol( file_name="OT2_P300M_P20S_HS_6_1_Smoke620release", file_extension="json", @@ -55,6 +58,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300M_P20S_MM_HS_TD_TC_6_1_AllMods_Error: Protocol = Protocol( file_name="OT2_P300M_P20S_MM_HS_TD_TC_6_1_AllMods_Error", file_extension="json", @@ -65,6 +69,7 @@ class Protocols: app_analysis_error="Heater-Shaker cannot open its labware latch while it is shaking.", robot_analysis_error="?", ) + OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40: Protocol = Protocol( file_name="OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40", file_extension="json", @@ -73,6 +78,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40Error: Protocol = Protocol( file_name="OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40Error", file_extension="json", @@ -83,6 +89,7 @@ class Protocols: app_analysis_error="Cannot aspirate more than pipette max volume", robot_analysis_error="?", ) + OT2_P300M_P20S_NoMod_6_1_MixTransferManyLiquids: Protocol = Protocol( file_name="OT2_P300M_P20S_NoMod_6_1_MixTransferManyLiquids", file_extension="json", @@ -91,6 +98,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300M_P300S_HS_6_1_HS_NormalUseWithTransfer: Protocol = Protocol( file_name="OT2_P300M_P300S_HS_6_1_HS_NormalUseWithTransfer", file_extension="json", @@ -99,6 +107,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300SG1_None_5_2_6_Gen1PipetteSimple: Protocol = Protocol( file_name="OT2_P300SG1_None_5_2_6_Gen1PipetteSimple", file_extension="json", @@ -107,6 +116,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300SLeft_MM_TM_TM_5_2_6_MOAMTemps: Protocol = Protocol( file_name="OT2_P300SLeft_MM_TM_TM_5_2_6_MOAMTemps", file_extension="json", @@ -129,6 +139,7 @@ class Protocols: robot_error=True, robot_analysis_error="?", ) + OT2_None_None_2_13_PythonSyntaxError: Protocol = Protocol( file_name="OT2_None_None_2_13_PythonSyntaxError", file_extension="py", @@ -139,6 +150,7 @@ class Protocols: app_analysis_error="No module named 'superspecialmagic'", robot_analysis_error="?", ) + OT2_P10S_P300M_TC1_TM_MM_2_11_Swift: Protocol = Protocol( file_name="OT2_P10S_P300M_TC1_TM_MM_2_11_Swift", file_extension="py", @@ -147,6 +159,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P20S_None_2_7_Walkthrough: Protocol = Protocol( file_name="OT2_P20S_None_2_7_Walkthrough", file_extension="py", @@ -155,6 +168,16 @@ class Protocols: app_error=False, robot_error=False, ) + + OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume: Protocol = Protocol( + file_name="OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume", + file_extension="py", + protocol_name="QA Protocol - API 2.16 - Aspirate Dispense Mix with 0 Volume", + robot="OT-2", + app_error=False, + robot_error=False, + ) + OT2_P300M_P20S_None_2_12_FailOnRun: Protocol = Protocol( file_name="OT2_P300M_P20S_None_2_12_FailOnRun", file_extension="py", @@ -172,6 +195,7 @@ class Protocols: robot_error=False, custom_labware=["cpx_4_tuberack_100ul"], ) + OT2_P300M_P20S_TC_HS_TM_2_14_SmokeTestV3: Protocol = Protocol( file_name="OT2_P300M_P20S_TC_HS_TM_2_14_SmokeTestV3", file_extension="py", @@ -181,6 +205,7 @@ class Protocols: robot_error=False, custom_labware=["cpx_4_tuberack_100ul"], ) + OT2_P300M_P20S_TC_HS_TM_2_15_SmokeTestV3: Protocol = Protocol( file_name="OT2_P300M_P20S_TC_HS_TM_2_15_SmokeTestV3", file_extension="py", @@ -190,6 +215,17 @@ class Protocols: robot_error=False, custom_labware=["cpx_4_tuberack_100ul"], ) + + OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3: Protocol = Protocol( + file_name="OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3", + file_extension="py", + protocol_name="🛠️ 2.16 Smoke Test V3 🪄", + robot="OT-2", + app_error=False, + robot_error=False, + custom_labware=["cpx_4_tuberack_100ul"], + ) + OT2_P300M_P20S_TC_MM_TM_2_13_Smoke620Release: Protocol = Protocol( file_name="OT2_P300M_P20S_TC_MM_TM_2_13_Smoke620Release", file_extension="py", @@ -199,6 +235,7 @@ class Protocols: robot_error=False, custom_labware=["cpx_4_tuberack_100ul"], ) + OT2_P300MLeft_MM_TM_2_4_Zymo: Protocol = Protocol( file_name="OT2_P300MLeft_MM_TM_2_4_Zymo", file_extension="py", @@ -207,6 +244,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300S_Thermocycler_Moam_Error: Protocol = Protocol( file_name="OT2_P300S_Thermocycler_Moam_Error", file_extension="py", @@ -217,6 +255,7 @@ class Protocols: app_analysis_error="DeckConflictError [line 19]: thermocyclerModuleV2 in slot 7 prevents thermocyclerModuleV1 from using slot 7.", # noqa: E501 robot_analysis_error="?", ) + OT2_P300S_Twinning_Error: Protocol = Protocol( file_name="OT2_P300S_Twinning_Error", file_extension="py", @@ -227,6 +266,7 @@ class Protocols: app_analysis_error="AttributeError [line 24]: 'InstrumentContext' object has no attribute 'pair_with'", robot_analysis_error="?", ) + OT2_P300SLeft_MM1_MM_2_2_EngageMagHeightFromBase: Protocol = Protocol( file_name="OT2_P300SLeft_MM1_MM_2_2_EngageMagHeightFromBase", file_extension="py", @@ -235,6 +275,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT2_P300SLeft_MM1_MM_TM_2_3_Mix: Protocol = Protocol( file_name="OT2_P300SLeft_MM1_MM_TM_2_3_Mix", file_extension="py", @@ -243,6 +284,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT3_P100_96_HS_TM_2_15_Quick_Zymo_RNA_Bacteria: Protocol = Protocol( file_name="OT3_P100_96_HS_TM_2_15_Quick_Zymo_RNA_Bacteria", file_extension="py", @@ -252,6 +294,7 @@ class Protocols: robot_error=False, custom_labware=["opentrons_ot3_96_tiprack_1000ul_rss"], ) + OT3_P1000_96_HS_TM_MM_2_15_ABR5_6_HDQ_Bacteria_ParkTips_96_channel: Protocol = Protocol( file_name="OT3_P1000_96_HS_TM_MM_2_15_ABR5_6_HDQ_Bacteria_ParkTips_96_channel", file_extension="py", @@ -261,6 +304,7 @@ class Protocols: robot_error=False, custom_labware=["opentrons_ot3_96_tiprack_1000ul_rss"], ) + OT3_P1000_96_HS_TM_MM_2_15_MagMaxRNACells96Ch: Protocol = Protocol( file_name="OT3_P1000_96_HS_TM_MM_2_15_MagMaxRNACells96Ch", file_extension="py", @@ -270,6 +314,7 @@ class Protocols: robot_error=False, custom_labware=["opentrons_ot3_96_tiprack_200ul_rss"], ) + OT3_P1000_96_HS_TM_TC_MM_2_15_ABR5_6_Illumina_DNA_Prep_96x_Head_PART_III: Protocol = Protocol( file_name="OT3_P1000_96_HS_TM_TC_MM_2_15_ABR5_6_Illumina_DNA_Prep_96x_Head_PART_III", file_extension="py", @@ -279,6 +324,7 @@ class Protocols: robot_error=False, custom_labware=["opentrons_ot3_96_tiprack_200ul_rss", "opentrons_ot3_96_tiprack_50ul_rss"], ) + OT3_P1000_96_None_2_15_ABR5_6_IDT_xGen_EZ_96x_Head_PART_I_III_ABR: Protocol = Protocol( file_name="OT3_P1000_96_None_2_15_ABR5_6_IDT_xGen_EZ_96x_Head_PART_I_III_ABR", file_extension="py", @@ -288,6 +334,7 @@ class Protocols: robot_error=False, custom_labware=["opentrons_ot3_96_tiprack_50ul_rss", "opentrons_ot3_96_tiprack_200ul_rss"], ) + OT3_P1000MLeft_P50MRight_HS_MM_TC_TM_2_15_ABR3_Illumina_DNA_Enrichment_v4: Protocol = Protocol( file_name="OT3_P1000MLeft_P50MRight_HS_MM_TC_TM_2_15_ABR3_Illumina_DNA_Enrichment_v4", file_extension="py", @@ -296,6 +343,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT3_P1000MLeft_P50MRight_HS_MM_TC_TM_2_15_ABR3_Illumina_DNA_Enrichment: Protocol = Protocol( file_name="OT3_P1000MLeft_P50MRight_HS_MM_TC_TM_2_15_ABR3_Illumina_DNA_Enrichment", file_extension="py", @@ -304,6 +352,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT3_P1000MLeft_P50MRight_HS_TM_MM_TC_2_15_ABR4_Illumina_DNA_Prep_24x: Protocol = Protocol( file_name="OT3_P1000MLeft_P50MRight_HS_TM_MM_TC_2_15_ABR4_Illumina_DNA_Prep_24x", file_extension="py", @@ -312,6 +361,7 @@ class Protocols: app_error=False, robot_error=False, ) + OT3_P1000SRight_None_2_15_ABR_Simple_Normalize_Long_Right: Protocol = Protocol( file_name="OT3_P1000SRight_None_2_15_ABR_Simple_Normalize_Long_Right", file_extension="py", @@ -321,6 +371,7 @@ class Protocols: robot_error=False, custom_labware=["opentrons_ot3_96_tiprack_200ul_rss"], ) + OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2: Protocol = Protocol( file_name="OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2", file_extension="py", @@ -330,34 +381,36 @@ class Protocols: robot_error=False, ) - OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn: Protocol = Protocol( - file_name="OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", + OT3_None_None_2_16_AnalysisError_TrashBinInCol2: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_TrashBinInCol2", file_extension="py", - protocol_name="QA Protocol - Analysis Error - Fixture Uses Middle Column", + protocol_name="QA Protocol - Analysis Error - Trash Bin in Column 2", robot="OT-3", app_error=True, robot_error=False, app_analysis_error="InvalidTrashBinLocationError [line 15]: Invalid location for trash bin: C2. Valid slots: Any slot in column 1 or 3.", # noqa: E501 ) - OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3: Protocol = Protocol( - file_name="OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3: Protocol = Protocol( + file_name="OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", file_extension="py", - protocol_name="QA Protocol - Analysis Error - Trash Bin Staging Area Column 3", + protocol_name="QA Protocol - Analysis Error - Trash Bin in Staging Area Column 3", robot="OT-3", app_error=True, robot_error=False, app_analysis_error="ProtocolCommandFailedError [line 21]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Trash Bin in C3, not compatible with one or more of the following fixtures: Slot C4", # noqa: E501 + expected_test_failure=True, + expected_test_reason="Analysis does not throw error when modules or fixtures are in staging area column 3.", # noqa: E501 ) OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4: Protocol = Protocol( file_name="OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", file_extension="py", - protocol_name="QA Protocol - Analysis Error - Trash Bin Staging Area Column 4", + protocol_name="QA Protocol - Analysis Error - Trash Bin in Staging Area Column 4", robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="ValueError [line 19]: Staging areas not permitted for trash bin.", # noqa: E501 + app_analysis_error="ValueError [line 15]: Staging areas not permitted for trash bin.", # noqa: E501 ) OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash: Protocol = Protocol( @@ -367,27 +420,29 @@ class Protocols: robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="NoTrashDefinedError [line 23]: Error 4000 GENERAL_ERROR (NoTrashDefinedError): No trash container has been defined in this protocol.", # noqa: E501 + app_analysis_error="NoTrashDefinedError [line 24]: Error 4000 GENERAL_ERROR (NoTrashDefinedError): No trash container has been defined in this protocol.", # noqa: E501 ) OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3: Protocol = Protocol( file_name="OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3", file_extension="py", - protocol_name="QA Protocol - Analysis Error - Module In Staging Area Column 3", + protocol_name="QA Protocol - Analysis Error - Module in Staging Area Column 3", robot="OT-3", app_error=True, robot_error=False, app_analysis_error="InvalidModuleError [line 19]: Error 4000 GENERAL_ERROR (InvalidModuleError): Cannot use temperature module in C3, not compatible with one or more of the following fixtures: Slot C4", # noqa: E501 + expected_test_failure=True, + expected_test_reason="Analysis does not throw error when modules or fixtures are in staging area column 3.", # noqa: E501 ) OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4: Protocol = Protocol( file_name="OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4", file_extension="py", - protocol_name="QA Protocol - Analysis Error - Module In Staging Area Column 4", + protocol_name="QA Protocol - Analysis Error - Module in Staging Area Column 4", robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="ValueError [line 19]: Cannot load a module onto a staging slot.", # noqa: E501 + app_analysis_error="ValueError [line 15]: Cannot load a module onto a staging slot.", # noqa: E501 ) OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict: Protocol = Protocol( @@ -397,7 +452,7 @@ class Protocols: robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="ProtocolCommandFailedError [line 24]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Waste Chute, not compatible with one or more of the following fixtures: Slot D3", # noqa: E501 + app_analysis_error="ProtocolCommandFailedError [line 25]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Waste Chute, not compatible with one or more of the following fixtures: Slot D3", # noqa: E501 ) OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp: Protocol = Protocol( @@ -417,5 +472,80 @@ class Protocols: robot="OT-3", app_error=True, robot_error=False, - app_analysis_error="ProtocolCommandFailedError [line 19]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Slot C3, not compatible with one or more of the following fixtures: Trash Bin in C3", # noqa: E501 + app_analysis_error="ProtocolCommandFailedError [line 20]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): IncompatibleAddressableAreaError: Cannot use Slot C3, not compatible with one or more of the following fixtures: Trash Bin in C3", # noqa: E501 + ) + + OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol: Protocol = Protocol( + file_name="OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - OT-2 Pipette in Flex Protocol", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ProtocolCommandFailedError [line 22]: Error 4000 GENERAL_ERROR (ProtocolCommandFailedError): InvalidSpecificationForRobotTypeError: Cannot load a Gen2 pipette on a Flex.", # noqa: E501 + ) + + OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol: Protocol = Protocol( + file_name="OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Magnetic Module in Flex Protocol", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ValueError [line 15]: A magneticModuleType cannot be loaded into slot C1", # noqa: E501 + ) + + OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2: Protocol = Protocol( + file_name="OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2", + file_extension="py", + protocol_name="QA Protocol - Analysis Error - Module in Column 2", + robot="OT-3", + app_error=True, + robot_error=False, + app_analysis_error="ValueError [line 15]: A temperatureModuleType cannot be loaded into slot C2", # noqa: E501 + ) + + OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures: Protocol = Protocol( + file_name="OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures", + file_extension="py", + protocol_name="QA Protocol - Deck Configuration 1 - No Fixtures", + robot="OT-3", + app_error=False, + robot_error=False, + ) + + OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules: Protocol = Protocol( + file_name="OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules", + file_extension="py", + protocol_name="QA Protocol - Deck Configuration 1 - No Modules", + robot="OT-3", + app_error=False, + robot_error=False, + ) + + OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures: Protocol = Protocol( + file_name="OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures", + file_extension="py", + protocol_name="QA Protocol - Deck Configuration 1 - No Modules or Fixtures", + robot="OT-3", + app_error=False, + robot_error=False, + ) + + OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1: Protocol = Protocol( + file_name="OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1", + file_extension="py", + protocol_name="QA Protocol - Deck Configuration 1", + robot="OT-3", + app_error=False, + robot_error=False, + ) + + OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke: Protocol = Protocol( + file_name="OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke", + file_extension="py", + protocol_name="QA Protocol - MEGAAA PROTOCOL - LETS BREAK, I MEAN TEST, EVERYTHING!!!!!", + robot="OT-3", + app_error=False, + robot_error=False, ) From 5fd257eeac9289ae1b06e7447bc6111242a46891 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:38:52 -0800 Subject: [PATCH 28/30] test: more tests --- ...AnalysisError_MagneticModuleInFlexProtocol.py | 15 +++++++++++++++ ...ne_None_TM_2_16_AnalysisError_ModuleInCol2.py | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 app-testing/files/protocols/py/OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol.py create mode 100644 app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2.py diff --git a/app-testing/files/protocols/py/OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol.py b/app-testing/files/protocols/py/OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol.py new file mode 100644 index 00000000000..d2b9c7cb2ed --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol.py @@ -0,0 +1,15 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Magnetic Module in Flex Protocol", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + ctx.load_module("magnetic module gen2", "C1") diff --git a/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2.py b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2.py new file mode 100644 index 00000000000..2ff8bb96261 --- /dev/null +++ b/app-testing/files/protocols/py/OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2.py @@ -0,0 +1,16 @@ +from opentrons import protocol_api + +metadata = { + "protocolName": "QA Protocol - Analysis Error - Module in Column 2", + "author": "Derek Maggio ", +} + +requirements = { + "robotType": "OT-3", + "apiLevel": "2.16", +} + + +def run(ctx: protocol_api.ProtocolContext) -> None: + temp_module = ctx.load_module("temperature module gen2", "C2") + temp_module.deactivate() From a28ee2704ac4a43f140540036ed9bfc719a09d75 Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 09:39:04 -0800 Subject: [PATCH 29/30] chore: misc --- app-testing/Makefile | 2 +- app-testing/automation/data/protocol_files.py | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app-testing/Makefile b/app-testing/Makefile index d037804ed74..3592ef29cdd 100644 --- a/app-testing/Makefile +++ b/app-testing/Makefile @@ -36,7 +36,7 @@ test-ci: .PHONY: test-protocol-analysis test-protocol-analysis: - pipenv run python -m pytest tests/protocol_analyze_test.py + pipenv run python -m pytest -v tests/protocol_analyze_test.py .PHONY: setup setup: diff --git a/app-testing/automation/data/protocol_files.py b/app-testing/automation/data/protocol_files.py index f3d33826604..97e30cfb6a0 100644 --- a/app-testing/automation/data/protocol_files.py +++ b/app-testing/automation/data/protocol_files.py @@ -10,6 +10,7 @@ "OT2_P20S_P300M_HS_6_1_HS_WithCollision_Error", "OT2_P20S_P300M_NoMods_6_1_TransferReTransferLiquid", "OT2_P20SRight_None_6_1_SimpleTransferError", + "OT2_P300M_P20S_2_16_aspirateDispenseMix0Volume", "OT2_P300M_P20S_HS_6_1_Smoke620release", "OT2_P300M_P20S_MM_HS_TD_TC_6_1_AllMods_Error", "OT2_P300M_P20S_MM_TM_TC1_5_2_6_PD40", @@ -19,6 +20,7 @@ "OT2_P300M_P20S_TC_HS_TM_2_13_SmokeTestV3", "OT2_P300M_P20S_TC_HS_TM_2_14_SmokeTestV3", "OT2_P300M_P20S_TC_HS_TM_2_15_SmokeTestV3", + "OT2_P300M_P20S_TC_HS_TM_2_16_SmokeTestV3", "OT2_P300M_P20S_TC_MM_TM_2_13_Smoke620Release", "OT2_P300M_P300S_HS_6_1_HS_NormalUseWithTransfer", "OT2_P300MLeft_MM_TM_2_4_Zymo", @@ -29,22 +31,31 @@ "OT2_P300SLeft_MM1_MM_2_2_EngageMagHeightFromBase", "OT2_P300SLeft_MM1_MM_TM_2_3_Mix", "OT3_None_None_2_16_AnalysisError_AccessToFixedTrashProp", - "OT3_None_None_2_16_AnalysisError_FixtureUsesMiddleColumn", - "OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + "OT3_None_None_2_16_AnalysisError_TrashBinInCol2", + "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", "OT3_None_None_2_16_AnalysisError_TrashBinInStagingAreaCol4", - "OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash", + "OT3_None_None_MM_2_16_AnalysisError_MagneticModuleInFlexProtocol", "OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol3", "OT3_None_None_TM_2_16_AnalysisError_ModuleInStagingAreaCol4", - "OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict", + "OT3_None_None_TM_2_16_AnalysisError_ModuleInCol2", "OT3_P100_96_HS_TM_2_15_Quick_Zymo_RNA_Bacteria", + "OT3_P1000_96_2_16_AnalysisError_DropTipsWithNoTrash", + "OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin", + "OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoFixtures", + "OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModules", + "OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1_NoModulesNoFixtures", + "OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_DeckConfiguration1", + "OT3_P1000_96_GRIPPER_HS_TM_TC_MB_2_16_Smoke", "OT3_P1000_96_HS_TM_MM_2_15_ABR5_6_HDQ_Bacteria_ParkTips_96_channel", "OT3_P1000_96_HS_TM_MM_2_15_MagMaxRNACells96Ch", "OT3_P1000_96_HS_TM_TC_MM_2_15_ABR5_6_Illumina_DNA_Prep_96x_Head_PART_III", "OT3_P1000_96_None_2_15_ABR5_6_IDT_xGen_EZ_96x_Head_PART_I_III_ABR", + "OT3_P1000_96_None_2_16_AnalysisError_TrashBinInStagingAreaCol3", + "OT3_P1000_96_TM_2_16_AnalysisError_ModuleAndWasteChuteConflict", "OT3_P1000MLeft_P50MRight_HS_MM_TC_TM_2_15_ABR3_Illumina_DNA_Enrichment_v4", "OT3_P1000MLeft_P50MRight_HS_MM_TC_TM_2_15_ABR3_Illumina_DNA_Enrichment", "OT3_P1000MLeft_P50MRight_HS_TM_MM_TC_2_15_ABR4_Illumina_DNA_Prep_24x", "OT3_P1000SRight_None_2_15_ABR_Simple_Normalize_Long_Right", + "OT3_P300Gen2_None_2_16_AnalysisError_OT2PipetteInFlexProtocol", "OT3_P50MLeft_P1000MRight_None_2_15_ABRKAPALibraryQuantLongv2", - "OT3_P1000_96_GRIPPER_2_16_AnalysisError_DropLabwareIntoTrashBin" ] From 0c339a6376ac288d0fbae2cd14ecaf503363570c Mon Sep 17 00:00:00 2001 From: Derek Maggio Date: Thu, 21 Dec 2023 10:28:15 -0800 Subject: [PATCH 30/30] chore: clean up control flow --- app-testing/tests/protocol_analyze_test.py | 30 +++++++++------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/app-testing/tests/protocol_analyze_test.py b/app-testing/tests/protocol_analyze_test.py index 53530e46579..1eb1d5e10b4 100644 --- a/app-testing/tests/protocol_analyze_test.py +++ b/app-testing/tests/protocol_analyze_test.py @@ -10,6 +10,7 @@ from automation.pages.protocol_landing import ProtocolLanding from rich.console import Console from selenium.webdriver.chrome.webdriver import WebDriver +from selenium.webdriver.remote.webelement import WebElement def _what_protocols() -> list[Protocol]: @@ -39,6 +40,13 @@ def _what_protocols() -> list[Protocol]: return tests +def get_error_text(protocol_landing: ProtocolLanding, error_link: WebElement) -> str: + protocol_landing.base.click_webelement(error_link) + error_details = protocol_landing.get_popout_error().text + protocol_landing.click_popout_close() + return error_details + + @pytest.mark.parametrize( "protocol", _what_protocols(), @@ -91,26 +99,12 @@ def test_analyses( ), f"Analysis took more than {analysis_timeout} seconds." # look for analysis error if the protocol should have one + error_link = protocol_landing.get_error_details_safe() if protocol.app_error: - error_link = protocol_landing.get_error_details_safe() - assert error_link is not None, "No analysis error but was expecting one." - protocol_landing.base.click_webelement(error_link) - error_details = protocol_landing.get_popout_error().text - try: - assert error_details == protocol.app_analysis_error - except AssertionError: - raise - finally: - protocol_landing.click_popout_close() - else: - error_link = protocol_landing.get_error_details_safe() - - if error_link is not None: - protocol_landing.base.click_webelement(error_link) - error_details = protocol_landing.get_popout_error().text - protocol_landing.click_popout_close() - raise AssertionError(f"Unexpected analysis error: {error_details}") + assert get_error_text(protocol_landing, error_link) == protocol.app_analysis_error + elif error_link is not None: + raise AssertionError(f"Unexpected analysis error: {get_error_text(protocol_landing, error_link)}") # Verifying elements on Protocol Landing Page # todo fix next line needs to be safe and print name not found