API Reference
Types
SpectroscopyTools.SpectroscopyTools — Module
SpectroscopyTools.jl — General-purpose spectroscopy analysis toolkit.
Provides data types, fitting routines, baseline correction, peak detection, unit conversions, and utility functions for spectroscopic data analysis.
Extracted from QPS.jl to serve as a standalone, reusable foundation.
SpectroscopyTools.AbstractSpectroscopyData — Type
AbstractSpectroscopyDataAbstract base type for all spectroscopy data types.
Subtypes must implement the following interface:
xdata(d)— Primary x-axis data (Vector{Float64})ydata(d)— Signal data (Vector{Float64}) or secondary axis for 2Dzdata(d)— Matrix data for 2D types,nothingfor 1Dxlabel(d)— X-axis label stringylabel(d)— Y-axis or signal label stringis_matrix(d)— Whether data is 2D (returns Bool)
Optional (have defaults):
source_file(d)— Source filename (default:"")npoints(d)— Number of data points (default:length(xdata(d)), tuple for 2D)title(d)— Display title (default:source_file(d))
This enables uniform handling in data viewers and plotting functions while maintaining semantic field names in each concrete type.
Example
# Works for any spectroscopy data type
function plot_data(data::AbstractSpectroscopyData)
if is_matrix(data)
heatmap(xdata(data), ydata(data), zdata(data)')
else
lines(xdata(data), ydata(data))
end
endSpectroscopyTools.TATrace — Type
TATrace <: AbstractSpectroscopyDataSingle-wavelength transient absorption kinetic trace.
Fields
time::Vector{Float64}: Time axis (ps)signal::Vector{Float64}: ΔA signalwavelength::Float64: Probe wavelength, NaN if unknownmetadata::Dict{Symbol,Any}: Additional info
SpectroscopyTools.TASpectrum — Type
TASpectrum <: AbstractSpectroscopyDataTransient absorption spectrum at a fixed time delay.
Fields
wavenumber::Vector{Float64}: Wavenumber axis (cm⁻¹)signal::Vector{Float64}: ΔA signaltime_delay::Float64: Time delay (ps), NaN if unknownmetadata::Dict{Symbol,Any}: Additional info
SpectroscopyTools.TAMatrix — Type
TAMatrix <: AbstractSpectroscopyDataTwo-dimensional transient absorption data (time x wavelength).
Fields
time::Vector{Float64}: Time axis (ps)wavelength::Vector{Float64}: Wavelength axis (nm) or wavenumber (cm⁻¹)data::Matrix{Float64}: ΔA signal matrix, size (ntime, nwavelength)metadata::Dict{Symbol,Any}: Additional info
Indexing
matrix[λ=800] # Extract TATrace at λ ≈ 800 nm
matrix[t=1.0] # Extract TASpectrum at t ≈ 1.0 psSpectroscopyTools.TASpectrumFit — Type
TASpectrumFitResult of TA spectrum fitting with N peaks of arbitrary lineshape.
Supports any combination of ESA, GSB, and SE peaks, each with its own lineshape model (Gaussian, Lorentzian, pseudo-Voigt).
Access peaks
result.peaks— Vector ofTAPeakresult[i]— i-th peakresult[:esa]— first peak with label:esaanharmonicity(result)— GSB center minus ESA center (NaN if not applicable)
Fields
peaks::Vector{TAPeak}— Fitted peak parametersoffset,rsquared,residuals— Fit metadata
SpectroscopyTools.TAPeak — Type
TAPeakInformation about a single peak in a TA spectrum fit.
Fields
label::Symbol— Peak type (:esa,:gsb,:se,:positive,:negative)model::String— Lineshape model name ("gaussian","lorentzian","pseudo_voigt")center::Float64— Peak center positionwidth::Float64— Width parameter (sigma for gaussian/voigt, fwhm for lorentzian)amplitude::Float64— Peak amplitude (always positive; sign determined by label)
Chirp Correction
SpectroscopyTools.ChirpCalibration — Type
ChirpCalibrationStores the result of chirp detection: detected chirp points, polynomial fit, and detection parameters for reproducibility.
Fields
wavelength: Wavelength points where chirp was detected (nm)time_offset: Detected chirp time at each wavelength (ps)poly_coeffs: Polynomial fit coefficients (constant term first, ascending order)poly_order: Polynomial order usedreference_λ: Reference wavelength where chirp = 0 (nm)r_squared: Polynomial fit qualitymetadata: Detection parameters for reproducibility
SpectroscopyTools.detect_chirp — Function
detect_chirp(matrix::TAMatrix; kwargs...) -> ChirpCalibrationDetect chirp (GVD) in a broadband TA matrix via cross-correlation (:xcorr) or threshold crossing (:threshold). Returns a ChirpCalibration with polynomial fit.
SpectroscopyTools.correct_chirp — Function
correct_chirp(matrix::TAMatrix, cal::ChirpCalibration) -> TAMatrixApply chirp correction via cubic spline interpolation, shifting each wavelength column by t_shift(λ) from the calibration polynomial.
SpectroscopyTools.subtract_background — Function
subtract_background(matrix::TAMatrix; t_range=nothing) -> TAMatrixSubtract pre-pump background from a TA matrix by averaging and removing the signal in the baseline region (before pump arrival).
subtract_background(m::PLMap; positions=nothing, margin=5) -> PLMapSubtract a background spectrum from every grid point.
The background is the average CCD spectrum over the reference positions. After subtraction, the intensity map is recomputed from the corrected spectra using the same pixel_range as the original load (if any).
Arguments
positions: Vector of(x, y)spatial coordinate tuples (μm) for background reference points. These should be off-flake positions with no PL signal.margin: Number of grid points from each edge used for auto-detection whenpositionsis not given. Auto mode averages the corners of the bottom half of the map (avoids top-row artifacts). Default: 5.
Example
m = load_pl_map("data.lvm"; nx=51, ny=51, step_size=2.16, pixel_range=(950, 1100))
# Explicit background positions
m_bg = subtract_background(m; positions=[(-40, -40), (40, -40), (-40, -20)])
# Auto mode (bottom corners)
m_bg = subtract_background(m)SpectroscopyTools.polynomial — Function
polynomial(cal::ChirpCalibration) -> FunctionReturn a callable polynomial t_shift = poly(λ) from the calibration. Coefficients are in ascending order: c[1] + c[2]*λ + c[3]*λ² + ...
SpectroscopyTools.save_chirp — Function
save_chirp(path::String, cal::ChirpCalibration)Save a chirp calibration to a JSON file.
SpectroscopyTools.load_chirp — Function
load_chirp(path::String) -> ChirpCalibrationLoad a chirp calibration from a JSON file.
SVD Filtering
SpectroscopyTools.svd_filter — Function
svd_filter(matrix::TAMatrix; n_components::Int=5) -> TAMatrixDenoise a TA matrix by keeping only the first n_components singular value components. Higher-order components (dominated by noise) are discarded.
This is a standard preprocessing step for broadband TA data. Typical usage: denoise first, then subtract background, detect chirp, and correct chirp.
Arguments
matrix::TAMatrix: Input time × wavelength ΔA matrix
Keywords
n_components::Int=5: Number of singular value components to retain. Usesingular_valuesto inspect the spectrum and choose.
Returns
A new TAMatrix with filtered data. Metadata includes :svd_filtered => true and :svd_n_components => n_components.
Examples
sv = singular_values(matrix) # inspect singular value spectrum
filtered = svd_filter(matrix; n_components=3)svd_filter(x::AbstractVector, y::AbstractVector, data::AbstractMatrix;
n_components::Int=5) -> Matrix{Float64}Denoise a raw data matrix by keeping only the first n_components singular value components. Returns the filtered matrix.
Arguments
x: First axis (e.g., time)y: Second axis (e.g., wavelength)data: Matrix of size(length(x), length(y))
Keywords
n_components::Int=5: Number of components to retain
SpectroscopyTools.singular_values — Function
singular_values(matrix::TAMatrix) -> Vector{Float64}Return the singular values of the TA data matrix. Inspect these to choose n_components for svd_filter — look for a gap between signal and noise components.
Examples
sv = singular_values(matrix)
# Plot sv to find the elbow, then filter:
filtered = svd_filter(matrix; n_components=3)singular_values(data::AbstractMatrix) -> Vector{Float64}Return the singular values of a raw data matrix.
Cosmic Ray Detection
SpectroscopyTools.CosmicRayResult — Type
CosmicRayResultResult of cosmic ray detection on a 1D signal.
Fields
indices::Vector{Int}— flagged channel indicescount::Int— number of flagged channels
SpectroscopyTools.CosmicRayMapResult — Type
CosmicRayMapResultResult of cosmic ray detection on a PLMap.
Fields
mask::BitArray{3}—(nx, ny, n_pixel),true= cosmic raycount::Int— total flagged voxelsaffected_spectra::Int— number of spectra with at least one cosmic raychannel_counts::Vector{Int}— cosmic ray count per spectral channel
SpectroscopyTools.detect_cosmic_rays — Function
detect_cosmic_rays(signal::AbstractVector; threshold=5.0) -> CosmicRayResultDetect cosmic ray spikes in a 1D spectrum using modified z-scores on first differences (Whitaker-Hayes method).
Computes first differences Δ[k] = signal[k+1] - signal[k], then flags channels where the modified z-score exceeds threshold. The modified z-score uses the Median Absolute Deviation (MAD) for robust scale estimation.
Arguments
signal: 1D spectral signalthreshold: z-score cutoff (default 5.0). Lower values detect more spikes but may flag real features.
Returns
A CosmicRayResult with the flagged channel indices.
Example
result = detect_cosmic_rays(spectrum; threshold=5.0)
println("Found $(result.count) cosmic rays at indices $(result.indices)")detect_cosmic_rays(m::PLMap; threshold=5.0, pixel_range=nothing, max_spike_width=7) -> CosmicRayMapResultDetect cosmic ray spikes across all spectra in a PLMap using Most Similar Neighbor (MSN) comparison.
For each pixel, selects the 4-connected neighbor with the highest Pearson correlation as the reference spectrum. The residual (pixel minus MSN) is then tested for positive outliers using the MAD-based robust scale estimate. Channels where the residual exceeds threshold × σ above the median residual are flagged.
Using the most-similar neighbor avoids false positives at spatial boundaries: real spectral differences cancel because the MSN is on the same side of the boundary. Only true cosmic ray spikes — absent from all neighbors — remain.
Additional filters:
- Width filter: contiguous flagged runs wider than
max_spike_widthare unflagged — cosmic rays span 1–5 channels; wider runs are spectral variation. - Fraction cap: if more than 5% of channels are still flagged after the width filter, all flags for that pixel are cleared.
A global noise floor (median of per-pixel σ estimates) prevents over-sensitivity in spatially homogeneous regions.
Arguments
m: PLMap with 3D spectra array(nx, ny, n_pixel)threshold: outlier cutoff in MAD-scaled units (default 5.0)pixel_range:(start, stop)channel indices to analyze. When set, only this subrange of each spectrum is checked for cosmic rays. Channels outside the range are never flagged. Defaults to thepixel_rangeinm.metadata, or the full spectrum if unset.max_spike_width: maximum width (in channels) of a contiguous flagged run to keep (default 7). Runs wider than this are unflagged as spectral variation.
Returns
A CosmicRayMapResult with a 3D boolean mask and summary statistics.
Example
cr = detect_cosmic_rays(plmap; threshold=5.0)
println("Found $(cr.count) cosmic rays in $(cr.affected_spectra) spectra")SpectroscopyTools.remove_cosmic_rays — Function
remove_cosmic_rays(signal::AbstractVector, result::CosmicRayResult) -> VectorReplace flagged cosmic ray channels with linearly interpolated values from the nearest non-flagged neighbors.
Returns a new vector; does not mutate the input.
Example
result = detect_cosmic_rays(spectrum)
cleaned = remove_cosmic_rays(spectrum, result)remove_cosmic_rays(m::PLMap, result::CosmicRayMapResult) -> PLMapRemove cosmic rays from a PLMap using scaled Most Similar Neighbor (MSN) replacement.
For each affected pixel, finds the 4-connected neighbor with the highest Pearson correlation (the MSN). A scale factor is computed from non-flagged channels to match the pixel's intensity level. Flagged channels are then replaced with scale × MSN[k]. This preserves the pixel's overall intensity while removing only the spike shape, avoiding the dark-patch artifacts that raw neighbor median replacement produces.
Falls back to spectral interpolation (1D linear from nearest non-flagged channels) for edge pixels with no spatial neighbors.
Returns a new PLMap with recomputed intensity.
Example
cr = detect_cosmic_rays(plmap)
cleaned = remove_cosmic_rays(plmap, cr)PL / Raman Mapping
SpectroscopyTools.PLMap — Type
PLMap <: AbstractSpectroscopyDataPhotoluminescence intensity map from a CCD raster scan.
A 2D spatial grid where each point has a full CCD spectrum. The intensity field holds the integrated PL signal at each position; the full spectra are stored in spectra for extraction at individual positions.
Fields
intensity::Matrix{Float64}— Integrated PL intensity(nx, ny)spectra::Array{Float64,3}— Raw CCD counts(nx, ny, n_pixel)x::Vector{Float64}— Spatial x positions (μm)y::Vector{Float64}— Spatial y positions (μm)pixel::Vector{Float64}— Pixel indices (or wavelength if calibrated)metadata::Dict{String,Any}— Source file, grid dims, step size, etc.
SpectroscopyTools.extract_spectrum — Function
extract_spectrum(m::PLMap, ix::Int, iy::Int) -> NamedTupleExtract the CCD spectrum at grid index (ix, iy).
Returns (pixel=..., signal=..., x=..., y=...).
extract_spectrum(m::PLMap; x::Real, y::Real) -> NamedTupleExtract the CCD spectrum at the spatial position nearest to (x, y).
Returns (pixel=..., signal=..., x=..., y=..., ix=..., iy=...).
SpectroscopyTools.integrated_intensity — Function
integrated_intensity(m::PLMap; pixel_range=nothing) -> Matrix{Float64}Compute the integrated intensity at each grid point.
Without pixel_range, returns m.intensity (the precomputed full-range sum). With pixel_range, sums m.spectra[:, :, p1:p2] over the given pixel window.
Arguments
pixel_range:(start, stop)pixel indices to integrate over. Falls back to thepixel_rangestored in metadata, or usesm.intensityif unset.
SpectroscopyTools.intensity_mask — Function
intensity_mask(m::PLMap; pixel_range=nothing, threshold=0.05, exclude=nothing) -> NamedTupleCompute a boolean mask over the PLMap grid based on integrated intensity.
Grid points where the integrated intensity is below threshold fraction of the intensity range are excluded (false). Spatial regions listed in exclude are also set to false regardless of intensity. This is useful for filtering out off-sample regions and known artifacts (e.g., substrate bands) before batch operations like fitting.
The threshold is computed as: cutoff = min + threshold × (max - min).
Arguments
pixel_range:(start, stop)pixel indices for computing integrated intensity. Ifnothing, uses the full precomputedm.intensity.threshold: Fraction of the intensity range (0.0 to 1.0). Default0.05(5%).exclude: Spatial regions to exclude. Each region is a tuple of x and y ranges in spatial coordinates (μm):((x_min, x_max), (y_min, y_max)). Accepts a single region or a vector of regions. Grid points whose spatial coordinates fall within any excluded region are masked out.
Returns
A named tuple with fields:
mask::BitMatrix—truefor included grid pointsn_included::Int— number of included pointsn_total::Int— total number of grid pointsintensity_min::Float64— minimum integrated intensityintensity_max::Float64— maximum integrated intensitycutoff::Float64— absolute intensity cutoff value
Examples
m = load_pl_map("scan.lvm"; nx=51, ny=51)
m = subtract_background(m)
# Threshold only
result = intensity_mask(m; pixel_range=(950, 1100), threshold=0.1)
# Exclude a substrate band at the top of the map
result = intensity_mask(m; threshold=0.05,
exclude=((-Inf, Inf), (40.0, Inf)))
# Multiple exclusion regions
result = intensity_mask(m; threshold=0.05,
exclude=[
((-Inf, Inf), (40.0, Inf)), # top substrate band
((-50.0, -40.0), (-50.0, -40.0)) # noisy corner
])SpectroscopyTools.peak_centers — Function
peak_centers(m::PLMap; pixel_range=nothing, threshold=0.05) -> Matrix{Float64}Compute the centroid (intensity-weighted average pixel) at each grid point.
Returns a (nx, ny) matrix of peak center positions in pixel units. Grid points where the PL intensity (m.intensity) is below threshold × the map maximum are set to NaN (renders as transparent in heatmaps with nan_color=:transparent).
Masking uses the PLMap's intensity field — the integrated PL signal already stored in the map. This produces clean masks that match the intensity heatmap: off-flake regions (low PL signal) are transparent, on-flake regions show centroid positions.
Arguments
pixel_range:(start, stop)pixel range to compute the centroid over. Falls back to thepixel_rangestored in metadata, or all pixels if unset.threshold: Fraction of the maximum PL intensity below which a grid point is masked asNaN. Default0.05(5%). Set to0to disable masking.
Example
m = load_pl_map("scan.lvm"; nx=51, ny=51, pixel_range=(950, 1100))
m = subtract_background(m)
centers = peak_centers(m)
heatmap(m.x, m.y, centers; colormap=:viridis, nan_color=:transparent)SpectroscopyTools.normalize_intensity — Function
normalize_intensity(m::PLMap) -> PLMapReturn a new PLMap with intensity normalized to [0, 1].
Peak Fitting
SpectroscopyTools.fit_peaks — Function
fit_peaks(x, y; kwargs...) -> MultiPeakFitResult
fit_peaks(spec::AbstractSpectroscopyData, region; kwargs...) -> MultiPeakFitResult
fit_peaks(spec::AbstractSpectroscopyData; kwargs...) -> MultiPeakFitResultFit one or more peaks in spectroscopy data.
SpectroscopyTools.fit_ta_spectrum — Function
fit_ta_spectrum(spec::TASpectrum; kwargs...) -> TASpectrumFitFit a transient absorption spectrum with N peaks of arbitrary lineshape.
Uses find_peaks to automatically detect initial peak positions from the data, so multiple well-separated peaks of the same type (e.g., three GSB peaks for W(CO)₆) are initialized correctly.
Keywords
peaks=[:esa, :gsb]— Peak types. Each element is either aSymbol(:esa,:gsb,:se,:positive,:negative) or a(Symbol, Function)tuple specifying label and lineshape model.model=gaussian— Default lineshape for peaks specified as symbols only.region=nothing— Optional(x_min, x_max)fitting region.fit_offset=false— Whether to fit a constant offset.p0=nothing— Manual initial parameter vector. Overrides automatic detection.
Peak signs
:esa,:positive→ +1 (positive ΔA):gsb,:se,:negative→ -1 (negative ΔA)
Examples
# Default: 1 Gaussian ESA + 1 Gaussian GSB
result = fit_ta_spectrum(spec)
# Three GSB peaks (e.g., W(CO)₆ carbonyl stretches)
result = fit_ta_spectrum(spec; peaks=[:esa, :esa, :esa, :gsb, :gsb, :gsb])
# Per-peak lineshapes
result = fit_ta_spectrum(spec; peaks=[(:esa, lorentzian), (:gsb, gaussian)])
# Access results
result[:esa].center # first ESA peak
result[2].center # second peak by index
anharmonicity(result) # GSB - ESA center (only if exactly 1 of each)
predict(result, ν) # full fitted curve
predict_peak(result, 1) # single peak contributionSpectroscopyTools.MultiPeakFitResult — Type
MultiPeakFitResultResult of multi-peak fitting (1 to N peaks with polynomial baseline).
Supports indexing by peak number: result[1] returns first peak's PeakFitResult.
SpectroscopyTools.PeakFitResult — Type
PeakFitResultResult of peak fitting with any lineshape model.
Access parameters by name: result[:center].value, result[:fwhm].err
SpectroscopyTools.anharmonicity — Function
anharmonicity(fit::TASpectrumFit) -> Float64Compute the anharmonicity (GSB center - ESA center) from a TA spectrum fit. Returns NaN if there is not exactly one ESA and one GSB peak.
Peak Detection
SpectroscopyTools.PeakInfo — Type
PeakInfoInformation about a detected peak.
Fields
position::Float64— Peak center in x-unitsintensity::Float64— Peak heightprominence::Float64— How much the peak stands out from surrounding baselinewidth::Float64— Full width at half prominence (FWHP) in x-unitsbounds::Tuple{Float64,Float64}— Left and right edges at half prominenceindex::Int— Index in the original data array
SpectroscopyTools.find_peaks — Function
find_peaks(y; kwargs...) -> Vector{PeakInfo}
find_peaks(x, y; kwargs...) -> Vector{PeakInfo}Find peaks in spectroscopic data.
Keyword Arguments
min_prominence::Real=0.05— Minimum prominence as fraction of data rangemin_width::Real=0— Minimum peak width in x-unitsmax_width::Real=Inf— Maximum peak width in x-unitsmin_height::Real=-Inf— Minimum peak height (absolute)window::Int=1— Comparison window for local maxima detectionmode::Symbol=:maxima—:maximafor peaks,:minimafor valleys (e.g. 2nd derivative)baseline::Union{Symbol,Nothing}=nothing— Apply baseline correction before peak detectionbaseline_kw::NamedTuple=NamedTuple()— Keyword arguments for baseline correction
SpectroscopyTools.peak_table — Function
peak_table(peaks::Vector{PeakInfo}) -> StringFormat detected peaks as an aligned text table for terminal display.
Exponential Decay Fitting
SpectroscopyTools.fit_exp_decay — Function
fit_exp_decay(trace::TATrace; n_exp=1, irf=false, irf_width=0.15, t_start=0.0, t_range=nothing)Fit exponential decay to a transient absorption trace.
Arguments
trace: TATracen_exp: Number of exponential components (default 1)irf: Include IRF convolution (default false)irf_width: Initial guess for IRF σ in ps (default 0.15)t_start: Start time for fitting when irf=false (default 0.0)t_range: Optional (tmin, tmax) to restrict fit region
Returns
n_exp=1:ExpDecayFitn_exp>1:MultiexpDecayFit
SpectroscopyTools.fit_global — Function
fit_global(traces::Vector{TATrace}; n_exp=1, irf_width=0.15, labels=nothing) -> GlobalFitResultFit multiple traces simultaneously with shared time constant(s) τ.
Supports single-exponential (n_exp=1) and multi-exponential (n_exp>1) global analysis. All traces share the same time constants, IRF width, and time zero, while amplitudes and offsets are fitted per-trace.
Keywords
n_exp::Int=1: Number of exponential componentsirf_width::Float64=0.15: Initial guess for IRF σ in pslabels=nothing: Optional trace labels (defaults to "Trace 1", "Trace 2", ...)
Returns
GlobalFitResult with shared taus and per-trace amplitudes matrix.
Examples
# Single-exponential global fit
result = fit_global([trace_esa, trace_gsb])
# Multi-exponential with 2 shared time constants
result = fit_global([trace1, trace2, trace3]; n_exp=2)
report(result)fit_global(matrix::TAMatrix; n_exp=1, irf_width=0.15, λ=nothing) -> GlobalFitResultGlobal analysis of a TAMatrix, extracting traces at each wavelength.
Returns a GlobalFitResult with the wavelengths field populated, enabling decay-associated spectra (DAS) via das(result).
Keywords
n_exp::Int=1: Number of exponential componentsirf_width::Float64=0.15: Initial guess for IRF σ in psλ=nothing: Specific wavelengths to fit. Ifnothing, fits all wavelengths.
Examples
result = fit_global(matrix; n_exp=2)
report(result)
# Get decay-associated spectra
spectra = das(result) # n_exp × n_wavelengths matrixSpectroscopyTools.ExpDecayFit — Type
ExpDecayFitResult of exponential decay fitting with instrument response function convolution.
Fields
amplitude,tau,t0,sigma,offset,signal_type,residuals,rsquared
SpectroscopyTools.MultiexpDecayFit — Type
MultiexpDecayFitResult of multi-exponential decay fitting (n >= 1 components).
Fields
taus::Vector{Float64}: Time constants (sorted fast->slow)amplitudes::Vector{Float64}: Corresponding amplitudest0,sigma,offset,signal_type,residuals,rsquared
Derived properties
n_exp(fit): Number of exponential componentsweights(fit): Relative amplitude weights (normalized to 100%)
SpectroscopyTools.GlobalFitResult — Type
GlobalFitResultResult of global fitting multiple traces with shared time constants.
Supports single-exponential (nexp=1) and multi-exponential (nexp>1) global analysis with shared τ values and per-trace amplitudes.
Fields
taus::Vector{Float64}: Shared time constants (sorted fast→slow)sigma::Float64: Shared IRF widtht0::Float64: Shared time zeroamplitudes::Matrix{Float64}: Per-trace amplitudes (ntraces × nexp)offsets::Vector{Float64}: Per-trace offsetslabels::Vector{String}: Trace labelswavelengths::Union{Nothing, Vector{Float64}}: Wavelength axis (from TAMatrix input)rsquared::Float64: Global R²rsquared_individual::Vector{Float64}: Per-trace R²residuals::Vector{Vector{Float64}}: Per-trace residuals
Derived properties
n_exp(fit): Number of exponential componentsdas(fit): Decay-associated spectra (requires TAMatrix input)
SpectroscopyTools.das — Function
das(fit::GlobalFitResult) -> Matrix{Float64}Return the decay-associated spectra (DAS) as an n_exp × n_wavelengths matrix. Each row is the amplitude spectrum for one time constant.
Requires that the fit was performed on a TAMatrix (wavelengths must be available).
SpectroscopyTools.report — Function
report(result)Print a formatted summary of a fit result to the terminal.
Baseline Correction
SpectroscopyTools.arpls_baseline — Function
arpls_baseline(y; λ=1e5, maxiter=100, tol=1e-6) -> VectorAsymmetrically Reweighted Penalized Least Squares baseline correction.
SpectroscopyTools.snip_baseline — Function
snip_baseline(y; iterations=40, decreasing=true) -> VectorSNIP baseline correction using iterative peak clipping.
SpectroscopyTools.rubberband_baseline — Function
rubberband_baseline(x, y)Rubber band baseline correction using the lower convex hull.
Equivalent to stretching a rubber band under the spectrum – the baseline follows the lower envelope. Used in OPUS for FTIR baseline correction.
Returns the baseline y-values (same length as input).
SpectroscopyTools.imodpoly_baseline — Function
imodpoly_baseline(x, y; poly_order=4, maxiter=100, tol=1e-3) -> VectorImproved Modified Polynomial baseline (Lieber & Mahadevan-Jansen, 2003).
Iteratively fits a polynomial to the spectrum, removing points that are above the fit by more than one standard deviation of the residuals. Converges when the fit changes less than tol between iterations.
SpectroscopyTools.rolling_ball_baseline — Function
rolling_ball_baseline(y; half_window=50, smooth_half_window=nothing) -> VectorRolling ball baseline estimation using morphological operations.
Applies erosion (rolling minimum) then dilation (rolling maximum) to estimate the baseline envelope, followed by moving-average smoothing.
Arguments
half_window::Int=50: Half-window size for morphological operations.smooth_half_window::Int: Half-window for final smoothing (default:half_window).
SpectroscopyTools.correct_baseline — Function
correct_baseline(y; method=:arpls, kwargs...) -> NamedTupleCorrect baseline and return both corrected spectrum and baseline.
Returns (y=corrected, baseline=baseline).
correct_baseline(x, y; kwargs...) -> NamedTupleVersion that also returns x values for convenience. Methods that use x-values (rubberband) receive real x, not dummy indices.
Spectroscopy Utilities
SpectroscopyTools.normalize — Function
normalize(x)Normalize array by maximum absolute value. Returns zeros if max is zero.
SpectroscopyTools.smooth_data — Function
smooth_data(y; window=3)Apply moving average smoothing to data.
SpectroscopyTools.calc_fwhm — Function
calc_fwhm(x, y; smooth_window=5)Calculate full width at half maximum (FWHM) of the dominant positive peak.
SpectroscopyTools.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.
SpectroscopyTools.transmittance_to_absorbance — Function
transmittance_to_absorbance(T; percent=false)Convert transmittance to absorbance: A = -log10(T). Input T is fractional (0 to 1). Use percent=true for percent transmittance.
SpectroscopyTools.absorbance_to_transmittance — Function
absorbance_to_transmittance(A; percent=false)Convert absorbance to transmittance: T = 10^(-A).
SpectroscopyTools.npoints — Function
npoints(d::AbstractSpectroscopyData) -> Int
npoints(d::TAMatrix) -> Tuple{Int,Int}Return the number of data points. For 1D data, returns an Int. For 2D data (TAMatrix), returns (n_time, n_wavelength).
SpectroscopyTools.source_file — Function
source_file(d::AbstractSpectroscopyData) -> StringReturn the source filename for the data.
SpectroscopyTools.title — Function
title(d::AbstractSpectroscopyData) -> StringReturn a display title for the data. Defaults to source_file(d).
Unit Conversions
SpectroscopyTools.wavenumber_to_wavelength — Function
wavenumber_to_wavelength(ν̃; output_unit=u"nm")Convert wavenumber (cm⁻¹) to wavelength.
SpectroscopyTools.wavelength_to_wavenumber — Function
wavelength_to_wavenumber(λ; output_unit=u"cm^-1")Convert wavelength to wavenumber. Input assumed in nm if unitless.
SpectroscopyTools.wavenumber_to_energy — Function
wavenumber_to_energy(ν̃; output_unit=u"eV")Convert wavenumber (cm⁻¹) to photon energy.
SpectroscopyTools.wavelength_to_energy — Function
wavelength_to_energy(λ; output_unit=u"eV")Convert wavelength to photon energy. Input assumed in nm if unitless.
SpectroscopyTools.energy_to_wavelength — Function
energy_to_wavelength(E; output_unit=u"nm")Convert photon energy to wavelength. Input assumed in eV if unitless.
SpectroscopyTools.linewidth_to_decay_time — Function
linewidth_to_decay_time(Γ; output_unit=u"ps")Convert spectral linewidth (FWHM) to decay time: τ = ℏ/Γ. Input assumed in meV if unitless.
SpectroscopyTools.decay_time_to_linewidth — Function
decay_time_to_linewidth(τ; output_unit=u"meV")Convert excited-state decay time to natural linewidth (FWHM): Γ = ℏ/τ. Input assumed in ps if unitless.