Compare commits

..

7 Commits

4 changed files with 52 additions and 5 deletions

View File

@ -98,7 +98,7 @@ def main():
if args.showplots:
plotter.plot()
if not (args.save and args.showplots):
if not (args.save or args.showplots):
logger.warning(
"No output produced. Use --save flag to save outputs and/or "
"--showplots to display interactive plots."

View File

@ -3,6 +3,7 @@ from typing import List
from pg_rad.landscape.landscape import Landscape
from pg_rad.simulator.outputs import (
CountRateOutput,
DetectorOutput,
SimulationOutput,
SourceOutput
)
@ -31,10 +32,13 @@ class SimulationEngine:
count_rate_results = self._calculate_count_rate_along_path()
source_results = self._calculate_point_source_distance_to_path()
detector_results = self._generate_detector_output()
return SimulationOutput(
name=self.landscape.name,
size=self.landscape.size,
count_rate=count_rate_results,
detector=detector_results,
sources=source_results
)
@ -79,3 +83,13 @@ class SimulationEngine:
)
return source_output
def _generate_detector_output(self) -> DetectorOutput:
return DetectorOutput(
name=self.detector.name,
type=self.detector.type,
is_isotropic=self.detector.is_isotropic,
field_eff=self.detector.get_efficiency(
self.landscape.point_sources[0].isotope.E
)
)

View File

@ -24,8 +24,18 @@ class SourceOutput:
dist_from_path: float
@dataclass
class DetectorOutput:
name: str
type: str
is_isotropic: bool
field_eff: float
@dataclass
class SimulationOutput:
name: str
size: tuple
detector: DetectorOutput
count_rate: CountRateOutput
sources: List[SourceOutput]

View File

@ -1,9 +1,11 @@
from dataclasses import asdict
from datetime import datetime as dt
import json
import os
import logging
import re
from numpy import array, full_like
from numpy import array, full_like, ndarray, bool_
from pandas import DataFrame
from pg_rad.simulator.outputs import SimulationOutput
@ -12,6 +14,15 @@ from pg_rad.simulator.outputs import SimulationOutput
logger = logging.getLogger(__name__)
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, ndarray):
return obj.tolist()
elif isinstance(obj, bool_):
return bool(obj)
return super().default(obj)
def generate_folder_name(sim: SimulationOutput) -> str:
formatted_sim_name = re.sub(r"\s+", '_', sim.name.lower())
folder_name = (
@ -35,9 +46,20 @@ def save_results(sim: SimulationOutput, folder_name: str) -> None:
df = generate_df(sim)
csv_name = generate_csv_name(sim)
df.to_csv(f"{folder_name}/{csv_name}.csv", index=False)
param_dict = generate_sim_param_dict(sim)
print(type(param_dict['detector']['is_isotropic']))
with open(f"{folder_name}/parameters.json", 'w') as f:
json.dump(param_dict, f, cls=NumpyEncoder)
logger.info(f"Simulation output saved to {folder_name}!")
def generate_sim_param_dict(sim: SimulationOutput) -> dict:
"""Parse simulation parameters and hyperparameters to dictionary."""
d = asdict(sim)
d.pop('count_rate')
return d
def generate_df(sim: SimulationOutput) -> DataFrame:
"""Parse simulation output to CSV format and the name of CSV."""
@ -62,13 +84,13 @@ def generate_df(sim: SimulationOutput) -> DataFrame:
def generate_csv_name(sim: SimulationOutput) -> str:
"""Generate CSV name according to Alex' specification"""
num_src = len(sim.sources)
src_ids = [str(i+1) for i in range(num_src)]
bkg_cps = round(sim.count_rate.mean_bkg_cps)
source_param_strings = [
[
str(round(s.activity))+"MBq",
str(round(s.dist_from_path))+"m",
str(round(s.position[0])),
str(round(s.position[1])),
str(round(s.position[0]))+'_'+str(round(s.position[1]))
]
for s in sim.sources
]
@ -82,5 +104,6 @@ def generate_csv_name(sim: SimulationOutput) -> str:
src_str = "_".join(src_str_array.flat)
csv_name = f"{num_src}_src_{bkg_cps}_cps_bkg_{src_str}"
src_ids_str = "_".join(src_ids)
csv_name = f"{src_ids_str}_src_{bkg_cps}_cps_bkg_{src_str}"
return csv_name