Ep 53 — Herramientas de código abierto (Parte 1): SpectroChemPy, pybaselines

Serie: Enciclopedia de espectroscopía infrarroja: de los fundamentos a la práctica
Sección: Quinta parte · Instrumentos y herramientas — Ecosistema de código abierto (Ep 46–55, parte final)
Público objetivo: Técnicos, estudiantes de posgrado, entusiastas de la quimiometría y usuarios de Python que deseen mejorar la eficiencia del procesamiento de datos
Conocimientos previos: Ep 18 (Procesamiento de espectros), Ep 19 (Búsqueda en bibliotecas), Ep 20 (Análisis cuantitativo), Ep 52 (Evaluación de software comercial)
Tiempo de lectura: Aproximadamente 45 minutos


Introducción: Cuando Python se encuentra con la espectroscopía infrarroja

Un estudiante de doctorado, Xiao Chen, utilizó un Bruker INVENIO para recolectar datos de espectroscopía infrarroja in situ de un catalizador, con el objetivo de estudiar la adsorción de CO en Pt/Al₂O₃. Abrió el software OPUS para realizar la corrección de línea base, pero descubrió que los algoritmos integrados de OPUS no manejaban bien la compleja situación de "espectro completo con fuerte inclinación + curvatura de línea base cerca de la región de absorción intensa". También probó la versión de prueba de OMNIC, pero seguía sin quedar satisfecho.

El supervisor le dijo: "Prueba pybaselines con Python, tiene más de 200 algoritmos de línea base".

Xiao Chen pasó 1 hora aprendiendo, escribió un código de Python de 20 líneas y obtuvo resultados: la corrección de línea base superó con creces los algoritmos predeterminados del software comercial. Desde entonces, se adentró en el mundo de las herramientas de espectroscopía de código abierto.

"Python y las bibliotecas de espectroscopía de código abierto están cambiando el ecosistema de análisis de datos en espectroscopía. Ya no son solo un 'complemento' del software comercial, sino que se han convertido en el núcleo del flujo de trabajo científico."
— Adaptado de un comentario en Applied Spectroscopy 2023 [1]

Este episodio analizará sistemáticamente tres herramientas de Python de código abierto para espectroscopía: SpectroChemPy (marco completo para espectroscopía química), pybaselines (biblioteca de algoritmos de corrección de línea base) y spectrapepper (paquete de análisis espectral de nivel introductorio). Cada una incluye enlace a GitHub, número de estrellas, código práctico y un marco de decisión sobre "cuándo usar código abierto y cuándo seguir necesitando software comercial".

💡 Enfoque de este episodio: Ep 52 evalúa software comercial, Ep 53–54 evalúa software de código abierto. El código abierto no es una "versión gratuita del software comercial", sino una "herramienta científica flexible y personalizable". Ambos episodios juntos constituyen el kit de herramientas espectrales para usuarios de Python.


I. Visión general del ecosistema de herramientas de espectroscopía de código abierto

1.1 ¿Por qué se necesitan herramientas de código abierto?

El software comercial de FTIR (OMNIC, OPUS, Spectrum) tiene funciones completas pero presenta las siguientes limitaciones [1][2]:

  • Algoritmos cerrados: el usuario desconoce la implementación específica de la corrección de línea base, suavizado, etc., lo que imposibilita la reproducibilidad.
  • Escalabilidad deficiente: no se pueden personalizar nuevos algoritmos o modelos.
  • Procesamiento por lotes débil: al procesar cientos de espectros con operaciones complejas, la interfaz gráfica es ineficiente.
  • Baja multiplataforma: solo Windows, sin versiones para Linux/Mac (excepto OPUS parcialmente).
  • Integración débil con aprendizaje automático: el análisis moderno de datos (deep learning, optimización bayesiana) requiere el ecosistema de Python.
  • Alto costo: cobro modular, funciones avanzadas se compran por separado.

Ventajas de las herramientas de código abierto [1][2][3]:

  • Algoritmos transparentes: código fuente disponible, resultados reproducibles.
  • Totalmente personalizables: algoritmos, flujos de trabajo y visualizaciones personalizados.
  • Ecosistema Python: integración perfecta con NumPy, SciPy, scikit-learn, PyTorch.
  • Multiplataforma: compatible con Windows, Linux y Mac.
  • Gratuito: sin restricciones de licencia.

1.2 "Lista de estrellas" de herramientas de espectroscopía de código abierto

Proyectos activos de código abierto en GitHub sobre "FTIR / spectroscopy" (hasta 2024) [2][3]:

Proyecto Estrellas Uso principal Cubierto en este episodio
HyperSpy ~560 Análisis de espectroscopía multidimensional (imágenes) Ep 54
pybaselines ~189 Biblioteca de algoritmos de corrección de línea base ✅ Este episodio
SpectroChemPy ~177 Marco completo para espectroscopía química ✅ Este episodio
Orange-Spectroscopy ~140 Flujo de trabajo visual de arrastrar y soltar Ep 54
spectrapepper ~100+ Paquete de análisis espectral de nivel introductorio ✅ Este episodio
NIRS4ALL ~80 Transformación NIR + deep learning Ep 54
pyspectrakit ~50 Operaciones básicas ligeras Ep 54

Tabla 1: Número de estrellas en GitHub de herramientas de espectroscopía de código abierto (Fuente: GitHub topic "spectroscopy" / "ftir", 2024)

🔗 Extensión: ftir.fun es un complemento de herramientas espectrales en línea amigable en chino, que proporciona visualización de espectros, identificación de picos y búsqueda en bibliotecas desde la web, permitiendo un análisis rápido sin necesidad de programación.


II. SpectroChemPy: Marco completo de Python para espectroscopía química

2.1 Descripción general del proyecto

SpectroChemPy es un marco de código abierto en Python desarrollado por el equipo de Arnaud Travert del Laboratorio de Química Física Aplicada y Láser (LCP-A2S) en Francia, diseñado específicamente para espectroscopía química (IR, Raman, NIR, UV-Vis, NMR) [3][4].

Figura 1: Página principal de SpectroChemPy en GitHub (Fuente: https://github.com/spectroche…)

2.2 Característica principal: Estructura de datos NDDataset

La innovación más importante de SpectroChemPy es la estructura de datos NDDataset [3][4]:

from spectrochempy import NDDataset

# Crear un conjunto de datos espectral
conjunto = NDDataset(
    datos_absorbancia,        # Arreglo 2D: muestras × números de onda
    coordset=[
        ('muestras', nombres_muestras),       # Primera dimensión: nombres de muestras
        ('numeros_onda', arreglo_wn, 'cm⁻¹')  # Segunda dimensión: números de onda + unidad
    ],
    title='Absorbancia',
    units='absorbancia',
    name='Adsorción_CO_Catalizador',
    history='2024-07-15: recolectado en INVENIO R',
    author='Bob',
)

Ventajas de NDDataset en comparación con NumPy ndarray [3][4]:

  • Metadatos integrados: coordenadas (número de onda, temperatura, tiempo), unidades, título, historial están vinculados a los datos.
  • Conciencia de unidades: maneja automáticamente conversiones como cm⁻¹ ↔ nm, Abs ↔ %T, etc.
  • Segmentación semántica clara: conjunto[:, '4000::1'] significa "todas las muestras, desde 4000 cm⁻¹ con paso de 1 cm⁻¹".
  • Trazabilidad: cada operación se añade automáticamente al historial (history), cumpliendo con los principios FAIR de datos.
  • Visualización integrada: conjunto.plot() grafica directamente, con etiquetas automáticas de unidades en los ejes.

2.3 Cobertura completa del flujo de trabajo

SpectroChemPy cubre todo el flujo de trabajo del análisis espectral [3][4]:

Lectura → Preprocesamiento → Análisis → Modelado → Visualización → Exportación
 │            │                │          │           │              │

│       │        │       │        │       └ CSV, JCAMP-DX, HDF5
│       │        │       │        └ matplotlib, plotly
│       │        │       └ PLS, PCA, MCR-ALS
│       │        └ Detección de picos, ajuste de curvas, integración
│       └ Línea base, suavizado, normalización, corrección ATR, derivación
└ OMNIC (.spa), OPUS (.opu), JCAMP-DX (.jdx), SPA, CSV

① Lectura de múltiples formatos de proveedores [3][4]:

from spectrochempy import read

# Lee el archivo Thermo OMNIC .spa
ds_omnic = read('sample.spa')

# Lee el archivo Bruker OPUS .opu
ds_opus = read('sample.opu')

# Lee el archivo JCAMP-DX .jdx
ds_jcamp = read('sample.jdx')

# Lee CSV (especificando columnas)
ds_csv = read('sample.csv', csv_delimiter=',')

Esta es una de las funciones más potentes de SpectroChemPy: leer directamente formatos propietarios de software comercial, sin necesidad de exportar y convertir primero [3].

② Preprocesamiento [3][4]:

# Corrección de línea base (múltiples algoritmos integrados)
ds_bc = ds_omnic.baseline_correct(method='als', lam=1e7, p=0.01)

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

# Normalización
ds_norm = ds_sm.normalize(method='max')

# Derivación
ds_d2 = ds_norm.derivative(order=2, window_size=11, polyorder=3)

③ Resolución multivariante de curvas (MCR-ALS) [3][4]:
MCR-ALS es la función estrella de SpectroChemPy, ideal para descomposición de espectros de mezclas:

from spectrochempy import MCRALS

# Supongamos que ds son múltiples espectros de un proceso de reacción (tiempo × número de onda)
mcr = MCRALS(ds, n_components=3, max_iter=100)
mcr.fit()

# Salida: espectros puros de 3 componentes + curvas de concentración
pure_spectra = mcr.ST  # Espectros de los componentes
concentrations = mcr.C  # Matriz de concentraciones

pure_spectra.plot()
concentrations.plot()

④ Visualización [3][4]:

import spectrochempy as scp

# Espectro único
ds.plot(title='Adsorción de CO en catalizador', color='red')

# Múltiples espectros superpuestos
scp.plot_multi(ds1, ds2, ds3, labels=['A', 'B', 'C'])

# Gráfico de superficie 3D
ds.plot_3D()

# Mapa de calor (datos de proceso de reacción)
ds.plot_waterfall()

2.4 Valor educativo

La API de SpectroChemPy está diseñada con el lenguaje de los químicos (baseline_correct en lugar de corregir_linea_base), la documentación es exhaustiva, y es la mejor entrada para aprender procesamiento de espectros con Python [3][4].

Ejemplo completo educativo — Leer y procesar un espectro de poliestireno:

import spectrochempy as scp

# 1. Leer datos (conjunto de datos de ejemplo)
ds = scp.read('irdata/nh4y-activation.spa')

# 2. Recortar región de interés
ds = ds[:, '4000::650']  # 4000-650 cm⁻¹

# 3. Corrección de línea base (ALS)
ds_bc = ds.baseline_correct(method='asls', lam=1e5, p=0.01)

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

# 5. Normalización
ds_norm = ds_sm.normalize(method='max')

# 6. Visualización
ds_norm.plot(title='Activación de NH4Y', colormap='viridis')

# 7. Exportación
ds_norm.write('processed.jdx')  # Formato JCAMP-DX
ds_norm.write('processed.csv')  # Formato CSV

2.5 Cuándo elegir SpectroChemPy

Adecuado [3][4]:

  • Flujo completo de procesamiento de espectros químicos (lectura → procesamiento → modelado → visualización);
  • Integración de datos de múltiples proveedores (lectura directa de .spa / .opu);
  • Docencia (API amigable, documentación detallada);
  • Descomposición avanzada como MCR-ALS;
  • Necesidad de metadatos trazables (principios FAIR de datos).

No adecuado:

  • Tareas únicas de corrección de línea base (usar pybaselines es más ligero);
  • Datos de imagen FPA (usar HyperSpy);
  • Flujo de trabajo basado en arrastrar y soltar (usar Orange-Spectroscopy);
  • Rendimiento extremo (el núcleo sigue siendo NumPy, sin optimización para matrices muy grandes).

3. pybaselines: "Enciclopedia" de algoritmos de corrección de línea base

3.1 Resumen del proyecto

pybaselines fue desarrollado por derb12 (nombre de usuario de GitHub) y es una biblioteca de Python especializada en corrección de línea base, que ofrece más de 200 algoritmos de corrección de línea base, siendo el proyecto con más estrellas en el tema FTIR [2][5].

  • GitHub: https://github.com/derb12/pyb…
  • Documentación: https://pybaselines.readthedo…
  • Estrellas: Al momento de escribir, alrededor de cien (a la fecha de la nota; consulte la página actual de GitHub, no como ranking permanente)
  • Licencia: BSD-3-Clause (una de las licencias de código abierto más permisivas)
  • Primera publicación: 2020
  • Versión de Python: 3.8+

Figura 2: Página principal de pybaselines en GitHub (Fuente: https://github.com/derb12/pyb…)

3.2 Por qué la corrección de línea base es el paso de preprocesamiento más crítico

La corrección de línea base es el paso que más afecta los resultados del análisis posterior en el preprocesamiento de espectros [5][6][7]:

  • Desplazamiento de posiciones de pico: Una línea base curva puede desplazar la posición de los picos en 1–5 cm⁻¹;
  • Distorsión del área de pico: Una línea base alta da un área de pico falsamente alta, con errores cuantitativos de hasta 20%+;
  • Riesgo de picos falsos: La corrección excesiva con polinomios de alto orden puede "cavar" picos falsos;
  • Impacto aguas abajo: Los espectros corregidos con línea base son la entrada para PLS, PCA, búsqueda en bibliotecas, propagando errores.

"En todos los pasos de preprocesamiento de análisis espectral, la corrección de línea base tiene el mayor impacto, la mayor controversia y es la más propensa a errores."
— Liland K H, Applied Spectroscopy 2011 [6]

El valor de pybaselines: Unificar más de 200 algoritmos en una API coherente, permitiendo comparar y elegir rápidamente el algoritmo más adecuado [5].

3.3 Clasificación de algoritmos

pybaselines clasifica los algoritmos de línea base en 8 categorías principales [5]:

Categoría Algoritmos representativos Escenario de aplicación
Polinomial Poly, ModPoly, IModPoly, Polynomial Inclinación simple, curvatura

| Whittaker | AsLS, IAsLS, AirPLS, ArPLS, DrPLS | Curva compleja, picos anchos |
| ALS | AsLS, IAsLS, arPLS, asPLS | Trabajo moderno, insensible a picos anchos |
| Morphological | Mor, Imor, AMor | Morfológico, adecuado para picos agudos |
| Window | Noise, Noisy | Ventana deslizante |
| Spline | mixture, mixture_mod | Spline suavizado |
| Baseline | Dietrich, CWT, FUNP | Onda, dominio de frecuencia |
| Optimization | Custom, Cole | Método de optimización |

Tabla 2: Clasificación de algoritmos de pybaselines (basado en [5][6])

3.4 Comparación de los cuatro algoritmos principales

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

  • Propuesto por Eilers & Boelens, es el algoritmo "estándar" para la corrección de línea base moderna;
  • Principio: mínimos cuadrados ponderados asimétricos + suavizado de segunda diferencia;
  • Parámetros: lam (suavidad, 1e5–1e9), p (asimetría, 0.001–0.1);
  • Adecuado para: la mayoría de escenarios, insensible a picos anchos.

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

  • Versión mejorada de AsLS, ajusta pesos automáticamente;
  • Más sensible a cambios de línea base, adecuado para deriva rápida;
  • Parámetros: lam normalmente necesita 1e6–1e8.

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

  • Pesos adaptativos, identificación de picos más inteligente;
  • Adecuado para picos superpuestos complejos.

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

  • Adecuado para espectros (originalmente diseñado para espectroscopia atómica);
  • Buena conservación de picos agudos.

3.5 Práctica: comparación de diferentes algoritmos en el mismo espectro

A continuación, se utiliza pybaselines para comparar la corrección de línea base de un espectro IR de catalizador severamente inclinado [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

# Cargar datos (asumiendo que wn es el número de onda, y es la absorbancia)
data = np.loadtxt('catalyst.csv', delimiter=',', skiprows=1)
wn, y = data[:, 0], data[:, 1]

# 5 algoritmos
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],
}

# Comparación visual
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='Línea base')
    ax.plot(wn, y - base, 'b-', lw=0.8, label='Corregido')
    ax.set_title(name)
    ax.legend(fontsize=8)
plt.tight_layout()
plt.savefig('baseline_comparison.png', dpi=150)

Resultados típicos de comparación [5][6]:

Algoritmo Tiempo de cálculo Conservación de picos anchos Corrección de inclinación Escenario recomendado
AsLS Rápido (< 1 s) Regular Buena Uso general preferido
arPLS Medio (1–3 s) Buena Excelente Deriva rápida
airPLS Medio (2–5 s) Excelente Excelente Picos superpuestos complejos
ModPoly Muy rápido (< 0.1 s) Mala (orden alto) Media Inclinación simple
Mor Rápido (< 1 s) Mala Media Picos agudos

Tabla 3: Comparación de cinco algoritmos de pybaselines (basado en [5][6][7])

3.6 Experiencia en ajuste de parámetros

Parámetro lam en AsLS / arPLS [5][6]:

  • lam controla la suavidad de la línea base, cuanto mayor, más suave;
  • Rango empírico: 1e5 (mucha curvatura) – 1e9 (casi lineal);
  • El valor predeterminado 1e6 es un buen punto de partida;
  • Juicio visual: la línea base "toca el fondo" pero no "excava picos", ajustar hasta que sea adecuado.

Parámetro p (solo AsLS) [6]:

  • Controla el grado de asimetría, cuanto menor, más sesgado por debajo de los picos;
  • Valor predeterminado 0.01;
  • Para espectros con picos anchos (como soluciones acuosas), se puede ajustar a 0.001.

Consejos de depuración [5]:

# Probar automáticamente múltiples lam, elegir el mejor
from pybaselines.whittaker import arpls
lams = [1e5, 1e6, 1e7, 1e8, 1e9]
for lam in lams:
    base = arpls(y, lam=lam)[0]
    corrected = y - base
    # Calcular la varianza de la región "por debajo del pico" (debería ser mínima)
    below = corrected[corrected < 0]
    score = np.var(below) if len(below) > 0 else 0
    print(f"lam={lam}: score={score:.4f}")

3.7 Cuándo elegir pybaselines

Adecuado [5][6]:

  • Cuando el algoritmo de línea base predeterminado del software comercial no es efectivo;
  • Se necesita corrección de línea base por lotes y reproducible;
  • Investigación de nuevos algoritmos de línea base, comparación de algoritmos;
  • "Paso de línea base" en cualquier flujo de procesamiento espectral en Python.

No adecuado:

  • Análisis espectral de flujo completo (usar SpectroChemPy);
  • Flujo de trabajo visual (usar Orange);
  • Cuando el algoritmo predeterminado del software comercial ya satisface las necesidades (evitar añadir complejidad).

💡 Consejo práctico: usar pybaselines como "complemento" de SpectroChemPy — SpectroChemPy lee datos + metadatos, pybaselines hace la línea base, luego regresar a SpectroChemPy para análisis posteriores [3][5].


Cuatro: spectrapepper: paquete de análisis espectral de nivel introductorio

4.1 Resumen del proyecto

spectrapepper es un paquete Python de análisis espectral de nivel introductorio, con una API sencilla, adecuado como "primer código espectral" [2][8].

Figura 3: Página principal de spectrapepper en GitHub (Fuente: https://github.com/spectrapep…)

4.2 Características principales

① API minimalista [8]:

import spectrapepper as spe

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

# Corrección de línea base
baseline = spe.baseline(data)
corrected = data - baseline

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

# Detección de picos
peaks = spe.find_peaks(smoothed, threshold=0.05)
print(peaks)

② Amigable para principiantes [8]:

  • Nombres de funciones intuitivos (load, baseline, smooth, find_peaks);
  • Parámetros por defecto con valores razonables;
  • Documentación con muchos tutoriales y ejemplos.

③ Adecuado para enseñanza [8]:

  • En el aula, los estudiantes pueden ejecutar el primer código de espectros en 5 minutos;
  • Alta legibilidad del código, fácil de explicar los principios de cada paso.

4.3 Funciones principales

Las funciones principales que ofrece spectrapepper [8]:

  • I/O de datos: CSV, TXT, algunos formatos de fabricantes;
  • Preprocesamiento: Corrección de línea base (polinomio + ALS), suavizado (SG), normalización;
  • Análisis de picos: Detección de picos, área de picos, ancho medio;
  • Análisis multivariante: PCA, PLS (basado en scikit-learn);
  • Visualización: Envoltura de matplotlib;
  • Comparación de espectros: Coeficiente de correlación, similitud coseno.

4.4 Ejemplo completo

import spectrapepper as spe
import matplotlib.pyplot as plt

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

# 2. Preprocesamiento
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. Detección de picos
peaks = spe.find_peaks(sample_sm, height=0.05, distance=10)
print(f"Encontrados {len(peaks)} picos en: {peaks}")

# 4. Similitud
similarity = spe.cosine_similarity(sample_sm, reference_sm)
print(f"Similitud con referencia: {similarity:.3f}")

# 5. Visualización
plt.figure(figsize=(10, 5))
plt.plot(sample_sm, label='Muestra')
plt.plot(reference_sm, label='Referencia', 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 Cuándo elegir spectrapepper

Adecuado [8]:

  • Principiantes en Python para espectroscopía;
  • Escenarios de enseñanza (primer contacto de estudiantes con programación de espectros);
  • Análisis simple (no requiere algoritmos complejos);
  • Prototipado rápido para validar ideas.

No adecuado:

  • Corrección de línea base compleja (usar pybaselines);
  • Lectura de formatos de múltiples fabricantes (usar SpectroChemPy);
  • Quimiometría avanzada (usar directamente scikit-learn);
  • Entornos de producción con grandes volúmenes de datos (la API abstracta es demasiado limitada en flexibilidad).

5. Comparación y selección

5.1 Comparación de las tres herramientas

Dimensión SpectroChemPy pybaselines spectrapepper
Enfoque Marco completo Enfoque en línea base Nivel de entrada
Estrellas ~177 ~189 ~100+
Curva de aprendizaje Media Suave Muy suave
Riqueza funcional ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ (especializado) ⭐⭐⭐
I/O de datos ⭐⭐⭐⭐⭐ (múltiples fabricantes) Solo arrays ⭐⭐⭐
Algoritmos de línea base Pocos integrados 200+ Pocos integrados
Análisis multivariante PCA, MCR-ALS Ninguno PCA, PLS
Visualización Integrada Ninguna Integrada
Valor didáctico Alto Medio Muy alto
Entorno de producción Adecuado Adecuado (para paso de línea base) Adecuado (tareas simples)

Tabla 4: Comparación de tres herramientas de espectroscopía de código abierto

5.2 Árbol de decisión para selección

¿Cuál es tu necesidad?
   │
   ├─ Procesamiento completo de espectros (leer→procesar→modelar)
   │   └─ SpectroChemPy
   │
   ├─ Solo corrección de línea base (y el software comercial no es suficiente)
   │   └─ pybaselines
   │
   ├─ Iniciación / Enseñanza / Prototipado rápido
   │   └─ spectrapepper
   │
   ├─ Datos de imágenes multidimensionales (FPA)
   │   └─ HyperSpy (ver Ep 54)
   │
   ├─ Flujo de trabajo por arrastrar y soltar
   │   └─ Orange-Spectroscopy (ver Ep 54)
   │
   └─ Multiplataforma / Visualización en línea
       └─ ftir.fun

Figura 4: Árbol de decisión para selección de herramientas de espectroscopía de código abierto

5.3 Caso de uso combinado

Ejemplo de flujo de trabajo real: Análisis de datos de infrarrojo in situ de catalizadores [3][5]:

# 1. SpectroChemPy lee datos de múltiples fabricantes
import spectrochempy as scp
ds = scp.read('catalyst_in_situ.spa')

# 2. pybaselines realiza corrección de línea base (más precisa)
from pybaselines.whittaker import arpls
import numpy as np

# Convertir a arrays para procesar
y = ds.data.T  # muestras × números de onda → números de onda × muestras
baselines = np.array([arpls(yi, lam=1e7)[0] for yi in y.T])
corrected = y - baselines.T

# Volver a NDDataset
ds_bc = scp.NDDataset(
    corrected,
    coordset=ds.coordset,
    title='Corregido de línea base',
    history='Corrección de línea base arPLS (pybaselines)'
)

3. SpectroChemPy para análisis posteriores (MCR-ALS)

mcr = scp.MCRALS(ds_bc, n_components=3)
mcr.fit()

# 4. Visualización
mcr.ST.plot(title='Espectros de componentes puros')
mcr.C.plot(title='Perfiles de concentración')

# 5. Exportar
mcr.ST.write('pure_components.csv')

Esta combinación (SpectroChemPy leer datos + pybaselines para línea base + SpectroChemPy para análisis posteriores) es una práctica común en el análisis espectral de código abierto en 2024 [3][5].


Sexto: ¿Cuándo se necesita aún software comercial?

Las herramientas de código abierto son potentes, pero no universales [1][2]. Los siguientes escenarios aún recomiendan software comercial:

6.1 Entorno de cumplimiento GMP / FDA

  • El software comercial tiene certificación 21 CFR Part 11 (pista de auditoría, firma electrónica) [1];
  • Las herramientas de código abierto carecen de certificación de cumplimiento, alto riesgo en QC farmacéutico;
  • La integridad de datos (Data Integrity) requiere que la versión del software sea rastreable y las operaciones inalterables.

6.2 Control nativo del instrumento

  • El software comercial está profundamente integrado con el hardware del instrumento (control de adquisición, reconocimiento de accesorios) [1];
  • La mayoría de las herramientas de código abierto solo pueden procesar datos ya exportados, no pueden controlar directamente la adquisición del instrumento;
  • Excepción: algunos proyectos de código abierto (como Solis) admiten control de instrumentos, pero el ecosistema es débil.

6.3 Grandes bibliotecas espectrales comerciales

  • Grandes bibliotecas espectrales comerciales como Sadtler, Aldrich, Hummel solo están completamente integradas en software comercial [1];
  • Las herramientas de código abierto solo pueden usar bibliotecas gratuitas como NIST WebBook (ver Ep 55);
  • El algoritmo de búsqueda en bibliotecas puede implementarse en código abierto, pero los derechos de autor del contenido son un obstáculo.

6.4 Validación de métodos estandarizados

  • Métodos de farmacopea como USP <854>, Ph.Eur. 2.2.24 tienen flujos de software específicos [1];
  • El software comercial cuenta con documentos de validación;
  • Las herramientas de código abierto requieren realizar una validación completa del método.

6.5 Colaboración en equipo y capacitación

  • En equipos grandes, el software comercial con GUI tiene menor costo de capacitación;
  • Las herramientas de código abierto requieren conocimientos básicos de Python;
  • En colaboración entre laboratorios, el software comercial unificado facilita la integración.

💡 Marco de decisión: Entorno de producción (QC, GMP) priorizar comercial; investigación, prototipos, análisis personalizados priorizar código abierto. Ambos no son excluyentes y a menudo se usan en combinación [1][2].


Séptimo: Consejos sobre "trampas" en herramientas de código abierto

7.1 Trampa 1: Compatibilidad de versiones

Situación: Después de actualizar SpectroChemPy 0.4 → 0.6, el código antiguo da error [3].

Causa: La API de proyectos de código abierto es inestable, las actualizaciones de versión principal suelen tener cambios que rompen la compatibilidad.

Contramedida:

  • Bloquear la versión con requirements.txt o environment.yml;
  • Leer CHANGELOG antes de actualizar;
  • Aislar el código crítico con entornos virtuales (venv / conda).

7.2 Trampa 2: Conflictos de dependencias

Situación: Después de instalar pybaselines, conflicto con la versión existente de NumPy [5].

Contramedida:

# Aislar entorno con conda
conda create -n spectra python=3.10
conda activate spectra
pip install spectrochempy pybaselines spectrapepper

7.3 Trampa 3: Uso incorrecto de algoritmos

Situación: Usar arPLS para corregir un espectro con un pico ancho fuerte de O-H a 4000 cm⁻¹, resultando en que el pico O-H se "excava" a la mitad [6].

Contramedida:

  • Los picos anchos grandes (O-H 3400, N-H 3300) son fácilmente malinterpretados por algoritmos de línea base;
  • Antes de la corrección, revisar el espectro y evitar regiones de picos anchos;
  • Usar el parámetro mask para excluir regiones de picos anchos:
    from pybaselines.whittaker import arpls
    # Excluir región O-H 3000-3700 cm⁻¹
    mask = (wn < 3000) | (wn > 3700)
    base = arpls(y, lam=1e7, mask=mask)[0]
    

7.4 Trampa 4: Confusión de unidades

Situación: Las unidades de número de onda leídas por SpectroChemPy son cm⁻¹, pero al graficar muestra nm [3].

Contramedida:

  • Especificar unidades explícitamente;
  • Usar la función de conciencia de unidades de NDDataset:
    ds.units = 'cm^-1'  # forzar
    ds.x.units = 'cm^-1'
    

7.5 Trampa 5: Estilos de visualización inconsistentes

Situación: Diferentes herramientas producen estilos de gráficos muy diferentes, mezclarlos en un artículo se ve mal [3][5].

Contramedida:

  • Unificar con matplotlib, personalizar estilo:
    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,
    })
    

Ilustraciones (claves de este episodio)

📷 Figura 5: Comparación de capacidades de instrumentos
Fuente: Imagen real/de código abierto · Project case study — PE spectrum (con marca de agua ftir.fun)

Comparación de capacidades de instrumentos

📷 Figura 6: Concepto de trayectoria óptica/accesorios
Fuente: Imagen real/de código abierto · Unsplash — chemistry lab (con marca de agua ftir.fun)

Concepto de trayectoria óptica/accesorios

📷 Figura 7: Flujo de trabajo de software/base de datos
Fuente: Diagrama didáctico de ftir.fun (con marca de agua; no es espectro real, solo para entender el concepto)

Flujo de trabajo de software/base de datos


Resumen de este episodio

Punto clave Detalle
Ventajas del código abierto Algoritmos transparentes, personalizables, ecosistema Python, multiplataforma, gratuito
Ventajas del software comercial Cumplimiento normativo, control de instrumentos, bibliotecas comerciales, bajo costo de capacitación
SpectroChemPy Marco de flujo completo, metadatos NDDataset integrados, lectura de múltiples formatos de fabricantes
NDDataset Datos + coordenadas + unidades + historial integrados, principio de datos FAIR
Fortalezas de SpectroChemPy MCR-ALS, E/S de múltiples fabricantes, alto valor didáctico
pybaselines Más de 200 algoritmos de línea base, el de mayor popularidad (topic star) en FTIR
Importancia de corrección de línea base Afecta posición de picos, área de picos, análisis posteriores; es donde más se cometen errores
Algoritmos principales AsLS (general), arPLS (deriva), airPLS (complejo), SNIP (picos agudos)
Parámetro lam Suavidad, 1e5–1e9, predeterminado 1e6
Parámetro p Asimetría, 0.001–0.1, predeterminado 0.01
spectrapepper Nivel de entrada, API concisa, primera elección didáctica
Marco de selección Flujo completo → SpectroChemPy; línea base → pybaselines; entrada → spectrapepper
Combinación práctica SpectroChemPy leer + pybaselines corregir + SpectroChemPy analizar
Software comercial necesario aún GMP, control de instrumentos, bibliotecas grandes, validación de métodos, colaboración en equipo
Trampas comunes Compatibilidad de versiones, conflictos de dependencias, mala interpretación de picos anchos, confusión de unidades, estilos inconsistentes

Preguntas de reflexión

  1. Tienes un lote de datos IR in situ de catalizadores adquiridos con Bruker OPUS (50 espectros) y necesitas realizar corrección de línea base + descomposición MCR-ALS. Diseña un flujo de trabajo completo en Python, indicando qué roles desempeñan SpectroChemPy y pybaselines, y escribe el código clave.

  2. Usa pybaselines para realizar corrección de línea base con AsLS, arPLS, airPLS y ModPoly (orden=4) en el mismo espectro de poliestireno severamente inclinado. Diseña un indicador cuantitativo para comparar el efecto de los cuatro algoritmos (sugerencia: considerar la varianza de la región debajo de los picos, la estabilidad de la posición del pico y la retención de picos anchos).

  3. Explica por qué el algoritmo AsLS puede no ser adecuado para la corrección de línea base de espectros de proteínas en solución acuosa (con un fuerte pico de agua a 1640 cm⁻¹). ¿Cómo se deben ajustar los parámetros o elegir otro algoritmo? Consulta la página de grupos funcionales de agua en ftir.fun.

  4. Un supervisor de control de calidad de una empresa farmacéutica pregunta: "¿Pueden las herramientas de espectroscopia de código abierto reemplazar a OMNIC para las pruebas de liberación GMP?" Proporciona una respuesta estructurada basada en 21 CFR Part 11, USP <854>, integridad de datos, etc.

  5. Escribe un código con spectrapepper para leer 5 espectros CSV, realizar corrección de línea base + suavizado + detección de picos en cada uno, y generar una lista de posiciones de picos por espectro en un CSV. Explica las ventajas y desventajas de este código en comparación con la operación manual en OMNIC.


Referencias

[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.
Dirección del proyecto: https://github.com/spectroche…
Documentación: https://www.spectrochempy.fr/

[4] Documentación de SpectroChemPy. "NDDataset: Core Data Structure."
https://www.spectrochempy.fr/…

[5] Documentación de Pybaselines. "Pybaselines: A Python Library for Baseline Correction."
Dirección del proyecto: https://github.com/derb12/pyb…
Documentación: 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] Documentación de spectrapepper. "Spectrapepper: Simple Spectral Analysis."
Dirección del proyecto: https://github.com/spectrapep…
Documentación: https://spectrapepper.github.…

[9] ftir.fun. "Herramienta de espectroscopia IR en línea."
https://ftir.fun

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


Avance del próximo episodio: Ep 54 — Herramientas de código abierto (parte 2): HyperSpy, Orange-Spectroscopy
El episodio anterior cubrió marcos generales de espectroscopia; el próximo se centrará en dos herramientas especializadas: HyperSpy (referente en análisis de imágenes espectrales multidimensionales, ~560 estrellas, opción preferida para procesamiento de datos FPA) y Orange-Spectroscopy (flujo de trabajo visual por arrastrar y soltar, sin necesidad de programación). También se presentarán SpectraKit, ligero, y el marco de aprendizaje profundo NIRS4ALL. Se incluirá un ejemplo práctico completo de procesamiento de cubos de datos de imágenes FPA y construcción de modelos PLS.


Este artículo tiene licencia CC BY-NC-SA 4.0. Las imágenes provienen de dominio público o de recursos en línea con atribución, los derechos de autor pertenecen a sus respectivos autores.

Enviar solicitud Formulario