Skip to content

Noise sources

Quantised shot-noise / one-photon-per-mode initial conditions and vacuum segments. Docstrings are the source of truth, rendered with mkdocstrings (numpydoc style).

photonics_helper.noise

Stochastic noise sources for GNLSE / NLSE simulations.

Deterministic split-step solvers cannot reproduce the noise-driven physics of spontaneous modulation instability, supercontinuum coherence, or Raman-induced spectral fluctuations. This module provides reproducible (seedable) stochastic sources that can be added to a :class:~photonics_helper.pulse.Wave.

Two conventions are supported:

  • Amplitude contrast (:func:complex_gaussian_noise / :func:add_noise) — time-domain complex Gaussian noise with a standard deviation fixed as a fraction of the field amplitude. This is the natural way to write "a CW with < 5 % intensity contrast".
  • Spectral level (:func:ase_noise_field / :func:add_ase_noise) — flat amplified-spontaneous-emission (ASE) background a given number of dB below the pump, with random spectral phase. This mirrors the noise model used in supercontinuum and MI experiments (e.g. Närhi et al. 2016, whose ASE background is -50 dB relative to the pump).

.. note::

Fields are built with :meth:~photonics_helper.pulse.TemporalGrid.fft / :meth:~photonics_helper.pulse.TemporalGrid.ifft, which are a scaled pair (fft(A) = raw_fft(A)·dt, ifft(A_w) = raw_ifft(A_w)/dt). A spectrum constructed with arbitrary units and mapped back with grid.ifft is therefore scaled by 1/dt. :func:ase_noise_field handles this internally; if you build a spectrum yourself, carry the dt factor (or construct the field in the time domain with :func:complex_gaussian_noise).

References
  • G. P. Agrawal, Nonlinear Fiber Optics, 5th ed., Sec. 5.2 (noise and MI).
  • J. M. Dudley, G. Genty, S. Coen, Rev. Mod. Phys. 78, 1135 (2006), Eq. 5.
  • M. Närhi et al., Nat. Commun. 7, 13675 (2016) (ASE seeding).

complex_gaussian_noise

complex_gaussian_noise(grid: TemporalGrid, rms: float, *, rng: Generator | None = None, seed: int | None = None, remove_mean: bool = True) -> NDArray

White complex-Gaussian noise with standard deviation rms.

The noise is generated in the time domain (so no FFT scaling enters) and is unit-variance per quadrature: Re(n) and Im(n) each have rms rms / sqrt(2).

Parameters:

Name Type Description Default
grid TemporalGrid — defines the number of samples ``N``.
required
rms float — target RMS amplitude in the same units as the envelope field

(i.e. sqrt(W) for power-based Wave objects).

required
rng optional generator / seed for reproducibility.
None
seed optional generator / seed for reproducibility.
None
remove_mean bool — subtract the mean so no DC pump is added.
True

Returns:

Type Description
ndarray — complex noise samples, shape ``(grid.N,)``.

add_noise

add_noise(wave: Wave, rms_relative: float, *, rng: Generator | None = None, seed: int | None = None, remove_mean: bool = True) -> Wave

Return a copy of wave with additive complex-Gaussian noise.

The noise RMS is rms_relative * sqrt(peak_power), i.e. rms_relative is the fractional amplitude contrast relative to the peak of the field. For a CW background of power P0 and A = sqrt(P0)(1 + n), an intensity contrast of ~5 % corresponds to rms_relative ≈ 0.025.

The input wave is not modified.

ase_noise_field

ase_noise_field(grid: TemporalGrid, reference_power: float, level_dB: float, *, rng: Generator | None = None, seed: int | None = None) -> NDArray

Flat amplified-spontaneous-emission background with random phase.

Builds a spectral field whose per-bin amplitude is level_dB below the DC line of a continuous wave of power reference_power, then returns the corresponding time-domain field using the grid's (scaled) inverse FFT. The DC bin is removed so the returned field carries no net pump.

Parameters:

Name Type Description Default
grid TemporalGrid
required
reference_power float — CW power in W whose DC line sets the reference.
required
level_dB float — noise level relative to that line (e.g. ``-50``).
required
rng optional generator / seed.
None
seed optional generator / seed.
None

Returns:

Type Description
ndarray — complex time-domain noise field, shape ``(grid.N,)``.

add_ase_noise

add_ase_noise(wave: Wave, level_dB: float, *, reference_power: float | None = None, rng: Generator | None = None, seed: int | None = None) -> Wave

Return a copy of wave with an ASE background added.

Parameters:

Name Type Description Default
wave Wave — input field.
required
level_dB float — background level relative to the pump DC line.
required
reference_power float, optional — CW reference power; defaults to the

peak power of wave.

None
rng optional generator / seed.
None
seed optional generator / seed.
None
Notes

The input wave is not modified.

raman_noise_field

raman_noise_field(grid: TemporalGrid, h_R_fft: NDArray, seed: int | None = None, *, omega0: float, temperature: float = 300.0, rng: Generator | None = None) -> NDArray

Spontaneous-Raman noise field for one GNLSE step (Dudley Eq. 5 Γ_R).

Semi-classical one-photon-per-mode seed: each frequency bin gets a complex Gaussian with variance σ² = (ℏω₀/2)·Im[h̃_R]·(n_th+1)·(2π/Δω), shaped by the (positive) Raman gain Im[h̃_R] — bins with Im[h̃_R] ≤ 0 (anti-Stokes side) carry no spontaneous Stokes seed. n_th is the thermal phonon occupation 1/(exp(ħΩ_R/k_B T) − 1) (Boer, Quantum Optics / Shen, The Principles of Nonlinear Optics, Ch. 7); n_th + 1 = 1/(1 − exp(−ħΩ_R/k_B T)) is the spontaneous + stimulated emission factor of the quantum Langevin treatment (Drummond & Hardman, Eur. Phys. J. D 21, 49 (2003)).

Note on n_th: at silica's 440 cm⁻¹ Raman shift the energy is ħΩ_R/k_B = 96 K, so at 300 K n_th = 0.138 and n_th + 1 = 1.138; at 600 K it is 0.534 / 1.534. The Bose factor is a 35 % correction at room temperature — not a negligible one. The semi-classical n_th → 0 limit needs T ≫ 96 K. The factor is built from grid.w in rad/s, while Raman shifts are quoted in Hz or cm⁻¹ — evaluating it at 13.2 THz instead of 2π × 13.2 THz misprices the floor by 2.8× in the variance ratio. The factor is applied per bin at each bin's |Ω|, so it runs from ~625 in the first bin down to ~1 far out, and the product Im[h̃_R]·(n_th+1) — not either factor alone — is what a bin receives. The 2π/Δω factor is the grid's FFT-pair normalization (fft(A) = raw_fft(A)·dt, ifft(A_w) = raw_ifft(A_w)/dt): it makes the time-domain noise variance ℏω₀/(2·dt)·Im[h̃_R], i.e. PSD ℏω₀/2 per unit angular frequency. The caller scales the returned field by sqrt(dz) (Langevin δ(z−z′) discretization) and adds it to the envelope once per step.

Parameters:

Name Type Description Default
grid TemporalGrid — defines ``N``, ``dt`` and the ``fft``/``ifft`` pair.
required
h_R_fft array — FFT of the Raman response on the grid (same ordering as

grid.fft output), shape (grid.N,).

required
seed int, optional — reproducibility seed (mutually exclusive with rng).
None
omega0 float — carrier angular frequency in rad/s (keyword-only; sets

the photon energy ℏω₀).

required
temperature float, optional — lattice/medium temperature in kelvin

(keyword-only; default 300). Sets the thermal factor n_th + 1.

300.0
rng Generator, optional — externally threaded generator for per-step

draws (mutually exclusive with seed).

None

Returns:

Type Description
ndarray — complex time-domain noise field, shape ``(grid.N,)``.

coherence_g12

coherence_g12(runs: NDArray) -> NDArray

First-order ensemble coherence g₁₂ over stochastic realizations.

implements the Dudley coherence formalism (Dudley, Genty & Coen, Rev. Mod. Phys. 78, 1135 (2006), Eq. (23)): for each frequency bin,

g₁₂ = |⟨E_m* · E_n⟩_{m≠n}| / ⟨|E|²⟩,

where the pair average is taken over all distinct realization pairs and the modulus of the complex pair average is used (not its real part), matching the convention of Dudley Fig. 19. Identical runs give g₁₂ = 1; partially decohered ensembles give g₁₂ < 1.

Parameters:

Name Type Description Default
runs array — complex spectra, shape ``(n_runs, n_bins)`` with

n_runs >= 2.

required

Returns:

Type Description
ndarray — ``g₁₂`` per bin, shape ``(n_bins,)``, values in ``[0, 1]``.