plesty.fss

Fine-structure analyzer module: exciton fine-structure splitting from polarization sweeps.

Submodules

Attributes

HARMONICS

Classes

FineStructure

Fine-structure splitting of every line in a polarization sweep.

FineStructureData

Fine structure of each fitted line, one entry per line.

SineFit

Result of fit_sine(), each value with its one-sigma error.

Functions

fit_sine(→ SineFit)

Fit mean + A·cos(k·(θ − axis)) to positions over rotator angles.

load_config(→ dict[str, Any])

Load the packaged module configuration (constants and running defaults).

Package Contents

class plesty.fss.FineStructure(angle: str = 'hwp_deg', rotator: str = 'hwp', fit_options: Mapping[str, Any] | None = None)

Bases: plesty.lib.analyzer.Analyzer

Fine-structure splitting of every line in a polarization sweep.

The spectrum must carry the rotator angle of each frame as a coordinate (SpectrumData.from_run(run, coordinates=("hwp_deg",))). Frames whose line fit fails are left out of that line’s sweep fit.

The splitting is the peak-to-peak amplitude of the oscillation of each line’s fitted position with the rotator angle, divided by the rotator’s contrast (CONTRAST: 1 for a half-wave plate or a polarizer, ½ for a quarter-wave plate). That measures a doublet only while its two orthogonally polarized components are closer than the linewidth and appear as one line. A line whose position oscillates by as much as its linewidth or more is marked fss_valid = 0 and named in a warning: its fit followed a different line from frame to frame, and its fss is not a splitting.

Outputs:

  • fine_structure — FineStructureData, one entry per line: the splitting in µeV and as a wavelength, the polarization axis and the mean position, each ± σ, with the linewidth and the fss_valid flag.

  • fit — the SpectrumFitData of the line fits.

  • curve — the fitted position at each fitted frame’s angle, shaped like fit["center"] so the two plot against each other directly.

Validate and store the sweep parameters.

Parameters:
  • angle (str) – Name of the spectrum coordinate holding the rotator angle.

  • rotator (str) – "hwp" (half-wave plate, 90° period), "polarizer" (180° period), or "qwp" (quarter-wave plate in front of a fixed polarizer, 90° period at half the contrast, so the splitting is twice the oscillation).

  • fit_options (Mapping[str, Any] | None) – Keyword arguments of SpectrumFit (peaks, model, window, center_tolerance, …). Without order, frames are fitted in angle order.

Raises:

ValueError – If the rotator is unknown or a fit option is invalid.

input_schema

name → schema entry.

Type:

Declared inputs of analyze()

output_schema

name → schema entry.

Type:

Declared outputs of analyze()

analyze(spectrum: plesty.lib.data.SpectrumData) → dict[str, Any]

Fit every line in every frame, then each line’s centre against the angle.

Parameters:

spectrum (plesty.lib.data.SpectrumData) – The polarization sweep.

Returns:

fine_structure, fit and curve, see the class description.

Raises:

ValueError – If the angle coordinate is missing or not an angle, or the wavelength unit is not a length.

Return type:

dict[str, Any]

report(outputs: Mapping[str, Any]) → plesty.lib.report.Report

Say what the sweep found: a sentence, a table of the lines, and the sweep drawn.

See plesty.fss.report. Only fine_structure and fit are read, so a report can be rebuilt from the two saved outputs.

Parameters:

outputs (Mapping[str, Any]) – What calling the analyzer returned, or at least its fine_structure and fit.

Returns:

The report, stamped with this analyzer’s provenance.

Return type:

plesty.lib.report.Report

class plesty.fss.FineStructureData(values: Mapping[str, numpy.typing.ArrayLike], wavelength_unit: str | None = 'nm', metadata: dict[str, Any] | None = None, provenance: dict[str, Any] | None = None)

Bases: plesty.lib.data.ExperimentData

Fine structure of each fitted line, one entry per line.

Produced by plesty.fss.FineStructure. Every array has shape (peaks,), nan where a line’s sweep could not be fitted.

fss

fine-structure splitting (µeV)

fss_wavelength

the same splitting as a wavelength (wavelength unit)

axis_deg

rotator angle of the longer-wavelength line (deg)

mean_center

mean line position over the sweep (wavelength unit)

r_squared

coefficient of determination of the sweep fit

n_points

sweep points the fit used

fwhm

median fitted linewidth over the sweep (wavelength unit)

fss_valid

1 when fss_wavelength < fwhm (fss is a splitting), else 0

fss, fss_wavelength, axis_deg and mean_center each have a one-sigma <name>_err array. metadata records the rotator, the sweep coordinate (angle) and its period_deg.

The splitting is the peak-to-peak amplitude of the oscillation of one fitted line’s position with the rotator angle, divided by the rotator’s contrast (½ for a quarter-wave plate, else 1). It measures a doublet only while the doublet’s two components are closer than the linewidth and appear as one line, whose position cannot then move by more than that linewidth. An oscillation at least as wide as the line (fss_valid == 0) means the fit followed a different line from frame to frame — typically because the two components are further apart than their linewidth and appear as two separate lines — and fss is then not a splitting.

Validate the arrays and attach their units.

Parameters:
  • values (Mapping[str, numpy.typing.ArrayLike]) – Every name in names(), as arrays.

  • wavelength_unit (str | None) – Unit of the fitted spectrum’s axis.

  • metadata (dict[str, Any] | None) – Sweep context (rotator, angle, period_deg).

  • provenance (dict[str, Any] | None) – Origin of the data.

Raises:

ValueError – If a name is missing, the metadata lacks period_deg, or the shapes disagree.

kind = 'fine_structure'

Registry key and schema dtype token, e.g. "spectrum".

schema_version = 1

Version of the array layout this class writes and reads.

QUANTITIES: ClassVar[tuple[str, ...]] = ('fss', 'fss_wavelength', 'axis_deg', 'mean_center')
columns

array name → entry, in reading order.

An entry’s keys, all optional:

  • label — the column heading, inline markup and $math$ allowed; the array name when left out.

  • unit — used when the array carries none of its own.

  • description — one line of meaning.

  • result — False for an array the analysis kept but a reader does not need (a fit quality, a point count); default True.

  • error — name of the array holding this one’s one-sigma uncertainty, so the two are shown as one value ± error.

Arrays left out are not tabulated.

Type:

What each array means to a reader

values: dict[str, plesty.lib.data.PlestyArray]

Every array by name.

classmethod names() → tuple[str, ...]

Return every array name, in storage order.

Return type:

tuple[str, …]

static _units(wavelength: str | None) → dict[str, str | None]

Return the unit of each array.

Parameters:

wavelength (str | None)

Return type:

dict[str, str | None]

__getitem__(name: str) → plesty.lib.data.PlestyArray

Return the array called name, e.g. result["fss"].

Parameters:

name (str)

Return type:

plesty.lib.data.PlestyArray

property n_peaks: int

Number of lines.

Return type:

int

property period_deg: float

Rotator angle over which each line’s position repeats.

Return type:

float

evaluate(angle_deg: numpy.typing.ArrayLike) → numpy.ndarray

Evaluate each line’s fitted position at rotator angles.

Parameters:

angle_deg (numpy.typing.ArrayLike) – Rotator angles in degrees, 1-D.

Returns:

Positions of shape (angles, peaks), in the wavelength unit.

Return type:

numpy.ndarray

to_arrays() → dict[str, plesty.lib.data.PlestyArray]

Return every array by name.

Return type:

dict[str, plesty.lib.data.PlestyArray]

classmethod from_arrays(arrays: dict[str, plesty.lib.data.PlestyArray], metadata: dict[str, Any], provenance: dict[str, Any]) → Self

Rebuild the result from to_arrays(); units travel with the arrays.

Parameters:
  • arrays (dict[str, plesty.lib.data.PlestyArray])

  • metadata (dict[str, Any])

  • provenance (dict[str, Any])

Return type:

Self

classmethod example() → Self

Return one line at 775 nm with a 40 µeV splitting seen through a half-wave plate.

Return type:

Self

plesty.fss.HARMONICS: dict[str, int]
class plesty.fss.SineFit

Result of fit_sine(), each value with its one-sigma error.

Variables:
  • mean – Mean line position (the unit of the positions).

  • amplitude – Half the peak-to-peak oscillation of the position, ≥ 0.

  • axis_deg – Rotator angle of the longest position, in [0, period).

  • harmonic – k of the model.

  • r_squared – Coefficient of determination.

  • n_points – Finite points the fit used.

  • values – The raw parameters (mean, a, b) of mean + a·sin(kθ) + b·cos(kθ).

  • covariance – Their covariance, in values order.

mean: float
mean_err: float
amplitude: float
amplitude_err: float
axis_deg: float
axis_deg_err: float
harmonic: int
r_squared: float
n_points: int
values: tuple[float, float, float]
covariance: numpy.ndarray
property period_deg: float

Rotator angle over which the position repeats.

Return type:

float

evaluate(angle_deg: numpy.typing.ArrayLike) → numpy.ndarray

Evaluate the fitted position at rotator angles in degrees.

Parameters:

angle_deg (numpy.typing.ArrayLike)

Return type:

numpy.ndarray

plesty.fss.fit_sine(angle_deg: numpy.typing.ArrayLike, position: numpy.typing.ArrayLike, harmonic: int, sigma: numpy.typing.ArrayLike | None = None) → SineFit

Fit mean + A·cos(k·(θ − axis)) to positions over rotator angles.

Non-finite points are dropped. With sigma the fit is weighted by 1/σ²; as in plesty.lib.analyzer.fit_spectrum(), the covariance is scaled by the reduced chi-square, so the weights are relative. A point without a positive, finite error is dropped too — an unweighted point cannot be combined with weighted ones — unless no point has one, when the fit is unweighted.

Parameters:
  • angle_deg (numpy.typing.ArrayLike) – Rotator angle of each point, in degrees.

  • position (numpy.typing.ArrayLike) – Line position at each angle.

  • harmonic (int) – k — 4 for a half-wave plate, 2 for a polarizer.

  • sigma (numpy.typing.ArrayLike | None) – One-sigma error of each position.

Returns:

The fit; every value is nan when fewer than four points remain or the angles do not determine the model.

Raises:

ValueError – If the arrays differ in shape or harmonic is not positive.

Return type:

SineFit

plesty.fss.load_config() → dict[str, Any]

Load the packaged module configuration (constants and running defaults).

Returns:

The parsed config.yaml shipped with this module.

Return type:

dict[str, Any]