Merge branch '37-biomek-i5i7' of https://github.com/dptech-corp/Uni-Lab-OS into 37-biomek-i5i7

This commit is contained in:
Junhan Chang
2025-06-07 18:52:23 +08:00
4 changed files with 8023 additions and 354 deletions

View File

@@ -692,39 +692,28 @@ if __name__ == "__main__":
] ]
} }
''' '''
labware_with_liquid = '''
[ {
"id": "stock plate on P1",
labware_with_liquid = '''
[
{
"id": "Tip Rack BC230 on TL1",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P1", "slot_on_deck": "TL1",
"class_name": "nest_12_reservoir_15ml", "class_name": "BC230",
"liquid_type": [ "liquid_type": [],
"master_mix" "liquid_volume": [],
], "liquid_input_wells": []
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
}, },
{ {
"id": "Tip Rack BC230 TL2", "id": "Tip Rack BC230 on TL2",
"parent": "deck", "parent": "deck",
"slot_on_deck": "TL2", "slot_on_deck": "TL2",
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
},
{
"id": "Tip Rack BC230 TL2",
"parent": "deck",
"slot_on_deck": "TL2",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
}, },
{ {
"id": "Tip Rack BC230 on TL3", "id": "Tip Rack BC230 on TL3",
@@ -733,8 +722,7 @@ if __name__ == "__main__":
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on TL4", "id": "Tip Rack BC230 on TL4",
@@ -743,8 +731,7 @@ if __name__ == "__main__":
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on TL5", "id": "Tip Rack BC230 on TL5",
@@ -753,8 +740,7 @@ if __name__ == "__main__":
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P5", "id": "Tip Rack BC230 on P5",
@@ -763,8 +749,7 @@ if __name__ == "__main__":
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P6", "id": "Tip Rack BC230 on P6",
@@ -773,46 +758,33 @@ if __name__ == "__main__":
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P7", "id": "Tip Rack BC230 on P15",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P7", "slot_on_deck": "P15",
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P8", "id": "Tip Rack BC230 on P16",
"parent": "deck",
"slot_on_deck": "P8",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 P16",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P16", "slot_on_deck": "P16",
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "stock plate on 4", "id": "stock plate on P1",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P2", "slot_on_deck": "P1",
"class_name": "nest_12_reservoir_15ml", "class_name": "nest_12_reservoir_15ml",
"liquid_type": [ "liquid_type": [
"bind beads" "master_mix"
], ],
"liquid_volume": [10000], "liquid_volume": [10000],
"liquid_input_wells": [ "liquid_input_wells": [
@@ -845,7 +817,19 @@ if __name__ == "__main__":
"A1" "A1"
] ]
}, },
{
"id": "elution buffer on P4",
"parent": "deck",
"slot_on_deck": "P4",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"elution buffer"
],
"liquid_volume": [5000],
"liquid_input_wells": [
"A1"
]
},
{ {
"id": "oscillation", "id": "oscillation",
"parent": "deck", "parent": "deck",
@@ -853,19 +837,16 @@ if __name__ == "__main__":
"class_name": "Orbital", "class_name": "Orbital",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "working plate on P11", "id": "working plate on P11",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P11", "slot_on_deck": "P11",
"class_name": "NEST 2ml Deep Well Plate", "class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [ "liquid_type": [],
],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "magnetics module on P12", "id": "magnetics module on P12",
@@ -874,46 +855,43 @@ if __name__ == "__main__":
"class_name": "magnetics module", "class_name": "magnetics module",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "working plate on P13", "id": "working plate on P13",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P13", "slot_on_deck": "P13",
"class_name": "NEST 2ml Deep Well Plate", "class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [ "liquid_type": [],
],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "waste on P22", "id": "waste on P22",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P22", "slot_on_deck": "P22",
"class_name": "nest_1_reservoir_195ml", "class_name": "nest_1_reservoir_195ml",
"liquid_type": [ "liquid_type": [],
],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
} }
] ]
''' '''
handler = LiquidHandlerBiomek()
handler.temp_protocol = {
handler = LiquidHandlerBiomek()
handler.temp_protocol = {
"meta": {}, "meta": {},
"labwares": [], "labwares": [],
"steps": [] "steps": []
} }
input_steps = json.loads(steps_info) input_steps = json.loads(steps_info)
labwares = json.loads(labware_with_liquid) labwares = json.loads(labware_with_liquid)
for step in input_steps['steps']: for step in input_steps['steps']:
operation = step['operation'] operation = step['operation']
parameters = step['parameters'] parameters = step['parameters']
@@ -933,6 +911,6 @@ if __name__ == "__main__":
elif operation == 'incubation': elif operation == 'incubation':
handler.incubation_biomek(time=parameters['time']) handler.incubation_biomek(time=parameters['time'])
print(json.dumps(handler.temp_protocol, indent=4)) print(json.dumps(handler.temp_protocol, indent=4))

View File

@@ -13,6 +13,7 @@ from typing import List, Sequence, Optional, Union, Literal
# from .liquid_handler_abstract import LiquidHandlerAbstract # from .liquid_handler_abstract import LiquidHandlerAbstract
import json import json
import pathlib
from typing import Sequence, Optional, List, Union, Literal from typing import Sequence, Optional, List, Union, Literal
@@ -33,6 +34,23 @@ class LiquidHandlerBiomek:
self._status_queue = kwargs.get("status_queue", None) # 状态队列 self._status_queue = kwargs.get("status_queue", None) # 状态队列
self.temp_protocol = {} self.temp_protocol = {}
self.py32_path = "/opt/py32" # Biomek的Python 3.2路径 self.py32_path = "/opt/py32" # Biomek的Python 3.2路径
# 预定义的仪器分类
self.tip_racks = [
"BC230", "BC1025F", "BC50", "TipRack200", "TipRack1000",
"tip", "tips", "Tip", "Tips"
]
self.reservoirs = [
"AgilentReservoir", "nest_12_reservoir_15ml", "nest_1_reservoir_195ml",
"reservoir", "Reservoir", "waste", "Waste"
]
self.plates_96 = [
"BCDeep96Round", "Matrix96_750uL", "NEST 2ml Deep Well Plate", "nest_96_wellplate_100ul_pcr_full_skirt",
"nest_96_wellplate_200ul_flat", "Matrix96", "96", "plate", "Plate"
]
self.aspirate_techniques = { self.aspirate_techniques = {
'MC P300 high':{ 'MC P300 high':{
'Position': 'P1', 'Position': 'P1',
@@ -49,7 +67,7 @@ class LiquidHandlerBiomek:
'LocalPattern': True, 'LocalPattern': True,
'Operation': 'Aspirate', 'Operation': 'Aspirate',
'OverrideHeight': False, 'OverrideHeight': False,
'Pattern': (True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True), 'Pattern': (True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True),
'Prototype': 'MC P300 High', 'Prototype': 'MC P300 High',
'ReferencedPattern': '', 'ReferencedPattern': '',
'RowsFirst': False, 'RowsFirst': False,
@@ -92,6 +110,30 @@ class LiquidHandlerBiomek:
} }
def _get_instrument_type(self, class_name: str) -> str:
"""
根据class_name判断仪器类型
Returns:
str: "tip_rack", "reservoir", "plate_96", 或 "unknown"
"""
# 检查是否是枪头架
for tip_name in self.tip_racks:
if tip_name in class_name:
return "tip_rack"
# 检查是否是储液槽
for reservoir_name in self.reservoirs:
if reservoir_name in class_name:
return "reservoir"
# 检查是否是96孔板
for plate_name in self.plates_96:
if plate_name in class_name:
return "plate_96"
return "unknown"
def create_protocol( def create_protocol(
self, self,
protocol_name: str, protocol_name: str,
@@ -126,7 +168,7 @@ class LiquidHandlerBiomek:
"date": protocol_date, "date": protocol_date,
"type": protocol_type, "type": protocol_type,
}, },
"labwares": [], "labwares": {}, # 改为字典格式以匹配DeckItems
"steps": [], "steps": [],
} }
return self.temp_protocol return self.temp_protocol
@@ -198,7 +240,101 @@ class LiquidHandlerBiomek:
# } # }
# self.temp_protocol["labwares"].append(resource) # self.temp_protocol["labwares"].append(resource)
# return resource # return resource
def instrument_setup_biomek(
self,
id: str,
parent: str,
slot_on_deck: str,
class_name: str,
liquid_type: list[str],
liquid_volume: list[int],
liquid_input_wells: list[str],
):
"""
设置Biomek仪器的参数配置按照DeckItems格式
根据不同的仪器类型容器、tip rack等设置相应的参数结构
位置作为键,配置列表作为值
"""
# 判断仪器类型
instrument_type = self._get_instrument_type(class_name)
config = None # 初始化为None
if instrument_type == "reservoir":
# 储液槽类型配置
config = {
"Properties": {
"Name": id, # 使用id作为名称
"Device": "",
"liquidtype": liquid_type[0] if liquid_type else "Water",
"BarCode": "",
"SenseEveryTime": False
},
"Known": True,
"Class": f"LabwareClasses\\{class_name}",
"DataSets": {"Volume": {}},
"RuntimeDataSets": {"Volume": {}},
"EvalAmounts": (float(liquid_volume[0]),) if liquid_volume else (0.0,),
"Nominal": False,
"EvalLiquids": (liquid_type[0],) if liquid_type else ("Water",)
}
elif instrument_type == "plate_96":
# 96孔板类型配置
volume_per_well = float(liquid_volume[0]) if liquid_volume else 500.0
liquid_per_well = liquid_type[0] if liquid_type else "Water"
config = {
"Properties": {
"Name": id, # 使用id作为名称
"Device": "",
"liquidtype": liquid_per_well,
"BarCode": "",
"SenseEveryTime": False
},
"Known": True,
"Class": f"LabwareClasses\\{class_name}",
"DataSets": {"Volume": {}},
"RuntimeDataSets": {"Volume": {}},
"EvalAmounts": tuple([volume_per_well] * 96),
"Nominal": False,
"EvalLiquids": tuple([liquid_per_well] * 96)
}
elif instrument_type == "tip_rack":
# 枪头架类型配置
tip_config = {
"Class": "TipClasses\\T230",
"Contents": [],
"_RT_Contents": [],
"Used": False,
"RT_Used": False,
"Dirty": False,
"RT_Dirty": False,
"MaxVolumeUsed": 0.0,
"RT_MaxVolumeUsed": 0.0
}
config = {
"Tips": tip_config,
"RT_Tips": tip_config.copy(),
"Properties": {},
"Known": False,
"Class": f"LabwareClasses\\{class_name}",
"DataSets": {"Volume": {}},
"RuntimeDataSets": {"Volume": {}}
}
# 按照DeckItems格式存储位置作为键配置列表作为值
if config is not None:
self.temp_protocol["labwares"][slot_on_deck] = [config]
else:
# 空位置
self.temp_protocol["labwares"][slot_on_deck] = []
return
def transfer_biomek( def transfer_biomek(
self, self,
@@ -266,7 +402,8 @@ class LiquidHandlerBiomek:
transfer_params["items"] = items transfer_params["items"] = items
transfer_params["Solvent"] = 'Water' transfer_params["Solvent"] = 'Water'
transfer_params["TipLocation"] = tip_rack transfer_params["TipLocation"] = tip_rack
self.temp_protocol["steps"].append(transfer_params) tmp={'transfer': transfer_params}
self.temp_protocol["steps"].append(tmp)
return return
@@ -287,7 +424,8 @@ class LiquidHandlerBiomek:
"Target": target, "Target": target,
"LeaveBottomLabware": False, "LeaveBottomLabware": False,
} }
self.temp_protocol["steps"].append(move_params) tmp={'move': move_params}
self.temp_protocol["steps"].append(tmp)
return return
@@ -304,7 +442,8 @@ class LiquidHandlerBiomek:
"Time": time, "Time": time,
"Mode": "TimedResource" "Mode": "TimedResource"
} }
self.temp_protocol["steps"].append(incubation_params) tmp={'incubation': incubation_params}
self.temp_protocol["steps"].append(tmp)
return return
@@ -321,7 +460,8 @@ class LiquidHandlerBiomek:
'Parameters': (str(rpm), '2', str(time), 'CounterClockwise'), 'Parameters': (str(rpm), '2', str(time), 'CounterClockwise'),
'Command': 'Timed Shake' 'Command': 'Timed Shake'
} }
self.temp_protocol["steps"].append(oscillation_params) tmp={'oscillation': oscillation_params}
self.temp_protocol["steps"].append(tmp)
return return
@@ -329,6 +469,10 @@ class LiquidHandlerBiomek:
if __name__ == "__main__": if __name__ == "__main__":
print("=== Biomek完整流程测试 ===")
print("包含: 仪器设置 + 完整实验步骤")
# 完整的步骤信息从biomek.py复制
steps_info = ''' steps_info = '''
{ {
"steps": [ "steps": [
@@ -592,41 +736,26 @@ if __name__ == "__main__":
} }
''' '''
# 完整的labware配置信息从biomek.py复制
labware_with_liquid = '''
labware_with_liquid = ''' [
[ { {
"id": "stock plate on P1", "id": "Tip Rack BC230 on TL1",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P1", "slot_on_deck": "TL1",
"class_name": "nest_12_reservoir_15ml", "class_name": "BC230",
"liquid_type": [ "liquid_type": [],
"master_mix" "liquid_volume": [],
], "liquid_input_wells": []
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
}, },
{ {
"id": "Tip Rack BC230 TL2", "id": "Tip Rack BC230 on TL2",
"parent": "deck", "parent": "deck",
"slot_on_deck": "TL2", "slot_on_deck": "TL2",
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
},
{
"id": "Tip Rack BC230 TL2",
"parent": "deck",
"slot_on_deck": "TL2",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
}, },
{ {
"id": "Tip Rack BC230 on TL3", "id": "Tip Rack BC230 on TL3",
@@ -635,8 +764,7 @@ labware_with_liquid = '''
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on TL4", "id": "Tip Rack BC230 on TL4",
@@ -645,8 +773,7 @@ labware_with_liquid = '''
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on TL5", "id": "Tip Rack BC230 on TL5",
@@ -655,8 +782,7 @@ labware_with_liquid = '''
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P5", "id": "Tip Rack BC230 on P5",
@@ -665,8 +791,7 @@ labware_with_liquid = '''
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P6", "id": "Tip Rack BC230 on P6",
@@ -675,46 +800,33 @@ labware_with_liquid = '''
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P7", "id": "Tip Rack BC230 on P15",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P7", "slot_on_deck": "P15",
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "Tip Rack BC230 on P8", "id": "Tip Rack BC230 on P16",
"parent": "deck",
"slot_on_deck": "P8",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 P16",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P16", "slot_on_deck": "P16",
"class_name": "BC230", "class_name": "BC230",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "stock plate on 4", "id": "stock plate on P1",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P2", "slot_on_deck": "P1",
"class_name": "nest_12_reservoir_15ml", "class_name": "nest_12_reservoir_15ml",
"liquid_type": [ "liquid_type": [
"bind beads" "master_mix"
], ],
"liquid_volume": [10000], "liquid_volume": [10000],
"liquid_input_wells": [ "liquid_input_wells": [
@@ -747,7 +859,19 @@ labware_with_liquid = '''
"A1" "A1"
] ]
}, },
{
"id": "elution buffer on P4",
"parent": "deck",
"slot_on_deck": "P4",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"elution buffer"
],
"liquid_volume": [5000],
"liquid_input_wells": [
"A1"
]
},
{ {
"id": "oscillation", "id": "oscillation",
"parent": "deck", "parent": "deck",
@@ -755,19 +879,16 @@ labware_with_liquid = '''
"class_name": "Orbital", "class_name": "Orbital",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "working plate on P11", "id": "working plate on P11",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P11", "slot_on_deck": "P11",
"class_name": "NEST 2ml Deep Well Plate", "class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [ "liquid_type": [],
],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "magnetics module on P12", "id": "magnetics module on P12",
@@ -776,66 +897,114 @@ labware_with_liquid = '''
"class_name": "magnetics module", "class_name": "magnetics module",
"liquid_type": [], "liquid_type": [],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "working plate on P13", "id": "working plate on P13",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P13", "slot_on_deck": "P13",
"class_name": "NEST 2ml Deep Well Plate", "class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [ "liquid_type": [],
],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
}, },
{ {
"id": "waste on P22", "id": "waste on P22",
"parent": "deck", "parent": "deck",
"slot_on_deck": "P22", "slot_on_deck": "P22",
"class_name": "nest_1_reservoir_195ml", "class_name": "nest_1_reservoir_195ml",
"liquid_type": [ "liquid_type": [],
],
"liquid_volume": [], "liquid_volume": [],
"liquid_input_wells": [ "liquid_input_wells": []
]
} }
] ]
''' '''
# 创建handler实例
handler = LiquidHandlerBiomek()
# 创建协议
protocol = handler.create_protocol(
protocol_name="DNA纯化完整流程",
protocol_description="使用磁珠进行DNA纯化的完整自动化流程",
protocol_version="1.0",
protocol_author="Biomek系统",
protocol_date="2024-01-01",
protocol_type="DNA_purification"
)
handler = LiquidHandlerBiomek() print("\n=== 第一步:设置所有仪器 ===")
# 解析labware配置
labwares = json.loads(labware_with_liquid)
handler.temp_protocol = { # 设置所有仪器
"meta": {}, instrument_count = 0
"labwares": [], for labware in labwares:
"steps": [] print(f"设置仪器: {labware['id']} ({labware['class_name']}) 在位置 {labware['slot_on_deck']}")
} handler.instrument_setup_biomek(
id=labware['id'],
parent=labware['parent'],
slot_on_deck=labware['slot_on_deck'],
class_name=labware['class_name'],
liquid_type=labware['liquid_type'],
liquid_volume=labware['liquid_volume'],
liquid_input_wells=labware['liquid_input_wells']
)
instrument_count += 1
input_steps = json.loads(steps_info) print(f"总共设置了 {instrument_count} 个仪器位置")
labwares = json.loads(labware_with_liquid)
for step in input_steps['steps']: print("\n=== 第二步:执行实验步骤 ===")
# 解析步骤信息
input_steps = json.loads(steps_info)
# 执行所有步骤
step_count = 0
for step in input_steps['steps']:
operation = step['operation'] operation = step['operation']
parameters = step['parameters'] parameters = step['parameters']
description = step['description']
print(f"步骤 {step['step_number']}: {description}")
if operation == 'transfer': if operation == 'transfer':
handler.transfer_biomek(source=parameters['source'], handler.transfer_biomek(
source=parameters['source'],
target=parameters['target'], target=parameters['target'],
volume=parameters['volume'], volume=parameters['volume'],
tip_rack=parameters['tip_rack'], tip_rack=parameters['tip_rack'],
aspirate_techniques='MC P300 high', aspirate_techniques='MC P300 high',
dispense_techniques='MC P300 high') dispense_techniques='MC P300 high'
)
elif operation == 'move_labware': elif operation == 'move_labware':
handler.move_biomek(source=parameters['source'], handler.move_biomek(
target=parameters['target']) source=parameters['source'],
target=parameters['target']
)
elif operation == 'oscillation': elif operation == 'oscillation':
handler.oscillation_biomek(rpm=parameters['rpm'], handler.oscillation_biomek(
time=parameters['time']) rpm=parameters['rpm'],
time=parameters['time']
)
elif operation == 'incubation': elif operation == 'incubation':
handler.incubation_biomek(time=parameters['time']) handler.incubation_biomek(
time=parameters['time']
)
print(json.dumps(handler.temp_protocol, indent=4)) step_count += 1
print(f"总共执行了 {step_count} 个步骤")
print("\n=== 第三步:保存完整协议 ===")
# 获取脚本目录
script_dir = pathlib.Path(__file__).parent
# 保存完整协议
complete_output_path = script_dir / "complete_biomek_protocol_0607.json"
with open(complete_output_path, 'w', encoding='utf-8') as f:
json.dump(handler.temp_protocol, f, indent=4, ensure_ascii=False)
print(f"完整协议已保存到: {complete_output_path}")
print("\n=== 测试完成 ===")
print("完整的DNA纯化流程已成功转换为Biomek格式")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff