Ep 53 — 开源工具篇(上):SpectroChemPy、pybaselines

系列:红外光谱百科:从原理到实战
篇章:第五篇 · 仪器与工具篇 — 开源生态(Ep 46–55 后段)
适合人群:希望提升数据处理效率的技术人员、研究生、化学计量学爱好者、Python 用户
前置知识:Ep 18(谱图处理)、Ep 19(库检索)、Ep 20(定量分析)、Ep 52(商业软件评析)
阅读时间:约 45 分钟


引子:当 Python 遇上红外光谱

某博士生小陈用 Bruker INVENIO 采集了一批催化剂原位红外数据,要研究 CO 在 Pt/Al₂O₃ 上的吸附。他打开 OPUS 软件准备做基线校正——发现 OPUS 内置的算法对这种"全谱严重倾斜 + 强吸收区附近基线弯曲"的复杂情况处理不好。他又试了 OMNIC 试用版,依然不满意。

导师说:"你用 Python 试试 pybaselines,200 多种基线算法。"

小陈花了 1 小时学习,写了一段 20 行的 Python 代码,跑出结果——基线校正效果远超商业软件默认算法。从此他入了开源光谱工具的"坑"。

"Python + 开源光谱库正在改变光谱学的数据分析生态。它不再只是商业软件的'补充',而已经成为科研工作流的核心。"
—— 改编自 Applied Spectroscopy 2023 评论 [1]

本集将系统评析三款开源光谱 Python 工具:SpectroChemPy(化学光谱全流程框架)、pybaselines(基线校正算法库)、spectrapepper(入门级光谱分析包)。每款都配有 GitHub 链接、star 数、实操代码,并给出"何时选开源、何时仍需商业软件"的判断框架。

💡 本集定位:Ep 52 评商业软件,Ep 53–54 评开源软件。开源不是"免费版商业软件",而是"灵活可定制的科研工具"。两集配合是 Python 用户的光谱工具箱。


一、开源光谱工具生态概览

1.1 为什么需要开源工具

商业 FTIR 软件(OMNIC、OPUS、Spectrum)功能完善但有以下局限 [1][2]:

  • 封闭算法:用户不知道基线校正、平滑的具体实现,无法复现;
  • 扩展性差:无法自定义新算法、新模型;
  • 批量处理弱:对数百张谱图做复杂处理时,GUI 操作低效;
  • 跨平台差:仅 Windows,无 Linux/Mac 版(OPUS 部分除外);
  • 机器学习集成弱:现代数据分析(深度学习、贝叶斯优化)需 Python 生态;
  • 价格高:模块化收费,高级功能单独购买。

开源工具的优势 [1][2][3]:

  • 算法透明:源码可查,结果可复现;
  • 完全可定制:自定义算法、流程、可视化;
  • Python 生态:与 NumPy、SciPy、scikit-learn、PyTorch 无缝衔接;
  • 跨平台:Windows、Linux、Mac 全支持;
  • 免费:无 license 限制。

1.2 开源光谱工具的"明星榜"

GitHub 上"FTIR / spectroscopy"主题的活跃开源项目(截至 2024 年)[2][3]:

| 项目 | Star 数 | 主要用途 | 本集覆盖 |
|------|---------|---------|---------|
| HyperSpy | ~560 | 多维光谱(成像)分析 | Ep 54 |
| pybaselines | ~189 | 基线校正算法库(star 数随时间变化,撰写时约百级)| ✅ 本集 |
| SpectroChemPy | ~177 | 化学光谱全流程框架 | ✅ 本集 |
| Orange-Spectroscopy | ~140 | 拖拽式可视化工作流 | Ep 54 |
| spectrapepper | ~100+ | 入门级光谱分析包 | ✅ 本集 |
| NIRS4ALL | ~80 | NIR 变换 + 深度学习 | Ep 54 |
| pyspectrakit | ~50 | 轻量级核心操作 | Ep 54 |

表 1:开源光谱工具 GitHub star 数(数据来源:GitHub topic "spectroscopy" / "ftir",2024 年)

🔗 延伸ftir.fun 是中文友好的在线光谱工具补充,提供 Web 端的谱图查看、峰识别、库检索,无需编程即可快速分析。


二、SpectroChemPy:化学光谱的全流程 Python 框架

2.1 项目概览

SpectroChemPy 是由法国激光与应用物理化学研究所(LCP-A2S)的 Arnaud Travert 团队开发的开源 Python 框架,专为化学光谱(IR、Raman、NIR、UV-Vis、NMR)设计 [3][4]。

图 1:SpectroChemPy GitHub 主页(来源:https://github.com/spectrochempy/spectrochempy)

2.2 核心特色:NDDataset 数据结构

SpectroChemPy 最核心的创新是 NDDataset 数据结构 [3][4]:

from spectrochempy import NDDataset

# 创建一个光谱数据集
dataset = NDDataset(
    absorbance_data,        # 二维数组:样品 × 波数
    coordset=[
        ('samples', sample_names),       # 第一维:样品名
        ('wavenumbers', wn_array, 'cm⁻¹')  # 第二维:波数 + 单位
    ],
    title='Absorbance',
    units='absorbance',
    name='Catalyst_CO_Adsorption',
    history='2024-07-15: collected on INVENIO R',
    author='Bob',
)

NDDataset 相比 NumPy ndarray 的优势 [3][4]:

  • 元数据一体化:坐标(波数、温度、时间)、单位、标题、历史记录都与数据绑定;
  • 单位感知:自动处理 cm⁻¹ ↔ nm、Abs ↔ %T 等转换;
  • 切片语义清晰dataset[:, '4000::1'] 表示"所有样品、4000 cm⁻¹ 起每隔 1 cm⁻¹";
  • 可追溯:每次操作自动追加到 history,符合 FAIR 数据原则;
  • 可视化集成dataset.plot() 直接出图,坐标轴单位自动标注。

2.3 全流程覆盖

SpectroChemPy 覆盖光谱分析的全流程 [3][4]:

读取 → 预处理 → 分析 → 建模 → 可视化 → 导出
 │       │        │       │        │       │
 │       │        │       │        │       └ CSV, JCAMP-DX, HDF5
 │       │        │       │        └ matplotlib, plotly
 │       │        │       └ PLS, PCA, MCR-ALS
 │       │        └ 峰检出, 曲线拟合, 积分
 │       └ 基线, 平滑, 归一化, ATR校正, 求导
 └ OMNIC (.spa), OPUS (.opu), JCAMP-DX (.jdx), SPA, CSV

① 读取多厂商格式 [3][4]:

from spectrochempy import read

# 读取 Thermo OMNIC .spa 文件
ds_omnic = read('sample.spa')

# 读取 Bruker OPUS .opu 文件
ds_opus = read('sample.opu')

# 读取 JCAMP-DX .jdx 文件
ds_jcamp = read('sample.jdx')

# 读取 CSV(需指定列)
ds_csv = read('sample.csv', csv_delimiter=',')

这是 SpectroChemPy 最强大的功能之一——直接读取商业软件私有格式,无需先导出转换 [3]。

② 预处理 [3][4]:

# 基线校正(内置多种算法)
ds_bc = ds_omnic.baseline_correct(method='als', lam=1e7, p=0.01)

# 平滑(Savitzky-Golay)
ds_sm = ds_bc.smooth(method='sg', window_size=9, polyorder=2)

# 归一化
ds_norm = ds_sm.normalize(method='max')

# 求导
ds_d2 = ds_norm.derivative(order=2, window_size=11, polyorder=3)

③ 多元曲线分辨(MCR-ALS) [3][4]:
MCR-ALS 是 SpectroChemPy 的招牌功能,适合混合物光谱分解:

from spectrochempy import MCRALS

# 假设 ds 是反应过程的多张谱图(时间 × 波数)
mcr = MCRALS(ds, n_components=3, max_iter=100)
mcr.fit()

# 输出:3 个组分的纯光谱 + 浓度曲线
pure_spectra = mcr.ST  # 组分光谱
concentrations = mcr.C  # 浓度矩阵

pure_spectra.plot()
concentrations.plot()

④ 可视化 [3][4]:

import spectrochempy as scp

# 单张谱图
ds.plot(title='Catalyst CO Adsorption', color='red')

# 多张谱图叠加
scp.plot_multi(ds1, ds2, ds3, labels=['A', 'B', 'C'])

# 3D 表面图
ds.plot_3D()

# 热图(反应过程数据)
ds.plot_waterfall()

2.4 教学价值

SpectroChemPy 的 API 设计贴近化学家语言(baseline_correct 而非 baseline_correct),文档详尽,是学习光谱 Python 处理的最佳入口 [3][4]。

完整教学示例——读取聚苯乙烯谱图并处理:

import spectrochempy as scp

# 1. 读取数据(示例数据集)
ds = scp.read('irdata/nh4y-activation.spa')

# 2. 截取感兴趣区域
ds = ds[:, '4000::650']  # 4000-650 cm⁻¹

# 3. 基线校正(ALS)
ds_bc = ds.baseline_correct(method='asls', lam=1e5, p=0.01)

# 4. 平滑
ds_sm = ds_bc.smooth(method='sg', window_size=9, polyorder=2)

# 5. 归一化
ds_norm = ds_sm.normalize(method='max')

# 6. 可视化
ds_norm.plot(title='NH4Y Activation', colormap='viridis')

# 7. 导出
ds_norm.write('processed.jdx')  # JCAMP-DX 格式
ds_norm.write('processed.csv')  # CSV 格式

2.5 何时选 SpectroChemPy

适合 [3][4]:

  • 化学光谱全流程处理(读取 → 处理 → 建模 → 可视化);
  • 多厂商数据整合(直接读 .spa / .opu);
  • 教学(API 友好,文档详尽);
  • MCR-ALS 等高级分解;
  • 需要元数据可追溯(FAIR 数据原则)。

不适合

  • 单一基线校正任务(用 pybaselines 更轻量);
  • FPA 成像数据(用 HyperSpy);
  • 拖拽式工作流(用 Orange-Spectroscopy);
  • 极致性能(核心仍是 NumPy,对超大矩阵无优化)。

三、pybaselines:基线校正算法的"百科全书"

3.1 项目概览

pybaselines 由 derb12(GitHub 用户名)开发,是专注基线校正的 Python 库,提供 200+ 种基线校正算法,是 FTIR topic 中 star 数最高的项目 [2][5]。

图 2:pybaselines GitHub 主页(来源:https://github.com/derb12/pybaselines)

3.2 为什么基线校正是预处理最关键的一步

基线校正是光谱预处理中最影响后续分析结果的环节 [5][6][7]:

  • 峰位偏移:基线弯曲会让峰位判断偏移 1–5 cm⁻¹;
  • 峰面积失真:基线高则峰面积虚高,定量误差可达 20%+;
  • 假峰风险:高阶多项式过度校正会"挖出"假峰;
  • 下游影响:基线校正后的谱图是 PLS、PCA、库检索的输入,错误传播。

"在光谱分析的所有预处理步骤中,基线校正的影响最大、争议最多、最容易出错。"
—— Liland K H, Applied Spectroscopy 2011 [6]

pybaselines 的价值在于:把 200+ 种算法统一到一致的 API,让你快速对比、选择最适合的算法 [5]。

3.3 算法分类

pybaselines 把基线算法分为 8 大类 [5]:

| 类别 | 代表算法 | 适用场景 |
|------|---------|---------|
| 多项式 | Poly, ModPoly, IModPoly, Polynomial | 简单倾斜、弯曲 |
| Whittaker | AsLS, IAsLS, AirPLS, ArPLS, DrPLS | 复杂弯曲、宽峰 |
| ALS | AsLS, IAsLS, arPLS, asPLS | 现代主力,对宽峰不敏感 |
| Morphological | Mor, Imor, AMor | 形态学,适合尖锐峰 |
| Window | Noise, Noisy | 滑动窗口 |
| Spline | mixture, mixture_mod | 平滑样条 |
| Baseline | Dietrich, CWT, FUNP | 小波、频率域 |
| Optimization | Custom, Cole | 优化方法 |

表 2:pybaselines 算法分类(综合 [5][6])

3.4 四大主力算法对比

① AsLS(Asymmetric Least Squares) [6][7]

  • 由 Eilers & Boelens 提出,是现代基线校正的"标准"算法;
  • 原理:非对称加权最小二乘 + 二阶差分平滑;
  • 参数:lam(平滑度,1e5–1e9)、p(非对称性,0.001–0.1);
  • 适合:大多数场景,对宽峰不敏感。

② arPLS(Asymmetrically Reweighted Penalized Least Squares) [5][7]

  • AsLS 的改进版,自动调整权重;
  • 对基线变化更敏感,适合快速漂移;
  • 参数:lam 通常需要 1e6–1e8。

③ AirPLS(Adaptive Iteratively Reweighted Penalized Least Squares) [5]

  • 自适应权重,对峰的识别更智能;
  • 适合复杂重叠峰。

④ SNIP(Statistics-sensitive Non-linear Iterative Peak-clipping) [5]

  • 适合光谱(最初为原子光谱设计);
  • 对尖锐峰保留好。

3.5 实操:同一谱图用不同算法对比

下面用 pybaselines 对一张严重倾斜的催化剂红外谱图做基线校正对比 [5]:

import numpy as np
import matplotlib.pyplot as plt
from pybaselines.whittaker import asls, arpls, airpls
from pybaselines.polynomial import modpoly
from pybaselines.morphological import mor

# 加载数据(假设 wn 是波数,y 是吸光度)
data = np.loadtxt('catalyst.csv', delimiter=',', skiprows=1)
wn, y = data[:, 0], data[:, 1]

# 5 种算法
baselines = {
    'AsLS (lam=1e7, p=0.01)': asls(y, lam=1e7, p=0.01)[0],
    'arPLS (lam=1e7)':        arpls(y, lam=1e7)[0],
    'airPLS':                 airpls(y)[0],
    'ModPoly (order=4)':      modpoly(y, x=wn, poly_order=4)[0],
    'Mor (window=50)':        mor(y, half_window=50)[0],
}

# 可视化对比
fig, axes = plt.subplots(2, 3, figsize=(15, 8))
axes = axes.flatten()

axes[0].plot(wn, y, 'k-', lw=0.5)
axes[0].set_title('Original')
for ax, (name, base) in zip(axes[1:], baselines.items()):
    ax.plot(wn, y, 'k-', lw=0.5, label='Original')
    ax.plot(wn, base, 'r-', lw=1.5, label='Baseline')
    ax.plot(wn, y - base, 'b-', lw=0.8, label='Corrected')
    ax.set_title(name)
    ax.legend(fontsize=8)
plt.tight_layout()
plt.savefig('baseline_comparison.png', dpi=150)

典型对比结果 [5][6]:

| 算法 | 计算时间 | 宽峰保留 | 倾斜校正 | 推荐场景 |
|------|---------|---------|---------|---------|
| AsLS | 快(< 1 s)| 一般 | 好 | 通用首选 |
| arPLS | 中(1–3 s)| 好 | 极好 | 快速漂移 |
| airPLS | 中(2–5 s)| 极好 | 极好 | 复杂重叠峰 |
| ModPoly | 极快(< 0.1 s)| 差(高阶)| 中 | 简单倾斜 |
| Mor | 快(< 1 s)| 差 | 中 | 尖锐峰 |

表 3:pybaselines 五大算法对比(综合 [5][6][7])

3.6 参数调优经验

AsLS / arPLS 的 lam 参数 [5][6]:

  • lam 控制 baseline 的平滑度,越大越平滑;
  • 经验范围:1e5(弯曲多)– 1e9(接近线性);
  • 默认 1e6 是好的起点;
  • 视觉判断:基线"贴底"但不"挖峰",调到合适。

p 参数(仅 AsLS)[6]:

  • 控制 asymmetric 程度,越小越偏向峰以下;
  • 默认 0.01;
  • 对宽峰谱图(如水溶液),可调到 0.001。

调试技巧 [5]:

# 自动尝试多个 lam,挑最优
from pybaselines.whittaker import arpls
lams = [1e5, 1e6, 1e7, 1e8, 1e9]
for lam in lams:
    base = arpls(y, lam=lam)[0]
    corrected = y - base
    # 计算"峰以下区域"的方差(应该最小)
    below = corrected[corrected < 0]
    score = np.var(below) if len(below) > 0 else 0
    print(f"lam={lam}: score={score:.4f}")

3.7 何时选 pybaselines

适合 [5][6]:

  • 商业软件默认基线算法效果不佳;
  • 需要批量、可复现的基线校正;
  • 研究新基线算法、对比算法;
  • 任何 Python 光谱处理流程的"基线步骤"。

不适合

  • 全流程光谱分析(用 SpectroChemPy);
  • 可视化工作流(用 Orange);
  • 商业软件默认算法已满足需求时(避免增加复杂度)。

💡 实用建议:把 pybaselines 作为 SpectroChemPy 的"插件"使用——SpectroChemPy 读数据 + 元数据,pybaselines 做基线,再回到 SpectroChemPy 做后续分析 [3][5]。


四、spectrapepper:入门级光谱分析包

4.1 项目概览

spectrapepper 是一个入门级光谱分析 Python 包,API 简洁,适合作为"第一段光谱代码" [2][8]。

图 3:spectrapepper GitHub 主页(来源:https://github.com/spectrapepper/spectrapepper)

4.2 核心特色

① API 极简 [8]:

import spectrapepper as spe

# 读取 CSV
data = spe.load('sample.csv')

# 基线校正
baseline = spe.baseline(data)
corrected = data - baseline

# 平滑
smoothed = spe.smooth(corrected, window=9)

# 峰检出
peaks = spe.find_peaks(smoothed, threshold=0.05)
print(peaks)

② 入门友好 [8]:

  • 函数名直观(load, baseline, smooth, find_peaks);
  • 默认参数即合理值;
  • 文档含大量教程示例。

③ 适合教学 [8]:

  • 课堂上能 5 分钟内让学生跑通第一段光谱代码;
  • 代码可读性高,便于讲解每步原理。

4.3 主要功能

spectrapepper 提供的核心功能 [8]:

  • 数据 I/O:CSV、TXT、部分厂商格式;
  • 预处理:基线校正(多项式 + ALS)、平滑(SG)、归一化;
  • 峰分析:峰检出、峰面积、半峰宽;
  • 多元分析:PCA、PLS(基于 scikit-learn);
  • 可视化:matplotlib 包装;
  • 光谱对比:相关系数、余弦相似度。

4.4 完整示例

import spectrapepper as spe
import matplotlib.pyplot as plt

# 1. 读取
sample = spe.load('unknown.csv')
reference = spe.load('reference.csv')

# 2. 预处理
sample_bc = spe.baseline_correction(sample)
sample_sm = spe.savitzky_golay(sample_bc, window=9, order=2)

reference_bc = spe.baseline_correction(reference)
reference_sm = spe.savitzky_golay(reference_bc, window=9, order=2)

# 3. 峰检出
peaks = spe.find_peaks(sample_sm, height=0.05, distance=10)
print(f"Found {len(peaks)} peaks at: {peaks}")

# 4. 相似度
similarity = spe.cosine_similarity(sample_sm, reference_sm)
print(f"Similarity to reference: {similarity:.3f}")

# 5. 可视化
plt.figure(figsize=(10, 5))
plt.plot(sample_sm, label='Sample')
plt.plot(reference_sm, label='Reference', alpha=0.7)
for p in peaks:
    plt.axvline(p, color='r', linestyle='--', alpha=0.3)
plt.legend()
plt.savefig('comparison.png', dpi=150)

4.5 何时选 spectrapepper

适合 [8]:

  • 光谱 Python 初学者;
  • 教学场景(学生第一次接触光谱编程);
  • 简单分析(不需要复杂算法);
  • 快速原型验证想法。

不适合

  • 复杂基线校正(用 pybaselines);
  • 多厂商格式读取(用 SpectroChemPy);
  • 高级化学计量学(直接用 scikit-learn);
  • 大规模数据生产环境(API 抽象过多,灵活性受限)。

五、对比与选型

5.1 三款工具对比

| 维度 | SpectroChemPy | pybaselines | spectrapepper |
|------|---------------|-------------|---------------|
| 定位 | 全流程框架 | 专注基线 | 入门级 |
| Star 数 | ~177 | ~189 | ~100+ |
| 学习曲线 | 中 | 平缓 | 极平缓 |
| 功能丰富度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐(专精)| ⭐⭐⭐ |
| 数据 I/O | ⭐⭐⭐⭐⭐(多厂商)| 仅数组 | ⭐⭐⭐ |
| 基线算法 | 内置少数 | 200+ | 内置少数 |
| 多元分析 | PCA, MCR-ALS | 无 | PCA, PLS |
| 可视化 | 集成 | 无 | 集成 |
| 教学价值 | 高 | 中 | 极高 |
| 生产环境 | 适合 | 适合(基线步骤)| 适合(简单任务)|

表 4:三款开源光谱工具对比

5.2 选型决策树

你的需求是什么?
   │
   ├─ 全流程光谱处理(读取→处理→建模)
   │   └─ SpectroChemPy
   │
   ├─ 仅需基线校正(且商业软件不够)
   │   └─ pybaselines
   │
   ├─ 入门 / 教学 / 快速原型
   │   └─ spectrapepper
   │
   ├─ 多维成像数据(FPA)
   │   └─ HyperSpy(见 Ep 54)
   │
   ├─ 拖拽式工作流
   │   └─ Orange-Spectroscopy(见 Ep 54)
   │
   └─ 跨平台 / 在线查看
       └─ ftir.fun

图 4:开源光谱工具选型决策树

5.3 组合使用案例

真实工作流示例:催化剂原位红外数据分析 [3][5]:

# 1. SpectroChemPy 读取多厂商数据
import spectrochempy as scp
ds = scp.read('catalyst_in_situ.spa')

# 2. pybaselines 做基线校正(更精细)
from pybaselines.whittaker import arpls
import numpy as np

# 转为数组处理
y = ds.data.T  # 样品 × 波数 → 波数 × 样品
baselines = np.array([arpls(yi, lam=1e7)[0] for yi in y.T])
corrected = y - baselines.T

# 转回 NDDataset
ds_bc = scp.NDDataset(
    corrected,
    coordset=ds.coordset,
    title='Baseline-corrected',
    history='arPLS baseline correction (pybaselines)'
)

# 3. SpectroChemPy 做后续分析(MCR-ALS)
mcr = scp.MCRALS(ds_bc, n_components=3)
mcr.fit()

# 4. 可视化
mcr.ST.plot(title='Pure component spectra')
mcr.C.plot(title='Concentration profiles')

# 5. 导出
mcr.ST.write('pure_components.csv')

这种组合(SpectroChemPy 读数据 + pybaselines 做基线 + SpectroChemPy 做后续)是 2024 年开源光谱分析的常见做法 [3][5]。


六、何时仍需商业软件

开源工具强大,但并非万能 [1][2]。以下场景仍建议商业软件:

6.1 GMP / FDA 合规环境

  • 商业软件有 21 CFR Part 11 认证(审计追踪、电子签名)[1];
  • 开源工具无合规认证,制药 QC 中使用风险高;
  • 数据完整性(Data Integrity)要求软件版本可追溯、操作不可篡改。

6.2 仪器原生控制

  • 商业软件与仪器硬件深度集成(采集控制、附件识别)[1];
  • 开源工具大多只能处理已导出的数据,不能直接控制仪器采集;
  • 例外:部分开源项目(如 Solis)支持仪器控制,但生态弱。

6.3 大型商业谱库

  • Sadtler、Aldrich、Hummel 等大型商业谱库只在商业软件中完整集成 [1];
  • 开源工具只能用 NIST WebBook 等免费库(见 Ep 55);
  • 库检索算法本身开源可实现,但库内容版权是障碍。

6.4 标准化方法验证

  • USP <854>、Ph.Eur. 2.2.24 等药典方法有指定软件流程 [1];
  • 商业软件有验证文档支持;
  • 开源工具需自行做完整方法验证。

6.5 团队协作与培训

  • 大团队中,GUI 商业软件培训成本低;
  • 开源工具要求 Python 基础;
  • 跨实验室协作时,统一商业软件更易对接。

💡 判断框架生产环境(QC、GMP)优先商业;科研、原型、定制分析优先开源。 两者并不冲突,常组合使用 [1][2]。


七、开源工具的"踩坑"提示

7.1 坑 1:版本兼容性

情境:升级 SpectroChemPy 0.4 → 0.6 后,老代码报错 [3]。

原因:开源项目 API 不稳定,主版本升级常有 breaking changes。

对策

  • requirements.txtenvironment.yml 锁定版本;
  • 升级前阅读 CHANGELOG;
  • 关键代码用虚拟环境隔离(venv / conda)。

7.2 坑 2:依赖冲突

情境:安装 pybaselines 后,与已有 NumPy 版本冲突 [5]。

对策

# 用 conda 隔离环境
conda create -n spectra python=3.10
conda activate spectra
pip install spectrochempy pybaselines spectrapepper

7.3 坑 3:算法误用

情境:用 arPLS 校正一张 4000 cm⁻¹ 处有强 O-H 宽峰的谱图,结果 O-H 峰被"挖掉"一半 [6]。

对策

  • 大宽峰(O-H 3400、N-H 3300)容易被基线算法误判;
  • 校正前先看谱图,避开宽峰区;
  • mask 参数排除宽峰区:
from pybaselines.whittaker import arpls
# 排除 3000-3700 cm⁻¹ 的 O-H 区
mask = (wn < 3000) | (wn > 3700)
base = arpls(y, lam=1e7, mask=mask)[0]

7.4 坑 4:单位混乱

情境:SpectroChemPy 读取的波数单位是 cm⁻¹,但 plot 时显示 nm [3]。

对策

  • 显式指定单位;
  • 用 NDDataset 的单位感知功能:
ds.units = 'cm^-1'  # 强制
ds.x.units = 'cm^-1'

7.5 坑 5:可视化样式不一致

情境:不同工具画的谱图样式差异大,论文中混用难看 [3][5]。

对策

  • 统一用 matplotlib,自定义样式:
import matplotlib.pyplot as plt
plt.style.use('seaborn-v0_8-whitegrid')
plt.rcParams.update({
    'figure.figsize': (10, 5),
    'font.size': 12,
    'axes.labelsize': 14,
    'axes.titlesize': 14,
    'legend.fontsize': 10,
})

配图(本集关键示意)

📷 图 5:仪器能力对比示意

仪器能力对比示意
来源:真实/开源图片 · Project case study — PE spectrum(已加水印 ftir.fun)

仪器能力对比示意

📷 图 6:光路/附件概念

光路/附件概念
来源:真实/开源图片 · Unsplash — chemistry lab(已加水印 ftir.fun)

光路/附件概念

📷 图 7:软件/数据库工作流

软件/数据库工作流
来源:ftir.fun 教学示意图(带水印;非实测谱,仅供理解概念)

软件/数据库工作流

本集小结

| 核心知识点 | 要点 |
|-----------|------|
| 开源工具优势 | 算法透明、可定制、Python 生态、跨平台、免费 |
| 商业软件优势 | 合规、仪器控制、商业库、培训成本低 |
| SpectroChemPy | 全流程框架,NDDataset 元数据一体化,多厂商格式读取 |
| NDDataset | 数据 + 坐标 + 单位 + 历史一体化,FAIR 数据原则 |
| SpectroChemPy 强项 | MCR-ALS、多厂商 I/O、教学价值高 |
| pybaselines | 200+ 基线算法,FTIR topic star 最高 |
| 基线校正重要性 | 影响峰位、峰面积、下游分析,最易出错 |
| 主力算法 | AsLS(通用)、arPLS(漂移)、airPLS(复杂)、SNIP(尖峰)|
| lam 参数 | 平滑度,1e5–1e9,默认 1e6 |
| p 参数 | 非对称性,0.001–0.1,默认 0.01 |
| spectrapepper | 入门级,API 简洁,教学首选 |
| 选型框架 | 全流程→SpectroChemPy;基线→pybaselines;入门→spectrapepper |
| 组合做法 | SpectroChemPy 读 + pybaselines 校 + SpectroChemPy 析 |
| 仍需商业软件 | GMP、仪器控制、大型库、方法验证、团队协作 |
| 常见踩坑 | 版本兼容、依赖冲突、宽峰误判、单位混乱、样式不一 |


思考题

  1. 你有一批 Bruker OPUS 采集的催化剂原位红外数据(50 张谱图),需要做基线校正 + MCR-ALS 分解。请设计一个完整的 Python 工作流,说明 SpectroChemPy 和 pybaselines 各自承担什么角色,并写出关键代码。

  2. 用 pybaselines 对同一张严重倾斜的聚苯乙烯谱图分别用 AsLS、arPLS、airPLS、ModPoly(order=4)做基线校正。请设计一个量化指标来比较四种算法的效果(提示:考虑峰以下区域的方差、峰位稳定性、宽峰保留度)。

  3. 解释为什么 AsLS 算法对水溶液蛋白质谱图(1640 cm⁻¹ 有强水峰)的基线校正效果可能不好。应该如何调整参数或选择其他算法?参考 ftir.fun 水分子官能团页

  4. 一位制药公司 QC 主管问:"开源光谱工具能否替代 OMNIC 用于 GMP 释放检测?"请基于 21 CFR Part 11、USP <854>、数据完整性等角度,给出一个结构化的回答。

  5. 用 spectrapepper 写一段代码,读取 5 张 CSV 谱图,对每张做基线校正 + 平滑 + 峰检出,输出每张图的峰位列表到 CSV。说明这段代码相比在 OMNIC 中手动操作的优劣。


参考文献

[1] Smith B C. "Open Source Software for FTIR Data Analysis." Spectroscopy, 2023, 38(7): 12–18.
https://www.spectroscopyonline.com/

[2] GitHub. "Topic: ftir." https://github.com/topics/ftir

[3] Travert A, et al. "SpectroChemPy: A Python Framework for Processing Spectral Data." Journal of Open Source Software, 2022, 7(71): 3904. DOI:10.21105/joss.03904.
项目地址:https://github.com/spectrochempy/spectrochempy
文档:https://www.spectrochempy.fr/

[4] SpectroChemPy Documentation. "NDDataset: Core Data Structure."
https://www.spectrochempy.fr/gettingstarted/nddataset.html

[5] Pybaselines Documentation. "Pybaselines: A Python Library for Baseline Correction."
项目地址:https://github.com/derb12/pybaselines
文档:https://pybaselines.readthedocs.io/

[6] Liland K H, Rukke E H, Olsen E F, et al. "Customized Baseline Correction." Applied Spectroscopy, 2011, 65(8): 907–915. DOI:10.1366/10-06124.

[7] Eilers P H C, Boelens H F M. "Baseline Correction with Asymmetric Least Squares Smoothing." Leiden University Medical Centre Report, 2005.

[8] spectrapepper Documentation. "Spectrapepper: Simple Spectral Analysis."
项目地址:https://github.com/spectrapepper/spectrapepper
文档:https://spectrapepper.github.io/spectrapepper/

[9] ftir.fun. "在线红外光谱工具."
https://ftir.fun

[10] McKinney W. "Data Structures for Statistical Computing in Python." Proc. SciPy 2010.(NumPy / pandas 基础)


下一集预告:Ep 54 — 开源工具篇(下):HyperSpy、Orange-Spectroscopy
上集讲了通用光谱框架,下集转向两大"专精"工具:HyperSpy(多维光谱成像分析标杆,~560 stars,FPA 数据处理首选)和 Orange-Spectroscopy(拖拽式可视化工作流,零编程门槛)。还会介绍轻量级 SpectraKit 和深度学习框架 NIRS4ALL。配 FPA 成像数据立方体处理、PLS 模型搭建的完整实操。


本文使用 CC BY-NC-SA 4.0 许可。配图来自公开领域或已标注来源的网络资源,版权归原作者所有。

Invia Richiesta Modulo