Source code for hexrd.instrument.detector_coatings

import numpy as np
from hexrd.material.utils import (
    calculate_energy_absorption_length,
    calculate_linear_absorption_length,
)


[docs]class AbstractLayer: """abstract class for encode information for an arbitrary planar layer of given thickness, density, and material Parameters ---------- material : str either the formula or a material name density : float density of element in g/cc thickness : float thickness in microns readout_length : float the distance of phosphor screen that encodes the information from x-rays pre_U0 : float scale factor for phosphor screen to convert intensity to PSL formula: str or None The chemical formula to use for absorption length calculations. If one is not provided, the chemical formula is assumed to be the same as the material name. """ def __init__(self, material: str | None = None, density: float | None = None, thickness: float | None = None, readout_length: float | None = None, pre_U0: float | None = None, formula: str | None = None, ): self._material = material self._density = density self._thickness = thickness self._formula = formula @property def attributes_to_serialize(self): return [ 'material', 'density', 'thickness', 'formula', ] @property def material(self): return self._material @material.setter def material(self, material): self._material = material @property def density(self): if self._density is None: return 0.0 return self._density @density.setter def density(self, density): self._density = density @property def thickness(self): if self._thickness is None: return 0.0 return self._thickness @thickness.setter def thickness(self, value): self._thickness = value @property def formula(self) -> str: return self._formula @formula.setter def formula(self, value: str): self._formula = value
[docs] def absorption_length(self, energy): if isinstance(energy, float): energy_inp = np.array([energy]) elif isinstance(energy, list): energy_inp = np.array(energy) elif isinstance(energy, np.ndarray): energy_inp = energy # Use the chemical formula if provided. Otherwise, assume the material # name is the chemical formula. formula = self.formula if self.formula else self.material args = ( self.density, formula, energy_inp, ) abs_length = calculate_linear_absorption_length(*args) if abs_length.shape[0] == 1: return abs_length[0] else: return abs_length
[docs] def energy_absorption_length(self, energy): if isinstance(energy, float): energy_inp = np.array([energy]) elif isinstance(energy, list): energy_inp = np.array(energy) elif isinstance(energy, np.ndarray): energy_inp = energy # Use the chemical formula if provided. Otherwise, assume the material # name is the chemical formula. formula = self.formula if self.formula else self.material args = ( self.density, formula, energy_inp, ) abs_length = calculate_energy_absorption_length(*args) if abs_length.shape[0] == 1: return abs_length[0] else: return abs_length
[docs] def serialize(self): return {a: getattr(self, a) for a in self.attributes_to_serialize}
[docs] def deserialize(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value)
[docs]class Filter(AbstractLayer): def __init__(self, **abstractlayer_kwargs): super().__init__(**abstractlayer_kwargs)
[docs]class Coating(AbstractLayer): def __init__(self, **abstractlayer_kwargs): super().__init__(**abstractlayer_kwargs)
[docs]class Phosphor(AbstractLayer): def __init__(self, **abstractlayer_kwargs): super().__init__(**abstractlayer_kwargs) self._readout_length = abstractlayer_kwargs['readout_length'] self._pre_U0 = abstractlayer_kwargs['pre_U0'] @property def attributes_to_serialize(self): return super().attributes_to_serialize + [ 'readout_length', 'pre_U0', ] @property def readout_length(self): if self._readout_length is None: return 0.0 return self._readout_length @readout_length.setter def readout_length(self, value): self._readout_length = value @property def pre_U0(self): if self._pre_U0 is None: return 0.0 return self._pre_U0 @pre_U0.setter def pre_U0(self, value): self._pre_U0 = value