X-Ray Sub-Module¶
x-ray utilities module
- pyPenred.simulation.xray.anodeSim(density: SupportsFloat, composition: Sequence[tuple[SupportsInt, SupportsFloat]], anode_angle: SupportsFloat, kvp: SupportsFloat, histories: SupportsFloat = 10000.0, min_energy: SupportsFloat = -1.0, bins: SupportsInt = 200, pixel_size: SupportsFloat = 0.1, max_angle: SupportsFloat = 80.0, save_distributions: bool = True, verbose: SupportsInt = 1) tuple ¶
Simulates an electron beam impinging on an anode with no filter.
- Parameters:
density (float) – Anode density in g/cm^3.
composition (list[tuple[int, float]]) – List of (Z, weight fraction) for material composition.
anode_angle (float) – Anode angle in degrees.
kvp (float) – Beam KVP value.
histories (float, optional) – Number of histories to simulate.
min_energy (float, optional) – Minimum energy to record in keV. Defaults to kvp/10.
bins (int, optional) – Number of spectrum bins.
pixel_size (float, optional) – Pixel size in cm.
max_angle (float, optional) – Maximum angle for scattered particles, in degrees.
save_distributions (bool) – If enabled, saves the spectrum and spatial distributions in files ready to be used by deviceSim.
verbose (int, optional) – Verbosity level.
- Returns:
- A tuple with the following information, in order:
Energy limits for the generated spectrum (emin, emax) in keV
A 1D numpy array with the resulting gamma spectrum (prob/hist)
A 1D numpy array with the uncertainty for each gamma spectrum bin
X limits for spatial distribution (xmin, xmax) in cm
Y limits for spatial distribution (ymin, ymax) in cm
A 2D numpy array with the resulting gamma spatial distribution (prob/hist)
A 2D numpy array with the uncertainty for each spatial distribution bin
The distance between the anode collision point and the recorded spatial distribution center
- Return type:
- Raises:
ValueError – Incompatible value has been provided.
Example
#!/usr/bin/env python3 import matplotlib.pyplot as plt import numpy as np import pyPenred # Run the simulation and store the results results = pyPenred.simulation.xray.anodeSim(density=10.0, composition=((74,1),), anode_angle=13, kvp=100.0, histories=1.0e5) # Extract energy and spatial ranges eLimits = results[0] xLimits = results[3] yLimits = results[4] # Produce X data for spectrum plot e_plot = np.linspace(eLimits[0], eLimits[1], len(results[1])) # Plot the spectrum plt.plot(e_plot, results[1]) plt.title("Anode spectrum") plt.xlabel("keV") plt.ylabel("Prob/hist") plt.savefig('anode-spectrum.png') # Plot the spatial distribution plt.imshow(results[5], extent=[xLimits[0], xLimits[1], yLimits[0], yLimits[1]], aspect='auto', origin='lower', cmap='viridis') plt.colorbar() plt.xlabel("X cm") plt.ylabel("Y cm") plt.savefig('anode-spatial-distrib.png')
- pyPenred.simulation.xray.deviceSim(source_position: Annotated[Sequence[SupportsFloat], 'FixedSize(3)'] = [0.0, 0.0, 0.0], focal_spot: SupportsFloat = 0.0, inherent_filter_width: SupportsFloat = -1.0, min_energy: SupportsFloat = 10.0, kvp: SupportsFloat = 100.0, anode_z: SupportsInt = 74, anode_angle: SupportsFloat = 13.0, spectrum_file: str = '', spatial_file: str = '', source_to_distribution: SupportsFloat = 0.68, source_to_filter: SupportsFloat = 7.0, source_to_detector: SupportsFloat = 14.0, filters: Sequence[tuple[SupportsFloat, SupportsFloat, Sequence[tuple[SupportsInt, SupportsFloat]]]] = [], histories: SupportsFloat = 100000.0, max_time: SupportsFloat = 600.0, detector_dx: SupportsFloat = 50.0, detector_dy: SupportsFloat = 50.0, xbins: SupportsInt = 100, ybins: SupportsInt = 100, ebins: SupportsInt = 200, threads: SupportsInt = 0, print_geometry: bool = False, seed_pair: SupportsInt = 0, tolerance: SupportsFloat = 0.01, user_geometry: dict = {}, geometry_materials: Sequence[tuple[SupportsFloat, Sequence[tuple[SupportsInt, SupportsFloat]]]] = [], only_check: bool = False, print_configuration: bool = False, verbose: SupportsInt = 1) tuple ¶
Simulates an electron beam impinging on an anode and records the resulting photon spectrum and spatial distribution.
- Parameters:
source_position (tuple[float, float, float]) – Position of the source in cm. This point is interpreted as the location at the anode where the beam impacts.
focal_spot (float) – Focal spot size of the beam in cm.
inherent_filter_width (float) – Width in cm for the inherent filter. Set to zero or a negative value to disable it.
min_energy (float) – Minimum photon energy to be recorded, in keV.
kvp (float) – Peak kilovoltage (kVp) of the beam.
anode_z (int) – Atomic number (Z) of the anode material.
anode_angle (float) – Angle of the anode in degrees.
spectrum_file (str) – Input file path to read the generated energy spectrum.
spatial_file (str) – Input file path to read the photon spatial distribution.
source_to_distribution (float) – Distance from source to the spatial distribution plane in cm.
source_to_filter (float) – Distance from source to the first filter in cm.
source_to_detector (float) – Distance from source to the detector in cm.
filters (list) – List of additional filters beyond the inherent one. Each filter should be defined as: (width_cm, density_g_cm3, [(Z1, fraction1), (Z2, fraction2), …])
histories (float) – Number of Monte Carlo histories (Beam electrons).
max_time (float) – Maximum simulation run time in seconds.
detector_dx (float) – Detector size in the X direction in cm.
detector_dy (float) – Detector size in the Y direction in cm.
xbins (int) – Number of bins (pixels) along the X axis.
ybins (int) – Number of bins (pixels) along the Y axis.
ebins (int) – Number of energy bins for the spectrum.
threads (int) – Number of threads to use. If 0, use all available CPU cores.
print_geometry (bool) – If True, saves the generated simulation geometry to a file.
seed_pair (int) – Seed pair index for RNG initialization. Must be less than 1001.
tolerance (float) – Desired relative error (error/value) for the simulation.
user_geometry (dict) – Configuration of additional geometry provided by the user.
geometry_materials (list) – List of extra materials used in the user-defined geometry. Each material should be defined as: (density, [(Z1, fraction1), (Z2, fraction2), …])
only_check (bool) – If True, validates the configuration and returns material count without running the simulation.
print_configuration (bool) – If True, saves the simulation configuration to a file named ‘simDevice.conf’.
verbose (int) – Verbosity level (higher values provide more output).
- Returns:
- if ‘only_check’ value is false, a tuple with the following information, in order:
Energy limits for the generated spectrum (emin, emax) in keV
A 1D numpy array with the detected gamma spectrum (prob/hist)
A 1D numpy array with the uncertainty for each gamma spectrum bin
X limits for spatial distribution (xmin, xmax) in cm
Y limits for spatial distribution (ymin, ymax) in cm
A 2D numpy array with the absorbed energy distribution, in eV, normalized per history. Notice that a perfect detector absorber is considered. The particle track is finished when the detector is reached.
A 2D numpy array with the uncertainty for each energy deposition distribution bin
A 2D numpy array with the detected gamma fluence distribution normalized per history
A 2D numpy array with the uncertainty for each fluence distribution bin
if ‘only_check’ is true, the number of materials used to construct the device geometry is returned as a tuple with only one element. This can be used to know the first avaible material index, for user defined geometries construction.
- Return type:
- Raises:
ValueError – Incompatible value has been provided.
Example
import matplotlib.pyplot as plt import numpy as np import pyPenred results = pyPenred.simulation.xray.deviceSim(ebins=100, inherent_filter_width=0.15, anode_angle=16, source_to_detector=100.0, max_time=600, histories=1.0e8) # Extract energy and spatial ranges eLimits = results[0] xLimits = results[3] yLimits = results[4] # Create X values for energy spectrum e_plot = np.linspace(eLimits[0], eLimits[1], len(results[1])) # Plot spectrum plt.plot(e_plot, results[1]) plt.title("Device spectrum") plt.xlabel("keV") plt.ylabel("Prob/hist") plt.savefig('device-spectrum.png') plt.close() # Plot energy deposition plt.imshow(results[5], extent=[xLimits[0], xLimits[1], yLimits[0], yLimits[1]], aspect='auto', origin='lower', interpolation='none', cmap='viridis') plt.title("Detector energy deposition") plt.colorbar() plt.xlabel("X cm") plt.ylabel("Y cm") plt.savefig('detector-energy-deposition.png') plt.close() # Plot fluence plt.imshow(results[7], extent=[xLimits[0], xLimits[1], yLimits[0], yLimits[1]], aspect='auto', origin='lower', interpolation='none', cmap='viridis') plt.title("Detected fluence") plt.colorbar() plt.xlabel("X cm") plt.ylabel("Y cm") plt.savefig('detector-fluence.png')