From a8cf389b00f1bd815a7d53e0a79a145808bfdd8f Mon Sep 17 00:00:00 2001 From: Guangxin Zhang Date: Sat, 19 Jul 2025 15:16:08 +0800 Subject: [PATCH] Update --- .../liquid_handler_abstract.py | 24 +- .../devices/liquid_handling/prcxi/prcxi.py | 677 +++++++++--------- 2 files changed, 361 insertions(+), 340 deletions(-) diff --git a/unilabos/devices/liquid_handling/liquid_handler_abstract.py b/unilabos/devices/liquid_handling/liquid_handler_abstract.py index d44a9ae..d5a8fbf 100644 --- a/unilabos/devices/liquid_handling/liquid_handler_abstract.py +++ b/unilabos/devices/liquid_handling/liquid_handler_abstract.py @@ -622,12 +622,10 @@ class LiquidHandlerAbstract(LiquidHandlerMiddleware): spread=spread, ) await self.discard_tips() - elif len(use_channels) == 8 and self.backend.num_channels == 8: - tip = [] - for _ in range(len(use_channels)): - tip.extend(next(self.current_tip)) - await self.pick_up_tips(tip) + elif len(use_channels) == 8 and self.backend.num_channels == 8: + + # 对于8个的情况,需要判断此时任务是不是能被8通道移液站来成功处理 if len(sources) % 8 != 0: raise ValueError(f"Length of `sources` {len(sources)} must be a multiple of 8 for 8-channel mode.") @@ -635,7 +633,6 @@ class LiquidHandlerAbstract(LiquidHandlerMiddleware): # 8个8个来取任务序列 for i in range(0, len(sources), 8): - # 取出8个任务 tip = [] for _ in range(len(use_channels)): tip.extend(next(self.current_tip)) @@ -764,19 +761,16 @@ class LiquidHandlerAbstract(LiquidHandlerMiddleware): await self.custom_delay(seconds=delays[1]) await self.touch_tip(targets[_]) await self.discard_tips() - elif len(use_channels) == 8: + elif len(use_channels) == 8: # 对于8个的情况,需要判断此时任务是不是能被8通道移液站来成功处理 if len(targets) % 8 != 0: raise ValueError(f"Length of `targets` {len(targets)} must be a multiple of 8 for 8-channel mode.") - - # 8个8个来取任务序列 - + tip = [] + for _ in range(len(use_channels)): + tip.extend(next(self.current_tip)) + await self.pick_up_tips(tip) for i in range(0, len(targets), 8): - tip = [] - for _ in range(len(use_channels)): - tip.extend(next(self.current_tip)) - await self.pick_up_tips(tip) current_targets = targets[i:i + 8] current_reagent_sources = reagent_sources[i:i + 8] current_asp_vols = asp_vols[i:i + 8] @@ -826,7 +820,7 @@ class LiquidHandlerAbstract(LiquidHandlerMiddleware): if delays is not None: await self.custom_delay(seconds=delays[1]) await self.touch_tip(current_targets) - await self.discard_tips() + await self.discard_tips() # except Exception as e: diff --git a/unilabos/devices/liquid_handling/prcxi/prcxi.py b/unilabos/devices/liquid_handling/prcxi/prcxi.py index 155e099..2f13242 100644 --- a/unilabos/devices/liquid_handling/prcxi/prcxi.py +++ b/unilabos/devices/liquid_handling/prcxi/prcxi.py @@ -455,7 +455,7 @@ class PRCXI9300Backend(LiquidHandlerBackend): # print(plate_indexes[0]) PlateNo = plate_indexes[0] + 1 hole_col = tip_columns[0] + 1 - + hole_row = 1 if self._num_channels == 1: hole_row = tipspot_index % 8 + 1 @@ -476,7 +476,7 @@ class PRCXI9300Backend(LiquidHandlerBackend): dosage=0, plate_no=PlateNo, is_whole_plate=False, - hole_row=3, + hole_row=1, hole_col=3, blending_times=0, balance_height=0, @@ -974,156 +974,9 @@ if __name__ == "__main__": # # 2. backend需要支持num channel为1的情况 # # 3. 设计一个单点动作流程,可以跑 # # 4. - # 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) - from pylabrobot.resources.opentrons.tip_racks import tipone_96_tiprack_200ul,opentrons_96_tiprack_10ul + from pylabrobot.resources.opentrons.tip_racks import opentrons_96_tiprack_300ul,opentrons_96_tiprack_10ul from pylabrobot.resources.opentrons.plates import corning_96_wellplate_360ul_flat, nest_96_wellplate_2ml_deep def get_well_container(name: str) -> PRCXI9300Container: @@ -1137,7 +990,7 @@ if __name__ == "__main__": return new_plate def get_tip_rack(name: str) -> PRCXI9300Container: - tip_racks = opentrons_96_tiprack_10ul("name").serialize() + tip_racks = opentrons_96_tiprack_300ul("name").serialize() tip_rack = PRCXI9300Container(name=name, size_x=50, size_y=50, size_z=10, category="tip_rack", ordering=collections.OrderedDict()) tip_rack_serialized = tip_rack.serialize() @@ -1146,204 +999,114 @@ if __name__ == "__main__": new_tip_rack: PRCXI9300Container = PRCXI9300Container.deserialize(tip_racks) return new_tip_rack - plate1 = get_well_container("HPLCPlateT1") + plate1 = get_tip_rack("RackT1") plate1.load_state({ "Material": { - "uuid": "548bbc3df0d4447586f2c19d2c0c0c55", - "Code": "HPLC01", - "Name": "HPLC料盘" + "uuid": "076250742950465b9d6ea29a225dfb00", + "Code": "ZX-001-300", + "Name": "300μL Tip头" } }) + plate2 = get_well_container("PlateT2") plate2.load_state({ "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650", + "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + "Code": "ZX-019-2.2", + "Name": "96深孔板" } }) - plate3 = get_well_container("PlateT3") + + + plate3 = PRCXI9300Trash("trash", size_x=50, size_y=100, size_z=10, category="trash") plate3.load_state({ - "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650", - } - }) - trash = PRCXI9300Trash(name="trash", size_x=50, size_y=50, size_z=10, category="trash") - trash.load_state({ "Material": { "uuid": "730067cf07ae43849ddf4034299030e9" } }) + + plate4 = get_tip_rack("RackT4") + plate4.load_state({ + "Material": { + "uuid": "076250742950465b9d6ea29a225dfb00", + "Code": "ZX-001-300", + "Name": "300μL Tip头" + } + }) + plate5 = get_well_container("PlateT5") plate5.load_state({ "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650", + "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + "Code": "ZX-019-2.2", + "Name": "96深孔板" } }) plate6 = get_well_container("PlateT6") 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 = get_tip_rack("RackT8") - plate8.load_state({ - "Material": { - "uuid": "068b3815e36b4a72a59bae017011b29f", - "Code": "ZX-001-10+", - "Name": "10μL加长 Tip头" - } - }) - plate9 = get_well_container("PlateT9") - plate9.load_state({ - "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650" - } - }) - plate10 = get_well_container("PlateT10") - plate10.load_state({ - "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650" - } - }) - plate11 = get_well_container("PlateT11") - plate11.load_state({ "Material": { "uuid": "57b1e4711e9e4a32b529f3132fc5931f", + "Code": "ZX-019-2.2", + "Name": "96深孔板" } }) - plate12 = get_well_container("PlateT12") - plate12.load_state({ - "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650" - } - }) - plate13 = get_well_container("PlateT13") - plate13.load_state({ - "Material": { - "uuid": "04211a2dc93547fe9bf6121eac533650" - } - }) - - # container_for_nothing = PRCXI9300Container(name="container_for_nothing", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) deck.assign_child_resource(plate1, location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing1", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing2", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(trash, location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing3", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing4", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(plate8, location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing5", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing6", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(plate11, location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing7", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) - deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing8", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), 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)) - handler = PRCXI9300Handler(deck=deck, host="10.181.102.13", port=9999, + # print(plate2) + plate_2_liquids = [[('water', 500)]]*96 + plate2.set_well_liquids(plate_2_liquids) + + handler = PRCXI9300Handler(deck=deck, host="10.181.214.132", port=9999, timeout=10.0, setup=False, debug=False, - matrix_id="fd383e6d-2d0e-40b5-9c01-1b2870b1f1b1", - channel_num=1, axis="Right") # Initialize the handler with the deck and host settings + matrix_id="71593", + channel_num=8, axis="Left") # Initialize the handler with the deck and host settings - handler.set_tiprack([plate8]) # Set the tip rack for the handler + + handler.set_tiprack([plate1]) + 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) - - plate11.set_well_liquids([("Water", 100) if (i % 8 == 0 and i // 8 < 6) else (None, 100) for i in range(96)]) # Set liquids for every 8 wells in plate8 - from unilabos.resources.graphio import * - A = tree_to_list([resource_plr_to_ulab(deck)]) - with open("deck.json", "w", encoding="utf-8") as f: - json.dump(A, f, indent=4, ensure_ascii=False) - - print(plate11.get_well(0).tracker.get_used_volume()) asyncio.run(handler.create_protocol(protocol_name="Test Protocol")) # Initialize the backend and setup the connection + # asyncio.run(handler.pick_up_tips(plate1.children[:8],[0,1,2,3,4,5,6,7])) - # asyncio.run(handler.pick_up_tips([plate8.children[8]],[0])) - # print(plate8.children[8]) - # # asyncio.run(handler.run_protocol()) - # asyncio.run(handler.aspirate([plate11.children[0]],[10], [0])) - # print(plate11.children[0]) - # # asyncio.run(handler.run_protocol()) - # asyncio.run(handler.dispense([plate1.children[0]],[10],[0])) - # print(plate1.children[0]) - # # asyncio.run(handler.run_protocol()) - # asyncio.run(handler.mix([plate1.children[0]], mix_time=3, mix_vol=5, height_to_bottom=0.5, offsets=Coordinate(0, 0, 0), mix_rate=100)) - # print(plate1.children[0]) + # asyncio.run(handler.aspirate(plate2.children[:8],[50]*8, [0,1,2,3,4,5,6,7])) + # asyncio.run(handler.dispense(plate5.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()) - print('1111'*500) - print(plate11.children[-2:]) - asyncio.run(handler.add_liquid( - asp_vols=[10]*2, - dis_vols=[10]*2, - reagent_sources=[plate11.children[0]], - targets=plate11.children[-2:], - use_channels=[0], - flow_rates=[None] * 4, - offsets=[Coordinate(0, 0, 0)] * 4, - liquid_height=[None] * 2, - blow_out_air_volume=[None] * 2, - delays=None, - mix_time=3, - mix_vol=5, - spread="wide", -)) -# asyncio.run(handler.transfer_liquid( -# asp_vols=[10]*2, -# dis_vols=[10]*2, -# sources=plate11.children[:2], -# targets=plate11.children[-2:], -# use_channels=[0], -# offsets=[Coordinate(0, 0, 0)] * 4, -# liquid_height=[None] * 2, -# blow_out_air_volume=[None] * 2, -# delays=None, -# mix_times=3, -# mix_vol=5, -# spread="wide", -# tip_racks=[plate8] -# )) - -# asyncio.run(handler.remove_liquid( -# vols=[10]*2, -# sources=plate11.children[:2], -# waste_liquid=plate11.children[43], -# use_channels=[0], -# offsets=[Coordinate(0, 0, 0)] * 4, -# liquid_height=[None] * 2, -# blow_out_air_volume=[None] * 2, -# delays=None, -# spread="wide" -# )) - - - - - - - - - asyncio.run(handler.run_protocol()) - - # 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 - + # #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=plate2.children[:16], + # targets=plate5.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], # 这个有些奇怪,但是好像也只能这么写 + # sources=plate2.children[-16:], + # waste_liquid=plate5.children[:16], # 这个有些奇怪,但是好像也只能这么写 # use_channels=[0, 1, 2, 3, 4, 5, 6, 7], # flow_rates=[None] * 32, # offsets=[Coordinate(0, 0, 0)] * 32, @@ -1351,26 +1114,290 @@ if __name__ == "__main__": # 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", - # )) + asyncio.run(handler.transfer_liquid( + asp_vols=[100]*16, + dis_vols=[100]*16, + tip_racks=[plate1], + sources=plate2.children[-16:], + targets=plate5.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.") + # # 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) + +# 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 + +# def get_well_container(name: str) -> PRCXI9300Container: +# well_containers = corning_96_wellplate_360ul_flat(name).serialize() +# plate = PRCXI9300Container(name=name, size_x=50, size_y=50, size_z=10, category="plate", +# ordering=collections.OrderedDict()) +# plate_serialized = plate.serialize() +# plate_serialized["parent_name"] = deck.name +# well_containers.update({k: v for k, v in plate_serialized.items() if k not in ["children"]}) +# new_plate: PRCXI9300Container = PRCXI9300Container.deserialize(well_containers) +# return new_plate + +# def get_tip_rack(name: str) -> PRCXI9300Container: +# tip_racks = opentrons_96_tiprack_10ul("name").serialize() +# tip_rack = PRCXI9300Container(name=name, size_x=50, size_y=50, size_z=10, category="tip_rack", +# ordering=collections.OrderedDict()) +# tip_rack_serialized = tip_rack.serialize() +# tip_rack_serialized["parent_name"] = deck.name +# tip_racks.update({k: v for k, v in tip_rack_serialized.items() if k not in ["children"]}) +# new_tip_rack: PRCXI9300Container = PRCXI9300Container.deserialize(tip_racks) +# return new_tip_rack + +# plate1 = get_well_container("HPLCPlateT1") +# plate1.load_state({ +# "Material": { +# "uuid": "548bbc3df0d4447586f2c19d2c0c0c55", +# "Code": "HPLC01", +# "Name": "HPLC料盘" +# } +# }) +# plate2 = get_well_container("PlateT2") +# plate2.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650", +# } +# }) +# plate3 = get_well_container("PlateT3") +# plate3.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650", +# } +# }) +# trash = PRCXI9300Trash(name="trash", size_x=50, size_y=50, size_z=10, category="trash") +# trash.load_state({ +# "Material": { +# "uuid": "730067cf07ae43849ddf4034299030e9" +# } +# }) +# plate5 = get_well_container("PlateT5") +# plate5.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650", +# } +# }) +# plate6 = get_well_container("PlateT6") +# 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 = get_tip_rack("RackT8") +# plate8.load_state({ +# "Material": { +# "uuid": "068b3815e36b4a72a59bae017011b29f", +# "Code": "ZX-001-10+", +# "Name": "10μL加长 Tip头" +# } +# }) +# plate9 = get_well_container("PlateT9") +# plate9.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650" +# } +# }) +# plate10 = get_well_container("PlateT10") +# plate10.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650" +# } +# }) +# plate11 = get_well_container("PlateT11") +# plate11.load_state({ +# "Material": { +# "uuid": "57b1e4711e9e4a32b529f3132fc5931f", +# } +# }) +# plate12 = get_well_container("PlateT12") +# plate12.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650" +# } +# }) +# plate13 = get_well_container("PlateT13") +# plate13.load_state({ +# "Material": { +# "uuid": "04211a2dc93547fe9bf6121eac533650" +# } +# }) + +# # container_for_nothing = PRCXI9300Container(name="container_for_nothing", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()) + +# deck.assign_child_resource(plate1, location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing1", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing2", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(trash, location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing3", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing4", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(plate8, location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing5", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing6", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(plate11, location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing7", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) +# deck.assign_child_resource(PRCXI9300Container(name="container_for_nothing8", size_x=50, size_y=50, size_z=10, category="plate", ordering=collections.OrderedDict()), location=Coordinate(0, 0, 0)) + +# handler = PRCXI9300Handler(deck=deck, host="10.181.102.13", port=9999, +# timeout=10.0, setup=False, debug=False, +# matrix_id="fd383e6d-2d0e-40b5-9c01-1b2870b1f1b1", +# channel_num=1, axis="Right") # Initialize the handler with the deck and host settings + +# handler.set_tiprack([plate8]) # 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) + +# plate11.set_well_liquids([("Water", 100) if (i % 8 == 0 and i // 8 < 6) else (None, 100) for i in range(96)]) # Set liquids for every 8 wells in plate8 + +# from unilabos.resources.graphio import * + +# A = tree_to_list([resource_plr_to_ulab(deck)]) +# with open("deck.json", "w", encoding="utf-8") as f: +# json.dump(A, f, indent=4, ensure_ascii=False) + +# print(plate11.get_well(0).tracker.get_used_volume()) +# asyncio.run(handler.create_protocol(protocol_name="Test Protocol")) # Initialize the backend and setup the connection + +# # asyncio.run(handler.pick_up_tips([plate8.children[8]],[0])) +# # print(plate8.children[8]) +# # # asyncio.run(handler.run_protocol()) +# # asyncio.run(handler.aspirate([plate11.children[0]],[10], [0])) +# # print(plate11.children[0]) +# # # asyncio.run(handler.run_protocol()) +# # asyncio.run(handler.dispense([plate1.children[0]],[10],[0])) +# # print(plate1.children[0]) +# # # asyncio.run(handler.run_protocol()) +# # asyncio.run(handler.mix([plate1.children[0]], mix_time=3, mix_vol=5, height_to_bottom=0.5, offsets=Coordinate(0, 0, 0), mix_rate=100)) +# # print(plate1.children[0]) +# # asyncio.run(handler.discard_tips()) + +# asyncio.run(handler.add_liquid( +# asp_vols=[10]*7, +# dis_vols=[10]*7, +# reagent_sources=[plate11.children[0]], +# targets=plate1.children[2:9], +# use_channels=[0], +# flow_rates=[None] * 4, +# offsets=[Coordinate(0, 0, 0)] * 4, +# liquid_height=[None] * 2, +# blow_out_air_volume=[None] * 2, +# delays=None, +# mix_time=3, +# mix_vol=5, +# spread="wide", +# )) + +# # asyncio.run(handler.transfer_liquid( +# # asp_vols=[10]*2, +# # dis_vols=[10]*2, +# # sources=plate11.children[:2], +# # targets=plate11.children[-2:], +# # use_channels=[0], +# # offsets=[Coordinate(0, 0, 0)] * 4, +# # liquid_height=[None] * 2, +# # blow_out_air_volume=[None] * 2, +# # delays=None, +# # mix_times=3, +# # mix_vol=5, +# # spread="wide", +# # tip_racks=[plate8] +# # )) + +# # asyncio.run(handler.remove_liquid( +# # vols=[10]*2, +# # sources=plate11.children[:2], +# # waste_liquid=plate11.children[43], +# # use_channels=[0], +# # offsets=[Coordinate(0, 0, 0)] * 4, +# # liquid_height=[None] * 2, +# # blow_out_air_volume=[None] * 2, +# # delays=None, +# # spread="wide" +# # )) + + + + + + + + +# asyncio.run(handler.run_protocol()) + +# # 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.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.")