Source code for magboltz_gui.util.run_result
"""Structured result model for parsed Magboltz runs and exports."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Optional, List, Dict, Any, cast
[docs]
@dataclass
class RunIntegration:
"""Energy integration settings reported by Magboltz."""
E_min_eV: Optional[float] = None
E_max_eV: Optional[float] = None
n_steps: Optional[int] = None
[docs]
@dataclass
class RunFlags:
"""Boolean and integer flags affecting the simulation model."""
penning_included: Optional[bool] = None
thermal_motion_included: Optional[bool] = None
anisotropic_scattering_type: Optional[int] = None
short_decorrelation_length_collisions: Optional[int] = None
[docs]
@dataclass
class RunConditions:
"""Physical and numerical conditions used for one run."""
gas_temperature_C: Optional[float] = None
gas_pressure_torr: Optional[float] = None
electric_field_V_cm: Optional[float] = None
magnetic_field_kG: Optional[float] = None
angle_E_B_deg: Optional[float] = None
cyclotron_freq_rad_ps: Optional[float] = None
initial_electron_energy_eV: Optional[float] = None
integration: RunIntegration = field(default_factory=RunIntegration)
flags: RunFlags = field(default_factory=RunFlags)
[docs]
@dataclass
class MixtureGas:
"""One gas entry reconstructed from the run summary."""
name: str
model_tag: Optional[str]
fraction_percent: Optional[float]
[docs]
@dataclass
class RunCounts:
"""Collision counters and related summary values."""
total_real_collisions: Optional[int] = None
num_null_collisions: Optional[int] = None
calculated_max_collision_time_ps: Optional[float] = None
null_collision_frequency_components: List[float] = field(default_factory=list)
[docs]
@dataclass
class DriftVelocity:
"""One drift-velocity component with its uncertainty."""
v_um_ns: Optional[float] = None
err_pct: Optional[float] = None
[docs]
@dataclass
class DiffusionComponent:
"""One diffusion observable with an uncertainty percentage."""
value: Optional[float] = None
err_pct: Optional[float] = None
[docs]
@dataclass
class RunDiffusion:
"""Grouped transverse and longitudinal diffusion quantities."""
transverse: Dict[str, DiffusionComponent] = field(default_factory=dict)
longitudinal: Dict[str, DiffusionComponent] = field(default_factory=dict)
[docs]
@dataclass
class RunTransport:
"""Transport observables extracted from the output."""
vx_um_ns: Optional[DriftVelocity] = None
vy_um_ns: Optional[DriftVelocity] = None
vz_um_ns: Optional[DriftVelocity] = None
diffusion: RunDiffusion = field(default_factory=RunDiffusion)
ionisation_rate_per_cm: Optional[float] = None
ionisation_rate_err_pct: Optional[float] = None
attachment_rate_per_cm: Optional[float] = None
attachment_rate_err_pct: Optional[float] = None
mean_electron_energy_eV: Optional[float] = None
mean_electron_energy_err_pct: Optional[float] = None
[docs]
@dataclass
class RunFrequenciesTotal:
"""Global collision-frequency summary from the run output."""
total_coll_freq_1e12_s: Optional[float] = None
elastic_coll_freq_1e12_s: Optional[float] = None
inelastic_coll_freq_1e12_s: Optional[float] = None
ionisation_coll_freq_1e12_s: Optional[float] = None
attachment_coll_freq_1e12_s: Optional[float] = None
[docs]
@dataclass
class CollisionProcess:
"""One process contribution in the per-gas collision-frequency tables."""
label: str
eloss_eV: Optional[float]
freq_1e12_s: Optional[float]
err_pct: Optional[float]
category: Optional[str] = None
[docs]
@dataclass
class GasFrequencies:
"""Collision-frequency breakdown for one gas species."""
gas_name: str
processes: List[CollisionProcess] = field(default_factory=list)
[docs]
@dataclass
class ConvergenceRow:
"""One row of the Magboltz convergence table."""
vel: float
pos: float
time: float
energy: float
count: float
difxx: float
difyy: float
difzz: float
[docs]
@dataclass
class EnergyRow:
"""One row of the energy-distribution table."""
E_eV: float
spec: float
bin_width_eV: Optional[float] = None
[docs]
@dataclass
class RunTables:
"""Tabular output sections captured from the run."""
convergence_table: List[ConvergenceRow] = field(default_factory=list)
energy_distribution: List[EnergyRow] = field(default_factory=list)
units: Dict[str, str] = field(default_factory=dict)
[docs]
@dataclass
class RunRaw:
"""Raw stdout plus parser warnings kept for debugging and export."""
stdout_text: Optional[str] = None
parser_warnings: List[str] = field(default_factory=list)
[docs]
@dataclass
class RunResult:
"""Top-level result object used across plotting and export code."""
meta: RunMeta = field(default_factory=RunMeta)
input: RunInput = field(default_factory=RunInput)
conditions: RunConditions = field(default_factory=RunConditions)
mixture: List[MixtureGas] = field(default_factory=list)
counts: RunCounts = field(default_factory=RunCounts)
transport: RunTransport = field(default_factory=RunTransport)
frequencies_total: RunFrequenciesTotal = field(default_factory=RunFrequenciesTotal)
frequencies_by_gas: List[GasFrequencies] = field(default_factory=list)
tables: RunTables = field(default_factory=RunTables)
raw: RunRaw = field(default_factory=RunRaw)
[docs]
def to_dict(self) -> Dict[str, Any]:
"""Recursively convert the result tree into plain Python containers."""
def _serialize(obj: Any) -> Any:
if hasattr(obj, "__dict__"):
return {k: _serialize(v) for k, v in obj.__dict__.items()}
if isinstance(obj, list):
return [_serialize(v) for v in obj]
return obj
return cast(Dict[str, Any], _serialize(self))