From 3f7b991dd978ae2e7b257ebec5f916c6923c3be2 Mon Sep 17 00:00:00 2001 From: Guangxin Zhang Date: Thu, 17 Jul 2025 22:36:45 +0800 Subject: [PATCH] Update 9320 --- .../devices/liquid_handling/prcxi/prcxi.py | 292 ++++++++++++++++-- 1 file changed, 262 insertions(+), 30 deletions(-) diff --git a/unilabos/devices/liquid_handling/prcxi/prcxi.py b/unilabos/devices/liquid_handling/prcxi/prcxi.py index c069574..ee7c0a9 100644 --- a/unilabos/devices/liquid_handling/prcxi/prcxi.py +++ b/unilabos/devices/liquid_handling/prcxi/prcxi.py @@ -961,71 +961,303 @@ class PRCXI9300Api: if __name__ == "__main__": + # # Example usage + # # 1. 用导出的json,给每个T1 T2板子设定相应的物料,如果是孔板和枪头盒,要对应区分 + # # 2. 设计一个单点动作流程,可以跑 + # # 3. + # deck = PRCXI9300Deck(name="PRCXI_Deck", size_x=100, size_y=100, size_z=100) + # plate1 = PRCXI9300Container(name="rackT1", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + # plate1.load_state({ + # "Material": { + # "uuid": "80652665f6a54402b2408d50b40398df", + # "Co#de": "ZX-001-1000", + # "Name": "1000μL Tip头", + # "SummaryName": "1000μL Tip头", + # "PipetteHeight": 100, + # "materialEnum": 1 + # } + # }) + + # plate2 = PRCXI9300Container(name="plateT2", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + # plate2.load_state({ + # "Material": { + # "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + # } + # }) + + # plate3 = PRCXI9300Container(name="plateT3", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + # plate3.load_state({ + # "Material": { + # "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + # } + # }) + + # plate4 = PRCXI9300Container(name="rackT4", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + # plate4.load_state({ + # "Material": { + # "uuid": "80652665f6a54402b2408d50b40398df", + # "Code": "ZX-001-1000", + # "Name": "1000μL Tip头", + # "SummaryName": "1000μL Tip头", + # "PipetteHeight": 100, + # "materialEnum": 1 + # } + # }) + + # plate5 = PRCXI9300Container(name="plateT5", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + # plate5.load_state({ + # "Material": { + # "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + # } + # }) + # plate6 = PRCXI9300Trash(name="trash", size_x=50, size_y=500, size_z=10, category="trash") + # plate6.load_state({ + # "Material": { + # "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + # } + # }) + + # from pylabrobot.resources.opentrons.tip_racks import tipone_96_tiprack_200ul + # from pylabrobot.resources.opentrons.plates import corning_96_wellplate_360ul_flat + + # tip_rack = tipone_96_tiprack_200ul("TipRack") + # well_containers = corning_96_wellplate_360ul_flat("Plate") + # # from pprint import pprint + # # pprint(well_containers.children) + # plate1.assign_child_resource(tip_rack, location=Coordinate(0, 0, 0)) + # plate2.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + + # deck.assign_child_resource(plate1, location=Coordinate(0, 0, 0)) + # deck.assign_child_resource(plate2, location=Coordinate(0, 0, 0)) + # deck.assign_child_resource(plate3, location=Coordinate(0, 0, 0)) + # deck.assign_child_resource(plate4, location=Coordinate(0, 0, 0)) + # deck.assign_child_resource(plate5, location=Coordinate(0, 0, 0)) + # deck.assign_child_resource(plate6, location=Coordinate(0, 0, 0)) + + # print(plate2) + # # plate_2_liquids = [[(None, 500)]]*96 + + # # plate2.set_well_liquids(plate_2_liquids) + + + # handler = PRCXI9300Handler(deck=deck, host="192.168.3.9", port=9999, timeout=10.0, setup=False, debug=True, matrix_id="fd383e6d-2d0e-40b5-9c01-1b2870b1f1b1") + # handler.set_tiprack([tip_rack]) # Set the tip rack for the handler + # asyncio.run(handler.setup()) # Initialize the handler and setup the connection + # from pylabrobot.resources import set_volume_tracking + + # # from pylabrobot.resources import set_tip_tracking + # set_volume_tracking(enabled=True) + # plate2.set_well_liquids([("Water", 100)] * plate2.num_items) + # asyncio.run(handler.create_protocol(protocol_name="Test Protocol")) # Initialize the backend and setup the connection + # # asyncio.run(handler.pick_up_tips(tip_rack.children[:8],[0,1,2,3,4,5,6,7])) + + # # asyncio.run(handler.aspirate(well_containers.children[:8],[50]*8, [0,1,2,3,4,5,6,7])) + # # asyncio.run(handler.dispense(well_containers.children[:8],[50]*8,[0,1,2,3,4,5,6,7])) + # # asyncio.run(handler.drop_tips(tip_rack.children[8:16],[0,1,2,3,4,5,6,7])) + # # asyncio.run(handler.discard_tips()) + # # asyncio.run(handler.mix(well_containers.children[:8 + # # ], mix_time=3, mix_vol=50, height_to_bottom=0.5, offsets=Coordinate(0, 0, 0), mix_rate=100)) + # #print(json.dumps(handler._unilabos_backend.steps_todo_list, indent=2)) # Print matrix info + # asyncio.run(handler.add_liquid( + # asp_vols=[100]*16, + # dis_vols=[100]*16, + # reagent_sources=well_containers.children[-16:], + # targets=well_containers.children[:16], + # use_channels=[0, 1, 2, 3, 4, 5, 6, 7], + # flow_rates=[None] * 32, + # offsets=[Coordinate(0, 0, 0)] * 32, + # liquid_height=[None] * 16, + # blow_out_air_volume=[None] * 16, + # delays=None, + # mix_time=3, + # mix_vol=50, + # spread="wide", + # )) + + # # asyncio.run(handler.remove_liquid( + # # vols=[100]*16, + # # sources=well_containers.children[-16:], + # # waste_liquid=well_containers.children[:16], # 这个有些奇怪,但是好像也只能这么写 + # # use_channels=[0, 1, 2, 3, 4, 5, 6, 7], + # # flow_rates=[None] * 32, + # # offsets=[Coordinate(0, 0, 0)] * 32, + # # liquid_height=[None] * 32, + # # blow_out_air_volume=[None] * 32, + # # spread="wide", + # # )) + # # asyncio.run(handler.transfer_liquid( + # # asp_vols=[100]*16, + # # dis_vols=[100]*16, + # # tip_racks=[tip_rack], + # # sources=well_containers.children[-16:], + # # targets=well_containers.children[:16], + # # use_channels=[0, 1, 2, 3, 4, 5, 6, 7], + # # offsets=[Coordinate(0, 0, 0)] * 32, + # # asp_flow_rates=[None] * 16, + # # dis_flow_rates=[None] * 16, + # # liquid_height=[None] * 32, + # # blow_out_air_volume=[None] * 32, + # # mix_times=3, + # # mix_vol=50, + # # spread="wide", + # # )) + # print(json.dumps(handler._unilabos_backend.steps_todo_list, indent=2)) # Print matrix info + # # input("pick_up_tips add step") + # #asyncio.run(handler.run_protocol()) # Run the protocol + # # input("Running protocol...") + # # input("Press Enter to continue...") # Wait for user input before proceeding + # # print("PRCXI9300Handler initialized with deck and host settings.") + + + + + + + + + + + + + + + + + + + + + + + + + # Example usage # 1. 用导出的json,给每个T1 T2板子设定相应的物料,如果是孔板和枪头盒,要对应区分 # 2. 设计一个单点动作流程,可以跑 # 3. deck = PRCXI9300Deck(name="PRCXI_Deck", size_x=100, size_y=100, size_z=100) - plate1 = PRCXI9300Container(name="rackT1", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate1 = PRCXI9300Container(name="HPLCPlateT1", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) plate1.load_state({ "Material": { - "uuid": "80652665f6a54402b2408d50b40398df", - "Co#de": "ZX-001-1000", - "Name": "1000μL Tip头", - "SummaryName": "1000μL Tip头", - "PipetteHeight": 100, - "materialEnum": 1 + "uuid": "548bbc3df0d4447586f2c19d2c0c0c55", + "Code": "HPLC01", + "Name": "HPLC料盘" } }) plate2 = PRCXI9300Container(name="plateT2", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) plate2.load_state({ "Material": { - "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + "uuid": "04211a2dc93547fe9bf6121eac533650" } }) + + #储液槽 plate3 = PRCXI9300Container(name="plateT3", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) plate3.load_state({ "Material": { - "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + "uuid": "04211a2dc93547fe9bf6121eac533650" } }) - plate4 = PRCXI9300Container(name="rackT4", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate4 = PRCXI9300Trash(name="trash", size_x=50, size_y=50, size_z=10, category="trash", ordering=collections.OrderedDict()) plate4.load_state({ "Material": { - "uuid": "80652665f6a54402b2408d50b40398df", - "Code": "ZX-001-1000", - "Name": "1000μL Tip头", - "SummaryName": "1000μL Tip头", - "PipetteHeight": 100, - "materialEnum": 1 + "uuid": "730067cf07ae43849ddf4034299030e9" } }) plate5 = PRCXI9300Container(name="plateT5", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) plate5.load_state({ "Material": { - "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + "uuid": "04211a2dc93547fe9bf6121eac533650" } }) - plate6 = PRCXI9300Trash(name="trash", size_x=50, size_y=500, size_z=10, category="trash") + + plate6 = PRCXI9300Container(name="plateT6", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) plate6.load_state({ + "Material": { + "uuid": "04211a2dc93547fe9bf6121eac533650" + } + }) + + plate7 = PRCXI9300Container(name="plateT7", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate7.load_state({ + "Material": { + "uuid": "04211a2dc93547fe9bf6121eac533650" + } + }) + + plate8 = PRCXI9300Container(name="rackT8", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate8.load_state({ + "Material": { + "uuid": "068b3815e36b4a72a59bae017011b29f", + "Code": "ZX-001-10+", + "Name": "10μL加长 Tip头" + } + }) + + plate9 = PRCXI9300Container(name="plateT9", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate9.load_state({ + "Material": { + "uuid": "04211a2dc93547fe9bf6121eac533650" + } + }) + + plate10 = PRCXI9300Container(name="plateT10", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate10.load_state({ + "Material": { + "uuid": "04211a2dc93547fe9bf6121eac533650" + } + }) + + + + plate11 = PRCXI9300Container(name="plateT11", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate11.load_state({ "Material": { "uuid": "57b1e4711e9e4a32b529f3132fc5931f", } }) - from pylabrobot.resources.opentrons.tip_racks import tipone_96_tiprack_200ul - from pylabrobot.resources.opentrons.plates import corning_96_wellplate_360ul_flat - tip_rack = tipone_96_tiprack_200ul("TipRack") - well_containers = corning_96_wellplate_360ul_flat("Plate") + plate12 = PRCXI9300Container(name="plateT12", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate12.load_state({ + "Material": { + "uuid": "04211a2dc93547fe9bf6121eac533650" + } + }) + + + plate13 = PRCXI9300Container(name="plateT13", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + plate13.load_state({ + "Material": { + "uuid": "04211a2dc93547fe9bf6121eac533650" + } + }) + + from pylabrobot.resources.opentrons.tip_racks import tipone_96_tiprack_200ul,opentrons_96_tiprack_10ul + from pylabrobot.resources.opentrons.plates import corning_96_wellplate_360ul_flat, nest_96_wellplate_2ml_deep + + tip_rack = opentrons_96_tiprack_10ul("TipRack") + well_containers = nest_96_wellplate_2ml_deep("Plate") # from pprint import pprint # pprint(well_containers.children) - plate1.assign_child_resource(tip_rack, location=Coordinate(0, 0, 0)) + plate1.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) plate2.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate3.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate4.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate5.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate6.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate7.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate8.assign_child_resource(tip_rack, location=Coordinate(0, 0, 0)) + plate9.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate10.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate11.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate12.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) + plate13.assign_child_resource(well_containers, location=Coordinate(0, 0, 0)) deck.assign_child_resource(plate1, location=Coordinate(0, 0, 0)) deck.assign_child_resource(plate2, location=Coordinate(0, 0, 0)) @@ -1033,11 +1265,14 @@ if __name__ == "__main__": deck.assign_child_resource(plate4, location=Coordinate(0, 0, 0)) deck.assign_child_resource(plate5, location=Coordinate(0, 0, 0)) deck.assign_child_resource(plate6, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate7, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate8, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate9, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate10, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate11, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate12, location=Coordinate(0, 0, 0)) + deck.assign_child_resource(plate13, location=Coordinate(0, 0, 0)) - print(plate2) - # plate_2_liquids = [[(None, 500)]]*96 - - # plate2.set_well_liquids(plate_2_liquids) handler = PRCXI9300Handler(deck=deck, host="192.168.3.9", port=9999, timeout=10.0, setup=False, debug=True, matrix_id="fd383e6d-2d0e-40b5-9c01-1b2870b1f1b1") @@ -1108,6 +1343,3 @@ if __name__ == "__main__": # input("Press Enter to continue...") # Wait for user input before proceeding # print("PRCXI9300Handler initialized with deck and host settings.") - - -# 但是怎么丢tip?这个需要手动设置一下? \ No newline at end of file