nirs4all.data.synthetic.procedural module

Procedural spectral component generation for synthetic NIRS data.

This module provides tools for generating chemically-plausible spectral components with physically-motivated constraints including: - Overtone relationships (bands at 2×, 3× wavenumber with anharmonicity correction) - Combination bands (ν₁ + ν₂ relationships) - Matrix-induced band shifts (hydrogen bonding, solvation) - Domain-specific constraints

The procedural generator can create thousands of unique, realistic spectral components without manual specification of band parameters.

Key Classes:
  • ProceduralComponentConfig: Configuration for procedural generation

  • ProceduralComponentGenerator: Main generator class

Example

>>> from nirs4all.data.synthetic.procedural import (
...     ProceduralComponentGenerator,
...     ProceduralComponentConfig
... )
>>>
>>> config = ProceduralComponentConfig(
...     n_fundamental_bands=2,
...     include_overtones=True,
...     include_combinations=True
... )
>>> generator = ProceduralComponentGenerator(random_state=42)
>>> library = generator.generate_library(n_components=10, config=config)

References

  • Workman Jr, J., & Weyer, L. (2012). Practical Guide and Spectral Atlas for Interpretive Near-Infrared Spectroscopy. CRC Press.

  • Siesler, H. W., Ozaki, Y., Kawata, S., & Heise, H. M. (2002). Near-Infrared Spectroscopy: Principles, Instruments, Applications. Wiley-VCH.

class nirs4all.data.synthetic.procedural.FunctionalGroupType(value)[source]

Bases: str, Enum

Types of functional groups for component generation.

AMINE = 'amine'
AROMATIC_CH = 'aromatic_ch'
CARBONYL = 'carbonyl'
CARBOXYL = 'carboxyl'
HYDROXYL = 'hydroxyl'
METHYL = 'methyl'
METHYLENE = 'methylene'
THIOL = 'thiol'
VINYL = 'vinyl'
WATER = 'water'
class nirs4all.data.synthetic.procedural.ProceduralComponentConfig(n_fundamental_bands: int = 3, include_overtones: bool = True, max_overtone_order: int = 3, include_combinations: bool = True, max_combinations: int = 3, h_bond_strength: float = 0.3, h_bond_variability: float = 0.2, anharmonicity: float = 0.02, anharmonicity_variability: float = 0.005, amplitude_variability: float = 0.3, bandwidth_variability: float = 0.2, wavelength_range: Tuple[float, float] = (900, 2500), functional_groups: List[FunctionalGroupType] | None = None, combination_amplitude_factor: float = 0.2)[source]

Bases: object

Configuration for procedural component generation.

Controls the complexity and characteristics of generated spectral components including the number of bands, overtone generation, combination bands, and environmental effects.

n_fundamental_bands

Number of fundamental vibration bands to generate.

Type:

int

include_overtones

Whether to generate overtone bands (1st, 2nd, etc.).

Type:

bool

max_overtone_order

Maximum overtone order (2=1st overtone, 3=2nd, etc.).

Type:

int

include_combinations

Whether to generate combination bands.

Type:

bool

max_combinations

Maximum number of combination bands.

Type:

int

h_bond_strength

Average hydrogen bonding strength (0-1).

Type:

float

h_bond_variability

Variability in H-bond strength between samples.

Type:

float

anharmonicity

Anharmonicity constant for overtone calculations.

Type:

float

anharmonicity_variability

Variability in anharmonicity.

Type:

float

amplitude_variability

Random variation in band amplitudes.

Type:

float

bandwidth_variability

Random variation in band widths.

Type:

float

wavelength_range

NIR wavelength range for band placement (nm).

Type:

Tuple[float, float]

functional_groups

Optional list of specific functional groups to use.

Type:

List[nirs4all.data.synthetic.procedural.FunctionalGroupType] | None

combination_amplitude_factor

Amplitude reduction for combination bands.

Type:

float

Example

>>> config = ProceduralComponentConfig(
...     n_fundamental_bands=3,
...     include_overtones=True,
...     include_combinations=True,
...     h_bond_strength=0.5
... )
amplitude_variability: float = 0.3
anharmonicity: float = 0.02
anharmonicity_variability: float = 0.005
bandwidth_variability: float = 0.2
combination_amplitude_factor: float = 0.2
functional_groups: List[FunctionalGroupType] | None = None
h_bond_strength: float = 0.3
h_bond_variability: float = 0.2
include_combinations: bool = True
include_overtones: bool = True
max_combinations: int = 3
max_overtone_order: int = 3
n_fundamental_bands: int = 3
wavelength_range: Tuple[float, float] = (900, 2500)
class nirs4all.data.synthetic.procedural.ProceduralComponentGenerator(random_state: int | None = None)[source]

Bases: object

Generator for procedurally-created spectral components.

Creates chemically-plausible spectral components with physically-motivated constraints. Uses wavenumber-space calculations for proper overtone and combination band placement.

rng

NumPy random generator for reproducibility.

Example

>>> generator = ProceduralComponentGenerator(random_state=42)
>>>
>>> # Generate a single component
>>> component = generator.generate_component("my_compound")
>>>
>>> # Generate a library of components
>>> library = generator.generate_library(n_components=10)
>>>
>>> # Generate with specific configuration
>>> config = ProceduralComponentConfig(n_fundamental_bands=4)
>>> component = generator.generate_component("complex_compound", config)
generate_component(name: str, config: ProceduralComponentConfig | None = None, functional_groups: List[FunctionalGroupType] | None = None, correlation_group: int | None = None) SpectralComponent[source]

Generate a single spectral component.

Creates a chemically-plausible component with bands following physical constraints (overtone relationships, combination bands, etc.).

Parameters:
  • name – Name for the component.

  • config – Generation configuration. If None, uses defaults.

  • functional_groups – Specific functional groups to use. If None, randomly selects based on config.

  • correlation_group – Optional correlation group ID.

Returns:

SpectralComponent with generated bands.

Example

>>> generator = ProceduralComponentGenerator(random_state=42)
>>> component = generator.generate_component("my_compound")
>>> print(f"Generated {len(component.bands)} bands")
generate_from_functional_groups(name: str, functional_groups: List[FunctionalGroupType | str], config: ProceduralComponentConfig | None = None) SpectralComponent[source]

Generate a component with specified functional groups.

Convenience method for creating components with known chemistry.

Parameters:
  • name – Component name.

  • functional_groups – List of functional groups (enum or string).

  • config – Optional generation configuration.

Returns:

SpectralComponent with bands from specified functional groups.

Example

>>> generator = ProceduralComponentGenerator(random_state=42)
>>> # Generate an alcohol
>>> alcohol = generator.generate_from_functional_groups(
...     "alcohol",
...     ["hydroxyl", "methyl", "methylene"]
... )
generate_library(n_components: int, config: ProceduralComponentConfig | None = None, name_prefix: str = 'component') ComponentLibrary[source]

Generate a library of procedural components.

Creates multiple unique components with varied characteristics.

Parameters:
  • n_components – Number of components to generate.

  • config – Generation configuration applied to all components.

  • name_prefix – Prefix for component names.

Returns:

ComponentLibrary populated with generated components.

Example

>>> generator = ProceduralComponentGenerator(random_state=42)
>>> library = generator.generate_library(10)
>>> print(f"Created library with {library.n_components} components")
generate_variant(base_component: SpectralComponent, variation_scale: float = 0.1, name: str | None = None) SpectralComponent[source]

Generate a variant of an existing component.

Creates a new component with similar characteristics but varied band positions, widths, and amplitudes. Useful for simulating batch effects or matrix variations.

Parameters:
  • base_component – Component to base the variant on.

  • variation_scale – Scale of random variations (0-1).

  • name – Name for the variant. If None, appends “_variant”.

Returns:

SpectralComponent variant.

Example

>>> generator = ProceduralComponentGenerator(random_state=42)
>>> base = generator.generate_component("base")
>>> variant = generator.generate_variant(base, variation_scale=0.15)