Skip to content

Pulse envelopes, grids and trains

Wave/Envelope construction, temporal grids, pulse trains and hygiene helpers. Docstrings are the source of truth, rendered with mkdocstrings (numpydoc style).

photonics_helper.pulse

Pulse envelopes, temporal grids, and pulse trains.

Envelope-field convention

An :class:Envelope describes a normalized complex envelope A(t). The absolute scale of A is whatever peak_amplitude the user chose, so Wave.envelope_intensity (|A|²) and the metrics derived from it (pulse_energy, peak_power) are in normalized envelope units, not W/m², joules, or watts, unless a physical effective mode area is attached with :meth:Wave.with_effective_area. Without one, peak_power/pulse_energy emit a one-time :class:UserWarning and the visualization summary labels the value as normalized. With an effective area A_eff the library uses P = ½·n·c·ε₀·A_eff·|A|² (see :class:~photonics_helper.base.PeakPower).

logger module-attribute

logger = logging.getLogger(__name__)

SHAPE_FACTORS module-attribute

SHAPE_FACTORS: dict[str, float] = {'gaussian': 2 * sqrt(log(2)), 'sech': 2 * acosh(sqrt(2)), 'lorentzian': 2 * sqrt(sqrt(2) - 1), 'rectangular': 2.0}

Envelope

shape instance-attribute

shape: Literal['gaussian', 'sech', 'lorentzian', 'rectangular', 'super-gaussian', 'triangular', 'parabolic', 'cosine', 'exponential', 'gauss-hermite', 'airy', 'custom']

peak_amplitude instance-attribute

peak_amplitude: float

pulse_width instance-attribute

pulse_width: Time

chirp class-attribute instance-attribute

chirp: float = 0.0

super_gaussian_order class-attribute instance-attribute

super_gaussian_order: int = 2

beam_waist class-attribute instance-attribute

beam_waist: Time | None = None

hg_mode class-attribute instance-attribute

hg_mode: int = 0

func class-attribute instance-attribute

func: Callable | None = None

phase_func class-attribute instance-attribute

phase_func: Callable | None = None

fwhm property

fwhm: Time

Full width at half maximum of the envelope (s).

from_fwhm classmethod

from_fwhm(shape: Literal['gaussian', 'sech', 'lorentzian', 'rectangular', 'super-gaussian', 'triangular', 'cosine', 'exponential', 'airy'], peak_amplitude: float, fwhm: Time) -> Self

Construct an Envelope from a desired full-width at half-maximum.

field

field(t: NDArray) -> NDArray

Returns complex envelope A(t).

intensity

intensity(t: NDArray) -> NDArray

Optical intensity |A|² (W).

calc_width

calc_width(level: float = 0.5) -> Time

Calculate the pulse width using linear interpolation at crossing points.

Finds the width between the widest pair of crossings where the intensity envelope drops to level * peak_intensity.

Parameters:

Name Type Description Default
level float — fraction of peak to calculate width at.

0.5 gives FWHM, 1/e ≈ 0.368, 1/e² ≈ 0.135. Default 0.5.

0.5

Returns:

Name Type Description
width Time — pulse width in seconds (use ``.as_ps`` etc. for display units).

apply_dispersion

apply_dispersion(GDD: float = 0.0, TOD: float = 0.0, FOD: float = 0.0, N: int = 2 ** 12) -> Envelope

Apply group-delay dispersion (GDD), TOD, FOD in the frequency domain.

Multiplies the spectral amplitude by exp(−i·φ(ω)) where φ(ω) = ½·GDD·Ω² + ⅙·TOD·Ω³ + ¹⁄₂₄·FOD·Ω⁴ and Ω is the offset from the central angular frequency. Uses the same sign as :meth:~photonics_helper.gnlse.SplitStepEngine._linear_step.

Parameters:

Name Type Description Default
GDD float — group-delay dispersion (ps²). Default 0.
0.0
TOD float — third-order dispersion (ps³). Default 0.
0.0
FOD float — fourth-order dispersion (ps⁴). Default 0.
0.0
N int — number of points for the internal grid (default 2¹²).
2 ** 12

Returns:

Type Description
Envelope — a new Envelope with the dispersion-applied field.
Notes

The returned envelope has shape="custom" and owns the numerical field computed on an internal grid sized to contain the broadened pulse (estimated from the input bandwidth and the requested GDD, TOD, FOD; N controls the sampling resolution). Requests outside that window are clamped to the edge values. The analytic parameters of the input envelope no longer describe the broadened pulse, so peak_amplitude and pulse_width are re-measured numerically and the chirp is reset to zero (any input chirp is already baked into the dispersed field).

visualize_2d

visualize_2d(backend: Literal['plotly', 'matplotlib'] = 'plotly', N: int = 2 ** 12, show_phase: bool = True, show_fwhm: bool = True, figsize: tuple[float, float] | None = None, title: str | None = None, theme: Literal['light', 'dark'] = 'light')

Plot temporal intensity, spectral intensity, and phase.

Parameters:

Name Type Description Default
backend "plotly" or "matplotlib" (default "plotly")
'plotly'
N number of time points (default 2^12)
2 ** 12
show_phase show instantaneous phase overlay (default True)
True
show_fwhm show FWHM markers (default True)
True
figsize figure size for matplotlib backend (default None)
None
title optional title override (default uses shape name)
None
theme "light" or "dark" (default "light")
'light'

visualize_3d

visualize_3d(N: int = 2 ** 12, title: str | None = None, theme: Literal['light', 'dark'] = 'light')

Plot 3D spectrogram (time vs frequency vs intensity).

Shows how the frequency content evolves over time. Useful for visualizing chirp and time-frequency structure.

Parameters:

Name Type Description Default
N number of time points (default 2^12)
2 ** 12
title optional title override
None
theme "light" or "dark" (default "light")
'light'

from_parabolic_asymptotic classmethod

from_parabolic_asymptotic(peak_amplitude: float, pulse_width: Time, gain: float, length: float, chirp: float = 0.0) -> Self

Construct a parabolic pulse with asymptotic amplifier chirp.

The chirp coefficient follows the asymptotic parabolic solution: α ≈ 0.2726 × z × gain.

Parameters:

Name Type Description Default
peak_amplitude A₀
required
pulse_width T₀
required
gain Small-signal gain coefficient (unitless or per-length as used in the amplifier model)
required
length Propagation length in the amplifier
required
chirp Additional chirp on top of the asymptotic value (default 0)
0.0

Wave

grid instance-attribute

grid: TemporalGrid

envelope instance-attribute

envelope: Envelope

central_wavelength instance-attribute

central_wavelength: Wavelength

refractive_index class-attribute instance-attribute

refractive_index: float = 1.0

repetition_rate class-attribute instance-attribute

repetition_rate: Frequency | None = None

central_frequency cached property

central_frequency: float

Carrier angular frequency at the central wavelength (rad/s).

wavelength_nm property

wavelength_nm: NDArray

Absolute wavelength grid (nm) for each frequency sample on grid.w.

electric_field property

electric_field

Physical electric field (V/m) reconstructed from the envelope.

envelope_intensity property

envelope_intensity

Intensity of the envelope |A|² (W).

envelope_field property

envelope_field

Complex envelope field (√W).

spectrum cached property

spectrum: NDArray

Frequency-domain envelope obtained via the configured FFT backend.

instantaneous_intensity

instantaneous_intensity()

Instantaneous intensity in physical units (W).

pulse_energy

pulse_energy() -> float

Pulse energy (or normalized integral ∫|A|²dt).

Returns:

Type Description
float

Joules when an effective mode area has been attached with :meth:with_effective_area; otherwise the normalized integral ∫|A|²dt in field-units²·seconds and a one-time :class:UserWarning is emitted.

calc_width

calc_width(level: float = 0.5) -> Time

Calculate the pulse width using linear interpolation at crossing points.

Finds the width between the widest pair of crossings where the intensity envelope drops to level * peak_intensity.

Parameters:

Name Type Description Default
level float — fraction of peak to calculate width at.

0.5 gives FWHM, 1/e ≈ 0.368, 1/e² ≈ 0.135. Default 0.5.

0.5

Returns:

Name Type Description
width Time — pulse width in seconds (use ``.as_ps`` etc. for display units).

peak_power

peak_power() -> float

Peak power (or normalized peak intensity max|A|²).

Returns:

Type Description
float

Watts when an effective mode area has been attached with :meth:with_effective_area (using P = ½·n·c·ε₀·A_eff·|A|²); otherwise max|A|² in normalized envelope units and a one-time :class:UserWarning is emitted.

**Unit hazard:** the return value changes by many orders of
magnitude depending on whether ``A_eff`` is attached. For a field
built as ``sqrt(5.0)``, ``peak_power()`` returns ``5.0`` without an
effective area and ``5.3e-13`` with one — the same field, 13 orders
of magnitude apart. ``add_ase_noise`` defaults ``reference_power``
to ``wave.peak_power()``, so passing a wave with an effective area
to one without silently changes the ASE level by 13 orders of
magnitude. Always check which convention you are in before using
the result.

with_effective_area

with_effective_area(A_eff: Area) -> Self

Return a copy of this Wave bound to a physical mode area.

Once an effective area is attached, :meth:peak_power and :meth:pulse_energy return physical watts and joules via the intensity relation P = ½·n·c·ε₀·A_eff·|A|² (with :attr:refractive_index as n). Without one they stay in normalized envelope units.

Parameters:

Name Type Description Default
A_eff Area — effective mode area (e.g. ``Area(80, "um^2")``).
required

Returns:

Type Description
Wave — a copy sharing this wave's field with the area attached.

average_power

average_power(repetition_rate: Frequency) -> float

Average power = pulse energy × repetition_rate.

Parameters:

Name Type Description Default
repetition_rate Hz
required

from_pulse_train classmethod

from_pulse_train(envelope: Envelope, central_wavelength: Wavelength, grid: TemporalGrid, repetition_rate: Frequency, n_pulses: int = 10, refractive_index: float = 1.0) -> Self

Construct a pulse train Wave from a single-envelope shape.

Parameters:

Name Type Description Default
envelope The single-pulse envelope shape to repeat
required
central_wavelength Central wavelength of the carrier
required
grid TemporalGrid covering the full window (all pulses + padding)
required
repetition_rate Hz — spacing between consecutive pulses
required
n_pulses number of pulses (default 10)
10
refractive_index background refractive index (default 1.0)
1.0

with_field

with_field(field: NDArray) -> Self

Return this Wave with an explicit envelope-field override.

Used by :meth:from_pulse_train for precomputed multi-pulse fields.

time_bandwidth_product

time_bandwidth_product() -> float

RMS time-bandwidth product. ≈0.707 for transform-limited Gaussian.

visualize

visualize(t_unit: str = 's', w_unit: str = 'rad/s', t_scale: float = 1.0, w_scale: float = 1.0, show_electric_field: bool = False, show_phase: bool = True, show_spectrogram: bool = False, figsize: tuple[float, float] | None = None, save_path: str | None = None)

Plot a comprehensive overview of the pulse.

Parameters:

Name Type Description Default
t_unit label for the time axis (e.g. "ps", "fs")
's'
w_unit label for the frequency axis (e.g. "THz", "rad/ps")
'rad/s'
t_scale multiply grid.t by this before plotting (e.g. 1e12 for ps)
1.0
w_scale multiply grid.w by this before plotting
1.0
show_electric_field add a panel with the real electric field
False
show_phase overlay instantaneous phase on the temporal panel
True
show_spectrogram add a spectrogram (STFT) panel
False
figsize passed to plt.figure()
None
save_path if given, save figure to this path
None

FROGTrace

Represents a FROG trace I(ω, τ).

Attributes:

Name Type Description
trace 2D array of shape (N_omega, N_tau)

The FROG trace (normalized if normalize=True in from_field).

unnormalized_trace 2D array of shape (N_omega, N_tau)

The raw trace before normalization (used for retrieval).

omega angular frequency axis (rad/s), centered at 0.
tau delay axis (s), centered at 0.
dt time step (s).
dw frequency step (rad/s).
field reconstructed field E(t) (set after retrieval).

trace instance-attribute

trace: NDArray

unnormalized_trace instance-attribute

unnormalized_trace: NDArray

omega instance-attribute

omega: NDArray

tau instance-attribute

tau: NDArray

dt instance-attribute

dt: float

dw instance-attribute

dw: float

field class-attribute instance-attribute

field: NDArray | None = None

from_field classmethod

from_field(E_field: NDArray, dt: float, normalize: bool = True) -> FROGTrace

Generate a FROG trace from a complex electric field E(t).

Parameters:

Name Type Description Default
E_field complex 1D array, the electric field on a uniform time grid.
required
dt time step in seconds.
required
normalize normalize trace to [0, 1] (default True).
True

Returns:

Type Description
FROGTrace

visualize

visualize(retrieved: FROGTrace | None = None, figsize: tuple[float, float] | None = None, save_path: str | None = None)

Plot the FROG trace and optionally the retrieved pulse.

Parameters:

Name Type Description Default
retrieved optional FROGTrace with .field set (from retrieve()).
None
figsize figure size.
None
save_path if given, save figure to this path.
None

generate_trace

generate_trace(E_field: NDArray, dt: float, normalize: bool = True) -> FROGTrace

Generate a SHG-FROG trace from an electric field.

Parameters:

Name Type Description Default
E_field complex 1D array, electric field on uniform time grid.
required
dt time step in seconds.
required
normalize normalize trace to [0, 1] (default True).
True

Returns:

Type Description
FROGTrace

fidelity

fidelity(trace1: FROGTrace, trace2: FROGTrace) -> float

Compute FROG fidelity between two traces.

fidelity = 1 - ||I1 - I2|| / ||I1||

Returns:

Type Description
float in [0, 1], where 1 = perfect match.

retrieve

retrieve(trace: FROGTrace, max_iter: int = 100, tol: float = 0.0001, verbose: bool = True, *, seed: int | None = 0, n_restarts: int = 5) -> FROGTrace

Retrieve the electric field E(t) from a FROG trace using PCGPA.

Implements the generalized-projections / PCGPA material-constraint step: after replacing the trace magnitude with the measurement (keeping the phase), the new field is the least-squares solution

E_new(t) = Σ_τ G'(t, τ)·E*(t+τ) / Σ_τ |E(t+τ)|²

for the bilinear SHG signal G(t, τ) = E(t)E(t+τ). Retrieval is initialized from the dominant SVD component of the trace plus one or more random complex fields (seeded for reproducibility); the lowest-error result is returned.

Parameters:

Name Type Description Default
trace FROGTrace — the measured (or generated) trace.
required
max_iter maximum iterations per restart (default 100).
100
tol convergence tolerance on the change in the normalized FROG error

(default 1e-4).

0.0001
verbose print iteration progress (default True).
True
seed RNG seed for the random initialization (default 0). ``None`` uses

fresh entropy.

0
n_restarts number of random restarts (default 5). Together with the

SVD initialization these are ranked by FROG error and the lowest-error result is returned.

5

Returns:

Type Description
FROGTrace with ``.field`` set to the retrieved E(t).
Notes

SHG-FROG cannot distinguish E(t) from E*(−t) or a global phase, so compare retrieved and reference fields up to those symmetries (comparing traces is ambiguity-free).