Lunatic API 三段字符串:实验、样品、结果
30 秒看懂
实验、样品、结果三段字符串决定测哪些孔、怎么扣空白、返回哪些列 blanking_information 取值 0–4,选错会让整板浓度整体偏掉 API Tester 上先验字符串:返回 −9 多为字段名、列号或必填字段有误
系列指南 · 第 5 篇
Lunatic API 三段字符串:实验、样品、结果
19 个 API 命令本身只是动作开关:打开托盘、关闭托盘、开始测量。仪器具体要测什么、测哪几个孔、结果里要给哪些列,都靠三段纯文本字符串传给 Lunatic。这三段是实验定义、样品定义、结果定义。三段字符串的格式不复杂,但字段较多,第一次写很容易漏字段或对不齐列号。
先认识几个名词
INI 格式 / [Section] 段 — 一种纯文本配置文件格式。用 [方括号里的名字] 划分段落,段落内每行 key=value。实验定义和结果定义都是这种格式。
CSV — Comma-Separated Values,逗号分隔的纯文本表格。样品定义就是一份没有表头的 CSV,每行一个孔。
列号映射 — 实验定义里告诉仪器"样品定义这张 CSV 表里第 N 列是什么内容"。列号从 0 开始数,没用到的列填 -1。
sample group(样品组) — 一组共用同一份空白的样品。一板上可以放多个 sample group,各自用各自的空白。
blanking_information — 实验定义里的一个字段,值 0–4,告诉仪器这次实验整体怎么扣空白。0 仪器内部估算。1 取多个空白的平均。2 整板共用一个空白。3 每个样品配自己的空白。4 用仪器本地存的空白库。
application_name — Lunatic & Stunner Client 软件里选择的应用名,例如 "Protein (Turbidity)"。实验定义里要写得跟 Client 显示的一字不差(大小写、空格、括号都一致)。
source plate / source position — 样品在源板(biobank 板、储样板)上的板名和孔位。用于追溯 Lunatic 板上每个孔对应到上游哪个原始样品,典型用于 NGS 流水线和 LIMS 集成。
plate_ID — 每块 Lunatic Plate 的标识字符串。DQ_Define_Experiment 后由仪器返回一份 plate_ID 数组(多板时有多个),后续 DQ_Measure(plate_id) 按这个 ID 挨块测。
三段字符串各管什么
脚本里要传字符串的地方有两处:调用 DQ_Define_Experiment 时,前两个参数是实验定义和样品定义;调用 DQ_Get_Results 时,第一个参数是结果定义。三段字符串各管各的内容,通过列号关联。实验定义里写"样品定义的第几列是什么内容",样品定义就按这个约定排列。
段 1 — 实验定义 — Experiment Definition — 告诉仪器这次"怎么测":实验名、用哪个应用、板型、扣空白方式。 — 同时声明样品定义那张表里每一列是什么(列号映射)。 — INI 格式,两个 [Section]
段 2 — 样品定义 — Sample Definition — 告诉仪器"测哪些孔":一行一个孔,板号、孔位、样品名、E1% 等等。 — 可以一次写多块板,共用一段实验定义。 — 无表头 CSV
段 3 — 结果定义 — Results Definition — 告诉仪器"返回什么":要哪些列、怎么分隔、空格子填什么。 — 列名必须和 Lunatic Analysis 软件 Report Settings 里的列名一字不差。 — INI 格式,一个 [Export results] 段
样品定义:一行一个孔
样品定义就是一份没有表头的 CSV,每行写一个孔的全部信息。列的顺序自己定,只要和实验定义里的列号映射对得上即可。Manual §4.3 Table 2 是一个完整例子:一块板 16 个孔,4 个空白 + 3 种样品各 4 复孔。sample1 用 E1%=13.7,sample2 用 6.67,sample3 用 10:
这例的列顺序:Plate ID、Plate position、Sample name、E1%。空白行最后一列空着,因为空白不需要消光系数。对应的实验定义里,列号映射是:column_plate_ID=0、column_plate_position=1、column_sample_name=2、column_E1%=3;一板上只有一个 sample group,所以 column_sample_group=-1(后面"多 sample group 的写法"一节会展开)。
写样品定义有三条要点:
分隔符是英文逗号。
某一列没数据,要保留空位(两个逗号之间空着 ,,),不要省略,否则后面的列会错位。
字段里如果含逗号或空格,用半角双引号包起来。
实验定义:仪器怎么测
实验定义文件分两个 INI 段:[Experiment definition] 写这次实验本身的设置(实验名、应用、板型、空白模式);[Import samples] 写样品定义那张 CSV 表的列号映射(每一列是什么内容)。
[Experiment definition] 段:必填字段
字段:含义
experiment_name:自定义实验名;含空格时整段套半角双引号
application_name:应用名,和 Lunatic & Stunner Client 的 Select app 页面里一模一样。Manual 示例用的是 "Protein (Turbidity)";其它应用名以 Client 实际显示的为准
dropplate_type:板型,Lunatic Plate 填 "Lunatic Plate",High Lunatic Plate 填 "High Lunatic Plate",字符串一字不差
[Import samples] 段:列号映射
每一项 column_xxx=N 表示样品定义 CSV 里第 N 列(从 0 开始数)是什么内容。某一项没用到,填 -1,仪器会跳过这一列。常用的几类字段:
基本定位 — column_plate_ID · column_plate_position · column_sample_name · column_sample_group — 孔的板号、孔位(A1–H12 写法)、样品名、样品组名(sample group)。一板上只有一组样品时,sample group 一列可以填 -1 省掉。
样品来源追溯 — column_source_plate · column_source_position — 样品在源板(biobank 板、储样板)上的板名和孔位。用于追溯 Lunatic 板上每个孔对应到上游哪个原始样品,典型用于 LIMS 集成和 NGS 流水线。
应用相关 — column_analyte · column_buffer — 可测物质和缓冲液。具体哪些字段必填、填什么值,由 application_name 决定,可以在 Lunatic & Stunner Client 的 Select app 页面查。
蛋白浓度 — column_E1% — 蛋白 1% 消光系数(E1%),Lunatic 用这个值把 280 nm 吸光度换算成浓度。
空白指定 — column_blank_plate_ID · column_blank_plate_position · column_stored_blanks_sample_group_name — 逐行指定每个样品配哪个空白。需要 blanking_information = 3(每行不同的空白)或 4(用存好的空白库)才用得到。
空白模式 — blanking_information · blank_name_used · blank_plate_ID · blank_plate_position · stored_blanks_sample_group_name — blanking_information 决定整板怎么扣空白,值 0–4 五种。其它几个字段按 blanking_information 的值选择性填写(详见下方专门一节)。
单 sample group 完整实验定义示例
对应前一节那个 16 孔样品定义(Manual Table 2)的完整实验定义(Manual Table 4)如下。这里用 blanking_information=1(averaging of blanks,取所有 blank1 孔的平均作为空白):
几个关键字段的含义:column_sample_group=-1 表示这次只有一个 sample group,样品定义里就不需要单独列出 group 名;column_E1%=3 指消光系数在样品定义的第 3 列(从 0 数起,即 13.7 / 6.67 / 10 那一列);blank_name_used="blank1" 让仪器从样品定义里挑 sample name 是 blank1 的孔做空白,A1/A2/B1/B2 这 4 个孔的测量值会取平均。
多 sample group 的写法
有时一板上要放多组样品,各自用不同缓冲液、各自需要自己的空白。这时在样品定义里多加一列,写 sample group 的名字。同时在实验定义里把 column_sample_group 改成那一列的列号(不是 -1)。Manual Table 3 的双 group 例子,SG1 用 E1%=6.67,SG2 用 E1%=13.7:
对应的实验定义(Manual Table 5),和单 group 版(Table 4)有两处差别:column_sample_group 从 -1 改成 3(指向 SG1/SG2 这一列);column_E1% 从 3 改成 4(SG 列插在样品名后面,E1% 那一列往后挪了一位)。其它字段都一样:
注意:两组的空白都叫 blank1,但 sample group 不同。Lunatic 会按 group,各自取本组内 sample name 是 blank1 的孔做空白。两组的空白不会混用。
结果定义:输出什么列
结果定义控制 DQ_Get_Results 返回的文本格式:要哪些列、怎么分隔、缺失值怎么显示。一个典型例子:
column_names — 返回的列名清单,用 ; 分隔。列名必须和 Lunatic & Stunner Analysis 软件 Report Settings 标签页里看到的一字不差(大小写、空格、单位、括号都一致)。Manual 示例的 8 个列:Plate ID、Plate Position、Sample name、Sample group、Pump、Concentration (mg/ml)、A280 (10mm)、E1%。其它可选列以 Report Settings 里能选到的为准。
separator — 列之间的分隔字符。只能填 ;(分号)、,(英文逗号)或 tab 三个值之一。
undefined_column_name — 当 column_names 里的某个列名 Analysis 不认识时怎么办。"remove" 从结果里去掉、"include" 保留但留空、"Return_error" 直接报错让脚本知道。生产环境建议用 "Return_error",避免列名写错却没察觉,等数据进了 LIMS 才发现。
no_result_value — 没结果的格子里填什么(比如空白孔的浓度、未加液孔的数值)。默认 "-",也可以写成 ""、"N/A"、"0"。要进数据库的,推荐 "" 或 "N/A",别用 "0",容易被误算进平均值。
Lunatic API Manual Figure 17。Lunatic & Stunner Analysis 软件的 Report Settings 标签页。左侧 Available column names 列出所有可选的列(Source Plate ID、Sample name、Concentration (mg/ml)、A280、A260/A280 等);右侧 Report columns 是这次实际要导出的列。结果定义里 column_names 字段写的列名,必须跟左侧列表里看到的一字不差。
把上面这段结果定义用在前一节那个双 group 样品上,返回的结果如下。结果用分号分隔,对应 Manual §4.3 Table 7:
仪器把这次测量的 .bin 原始数据写到 Network Settings 配置的网络共享路径里。同时,DQ_Get_Results 把这段 results 文本和 experiment_path 路径返给脚本。
空白的五种用法
实验定义里的 blanking_information 字段,值 0–4,决定这次实验整体怎么扣空白。选错的话,整板的浓度结果会整体偏掉,而且不容易立刻看出来。
怎么选:日常筛选最常用 1 或 3。1 简单,每板放几个空白做平均,适合大多数场景;3 严谨,每个样品配对自己的缓冲液空白,适合多种缓冲液混测的实验。空白长期固定的自动化项目,4 最省人工,前提是库里的空白不超过 100 天、期间仪器没做过校准。前一天做一板空白存进库里,后面几板都直接引用。0 只用在浓度高、精度要求不严的场景,低浓度样品不要用。
多板实验的两条约束
一次 DQ_Define_Experiment 可以包含任意多块板。所有孔都写进同一个样品定义字符串里,通过 Plate 1、Plate 2 这样的板号区分。DQ_Define_Experiment 返回的 plate_IDs 数组按定义顺序列出每块板的 ID,后续 DQ_Measure(plate_ID) 依次调用即可。
设计上有两条硬约束,违反会被仪器直接报错。
板数要对得上
实际放进仪器测量的板数,要和样品定义里声明的板数一致。多放或少放都会被拒。
DQ_Get_Results 要等全部测完才返回结果
所有声明的板都测完之前调用 DQ_Get_Results,Lunatic 会返回 -104(Results can only be exported if all Lunatic Plates are measured)。它不会返回半截结果。第 4 篇讲的重试循环就是处理这种情况:每次返回 −104 就再试一次,直到返回 0。
声明几块板就要测几块板;中途要放弃,需要显式发 DQ_Abort_Measurement,不能默默跳过。
在 API Tester 上先验一遍
字符串里要写的字段多,出错点也多。把脚本直接接上工作站再调试,代价不小,一块 Lunatic Plate 装错就要重做。Unchained Labs 提供一个 API Tester 桌面工具(Lunatic 和 Stunner 共用,选 Lunatic 模式即可)。用它可以不接工作站,直接对着 Lunatic 把字符串和命令逐一调通。Lunatic API quick start guide 明确推荐先在 Tester 上验通,再接真实驱动。
Lunatic & Stunner API Tester 工具(Lunatic 和 Stunner 共用,启动后选 Lunatic 模式)。顶部一排按钮对应 19 个 API 命令;中间 Experiment / Sample / Results 三块文本框就是这一篇讲的三段字符串;底部 return code / return text 显示每条命令的执行结果。
按 QSG 推荐的顺序走一遍:
启动 API Tester,选择 Lunatic 模式。把左侧默认的 localhost 改成 Lunatic 的实际 IP,端口填 Client Settings/Info 页面显示的值(Manual 里出现过 6700 和 6300 两个值)。
点 DQ_Request_Access → DQ_Get_Instrument_Serial_Number(确认返回的序列号就是这台仪器)→ DQ_Open_Tray → DQ_Close_Tray(确认托盘能正常开关)。
把三段字符串粘进 Experiment / Sample / Results 文本框,点 DQ_Define_Experiment。返回 0 表示字符串语法没问题;返回 −9 就回去查字符串(常见原因:字段名拼错、列号对不上、缺必填字段)。
(可选)装一块加好样的 Lunatic Plate,点 DQ_Measure 跑一次,再点 DQ_Get_Results 取结果。
结束前点 DQ_Release_Access。
Tester 能验字符串语法和命令顺序。它还会把 .bin 原始数据写到 Network Settings 配置的网络共享目录。这一步顺带确认了 .bin 是否正确写到目标路径。这样不接工作站,就能把"配置字符串、发命令、原始数据写入共享盘"这三步一次验证完。
另一项配合做法:从 Lunatic & Stunner Analysis 软件的 Report Settings 标签页,把列名一字不差地拷下来。用它作为结果定义 column_names 的依据,避免手输写错大小写、空格或单位。
没有 Tester 也能用替代方案:如果暂时拿不到 API Tester,可以写一个最小脚本(C# / Python),直接调用 DropQuant_Remote.dll。按上面同样的顺序逐条调命令,看返回码。先在脚本里把命令一条条手动验通,再交工作站。这样能把字符串问题和工作站调度问题分开排查,定位起来更快。
three-strings · 三段字符串各管什么
experiment · 实验定义:仪器怎么测
sample-groups · 多 sample group 的写法
results · 结果定义:输出什么列
multi-plate · 多板实验的两条约束
api-tester · 在 API Tester 上先验一遍
INI 格式 / [Section] 段 · 一种纯文本配置文件格式。用 [方括号里的名字] 划分段落,段落内每行 key=value。实验定义和结果定义都是这种格式。
CSV · Comma-Separated Values,逗号分隔的纯文本表格。样品定义就是一份没有表头的 CSV,每行一个孔。
列号映射 · 实验定义里告诉仪器"样品定义这张 CSV 表里第 N 列是什么内容"。列号从 0 开始数,没用到的列填 -1。
sample group(样品组) · 一组共用同一份空白的样品。一板上可以放多个 sample group,各自用各自的空白。
blanking_information · 实验定义里的一个字段,值 0–4,告诉仪器这次实验整体怎么扣空白。0 仪器内部估算。1 取多个空白的平均。2 整板共用一个空白。3 每个样品配自己的空白。4 用仪器本地存的空白库。
application_name · Lunatic & Stunner Client 软件里选择的应用名,例如 "Protein (Turbidity)"。实验定义里要写得跟 Client 显示的一字不差(大小写、空格、括号都一致)。
source plate / source position · 样品在源板(biobank 板、储样板)上的板名和孔位。用于追溯 Lunatic 板上每个孔对应到上游哪个原始样品,典型用于 NGS 流水线和 LIMS 集成。
plate_ID · 每块 Lunatic Plate 的标识字符串。DQ_Define_Experiment 后由仪器返回一份 plate_ID 数组(多板时有多个),后续 DQ_Measure(plate_id) 按这个 ID 挨块测。
段 1 · 实验定义 · Experiment Definition · 告诉仪器这次"怎么测":实验名、用哪个应用、板型、扣空白方式。 · 同时声明样品定义那张表里每一列是什么(列号映射)。 · INI 格式,两个 [Section]
段 2 · 样品定义 · Sample Definition · 告诉仪器"测哪些孔":一行一个孔,板号、孔位、样品名、E1% 等等。 · 可以一次写多块板,共用一段实验定义。 · 无表头 CSV
段 3 · 结果定义 · Results Definition · 告诉仪器"返回什么":要哪些列、怎么分隔、空格子填什么。 · 列名必须和 Lunatic Analysis 软件 Report Settings 里的列名一字不差。 · INI 格式,一个 [Export results] 段
基本定位 · column_plate_ID · column_plate_position · column_sample_name · column_sample_group · 孔的板号、孔位(A1–H12 写法)、样品名、样品组名(sample group)。一板上只有一组样品时,sample group 一列可以填 -1 省掉。
样品来源追溯 · column_source_plate · column_source_position · 样品在源板(biobank 板、储样板)上的板名和孔位。用于追溯 Lunatic 板上每个孔对应到上游哪个原始样品,典型用于 LIMS 集成和 NGS 流水线。
应用相关 · column_analyte · column_buffer · 可测物质和缓冲液。具体哪些字段必填、填什么值,由 application_name 决定,可以在 Lunatic & Stunner Client 的 Select app 页面查。
蛋白浓度 · column_E1% · 蛋白 1% 消光系数(E1%),Lunatic 用这个值把 280 nm 吸光度换算成浓度。
空白指定 · column_blank_plate_ID · column_blank_plate_position · column_stored_blanks_sample_group_name · 逐行指定每个样品配哪个空白。需要 blanking_information = 3(每行不同的空白)或 4(用存好的空白库)才用得到。
空白模式 · blanking_information · blank_name_used · blank_plate_ID · blank_plate_position · stored_blanks_sample_group_name · blanking_information 决定整板怎么扣空白,值 0–4 五种。其它几个字段按 blanking_information 的值选择性填写(详见下方专门一节)。
column_names · 返回的列名清单,用 ; 分隔。列名必须和 Lunatic & Stunner Analysis 软件 Report Settings 标签页里看到的一字不差(大小写、空格、单位、括号都一致)。Manual 示例的 8 个列:Plate ID、Plate Position、Sample name、Sample group、Pump、Concentration (mg/ml)、A280 (10mm)、E1%。其它可选列以 Report Settings 里能选到的为准。
separator · 列之间的分隔字符。只能填 ;(分号)、,(英文逗号)或 tab 三个值之一。
undefined_column_name · 当 column_names 里的某个列名 Analysis 不认识时怎么办。"remove" 从结果里去掉、"include" 保留但留空、"Return_error" 直接报错让脚本知道。生产环境建议用 "Return_error",避免列名写错却没察觉,等数据进了 LIMS 才发现。
no_result_value · 没结果的格子里填什么(比如空白孔的浓度、未加液孔的数值)。默认 "-",也可以写成 ""、"N/A"、"0"。要进数据库的,推荐 "" 或 "N/A",别用 "0",容易被误算进平均值。
0 · autoblank · 仪器内部估算,不专门测空白。Manual §4.3 特别注明这种方式不推荐用于低浓度样品的精确定量。仅在浓度较高、对精度要求不严的样品上用。
1 · averaging of blanks · 多个空白取平均。在 blank_name_used 里写空白的名字(例 "blank1")。样品定义里把这个名字写到几个孔上,仪器取这些孔的平均值作为空白。
2 · single blank · 整板共用一个空白。可以用 blank_name_used 指定名字,也可以用 blank_plate_ID + blank_plate_position 直接指定一个具体的孔。
3 · multiple blanks · 每个样品配自己的空白。在样品定义里用 column_blank_plate_ID 和 column_blank_plate_position 两列,逐行指定。
4 · stored blanks · 用仪器本地存好的空白库(空白库通过 Lunatic & Stunner Client 的 Transfer Blanks 或 API 的 DQ_Store_Blanks 命令存入)。多个 sample group 时,用 stored_blanks_sample_group_name(整体指定)或 column_stored_blanks_sample_group_name(逐行指定)告诉仪器从空白库里取哪个 group。