Ep 53 — Open-Source Tools (Part I): SpectroChemPy, pybaselines
Series: Encyclopedia of Infrared Spectroscopy: From Principles to Practice
Chapter: Part 5 · Instruments and Tools — Open-Source Ecosystem (Ep 46–55 latter part)
Target Audience: Technical personnel, graduate students, chemometrics enthusiasts, Python users who want to improve data processing efficiency
Prerequisites: Ep 18 (spectral processing), Ep 19 (library search), Ep 20 (quantitative analysis), Ep 52 (commercial software review)
Reading Time: ~45 minutes
Introduction: When Python Meets Infrared Spectroscopy
A PhD student, Xiao Chen, collected in-situ IR data of catalysts using a Bruker INVENIO to study CO adsorption on Pt/Al₂O₃. He opened OPUS software to do baseline correction—but found that OPUS's built-in algorithm performed poorly on this complex scenario of "full spectrum heavily tilted + baseline curvature near strong absorption regions." He then tried the OMNIC trial version, but was still unsatisfied.
His advisor said: "Try pybaselines with Python; it has over 200 baseline algorithms."
Xiao Chen spent 1 hour learning, wrote 20 lines of Python code, and got results—the baseline correction was far better than the default algorithms in commercial software. From then on, he fell into the "rabbit hole" of open-source spectral tools.
"Python + open-source spectral libraries are changing the data analysis ecosystem of spectroscopy. They are no longer just 'supplements' to commercial software, but have become the core of scientific research workflows."
— Adapted from Applied Spectroscopy 2023 commentary [1]
This episode will systematically review three open-source Python spectral tools: SpectroChemPy (full workflow framework for chemical spectroscopy), pybaselines (baseline correction algorithm library), and spectrapepper (entry-level spectral analysis package). Each comes with GitHub links, star counts, practical code, and a decision framework for "when to choose open source and when to stick with commercial software."
💡 Positioning: Ep 52 reviews commercial software, Ep 53–54 review open-source software. Open source is not a "free version of commercial software" but a "flexible and customizable research tool." Together, these two episodes form a spectral toolbox for Python users.
1. Overview of the Open-Source Spectral Tool Ecosystem
1.1 Why Open-Source Tools
Commercial FTIR software (OMNIC, OPUS, Spectrum) is fully featured but has the following limitations [1][2]:
- Closed algorithms: Users do not know the specific implementation of baseline correction, smoothing, etc.; results are not reproducible;
- Poor extensibility: Unable to customize new algorithms or models;
- Weak batch processing: GUI operations are inefficient for complex processing of hundreds of spectra;
- Poor cross-platform: Windows only, no Linux/Mac version (except partially for OPUS);
- Weak machine learning integration: Modern data analysis (deep learning, Bayesian optimization) requires the Python ecosystem;
- High cost: Modular pricing, advanced features purchased separately.
Advantages of open-source tools [1][2][3]:
- Algorithm transparency: Source code is viewable, results are reproducible;
- Fully customizable: Custom algorithms, workflows, and visualizations;
- Python ecosystem: Seamless integration with NumPy, SciPy, scikit-learn, PyTorch;
- Cross-platform: Full support for Windows, Linux, Mac;
- Free: No license restrictions.
1.2 "Star List" of Open-Source Spectral Tools
Active open-source projects on GitHub under the topic "FTIR / spectroscopy" (as of 2024) [2][3]:
| Project | Stars | Primary Use | Covered in This Episode |
|---|---|---|---|
| HyperSpy | ~560 | Multidimensional spectral (imaging) analysis | Ep 54 |
| pybaselines | ~189 | Baseline correction algorithm library (star count varies with time, ~hundreds at time of writing) | ✅ This episode |
| SpectroChemPy | ~177 | Full workflow framework for chemical spectroscopy | ✅ This episode |
| Orange-Spectroscopy | ~140 | Drag-and-drop visual workflow | Ep 54 |
| spectrapepper | ~100+ | Entry-level spectral analysis package | ✅ This episode |
| NIRS4ALL | ~80 | NIR transformation + deep learning | Ep 54 |
| pyspectrakit | ~50 | Lightweight core operations | Ep 54 |
Table 1: GitHub star counts of open-source spectral tools (Source: GitHub topics "spectroscopy" / "ftir", 2024)
🔗 Extension: ftir.fun is a Chinese-friendly online spectral tool supplement, providing web-based spectral viewing, peak identification, and library search, requiring no programming for quick analysis.
2. SpectroChemPy: A Full Workflow Python Framework for Chemical Spectroscopy
2.1 Project Overview
SpectroChemPy is an open-source Python framework developed by Arnaud Travert's team at the French Institute of Laser and Applied Physical Chemistry (LCP-A2S), specifically designed for chemical spectroscopy (IR, Raman, NIR, UV-Vis, NMR) [3][4].
- GitHub: https://github.com/spectroche…
- Documentation: https://www.spectrochempy.fr/
- Stars: ~177 (as of 2024)
- License: CeCILL-B (French version of MIT, business-friendly)
- First Release: 2019
- Python Version: 3.8+
Figure 1: SpectroChemPy GitHub homepage (Source: https://github.com/spectroche…)
2.2 Core Feature: NDDataset Data Structure
The most important innovation of SpectroChemPy is the NDDataset data structure [3][4]:
from spectrochempy import NDDataset
# Create a spectral dataset
dataset = NDDataset(
absorbance_data, # 2D array: samples × wavenumbers
coordset=[
('samples', sample_names), # First dimension: sample names
('wavenumbers', wn_array, 'cm⁻¹') # Second dimension: wavenumbers + unit
],
title='Absorbance',
units='absorbance',
name='Catalyst_CO_Adsorption',
history='2024-07-15: collected on INVENIO R',
author='Bob',
)
Advantages of NDDataset over NumPy ndarray [3][4]:
- Integrated metadata: Coordinates (wavenumber, temperature, time), units, titles, history are bound to the data;
- Unit-aware: Automatically handles conversions such as cm⁻¹ ↔ nm, Abs ↔ %T;
- Clear slicing semantics:
dataset[:, '4000::1']means "all samples, starting from 4000 cm⁻¹ with step 1 cm⁻¹"; - Traceable: Each operation is automatically appended to
history, complying with FAIR data principles; - Visualization integrated:
dataset.plot()directly produces plots with automatic unit labeling on axes.
2.3 Full Workflow Coverage
SpectroChemPy covers the entire workflow of spectral analysis [3][4]:
Read → Preprocess → Analyze → Model → Visualize → Export
│ │ │ │ │ │
│ │ │ │ │ └ CSV, JCAMP-DX, HDF5
│ │ │ │ └ matplotlib, plotly
│ │ │ └ PLS, PCA, MCR-ALS
│ │ └ Peak detection, curve fitting, integration
│ └ Baseline, smoothing, normalization, ATR correction, derivation
└ OMNIC (.spa), OPUS (.opu), JCAMP-DX (.jdx), SPA, CSV
**① Read multi-vendor formats** [3][4]:
```python
from spectrochempy import read
# Read Thermo OMNIC .spa file
ds_omnic = read('sample.spa')
# Read Bruker OPUS .opu file
ds_opus = read('sample.opu')
# Read JCAMP-DX .jdx file
ds_jcamp = read('sample.jdx')
# Read CSV (specify columns)
ds_csv = read('sample.csv', csv_delimiter=',')
This is one of SpectroChemPy's most powerful features — direct reading of commercial software proprietary formats without needing to export and convert first [3].
② Preprocessing [3][4]:
# Baseline correction (multiple built-in algorithms)
ds_bc = ds_omnic.baseline_correct(method='als', lam=1e7, p=0.01)
# Smoothing (Savitzky-Golay)
ds_sm = ds_bc.smooth(method='sg', window_size=9, polyorder=2)
# Normalization
ds_norm = ds_sm.normalize(method='max')
# Derivation
ds_d2 = ds_norm.derivative(order=2, window_size=11, polyorder=3)
③ Multivariate Curve Resolution (MCR-ALS) [3][4]:
MCR-ALS is SpectroChemPy's signature feature, ideal for mixture spectrum decomposition:
from spectrochempy import MCRALS
# Assume ds is multiple spectra from a reaction process (time × wavenumber)
mcr = MCRALS(ds, n_components=3, max_iter=100)
mcr.fit()
# Output: pure spectra of 3 components + concentration profiles
pure_spectra = mcr.ST # Component spectra
concentrations = mcr.C # Concentration matrix
pure_spectra.plot()
concentrations.plot()
④ Visualization [3][4]:
import spectrochempy as scp
# Single spectrum
ds.plot(title='Catalyst CO Adsorption', color='red')
# Multiple spectra overlay
scp.plot_multi(ds1, ds2, ds3, labels=['A', 'B', 'C'])
# 3D surface plot
ds.plot_3D()
# Heatmap (reaction process data)
ds.plot_waterfall()
2.4 Educational Value
SpectroChemPy's API design is close to chemist language (baseline_correct rather than baseline_correct), with detailed documentation, making it the best entry point for learning spectral Python processing [3][4].
Complete teaching example — read polystyrene spectrum and process:
import spectrochempy as scp
# 1. Read data (example dataset)
ds = scp.read('irdata/nh4y-activation.spa')
# 2. Crop region of interest
ds = ds[:, '4000::650'] # 4000-650 cm⁻¹
# 3. Baseline correction (ALS)
ds_bc = ds.baseline_correct(method='asls', lam=1e5, p=0.01)
# 4. Smoothing
ds_sm = ds_bc.smooth(method='sg', window_size=9, polyorder=2)
# 5. Normalization
ds_norm = ds_sm.normalize(method='max')
# 6. Visualization
ds_norm.plot(title='NH4Y Activation', colormap='viridis')
# 7. Export
ds_norm.write('processed.jdx') # JCAMP-DX format
ds_norm.write('processed.csv') # CSV format
2.5 When to Choose SpectroChemPy
Suitable for [3][4]:
- Full chemical spectroscopy workflow (read → process → model → visualize);
- Multi-vendor data integration (directly read .spa / .opu);
- Teaching (API-friendly, comprehensive documentation);
- Advanced decomposition like MCR-ALS;
- Need for traceable metadata (FAIR data principles).
Not suitable for:
- Single baseline correction task (use pybaselines for lighter weight);
- FPA imaging data (use HyperSpy);
- Drag-and-drop workflow (use Orange-Spectroscopy);
- Extreme performance (core is still NumPy, no optimization for very large matrices).
Three, pybaselines: Encyclopedia of Baseline Correction Algorithms
3.1 Project Overview
pybaselines developed by derb12 (GitHub username), is a Python library focused on baseline correction, providing 200+ baseline correction algorithms, and is the highest-starred project in the FTIR topic [2][5].
- GitHub: https://github.com/derb12/pyb…
- Documentation: https://pybaselines.readthedo…
- Stars: approximately hundreds at the time of writing (as of note date; please refer to GitHub's current page, do not treat as permanent ranking)
- License: BSD-3-Clause (one of the most permissive open-source licenses)
- First release: 2020
- Python version: 3.8+
Figure 2: pybaselines GitHub homepage (Source: https://github.com/derb12/pyb…)
3.2 Why Baseline Correction is the Most Critical Preprocessing Step
Baseline correction is the step in spectral preprocessing that most affects subsequent analysis results [5][6][7]:
- Peak shift: Baseline curvature can shift peak position by 1–5 cm⁻¹;
- Peak area distortion: High baseline inflates peak area, quantification error can exceed 20%;
- False peak risk: Over-correction with high-order polynomials can "dig out" false peaks;
- Downstream impact: Baseline-corrected spectra are inputs to PLS, PCA, library search; errors propagate.
"Among all preprocessing steps in spectral analysis, baseline correction has the greatest impact, the most controversy, and is the easiest to make mistakes."
— Liland K H, Applied Spectroscopy 2011 [6]
The value of pybaselines is: unify over 200 algorithms into a consistent API, allowing you to quickly compare and select the most suitable algorithm [5].
3.3 Algorithm Classification
pybaselines categorizes baseline algorithms into 8 classes [5]:
| Category | Representative Algorithms | Applicable Scenarios |
|---|---|---|
| Polynomial | Poly, ModPoly, IModPoly, Polynomial | Simple tilt, curvature |
| Whittaker | AsLS, IAsLS, AirPLS, ArPLS, DrPLS | Complex curvature, broad peaks |
| ALS | AsLS, IAsLS, arPLS, asPLS | Modern workhorse, insensitive to broad peaks |
| Morphological | Mor, Imor, AMor | Morphological, suitable for sharp peaks |
| Window | Noise, Noisy | Sliding window |
| Spline | mixture, mixture_mod | Smoothing spline |
| Baseline | Dietrich, CWT, FUNP | Wavelet, frequency domain |
| Optimization | Custom, Cole | Optimization methods |
Table 2: pybaselines algorithm categories (synthesized from [5][6])
3.4 Comparison of Four Major Algorithms
① AsLS (Asymmetric Least Squares) [6][7]
- Proposed by Eilers & Boelens, the "standard" algorithm for modern baseline correction;
- Principle: asymmetric weighted least squares + second-order difference smoothing;
- Parameters:
lam(smoothness, 1e5–1e9),p(asymmetry, 0.001–0.1); - Suitable for: most scenarios, insensitive to broad peaks.
② arPLS (Asymmetrically Reweighted Penalized Least Squares) [5][7]
- Improved version of AsLS, automatically adjusts weights;
- More sensitive to baseline changes, suitable for fast drift;
- Parameters:
lamtypically needs 1e6–1e8.
③ AirPLS (Adaptive Iteratively Reweighted Penalized Least Squares) [5]
- Adaptive weighting, more intelligent peak identification;
- Suitable for complex overlapping peaks.
④ SNIP (Statistics-sensitive Non-linear Iterative Peak-clipping) [5]
- Suitable for spectra (originally designed for atomic spectra);
- Good preservation of sharp peaks.
3.5 Practical: Comparison of Different Algorithms on the Same Spectrum
The following uses pybaselines to perform baseline correction comparison on a severely tilted catalyst infrared spectrum [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
# Load data (assume wn is wavenumber, y is absorbance)
data = np.loadtxt('catalyst.csv', delimiter=',', skiprows=1)
wn, y = data[:, 0], data[:, 1]
# 5 algorithms
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],
}
# Visualization comparison
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)
Typical comparison results [5][6]:
| Algorithm | Computation time | Broad peak retention | Tilt correction | Recommended scenario |
|---|---|---|---|---|
| AsLS | Fast (< 1 s) | Fair | Good | General purpose first choice |
| arPLS | Medium (1–3 s) | Good | Excellent | Fast drift |
| airPLS | Medium (2–5 s) | Excellent | Excellent | Complex overlapping peaks |
| ModPoly | Very fast (< 0.1 s) | Poor (high order) | Fair | Simple tilt |
| Mor | Fast (< 1 s) | Poor | Fair | Sharp peaks |
Table 3: Comparison of five pybaselines algorithms (synthesized from [5][6][7])
3.6 Parameter Tuning Experience
lam parameter for AsLS / arPLS [5][6]:
lamcontrols the smoothness of the baseline; larger values give smoother baselines;- Empirical range: 1e5 (more curvature) – 1e9 (nearly linear);
- Default 1e6 is a good starting point;
- Visual judgment: baseline "hugs the bottom" but does not "dig into peaks"; adjust appropriately.
p parameter (AsLS only) [6]:
- Controls the degree of asymmetry; smaller values favor being below peaks;
- Default 0.01;
- For spectra with broad peaks (e.g., aqueous solutions), can be adjusted to 0.001.
Debugging tips [5]:
# Automatically try multiple lam values, pick the best
from pybaselines.whittaker import arpls
lams = [1e5, 1e6, 1e7, 1e8, 1e9]
for lam in lams:
base = arpls(y, lam=lam)[0]
corrected = y - base
# Calculate the variance of "below-peak" regions (should be minimal)
below = corrected[corrected < 0]
score = np.var(below) if len(below) > 0 else 0
print(f"lam={lam}: score={score:.4f}")
3.7 When to Choose pybaselines
Suitable [5][6]:
- When default baseline algorithms in commercial software perform poorly;
- When batch, reproducible baseline correction is needed;
- When researching new baseline algorithms or comparing algorithms;
- As the "baseline step" in any Python spectral processing pipeline.
Not suitable:
- For full-pipeline spectral analysis (use SpectroChemPy);
- For visual workflow (use Orange);
- When default algorithms in commercial software already meet requirements (to avoid added complexity).
💡 Practical advice: Use pybaselines as a "plugin" for SpectroChemPy—SpectroChemPy for data loading and metadata, pybaselines for baseline correction, then back to SpectroChemPy for subsequent analysis [3][5].
4. spectrapepper: Entry-level Spectral Analysis Package
4.1 Project Overview
spectrapepper is an entry-level spectral analysis Python package with a simple API, suitable as a "first spectral code" [2][8].
- GitHub: https://github.com/spectrapep…
- Documentation: https://spectrapepper.github.…
- Stars: ~100+ (as of 2024)
- License: MIT
- First Release: 2022
- Python Version: 3.7+
Figure 3: spectrapepper GitHub homepage (source: https://github.com/spectrapep…)
4.2 Core Features
① Minimalist API [8]:
import spectrapepper as spe
# Read CSV
data = spe.load('sample.csv')
# Baseline correction
baseline = spe.baseline(data)
corrected = data - baseline
# Smoothing
smoothed = spe.smooth(corrected, window=9)
# Peak detection
peaks = spe.find_peaks(smoothed, threshold=0.05)
print(peaks)
② Beginner-Friendly [8]:
- Intuitive function names (
load,baseline,smooth,find_peaks); - Default parameters are reasonable values;
- Documentation includes many tutorial examples.
③ Suitable for Teaching [8]:
- In class, students can run their first spectrum code within 5 minutes;
- High code readability, easy to explain each step's principle.
4.3 Main Functions
Core functions provided by spectrapepper [8]:
- Data I/O: CSV, TXT, some vendor formats;
- Preprocessing: Baseline correction (polynomial + ALS), smoothing (SG), normalization;
- Peak Analysis: Peak detection, peak area, full width at half maximum;
- Multivariate Analysis: PCA, PLS (based on scikit-learn);
- Visualization: matplotlib wrapper;
- Spectral Comparison: Correlation coefficient, cosine similarity.
4.4 Complete Example
import spectrapepper as spe
import matplotlib.pyplot as plt
# 1. Load
sample = spe.load('unknown.csv')
reference = spe.load('reference.csv')
# 2. Preprocessing
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. Peak detection
peaks = spe.find_peaks(sample_sm, height=0.05, distance=10)
print(f"Found {len(peaks)} peaks at: {peaks}")
# 4. Similarity
similarity = spe.cosine_similarity(sample_sm, reference_sm)
print(f"Similarity to reference: {similarity:.3f}")
# 5. Visualization
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 When to Choose spectrapepper
Suitable [8]:
- Python beginners in spectroscopy;
- Teaching scenarios (students' first encounter with spectral programming);
- Simple analysis (no complex algorithms needed);
- Quick prototype to validate ideas.
Not Suitable:
- Complex baseline correction (use pybaselines);
- Reading multiple vendor formats (use SpectroChemPy);
- Advanced chemometrics (use scikit-learn directly);
- Large-scale production environments (API is too abstract, limited flexibility).
V. Comparison and Selection
5.1 Comparison of Three Tools
| Dimension | SpectroChemPy | pybaselines | spectrapepper |
|---|---|---|---|
| Positioning | Full workflow framework | Focused on baseline | Entry-level |
| Stars | ~177 | ~189 | ~100+ |
| Learning Curve | Medium | Gentle | Very gentle |
| Feature Richness | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ (specialized) | ⭐⭐⭐ |
| Data I/O | ⭐⭐⭐⭐⭐ (multiple vendors) | Array only | ⭐⭐⭐ |
| Baseline Algorithms | Built-in few | 200+ | Built-in few |
| Multivariate Analysis | PCA, MCR-ALS | None | PCA, PLS |
| Visualization | Integrated | None | Integrated |
| Teaching Value | High | Medium | Very high |
| Production Environment | Suitable | Suitable (baseline step) | Suitable (simple tasks) |
Table 4: Comparison of three open-source spectral tools
5.2 Selection Decision Tree
What are your needs?
|
├─ Full-spectrum processing (load → process → model)
│ └─ SpectroChemPy
|
├─ Baseline correction only (and commercial software is insufficient)
│ └─ pybaselines
|
├─ Entry-level / Teaching / Quick prototype
│ └─ spectrapepper
|
├─ Multidimensional imaging data (FPA)
│ └─ HyperSpy (see Ep 54)
|
├─ Drag-and-drop workflow
│ └─ Orange-Spectroscopy (see Ep 54)
|
└─ Cross-platform / Online viewing
└─ ftir.fun
Figure 4: Decision tree for selecting open-source spectral tools
5.3 Combined Use Case
Real workflow example: In situ catalyst infrared data analysis [3][5]:
# 1. SpectroChemPy reads multiple vendor data
import spectrochempy as scp
ds = scp.read('catalyst_in_situ.spa')
# 2. pybaselines for baseline correction (more refined)
from pybaselines.whittaker import arpls
import numpy as np
# Convert to array for processing
y = ds.data.T # samples × wavenumbers → wavenumbers × samples
baselines = np.array([arpls(yi, lam=1e7)[0] for yi in y.T])
corrected = y - baselines.T
# Convert back to NDDataset
ds_bc = scp.NDDataset(
corrected,
coordset=ds.coordset,
title='Baseline-corrected',
history='arPLS baseline correction (pybaselines)'
)
3. Post-analysis with SpectroChemPy (MCR-ALS)
mcr = scp.MCRALS(ds_bc, n_components=3)
mcr.fit()
# 4. Visualization
mcr.ST.plot(title='Pure component spectra')
mcr.C.plot(title='Concentration profiles')
# 5. Export
mcr.ST.write('pure_components.csv')
This combination (SpectroChemPy for reading + pybaselines for baseline + SpectroChemPy for subsequent analysis) is a common approach in open-source spectral analysis as of 2024 [3][5].
6. When Commercial Software Is Still Needed
Open-source tools are powerful but not omnipotent [1][2]. The following scenarios still recommend commercial software:
6.1 GMP / FDA Compliant Environments
- Commercial software has 21 CFR Part 11 certification (audit trail, electronic signatures) [1];
- Open-source tools lack compliance certifications, posing high risk in pharmaceutical QC;
- Data Integrity requires that software versions be traceable and operations non-tamperable.
6.2 Native Instrument Control
- Commercial software integrates deeply with instrument hardware (acquisition control, accessory recognition) [1];
- Most open-source tools can only process already exported data, not directly control instrument acquisition;
- Exception: Some open-source projects (e.g., Solis) support instrument control, but the ecosystem is weak.
6.3 Large Commercial Spectral Libraries
- Large commercial libraries such as Sadtler, Aldrich, and Hummel are only fully integrated in commercial software [1];
- Open-source tools can only use free libraries like NIST WebBook (see Ep 55);
- Library search algorithms themselves are implementable in open-source, but library content copyright is a barrier.
6.4 Standardized Method Validation
- Pharmacopoeial methods like USP <854>, Ph.Eur. 2.2.24 have specified software workflows [1];
- Commercial software comes with validation documentation;
- Open-source tools require self-conducted full method validation.
6.5 Team Collaboration and Training
- In large teams, GUI-based commercial software has lower training costs;
- Open-source tools require Python basics;
- For cross-laboratory collaboration, unified commercial software is easier to coordinate.
💡 Decision Framework: Production environments (QC, GMP) prioritize commercial; research, prototyping, and customized analysis prioritize open-source. The two are not conflicting and are often used in combination [1][2].
7. Pitfalls of Open-Source Tools
7.1 Pitfall 1: Version Compatibility
Scenario: After upgrading SpectroChemPy 0.4 → 0.6, old code throws errors [3].
Reason: Open-source project APIs are unstable; major version upgrades often have breaking changes.
Countermeasure:
- Lock versions using
requirements.txtorenvironment.yml; - Read CHANGELOG before upgrading;
- Isolate critical code with virtual environments (venv / conda).
7.2 Pitfall 2: Dependency Conflicts
Scenario: After installing pybaselines, conflicts with existing NumPy version [5].
Countermeasure:
# Isolate environment with conda
conda create -n spectra python=3.10
conda activate spectra
pip install spectrochempy pybaselines spectrapepper
7.3 Pitfall 3: Algorithm Misuse
Scenario: Using arPLS to correct a spectrum with a strong O-H broad peak at 4000 cm⁻¹, resulting in the O-H peak being "dug out" halfway [6].
Countermeasure:
- Broad peaks (O-H 3400, N-H 3300) are easily misjudged by baseline algorithms;
- Inspect the spectrum before correction to avoid broad peak regions;
- Use the
maskparameter to exclude broad peak regions:from pybaselines.whittaker import arpls # Exclude O-H region 3000-3700 cm⁻¹ mask = (wn < 3000) | (wn > 3700) base = arpls(y, lam=1e7, mask=mask)[0]
7.4 Pitfall 4: Unit Confusion
Scenario: The wavenumber unit read by SpectroChemPy is cm⁻¹, but plot displays nm [3].
Countermeasure:
- Explicitly specify units;
- Use NDDataset's unit-aware functionality:
ds.units = 'cm^-1' # Force ds.x.units = 'cm^-1'
7.5 Pitfall 5: Inconsistent Visualization Styles
Scenario: Different tools produce spectra with vastly different styles, leading to poor appearance when mixed in a paper [3][5].
Countermeasure:
- Unify with matplotlib, custom style:
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, })
Episode Summary
| Core Knowledge Point | Key Points |
|---|---|
| Open-source tool advantages | Algorithm transparency, customizability, Python ecosystem, cross-platform, free |
| Commercial software advantages | Compliance, instrument control, commercial libraries, low training cost |
| SpectroChemPy | Full workflow framework, NDDataset metadata integration, multi-vendor format reading |
| NDDataset | Data + coordinates + units + history integrated, FAIR data principles |
| SpectroChemPy strengths | MCR-ALS, multi-vendor I/O, high pedagogical value |
| pybaselines | 200+ baseline algorithms, highest FTIR topic star |
| Importance of baseline correction | Affects peak positions, peak areas, downstream analysis; most error-prone |
| Main algorithms | AsLS (general), arPLS (drift), airPLS (complex), SNIP (sharp peaks) |
| lam parameter | Smoothness, 1e5–1e9, default 1e6 |
| p parameter | Asymmetry, 0.001–0.1, default 0.01 |
| spectrapepper | Entry-level, concise API, preferred for teaching |
| Selection framework | Full workflow → SpectroChemPy; baseline → pybaselines; entry → spectrapepper |
| Combined approach | SpectroChemPy read + pybaselines correct + SpectroChemPy analyze |
| When commercial software is still needed | GMP, instrument control, large libraries, method validation, team collaboration |
| Common pitfalls | Version compatibility, dependency conflicts, broad peak misjudgment, unit confusion, inconsistent styles |
Thought Questions
You have a batch of catalyst in-situ infrared data (50 spectra) collected by Bruker OPUS, needing baseline correction + MCR-ALS decomposition. Design a complete Python workflow, explaining the roles of SpectroChemPy and pybaselines, and write key code.
Use pybaselines to apply AsLS, arPLS, airPLS, and ModPoly (order=4) baseline correction to the same severely tilted polystyrene spectrum. Design a quantitative metric to compare the performance of the four algorithms (hint: consider variance below peaks, peak position stability, broad peak retention).
Explain why AsLS may perform poorly on baseline correction of aqueous protein spectra (with a strong water peak at 1640 cm⁻¹). How should parameters be adjusted or other algorithms be chosen? Refer to ftir.fun water functional group page.
A QC manager at a pharmaceutical company asks: "Can open-source spectral tools replace OMNIC for GMP release testing?" Provide a structured answer based on 21 CFR Part 11, USP <854>, Data Integrity, etc.
Write a piece of code using spectrapepper to read 5 CSV spectra, perform baseline correction + smoothing + peak detection on each, and output the peak list of each spectrum to CSV. Explain the pros and cons of this code compared to manual operation in OMNIC.
References
[1] Smith B C. "Open Source Software for FTIR Data Analysis." Spectroscopy, 2023, 38(7): 12–18.
https://www.spectroscopyonlin…
[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.
Project address: https://github.com/spectroche…
Documentation: https://www.spectrochempy.fr/
[4] SpectroChemPy Documentation. "NDDataset: Core Data Structure."
https://www.spectrochempy.fr/…
[5] Pybaselines Documentation. "Pybaselines: A Python Library for Baseline Correction."
Project address: https://github.com/derb12/pyb…
Documentation: https://pybaselines.readthedo…
[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."
Project address: https://github.com/spectrapep…
Documentation: https://spectrapepper.github.…
[9] ftir.fun. "Online FTIR Tool."
https://ftir.fun
[10] McKinney W. "Data Structures for Statistical Computing in Python." Proc. SciPy 2010. (NumPy/pandas basics)
Next episode preview: Ep 54 — Open-source Tools (Part 2): HyperSpy, Orange-Spectroscopy
The previous episode covered general spectral frameworks, the next turns to two specialized tools: HyperSpy (benchmark for multidimensional spectral imaging analysis, ~560 stars, preferred for FPA data processing) and Orange-Spectroscopy (drag-and-drop visual workflow, zero programming threshold). It will also introduce lightweight SpectraKit and deep learning framework NIRS4ALL. Complete hands-on with FPA imaging data cube processing and PLS model building.
This article is licensed under CC BY-NC-SA 4.0. Images are from public domain or online sources with attributed origin, copyright belongs to the original authors.