Add background functionality

This commit is contained in:
Pim Nelissen
2026-03-30 08:24:07 +02:00
parent 0a60bb09e9
commit c635c7f594
6 changed files with 43 additions and 11 deletions

View File

@ -9,11 +9,18 @@ from pg_rad.detector.detector import Detector
def generate_background(
cps_array: np.ndarray,
detector: Detector,
energy_keV: float,
) -> np.ndarray:
"""
Generate synthetic background cps for a given detector and energy.
"""
pass
ROI_lo, ROI_hi = get_roi_from_fwhm(detector, energy_keV)
lam = get_cps_from_roi(detector, ROI_lo, ROI_hi)
rng = np.random.default_rng()
return rng.poisson(lam=lam, size=cps_array.shape)
def fwhm(A: float, B: float, C: float, E: float) -> float:
@ -39,8 +46,13 @@ def get_cps_from_roi(
roi_hi: float
) -> float:
csv = files('pg_rad.data.backgrounds').joinpath(detector.name+'.csv')
data = read_csv(csv)
try:
csv = files('pg_rad.data.backgrounds').joinpath(detector.name+'.csv')
data = read_csv(csv)
except FileNotFoundError:
raise NotImplementedError(
f"Detector {detector.name} does not have backgrounds implemented."
)
# get indices of nearest bins
idx_min = (data["Energy"] - roi_lo).abs().idxmin()

View File

@ -0,0 +1,3 @@
Energy,Data,cps
0,0,0
10000,0,0
1 Energy Data cps
2 0 0 0
3 10000 0 0

View File

@ -111,7 +111,8 @@ def main():
OutOfBoundsError,
DimensionError,
InvalidIsotopeError,
InvalidConfigValueError
InvalidConfigValueError,
NotImplementedError
) as e:
logger.critical(e)
logger.critical(

View File

@ -2,6 +2,8 @@ from typing import Tuple, TYPE_CHECKING
import numpy as np
from pg_rad.background.background import generate_background
if TYPE_CHECKING:
from pg_rad.landscape.landscape import Landscape
from pg_rad.detector.detector import Detector
@ -146,12 +148,17 @@ def calculate_counts_along_path(
landscape, full_positions, detector
)
bkg = generate_background(
cps, detector, landscape.point_sources[0].isotope.E
)
cps_with_bg = cps# + bkg
# reshape so each segment is on a row
cps_per_seg = cps.reshape(num_segments, points_per_segment)
cps_per_seg = cps_with_bg.reshape(num_segments, points_per_segment)
du = s[1] - s[0]
integrated_counts = np.trapezoid(cps_per_seg, dx=du, axis=1) / velocity
int_counts_result = np.zeros(num_points)
int_counts_result[1:] = integrated_counts
return original_distances, s, cps, int_counts_result
return original_distances, s, cps_with_bg, int_counts_result, np.mean(bkg)

View File

@ -39,13 +39,21 @@ class SimulationEngine:
)
def _calculate_count_rate_along_path(self) -> CountRateOutput:
acq_points, sub_points, cps, int_counts = calculate_counts_along_path(
self.landscape,
self.detector,
velocity=self.runtime_spec.speed
acq_points, sub_points, cps, int_counts, mean_bkg_counts = (
calculate_counts_along_path(
self.landscape,
self.detector,
velocity=self.runtime_spec.speed
)
)
return CountRateOutput(acq_points, sub_points, cps, int_counts)
return CountRateOutput(
acq_points,
sub_points,
cps,
int_counts,
mean_bkg_counts
)
def _calculate_point_source_distance_to_path(self) -> List[SourceOutput]:

View File

@ -9,6 +9,7 @@ class CountRateOutput:
sub_points: List[float]
cps: List[float]
integrated_counts: List[float]
mean_bkg_cps: List[float]
@dataclass