# Analysis
分析流程主要包括校准流程和检测流程,另外还包括自定义流程和DRE流程
# Analysis
Analysis是所有分析流程的基类,除了定义分析流程的基础框架,它还实现了一些通用的方法。
# AnalysisParameters
AnalysisParameters是所有分析参数类的基类。
# AnalysisResult
AnalysisResult是所有分析结果类的基类。
# MzAxisRangeCalibration
注意
- calculate_detector_gain 需要使用到
# calibrateDetectorGain
isotope_list[34]
{
"isotope_list": [
[
74.0964,
75.0998,
76.1028
],
[
130.1596,
131.1624,
132.1659
],
[
242.284,
243.2876,
244.2909,
245.295
],
[
354.409,
355.4128,
356.4161,
357.42
],
[
455.2904,
456.2938,
457.2971,
458.3,
459.3025
],
[
466.535,
467.538,
468.5413,
469.5452,
470.5486
],
[
578.6598,
579.6632,
580.6665,
581.6705,
582.6739
],
[
690.785,
691.7884,
692.7917,
693.7951,
694.7991
]
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Client STD Implementation
在质量轴和质量范围都已经校准的前提下:
利用质量轴和范围校准通过的那张MS1的谱图的processed_counting_data。在谱图中寻找出所有峰(目标峰和目标峰的同位素峰)。然后对所有目标峰和目标峰的同位素进行匹配,获取所有匹配上的峰表。
求processed_counting_data的峰面积list, 截取processed_analog_data的峰面积list;然后计算gain:
gain_list = []
for c_area, a_area in zip(area_list_counting, area_list_analog):
if c_area > 0:
current_per_pt = 2.5/65536/pre_amp1/pre_amp2
second_per_pt = 1/pt_per_th/scan_speed/1000
q = a_area*current_per_pt*second_per_pt
gain = q/1.6e-19/c_area
gain_list.append(gain)
# Valid gain range [5e5,5e7]
gain = mean(gain_list) # gain_mean
gain_std = std(gain_list) # gain_std
print(f"gain = {gain}, gain_std = {gain_std}")
2
3
4
5
6
7
8
9
10
11
12
# PMS Pyplugin Implementation
在质量轴和质量范围都已经校准的前提下:
对n根目标峰std_mz_list[130.159, 242.284, 354.409, 578.66]进行DRE, 找到一个合适的进样量;
在该进样量下做 cycle = 3 的 MS1_ISO(宽坑,iso2_swift2_amp=0) 保存3张processed_counting_data和3张processed_analog_data
分别对每一张谱的每一根峰和每一根同位素峰做gain计算,不存在的肯定为零不计入结果
最后对gain_list进行平均, 求出gain = mean(gain_list) # gain_mean
gain_std = std(gain_list) # gain_std
# IsoRfMonitorAnalysis
在质量轴和质量范围都已经校准的前提下:
使用校正液对一个或者多个目标峰进行 swift2_width_mz=4 的 ISO,比较 ISO 前后的效率 iso_eff(ISO 效率)。
iso_eff计算可按照 ISO 前后谱图中目标峰的强度或(和)峰的面积的比值。
判定标准:如果 iso_eff 大于 "iso_eff_threshold": 0.6 则判定 iso_rf 对正
否则 ISO 后目标峰损失的强度或面积过多(超过40%),则表明 iso_rf 已经偏离。需要对iso_rf进行校准。
# 使用的扫描方程
- 方案1: MS1 和 MS1_ISO;// 风险:由于space charge因素影响,相同进样量的情况下,MS1_ISO > MS1 (intensity tic)
- 方案2: MS1_ISO(宽坑)和 MS1_ISO
建议
从简单方面考虑,STD 应该采用方案1, 从准确率考虑可能方案2更稳妥,需要实验再次确认。
实验:PCS试剂盒,正负模式校正液,再最优进样量下,分别进行MS1,MS1_ISO(宽坑), MS1_ISO;
比较455/265峰的强度变化。
期待结果:MS1 < MS1_ISO(宽坑) and MS1_ISO < MS1_ISO(宽坑)
# CidRfMonitorAnalysis
在质量轴和质量范围都已经校准,iso_rf 对正的前提下:
使用校正液针对一个或者多个目标峰进行特定能量下的 CID,比较 ISO 前后的效率 cid_ratio(CID 效率)。
cid_ratio 计算可按照 CID 前后谱图中目标峰的强度或(和)峰的面积的比值。
也可以按照碎裂后谱图中的剩余的母离子和母离子和所有子离子的和的强度或(和)峰的面积的比值。
判定标准:如果 cid_ratio 在 [cid_ratio_lower_threshold, cid_ratio_upper_threshold] 之间则判定 cid_rf 对正, pressure 正常
如果 cid_ratio < cid_eff_lower_threshold, 则判定 cid_rf 已经偏离。需要对 cid_rf 进行校准(不能判定pressure状态)。
如果 cid_ratio > cid_eff_upper_threshold, 则判定 pressure 已经偏离。需要对 pressure 进行校准。
# 使用的扫描方程
- 方案1: MS1_ISO,MS2_RF_Calib 和 MS2_Pressure_Calib;
- 方案2: MS2_RF_Calib 和 MS2_Pressure_Calib
原理
CID 需要的能量 cid_amp 固定时,母离子 CID 的碎裂比率 cid_ratio 和 (cid_rf 、 pressure) 相关。
cid_rf 和 cid_mz 相关,cid_rf 为2次曲线,对称轴:x=-b/(2a)
// 假设目标物没有质量低于50m/z的碎片,这时下述关系成立:(455 符合要求)
cid_ratio = (剩余母离子/(剩余母离子 + 所有子离子)), // 全部母离子 = 剩余母离子 + 所有子离子
cid_rf 对的越正,碎裂效果越好;太偏了(偏左、偏右)都会导致母离子不碎
pressure 越高, CID需要的能量越大, cid_amp 固定时,碎裂效果越差;
pressure 越低, CID需要的能量越小, cid_amp 固定时,碎裂效果越好;
cid_eff_lower_threshold = 0.05;九成五碎裂 // plugin 为 0.025
cid_eff_upper_threshold = 0.4; 四成以上不碎
cid_rf--> pressure | cid_rf too left | cid_rf left(mz-3) | cid_rf ok | cid_rf right(mz+3) | cid_rf too right |
---|---|---|---|---|---|
pressure_too_high | 不碎 | 不碎 | 不碎 | 不碎 | 不碎 |
pressure_ok | 不碎 | 合适 | 合适 | 合适 | 不碎 |
pressure_too_low | 不碎 | 全碎 | 全碎 | 全碎 | 不碎 |
建议
从简单方面考虑,STD 应该采用方案2
cid_eff 定义为: 剩余的母离子/(剩余母离子+所有子离子)
- 如果 mz±3 的3张谱有1张符合要求,则 cid_rf 和 pressure 合适
- 如果 mz±3 的3张谱全部全碎, 则证明气压过低, cid_rf 应该比较合适(可能稍微有点偏)
2.1 如果 mz±10 的2张谱也全部全碎, 则证明气压过低
2.2 如果 mz±10 的2张谱有1张符合要求或不碎,则证明 cid_rf 再该方向上偏离较远 - 如果 mz±3 的三张谱全部不碎, 则证明气压过高 或 则证明气压还行, 但 cid_rf 偏了很远(说不清楚)
3.1 如果 mz±10 的2张谱也全部不碎, 则证明气压过高
3.2 如果 mz±10 的2张谱有1张符合要求或全碎,则证明 cid_rf 再该方向上偏离较远
综上所述:
第一阶段,先考虑1,2,3这3种基本情况
第二阶段,再考虑2.1,2.2,3.1,3.2这些细节情况
# ArbitrarySequenceAnalysis
# DreAnalysis
分析目标
根据给定的离子强度(TIC)目标范围,通过扫描迭代,找到符合要求的扫描进样量inj_size。输入参数
{
"dre_average": 1,
"dre_target": 10000,
"dre_target_tol_high": 1.5,
"dre_target_tol_low": 0.8,
"inj_size": 30,
"inj_size_max": 60,
"inj_size_min": 20,
"method_parameters": {
"inj_lmco_mz": 50,
"method_type": "MS1"
},
"max_dre_times": 10,
"window_size_min": 0.2,
"window_size_extension": 5,
"window_lifespan_max": 4,
"update_inj_size": 0
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 分析流程
dre_target_max = dre_target * dre_target_tol_high
dre_target_min = dre_target * dre_target_tol_low
left = (inj_size_min, 0, 0) // inj_size, tic, lifespan
right = (inj_size_max, INT_MAX, 0)
// 1st scan
spectrum = scan(method_parameterss, inj_size)
tic = spectrum.tic()
scan_count = 1
WHILE ( (tic > dre_target_max || tic < dre_target_min) && scan_count <= max_dre_times) {
if (tic > dre_target_max) {
right = (inj_size, tic, 0)
left.lifespan++
}
if (tic < dre_target_min) {
left = (inj_size, tic, 0)
right.lifespan++
}
// error handling
if (right.x - left.x < window_size_min) {
if (left.lifespan > 0) {
left = (max(left.x - window_size_extension, inj_size_min), 0, 0)
} else {
right = (min(right.x + window_size_extension, inj_size_max), INT_MAX, 0)
}
} else if (left.lifespan >= window_lifespan_max) {
left = (max(left.x - window_size_extension, inj_size_min), 0, 0)
} else if (right.lifespan >= window_lifespan_max) {
right = (min(right.x + window_size_extension, inj_size_max), INT_MAX, 0)
}
if (mode = HALF || left.y == 0 || right.y == INT_MAX)
inj_size = (left.x + right.x) / 2
else // mode = LINER
inj_size = (dre_target-left.y)*(right.x-left.x)/(right.y-left.y) + left.x
spectrum = scan(method_parameterss, inj_size)
tic = spectrum.tic()
scam_count++
}
return inj_size
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# DdaAnalysis
# TargetedAnalysis
# TargetedProAnalysis
# TargetedQuantAnalysis
# Quant for Voriconazole
本流程是为了支持预临床和临床阶段的一键检测流程,不涉及和医院通讯,样品信息扫码绑定等方面。
目标是能够在仪器端完成自动一键检测,手动录入样品信息,储存数据
# 交互流程
- 采样->前处理完成:软件不介入,待测样品在一个PCS试剂盒上,试剂盒应有特定标签编号
- 插入试剂盒,界面弹出开始检测
- 点击检测,仪器执行扫描序列,详述见下,出口为1组scan的数据/mrz
- 数据处理,数据处理流程详述如下,出口为一个浓度
- 展示报告,可录入样品信息,报告细节见下
- 保存mrz
# 扫描流程
- [optional] Target 模式类型的DRE
- swift坑宽=40, 6(参数化)
- 单一MS2方程, 方程参数均参数化或进库:cycle=15(参数化):
polarity = 'POS'
inj_size = 60
precursor_mz = 351.5
spray_voltage = 4500
inj_size = 60
inj_lmco = 50
iso_amp1 = auto
iso_amp2 = auto
cid_q = 0.25
cid_amp = 3.6
scan_mass_start = 50
scan_mass_start = 1000
2
3
4
5
6
7
8
9
10
11
12
# 数据处理流程
- 对内标和目标物所在mz进行局部寻峰
- 对寻到的峰进行局部积分,得到内标和目标物强度
- 对所有谱图的内标强度和目标物面积求和,得到sum_area_sample, sum_area_is
- 根据 conc = sum_area_sample/sum_area_is*conc_is计算浓度, conc_is预计是2ug/mL,需要可配置
- 数据保护:
若sum_area_is == 0:输出“无效”
若sum_area_is != 0 & conc < 0.1[可配置]: 输出“未检出”
若sum_area_is != 0 & conc > 10[可配置]: 输出“超出检测范围” - 和参考范围[0.5, 5.5]比较,参考范围可配置。
- 输出浓度,和详细result记录
clear
%%用于单阱定量计算
% 程序使用说明:
% 1. 将所有文件放入data文件夹中
% 2. need change的位置要根据实际情况进行修改
% 3. needvalue是需要选择的峰位中心(大概值)
% 4. Triger是阈值, 该值代表在峰位为中心左右绝对值范围内寻找最高峰
% 5. 如果出现峰强度为0,说明该文件中选定的预计峰位无峰;面积同理
% 6. 结果输出在result
%% 参数
peak_tolerance =0.5; % 寻峰mz容差,默认0.5
area_tolerance = 0.5; % 积分上下限宽度,默认0.5
target1 = 284.1; % IS mz goes here
target2 = 281.1; % target mz goes here
%%
files = dir('data/**/*.mrz');
for i = 1 : size(files,1) %mrz个数
% get next file
name = fullfile(files(i).folder,files(i).name);
data = load_mrz(name);
% init variables
peak1_mzs=[];
peak1_intensities=[];
peak1_areas=[];
peak2_mzs=[];
peak2_intensities=[];
peak2_areas=[];
% loop through scans to process
for j = 1 :length(data.analysis.scan_list)
% 计算质量轴
len = length(data.analysis.scan_list(j).data);
x = 0:len-1;%点数
c0 = data.analysis.scan_list(j).spec_parameters.mass_calib_c0;
c1 = data.analysis.scan_list(j).spec_parameters.mass_calib_c1;
c2 = data.analysis.scan_list(j).spec_parameters.mass_calib_c2;
mz = c0 + x.*c1 + x.*x.*c2; %质量数
intensity=data.analysis.scan_list(j).data;
%处理谱图--局部寻峰
local1_mz = mz(mz - target1 < peak_tolerance & mz - target1 > -1*peak_tolerance);
local1_intensity = intensity(mz - target1 < peak_tolerance & mz - target1 > -1*peak_tolerance);
peak1_idx = find(local1_intensity==max(local1_intensity));
if length(peak1_idx) > 1
peak1_idx = peak1_idx(1);
end
local2_mz= mz(mz - target2 < peak_tolerance & mz - target2 > -1*peak_tolerance);
local2_intensity= intensity(mz - target2 < peak_tolerance & mz - target2 > -1*peak_tolerance);
peak2_idx = find(local2_intensity==max(local2_intensity));
if length(peak2_idx) > 1
peak2_idx = peak2_idx(1);
end
peak1_mz = local1_mz(peak1_idx);%找到准确位置
peak1_intensity = local1_intensity(peak1_idx);
peak1_mzs =[peak1_mzs;peak1_mz];
peak1_intensities =[ peak1_intensities; peak1_intensity];
peak2_mz = local2_mz(peak2_idx); %找到准确位置
peak2_intensity = local2_intensity(peak2_idx);
peak2_mzs = [peak2_mzs; peak2_mz];
peak2_intensities = [peak2_intensities; peak2_intensity];
%处理谱图--在峰两侧定宽积面积
peaklocal1_mz = mz(mz - peak1_mz < area_tolerance & mz - peak1_mz > -1*area_tolerance);
peaklocal1_intensity = intensity(mz - peak1_mz < area_tolerance & mz - peak1_mz > -1*area_tolerance);
peaklocal2_mz= mz(mz - peak2_mz < area_tolerance & mz - peak2_mz > -1*area_tolerance);
peaklocal2_intensity= intensity(mz - peak2_mz < area_tolerance & mz - peak2_mz > -1*area_tolerance);
peak1_areas=[peak1_areas; sum(peaklocal1_intensity)];
peak2_areas=[peak2_areas; sum(peaklocal2_intensity)];
end
ratio_height=mean(peak2_intensities)/mean(peak1_intensities);
ratio_area=mean(peak2_areas)/mean(peak1_areas);
% store the file path
result(i).name = name;
% store the peak mz, peak heigh, and peak area on each spectra
result(i).details = [peak1_mzs peak1_intensities peak1_areas peak2_mzs peak2_intensities peak2_areas];
result(i).ratio_height = ratio_height;
result(i).ratio_area = ratio_area;
end
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# 报告
以下图为基础做如下调整:
- 和参考范围比较的箭头放在结果列
- 形成:序号-名称-结果-参考范围 四列
- 去除“检出x种物质”
- 去除“检测谱图”, “谱图”, 和实际谱图