mirror of
https://github.com/deepmodeling/Uni-Lab-OS
synced 2026-03-28 18:33:13 +00:00
Merge pull request #250 from ALITTLELZ/adaptors
Add PRCXI functional modules and fix Deck layout
This commit is contained in:
@@ -45,6 +45,7 @@ from pylabrobot.resources import (
|
|||||||
Trash,
|
Trash,
|
||||||
PlateAdapter,
|
PlateAdapter,
|
||||||
TubeRack,
|
TubeRack,
|
||||||
|
create_homogeneous_resources,
|
||||||
)
|
)
|
||||||
|
|
||||||
from unilabos.devices.liquid_handling.liquid_handler_abstract import (
|
from unilabos.devices.liquid_handling.liquid_handler_abstract import (
|
||||||
@@ -55,6 +56,7 @@ from unilabos.devices.liquid_handling.liquid_handler_abstract import (
|
|||||||
TransferLiquidReturn,
|
TransferLiquidReturn,
|
||||||
)
|
)
|
||||||
from unilabos.registry.placeholder_type import ResourceSlot
|
from unilabos.registry.placeholder_type import ResourceSlot
|
||||||
|
from unilabos.resources.itemized_carrier import ItemizedCarrier
|
||||||
from unilabos.resources.resource_tracker import ResourceTreeSet
|
from unilabos.resources.resource_tracker import ResourceTreeSet
|
||||||
from unilabos.ros.nodes.base_device_node import BaseROS2DeviceNode
|
from unilabos.ros.nodes.base_device_node import BaseROS2DeviceNode
|
||||||
|
|
||||||
@@ -91,15 +93,15 @@ class PRCXI9300Deck(Deck):
|
|||||||
该类定义了 PRCXI 9300 的工作台布局和槽位信息。
|
该类定义了 PRCXI 9300 的工作台布局和槽位信息。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# T1-T16 默认位置 (4列×4行)
|
# T1-T16 默认位置 (4列×4行, Y轴从上往下递减, T1在左上角)
|
||||||
_DEFAULT_SITE_POSITIONS = [
|
_DEFAULT_SITE_POSITIONS = [
|
||||||
(0, 0, 0), (138, 0, 0), (276, 0, 0), (414, 0, 0), # T1-T4
|
(0, 288, 0), (138, 288, 0), (276, 288, 0), (414, 288, 0), # T1-T4 (第1行, 最上)
|
||||||
(0, 96, 0), (138, 96, 0), (276, 96, 0), (414, 96, 0), # T5-T8
|
(0, 192, 0), (138, 192, 0), (276, 192, 0), (414, 192, 0), # T5-T8 (第2行)
|
||||||
(0, 192, 0), (138, 192, 0), (276, 192, 0), (414, 192, 0), # T9-T12
|
(0, 96, 0), (138, 96, 0), (276, 96, 0), (414, 96, 0), # T9-T12 (第3行)
|
||||||
(0, 288, 0), (138, 288, 0), (276, 288, 0), (414, 288, 0), # T13-T16
|
(0, 0, 0), (138, 0, 0), (276, 0, 0), (414, 0, 0), # T13-T16 (第4行, 最下)
|
||||||
]
|
]
|
||||||
_DEFAULT_SITE_SIZE = {"width": 128.0, "height": 86, "depth": 0}
|
_DEFAULT_SITE_SIZE = {"width": 128.0, "height": 86, "depth": 0}
|
||||||
_DEFAULT_CONTENT_TYPE = ["plate", "tip_rack", "plates", "tip_racks", "tube_rack", "adaptor"]
|
_DEFAULT_CONTENT_TYPE = ["plate", "tip_rack", "plates", "tip_racks", "tube_rack", "adaptor", "plateadapter", "module"]
|
||||||
|
|
||||||
def __init__(self, name: str, size_x: float, size_y: float, size_z: float,
|
def __init__(self, name: str, size_x: float, size_y: float, size_z: float,
|
||||||
sites: Optional[List[Dict[str, Any]]] = None, **kwargs):
|
sites: Optional[List[Dict[str, Any]]] = None, **kwargs):
|
||||||
@@ -544,6 +546,108 @@ class PRCXI9300TubeRack(TubeRack):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class PRCXI9300ModuleSite(ItemizedCarrier):
|
||||||
|
"""
|
||||||
|
PRCXI 功能模块的基础站点类(加热/冷却/震荡/磁吸等)。
|
||||||
|
|
||||||
|
- 继承 ItemizedCarrier,可被拖放到 Deck 槽位上
|
||||||
|
- 顶面有一个 ResourceHolder 站点,可吸附板类资源(叠放)
|
||||||
|
- content_type 包含 "plateadapter" 以支持适配器叠放
|
||||||
|
- 支持 material_info 注入
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name: str, size_x: float, size_y: float, size_z: float,
|
||||||
|
material_info: Optional[Dict[str, Any]] = None, **kwargs):
|
||||||
|
sites = create_homogeneous_resources(
|
||||||
|
klass=ResourceHolder,
|
||||||
|
locations=[Coordinate(0, 0, 0)],
|
||||||
|
resource_size_x=size_x,
|
||||||
|
resource_size_y=size_y,
|
||||||
|
resource_size_z=size_z,
|
||||||
|
name_prefix=name,
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
kwargs.pop('layout', None)
|
||||||
|
sites_in = kwargs.pop('sites', None)
|
||||||
|
|
||||||
|
sites_dict = {name: sites}
|
||||||
|
|
||||||
|
content_type = [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"plateadapter",
|
||||||
|
]
|
||||||
|
|
||||||
|
if sites_in is not None and isinstance(sites_in, dict):
|
||||||
|
for site_key, site_value in sites_in.items():
|
||||||
|
if site_key in sites_dict:
|
||||||
|
sites_dict[site_key] = site_value
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
name, size_x, size_y, size_z,
|
||||||
|
sites=sites_dict,
|
||||||
|
num_items_x=kwargs.pop('num_items_x', 1),
|
||||||
|
num_items_y=kwargs.pop('num_items_y', 1),
|
||||||
|
num_items_z=kwargs.pop('num_items_z', 1),
|
||||||
|
content_type=content_type,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
self._unilabos_state = {}
|
||||||
|
if material_info:
|
||||||
|
self._unilabos_state["Material"] = material_info
|
||||||
|
|
||||||
|
def assign_child_resource(self, resource, location=Coordinate(0, 0, 0), reassign=True, spot=None):
|
||||||
|
from pylabrobot.resources.resource import Resource
|
||||||
|
Resource.assign_child_resource(self, resource, location=location, reassign=reassign)
|
||||||
|
|
||||||
|
def unassign_child_resource(self, resource):
|
||||||
|
from pylabrobot.resources.resource import Resource
|
||||||
|
Resource.unassign_child_resource(self, resource)
|
||||||
|
|
||||||
|
def serialize_state(self) -> Dict[str, Dict[str, Any]]:
|
||||||
|
try:
|
||||||
|
data = super().serialize_state()
|
||||||
|
except AttributeError:
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
if hasattr(self, 'sites') and self.sites:
|
||||||
|
sites_info = []
|
||||||
|
for site in self.sites:
|
||||||
|
if hasattr(site, '__class__') and 'pylabrobot' in str(site.__class__.__module__):
|
||||||
|
sites_info.append({
|
||||||
|
"__pylabrobot_object__": True,
|
||||||
|
"class": site.__class__.__name__,
|
||||||
|
"module": site.__class__.__module__,
|
||||||
|
"name": getattr(site, 'name', str(site))
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
sites_info.append(site)
|
||||||
|
data['sites'] = sites_info
|
||||||
|
|
||||||
|
if hasattr(self, "_unilabos_state") and self._unilabos_state:
|
||||||
|
safe_state: Dict[str, Any] = {}
|
||||||
|
for k, v in self._unilabos_state.items():
|
||||||
|
if k == "Material" and isinstance(v, dict):
|
||||||
|
safe_material: Dict[str, Any] = {}
|
||||||
|
for mk, mv in v.items():
|
||||||
|
if isinstance(mv, (str, int, float, bool, list, dict, type(None))):
|
||||||
|
safe_material[mk] = mv
|
||||||
|
safe_state[k] = safe_material
|
||||||
|
elif isinstance(v, (str, int, float, bool, list, dict, type(None))):
|
||||||
|
safe_state[k] = v
|
||||||
|
data.update(safe_state)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def load_state(self, state: Dict[str, Any]) -> None:
|
||||||
|
super().load_state(state)
|
||||||
|
if 'sites' in state:
|
||||||
|
self.sites = [state['sites']]
|
||||||
|
|
||||||
|
|
||||||
class PRCXI9300PlateAdapter(PlateAdapter):
|
class PRCXI9300PlateAdapter(PlateAdapter):
|
||||||
"""
|
"""
|
||||||
专用板式适配器类:用于承载 Plate 的底座(如 PCR 适配器、磁吸架等)。
|
专用板式适配器类:用于承载 Plate 的底座(如 PCR 适配器、磁吸架等)。
|
||||||
|
|||||||
150
unilabos/devices/liquid_handling/prcxi/prcxi_modules.py
Normal file
150
unilabos/devices/liquid_handling/prcxi/prcxi_modules.py
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
|
from .prcxi import PRCXI9300ModuleSite
|
||||||
|
|
||||||
|
|
||||||
|
class PRCXI9300FunctionalModule(PRCXI9300ModuleSite):
|
||||||
|
"""
|
||||||
|
PRCXI 9300 功能模块基类(加热/冷却/震荡/加热震荡/磁吸等)。
|
||||||
|
|
||||||
|
设计目标:
|
||||||
|
- 作为一个可以在工作台上拖拽摆放的实体资源(继承自 PRCXI9300ModuleSite -> ItemizedCarrier)。
|
||||||
|
- 顶面存在一个站点(site),可吸附标准板类资源(plate / tip_rack / tube_rack 等)。
|
||||||
|
- 支持注入 `material_info` (UUID 等),并且在 serialize_state 时做安全过滤。
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
size_x: float,
|
||||||
|
size_y: float,
|
||||||
|
size_z: float,
|
||||||
|
module_type: Optional[str] = None,
|
||||||
|
category: str = "module",
|
||||||
|
model: Optional[str] = None,
|
||||||
|
material_info: Optional[Dict[str, Any]] = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
name=name,
|
||||||
|
size_x=size_x,
|
||||||
|
size_y=size_y,
|
||||||
|
size_z=size_z,
|
||||||
|
material_info=material_info,
|
||||||
|
model=model,
|
||||||
|
category=category,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 记录模块类型(加热 / 冷却 / 震荡 / 加热震荡 / 磁吸)
|
||||||
|
self.module_type = module_type or "generic"
|
||||||
|
|
||||||
|
# 与 PRCXI9300PlateAdapter 一致,使用 _unilabos_state 保存扩展信息
|
||||||
|
if not hasattr(self, "_unilabos_state") or self._unilabos_state is None:
|
||||||
|
self._unilabos_state = {}
|
||||||
|
|
||||||
|
# super().__init__ 已经在有 material_info 时写入 "Material",这里仅确保存在
|
||||||
|
if material_info is not None and "Material" not in self._unilabos_state:
|
||||||
|
self._unilabos_state["Material"] = material_info
|
||||||
|
|
||||||
|
# 额外标记 category 和模块类型,便于前端或上层逻辑区分
|
||||||
|
self._unilabos_state.setdefault("category", category)
|
||||||
|
self._unilabos_state["module_type"] = module_type
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# 具体功能模块定义
|
||||||
|
# 这里的尺寸和 material_info 目前为占位参数,后续可根据实际测量/JSON 配置进行更新。
|
||||||
|
# 顶面站点尺寸与模块外形一致,保证可以吸附标准 96 板/储液槽等。
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
def PRCXI_Heating_Module(name: str) -> PRCXI9300FunctionalModule:
|
||||||
|
"""加热模块(顶面可吸附标准板)。"""
|
||||||
|
return PRCXI9300FunctionalModule(
|
||||||
|
name=name,
|
||||||
|
size_x=127.76,
|
||||||
|
size_y=85.48,
|
||||||
|
size_z=40.0,
|
||||||
|
module_type="heating",
|
||||||
|
model="PRCXI_Heating_Module",
|
||||||
|
material_info={
|
||||||
|
"uuid": "TODO-HEATING-MODULE-UUID",
|
||||||
|
"Code": "HEAT-MOD",
|
||||||
|
"Name": "PRCXI 加热模块",
|
||||||
|
"SupplyType": 3,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def PRCXI_MetalCooling_Module(name: str) -> PRCXI9300FunctionalModule:
|
||||||
|
"""金属冷却模块(顶面可吸附标准板)。"""
|
||||||
|
return PRCXI9300FunctionalModule(
|
||||||
|
name=name,
|
||||||
|
size_x=127.76,
|
||||||
|
size_y=85.48,
|
||||||
|
size_z=40.0,
|
||||||
|
module_type="metal_cooling",
|
||||||
|
model="PRCXI_MetalCooling_Module",
|
||||||
|
material_info={
|
||||||
|
"uuid": "TODO-METAL-COOLING-MODULE-UUID",
|
||||||
|
"Code": "METAL-COOL-MOD",
|
||||||
|
"Name": "PRCXI 金属冷却模块",
|
||||||
|
"SupplyType": 3,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def PRCXI_Shaking_Module(name: str) -> PRCXI9300FunctionalModule:
|
||||||
|
"""震荡模块(顶面可吸附标准板)。"""
|
||||||
|
return PRCXI9300FunctionalModule(
|
||||||
|
name=name,
|
||||||
|
size_x=127.76,
|
||||||
|
size_y=85.48,
|
||||||
|
size_z=50.0,
|
||||||
|
module_type="shaking",
|
||||||
|
model="PRCXI_Shaking_Module",
|
||||||
|
material_info={
|
||||||
|
"uuid": "TODO-SHAKING-MODULE-UUID",
|
||||||
|
"Code": "SHAKE-MOD",
|
||||||
|
"Name": "PRCXI 震荡模块",
|
||||||
|
"SupplyType": 3,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def PRCXI_Heating_Shaking_Module(name: str) -> PRCXI9300FunctionalModule:
|
||||||
|
"""加热震荡模块(顶面可吸附标准板)。"""
|
||||||
|
return PRCXI9300FunctionalModule(
|
||||||
|
name=name,
|
||||||
|
size_x=127.76,
|
||||||
|
size_y=85.48,
|
||||||
|
size_z=55.0,
|
||||||
|
module_type="heating_shaking",
|
||||||
|
model="PRCXI_Heating_Shaking_Module",
|
||||||
|
material_info={
|
||||||
|
"uuid": "TODO-HEATING-SHAKING-MODULE-UUID",
|
||||||
|
"Code": "HEAT-SHAKE-MOD",
|
||||||
|
"Name": "PRCXI 加热震荡模块",
|
||||||
|
"SupplyType": 3,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def PRCXI_Magnetic_Module(name: str) -> PRCXI9300FunctionalModule:
|
||||||
|
"""磁吸模块(顶面可吸附标准板)。"""
|
||||||
|
return PRCXI9300FunctionalModule(
|
||||||
|
name=name,
|
||||||
|
size_x=127.76,
|
||||||
|
size_y=85.48,
|
||||||
|
size_z=30.0,
|
||||||
|
module_type="magnetic",
|
||||||
|
model="PRCXI_Magnetic_Module",
|
||||||
|
material_info={
|
||||||
|
"uuid": "TODO-MAGNETIC-MODULE-UUID",
|
||||||
|
"Code": "MAG-MOD",
|
||||||
|
"Name": "PRCXI 磁吸模块",
|
||||||
|
"SupplyType": 3,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
70
unilabos/registry/resources/prcxi/modules.yaml
Normal file
70
unilabos/registry/resources/prcxi/modules.yaml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
PRCXI_Heating_Module:
|
||||||
|
category:
|
||||||
|
- prcxi
|
||||||
|
- modules
|
||||||
|
class:
|
||||||
|
module: unilabos.devices.liquid_handling.prcxi.prcxi_modules:PRCXI_Heating_Module
|
||||||
|
type: pylabrobot
|
||||||
|
description: '加热模块 (Code: HEAT-MOD)'
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
PRCXI_MetalCooling_Module:
|
||||||
|
category:
|
||||||
|
- prcxi
|
||||||
|
- modules
|
||||||
|
class:
|
||||||
|
module: unilabos.devices.liquid_handling.prcxi.prcxi_modules:PRCXI_MetalCooling_Module
|
||||||
|
type: pylabrobot
|
||||||
|
description: '金属冷却模块 (Code: METAL-COOL-MOD)'
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
PRCXI_Shaking_Module:
|
||||||
|
category:
|
||||||
|
- prcxi
|
||||||
|
- modules
|
||||||
|
class:
|
||||||
|
module: unilabos.devices.liquid_handling.prcxi.prcxi_modules:PRCXI_Shaking_Module
|
||||||
|
type: pylabrobot
|
||||||
|
description: '震荡模块 (Code: SHAKE-MOD)'
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
PRCXI_Heating_Shaking_Module:
|
||||||
|
category:
|
||||||
|
- prcxi
|
||||||
|
- modules
|
||||||
|
class:
|
||||||
|
module: unilabos.devices.liquid_handling.prcxi.prcxi_modules:PRCXI_Heating_Shaking_Module
|
||||||
|
type: pylabrobot
|
||||||
|
description: '加热震荡模块 (Code: HEAT-SHAKE-MOD)'
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
PRCXI_Magnetic_Module:
|
||||||
|
category:
|
||||||
|
- prcxi
|
||||||
|
- modules
|
||||||
|
class:
|
||||||
|
module: unilabos.devices.liquid_handling.prcxi.prcxi_modules:PRCXI_Magnetic_Module
|
||||||
|
type: pylabrobot
|
||||||
|
description: '磁吸模块 (Code: MAG-MOD)'
|
||||||
|
handles: []
|
||||||
|
icon: ''
|
||||||
|
init_param_schema: {}
|
||||||
|
registry_type: resource
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
@@ -9,6 +9,9 @@ def register():
|
|||||||
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300TipRack
|
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300TipRack
|
||||||
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300Trash
|
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300Trash
|
||||||
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300TubeRack
|
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300TubeRack
|
||||||
|
from unilabos.devices.liquid_handling.prcxi.prcxi import PRCXI9300ModuleSite
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
from unilabos.devices.liquid_handling.prcxi.prcxi_modules import PRCXI9300FunctionalModule
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from unilabos.devices.workstation.workstation_base import WorkStationContainer
|
from unilabos.devices.workstation.workstation_base import WorkStationContainer
|
||||||
|
|
||||||
|
|||||||
@@ -459,6 +459,8 @@ class ResourceTreeSet(object):
|
|||||||
"reagent_bottle": "reagent_bottle",
|
"reagent_bottle": "reagent_bottle",
|
||||||
"flask": "flask",
|
"flask": "flask",
|
||||||
"beaker": "beaker",
|
"beaker": "beaker",
|
||||||
|
"module": "module",
|
||||||
|
"carrier": "carrier",
|
||||||
}
|
}
|
||||||
if source in replace_info:
|
if source in replace_info:
|
||||||
return replace_info[source]
|
return replace_info[source]
|
||||||
@@ -596,6 +598,8 @@ class ResourceTreeSet(object):
|
|||||||
"deck": "Deck",
|
"deck": "Deck",
|
||||||
"container": "RegularContainer",
|
"container": "RegularContainer",
|
||||||
"tip_spot": "TipSpot",
|
"tip_spot": "TipSpot",
|
||||||
|
"module": "PRCXI9300ModuleSite",
|
||||||
|
"carrier": "ItemizedCarrier",
|
||||||
}
|
}
|
||||||
|
|
||||||
def collect_node_data(node: ResourceDictInstance, name_to_uuid: dict, all_states: dict, name_to_extra: dict):
|
def collect_node_data(node: ResourceDictInstance, name_to_uuid: dict, all_states: dict, name_to_extra: dict):
|
||||||
@@ -958,6 +962,17 @@ class ResourceTreeSet(object):
|
|||||||
f"从远端同步了 {added_count} 个物料子树"
|
f"从远端同步了 {added_count} 个物料子树"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
# 二级是物料
|
||||||
|
if remote_child_name not in local_children_map:
|
||||||
|
# 本地不存在该物料,直接引入
|
||||||
|
remote_child.res_content.parent = local_device.res_content
|
||||||
|
local_device.children.append(remote_child)
|
||||||
|
local_children_map[remote_child_name] = remote_child
|
||||||
|
logger.info(
|
||||||
|
f"物料 '{remote_root_id}/{remote_child_name}': "
|
||||||
|
f"从远端同步了整个子树"
|
||||||
|
)
|
||||||
|
continue
|
||||||
# 二级物料已存在,比较三级子节点是否缺失
|
# 二级物料已存在,比较三级子节点是否缺失
|
||||||
local_material = local_children_map[remote_child_name]
|
local_material = local_children_map[remote_child_name]
|
||||||
local_material_children_map = {child.res_content.name: child for child in
|
local_material_children_map = {child.res_content.name: child for child in
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 0,
|
"y": 288,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
@@ -89,7 +89,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -98,7 +100,7 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 138,
|
"x": 138,
|
||||||
"y": 0,
|
"y": 288,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
@@ -112,7 +114,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -121,7 +125,7 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 276,
|
"x": 276,
|
||||||
"y": 0,
|
"y": 288,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
@@ -135,7 +139,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -144,6 +150,231 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 414,
|
"x": 414,
|
||||||
|
"y": 288,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T5",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 192,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T6",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 138,
|
||||||
|
"y": 192,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T7",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 276,
|
||||||
|
"y": 192,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T8",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 414,
|
||||||
|
"y": 192,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T9",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 96,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T10",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 138,
|
||||||
|
"y": 96,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T11",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 276,
|
||||||
|
"y": 96,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T12",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 414,
|
||||||
|
"y": 96,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"width": 128.0,
|
||||||
|
"height": 86,
|
||||||
|
"depth": 0
|
||||||
|
},
|
||||||
|
"content_type": [
|
||||||
|
"plate",
|
||||||
|
"tip_rack",
|
||||||
|
"plates",
|
||||||
|
"tip_racks",
|
||||||
|
"tube_rack",
|
||||||
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "T13",
|
||||||
|
"visible": true,
|
||||||
|
"occupied_by": null,
|
||||||
|
"position": {
|
||||||
|
"x": 0,
|
||||||
"y": 0,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
@@ -158,214 +389,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
]
|
"plateadapter",
|
||||||
},
|
"module"
|
||||||
{
|
|
||||||
"label": "T5",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 96,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T6",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 138,
|
|
||||||
"y": 96,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T7",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 276,
|
|
||||||
"y": 96,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T8",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 414,
|
|
||||||
"y": 96,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T9",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 192,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T10",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 138,
|
|
||||||
"y": 192,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T11",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 276,
|
|
||||||
"y": 192,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T12",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 414,
|
|
||||||
"y": 192,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "T13",
|
|
||||||
"visible": true,
|
|
||||||
"occupied_by": null,
|
|
||||||
"position": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 288,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"size": {
|
|
||||||
"width": 128.0,
|
|
||||||
"height": 86,
|
|
||||||
"depth": 0
|
|
||||||
},
|
|
||||||
"content_type": [
|
|
||||||
"plate",
|
|
||||||
"tip_rack",
|
|
||||||
"plates",
|
|
||||||
"tip_racks",
|
|
||||||
"tube_rack",
|
|
||||||
"adaptor"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -374,7 +400,7 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 138,
|
"x": 138,
|
||||||
"y": 288,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
@@ -388,7 +414,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -397,7 +425,7 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 276,
|
"x": 276,
|
||||||
"y": 288,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
@@ -411,7 +439,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -420,7 +450,7 @@
|
|||||||
"occupied_by": null,
|
"occupied_by": null,
|
||||||
"position": {
|
"position": {
|
||||||
"x": 414,
|
"x": 414,
|
||||||
"y": 288,
|
"y": 0,
|
||||||
"z": 0
|
"z": 0
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
@@ -434,7 +464,9 @@
|
|||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack",
|
"tube_rack",
|
||||||
"adaptor"
|
"adaptor",
|
||||||
|
"plateadapter",
|
||||||
|
"module"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -108,7 +108,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -153,7 +154,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -198,7 +200,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -243,7 +246,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -288,7 +292,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -333,7 +338,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -378,7 +384,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -423,7 +430,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -468,7 +476,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -513,7 +522,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -558,7 +568,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -603,7 +614,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -648,7 +660,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -693,7 +706,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -738,7 +752,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -783,7 +798,8 @@
|
|||||||
"tip_rack",
|
"tip_rack",
|
||||||
"plates",
|
"plates",
|
||||||
"tip_racks",
|
"tip_racks",
|
||||||
"tube_rack"
|
"tube_rack",
|
||||||
|
"plateadapter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user