Preprocessing
Spectrum subtraction, smoothing, normalization, and related utilities.
Spectrum Subtraction
OpticalSpectroscopy.subtract_spectrum — Function
subtract_spectrum(sample, reference; scale=1.0, interpolate=false)Subtract a reference spectrum from a sample spectrum.
Accepts AbstractSpectroscopyData types (uses xdata/ydata interface) or any objects with .x and .y fields.
Returns (x=..., y=...) NamedTuple.
subtract_spectrum(s::Spectrum, ref::Spectrum; scale=1.0, interpolate=false) -> SpectrumSubtract ref from s. Returns a new Spectrum carrying s's shallow-copied metadata.
Smoothing
OpticalSpectroscopy.smooth_data — Function
smooth_data(y; window=3)Apply moving average smoothing to data.
smooth_data(s::Spectrum; window=3) -> SpectrumMoving-average smoothing of a Spectrum. Returns a new Spectrum with shallow-copied metadata.
OpticalSpectroscopy.savitzky_golay_smooth — Function
savitzky_golay_smooth(y; window=11, order=3)Apply Savitzky-Golay smoothing filter to data.
Uses polynomial fitting within a sliding window to smooth data while preserving peak shape and width better than moving-average smoothing (Savitzky & Golay, 1964).
Arguments
y::AbstractVector{<:Real}: Input data vector.
Keywords
window::Int=11: Window size (must be odd and ≥ order + 2).order::Int=3: Polynomial order for the local fit.
Returns
Vector{Float64}: Smoothed data vector (same length as input).
Examples
y_noisy = sin.(0:0.1:2π) .+ 0.1 * randn(63)
y_smooth = savitzky_golay_smooth(y_noisy; window=11, order=3)savitzky_golay_smooth(s::Spectrum; window=11, order=3) -> SpectrumSavitzky-Golay smoothing of a Spectrum. Returns a new Spectrum with shallow-copied metadata.
Derivatives
OpticalSpectroscopy.derivative — Function
derivative(y; order=1, window=11, poly_order=3)
derivative(x, y; order=1, window=11, poly_order=3)Compute the derivative of a signal using Savitzky-Golay differentiation.
When x is provided, the derivative is correctly scaled by the x-spacing (using the median point spacing as the rate parameter).
Arguments
x::AbstractVector{<:Real}: (optional) Independent variable (e.g., wavenumber, wavelength).y::AbstractVector{<:Real}: Signal to differentiate.
Keywords
order::Int=1: Derivative order (1 = first derivative, 2 = second, etc.).window::Int=11: Savitzky-Golay window size (must be odd, ≥ poly_order + 2).poly_order::Int=3: Polynomial order for the SG filter (must be ≥order).
Returns
Vector{Float64}: Derivative of the input signal.
Examples
x = 400.0:0.5:800.0
y = @. 100 * exp(-(x - 520)^2 / (2 * 20^2))
dy = derivative(x, y; order=1) # First derivative (correctly scaled)
d2y = derivative(x, y; order=2) # Second derivativederivative(s::Spectrum; order=1, window=11, poly_order=3) -> SpectrumSavitzky-Golay derivative of a Spectrum, scaled by the x-spacing. Returns a new Spectrum with shallow-copied metadata, retagged with the :derivative signal token (the original y-quantity no longer applies).
Normalization and Band Analysis
OpticalSpectroscopy.band_area — Function
band_area(x, y, x_min, x_max)
band_area(spec, x_min, x_max)Compute the integrated area under a spectrum within a given range using trapezoidal integration.
The spec form accepts any 1D AbstractSpectroscopyData (uses xdata/ydata).
Arguments
x::AbstractVector{<:Real}: x-axis values (e.g., wavenumber, wavelength).y::AbstractVector{<:Real}: y-axis values (e.g., intensity).x_min::Real: Lower bound of integration range.x_max::Real: Upper bound of integration range.
Returns
Float64: Integrated area.
Examples
x = 400.0:0.5:800.0
y = @. 100 * exp(-(x - 520)^2 / (2 * 10^2))
area = band_area(x, y, 480.0, 560.0)OpticalSpectroscopy.normalize_area — Function
normalize_area(x, y)Normalize a spectrum so its total integrated area equals 1.
Arguments
x::AbstractVector{<:Real}: x-axis values.y::AbstractVector{<:Real}: y-axis values.
Returns
Vector{Float64}: Area-normalized y-values.
Examples
x = 1.0:0.1:10.0
y = ones(length(x))
y_norm = normalize_area(x, y) # Total area ≈ 1.0normalize_area(s::Spectrum) -> SpectrumNormalize a Spectrum to unit integrated area. Returns a new Spectrum with shallow-copied metadata, retagged with the :normalized_intensity signal token (the original y-unit no longer applies).
OpticalSpectroscopy.normalize_to_peak — Function
normalize_to_peak(x, y, position; tolerance=5.0)Normalize a spectrum by dividing by the intensity at a specified peak position.
Finds the data point nearest to position within tolerance and divides the entire spectrum by that point's intensity.
Arguments
x::AbstractVector{<:Real}: x-axis values.y::AbstractVector{<:Real}: y-axis values.position::Real: Target x-position for normalization (e.g., 520 cm-1 for Si).
Keywords
tolerance::Real=5.0: Maximum allowed distance frompositionto nearest data point.
Returns
Vector{Float64}: Peak-normalized y-values.
Examples
x = 400.0:1.0:800.0
y = @. 50 * exp(-(x - 520)^2 / (2 * 10^2))
y_norm = normalize_to_peak(x, y, 520.0) # y at x≈520 becomes 1.0normalize_to_peak(s::Spectrum, position; tolerance=5.0) -> SpectrumNormalize a Spectrum to the intensity at position. Returns a new Spectrum with shallow-copied metadata, retagged with the :normalized_intensity signal token (the original y-unit no longer applies).
OpticalSpectroscopy.estimate_snr — Function
estimate_snr(y)
estimate_snr(spec)Estimate the signal-to-noise ratio using the DER-SNR method.
The spec form accepts any 1D AbstractSpectroscopyData (signal comes from ydata).
Uses the second-order finite difference of adjacent pixels to estimate noise (Stoehr et al., 2008, "DER_SNR: A Simple & General Spectroscopic Signal-to-Noise Measurement Algorithm").
Arguments
y::AbstractVector{<:Real}: Spectral intensity values.
Returns
NamedTuple{(:snr, :signal, :noise)}: Estimated SNR, signal level, and noise level.
Examples
y_clean = 100 * ones(100)
y_noisy = y_clean .+ 2 * randn(100)
result = estimate_snr(y_noisy)
result.snr # ≈ 50