Skip to content

Commit

Permalink
Add expanded config support to SeedSynthesizer.
Browse files Browse the repository at this point in the history
Co-authored-by: Alan Van Omen <[email protected]>
  • Loading branch information
tymorrow and alanjvano committed Dec 20, 2023
1 parent a83a483 commit 0bbcb6c
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 79 deletions.
81 changes: 81 additions & 0 deletions examples/data/synthesis/synthesize_seeds_advanced.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright 2021 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
# Under the terms of Contract DE-NA0003525 with NTESS,
# the U.S. Government retains certain rights in this software.
"""This example demonstrates how to generate synthetic seeds from GADRAS using PyRIID's
configuration expansion features."""
import yaml

from riid.data.synthetic.seed import SeedSynthesizer
from riid.gadras.api import get_expanded_config, validate_inject_config

seed_synth_config = """
---
gamma_detector:
name: Generic\\NaI\\2x4x16
parameters:
distance_cm:
- 10
- 100
- 1000
height_cm: 100
dead_time_per_pulse: 5
latitude_deg: 35.0
longitude_deg: 253.4
elevation_m: 1620
sources:
- isotope: Cs137
configurations:
- Cs137,100uCi
- name: Cs137
activity:
- 1
- 0.5
activity_units: Ci
shielding_atomic_number:
min: 10
max: 40.0
dist: uniform
num_samples: 5
shielding_aerial_density:
mean: 120
std: 2
num_samples: 5
- isotope: Cosmic
configurations:
- Cosmic
- isotope: K40
configurations:
- PotassiumInSoil
- isotope: Ra226
configurations:
- UraniumInSoil
- isotope: Th232
configurations:
- ThoriumInSoil
...
"""
seed_synth_config = yaml.safe_load(seed_synth_config)
validate_inject_config(seed_synth_config)
from pprint import pprint
pprint(len(get_expanded_config(seed_synth_config)["sources"][0]["configurations"]))

try:
seeds_ss = SeedSynthesizer().generate(
seed_synth_config,
verbose=True
)
print(seeds_ss)

# At this point, you could save out the seeds via:
seeds_ss.to_hdf("seeds.h5")

# or start separating your backgrounds from foreground for use with the StaticSynthesizer
fg_seeds_ss, bg_seeds_ss = seeds_ss.split_fg_and_bg()

print(fg_seeds_ss)
print(bg_seeds_ss)

fg_seeds_ss.to_hdf("./fg_seeds.h5")
bg_seeds_ss.to_hdf("./bg_seeds.h5")
except FileNotFoundError:
pass # Happens when not on Windows
50 changes: 17 additions & 33 deletions riid/data/synthetic/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from riid.data.sampleset import SampleSet, _get_utc_timestamp, read_pcf
from riid.gadras.api import (DETECTOR_PARAMS, GADRAS_ASSEMBLY_PATH,
INJECT_PARAMS, SourceInjector, get_gadras_api,
validate_inject_config)
get_inject_setups, validate_inject_config)


class SeedSynthesizer():
Expand Down Expand Up @@ -65,7 +65,7 @@ def _set_detector_parameters(self, gadras_api, new_parameters: dict, verbose=Fal

def generate(self, config: Union[str, dict],
normalize_spectra: bool = True, normalize_sources: bool = True,
dry_run=False, verbose: bool = False) -> SampleSet:
verbose: bool = False) -> SampleSet:
"""Produce a `SampleSet` containing foreground and/or background seeds using GADRAS based
on the given inject configuration.
Expand All @@ -75,8 +75,6 @@ def generate(self, config: Union[str, dict],
file which deserialized as a dictionary
normalize_spectra: whether to divide each row of `SampleSet.spectra` by each row's sum
normalize_sources: whether to divide each row of `SampleSet.sources` by each row's sum
dry_run: when False, actually perform inject(s), otherwise simply report info about
what would hypothetically happen
verbose: whether to show detailed output
Returns:
Expand All @@ -95,30 +93,25 @@ def generate(self, config: Union[str, dict],

validate_inject_config(config)

setups = get_inject_setups(config)
with self._cwd(GADRAS_ASSEMBLY_PATH):
gadras_api = get_gadras_api()
detector_name = config["gamma_detector"]["name"]
new_detector_parameters = config["gamma_detector"]["parameters"]
gadras_api.detectorSetCurrent(detector_name)
original_detector_parameters = self._get_detector_parameters(gadras_api)
now = _get_utc_timestamp().replace(":", "_") # replace() prevents error on Windows

rel_output_path = f"{now}_sources.pcf"
source_list = []
detector_setups = [new_detector_parameters] # TODO: generate all detector_setups
source_injector = SourceInjector(gadras_api)
try:
for d in detector_setups:
self._set_detector_parameters(gadras_api, d, verbose, dry_run)

if dry_run:
continue

if verbose:
print(f"Obtaining sources for '{detector_name}'")

for s in setups:
new_detector_parameters = s["gamma_detector"]["parameters"]
now = _get_utc_timestamp().replace(":", "_") # replace() prevents error on Windows
rel_output_path = f"{now}_sources.pcf"
source_list = []
try:
self._set_detector_parameters(gadras_api, new_detector_parameters, verbose)
# TODO: propagate dry_run to injectors

# Source injects
if verbose:
print(f"Obtaining sources for '{detector_name}'")
pcf_abs_path = source_injector.generate(
config,
rel_output_path,
Expand All @@ -130,22 +123,13 @@ def generate(self, config: Union[str, dict],
if normalize_spectra:
seeds_ss.normalize()
source_list.append(seeds_ss)

if verbose:
print()

if dry_run:
return None

except Exception as e:
# Try to restore .dat file to original state even when an error occurs
if not dry_run:
except Exception as e:
# Try to restore .dat file to original state even when an error occurs
self._set_detector_parameters(gadras_api, original_detector_parameters)
raise e
raise e

# Restore .dat file to original state
if not dry_run:
self._set_detector_parameters(gadras_api, original_detector_parameters)
self._set_detector_parameters(gadras_api, original_detector_parameters)

ss = SampleSet()
ss.concat(source_list)
Expand Down
26 changes: 17 additions & 9 deletions riid/gadras/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,15 +535,19 @@ def get_expanded_config(config: dict) -> dict:
return expanded_config


def get_detector_setups(expanded_config: dict):
"""
Permutate the lists of values in the expanded config to
def get_detector_setups(expanded_config: dict) -> list:
"""Permutate the lists of values in the expanded config to
generate a list of detector setups.
Args:
expanded_config: a dictionary representing an expanded seed synthesis configuration
Returns:
A list of detector setups
"""
detector_params = expanded_config["gamma_detector"]["parameters"]
list_of_parameters_values = [x for x in detector_params.values()]
parameter_permutations = list(itertools.product(*list_of_parameters_values))

detector_setups = []
for perm in parameter_permutations:
setup = copy.deepcopy(expanded_config["gamma_detector"])
Expand All @@ -554,13 +558,17 @@ def get_detector_setups(expanded_config: dict):
return detector_setups


def get_inject_setups(config: dict):
"""
Creates a list of dictionaries containing the individual detector_setups with
expanded sources.
def get_inject_setups(config: dict) -> list:
"""Get a list of fully expanded synthesis configurations from an initial,
collapsed configuration.
Args:
config: a dictionary representing a collapsed seed synthesis configuration
Returns:
A list of expanded configurations
"""
expanded_config = get_expanded_config(config)

detector_setups = get_detector_setups(expanded_config)
inject_setups = []
for detector_setup in detector_setups:
Expand Down
Loading

0 comments on commit 0bbcb6c

Please sign in to comment.