"""Partial coherence module for optical simulations.

Extended Summary
----------------
This module provides comprehensive support for partially coherent optical
fields, including both spatial coherence (extended sources, van Cittert-Zernike
theorem) and temporal coherence (finite bandwidth, chromatic effects).

The core approach is **coherent mode decomposition**: any partially coherent
field can be represented as a weighted sum of orthogonal coherent modes
(Mercer's theorem). This enables efficient simulation by propagating a
finite number of modes and summing intensities.

Routine Listings
----------------
:func:`apply_element_to_modes`
    Apply optical element to all modes.
:func:`bandwidth_from_coherence_length`
    Invert coherence length to bandwidth.
:func:`blackbody_spectrum`
    Planck spectral distribution.
:func:`coherence_length`
    Calculate coherence length from bandwidth.
:func:`coherence_time`
    Calculate coherence time from bandwidth.
:func:`coherence_width_from_source`
    Coherence width via van Cittert-Zernike theorem.
:func:`complex_degree_of_coherence`
    Normalized coherence from mutual intensity.
:func:`effective_mode_count`
    Calculate participation ratio of modes.
:func:`eigenmode_decomposition`
    Decompose mutual intensity into modes.
:func:`gaussian_coherence_kernel`
    Gaussian spatial coherence kernel.
:func:`gaussian_schell_model_modes`
    Modes for Gaussian Schell-model source.
:func:`gaussian_spectrum`
    Gaussian spectral distribution.
:func:`hermite_gaussian_modes`
    Generate Hermite-Gaussian mode set.
:func:`intensity_from_modes`
    Total intensity from mode sum.
:func:`intensity_from_polychromatic`
    Total intensity from spectral sum.
:func:`jinc_coherence_kernel`
    Jinc kernel from circular incoherent source.
:func:`laser_with_mode_noise`
    Laser with imperfect mode purity.
:func:`led_source`
    LED with spatial and temporal partial coherence.
:func:`lorentzian_spectrum`
    Lorentzian (natural) lineshape.
:func:`modes_from_wavefront`
    Wrap coherent field as single-mode set.
:func:`multimode_fiber_output`
    Multimode fiber output.
:func:`mutual_intensity_from_modes`
    Reconstruct mutual intensity from modes.
:func:`propagate_and_focus_modes`
    Lens focusing and propagation of modes.
:func:`propagate_coherent_modes`
    Propagate all modes through free space.
:func:`propagate_polychromatic`
    Propagate polychromatic wavefront.
:func:`rectangular_coherence_kernel`
    Sinc kernel from rectangular source.
:func:`rectangular_spectrum`
    Flat-top spectral distribution.
:func:`spectral_phase_from_dispersion`
    Spectral phase from material dispersion.
:func:`synchrotron_source`
    Synchrotron X-ray source (anisotropic).
:func:`thermal_mode_weights`
    Generate thermal (exponentially decreasing) mode weights.
:func:`thermal_source`
    Thermal (blackbody) source.

Notes
-----
The memory-efficient coherent mode representation stores O(M × N²) data
for M modes on an N×N grid, compared to O(N⁴) for the full mutual
intensity. For typical simulations, 5-20 modes capture most of the
field energy.

The total intensity from coherent modes is:
    I(r) = Σₙ wₙ |φₙ(r)|²

where wₙ are the modal weights and φₙ are the modes.

Internal Functions
------------------
Each submodule exposes internal ``_impl`` functions that are pure JAX
implementations with ``static_argnums`` for grid dimensions. These can
be imported directly for use in pure JAX workflows where maximum
performance is needed:

- ``janssen.cohere.spatial``: ``_gaussian_coherence_kernel_impl``,
  ``_jinc_coherence_kernel_impl``, ``_rectangular_coherence_kernel_impl``,
  ``_complex_degree_of_coherence_impl``
- ``janssen.cohere.temporal``: ``_gaussian_spectrum_impl``,
  ``_lorentzian_spectrum_impl``, ``_rectangular_spectrum_impl``,
  ``_blackbody_spectrum_impl``
- ``janssen.cohere.modes``: ``_hermite_gaussian_modes_impl``,
  ``_gaussian_schell_model_modes_impl``, ``_eigenmode_decomposition_impl``
- ``janssen.cohere.sources``: ``_synchrotron_source_impl``,
  ``_multimode_fiber_output_impl``

See individual module docstrings for detailed parameter documentation.
"""

from .modes import (
    effective_mode_count,
    eigenmode_decomposition,
    gaussian_schell_model_modes,
    hermite_gaussian_modes,
    modes_from_wavefront,
    mutual_intensity_from_modes,
    thermal_mode_weights,
)
from .propagation import (
    apply_element_to_modes,
    intensity_from_modes,
    intensity_from_polychromatic,
    propagate_and_focus_modes,
    propagate_coherent_modes,
    propagate_polychromatic,
)
from .sources import (
    laser_with_mode_noise,
    led_source,
    multimode_fiber_output,
    synchrotron_source,
    thermal_source,
)
from .spatial import (
    coherence_width_from_source,
    complex_degree_of_coherence,
    gaussian_coherence_kernel,
    jinc_coherence_kernel,
    rectangular_coherence_kernel,
)
from .temporal import (
    bandwidth_from_coherence_length,
    blackbody_spectrum,
    coherence_length,
    coherence_time,
    gaussian_spectrum,
    lorentzian_spectrum,
    rectangular_spectrum,
    spectral_phase_from_dispersion,
)

__all__: list[str] = [
    "apply_element_to_modes",
    "bandwidth_from_coherence_length",
    "blackbody_spectrum",
    "coherence_length",
    "coherence_time",
    "coherence_width_from_source",
    "complex_degree_of_coherence",
    "effective_mode_count",
    "eigenmode_decomposition",
    "gaussian_coherence_kernel",
    "gaussian_schell_model_modes",
    "gaussian_spectrum",
    "hermite_gaussian_modes",
    "intensity_from_modes",
    "intensity_from_polychromatic",
    "jinc_coherence_kernel",
    "laser_with_mode_noise",
    "led_source",
    "lorentzian_spectrum",
    "modes_from_wavefront",
    "multimode_fiber_output",
    "mutual_intensity_from_modes",
    "propagate_and_focus_modes",
    "propagate_coherent_modes",
    "propagate_polychromatic",
    "rectangular_coherence_kernel",
    "rectangular_spectrum",
    "spectral_phase_from_dispersion",
    "synchrotron_source",
    "thermal_mode_weights",
    "thermal_source",
]
