Skip to content

Commit

Permalink
GUI implementation old functionality almost complete
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroCubi committed Jul 26, 2023
1 parent 0aa6218 commit ab37505
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 83 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ old_data
*.prof
delete.py
*.xlsx
test_1d_benchmark
21 changes: 18 additions & 3 deletions f4e_radwaste/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,26 @@
KEY_RADWASTE_CLASS = "Radwaste class"
KEY_CDR = "Contact dose rate [Sv/h]"
KEY_DOSE_1_METER = "Dose 1 meter [Sv/h/g]"
TYPE_TFA = 0
TYPE_A = 1
TYPE_B = 2
TYPE_TFA_INT = 0
TYPE_A_INT = 1
TYPE_B_INT = 2
TYPE_TFA_STR = "TFA"
TYPE_A_STR = "Type A"
TYPE_B_STR = "Type B"


class CoordinateType(Enum):
CARTESIAN = "cartesian"
CYLINDRICAL = "cylindrical"


def get_radwaste_class_str_from_int(value: int) -> str:
if value == TYPE_TFA_INT:
return TYPE_TFA_STR
if value == TYPE_A_INT:
return TYPE_A_STR
if value == TYPE_B_INT:
return TYPE_B_STR
raise ValueError(
"The only acceptable radwaste class values in int form are 0, 1 and 2..."
)
8 changes: 5 additions & 3 deletions f4e_radwaste/data_formats/data_mass.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ def get_filtered_dataframe(

return super().get_filtered_dataframe(**filters)

def get_cells_and_masses_from_materials(
self, materials: List
def get_cells_and_masses_from_selection(
self, materials: Optional[List[int]] = None, voxels: Optional[List[int]] = None
) -> Tuple[List[int], pd.DataFrame]:
filtered_dataframe = self.get_filtered_dataframe(materials=materials)
filtered_dataframe = self.get_filtered_dataframe(
materials=materials, voxels=voxels
)
cells = filtered_dataframe.index.unique(level=KEY_CELL).values
voxel_masses = filtered_dataframe[KEY_MASS_GRAMS].groupby(KEY_VOXEL).sum()
return list(cells), voxel_masses
Expand Down
56 changes: 30 additions & 26 deletions f4e_radwaste/gui/gui_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,32 +217,36 @@ def button_pressed_load_stl_box(self):
self.active = True

def button_pressed_calculate_radwaste(self) -> DataMeshActivity | None:
pass
# grid = self.manager.data.grid
# if grid.n_cells == 0:
# return
# box = self.manager.main_window.overlaid_box_widget.box_grid
# if box.n_cells == 0:
# return
# # get the time and material from the combo boxes
# results_widget = self.manager.main_window.results_widget
# decay_time = results_widget.get_decay_time()
# materials = results_widget.get_materials()
# mask_cells_inside = self.get_mask_vtk_cells_inside_box(box, grid)
# voxels_inside = grid[KEY_R2S_INDICES][mask_cells_inside]
# pacakge_activity = collapse_data_by_time_material_and_voxels(
# data_absolute_activity=self.manager.data.data_absolute_activity,
# data_mass=self.manager.data.mesh_info.data_mass,
# decay_time=decay_time,
# materials=materials,
# voxels=voxels_inside,
# )
# # add the extra columns with radwaste relevant information
# classify_waste(pacakge_activity, self.manager.data.criteria_info)
# self.manager.main_window.results_widget.update_radwaste_display(
# pacakge_activity, self.manager.data.criteria_info
# )
# return pacakge_activity
grid = self.manager.grid

if grid.n_cells == 0:
return

box = self.manager.main_window.overlaid_box_widget.box_grid

if box.n_cells == 0:
return

# Get the time and material from the combo boxes
results_widget = self.manager.main_window.results_widget
decay_time = results_widget.get_decay_time()
materials = results_widget.get_materials()

mask_cells_inside = self.get_mask_vtk_cells_inside_box(box, grid)

voxels_inside = grid[KEY_R2S_INDICES][mask_cells_inside]

input_data = self.manager.processor.input_data
package_activity = input_data.get_collapsed_activity(
decay_time=decay_time, materials=materials, voxels=voxels_inside
)
pacakge_activity = classify_waste(package_activity, input_data.isotope_criteria)

self.manager.main_window.results_widget.update_radwaste_display(
pacakge_activity, input_data.isotope_criteria
)

return pacakge_activity

@staticmethod
def get_mask_vtk_cells_inside_box(box, value_grid):
Expand Down
4 changes: 2 additions & 2 deletions f4e_radwaste/gui/gui_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ def __init__(self):
self.grid: pv.StructuredGrid = pv.StructuredGrid()
self.geo_meshes: dict[str, pv.DataSet] = {}

self.functions = GUIFunctions(manager=self)
self.main_window = MainWindowGUI(manager=self)
self.functions: GUIFunctions = GUIFunctions(manager=self)
self.main_window: MainWindowGUI = MainWindowGUI(manager=self)

def start(self):
self.functions.active = True
Expand Down
6 changes: 3 additions & 3 deletions f4e_radwaste/gui/gui_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

class GUIProcessor:
def __init__(self, data_tables_folder_path: Path):
self.data_tables_folder_path = data_tables_folder_path
self.input_data = load_input_data_tables(data_tables_folder_path)
self.dose_calculator = DoseCalculator(
self.data_tables_folder_path: Path = data_tables_folder_path
self.input_data: InputData = load_input_data_tables(data_tables_folder_path)
self.dose_calculator: DoseCalculator = DoseCalculator(
dose_1_m_factors=read_dose_1_m_factors(),
cdr_factors=read_contact_dose_rate_factors(),
element_mix_by_material_id=read_element_mixes_of_materials(
Expand Down
3 changes: 3 additions & 0 deletions f4e_radwaste/gui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@


class MainWindowGUI(MainWindow):
overlaid_box_widget: OverlaidBoxWidget
results_widget: ResultsWidget

def __init__(self, manager):
self._app = QtWidgets.QApplication(sys.argv)
super().__init__()
Expand Down
63 changes: 32 additions & 31 deletions f4e_radwaste/gui/widgets/results_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

from qtpy import QtWidgets, QtCore

from f4e_radwaste.constants import KEY_TOTAL_SPECIFIC_ACTIVITY
from f4e_radwaste.constants import KEY_TOTAL_SPECIFIC_ACTIVITY, TYPE_B_STR
from f4e_radwaste.data_formats.data_isotope_criteria import DataIsotopeCriteria
from f4e_radwaste.data_formats.data_mesh_activity import DataMeshActivity

from f4e_radwaste.gui.gui_helpers import (
add_combo_box,
Expand All @@ -16,6 +18,7 @@
from f4e_radwaste.gui.widgets.custom_material_mixer_widget import (
CustomMaterialMixer,
)
from f4e_radwaste.post_processing.collapsed_data import CollapsedData


class MeshSelection:
Expand Down Expand Up @@ -240,33 +243,31 @@ def show_hide_display_options(self):
self.plotting_options.check_sample_data_over_geo.setVisible(checked)
self.plotting_options.check_log_scale.setVisible(checked)

# def update_radwaste_display(
# self, package_activity: DataVoxelActivity, criteria_info: CriteriaInfo
# ):
# radwaste_class_int = int(
# package_activity.get_value(voxel=0, isotope=KEY_RADWASTE_CLASS)
# )
# radwaste_class_str = get_radwaste_class_str_from_int(radwaste_class_int)
# self.radwaste_display.radwaste_type.setText(f"{radwaste_class_str}")
# mass_float_g = package_activity.get_value(
# voxel=0, isotope=COLUMN_KEY_MASS_GRAMS
# )
# self.radwaste_display.mass.setText(f"{mass_float_g / 1000:.2f}")
# self.radwaste_display.iras.setText(
# f"{package_activity.get_value(voxel=0, isotope=KEY_IRAS):.2f}"
# )
# self.radwaste_display.lma_isotopes.clear()
# # only call this function if type B
# if radwaste_class_str == "B":
# lma_exceeded_isotopes = get_isotopes_exceeding_lma_inside_package(
# package_activity, criteria_info
# )
# self.radwaste_display.lma_isotopes.addItems(lma_exceeded_isotopes)
# relevant_activity = package_activity.get_value(
# voxel=0, isotope=KEY_RELEVANT_SPECIFIC_ACTIVITY
# )
# self.radwaste_display.relevant_activity.setText(f"{relevant_activity:.2e}")
# total_activity = package_activity.get_value(
# voxel=0, isotope=KEY_TOTAL_SPECIFIC_ACTIVITY
# )
# self.radwaste_display.total_activity.setText(f"{total_activity:.2e}")
def update_radwaste_display(
self, package_activity: DataMeshActivity, isotope_criteria: DataIsotopeCriteria
):
collapsed_data = CollapsedData(package_activity)

radwaste_class = collapsed_data.get_radwaste_class_str()
self.radwaste_display.radwaste_type.setText(f"{radwaste_class}")

mass_grams = collapsed_data.get_mass()
self.radwaste_display.mass.setText(f"{mass_grams / 1000:.2f}")

iras = collapsed_data.get_iras()
self.radwaste_display.iras.setText(f"{iras:.2f}")

self.radwaste_display.lma_isotopes.clear()
if radwaste_class == TYPE_B_STR:
lma_exceeded_isotopes = collapsed_data.get_isotopes_exceeding_lma(
isotope_criteria
)
self.radwaste_display.lma_isotopes.addItems(lma_exceeded_isotopes)

relevant_activity = collapsed_data.get_relevant_activity()
self.radwaste_display.relevant_activity.setText(f"{relevant_activity:.2e}")

total_activity = collapsed_data.get_total_activity()
self.radwaste_display.total_activity.setText(f"{total_activity:.2e}")

self.radwaste_display.total_activity.setText(f"{total_activity:.2e}")
12 changes: 6 additions & 6 deletions f4e_radwaste/post_processing/classify_waste.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import pandas as pd

from f4e_radwaste.constants import (
TYPE_TFA,
TYPE_A,
TYPE_B,
TYPE_TFA_INT,
TYPE_A_INT,
TYPE_B_INT,
KEY_RADWASTE_CLASS,
KEY_IRAS,
KEY_LMA,
Expand All @@ -30,9 +30,9 @@ def classify_waste(
# Calculate radwaste class
mask_iras_exceeded = iras >= 1
mask_lma_exceeded = lma_exceeded >= 1
radwaste_class = pd.Series(data=TYPE_TFA, index=iras.index)
radwaste_class[mask_iras_exceeded] = TYPE_A
radwaste_class[mask_iras_exceeded * mask_lma_exceeded] = TYPE_B
radwaste_class = pd.Series(data=TYPE_TFA_INT, index=iras.index)
radwaste_class[mask_iras_exceeded] = TYPE_A_INT
radwaste_class[mask_iras_exceeded * mask_lma_exceeded] = TYPE_B_INT

# Get the activity of relevant isotopes (have a TFA class)
relevant_isotopes_activity = data_mesh_activity.get_filtered_dataframe(
Expand Down
39 changes: 39 additions & 0 deletions f4e_radwaste/post_processing/collapsed_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from typing import List

from f4e_radwaste.constants import (
KEY_RADWASTE_CLASS,
get_radwaste_class_str_from_int,
KEY_MASS_GRAMS,
KEY_IRAS, KEY_RELEVANT_SPECIFIC_ACTIVITY, KEY_TOTAL_SPECIFIC_ACTIVITY,
)
from f4e_radwaste.data_formats.data_isotope_criteria import DataIsotopeCriteria
from f4e_radwaste.data_formats.data_mesh_activity import DataMeshActivity


class CollapsedData:
def __init__(self, package_activity: DataMeshActivity):
self.dataframe = package_activity.get_filtered_dataframe()

def get_radwaste_class_str(self) -> str:
return get_radwaste_class_str_from_int(
self.dataframe[KEY_RADWASTE_CLASS].values[0]
)

def get_mass(self) -> float:
return self.dataframe[KEY_MASS_GRAMS].values[0]

def get_iras(self) -> float:
return self.dataframe[KEY_IRAS].values[0]

def get_isotopes_exceeding_lma(
self, isotope_criteria: DataIsotopeCriteria
) -> List[str]:
lma_exceeded_mask = self.dataframe.ge(isotope_criteria.lma).transpose()
column_name = lma_exceeded_mask.columns[0]
return lma_exceeded_mask[lma_exceeded_mask[column_name]].index.values.tolist()

def get_relevant_activity(self) -> float:
return self.dataframe[KEY_RELEVANT_SPECIFIC_ACTIVITY].values[0]

def get_total_activity(self) -> float:
return self.dataframe[KEY_TOTAL_SPECIFIC_ACTIVITY].values[0]
34 changes: 33 additions & 1 deletion f4e_radwaste/post_processing/input_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def get_mesh_activity_by_time_and_materials(
self, decay_time: float, materials: Optional[List[int]] = None
) -> DataMeshActivity:
data_mass = self.data_mesh_info.data_mass
selected_cells, voxel_masses = data_mass.get_cells_and_masses_from_materials(
selected_cells, voxel_masses = data_mass.get_cells_and_masses_from_selection(
materials
)

Expand Down Expand Up @@ -90,6 +90,38 @@ def get_mesh_activity_by_time_and_materials(

return DataMeshActivity(voxel_activity_dataframe)

def get_collapsed_activity(
self, decay_time: float, materials: List[int], voxels: List[int]
) -> DataMeshActivity:
data_mass = self.data_mesh_info.data_mass
selected_cells, voxel_masses = data_mass.get_cells_and_masses_from_selection(
materials, voxels
)

# Get the activity only at the cells, voxels and decay time of interest
filtered_activity = self.data_absolute_activity.get_filtered_dataframe(
decay_times=[decay_time],
cells=selected_cells,
voxels=voxels,
)

combined_activity = filtered_activity.groupby([KEY_ISOTOPE]).sum()

# Calculate the specific activity in Bq/g
package_mass = voxel_masses.sum()
voxel_specific_activity = combined_activity.div(package_mass, fill_value=0.0)

voxel_activity_dataframe = voxel_specific_activity.T

voxel_activity_dataframe.columns.name = None
voxel_activity_dataframe.index = [0]
voxel_activity_dataframe.index.name = KEY_VOXEL

# Add the mass information to the dataframe
voxel_activity_dataframe.insert(0, KEY_MASS_GRAMS, package_mass)

return DataMeshActivity(voxel_activity_dataframe)

def get_component_output_by_time_and_ids(
self,
decay_time: float,
Expand Down
9 changes: 7 additions & 2 deletions tests/test_data_formats/test_data_mass.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_get_filtered_dataframe_by_voxels_and_materials(self):
)
self.assertTrue(filtered_df.equals(expected_df))

def test_get_cells_and_masses_from_materials(self):
def test_get_cells_and_masses_from_selection(self):
data = {
KEY_VOXEL: [1, 2],
KEY_MASS_GRAMS: [2.34 + 3.13, 1.09],
Expand All @@ -65,11 +65,16 @@ def test_get_cells_and_masses_from_materials(self):
expected_masses.set_index([KEY_VOXEL], inplace=True)
expected_masses.columns.name = None

cells, masses = self.data_mass.get_cells_and_masses_from_materials(
cells, _masses = self.data_mass.get_cells_and_masses_from_selection(
materials=[10, 20]
)
self.assertListEqual([11, 12], cells)

_cells, masses = self.data_mass.get_cells_and_masses_from_selection(
materials=[10, 20], voxels=[2]
)
self.assertListEqual([1.09], masses.to_list())

def test_get_mass_from_cells(self):
result = self.data_mass.get_mass_from_cells([11, 12])
expected = 2.34 + 3.13 + 1.09
Expand Down
12 changes: 6 additions & 6 deletions tests/test_post_processing/test_classify_waste.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
KEY_RELEVANT_SPECIFIC_ACTIVITY,
KEY_IRAS,
KEY_RADWASTE_CLASS,
TYPE_TFA,
TYPE_A,
TYPE_B,
TYPE_TFA_INT,
TYPE_A_INT,
TYPE_B_INT,
)
from f4e_radwaste.data_formats.data_isotope_criteria import DataIsotopeCriteria
from f4e_radwaste.data_formats.data_mesh_activity import DataMeshActivity
Expand Down Expand Up @@ -72,12 +72,12 @@ def test_classify_waste(self):
self.assertEqual(relevant_activity_voxel_1, 4 + 5)
self.assertEqual(iras_voxel_1, 4 / 1000 + 5 / 100)
self.assertEqual(lma_voxel_1, 1)
self.assertEqual(radwaste_class_voxel_1, TYPE_TFA)
self.assertEqual(radwaste_class_voxel_1, TYPE_TFA_INT)

voxel_3_data = data_mesh_activity.get_filtered_dataframe(voxels=[3])
radwaste_class_voxel_3 = voxel_3_data[KEY_RADWASTE_CLASS].values[0]
self.assertEqual(radwaste_class_voxel_3, TYPE_A)
self.assertEqual(radwaste_class_voxel_3, TYPE_A_INT)

voxel_4_data = data_mesh_activity.get_filtered_dataframe(voxels=[4])
radwaste_class_voxel_4 = voxel_4_data[KEY_RADWASTE_CLASS].values[0]
self.assertEqual(radwaste_class_voxel_4, TYPE_B)
self.assertEqual(radwaste_class_voxel_4, TYPE_B_INT)

0 comments on commit ab37505

Please sign in to comment.