from typing import Any
from typing import Dict
from typing import List
from typing import Literal
from typing import Optional
from typing import Union
from pydantic import BaseModel
from pydantic import Field
from pydantic import PrivateAttr
[docs]
class PyMcaBaseModel(BaseModel, extra="allow", validate_assignment=True):
pass
EnergyType = Union[float, None, Literal["None", "NONE"]]
[docs]
class Fit(PyMcaBaseModel):
deltaonepeak: Optional[float] = None
strategy: Optional[str] = None
strategyflag: Optional[int] = None
fitfunction: Optional[int] = None
continuum: Optional[int] = None
fitweight: Optional[int] = None
stripalgorithm: Optional[int] = Field(default=None, description="0: STRIP, 1: SNIP")
linpolorder: Optional[int] = None
exppolorder: Optional[int] = None
stripconstant: Optional[float] = None
snipwidth: Optional[int] = None
stripiterations: Optional[int] = None
stripwidth: Optional[int] = None
stripfilterwidth: Optional[int] = None
stripanchorsflag: Optional[int] = None
maxiter: Optional[int] = None
deltachi: Optional[float] = None
xmin: Optional[int] = None
xmax: Optional[int] = None
linearfitflag: Optional[int] = None
use_limit: Optional[int] = None
stripflag: Optional[int] = None
escapeflag: Optional[int] = None
sumflag: Optional[int] = None
scatterflag: Optional[int] = None
hypermetflag: Optional[int] = None
stripanchorslist: List[int] = Field(default_factory=list)
energy: Union[List[EnergyType], EnergyType] = Field(default_factory=list)
energyweight: Union[List[float], float] = Field(default_factory=list)
energyflag: Union[List[int], int] = Field(default_factory=list)
energyscatter: Union[List[int], int] = Field(default_factory=list)
[docs]
class Concentrations(PyMcaBaseModel):
usematrix: Optional[int] = None
useattenuators: Optional[int] = None
usemultilayersecondary: Optional[int] = None
usexrfmc: Optional[int] = None
mmolarflag: Optional[int] = None
flux: Optional[float] = None
time: Optional[float] = None
area: Optional[float] = None
distance: Optional[float] = None
reference: Optional[str] = None
useautotime: Optional[int] = None
[docs]
class Detector(PyMcaBaseModel):
detele: str
nthreshold: int
zero: float
deltazero: float
fixedzero: int
gain: float
deltagain: float
fixedgain: int
noise: float
deltanoise: float
fixednoise: int
fano: float
deltafano: float
fixedfano: int
sum: float
deltasum: float
fixedsum: int
ignoreinputcalibration: Optional[int] = None
ethreshold: Optional[float] = None
ithreshold: Optional[float] = None
[docs]
class PeakShape(PyMcaBaseModel):
st_arearatio: float
deltast_arearatio: float
fixedst_arearatio: int
st_sloperatio: float
deltast_sloperatio: float
fixedst_sloperatio: int
lt_arearatio: float
deltalt_arearatio: float
fixedlt_arearatio: int
lt_sloperatio: float
deltalt_sloperatio: float
fixedlt_sloperatio: int
step_heightratio: float
deltastep_heightratio: float
fixedstep_heightratio: int
eta_factor: Optional[float] = None
deltaeta_factor: Optional[float] = None
fixedeta_factor: Optional[int] = None
[docs]
class Material(PyMcaBaseModel):
Comment: Optional[str] = None
Density: float
Thickness: Optional[float] = None
CompoundFraction: Union[float, Literal[""], List[float]]
CompoundList: Union[str, List[str]] = Field(
description="key in materials or chemical formula"
)
[docs]
class UserAttenuator(PyMcaBaseModel):
use: int
name: str
comment: Optional[str]
energy: Union[float, List[float]]
transmission: Union[float, List[float]]
[docs]
class Tube(PyMcaBaseModel):
transmission: int
voltage: float
anode: str
anodethickness: float
anodedensity: float
window: str
windowthickness: float
windowdensity: float
filter1: str
filter1thickness: float
filter1density: float
alphax: float
alphae: float
deltaplotting: float
[docs]
class XRFMCSetup(PyMcaBaseModel):
p_polarisation: float
source_sample_distance: float
slit_distance: float
slit_width_x: float
slit_width_y: float
source_size_x: float
source_size_y: float
source_diverg_x: float
source_diverg_y: float
nmax_interaction: int
layer: int
collimator_height: float
collimator_diameter: float
histories: int
[docs]
class XRFMC(PyMcaBaseModel):
program: Optional[str] = None
setup: XRFMCSetup
[docs]
class Fisx(PyMcaBaseModel):
pass
[docs]
class AttenuatorView(BaseModel):
enabled: int
material: Optional[str] = Field(description="key in materials or chemical formula")
density: float = Field(description="g/cm^3")
thickness: float = Field(description="cm")
incidence_angle: Optional[float] = Field(
None, description="Angle between incident beam and sample surface (degrees)"
)
exit_angle: Optional[float] = Field(
None, description="Angle between outgoing beam and sample surface (degrees)"
)
scattering_flag: Optional[bool] = None
scattering_angle: Optional[float] = Field(
None, description="Angle between incident beam and outgoing beam (degrees)"
)
_raw: List[Any] = PrivateAttr()
[docs]
@classmethod
def from_list(cls, data: List[Any]) -> "AttenuatorView":
padded = (data + [None] * 8)[:8]
obj = cls(
enabled=padded[0],
material=padded[1],
density=padded[2],
thickness=padded[3],
incidence_angle=padded[4],
exit_angle=padded[5],
scattering_flag=padded[6],
scattering_angle=padded[7],
)
obj._raw = data
return obj
def _sync(self) -> None:
new = [
self.enabled,
self.material,
self.density,
self.thickness,
self.incidence_angle,
self.exit_angle,
self.scattering_flag,
self.scattering_angle,
]
self._raw[:] = new[: len(self._raw)]
def __setattr__(self, name, value):
super().__setattr__(name, value)
if name in type(self).model_fields:
if hasattr(self, "_raw"):
self._sync()
[docs]
class MultilayerView(BaseModel):
use: int
material: str = Field(description="key in materials or chemical formula")
density: float
thickness: float
_raw: List[Any] = PrivateAttr()
[docs]
@classmethod
def from_list(cls, data: List[Any]) -> "MultilayerView":
padded = (data + [None] * 4)[:4]
obj = cls(
use=padded[0],
material=padded[1],
density=padded[2],
thickness=padded[3],
)
obj._raw = data
return obj
def _sync(self) -> None:
self._raw[:] = [
self.use,
self.material,
self.density,
self.thickness,
]
def __setattr__(self, name, value):
super().__setattr__(name, value)
if name in type(self).model_fields:
if hasattr(self, "_raw"):
self._sync()
[docs]
class PyMcaXrfConfiguration(PyMcaBaseModel):
peaks: Dict[str, Union[str, List[str]]] = Field(default_factory=dict)
fit: Fit = Field(default_factory=dict)
concentrations: Concentrations = Field(default_factory=dict)
detector: Detector = Field(default_factory=dict)
peakshape: PeakShape = Field(default_factory=dict)
materials: Dict[str, Material] = Field(default_factory=dict)
attenuators: Dict[str, List[Any]] = Field(default_factory=dict)
multilayer: Dict[str, List[Any]] = Field(default_factory=dict)
userattenuators: Dict[str, UserAttenuator] = Field(default_factory=dict)
tube: Optional[Tube] = None
xrfmc: Optional[XRFMC] = None
fisx: Optional[Fisx] = None
@property
def attenuator_views(self) -> Dict[str, AttenuatorView]:
return {
name: AttenuatorView.from_list(values)
for name, values in self.attenuators.items()
}
@property
def multilayer_views(self) -> Dict[str, MultilayerView]:
return {
name: MultilayerView.from_list(values)
for name, values in self.multilayer.items()
}