New transfer_biomek

This commit is contained in:
Guangxin Zhang
2025-06-04 21:29:54 +08:00
parent 5b240cb0ea
commit e63c15997c
2 changed files with 867 additions and 133 deletions

View File

@@ -1,7 +1,7 @@
import requests import requests
from typing import List, Sequence, Optional, Union, Literal from typing import List, Sequence, Optional, Union, Literal
from geometry_msgs.msg import Point from geometry_msgs.msg import Point
from unilabos_msgs.msg import Resource #from unilabos_msgs.msg import Resource
from pylabrobot.resources import ( from pylabrobot.resources import (
TipRack, TipRack,
@@ -29,25 +29,45 @@ class LiquidHandlerBiomek(LiquidHandlerAbstract):
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.technique = { self.aspirate_techniques = {
'MC P300 high':{ 'MC P300 high':{
"use_channels": "Span8", "Solvent": "Water",
"asp_vols": [50], }
"asp_flow_rates": 50, }
"dis_flow_rates": 50, self.dispense_techniques = {
"offsets": None, 'MC P300 high':{
"touch_tip": True, "Span8": False,
"liquid_height": 20, "Pod": "Pod1",
"blow_out_air_volume": 20, "Wash": False,
"spread": "wide", "Dynamic?": True,
"is_96_well": True, "AutoSelectActiveWashTechnique": False,
"mix_stage": "none", "ActiveWashTechnique": "",
"mix_times": None, "ChangeTipsBetweenDests": True,
"mix_vol": None, "ChangeTipsBetweenSources": False,
"mix_rate": None, "DefaultCaption": "",
"mix_liquid_height": None, "UseExpression": False,
"delays": None, "LeaveTipsOn": False,
"none_keys": [] "MandrelExpression": "",
"Repeats": "1",
"RepeatsByVolume": False,
"Replicates": "1",
"ShowTipHandlingDetails": False,
"ShowTransferDetails": True,
"Span8Wash": False,
"Span8WashVolume": "2",
"Span8WasteVolume": "1",
"SplitVolume": False,
"SplitVolumeCleaning": False,
"Stop": "Destinations",
"UseCurrentTips": False,
"UseDisposableTips": False,
"UseFixedTips": False,
"UseJIT": True,
"UseMandrelSelection": True,
"UseProbes": [True, True, True, True, True, True, True, True],
"WashCycles": "3",
"WashVolume": "110%",
"Wizard": False
} }
} }
@@ -171,8 +191,6 @@ class LiquidHandlerBiomek(LiquidHandlerAbstract):
sources: Sequence[Container], sources: Sequence[Container],
targets: Sequence[Container], targets: Sequence[Container],
tip_racks: Sequence[TipRack], tip_racks: Sequence[TipRack],
solvent: Optional[str] = None,
TipLocation :str = None,
*, *,
use_channels: Optional[List[int]] = None, use_channels: Optional[List[int]] = None,
asp_vols: Union[List[float], float], asp_vols: Union[List[float], float],
@@ -213,7 +231,7 @@ class LiquidHandlerBiomek(LiquidHandlerAbstract):
"Replicates": "1", "Replicates": "1",
"ShowTipHandlingDetails": False, "ShowTipHandlingDetails": False,
"ShowTransferDetails": True, "ShowTransferDetails": True,
"Solvent": "Water", "Solvent": "Well Content",
"Span8Wash": False, "Span8Wash": False,
"Span8WashVolume": "2", "Span8WashVolume": "2",
"Span8WasteVolume": "1", "Span8WasteVolume": "1",
@@ -240,7 +258,9 @@ class LiquidHandlerBiomek(LiquidHandlerAbstract):
"Volume": dis_vols[idx] "Volume": dis_vols[idx]
} }
transfer_params["items"] = items transfer_params["items"] = items
transfer_params["Solvent"] = solvent if solvent else "Water" transfer_params["Solvent"] = solvent if solvent else "Water"
TipLocation = tip_racks[0].name
transfer_params["TipLocation"] = TipLocation transfer_params["TipLocation"] = TipLocation
if len(tip_racks) == 1: if len(tip_racks) == 1:
@@ -251,30 +271,564 @@ class LiquidHandlerBiomek(LiquidHandlerAbstract):
self.temp_protocol["steps"].append(transfer_params) self.temp_protocol["steps"].append(transfer_params)
return return
def transfer_biomek( def transfer_biomek(
self, self,
parameters: dict, source: str,
technique: str, target: str,
tip_rack: str,
volume: float,
aspirate_techniques: str,
dispense_techniques: str,
): ):
""" """
处理Biomek的液体转移操作。 处理Biomek的液体转移操作。
""" """
sources = parameters.get("source")
targets = parameters.get("target") asp_params = self.aspirate_techniques.get(aspirate_techniques, {})
tip_rack = parameters.get("tip_rack") dis_params = self.dispense_techniques.get(dispense_techniques, {})
volume = parameters.get("volume")
liquid_type = parameters.get("liquid_type", "Well Content")
other_params = self.technique.get(technique, {})
self.transfer_liquid( transfer_params = {
sources=[sources], "Span8": False,
targets=[targets], "Pod": "Pod1",
TipLocation=tip_rack, "items": {},
tip_racks=[tip_rack], "Wash": False,
solvent=liquid_type, "Dynamic?": True,
dis_vols=[volume], "AutoSelectActiveWashTechnique": False,
**other_params "ActiveWashTechnique": "",
) "ChangeTipsBetweenDests": False,
"ChangeTipsBetweenSources": True,
"DefaultCaption": "",
"UseExpression": False,
"LeaveTipsOn": False,
"MandrelExpression": "",
"Repeats": "1",
"RepeatsByVolume": False,
"Replicates": "1",
"ShowTipHandlingDetails": False,
"ShowTransferDetails": True,
"Solvent": "Water",
"Span8Wash": False,
"Span8WashVolume": "2",
"Span8WasteVolume": "1",
"SplitVolume": False,
"SplitVolumeCleaning": False,
"Stop": "Destinations",
"TipLocation": "BC1025F",
"UseCurrentTips": False,
"UseDisposableTips": True,
"UseFixedTips": False,
"UseJIT": True,
"UseMandrelSelection": True,
"UseProbes": [True, True, True, True, True, True, True, True],
"WashCycles": "1",
"WashVolume": "110%",
"Wizard": False
}
items: dict = {}
items["Source"] = source
items["Destination"] = target
items["Volume"] = volume
transfer_params["items"] = items
transfer_params["Solvent"] = asp_params['Solvent']
transfer_params["TipLocation"] = tip_rack
transfer_params.update(asp_params)
transfer_params.update(dis_params)
self.temp_protocol["steps"].append(transfer_params)
return return
steps_info = '''
{
"steps": [
{
"step_number": 1,
"operation": "transfer",
"description": "转移PCR产物或酶促反应液至0.05ml 96孔板中",
"parameters": {
"source": "P1",
"target": "P11",
"tip_rack": "BC230",
"volume": 50
}
},
{
"step_number": 2,
"operation": "transfer",
"description": "加入2倍体积Bind Beads BC至产物中",
"parameters": {
"source": "P2",
"target": "P11",
"tip_rack": "BC230",
"volume": 100
}
},
{
"step_number": 3,
"operation": "move_labware",
"description": "移动P11至Orbital1用于振荡混匀",
"parameters": {
"source": "P11",
"target": "Orbital1"
}
},
{
"step_number": 4,
"operation": "oscillation",
"description": "在Orbital1上振荡混匀Bind Beads BC与PCR产物700-900rpm300秒",
"parameters": {
"rpm": 800,
"time": 300
}
},
{
"step_number": 5,
"operation": "move_labware",
"description": "移动混匀后的板回P11",
"parameters": {
"source": "Orbital1",
"target": "P11"
}
},
{
"step_number": 6,
"operation": "move_labware",
"description": "将P11移动到磁力架P12吸附3分钟",
"parameters": {
"source": "P11",
"target": "P12"
}
},
{
"step_number": 7,
"operation": "incubation",
"description": "磁力架上室温静置3分钟完成吸附",
"parameters": {
"time": 180
}
},
{
"step_number": 8,
"operation": "transfer",
"description": "去除上清液至废液槽",
"parameters": {
"source": "P12",
"target": "P22",
"tip_rack": "BC230",
"volume": 150
}
},
{
"step_number": 9,
"operation": "transfer",
"description": "加入300-500μl 75%乙醇清洗",
"parameters": {
"source": "P3",
"target": "P12",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 10,
"operation": "move_labware",
"description": "移动清洗板到Orbital1进行振荡",
"parameters": {
"source": "P12",
"target": "Orbital1"
}
},
{
"step_number": 11,
"operation": "oscillation",
"description": "乙醇清洗液振荡混匀700-900rpm, 45秒",
"parameters": {
"rpm": 800,
"time": 45
}
},
{
"step_number": 12,
"operation": "move_labware",
"description": "振荡后将板移回磁力架P12吸附",
"parameters": {
"source": "Orbital1",
"target": "P12"
}
},
{
"step_number": 13,
"operation": "incubation",
"description": "吸附3分钟",
"parameters": {
"time": 180
}
},
{
"step_number": 14,
"operation": "transfer",
"description": "去除乙醇上清液至废液槽",
"parameters": {
"source": "P12",
"target": "P22",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 15,
"operation": "transfer",
"description": "第二次加入300-500μl 75%乙醇清洗",
"parameters": {
"source": "P3",
"target": "P12",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 16,
"operation": "move_labware",
"description": "再次移动清洗板到Orbital1振荡",
"parameters": {
"source": "P12",
"target": "Orbital1"
}
},
{
"step_number": 17,
"operation": "oscillation",
"description": "再次乙醇清洗液振荡混匀700-900rpm, 45秒",
"parameters": {
"rpm": 800,
"time": 45
}
},
{
"step_number": 18,
"operation": "move_labware",
"description": "振荡后板送回磁力架P12吸附",
"parameters": {
"source": "Orbital1",
"target": "P12"
}
},
{
"step_number": 19,
"operation": "incubation",
"description": "再次吸附3分钟",
"parameters": {
"time": 180
}
},
{
"step_number": 20,
"operation": "transfer",
"description": "去除乙醇上清液至废液槽",
"parameters": {
"source": "P12",
"target": "P22",
"tip_rack": "BC230",
"volume": 400
}
},
{
"step_number": 21,
"operation": "incubation",
"description": "空气干燥15分钟",
"parameters": {
"time": 900
}
},
{
"step_number": 22,
"operation": "transfer",
"description": "加30-50μl Elution Buffer洗脱",
"parameters": {
"source": "P4",
"target": "P12",
"tip_rack": "BC230",
"volume": 40
}
},
{
"step_number": 23,
"operation": "move_labware",
"description": "移动到Orbital1振荡混匀60秒",
"parameters": {
"source": "P12",
"target": "Orbital1"
}
},
{
"step_number": 24,
"operation": "oscillation",
"description": "Elution Buffer振荡混匀700-900rpm, 60秒",
"parameters": {
"rpm": 800,
"time": 60
}
},
{
"step_number": 25,
"operation": "move_labware",
"description": "振荡后送回磁力架P12",
"parameters": {
"source": "Orbital1",
"target": "P12"
}
},
{
"step_number": 26,
"operation": "incubation",
"description": "室温静置3分钟洗脱反应",
"parameters": {
"time": 180
}
},
{
"step_number": 27,
"operation": "transfer",
"description": "将上清液DNA转移到新板P13",
"parameters": {
"source": "P12",
"target": "P13",
"tip_rack": "BC230",
"volume": 40
}
}
]
}
'''
labware_with_liquid = '''
[ {
"id": "stock plate on P1",
"parent": "deck",
"slot_on_deck": "P1",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"master_mix"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"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",
"parent": "deck",
"slot_on_deck": "TL3",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on TL4",
"parent": "deck",
"slot_on_deck": "TL4",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on TL5",
"parent": "deck",
"slot_on_deck": "TL5",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P5",
"parent": "deck",
"slot_on_deck": "P5",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P6",
"parent": "deck",
"slot_on_deck": "P6",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P7",
"parent": "deck",
"slot_on_deck": "P7",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P8",
"parent": "deck",
"slot_on_deck": "P8",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 P16",
"parent": "deck",
"slot_on_deck": "P16",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "stock plate on 4",
"parent": "deck",
"slot_on_deck": "P2",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"bind beads"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"id": "stock plate on P2",
"parent": "deck",
"slot_on_deck": "P2",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"bind beads"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"id": "stock plate on P3",
"parent": "deck",
"slot_on_deck": "P3",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"ethyl alcohol"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"id": "oscillation",
"parent": "deck",
"slot_on_deck": "Orbital1",
"class_name": "Orbital",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "working plate on P11",
"parent": "deck",
"slot_on_deck": "P11",
"class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [
],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "magnetics module on P12",
"parent": "deck",
"slot_on_deck": "P12",
"class_name": "magnetics module",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "working plate on P13",
"parent": "deck",
"slot_on_deck": "P13",
"class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [
],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "waste on P22",
"parent": "deck",
"slot_on_deck": "P22",
"class_name": "nest_1_reservoir_195ml",
"liquid_type": [
],
"liquid_volume": [],
"liquid_input_wells": [
]
}
]
'''
handler = LiquidHandlerBiomek()
handler.temp_protocol = {
"meta": {},
"labwares": [],
"steps": []
}
input_steps = json.loads(steps_info)
labwares = json.loads(labware_with_liquid)
for step in input_steps['steps']:
if step['operation'] != 'transfer':
continue
parameters = step['parameters']
tip_rack=parameters['tip_rack']
# 找到labwares中与tip_rack匹配的项的id
tip_rack_id = [lw['id'] for lw in labwares if lw['class_name'] == tip_rack][0]
handler.transfer_biomek(source=parameters['source'],
target=parameters['target'],
volume=parameters['volume'],
tip_rack=tip_rack_id,
aspirate_techniques='MC P300 high',
dispense_techniques='MC P300 high'
)
print(json.dumps(handler.temp_protocol['steps'],indent=4, ensure_ascii=False))

View File

@@ -296,25 +296,45 @@ 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.technique = { self.aspirate_techniques = {
'MC P300 high':{ 'MC P300 high':{
"use_channels": "Span8", "Solvent": "Water",
"asp_vols": [50], }
"asp_flow_rates": 50, }
"dis_flow_rates": 50, self.dispense_techniques = {
"offsets": None, 'MC P300 high':{
"touch_tip": True, "Span8": False,
"liquid_height": 20, "Pod": "Pod1",
"blow_out_air_volume": 20, "Wash": False,
"spread": "wide", "Dynamic?": True,
"is_96_well": True, "AutoSelectActiveWashTechnique": False,
"mix_stage": "none", "ActiveWashTechnique": "",
"mix_times": None, "ChangeTipsBetweenDests": True,
"mix_vol": None, "ChangeTipsBetweenSources": False,
"mix_rate": None, "DefaultCaption": "",
"mix_liquid_height": None, "UseExpression": False,
"delays": None, "LeaveTipsOn": False,
"none_keys": [] "MandrelExpression": "",
"Repeats": "1",
"RepeatsByVolume": False,
"Replicates": "1",
"ShowTipHandlingDetails": False,
"ShowTransferDetails": True,
"Span8Wash": False,
"Span8WashVolume": "2",
"Span8WasteVolume": "1",
"SplitVolume": False,
"SplitVolumeCleaning": False,
"Stop": "Destinations",
"UseCurrentTips": False,
"UseDisposableTips": False,
"UseFixedTips": False,
"UseJIT": True,
"UseMandrelSelection": True,
"UseProbes": [True, True, True, True, True, True, True, True],
"WashCycles": "3",
"WashVolume": "110%",
"Wizard": False
} }
} }
@@ -425,34 +445,24 @@ class LiquidHandlerBiomek:
# } # }
# self.temp_protocol["labwares"].append(resource) # self.temp_protocol["labwares"].append(resource)
# return resource # return resource
def transfer_liquid( def transfer_biomek(
self, self,
sources: Sequence[Container], source: str,
targets: Sequence[Container], target: str,
tip_racks: Sequence[TipRack], tip_rack: str,
solvent: Optional[str] = None, volume: float,
TipLocation :str = None, aspirate_techniques: str,
*, dispense_techniques: str,
use_channels: Optional[List[int]] = None,
asp_vols: Union[List[float], float],
dis_vols: Union[List[float], float],
asp_flow_rates: Optional[List[Optional[float]]] = None,
dis_flow_rates: Optional[List[Optional[float]]] = None,
offsets: Optional[List[Coordinate]] = None,
touch_tip: bool = False,
liquid_height: Optional[List[Optional[float]]] = None,
blow_out_air_volume: Optional[List[Optional[float]]] = None,
spread: Literal["wide", "tight", "custom"] = "wide",
is_96_well: bool = False,
mix_stage: Optional[Literal["none", "before", "after", "both"]] = "none",
mix_times: Optional[int] = None,
mix_vol: Optional[int] = None,
mix_rate: Optional[int] = None,
mix_liquid_height: Optional[float] = None,
delays: Optional[List[int]] = None,
none_keys: List[str] = []
): ):
"""
处理Biomek的液体转移操作。
"""
asp_params = self.aspirate_techniques.get(aspirate_techniques, {})
dis_params = self.dispense_techniques.get(dispense_techniques, {})
transfer_params = { transfer_params = {
"Span8": False, "Span8": False,
@@ -463,7 +473,7 @@ class LiquidHandlerBiomek:
"AutoSelectActiveWashTechnique": False, "AutoSelectActiveWashTechnique": False,
"ActiveWashTechnique": "", "ActiveWashTechnique": "",
"ChangeTipsBetweenDests": False, "ChangeTipsBetweenDests": False,
"ChangeTipsBetweenSources": False, "ChangeTipsBetweenSources": True,
"DefaultCaption": "", "DefaultCaption": "",
"UseExpression": False, "UseExpression": False,
"LeaveTipsOn": False, "LeaveTipsOn": False,
@@ -493,61 +503,220 @@ class LiquidHandlerBiomek:
} }
items: dict = {} items: dict = {}
for idx, (src, dst) in enumerate(zip(sources, targets)): items["Source"] = source
items[str(idx)] = { items["Destination"] = target
"Source": str(src), items["Volume"] = volume
"Destination": str(dst),
"Volume": dis_vols[idx]
}
transfer_params["items"] = items transfer_params["items"] = items
transfer_params["Solvent"] = solvent if solvent else "Water" transfer_params["Solvent"] = asp_params['Solvent']
transfer_params["TipLocation"] = TipLocation transfer_params["TipLocation"] = tip_rack
transfer_params.update(asp_params)
if len(tip_racks) == 1: transfer_params.update(dis_params)
transfer_params['UseCurrentTips'] = True
elif len(tip_racks) > 1:
transfer_params["ChangeTipsBetweenDests"] = True
self.temp_protocol["steps"].append(transfer_params) self.temp_protocol["steps"].append(transfer_params)
return return
def transfer_biomek(
self,
parameters: dict,
technique: str,
):
"""
创建一个Biomek液体处理器的转移步骤。
Args: labware_with_liquid = '''
step_number (int): 步骤编号 [ {
operation (str): 操作类型 "id": "stock plate on P1",
description (str): 步骤描述 "parent": "deck",
parameters (dict): 步骤参数 "slot_on_deck": "P1",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"master_mix"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"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",
"parent": "deck",
"slot_on_deck": "TL3",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on TL4",
"parent": "deck",
"slot_on_deck": "TL4",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on TL5",
"parent": "deck",
"slot_on_deck": "TL5",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P5",
"parent": "deck",
"slot_on_deck": "P5",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P6",
"parent": "deck",
"slot_on_deck": "P6",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P7",
"parent": "deck",
"slot_on_deck": "P7",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 on P8",
"parent": "deck",
"slot_on_deck": "P8",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "Tip Rack BC230 P16",
"parent": "deck",
"slot_on_deck": "P16",
"class_name": "BC230",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "stock plate on 4",
"parent": "deck",
"slot_on_deck": "P2",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"bind beads"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"id": "stock plate on P2",
"parent": "deck",
"slot_on_deck": "P2",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"bind beads"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
{
"id": "stock plate on P3",
"parent": "deck",
"slot_on_deck": "P3",
"class_name": "nest_12_reservoir_15ml",
"liquid_type": [
"ethyl alcohol"
],
"liquid_volume": [10000],
"liquid_input_wells": [
"A1"
]
},
Returns: {
dict: 创建的转移步骤字典 "id": "oscillation",
""" "parent": "deck",
"slot_on_deck": "Orbital1",
sources = parameters.get("source") "class_name": "Orbital",
targets = parameters.get("target") "liquid_type": [],
tip_rack = parameters.get("tip_rack") "liquid_volume": [],
volume = parameters.get("volume") "liquid_input_wells": [
liquid_type = parameters.get("liquid_type", "Well Content") ]
other_params = self.technique.get(technique, {}) },
{
"id": "working plate on P11",
"parent": "deck",
"slot_on_deck": "P11",
"class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [
],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "magnetics module on P12",
"parent": "deck",
"slot_on_deck": "P12",
"class_name": "magnetics module",
"liquid_type": [],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "working plate on P13",
"parent": "deck",
"slot_on_deck": "P13",
"class_name": "NEST 2ml Deep Well Plate",
"liquid_type": [
],
"liquid_volume": [],
"liquid_input_wells": [
]
},
{
"id": "waste on P22",
"parent": "deck",
"slot_on_deck": "P22",
"class_name": "nest_1_reservoir_195ml",
"liquid_type": [
],
"liquid_volume": [],
"liquid_input_wells": [
]
}
]
'''
self.transfer_liquid(
sources=[sources],
targets=[targets],
TipLocation=tip_rack,
tip_racks=[tip_rack],
solvent=liquid_type,
dis_vols=[volume],
**other_params
)
return
handler = LiquidHandlerBiomek() handler = LiquidHandlerBiomek()
@@ -556,13 +725,24 @@ handler.temp_protocol = {
"labwares": [], "labwares": [],
"steps": [] "steps": []
} }
input_steps = json.loads(steps_info) input_steps = json.loads(steps_info)
labwares = json.loads(labware_with_liquid)
for step in input_steps['steps']: for step in input_steps['steps']:
if step['operation'] != 'transfer': if step['operation'] != 'transfer':
continue continue
parameters = step['parameters'] parameters = step['parameters']
handler.transfer_biomek(parameters, technique='MC P300 high') tip_rack=parameters['tip_rack']
# 找到labwares中与tip_rack匹配的项的id
tip_rack_id = [lw['id'] for lw in labwares if lw['class_name'] == tip_rack][0]
handler.transfer_biomek(source=parameters['source'],
target=parameters['target'],
volume=parameters['volume'],
tip_rack=tip_rack_id,
aspirate_techniques='MC P300 high',
dispense_techniques='MC P300 high'
)
print(json.dumps(handler.temp_protocol['steps'],indent=4, ensure_ascii=False)) print(json.dumps(handler.temp_protocol['steps'],indent=4, ensure_ascii=False))