Skip to content

Commit

Permalink
Merge pull request #1773 from bnmajor/physics-pkg-and-filters
Browse files Browse the repository at this point in the history
Separate physics package and detector filters
  • Loading branch information
psavery authored Jan 10, 2025
2 parents a1bef0a + d363b6d commit 8393744
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 108 deletions.
68 changes: 58 additions & 10 deletions hexrdgui/absorption_correction_options_dialog.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import h5py

from hexrdgui.hexrd_config import HexrdConfig
from hexrdgui.ui_loader import UiLoader

from hexrd.material import _angstroms, _kev, Material


class AbsorptionCorrectionOptionsDialog:

Expand Down Expand Up @@ -49,6 +45,12 @@ def load_additional_materials(self):
# FIXME: Update to use defaults once they've been added to HEXRD
return

@property
def any_detector_filters_applied(self):
det_names = HexrdConfig().detector_names
all_filters = [HexrdConfig().detector_filter(det) for det in det_names]
return any(filter.thickness > 0 for filter in all_filters)

def update_gui(self):
# Filter info is set per detector
self.ui.detectors.addItems(HexrdConfig().detector_names)
Expand All @@ -65,31 +67,41 @@ def update_gui(self):
w.insertSeparator(2 + len(custom_mats))

# Set default values
filter = HexrdConfig().detector_filter(self.ui.detectors.currentText())
coating = HexrdConfig().detector_coating(
self.ui.detectors.currentText())
phosphor = HexrdConfig().detector_phosphor(self.ui.detectors.currentText())
det = self.ui.detectors.currentText()
if (filter := HexrdConfig().detector_filter(det)) is None:
HexrdConfig().update_detector_filter(det)
filter = HexrdConfig().detector_filter(det)
if (coating := HexrdConfig().detector_coating(det)) is None:
HexrdConfig().update_detector_coating(det)
coating = HexrdConfig().detector_coating(det)
if (phosphor := HexrdConfig().detector_phosphor(det)) is None:
HexrdConfig().update_detector_phosphor(det)
phosphor = HexrdConfig().detector_phosphor(det)

# FILTER
if filter.material not in self.mat_options:
self.ui.filter_material_input.setText(filter.material)
else:
self.ui.filter_material.setCurrentText(filter.material)
self.ui.filter_density.setValue(filter.density)
self.ui.filter_thickness.setValue(filter.thickness)
self.ui.apply_filters.setChecked(self.any_detector_filters_applied)
# COATING
if coating.material not in self.mat_options:
self.ui.coating_material_input.setText(coating.material)
else:
self.ui.coating_material.setCurrentText(coating.material)
self.ui.coating_density.setValue(coating.density)
self.ui.coating_thickness.setValue(coating.thickness)
self.ui.apply_coating.setChecked(coating.thickness > 0)
# PHOSPHOR
if phosphor.material not in self.mat_options:
self.ui.phosphor_material_input.setText(phosphor.material)
else:
self.ui.phosphor_material.setCurrentText(phosphor.material)
self.ui.phosphor_density.setValue(phosphor.density)
self.ui.phosphor_thickness.setValue(phosphor.thickness)
self.ui.apply_phosphor.setChecked(phosphor.thickness > 0)
self.ui.phosphor_readout_length.setValue(phosphor.readout_length)
self.ui.phosphor_pre_U0.setValue(phosphor.pre_U0)

Expand All @@ -103,6 +115,9 @@ def setup_connections(self):
self.ui.button_box.accepted.connect(self.accept_changes)
self.ui.button_box.accepted.connect(self.ui.accept)
self.ui.button_box.rejected.connect(self.ui.reject)
self.ui.apply_filters.toggled.connect(self.toggle_apply_filters)
self.ui.apply_coating.toggled.connect(self.toggle_apply_coating)
self.ui.apply_phosphor.toggled.connect(self.toggle_apply_phosphor)

def exec(self):
return self.ui.exec()
Expand All @@ -127,8 +142,9 @@ def material_changed(self, index, category):
else:
self.density_inputs[category].setValue(0.0)

def filter_info_changed(self):
det_name = self.ui.detectors.currentText()
def filter_info_changed(self, new_value=None, det_name=None):
if det_name is None:
det_name = self.ui.detectors.currentText()
self.filters.setdefault(det_name, {})
self.filters[det_name]['density'] = self.ui.filter_density.value()
self.filters[det_name]['thickness'] = self.ui.filter_thickness.value()
Expand Down Expand Up @@ -173,3 +189,35 @@ def accept_changes(self):
density=self.ui.phosphor_density.value(),
thickness=self.ui.phosphor_thickness.value()
)

def toggle_apply_filters(self, checked):
if not checked:
self.ui.filter_thickness.setValue(0.0)
for det in HexrdConfig().detector_names:
self.filter_info_changed(det_name=det)
self.ui.detectors.setEnabled(checked)
self.ui.filter_material.setEnabled(checked)
index = self.ui.filter_material.currentIndex()
self.ui.filter_material_input.setEnabled(checked and index == 0)
self.ui.filter_density.setEnabled(checked)
self.ui.filter_thickness.setEnabled(checked)

def toggle_apply_coating(self, checked):
if not checked:
self.ui.coating_thickness.setValue(0.0)
self.ui.coating_material.setEnabled(checked)
index = self.ui.coating_material.currentIndex()
self.ui.coating_material_input.setEnabled(checked and index == 0)
self.ui.coating_density.setEnabled(checked)
self.ui.coating_thickness.setEnabled(checked)

def toggle_apply_phosphor(self, checked):
if not checked:
self.ui.phosphor_thickness.setValue(0.0)
self.ui.phosphor_material.setEnabled(checked)
index = self.ui.phosphor_material.currentIndex()
self.ui.phosphor_material_input.setEnabled(checked and index == 0)
self.ui.phosphor_density.setEnabled(checked)
self.ui.phosphor_thickness.setEnabled(checked)
self.ui.phosphor_readout_length.setEnabled(checked)
self.ui.phosphor_pre_U0.setEnabled(checked)
17 changes: 9 additions & 8 deletions hexrdgui/create_hedm_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ def create_hedm_instrument():

# Make sure that the physics package is included for instruments
# that expect it
if HexrdConfig().physics_package is not None:
if HexrdConfig().has_physics_package:
iconfig['physics_package'] = HexrdConfig().physics_package
for det in HexrdConfig().detector_names:
iconfig['detectors'][det]['filter'] = (
HexrdConfig().detector_filter(det))
iconfig['detectors'][det]['coating'] = (
HexrdConfig().detector_coating(det))
iconfig['detectors'][det]['phosphor'] = (
HexrdConfig().detector_phosphor(det))
if HexrdConfig().apply_absorption_correction:
for det in HexrdConfig().detector_names:
iconfig['detectors'][det]['filter'] = (
HexrdConfig().detector_filter(det))
iconfig['detectors'][det]['coating'] = (
HexrdConfig().detector_coating(det))
iconfig['detectors'][det]['phosphor'] = (
HexrdConfig().detector_phosphor(det))

kwargs = {
'instrument_config': iconfig,
Expand Down
67 changes: 44 additions & 23 deletions hexrdgui/hexrd_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import hexrd.imageseries.save
from hexrd.config.loader import NumPyIncludeLoader
from hexrd.instrument import HEDMInstrument
from hexrd.instrument.constants import PHYSICS_PACKAGE_DEFAULTS
from hexrd.instrument.constants import PHYSICS_PACKAGE_DEFAULTS, PINHOLE_DEFAULTS
from hexrd.instrument.physics_package import HEDPhysicsPackage
from hexrd.material import load_materials_hdf5, save_materials_hdf5, Material
from hexrd.rotations import RotMatEuler
Expand All @@ -27,7 +27,6 @@
from hexrdgui import utils
from hexrdgui.masking.constants import MaskType
from hexrdgui.singletons import QSingleton
from hexrdgui.utils.guess_instrument_type import guess_instrument_type

import hexrdgui.resources.calibration
import hexrdgui.resources.indexing
Expand Down Expand Up @@ -596,7 +595,7 @@ def set_overlays():
def set_physics_and_coatings():
pp = state.get('physics_package_dictified', None)
self.physics_package_dictified = pp if pp is not None else {}
dc = state.get('detector_coatings_dictified')
dc = state.get('detector_coatings_dictified', None)
self.detector_coatings_dictified = dc if dc is not None else {}

if 'detector_coatings_dictified' in state:
Expand Down Expand Up @@ -702,7 +701,7 @@ def overlays_dictified(self, v):
continue

if overlay_dict.get('tth_distortion_type') is not None:
if self.physics_package is None:
if not self.has_physics_package:
# We need to create a default physics package
# This is for backward compatibility
self.create_default_physics_package()
Expand Down Expand Up @@ -2434,7 +2433,7 @@ def custom_polar_tth_distortion_object_serialized(self):
def custom_polar_tth_distortion_object_serialized(self, v):
obj = None
if v is not None:
if self.physics_package is None:
if not self.has_physics_package:
# This requires a physics package to deserialize
self.create_default_physics_package()

Expand Down Expand Up @@ -3045,37 +3044,53 @@ def apply_absorption_correction(self, v):

@property
def physics_package_dictified(self):
if self.physics_package is None:
if not self.has_physics_package:
return None

return self.physics_package.serialize()

@physics_package_dictified.setter
def physics_package_dictified(self, v):
instr_type = guess_instrument_type(self.detector_names)
self.update_physics_package(instr_type, **v)
def physics_package_dictified(self, kwargs):
if not kwargs:
self.physics_package = None
return

# Set defaults if missing
kwargs = {
**PHYSICS_PACKAGE_DEFAULTS.HED,
**kwargs,
}
self.physics_package = HEDPhysicsPackage(**kwargs)

def update_physics_package(self, **kwargs):
self.physics_package_dictified = {
**self.physics_package_dictified,
**kwargs,
}

@property
def physics_package(self):
return self._physics_package

def update_physics_package(self, instr_type=None, **kwargs):
if instr_type not in ('TARDIS', 'PXRDIP'):
self._physics_package = None
elif self.physics_package is None:
all_kwargs = PHYSICS_PACKAGE_DEFAULTS.HED
all_kwargs.update(**kwargs)
self._physics_package = HEDPhysicsPackage(**all_kwargs)
else:
self._physics_package.deserialize(**kwargs)
self.physics_package_modified.emit()
@physics_package.setter
def physics_package(self, value):
if value != self._physics_package:
self._physics_package = value
self.physics_package_modified.emit()

@property
def has_physics_package(self) -> bool:
return self.physics_package is not None

def create_default_physics_package(self):
self._physics_package = HEDPhysicsPackage(
**PHYSICS_PACKAGE_DEFAULTS.HED)
self.physics_package_modified.emit()
# Our default will be an HED Physics package with a pinhole
self.physics_package_dictified = {
**PHYSICS_PACKAGE_DEFAULTS.HED,
**PINHOLE_DEFAULTS.TARDIS,
}

def absorption_length(self):
if self._physics_package is None:
if not self.has_physics_package:
raise ValueError(
f'Cannot calculate absorption length without physics package')
return self.physics_package.pinhole_absorption_length(
Expand Down Expand Up @@ -3129,6 +3144,8 @@ def detector_filter(self, det_name):
return self._detector_coatings[det_name].get('filter', None)

def update_detector_filter(self, det_name, **kwargs):
if det_name not in self.detector_names:
return None
self._set_detector_coatings('filter')
filter = self._detector_coatings[det_name]['filter']
filter.deserialize(**kwargs)
Expand All @@ -3138,6 +3155,8 @@ def detector_coating(self, det_name):
return self._detector_coatings[det_name].get('coating', None)

def update_detector_coating(self, det_name, **kwargs):
if det_name not in self.detector_names:
return None
self._set_detector_coatings('coating')
coating = self._detector_coatings[det_name]['coating']
coating.deserialize(**kwargs)
Expand All @@ -3147,6 +3166,8 @@ def detector_phosphor(self, det_name):
return self._detector_coatings[det_name].get('phosphor', None)

def update_detector_phosphor(self, det_name, **kwargs):
if det_name not in self.detector_names:
return None
self._set_detector_coatings('phosphor')
phosphor = self._detector_coatings[det_name]['phosphor']
phosphor.deserialize(**kwargs)
4 changes: 1 addition & 3 deletions hexrdgui/llnl_import_tool_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class LLNLImportToolDialog(QObject):

cancel_workflow = Signal()

def __init__(self, cmap=None, physics_package_manager=None, parent=None):
def __init__(self, cmap=None, parent=None):
super().__init__(parent)

loader = UiLoader()
Expand All @@ -59,7 +59,6 @@ def __init__(self, cmap=None, physics_package_manager=None, parent=None):
self.import_in_progress = False
self.loaded_images = []
self.canvas = parent.image_tab_widget.active_canvas
self.physics_package_manager = physics_package_manager

# Disable these by default.
# If we disable these in Qt Designer, there are some weird bugs
Expand Down Expand Up @@ -620,7 +619,6 @@ def completed(self):
self.ui.instrument.setDisabled(False)
HexrdConfig().enable_canvas_toolbar.emit(True)
self.cmap.block_updates(False)
self.physics_package_manager.show()

def show(self):
self.ui.show()
Expand Down
Loading

0 comments on commit 8393744

Please sign in to comment.