thunder4d.pulse
Pulse initialisation. A pulse is built as
where \(E(\Omega)\) is a 1D complex spectral amplitude and \(U\) a spatial field evaluated separately at every frequency (so it can be chromatic) and normalised to unit power at each frequency. The spatially integrated spectrum is therefore exactly \(|E(\Omega)|^2\).
Spectral amplitude
All functions return a complex 1D array on grid.Omega (FFT order).
- thunder4d.pulse.gaussian_spectrum(grid, fwhm_fs=None, fwhm_nm=None, center_nm=None)[source]
Transform-limited Gaussian. Give either the intensity FWHM duration [fs] or the spectral FWHM [nm].
center_nmdefaults to \(\lambda_0\).
- thunder4d.pulse.measured_spectrum(grid, wavelength_nm, intensity, phase_rad=None, background=0.0)[source]
Spectrum measured against wavelength. Applies the Jacobian \(S_\omega = S_\lambda\,\lambda^2/2\pi c\), subtracts
background, clips negative values and interpolates onto the grid. An optional spectral phase (e.g. from a d-scan or FROG retrieval) can be given on the same wavelength axis; it is unwrapped before interpolation.
- thunder4d.pulse.spectrum_from_temporal_field(grid, t_fs, field)[source]
Complex temporal envelope (e.g. a retrieved pulse \(|E|e^{i\varphi}\)), relative to
grid.lambda0, interpolated on the time grid and transformed.
- thunder4d.pulse.add_spectral_phase(grid, E, gdd_fs2=0.0, tod_fs3=0.0, fod_fs4=0.0, delay_fs=0.0, phase=None)[source]
Returns \(E\,e^{i\varphi}\) with \(\varphi = \frac{\text{GDD}}{2}\Omega^2 + \frac{\text{TOD}}{6}\Omega^3 + \frac{\text{FOD}}{24}\Omega^4 + \text{delay}\cdot\Omega\) (\(\Omega\) in rad/fs).
phaseadds an arbitrary term: a callable of \(\Omega\) [rad/s] or an array ongrid.Omega.
Spatial profiles
- class thunder4d.pulse.Profile(func, radius, name)[source]
Callable
f(X, Y)returning a complex amplitude.radiusis used as the default Zernike pupil.
- thunder4d.pulse.super_gaussian(w, order=10)[source]
\(\exp[-(r/w)^\text{order}]\); order 2 is a Gaussian.
- thunder4d.pulse.top_hat(radius, order=24)[source]
Super-Gaussian with soft edges. Higher orders give harder edges and need a finer near-field sampling (e.g. order 100 with 384 points).
- thunder4d.pulse.knife_edge(profile, edge, axis='x', side='+', width=None)[source]
Clip any profile with a hard edge at
edge[m] alongaxis.- Parameters:
side (str) –
"+"blocks \(x > \text{edge}\),"-"blocks \(x < \text{edge}\),"both"keeps \(|x| < |\text{edge}|\) (slit)width (float) – 10–90 % width of a tanh edge [m];
Nonegives a step
Aberrations
- thunder4d.pulse.zernike_wavefront(X, Y, coeffs_waves, pupil_radius, lambda0)[source]
Wavefront error \(W\) [m] from RMS-normalised Zernike terms with coefficients in waves at \(\lambda_0\). In
Beamit is applied as the phase \((\omega/c)\,W\), an achromatic path error correct for every colour.Available terms:
piston,tilt_x,tilt_y,defocus,astig_0,astig_45,coma_x,coma_y,trefoil_0,trefoil_30,spherical.
Beam
- class thunder4d.pulse.Beam(profile, zernike=None, pupil_radius=None, spatial_chirp_mm_per_nm=(0, 0), angular_dispersion_urad_per_nm=(0, 0), pft_fs_per_mm=(0, 0), pfc_fs_per_mm2=0.0, radial_gdd_fs2_per_mm2=0.0, tilt_urad=(0, 0), offset_m=(0, 0), custom_phase=None)[source]
Spatial part of the pulse: profile + aberrations + space-time couplings. With \(\Delta\lambda = \lambda - \lambda_0\) and \(\Omega\) in rad/fs:
profilespatial amplitude (
Profile)zernikedict, e.g.
{"astig_0": 0.1, "coma_x": 0.05}(RMS waves at \(\lambda_0\))pupil_radiusZernike normalisation radius [m] (default
profile.radius)spatial_chirp_mm_per_nm(sx, sy): each colour shifted by \(s\,\Delta\lambda\)angular_dispersion_urad_per_nm(ax, ay): propagation angle \(a\,\Delta\lambda\)pft_fs_per_mm(px, py): pulse-front tilt, delay \(p\,x\)pfc_fs_per_mm2pulse-front curvature, delay \(a\,r^2\)
radial_gdd_fs2_per_mm2GDD varying as \(r^2\) (radial chirp)
tilt_uradpointing, same for all colours
offset_mtransverse position
custom_phasecallable
(X, Y, Omega) -> phase [rad]
Pulse
- class thunder4d.pulse.Pulse(grid, Aw)[source]
Field \(A(x, y, \Omega)\) of shape
grid.shape.Builders
- classmethod from_near_field(grid, E, beam, energy, nf_size, nf_points=256, focal_length=None, target_waist=None, verbose=True)[source]
Beam defined in the collimated near field, in the front focal plane of an achromatic lens; the cell centre is the focal plane. Exact per-colour Fraunhofer transform (spot size \(\propto\lambda\)): a top-hat gives an Airy pattern.
- Parameters:
nf_size (float) – full width of the near-field window [m]
nf_points (int) – near-field sampling
focal_length (float) – lens focal length [m]. If
None, it is chosen by golden-section search to maximise the overlap at \(\lambda_0\) with a Gaussian of waisttarget_waistand stored inpulse.focal_length.
A
UserWarningis emitted if less than 99 % of the focused power fits in the box, even withverbose=False.
- classmethod imaged_near_field(grid, E, beam, energy, cell, image_z=None, curvature_radius=None, verbose=True)[source]
Near field relay-imaged (same size for every colour) onto the plane at distance
image_zfrom the centre, on the input side (default: the mirror, \(d/2\)), with a spherical wavefront of radiuscurvature_radius(default \(R(z) = z + z_R^2/z\) of the linear mode, equal to the mirror ROC at the mirror plane). The field is then propagated back (linear, exact) to the cell centre.Tip
For a top-hat, a radius of 1.12 ×
w_mirrormaximises the overlap with the Gaussian mode (\(\eta = 0.815\)).Note
This builder works on a standard (fixed) grid. On a lens-frame grid use
imaged_near_field_lens(), which takes the same profile.
All builders normalise each colour to unit power before multiplying by \(E(\Omega)\), then scale the total to
energy[J].Methods and properties
- property energy
Energy [J].
- weighted_power()[source]
\(\int P^2 dt / \int P\,dt\) (= \(P_\text{peak}/\sqrt 2\) for a Gaussian).
- add_spectral_phase(**kw)[source]
Same arguments as
add_spectral_phase(), applied to every pixel.