autoemx.config.schema_models.particle_stats module

Particle size statistics stored in the sample ledger: the measurements (SampleLedger.size_measurements) and the statistics computed from frames under a segmentation (SampleLedger.size_results), with the working records of size bands and frames used to compute them (built from SampleLedger.frames, not stored).

autoemx.config.schema_models.particle_stats.ParticleSelection

found by a particle size statistics measurement (‘size_stats’, ledgers before frames were recorded), or measured by EDS with particle selection mode ‘auto’, ‘manual’ or ‘list’ (PowderMeasurementConfig.par_selection_mode).

Type:

How a particle was chosen

alias of Literal[‘size_stats’, ‘auto’, ‘manual’, ‘list’]

autoemx.config.schema_models.particle_stats.ParticleKey

(frame_id, index of the particle in the frame result)

Type:

A particle found by a segmentation of a frame

alias of Tuple[str, int]

class autoemx.config.schema_models.particle_stats.ParticleSizeStats(*, n_par_analysed: int, mean: float, stdev: float, median: float, max: float, min: float, D10: float, D25: float, D75: float, D90: float, D43: float | None = None, Dv10: float | None = None, Dv50: float | None = None, Dv90: float | None = None)[source]

Bases: BaseModel

Summary statistics of particle equivalent diameters, in µm (median is the D50).

D43 (volume-weighted mean, D[4,3]) and the volume-weighted percentiles Dv10, Dv50, Dv90 weight each particle by the volume of a sphere of its equivalent diameter, for comparison with laser diffraction (not computed before AutoEMX 1.6.0).

n_par_analysed: int
mean: float
stdev: float
median: float
max: float
min: float
D10: float
D25: float
D75: float
D90: float
D43: float | None
Dv10: float | None
Dv50: float | None
Dv90: float | None
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod validate_n_par(v: int) → int[source]
classmethod validate_finite(v: float | None) → float | None[source]
class autoemx.config.schema_models.particle_stats.ParticleStatsFrame(*, frame_id: str, center_mm: Coordinate2D | None = None, frame_width_um: float, pixel_size_um: float, area_um2: float, n_particles: int, particle_areas_um2: List[float] | None = None, particle_edge_corrections: List[float] | None = None, image_file: str | None = None, particle_marks_px: List[Tuple[int, int, int, int | None]] | None = None)[source]

Bases: BaseModel

Working record of a frame under one segmentation (built from SampleLedger.frames): center_mm (stage position of its centre, if known), frame width and pixel size, area_um2 (total area of the frame), the area and frame-edge correction of each particle valid for the statistics, image_file (in the SEM images folder of the sample) and particle_marks_px (x, y, radius in pixels, and index of the particle in the frame).

frame_id: str
center_mm: Coordinate2D | None
frame_width_um: float
pixel_size_um: float
area_um2: float
n_particles: int
particle_areas_um2: List[float] | None
particle_edge_corrections: List[float] | None
image_file: str | None
particle_marks_px: List[Tuple[int, int, int, int | None]] | None
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

validate_particle_lists() → ParticleStatsFrame[source]
classmethod validate_positive(v: float) → float[source]
classmethod validate_n_particles(v: int) → int[source]
class autoemx.config.schema_models.particle_stats.ParticleSizeBand(*, d_min_um: float, d_max_um: float, frame_width_um: float | None = None, n_frames: int, scanned_area_um2: float, frames: List[ParticleStatsFrame] = <factory>, number_density_per_mm2: float | None = None, n_eds_particles: int = 0)[source]

Bases: BaseModel

Working record of the frames of a size band of a measurement, or of frames searched by EDS with the same size range and frame width, under one segmentation: diameters searched, frame width, frames and scanned area, and (once weighted) number_density_per_mm2 (particles counted per mm²) and n_eds_particles (particles measured by EDS sharing the weight of the band, ledgers without frames searched by EDS).

d_min_um: float
d_max_um: float
frame_width_um: float | None
n_frames: int
scanned_area_um2: float
frames: List[ParticleStatsFrame]
number_density_per_mm2: float | None
n_eds_particles: int
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod validate_non_negative(v: float) → float[source]
classmethod validate_frame_width(v: float | None) → float | None[source]
validate_frames() → ParticleSizeBand[source]
property n_particles: int

Particles counted in the frames of the band.

add_frame(frame: ParticleStatsFrame) → None[source]

Record a frame analysed in the band.

frame_area_um2(frame_ids) → float[source]

Total area of the recorded frames of the band with the given ids.

class autoemx.config.schema_models.particle_stats.SizeBand(*, d_min_um: float, d_max_um: float, frame_width_um: float | None = None, frame_ids: List[str] = <factory>)[source]

Bases: BaseModel

Size band of a particle size statistics measurement: diameters searched, frame width, and its frames.

d_min_um: float
d_max_um: float
frame_width_um: float | None
frame_ids: List[str]
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class autoemx.config.schema_models.particle_stats.SizeMeasurement(*, measurement_id: int, autoemx_version: str = '1.8.0', datetime: str = <factory>, status: Literal['in_progress', 'completed', 'interrupted']='in_progress', n_par_target: int, powder_meas_cfg: PowderMeasurementConfig, segmentation_id: int, count_eds_frames: bool = False, bands: List[SizeBand] = <factory>, precision_reached: bool | None = None)[source]

Bases: BaseModel

A particle size statistics measurement of the sample: its target, settings, size bands (largest particles first, with the frames acquired in each) and the segmentation used while acquiring (which decided when each band reached its target). status is ‘in_progress’ while acquiring (an interrupted measurement with the same target and settings is resumed), then ‘completed’, or ‘interrupted’ if a new measurement started instead of resuming it (its frames are kept). count_eds_frames: it continued an EDS acquisition, counting the frames searched by EDS.

measurement_id: int
autoemx_version: str
datetime: str
status: Literal['in_progress', 'completed', 'interrupted']
n_par_target: int
powder_meas_cfg: PowderMeasurementConfig
segmentation_id: int
count_eds_frames: bool
bands: List[SizeBand]
precision_reached: bool | None
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property frame_ids: List[str]
class autoemx.config.schema_models.particle_stats.BandSummary(*, d_min_um: float, d_max_um: float, frame_width_um: float | None = None, n_frames: int, scanned_area_um2: float, n_particles: int, number_density_per_mm2: float | None = None, n_eds_particles: int = 0, frame_ids: List[str] = <factory>)[source]

Bases: BaseModel

Size band (or frames searched by EDS) as counted in a statistics result.

d_min_um: float
d_max_um: float
frame_width_um: float | None
n_frames: int
scanned_area_um2: float
n_particles: int
number_density_per_mm2: float | None
n_eds_particles: int
frame_ids: List[str]
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class autoemx.config.schema_models.particle_stats.ParticleSizeStatsResult(*, result_id: int, autoemx_version: str = '1.8.0', datetime: str = <factory>, measurement_id: int | None = None, segmentation_id: int | None = None, eds_segmentation_id: int | None = None, n_par_target: int | None = None, powder_meas_cfg: PowderMeasurementConfig, n_par_by_selection: Dict[str, int]=<factory>, size_stats: ParticleSizeStats, unweighted_size_stats: ParticleSizeStats | None = None, n_par_without_weight: int = 0, confidence_intervals_95: Dict[str, ~typing.Tuple[float, float]]=<factory>, precision_reached: bool | None = None, bands: List[BandSummary] = <factory>, eds_scans: List[BandSummary] = <factory>, excluded_frame_ids: List[str] = <factory>, excluded_particles: Tuple[str, int]]=<factory>, overlapping_frame_ids: List[str] = <factory>, missing_frame_ids: List[str] = <factory>)[source]

Bases: BaseModel

Particle size statistics of the sample computed from frames under a segmentation: the frames of measurement measurement_id segmented with segmentation_id and, if eds_segmentation_id is set, the frames searched by EDS segmented with it (usually the same segmentation); frames without result of the segmentation are left out. For samples measured before frames searched by EDS were recorded, the particles measured by EDS with automatic selection (n_par_by_selection['auto']) share the weight of the band of their diameter.

size_stats are number-weighted: each particle counts its frame-edge correction over the area of the frames able to observe its size, so that each size counts in proportion to its number of particles per unit area of the sample; unweighted_size_stats treat all particles equally. confidence_intervals_95 are bootstrapped by frame. Frames and particles left out (excluded_frame_ids, excluded_particles as (frame_id, index)) are recorded; overlapping_frame_ids are left out because a larger frame counts the same sizes there. powder_meas_cfg are the settings of the measurement (of the EDS acquisition, without measurement).

result_id: int
autoemx_version: str
datetime: str
measurement_id: int | None
segmentation_id: int | None
eds_segmentation_id: int | None
n_par_target: int | None
powder_meas_cfg: PowderMeasurementConfig
n_par_by_selection: Dict[str, int]
size_stats: ParticleSizeStats
unweighted_size_stats: ParticleSizeStats | None
n_par_without_weight: int
confidence_intervals_95: Dict[str, Tuple[float, float]]
precision_reached: bool | None
bands: List[BandSummary]
eds_scans: List[BandSummary]
excluded_frame_ids: List[str]
excluded_particles: List[Tuple[str, int]]
overlapping_frame_ids: List[str]
missing_frame_ids: List[str]
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

inputs_key() → tuple[source]

What the result was computed from: a new result with the same inputs replaces it.