solprop.processing.compression#

Compress the pulse of a saved run with linear optics, and say how well.

Each compressor searches the parameters of one kind of element of solprop.optics – a Taylor spectral phase, a thickness of material, reflections from a chirped mirror with an optional wedge – for the pulse of highest peak power, and returns a Compression holding what it found, the transfer function ready to hand to get_power() or time_1d(), and the pulse’s duration and peak power before, after, and at the transform limit.

The objective is

\[J = \frac{\max_t P_{\rm limit}(t)}{\max_t P(t)} \ge 1,\]

with \(P\) the instantaneous power summed over the selected modes and both polarisation components. \(J = 1\) is the transform limit and is the target. Every search is deterministic: SciPy’s bounded scalar minimiser after a coarse scan, or its differential evolution with a fixed seed. A search that ends on a bound or fails is reported in the result and logged; it never raises for that and never claims success.

Module Attributes

ModeChoice

Which modes a compressor works on: one, several, or None for all of them.

Functions

apply_transfer(transfer, output, *[, plane, ...])

Return the spectrum of a plane after a linear optical element.

compress_gratings([output, grid, spectrum, ...])

Find the normal grating separation that maximises selected pulse peak power.

compress_material([output, grid, spectrum, ...])

Find the thickness of a material that best compresses a pulse.

compress_mirrors([output, medium, ...])

Find the number of chirped-mirror reflections that best compresses a pulse.

compress_prisms([output, insertion_range, ...])

Tune second-prism insertion, separation, or both for maximum pulse peak power.

compress_taylor([output, grid, spectrum, ...])

Find the Taylor spectral phase that best compresses a pulse.

optimise_cep([output, grid, spectrum, ...])

Find the carrier-envelope phase that maximises the peak of the real field.

transform_limit([output, grid, spectrum, ...])

Return the duration and peak power of a plane's transform-limited pulse.

Classes

CepOptimum(phase, transfer, peak_field)

The carrier-envelope phase that maximises the peak of the real field.

Compression(kind, transfer, coefficients, ...)

What a compressor found.

class solprop.processing.compression.CepOptimum(phase, transfer, peak_field)[source]#

Bases: Displayed

The carrier-envelope phase that maximises the peak of the real field.

Attributes:
phasefloat

The phase in rad, in [-pi, pi], to add in the optics convention.

transferTransferFunction

TaylorPhase((phase,), wavelength).

peak_fieldfloat

The largest value of the real field after the shift, in the square root of W.

peak_field: float#
phase: float#
transfer: TransferFunction#
class solprop.processing.compression.Compression(kind, transfer, coefficients, thickness, reflections, fwhm_before, fwhm_after, fwhm_limit, peak_power_before, peak_power_after, peak_power_limit, quality, evaluations, success, message, table=())[source]#

Bases: Displayed

What a compressor found.

Attributes:
kindstr

"taylor", "material", "mirrors", "gratings" or "prisms".

transferTransferFunction

The optimal element, for get_power(..., transfer=...) and time_1d(..., transfer=...).

coefficientstuple of float

Taylor coefficients (0, 0, GDD, TOD, ...) in s**n; empty otherwise.

thicknessfloat

Material thickness in m; NaN when no material is involved.

reflectionsint

Number of mirror reflections; zero when no mirror is involved.

fwhm_beforefloat

Full width at half maximum of the power before compression, s.

fwhm_afterfloat

The same after it, s.

fwhm_limitfloat

The same at the transform limit, s.

peak_power_beforefloat

Peak power before compression, W.

peak_power_afterfloat

Peak power after it, W. A mirror’s reflectivity lowers it.

peak_power_limitfloat

Peak power at the transform limit, W.

qualityfloat

peak_power_after / peak_power_limit, at most one.

evaluationsint

Objective evaluations spent.

successbool

Whether the optimiser converged and the optimum lies inside its bounds.

messagestr

What the optimiser said, and which bound was reached if one was.

tabletuple of tuple

For mirrors: (reflections, thickness, quality) of every count tried.

coefficients: tuple[float, ...]#
evaluations: int#
fwhm_after: float#
fwhm_before: float#
fwhm_limit: float#
kind: str#
message: str#
peak_power_after: float#
peak_power_before: float#
peak_power_limit: float#
quality: float#
reflections: int#
success: bool#
table: tuple[tuple[int, float, float], ...] = ()#
thickness: float#
transfer: TransferFunction#
solprop.processing.compression.ModeChoice = int | collections.abc.Sequence[int] | None#

Which modes a compressor works on: one, several, or None for all of them.

solprop.processing.compression.apply_transfer(transfer, output, *, plane=-1, modes=None)[source]#

Return the spectrum of a plane after a linear optical element.

Parameters:
transferTransferFunction

The element, from solprop.optics.

outputsolprop.output.schema.Output

An opened output handler.

planeint, optional

Index of the plane, negative from the end.

modesint, sequence of int or None, optional

Which modes to return.

Returns:
omeganumpy.ndarray

Angular frequency of the active band, rad/s, ascending.

spectrumnumpy.ndarray

The spectral amplitude in the optics convention, in the square root of J/(rad/s), shape (n_modes, n_pol, n_x): the normalisation of get_spectrum() with no axis squeezed.

Examples

>>> import numpy as np
>>> from solprop.optics import TaylorPhase
>>> from solprop.processing._examples import example_output
>>> from solprop.processing.compression import apply_transfer
>>> element = TaylorPhase((0, 0, 1e-27), 800e-9)
>>> omega, spectrum = apply_transfer(element, example_output())
>>> spectrum.shape[-1] == omega.size
True
solprop.processing.compression.compress_gratings(output=None, *, pair, separation_range, grid=None, spectrum=None, plane=-1, modes=None, bandpass=None, oversampling=2)[source]#

Find the normal grating separation that maximises selected pulse peak power.

Scan and refine the explicit motor range with every other pair setting fixed. A fixed pair band and any additional bandpass select the pulse before all metrics. An optimum on a bound returns useful settings with success=False.

Parameters:
outputsolprop.output.schema.Output or None

Orthogonal modal output; alternative to grid and spectrum together.

pairGratingPair

Fixed grating density, angles, order, reference, pass count and working band.

separation_rangetuple of float

Finite, nonnegative, strictly ascending normal separations in m.

gridsolprop.grid.TimeGrid or None

Grid for a raw stored spectrum.

spectrumnumpy.ndarray or None

Internal-convention orthogonal power amplitudes, shape (n_omega,) or (n_modes, n_pol, n_omega). Coordinate power must equal physical power.

planeint, optional

Output plane index, negative from the end.

modesint, sequence of int or None, optional

Modes whose powers are summed; all by default, including both polarisations.

bandpasstuple of float, numpy.ndarray or None, optional

Additional fixed spectral window, as in the existing compressors.

oversamplingint, optional

Positive integer temporal resampling factor for every trial, two by default.

Returns:
Compression

Fitted GratingPair in transfer, selected-pulse metrics, evaluation count and boundary/convergence status.

Raises:
ProcessingError

If bounds, inputs or selection are invalid, the output is spatial or general modal, or no feasible setting is found by the scan.

MaterialError

If the optical or material inputs are invalid.

solprop.processing.compression.compress_material(output=None, *, medium, thickness_range, grid=None, spectrum=None, wavelength=None, pressure=None, plane=-1, modes=None, bandpass=None, oversampling=2)[source]#

Find the thickness of a material that best compresses a pulse.

Parameters:
outputsolprop.output.schema.Output or None

An opened output handler.

mediumGlassIndex, Gas, str or Mixture

What the material is; see solprop.optics.Material.

thickness_rangetuple of float

Smallest and largest thickness in m. Negative values remove material: a compressor built with too much glass in it is corrected by taking some out.

gridsolprop.grid.TimeGrid or None

With spectrum, the alternative to output.

spectrumnumpy.ndarray or None

A stored spectrum in the internal convention, as pulse.build(grid) returns.

wavelengthfloat or None, optional

Wavelength at which the material’s group delay is removed, m; the grid’s reference by default.

pressurefloat or None, optional

Pressure in bar, for a built-in gas.

planeint, optional

Index of the plane, negative from the end.

modesint, sequence of int or None, optional

Modes whose summed power is maximised.

bandpasstuple of float, numpy.ndarray or None, optional

Window applied to the spectrum first.

oversamplingint, optional

Time-domain resampling factor of every power evaluated.

Returns:
Compression

thickness holds the optimum. The range is scanned coarsely before the bounded refinement, so the global optimum is found where a blind Brent search would find the nearest one.

Raises:
solprop.exceptions.ProcessingError

If the thickness range is not ordered, or the input forms are mixed.

Examples

>>> from solprop.physdata import calcium_fluoride
>>> from solprop.processing._examples import example_output
>>> from solprop.processing.compression import compress_material
>>> window = calcium_fluoride(model="malitson_1963/sellmeier")
>>> found = compress_material(
...     example_output(), medium=window, thickness_range=(-0.05, 0.05))
>>> found.kind
'material'
solprop.processing.compression.compress_mirrors(output=None, *, mirror, max_reflections, medium=None, thickness_range=None, grid=None, spectrum=None, wavelength=None, plane=-1, modes=None, bandpass=None, oversampling=2)[source]#

Find the number of chirped-mirror reflections that best compresses a pulse.

Every count from zero to max_reflections is tried. With a medium, its thickness is optimised for each count – the mirrors-and-wedges compressor as it stands on a table, where the mirrors over-compensate in whole bounces and glass trims the rest.

Parameters:
outputsolprop.output.schema.Output or None

An opened output handler.

mirrorChirpedMirror or str

The mirror, or the name of a shipped data set (solprop.optics.chirped_mirrors()).

max_reflectionsint

Largest number of reflections tried, at least 1.

mediumGlassIndex, Gas, str, Mixture or None, optional

A material whose thickness is tuned for each count.

thickness_rangetuple of float or None, optional

Its smallest and largest thickness in m; required with medium.

gridsolprop.grid.TimeGrid or None

With spectrum, the alternative to output.

spectrumnumpy.ndarray or None

A stored spectrum in the internal convention, as pulse.build(grid) returns.

wavelengthfloat or None, optional

Wavelength at which the material’s group delay is removed, m.

planeint, optional

Index of the plane, negative from the end.

modesint, sequence of int or None, optional

Modes whose summed power is maximised.

bandpasstuple of float, numpy.ndarray or None, optional

Window applied to the spectrum first.

oversamplingint, optional

Time-domain resampling factor of every power evaluated.

Returns:
Compression

reflections and thickness hold the best pair and table every count tried. quality includes the mirror’s reflectivity and the part of the spectrum outside its band, both of which lower the peak power.

Raises:
solprop.exceptions.ProcessingError

If max_reflections is below one, a medium is given without a range or a range without a medium, or the input forms are mixed.

Examples

>>> from solprop.processing._examples import example_output
>>> from solprop.processing.compression import compress_mirrors
>>> found = compress_mirrors(example_output(), mirror="PC70", max_reflections=4)
>>> 0 <= found.reflections <= 4
True
solprop.processing.compression.compress_prisms(output=None, *, pair, insertion_range=None, separation_range=None, grid=None, spectrum=None, plane=-1, modes=None, bandpass=None, oversampling=2)[source]#

Tune second-prism insertion, separation, or both for maximum pulse peak power.

Keep the first prism, incidence, apex angle, material, reference, pass count and working band fixed. Omit a coordinate range to hold that coordinate fixed. The search is deterministic; an interior result is not a global-optimality certificate. Narrow spectra may not uniquely determine both coordinates.

Parameters:
outputsolprop.output.schema.Output or None

Orthogonal modal output; alternative to grid and spectrum together.

pairPrismPair

Initial feasible pair and the settings held fixed during the search.

insertion_rangetuple of float or None, optional

Strictly ascending finite nonnegative H bounds in m, perpendicular to the base.

separation_rangetuple of float or None, optional

Strictly ascending finite nonnegative R bounds in m, along the reference ray. At least one of the two ranges is required.

gridsolprop.grid.TimeGrid or None

Grid for a raw stored spectrum.

spectrumnumpy.ndarray or None

Internal-convention orthogonal power amplitudes, shape (n_omega,) or (n_modes, n_pol, n_omega). Coordinate power must equal physical power.

planeint, optional

Output plane index, negative from the end.

modesint, sequence of int or None, optional

Modes whose powers are summed; all by default, including both polarisations.

bandpasstuple of float, numpy.ndarray or None, optional

Additional fixed spectral window, applied before all reported pulse metrics.

oversamplingint, optional

Positive integer temporal resampling factor for every trial, two by default.

Returns:
Compression

Fitted PrismPair in transfer and selected-pulse metrics. A best setting on a bound has success=False. Geometry failures count as infeasible trials; the selected band never changes with the trial.

Raises:
ProcessingError

If no range is supplied, bounds or inputs are invalid, the output is spatial or general modal, selection is empty, or no feasible setting is found.

MaterialError

If an optical input or material model is invalid; material errors propagate.

solprop.processing.compression.compress_taylor(output=None, *, grid=None, spectrum=None, order=2, wavelength=None, plane=-1, modes=None, bandpass=None, bound_factor=8.0, oversampling=2, seed=0)[source]#

Find the Taylor spectral phase that best compresses a pulse.

Orders two to order are searched together; the carrier-envelope phase and the group delay are held at zero, since neither changes the peak power. The bounds are heuristic: with phi2 = tau_lim sqrt(abs(tau**2 - tau_lim**2)) the chirp a Gaussian of the measured and transform-limited widths would carry, order n is searched within plus and minus bound_factor * phi2**(n/2). The search starts from the better of -phi2 and +phi2.

Parameters:
outputsolprop.output.schema.Output or None

An opened output handler.

gridsolprop.grid.TimeGrid or None

With spectrum, the alternative to output.

spectrumnumpy.ndarray or None

A stored spectrum in the internal convention, as pulse.build(grid) returns.

orderint, optional

Highest order searched, at least 2. Two is a one-parameter search; above it the search is SciPy’s differential evolution, seeded, then polished.

wavelengthfloat or None, optional

Wavelength the phase is expanded about, m; the grid’s reference by default.

planeint, optional

Index of the plane, negative from the end.

modesint, sequence of int or None, optional

Modes whose summed power is maximised.

bandpasstuple of float, numpy.ndarray or None, optional

Window applied to the spectrum first.

bound_factorfloat, optional

Width of the search box in units of the Gaussian estimate, > 0.

oversamplingint, optional

Time-domain resampling factor of every power evaluated.

seedint, optional

Seed of the differential evolution; the same seed gives the same result.

Returns:
Compression

coefficients is (0, 0, GDD, ...), ready for TaylorPhase and for the phases= keyword of a run.

Raises:
solprop.exceptions.ProcessingError

If order is below two, bound_factor is not positive, or the input forms are mixed.

Examples

>>> from solprop.processing._examples import example_output
>>> from solprop.processing.compression import compress_taylor
>>> found = compress_taylor(example_output())
>>> found.success and found.quality > 0.999
True
solprop.processing.compression.optimise_cep(output=None, *, grid=None, spectrum=None, plane=-1, mode=0, oversampling=4)[source]#

Find the carrier-envelope phase that maximises the peak of the real field.

The phase is periodic, so the circle is scanned and the best sample refined in its own neighbourhood; Brent’s method run across [-pi, pi] could not see an optimum at the ends.

Both grids are served, an envelope’s carrier being restored first. The phase returned is the optics-convention constant to add; it is the negative of the phase to add to an FFT-convention spectrum.

Parameters:
outputsolprop.output.schema.Output or None

An opened output handler.

gridsolprop.grid.TimeGrid or None

With spectrum, the alternative to output.

spectrumnumpy.ndarray or None

A stored spectrum in the internal convention, as pulse.build(grid) returns.

planeint, optional

Index of the plane, negative from the end.

modeint, optional

The one mode whose field is optimised: modal fields do not add away from a point in space. The first polarisation component is used.

oversamplingint, optional

Time-domain resampling factor; the field’s peak lies between samples.

Returns:
CepOptimum

The phase to add, the element that adds it, and the peak field reached.

Examples

>>> from solprop.processing._examples import example_output
>>> from solprop.processing.compression import optimise_cep
>>> found = optimise_cep(example_output("field"))
>>> -3.1416 < found.phase <= 3.1416
True
solprop.processing.compression.transform_limit(output=None, *, grid=None, spectrum=None, plane=-1, modes=None, bandpass=None, oversampling=4)[source]#

Return the duration and peak power of a plane’s transform-limited pulse.

Parameters:
outputsolprop.output.schema.Output or None

An opened output handler.

gridsolprop.grid.TimeGrid or None

With spectrum, the alternative to output.

spectrumnumpy.ndarray or None

A stored spectrum in the internal convention, as pulse.build(grid) returns.

planeint, optional

Index of the plane, negative from the end.

modesint, sequence of int or None, optional

Modes whose summed power is measured.

bandpasstuple of float, numpy.ndarray or None, optional

Window applied to the spectrum first.

oversamplingint, optional

Time-domain resampling factor.

Returns:
fwhmfloat

Full width at half maximum of the transform-limited power, s.

peak_powerfloat

Its peak power, W.

Examples

>>> from solprop.processing._examples import example_output
>>> from solprop.processing.compression import transform_limit
>>> fwhm, peak = transform_limit(example_output())
>>> fwhm > 0.0 and peak > 0.0
True