概述:

对色谱数据的自动处理,包括数据导入、基线校正、峰检测、峰积分、峰识别等功能,最终为化学分析人员提供准确的峰信息(保留时间、峰高、峰面积、组分名称等)

数据结构定义:

色谱点

public struct ChromatogramPoint
{
    public double Time { get; set; }      // 保留时间(单位:min/s)
    public double Intensity { get; set; } // 信号强度(单位:mV/AU)
}

色谱峰

public struct ChromatogramPeak
{
    public int StartIndex { get; set; }   // 峰起点索引
    public int PeakIndex { get; set; }    // 峰顶点索引
    public int EndIndex { get; set; }     // 峰终点索引
    public double StartTime { get; set; } // 峰起点时间
    public double PeakTime { get; set; }  // 保留时间
    public double EndTime { get; set; }   // 峰终点时间
    public double PeakHeight { get; set; } // 峰高
    public double PeakArea { get; set; }  // 峰面积
}

已知组分

public struct KnownComponent
{
    public string Name { get; set; }           // 组分名称
    public double RetentionTime { get; set; }  // 标准保留时间
    public double MatchTolerance { get; set; } // 匹配容差(±min)
}

核心算法模块:

1. 数据读取:

  • 支持 CSV、TXT 等文本格式
  • 未来可扩展支持 NetCDF、mzXML 等
  • 读取后自动排序并转换为List<ChromatogramPoint>
var points = ChromatogramReader.ReadFromCsv("data.csv");

2. 基线矫正:

为什么必须进行基线矫正?

不正确的基线会严重影响定量分析的准确性,因为峰面积和峰高的计算都是相对于基线进行的。

2.1. 空白扣除法:

原理:在完全相同的色谱条件下,运行一个不含待测组分的“空白”样品(如纯溶剂),得到一条“空白基线”。然后,从你的样品色谱图中直接减去这条空白基线。

优点:能有效消除由流动相、仪器系统等带来的固定模式的基线噪声和漂移。

缺点:无法消除由样品基质本身带来的基线变化。

2.2. 线性拟合法:

原理:

  1. 由用户或算法在色谱峰的起点和终点手动设置两个“基线点”。
  2. 算法假设这两个点之间的基线是一条直线,并用直线连接这两点。
  3. 从整个色谱信号中减去这条拟合的直线。

适用场景:适用于基线仅有轻微、线性漂移的简单色谱图。

缺点:如果基线是弯曲的(非线性),这种方法会引入较大误差。

2.3. 移动窗口最小值/分位数法:

这是目前许多现代色谱数据系统默认采用的、自动化程度很高的算法。

原理:

  1. 算法定义一个一定宽度的“窗口”,这个窗口从色谱图的开始到结束滑动。
  2. 在每一个窗口位置,算法找出该窗口内所有数据点的最小值(或一个较低的分位数,如5%分位数)。
  3. 因为色谱峰是突起的,窗口内的最小值点很可能就位于基线附近。将这些每个窗口找到的最小值点连接起来,就形成了一条对真实基线的估计线。
  4. 用样条插值等算法平滑这些点,生成最终的基线,然后从原信号中减去。

优点:全自动,无需人工设定基线点,对于处理复杂基线和多个色谱峰的情况非常有效。

关键参数:窗口大小是关键。窗口必须足够大,以确保每个窗口内都能包含不属于峰的“基线区域”。如果窗口设得太小,可能会把峰的一部分误认为是基线,导致“削峰”现象,严重低估峰面积。

2.4. 多项式拟合:

原理:使用一个多项式函数来拟合基线。用户需要提供一些被认为是纯基线的点,然后算法用多项式曲线去拟合这些点,并将这条曲线作为基线减去。

适用场景:处理明显弯曲的非线性基线。

缺点:需要用户干预来选择基线点,且多项式的阶数选择不当会导致过拟合或欠拟合。

2.5. 其他算法:

对于非常复杂的基线,还有更先进的算法,如:

不对称加权最小二乘法:它对正值(很可能是峰)赋予较小的权重,对负值(很可能是基线)赋予较大的权重,通过迭代来优化拟合出基线。这种方法非常强大,尤其适用于噪音大、基线漂移严重的图谱。

小波变换:可以将信号分解成不同频率的成分,从而分离出代表基线的低频成分和代表峰及噪音的高频成分。

3. 峰检测

从连续的色谱信号中,自动、准确地识别出每一个色谱峰的起始点、顶点和终止点。 后续的定性和定量分析(计算保留时间、峰面积/峰高)都完全依赖于峰检测的成功与否。

3.1. 峰检测的基本逻辑与流程:

  1. 信号预处理:首先对原始信号进行“降噪”和基线校正,为准确的峰检测打下基础。这是我们上一节讨论的内容。
  2. 潜在峰识别:找出信号中可能是“峰”的区域。
  3. 关键点定位:对于每个识别出的潜在峰,精确判定其起始点、顶点和终止点。
  4. 峰解析:处理重叠峰,将其分解为多个独立的峰。
  5. 峰过滤:根据一定的规则(如面积阈值、信噪比)剔除假峰(如噪音毛刺)。

3.2. 一阶导数法:

这是最经典、最直观的基于微积分的方法。
原理:

  1. 计算色谱信号(强度 vs. 时间)的一阶导数(即斜率)。
  2. 峰起始点:信号从基线上升,一阶导数由零变为正值的点。
  3. 峰顶点:一阶导数由正值穿过零变为负值的点。此处斜率由正变负,对应信号的最高点。
  4. 峰终止点:一阶导数由负值回归到零的点。

优点:逻辑简单,计算速度快。

缺点:对噪音非常敏感。因为微分会放大噪音,所以必须先进行有效的平滑滤波。对于严重重叠的峰,效果不佳。

3.3. 二阶导数法:

常用于辅助一阶导数法,特别是用于检测肩峰或严重重叠的峰。

原理:分析信号的二阶导数(即一阶导数的导数,反映曲率)。

  1. 在一个对称峰中,峰顶点对应二阶导数的极小值。
  2. 对于重叠峰,主峰和肩峰的顶点会对应二阶导数的过零点。通过检测二阶导数的过零点数量,可以判断重叠峰中包含的峰个数。

优点:对重叠峰的分辨能力比一阶导数强。

缺点:对噪音比一阶导数更敏感。

3.4. 基于阈值的算法:

这是现代色谱工作站中最常用、最核心的方法之一。它不直接依赖导数,而是基于信号的变化幅度。

原理:设定几个关键阈值来判断峰的起点和终点。

  • 斜率/绝对值阈值:当信号值超过预设的绝对值时,认为可能是一个峰的起点。
  • 关键参数:
    • 峰宽:用户需要提供一个典型的峰宽估计值。算法会以此为基础来设置检测窗口。
    • 灵敏度/阈值:决定算法识别峰的“激进”程度。低灵敏度会忽略小峰,高灵敏度可能将噪音误判为峰。

工作流程:

  1. 算法用一个移动窗口扫描信号。
  2. 如果信号强度超过某个阈值(如基线噪音的2倍),则标记为潜在峰起点。
  3. 继续扫描,找到信号的最大值点,标记为峰顶点。
  4. 信号继续下降,当回落到另一个阈值(或低于阈值)时,标记为峰终点。

3.5. 基于波形(小波变换)的算法

这是一种更先进、抗噪能力更强的信号处理方法。

原理:

  • 小波可以理解为一个与色谱峰形状类似的短波。常用的小波基函数(如高斯函数的一阶、二阶导数)与色谱峰形高度匹配。
  • 算法将不同尺度的“小波”与色谱信号进行卷积。
  • 在色谱峰的位置,小波与信号波形高度相似,卷积结果会产生一个极值。这个极值的位置和强度就对应了峰的位置和大小。

优点:

  • 强大的抗噪能力:能有效抑制噪音,同时保留信号的尖锐特征
  • 出色的重叠峰解析能力:通过使用不同尺度的小波,可以同时检测宽峰和窄峰,并能有效分离重叠峰。

缺点:计算相对复杂,对用户来说更像一个“黑箱”。

3.6. 难点攻克:重叠峰解析

当两个或多个峰分离度不佳时,会形成一个“鼓包”。峰检测算法必须能将其解析开来。常用技术包括:

  • 垂直分割法:在两峰之间的谷底画一条垂直线分割。方法简单,但误差大。
  • 切线 skim:对于主峰上的肩峰,从肩峰的起点和终点画一条切线,切线以上的面积算作肩
  • 高斯/洛伦兹拟合:最准确的方法。假设每个峰都服从高斯分布(或类似分布),然后用计算机进行非线性最小二乘拟合,直接计算出每个子峰的最佳参数(面积、保留时间、峰宽)。

4. 峰积分:

计算出色谱峰的面积或高度。在绝大多数情况下,峰面积因其更好的重现性和准确性而成为首选的定量参数。

4.1. 基本积分法:

这类算法假设基线是平直的,且峰与峰之间完全分离。

4.1.1. 垂直分割法

原理:在峰的起点(B)和终点(E)之间画一条直线作为基线。然后,从峰顶点(V)向这条基线作一条垂线。积分器分别计算垂线左侧(从B到V的区域)和右侧(从V到E的区域)的面积,然后相加。

图示:|BV| + |VE|(其中 BV 和 VE 是围绕顶点 V 的两块面积)

评价:这是最朴素的方法,仅在教科书式的理想情况下准确,实际应用中因基线漂移和峰重叠而很少直接使用。

4.1.2. 谷-谷积分法

原理:这是最常用、自动化程度最高的默认方法。直接连接前一个峰的终点与后一个峰的起点(即波谷),以这条直线作为当前峰的积分基线,计算峰轮廓线与这条基线之间的总面积。

优点:计算简单、快速,对于分离度(R > 1.5)良好的峰非常准确。

缺点:当基线存在漂移或峰严重重叠时,误差会非常大。

4.2. 高级积分算法

当色谱图不理想时,必须使用更智能的算法。

4.2.1. 基线校正后积分

原理:这不是一个独立的积分算法,而是一个必需的预处理步骤。算法先使用移动平均、多项式拟合等方法估算出真实的基线(可能是一条曲线),然后将这条基线“拉平”。之后,再在平直的基线上使用谷-谷积分法。
适用场景:处理所有存在基线漂移、弯曲的色谱图。

4.2.2. 重叠峰解析算法

这是峰积分技术的精髓和难点所在。当两个峰分离度不佳时,不能简单地进行谷-谷积分,必须采用数学方法将其“分解”。

(1)垂直分割法(近似法)

原理:在两个重叠峰的波谷最低点画一条垂直于时间轴的直线,强行将重叠区域分割开。左侧峰积分到分割线,右侧峰从分割线开始积分。
评价:非常不精确。它武断地认为在波谷处两个峰的贡献各占50%,但这几乎从来不是事实。仅在精度要求不高的快速估算中使用。

(2)切线撇去法
原理:主要用于处理主峰上的“肩峰”。从肩峰的起点到主峰的下降沿画一条切线,肩峰的面积就是其轮廓线与这条切线之间的区域。
适用场景:分析微量组分附着在主组分上的情况。

(3)模型拟合法(最准确的方法)
原理:这是目前认为最科学、最精确的积分方法。算法假设每个色谱峰都遵循某种数学模型(如高斯分布、指数修正高斯分布或洛伦兹分布)。
流程:

  1. 用户指定重叠区域内可能包含的峰个数。
  2. 算法使用非线性最小二乘拟合技术,自动调整每个子峰的参数(峰高、保留时间、峰宽),使得这些理论模型峰相加后的总曲线与实测的重叠峰信号达到最佳匹配。
  3. 拟合完成后,每个子峰的积分面积就是其对应数学模型曲线下的面积。

优点:能够最大限度地还原每个组分的真实含量,结果可靠。
缺点:计算复杂,对初始值敏感,且拟合效果依赖于实际峰形与所选模型的匹配度。

5. 峰识别

将检测到的峰与已知化合物数据库进行比对匹配。最基础、最核心的匹配依据就是保留时间。

5.1. 数据预处理与校准

这是确保后续匹配准确性的基础。算法通常会先进行一个系统误差校正。
算法操作:保留时间偏移校正
原理:由于色谱柱老化、流动相轻微变化等,整个色谱图的保留时间可能会发生系统性漂移(全部提前或延后)。
实现:

  1. 算法在数据库中查找一个或多个内标物。
  2. 在检测峰列表中寻找这些内标物峰,计算其检测到的保留时间与数据库中的标准保留时间之间的平均差值 ΔRT。
  3. 对整个检测峰列表或整个标准数据库的保留时间进行平移校正:
    RT_corrected = RT_detected - ΔRT(校正检测列表)
    或 Std_RT_corrected = Std_RT_database + ΔRT(校正数据库)

5.2. 核心匹配算法 - 基于动态时间窗口的搜索

这是最核心的步骤,其本质是一个最近邻搜索问题。
算法操作:为每个标准品动态计算一个匹配窗口,然后进行双向匹配
原理:为一个标准品 Std_j设定一个可接受的时间范围 [Std_RT_j - W_j, Std_RT_j + W_j]。任何落在此范围内的检测峰 Peak_i都被视为候选匹配。
算法核心:

  1. 窗口计算:窗口宽度 W_j不是固定的,而是动态计算的。
    W_j = Std_RT_j * tolerance_percentage + tolerance_absolute

例如,tolerance_percentage = 1%, tolerance_absolute = 0.1 min。这意味着一个保留时间为10分钟的标准品,其窗口宽度为 10 * 0.01 + 0.1 = 0.2 min,即 [9.8, 10.2]分钟。这比固定窗口更科学。

  1. 搜索策略:为了高效处理成百上千个峰和标准品,不能使用简单的双重循环。算法会进行优化:
  • 将检测峰列表和标准品列表分别按保留时间排序。
  • 使用单次遍历或滑动窗口算法。因为列表有序,算法可以同时遍历两个列表,只比较时间上相近的峰和标准品,时间复杂度从 O(n*m) 降低到 O(n+m)。
  1. 匹配决策:
  • 情况A(理想,一对一):一个检测峰 Peak_i只落在一个标准品 Std_j的窗口内。算法直接建立匹配关系 Peak_i -> Std_j。
  • 情况B(未识别):一个检测峰不在任何标准品的窗口内。标记为“未知物”。
  • 情况C(歧义,多对一):一个检测峰 Peak_i同时落在多个标准品(如 Std_j和 Std_k)的窗口内。
  • 情况D(歧义,一对多):多个检测峰(如 Peak_i和 Peak_{i+1})都落在同一个标准品 Std_j的窗口内。

5.3. 步骤三:歧义解决算法

当出现上述情况C和D时,需要更复杂的决策算法。

5.3.1. 对于情况C(一个峰对应多个标准品):

算法:最近邻算法

操作:计算 Peak_i的保留时间与每个候选标准品保留时间的绝对差值 |RT_i - Std_RT|。

决策:选择差值最小的那个标准品作为最终匹配。同时,可以设置一个最大差值阈值,如果最小的差值也超过阈值,则判定为“匹配不确定”。

5.3.2. 对于情况D(多个峰对应一个标准品):

算法:相似度评分算法(如果有多维数据)

情景:这通常意味着共流出物或存在异构体。如果只有保留时间,算法可能无法解决,会标记为“需要人工检查”。

进阶操作:如果配有DAD或MS检测器,算法会调用每个峰的光谱数据。

  1. 计算每个候选峰 Peak_i的光谱与标准品 Std_j的光谱的相似度分数(如余弦相似度、皮尔逊相关系数)。
  2. 选择相似度最高的峰作为正确匹配。如果所有峰的相似度都低于阈值,则可能报告“未发现标准品Std_j,可能存在共流出”。

5.4. 置信度评估与输出

匹配完成后,算法会为每个识别结果赋予一个置信度
算法:基于规则的评分系统
操作:

  • 高置信度:一对一匹配,且保留时间偏差很小,并且(如果可用)光谱匹配度很高。
  • 中置信度:一对一匹配,但保留时间偏差接近窗口边界,或光谱匹配度一般。
  • 低置信度:通过歧义解决算法得出的匹配,或只有保留时间匹配而缺乏光谱确认。
  • 算法输出:最终生成一个列表,包含峰ID、化合物名称、保留时间偏差、光谱匹配度(如有)和综合置信度指标。

相关数学库:

核心数学库:

MathNet.Numerics:

安装教程:(请参考这个博主写的教程)

Math.NET Numerics 安装

主要功能:

  • 线性代数(矩阵运算)
  • 数值分析(积分、插值)
  • 统计功能(均值、标准差)

适用场景:

  • ALS 基线校正中的矩阵运算
  • 噪声水平估计
  • 峰面积计算

专业科学计算库

MathNet.Filtering

  • 功能:信号滤波(平滑、去噪)
  • 适用:预处理阶段平滑色谱图

Accord.NET

  • 功能:统计、信号处理、机器学习
  • 适用:高级峰形分析、模式识别

MathKernel

  • 功能:专业数学库,支持 FFT、优化
  • 特点:商业库,性能高但需授权

专用信号处理库

FftSharp

  • 功能:快速傅里叶变换
  • 适用:频域分析、去噪

DSPLib

  • 功能:数字信号处理
  • 适用:滤波器设计、峰值检测

绘图可视化库

OxyPlot

  • 功能:科学数据可视化
  • 适用:绘制色谱图、标注峰

ScottPlot

  • 功能:实时数据绘图
  • 适用:实时色谱监控

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐