Source code for libpyhat.transform.baseline_code.min_spline

"""
This baseline removal method is a simple alternative inspired by the
wavelet+spline method described for ChemCam.
It divides the spectrum up into windows of a user-specified size, finds the
minimum value within each window
that is also a local minimum, and then fits a cubic spline.

"""

import numpy as np
import scipy.interpolate as interp
import scipy.signal as signal

from libpyhat.transform.baseline_code.common import Baseline


[docs] def min_interp(wvl, spectrum, window=50, kind="cubic"): nbands = len(wvl) n_windows = int(nbands / window) all_minima = signal.argrelextrema(spectrum, np.less)[ 0 ] # find the local minima of the spectrum s_minima = [] for i in range(n_windows): ind_window = np.arange( i * window, np.min(((i * window) + window, len(wvl) - 1)), 1 ) # find the local minima within the current window window_minima = all_minima[ (all_minima > ind_window[0]) & (all_minima < ind_window[-1]) ] if len(window_minima) > 0: # of those, find the one with the minimum value current_min = window_minima[np.argmin(spectrum[window_minima])] s_minima.append(current_min) # add the first and last elements to avoid extrapolation s_minima = np.hstack(([0], s_minima, len(spectrum) - 1)) # remove any duplicates just to be safe s_minima = np.unique(s_minima) # fit a cubic spline to the points if len(s_minima) > 3: spline = interp.interp1d(wvl[s_minima], spectrum[s_minima], kind=kind) baseline = spline(wvl) else: # if there aren't enough minima, make the baseline zero print("Not enough minima to fit the baseline! Try using a smaller " "window.") baseline = np.zeros_like(wvl) return baseline
[docs] class minimum_interp(Baseline): def __init__(self, window=50, kind="cubic"): self.window = window self.kind = kind def _fit_one(self, x, y): return min_interp(x, y, window=self.window, kind=self.kind)