plesty.pol_pl.experiment
Polarization-dependent photoluminescence of quantum dots.
The atomic step is one analyser angle: rotate the half-wave plate in the
detection path (in front of a fixed polarizer) to the next angle, then take one
spectrum. After the last angle of a quantum dot, one analysis step runs the
plesty.fss.FineStructure analyzer over that dot’s spectra and saves its
result in the run: the fine-structure splitting of every emission line, with a
flag saying whether the splitting could be measured from that line.
All data lands on the shared disk, and frames never cross the network. Runs
go under the experiment’s root there (pol-pl/<run_id>). The run routes the
spectrometer once, at setup, to the run directory’s raw/spec folder by its
path relative to the shared point, which the spectrometer resolves under its
own bench’s view of the disk; the run records each spectrum by that folder and
the file name the spectrometer reports, and reads it under its own
PLESTY_DATA. The framework commits each step’s
record to <run_root>/<run_id>/records.jsonl the moment the step completes,
so an interrupted sweep resumes at the exact angle it stopped
(run(resume=<run_id>)).
Positioning is not automated: the steps assume the dot is already on the spectrometer. The catalogue coordinates are recorded in every spectrum record.
Attributes
Classes
Measure the polarization sweep of every catalogued quantum dot and analyse it. |
Functions
|
Return the inclusive angle series without float accumulation drift. |
|
Return whether value is a finite number (booleans excluded). |
|
Return value as a float, or |
Module Contents
- plesty.pol_pl.experiment.ANGLE_KEY = 'hwp_deg'
- plesty.pol_pl.experiment.RUN_ROOT = 'pol-pl'
- plesty.pol_pl.experiment._SPECTRUM_SUFFIXES = ('.spe', '.npz')
- plesty.pol_pl.experiment._DEFAULT_CONFIG: dict[str, Any]
- plesty.pol_pl.experiment.angle_series(start_deg: float, stop_deg: float, step_deg: float) list[float]
Return the inclusive angle series without float accumulation drift.
- Parameters:
start_deg (float) – First angle in degrees.
stop_deg (float) – Last angle in degrees, included when reachable by whole steps.
step_deg (float) – Increment in degrees; must be positive.
- Returns:
The commanded angles in degrees.
- Raises:
ValueError – If
step_degis not positive orstop_deg < start_deg.- Return type:
list[float]
- class plesty.pol_pl.experiment.Experiment(devices: plesty.pol_pl.rig.PolPlRig | None = None, config: dict[str, Any] | None = None, run_root: str | pathlib.Path | None = None, **kwargs: Any)
Bases:
plesty.lib.experiment.ExperimentMeasure the polarization sweep of every catalogued quantum dot and analyse it.
Configuration comes from a plain dict (loaded from
config/*.yamlby__main__) and is frozen into the plan, so a resumed run refuses a changed configuration. Instruments are reached exclusively through thePolPlRigcomposite passed at construction.Initialize and validate the plan-shaping configuration.
The configuration is checked here, before anything connects, so a malformed sweep fails at the prompt rather than halfway through a run. What only a hardware run needs — the shared data disk — is checked by
validate_hardware_config(), so--dry-runworks without it.- Parameters:
devices (Optional[plesty.pol_pl.rig.PolPlRig]) – The instrument rig;
Nonefor plan-only inspection.config (Optional[dict[str, Any]]) – Measurement configuration (see
config/default.yaml); missing sections take the defaults of this module.run_root (str | pathlib.Path | None) – Directory under which each run creates its data directory; a relative one is under
PLESTY_DATA(the share) —RUN_ROOTfor a run started by the command line.**kwargs (Any) – Forwarded to the base
Experiment(name,max_retries,retry_sleep,data_root).
- Raises:
ValueError – If the configuration is malformed.
- config
- rig = None
- _grating_center_nm: float | None = None
- build_plan() plesty.lib.experiment.Plan
Expand the configuration into one step per dot per angle, plus one analysis per dot.
Absolute angles, so no error accumulates along the sweep; resume granularity is the single angle.
- Returns:
The frozen schedule. Step ids look like
qd[QD-01]-hwp[004.00]andqd[QD-01]-analysis.- Return type:
plesty.lib.experiment.Plan
- record_rig() dict[str, Any]
Record the instrument identities, so a run is replayable from its records.
- Returns:
Each device’s identity and the UTC time it was recorded.
- Return type:
dict[str, Any]
- measure_spectrum(sample: str, qd: str, x_um: float, y_um: float, angle_deg: float, exposure_ms: float, frames: int, settle_s: float = 0.0) dict[str, Any]
Rotate the half-wave plate to one angle and take one spectrum.
- Parameters:
sample (str) – Sample identifier.
qd (str) – Quantum-dot identifier from the catalogue.
x_um (float) – Catalogued chip X coordinate in micrometres.
y_um (float) – Catalogued chip Y coordinate in micrometres.
angle_deg (float) – Commanded absolute half-wave-plate angle in degrees.
exposure_ms (float) – Exposure time in milliseconds.
frames (int) – Frames stored in the spectrum file.
settle_s (float) – Pause after the plate has settled, before the exposure.
- Returns:
identifiers, coordinates, commanded and reported angle, the spectrum file relative to the shared point, the exposure window and the grating centre wavelength.
- Return type:
The spectrum record
- Raises:
RuntimeError – If no rig is attached or the spectrometer wrote no file.
TimeoutError – If the file does not appear on this host’s mount.
- analyze_qd(qd: str) dict[str, Any]
Analyse one quantum dot’s polarization sweep with
plesty.fss.FineStructure.Reads the dot’s spectra back from this run’s records, fits every line in every spectrum and each line’s position against the angle, and saves the analyzer’s
fine_structureandfitoutputs under<run_dir>/analysis/, where the run viewer (viz) finds them, with the analyzer’s report of them beside them (<qd>.report.json). Warnings the analyzer raises — a line whose fit moved onto a different line, a splitting that cannot be read from a line — are logged and kept in the record.- Parameters:
qd (str) – Quantum-dot identifier.
- Returns:
position, fine-structure splitting ± σ in µeV, whether the splitting is valid, and polarization axis; plus the analyzer warnings and where the full results were saved.
- Return type:
Per emission line
- Raises:
RuntimeError – If the run has not started.
ValueError – If the run holds no spectrum of this dot.
- async setup() None
Check the configuration, connect, route the frames, home the plate.
- Raises:
ValueError – If the hardware configuration is incomplete.
RuntimeError – If this machine is not told where the Plesty share is.
- Return type:
None
- async teardown() None
Park the half-wave plate at 0° (best effort), then disconnect.
- Return type:
None
- classmethod validate_plan_config(config: dict[str, Any]) None
Validate everything that shapes the plan.
- Parameters:
config (dict[str, Any]) – The measurement configuration, defaults merged in.
- Raises:
ValueError – If a value is missing, of the wrong kind or out of range.
- Return type:
None
- classmethod validate_hardware_config(config: dict[str, Any], data_root: str | None) None
Validate what a hardware run needs beyond a valid plan.
The spectra are written by the spectrometer and read back here — to confirm each file arrived and to analyse the sweep — so this machine’s view of the shared disk is required.
- Parameters:
config (dict[str, Any]) – The measurement configuration.
data_root (Optional[str]) – The shared disk as this machine sees it.
- Raises:
ValueError – If the plan configuration is invalid or the shared disk is not configured.
- Return type:
None
- _base_filename(qd: str, angle_deg: float) str
Build the spectrometer file-name stem, e.g.
pol_pl_QD-01_hwp004p00.- Parameters:
qd (str)
angle_deg (float)
- Return type:
str
- _grating_center() float | None
Return the grating centre wavelength, queried once per process.
A value the spectrometer cannot report is recorded as
Nonewith one warning; metadata must not abort a sweep whose spectra are fine.- Return type:
Optional[float]
- _local_raw_path(data_file: str) pathlib.Path
A recorded spectrum file, relative to the shared point, on this machine.
The folder is the run’s own (
raw_file()); only the name came from the spectrometer, and it is checked rather than trusted — it becomes a path this process reads — so it must name a spectrum.- Raises:
RuntimeError – If the run has no data root.
ValueError – If the spectrometer’s file is not a spectrum.
- Parameters:
data_file (str)
- Return type:
pathlib.Path
- _wait_for_file(path: pathlib.Path) None
Wait for a written spectrum to become visible on this machine’s mount.
- Raises:
TimeoutError – If it does not appear within
spectra.file_visibility_timeout_s.- Parameters:
path (pathlib.Path)
- Return type:
None
- _require_rig() plesty.pol_pl.rig.PolPlRig
Return the rig.
- Raises:
RuntimeError – If the experiment was built without one.
- Return type:
- plesty.pol_pl.experiment._is_finite(value: Any) bool
Return whether value is a finite number (booleans excluded).
- Parameters:
value (Any)
- Return type:
bool
- plesty.pol_pl.experiment._finite(value: Any) float | None
Return value as a float, or
Nonewhen it is not finite (for JSON records).- Parameters:
value (Any)
- Return type:
Optional[float]