diff --git a/hexsample/app.py b/hexsample/app.py index 307d9c98..12b1c1ba 100644 --- a/hexsample/app.py +++ b/hexsample/app.py @@ -188,6 +188,10 @@ def add_source_options(self) -> None: """Add an option group for the source properties. """ group = self.add_argument_group('source', 'X-ray source properties') + types = ['lines', 'continuum'] + group.add_argument('--spectrumtype', type=str, choices=types, default='lines', + help='type of spectrum, choices are between a discrete\ + and a continuum spectrum in the range [7000, 9000] eV.') group.add_argument('--srcelement', type=str, default='Cu', help='element generating the line forest') group.add_argument('--srclevel', type=str, default='K', diff --git a/hexsample/bin/hxsim.py b/hexsample/bin/hxsim.py index 8326af71..2fc5675a 100755 --- a/hexsample/bin/hxsim.py +++ b/hexsample/bin/hxsim.py @@ -35,7 +35,7 @@ from hexsample.hexagon import HexagonalLayout from hexsample.mc import PhotonList from hexsample.roi import Padding -from hexsample.source import LineForest, GaussianBeam, Source +from hexsample.source import ContinuumSpectrum, LineForest, GaussianBeam, Source from hexsample.sensor import Material, Sensor @@ -58,7 +58,11 @@ def hxsim(**kwargs): """ # pylint: disable=too-many-locals, invalid-name rng.initialize(seed=kwargs['seed']) - spectrum = LineForest(kwargs['srcelement'], kwargs['srclevel']) + spectrum_type = kwargs['spectrumtype'] + if spectrum_type == 'continuum': + spectrum = ContinuumSpectrum() + else: + spectrum = LineForest(kwargs['srcelement'], kwargs['srclevel']) beam = GaussianBeam(kwargs['srcposx'], kwargs['srcposy'], kwargs['srcsigma']) source = Source(spectrum, beam) material = Material(kwargs['actmedium'], kwargs['fano']) diff --git a/hexsample/fileio.py b/hexsample/fileio.py index 74daa489..a2f27f8d 100644 --- a/hexsample/fileio.py +++ b/hexsample/fileio.py @@ -262,6 +262,7 @@ def _fill_recon_row(row: tables.tableextension.Row, event: ReconEvent) -> None: row['trigger_id'] = event.trigger_id row['timestamp'] = event.timestamp row['livetime'] = event.livetime + # Roi size is not implemented in all event type classes #row['roi_size'] = event.roi_size row['cluster_size'] = event.cluster.size() row['energy'] = event.energy() diff --git a/hexsample/source.py b/hexsample/source.py index 8cacc21c..1f7e158b 100644 --- a/hexsample/source.py +++ b/hexsample/source.py @@ -205,8 +205,6 @@ def plot(self) -> None: """ raise NotImplementedError - - class LineForest(SpectrumBase): """Class describing a set of X-ray emission lines for a given element and @@ -269,8 +267,47 @@ def __str__(self): """String formatting. """ return f'{self.line_dict}' + +class ContinuumSpectrum(SpectrumBase): + """Class describing a continuum and uniform x-ray energy spectrum between + a minimum and a maximum value. By now the continuum spectrum is set in the + range [7000, 9000] eV, the possibility to choose it in the sim has to be + implemented. + Arguments + --------- + min_energy : float + Minimum energy of the spectrum + max_energy : float + Maximum energy of the spectrum + """ + def __init__(self, min_energy: float=7000, max_energy: float=9000) -> None: + self.minimum_energy = min_energy + self.maximum_energy = max_energy + def rvs(self, size: int = 1) -> np.ndarray: + """Throw random energies from the line forest. + + Arguments + --------- + size : int + The number of X-ray energies to be generated. + + Returns + ------- + energy : np.ndarray of shape ``size`` + The photon energies in eV. + """ + # Random generating the energies in [minimum_energy, maximum_energy] + return rng.generator.uniform(self.minimum_energy, self.maximum_energy, size) + + def plot(self) -> None: + """Plot the continuum spectrum for 1e4 generated photons. + """ + # pylint: disable=invalid-name + energies_ = self.rvs(10000) + plt.hist(energies_, density=True, color='tab:blue') + setup_gca(xlabel='Energy [eV]', ylabel='PDF', logy=True, grids=True) class Source: