nirs4all.synthesis.reconstruction.forward module
Forward model components for physical signal-chain reconstruction.
- This module implements the forward measurement chain:
Canonical physical model → Instrument effects → Domain transform → Preprocessing
Key principle: Keep one latent physical model on a canonical grid, then apply dataset-specific transforms to match observed data.
- class nirs4all.synthesis.reconstruction.forward.CanonicalForwardModel(canonical_grid: ndarray, component_names: List[str] = <factory>, baseline_order: int = 5, continuum_order: int = 3, _component_spectra: ndarray | None = None, _baseline_basis: ndarray | None = None, _continuum_basis: ndarray | None = None)[source]
Bases:
objectPhysical model on canonical high-resolution wavelength grid.
- Computes absorption coefficient K(λ) from chemical components:
K(λ) = Σ c_k * ε_k(λ) + K0(λ)
- where:
c_k: concentration of component k
ε_k(λ): molar absorptivity (from component library)
K0(λ): continuum/background absorption (low-frequency)
- canonical_grid
High-resolution wavelength grid (nm).
- Type:
- component_spectra
Pre-computed component spectra on canonical grid.
- compute_absorption(concentrations: ndarray, path_length: float = 1.0, baseline_coeffs: ndarray | None = None, continuum_coeffs: ndarray | None = None) ndarray[source]
Compute absorption coefficient on canonical grid.
- Parameters:
concentrations – Component concentrations, shape (n_components,).
path_length – Optical path length factor.
baseline_coeffs – Baseline polynomial coefficients.
continuum_coeffs – Continuum absorption coefficients.
- Returns:
Absorbance spectrum on canonical grid.
- class nirs4all.synthesis.reconstruction.forward.DomainTransform(domain: Literal['absorbance', 'reflectance', 'transmittance', 'km'] = 'absorbance', scatter_coeffs: ndarray | None = None, scatter_wavelength_exp: float = 0.0)[source]
Bases:
objectTransform between physical domains (absorbance, reflectance, etc.).
For absorbance datasets: A(λ) = absorption coefficient (direct) For reflectance datasets: R(λ) computed via Kubelka-Munk or approximation
- domain
Domain type (‘absorbance’, ‘reflectance’, ‘transmittance’, ‘km’).
- Type:
Literal[‘absorbance’, ‘reflectance’, ‘transmittance’, ‘km’]
- scatter_coeffs
Scattering coefficients for KM model (reflectance).
- Type:
numpy.ndarray | None
- scatter_wavelength_dep
Wavelength-dependent scatter (λ^-n).
- inverse_transform(spectrum: ndarray, wavelengths: ndarray, scatter: ndarray | None = None) ndarray[source]
Inverse transform from domain to absorption.
- Parameters:
spectrum – Spectrum in domain representation.
wavelengths – Wavelength grid.
scatter – Scattering coefficient for reflectance.
- Returns:
Absorption coefficient.
- transform(absorption: ndarray, wavelengths: ndarray, scatter: ndarray | None = None) ndarray[source]
Transform absorption to target domain.
- Parameters:
absorption – Absorption coefficient K(λ).
wavelengths – Wavelength grid.
scatter – Scattering coefficient S(λ) for reflectance.
- Returns:
Spectrum in target domain representation.
- class nirs4all.synthesis.reconstruction.forward.ForwardChain(canonical_model: CanonicalForwardModel, instrument_model: InstrumentModel, domain_transform: DomainTransform, preprocessing: PreprocessingOperator, environmental_model: 'EnvironmentalEffectsModel' | None = None)[source]
Bases:
objectComplete forward measurement chain combining all components.
Chain: CanonicalForwardModel → [EnvironmentalEffects] → DomainTransform → InstrumentModel → PreprocessingOperator
- canonical_model
Physical model on canonical grid.
- Type:
- environmental_model
Optional environmental effects (temperature, moisture, scattering).
- Type:
Optional[‘EnvironmentalEffectsModel’]
- instrument_model
Instrument effects.
- Type:
- domain_transform
Domain conversion.
- Type:
- preprocessing
Dataset preprocessing.
- Type:
- canonical_model: CanonicalForwardModel
- classmethod create(canonical_grid: ndarray, target_grid: ndarray, component_names: List[str], domain: str = 'absorbance', preprocessing_type: str = 'none', instrument_params: Dict[str, float] | None = None, baseline_order: int = 5, continuum_order: int = 3, sg_window: int = 15, sg_polyorder: int = 2, include_environmental: bool = False) ForwardChain[source]
Convenience factory method to create ForwardChain.
- Parameters:
canonical_grid – High-resolution canonical wavelength grid.
target_grid – Target dataset wavelength grid.
component_names – Names of components to include.
domain – Domain type (‘absorbance’, ‘reflectance’).
preprocessing_type – Preprocessing type.
instrument_params – Instrument parameters dict.
baseline_order – Baseline polynomial order.
continuum_order – Continuum polynomial order.
sg_window – Savitzky-Golay window.
sg_polyorder – Savitzky-Golay polynomial order.
include_environmental – Whether to include environmental effects model.
- Returns:
Configured ForwardChain instance.
- domain_transform: DomainTransform
- forward(concentrations: ndarray, path_length: float = 1.0, baseline_coeffs: ndarray | None = None, continuum_coeffs: ndarray | None = None, scatter: ndarray | None = None) ndarray[source]
Run full forward chain.
- Parameters:
concentrations – Component concentrations.
path_length – Optical path length factor.
baseline_coeffs – Baseline polynomial coefficients.
continuum_coeffs – Continuum absorption coefficients.
scatter – Scattering coefficients for reflectance.
- Returns:
Spectrum on target grid with preprocessing applied.
- forward_design_matrix(path_length: float = 1.0) ndarray[source]
Get transformed design matrix for linear fitting.
Returns the design matrix after applying instrument and preprocessing transforms. Note: Domain transform is not applied here as it may be nonlinear (KM).
- instrument_model: InstrumentModel
- preprocessing: PreprocessingOperator
- class nirs4all.synthesis.reconstruction.forward.InstrumentModel(target_grid: ndarray, wl_shift: float = 0.0, wl_stretch: float = 1.0, wl_poly_coeffs: ndarray | None = None, ils_sigma: float = 4.0, stray_light: float = 0.0, gain: float = 1.0, offset: float = 0.0)[source]
Bases:
objectInstrument effects: warp, ILS convolution, gain/offset, resampling.
- Transforms spectrum from canonical grid to target instrument grid:
Wavelength warp: λ* → λ’ (shift + stretch + optional higher order)
ILS convolution: Gaussian or Voigt line shape
Stray light / gain / offset
Resample to target grid
- target_grid
Target wavelength grid (dataset grid).
- Type:
- wl_poly_coeffs
Higher-order polynomial warp coefficients.
- Type:
numpy.ndarray | None
- apply(spectrum: ndarray, canonical_grid: ndarray) ndarray[source]
Apply instrument chain to transform spectrum.
- Parameters:
spectrum – Input spectrum on canonical grid.
canonical_grid – Canonical wavelength grid.
- Returns:
Transformed spectrum on target grid.
- classmethod from_params(target_grid: ndarray, params: Dict[str, float]) InstrumentModel[source]
Create InstrumentModel from parameter dictionary.
- get_jacobian_wrt_ils_sigma(spectrum: ndarray, canonical_grid: ndarray, eps: float = 0.1) ndarray[source]
Numerical Jacobian w.r.t. ILS sigma.
- class nirs4all.synthesis.reconstruction.forward.PreprocessingOperator(preprocessing_type: Literal['none', 'first_derivative', 'second_derivative', 'snv', 'msc', 'detrend', 'mean_centered'] = 'none', sg_window: int = 15, sg_polyorder: int = 2, sg_deriv: int = 0, reference_spectrum: ndarray | None = None)[source]
Bases:
objectApply dataset preprocessing to match stored representation.
- Implements exact preprocessing steps:
Savitzky-Golay derivatives (1st, 2nd order)
SNV (Standard Normal Variate)
MSC (Multiplicative Scatter Correction)
Detrend
Mean centering
- preprocessing_type
Type of preprocessing.
- Type:
Literal[‘none’, ‘first_derivative’, ‘second_derivative’, ‘snv’, ‘msc’, ‘detrend’, ‘mean_centered’]
- reference_spectrum
Reference for MSC (mean of calibration set).
- Type:
numpy.ndarray | None
- apply(spectrum: ndarray) ndarray[source]
Apply preprocessing to spectrum.
- Parameters:
spectrum – Input spectrum, shape (n_wavelengths,) or (n_samples, n_wavelengths).
- Returns:
Preprocessed spectrum(a).
- classmethod from_detection(preprocessing_type: str, sg_window: int = 15, sg_polyorder: int = 2) PreprocessingOperator[source]
Create PreprocessingOperator from detected preprocessing type.