Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate physics package and detector filters #1773

Merged
merged 14 commits into from
Jan 10, 2025
Merged
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
Loading