From 00332c2aeec212134ea7320e0e05d4e71e50c1da Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 08:56:03 -0500 Subject: [PATCH 01/14] Do not use update function when removing physics package Rather than using the update_physics_package function to also remove the package (set it to None), set it to None explicitly. The update function should only be used for actually updating the package. Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 19 +++++++++++++------ hexrdgui/main_window.py | 4 ++-- hexrdgui/physics_package_manager_dialog.py | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index b9b4488fa..d0f28ee15 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -3058,24 +3058,31 @@ def physics_package_dictified(self, v): def physics_package(self): return self._physics_package + @physics_package.setter + def physics_package(self, value): + self._physics_package = value + 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: + raise ValueError( + f'Expected physics package instrument type to be either ' + f'"TARDIS" or "PXRDIP", got {instr_type} instead.' + ) + if self.physics_package is None: all_kwargs = PHYSICS_PACKAGE_DEFAULTS.HED all_kwargs.update(**kwargs) - self._physics_package = HEDPhysicsPackage(**all_kwargs) + self.physics_package = HEDPhysicsPackage(**all_kwargs) else: - self._physics_package.deserialize(**kwargs) + self.physics_package.deserialize(**kwargs) self.physics_package_modified.emit() def create_default_physics_package(self): - self._physics_package = HEDPhysicsPackage( + self.physics_package = HEDPhysicsPackage( **PHYSICS_PACKAGE_DEFAULTS.HED) self.physics_package_modified.emit() def absorption_length(self): - if self._physics_package is None: + if self.physics_package is None: raise ValueError( f'Cannot calculate absorption length without physics package') return self.physics_package.pinhole_absorption_length( diff --git a/hexrdgui/main_window.py b/hexrdgui/main_window.py index fd03c620d..37c9162f0 100644 --- a/hexrdgui/main_window.py +++ b/hexrdgui/main_window.py @@ -482,8 +482,8 @@ def update_physics_package_visibilities(self): # Turn off absorption correction self.ui.action_apply_absorption_correction.setChecked(False) - # Set the physics package to None - HexrdConfig().update_physics_package() + # Remove the physics package + HexrdConfig().physics_package = None # Turn off all detector coatings HexrdConfig().detector_coatings_dictified = {} diff --git a/hexrdgui/physics_package_manager_dialog.py b/hexrdgui/physics_package_manager_dialog.py index 0e7fde09c..bce3aded3 100644 --- a/hexrdgui/physics_package_manager_dialog.py +++ b/hexrdgui/physics_package_manager_dialog.py @@ -119,7 +119,7 @@ def update_instrument_type(self): HexrdConfig().update_detector_filter( det, **FILTER_DEFAULTS.PXRDIP) else: - HexrdConfig().update_physics_package(instr_type=None) + HexrdConfig().physics_package = None self.instrument_type = new_instr_type def setup_form(self): From 5f66209dfdd5113b5bc26f489900e673188c9616 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 11:27:28 -0500 Subject: [PATCH 02/14] Do not automatically create the physics package If the physics package is needed but missing, warn users and allow them to make the decision. Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 3 ++- hexrdgui/overlays/powder_overlay.py | 5 +++-- hexrdgui/pinhole_correction_editor.py | 6 +++--- hexrdgui/utils/physics_package.py | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index d0f28ee15..e701c0204 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -28,6 +28,7 @@ from hexrdgui.masking.constants import MaskType from hexrdgui.singletons import QSingleton from hexrdgui.utils.guess_instrument_type import guess_instrument_type +from hexrdgui.utils.physics_package import ask_to_create_physics_package_if_missing import hexrdgui.resources.calibration import hexrdgui.resources.indexing @@ -3082,7 +3083,7 @@ def create_default_physics_package(self): self.physics_package_modified.emit() def absorption_length(self): - if self.physics_package is None: + if not ask_to_create_physics_package_if_missing(): raise ValueError( f'Cannot calculate absorption length without physics package') return self.physics_package.pinhole_absorption_length( diff --git a/hexrdgui/overlays/powder_overlay.py b/hexrdgui/overlays/powder_overlay.py index 5bd6b9183..c6be2427b 100644 --- a/hexrdgui/overlays/powder_overlay.py +++ b/hexrdgui/overlays/powder_overlay.py @@ -17,6 +17,7 @@ from hexrdgui.utils.conversions import ( angles_to_cart, angles_to_stereo, cart_to_angles ) +from hexrdgui.utils.physics_package import ask_to_create_physics_package_if_missing from hexrdgui.utils.tth_distortion import apply_tth_distortion_if_needed @@ -83,9 +84,9 @@ def validate_tth_distortion_kwargs(self): from hexrdgui.hexrd_config import HexrdConfig if self.tth_distortion_type is not None: - if HexrdConfig().physics_package is None: + if not ask_to_create_physics_package_if_missing(): # This will require a physics package - HexrdConfig().create_default_physics_package() + return if self.tth_distortion_type == 'SampleLayerDistortion': # We added pinhole_radius later. Set a default if it is missing. diff --git a/hexrdgui/pinhole_correction_editor.py b/hexrdgui/pinhole_correction_editor.py index af0cd85b6..73baacebc 100644 --- a/hexrdgui/pinhole_correction_editor.py +++ b/hexrdgui/pinhole_correction_editor.py @@ -164,9 +164,9 @@ def correction_kwargs(self, v): vp[key] = value * multiplier - physics = HexrdConfig().physics_package - if physics is None: + if not ask_to_create_physics_package_if_missing(): return + physics = HexrdConfig().physics_package # Values are (key, default) values = { @@ -408,7 +408,7 @@ def enter_manually_idx(self): return 0 def on_rygg_absorption_length_selector_changed(self): - if HexrdConfig().physics_package is None: + if not ask_to_create_physics_package_if_missing(): # Cannot update return diff --git a/hexrdgui/utils/physics_package.py b/hexrdgui/utils/physics_package.py index a55df05ae..bd823cbf1 100644 --- a/hexrdgui/utils/physics_package.py +++ b/hexrdgui/utils/physics_package.py @@ -1,9 +1,9 @@ from PySide6.QtWidgets import QMessageBox -from hexrdgui.hexrd_config import HexrdConfig - def ask_to_create_physics_package_if_missing() -> bool: + from hexrdgui.hexrd_config import HexrdConfig # Avoid circular import + if HexrdConfig().physics_package is not None: return True From 1d7ec0be5d3affdf60011b85f7bdaba726c6faf3 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 11:39:36 -0500 Subject: [PATCH 03/14] Separate absorption correction from phsyics package Users can have one without the other - remove any interdependencies that previously prevented this. Signed-off-by: Brianna Major --- .../absorption_correction_options_dialog.py | 19 +++++++++++-------- hexrdgui/main_window.py | 13 ------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/hexrdgui/absorption_correction_options_dialog.py b/hexrdgui/absorption_correction_options_dialog.py index db2145e2d..5fa5bc13c 100644 --- a/hexrdgui/absorption_correction_options_dialog.py +++ b/hexrdgui/absorption_correction_options_dialog.py @@ -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: @@ -65,10 +61,17 @@ 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) diff --git a/hexrdgui/main_window.py b/hexrdgui/main_window.py index 37c9162f0..6bb91ac66 100644 --- a/hexrdgui/main_window.py +++ b/hexrdgui/main_window.py @@ -476,12 +476,8 @@ def update_physics_package_visibilities(self): visible = instr_type in ('TARDIS', 'PXRDIP') self.ui.action_physics_package_editor.setVisible(visible) - self.ui.action_apply_absorption_correction.setVisible(visible) if not visible: - # Turn off absorption correction - self.ui.action_apply_absorption_correction.setChecked(False) - # Remove the physics package HexrdConfig().physics_package = None @@ -1669,15 +1665,6 @@ def action_apply_absorption_correction_toggled(self, b): HexrdConfig().apply_absorption_correction = b return - # Make sure the physics package exists first - if HexrdConfig().physics_package is None: - msg = ( - 'Physics package must be set before absorption correction can be ' - 'applied. See the "Physics Package" editor under the "Edit" menu.' - ) - QMessageBox.warning(self.ui, 'HEXRD', msg) - return - # Get the user to first select the absorption correction options d = AbsorptionCorrectionOptionsDialog(self.ui) if not d.exec(): From 899ce25afa7e88944948eec6aaa48dc54af52d20 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 12:32:05 -0500 Subject: [PATCH 04/14] Use default of None if detector_coatings_dictified not found in state Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index e701c0204..5799ebb10 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -597,7 +597,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: From 9377f3ad2698c327e969d54fa06bcae98565720c Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 14:26:21 -0500 Subject: [PATCH 05/14] Reset detector coatings when detectors change Signed-off-by: Brianna Major --- hexrdgui/physics_package_manager_dialog.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hexrdgui/physics_package_manager_dialog.py b/hexrdgui/physics_package_manager_dialog.py index bce3aded3..7197351b2 100644 --- a/hexrdgui/physics_package_manager_dialog.py +++ b/hexrdgui/physics_package_manager_dialog.py @@ -73,9 +73,13 @@ def setup_connections(self): for k, w in self.material_selectors.items(): w.currentIndexChanged.connect( lambda index, k=k: self.material_changed(index, k)) - HexrdConfig().instrument_config_loaded.connect(self.update_instrument_type) + HexrdConfig().instrument_config_loaded.connect( + self.update_instrument_type) + HexrdConfig().detectors_changed(self.initialize_detector_coatings) def initialize_detector_coatings(self): + # Reset detector coatings to make sure they're in sync w/ current dets + HexrdConfig().detector_coatings_dictified = {} for det in HexrdConfig().detector_names: HexrdConfig().update_detector_filter(det) HexrdConfig().update_detector_coating(det) From a1f20c03c3b5acca460985342fc1a91e3095f47a Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 14:41:23 -0500 Subject: [PATCH 06/14] Do not set detector coatings unless absorption correction is applied Signed-off-by: Brianna Major --- hexrdgui/create_hedm_instrument.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hexrdgui/create_hedm_instrument.py b/hexrdgui/create_hedm_instrument.py index ffad161a4..6da00088d 100644 --- a/hexrdgui/create_hedm_instrument.py +++ b/hexrdgui/create_hedm_instrument.py @@ -22,13 +22,14 @@ def create_hedm_instrument(): # that expect it if HexrdConfig().physics_package is not None: 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, From ea8319919619d17cdf5602616516f2bf0fb9d3ae Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 16:11:37 -0500 Subject: [PATCH 07/14] Update physics package menu option The physics package option in the "edit" menu is no longer hidden based on instrument type. There are now two options: apply physics package, and edit physics package. Signed-off-by: Brianna Major --- hexrdgui/resources/ui/main_window.ui | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/hexrdgui/resources/ui/main_window.ui b/hexrdgui/resources/ui/main_window.ui index d90ad527f..3b6918f1c 100644 --- a/hexrdgui/resources/ui/main_window.ui +++ b/hexrdgui/resources/ui/main_window.ui @@ -213,6 +213,13 @@ + + + Physics Package + + + + @@ -221,7 +228,7 @@ - + @@ -873,9 +880,17 @@ Preconfigured - + + + true + + + Apply Physics Package + + + - Physics Package + Edit Physics Package From dce50bd9b21755254ffd0cadd1be7dd2fe71dbfa Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Wed, 8 Jan 2025 16:22:14 -0500 Subject: [PATCH 08/14] Do not limit the physics package to TARDIS and PXRDIP - Whether or not the Physics Package is used is now indicated by a separate flag: "use_physics_package". - Users can only edit the physics package if "use_physics_package" is true - If "apply physics package" is selected the package manager dialog will automatically be displayed - While the physics package is no longer limited to PXRDIP and TARDIS it is still automatically applied after using the LLNL Import tool. Signed-off-by: Brianna Major --- hexrdgui/create_hedm_instrument.py | 2 +- hexrdgui/hexrd_config.py | 33 ++++++++++------ hexrdgui/llnl_import_tool_dialog.py | 1 + hexrdgui/main_window.py | 46 +++++++++++++--------- hexrdgui/overlays/powder_overlay.py | 4 +- hexrdgui/physics_package_manager_dialog.py | 23 +++++------ hexrdgui/resources/ui/main_window.ui | 3 ++ hexrdgui/utils/physics_package.py | 2 +- 8 files changed, 65 insertions(+), 49 deletions(-) diff --git a/hexrdgui/create_hedm_instrument.py b/hexrdgui/create_hedm_instrument.py index 6da00088d..3a513c17a 100644 --- a/hexrdgui/create_hedm_instrument.py +++ b/hexrdgui/create_hedm_instrument.py @@ -20,7 +20,7 @@ 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().use_physics_package: iconfig['physics_package'] = HexrdConfig().physics_package if HexrdConfig().apply_absorption_correction: for det in HexrdConfig().detector_names: diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index 5799ebb10..4ea34de25 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -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 from hexrdgui.utils.physics_package import ask_to_create_physics_package_if_missing import hexrdgui.resources.calibration @@ -328,6 +327,7 @@ def __init__(self): self._physics_package = None self._detector_coatings = {} self._instrument_rigid_body_params = {} + self._use_physics_package = False # Make sure that the matplotlib font size matches the application self.font_size = self.font_size @@ -433,6 +433,7 @@ def _attributes_to_persist(self): ('_instrument_rigid_body_params', {}), ('recent_state_files', []), ('apply_absorption_correction', False), + ('use_physics_package', False), ('physics_package_dictified', None), ('custom_polar_tth_distortion_object_serialized', None), ('detector_coatings_dictified', {}), @@ -553,6 +554,8 @@ def load_from_state(self, state): self.show_all_colormaps = self.show_all_colormaps == 'true' if not isinstance(self.apply_absorption_correction, bool): self.apply_absorption_correction = self.apply_absorption_correction == 'true' + if not isinstance(self.use_physics_package, bool): + self.use_physics_package = self.use_physics_package == 'true' # This is None sometimes. Make sure it is an empty list instead. if self.recent_state_files is None: @@ -703,7 +706,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.use_physics_package: # We need to create a default physics package # This is for backward compatibility self.create_default_physics_package() @@ -2435,7 +2438,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.use_physics_package: # This requires a physics package to deserialize self.create_default_physics_package() @@ -3044,16 +3047,23 @@ def apply_absorption_correction(self, v): self._apply_absorption_correction = v self.deep_rerender_needed.emit() + @property + def use_physics_package(self): + return self._use_physics_package + + @use_physics_package.setter + def use_physics_package(self, v): + self._use_physics_package = v + @property def physics_package_dictified(self): - if self.physics_package is None: + if not self.use_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) + self.update_physics_package(**v) @property def physics_package(self): @@ -3062,14 +3072,10 @@ def physics_package(self): @physics_package.setter def physics_package(self, value): self._physics_package = value + self.use_physics_package = bool(value is None) - def update_physics_package(self, instr_type=None, **kwargs): - if instr_type not in ('TARDIS', 'PXRDIP'): - raise ValueError( - f'Expected physics package instrument type to be either ' - f'"TARDIS" or "PXRDIP", got {instr_type} instead.' - ) - if self.physics_package is None: + def update_physics_package(self, **kwargs): + if not self.use_physics_package: all_kwargs = PHYSICS_PACKAGE_DEFAULTS.HED all_kwargs.update(**kwargs) self.physics_package = HEDPhysicsPackage(**all_kwargs) @@ -3078,6 +3084,7 @@ def update_physics_package(self, instr_type=None, **kwargs): self.physics_package_modified.emit() def create_default_physics_package(self): + self.use_physics_package = True self.physics_package = HEDPhysicsPackage( **PHYSICS_PACKAGE_DEFAULTS.HED) self.physics_package_modified.emit() diff --git a/hexrdgui/llnl_import_tool_dialog.py b/hexrdgui/llnl_import_tool_dialog.py index a09e93dac..4ad33cc4c 100644 --- a/hexrdgui/llnl_import_tool_dialog.py +++ b/hexrdgui/llnl_import_tool_dialog.py @@ -620,6 +620,7 @@ def completed(self): self.ui.instrument.setDisabled(False) HexrdConfig().enable_canvas_toolbar.emit(True) self.cmap.block_updates(False) + HexrdConfig().use_physics_package = True self.physics_package_manager.show() def show(self): diff --git a/hexrdgui/main_window.py b/hexrdgui/main_window.py index 6bb91ac66..c39869968 100644 --- a/hexrdgui/main_window.py +++ b/hexrdgui/main_window.py @@ -78,7 +78,6 @@ from hexrdgui.ui_loader import UiLoader from hexrdgui.utils import block_signals, unique_name from hexrdgui.utils.dialog import add_help_url -from hexrdgui.utils.guess_instrument_type import guess_instrument_type from hexrdgui.utils.physics_package import ( ask_to_create_physics_package_if_missing, ) @@ -170,7 +169,6 @@ def __init__(self, parent=None, image_files=None): self.setup_connections() self.update_config_gui() - self.update_physics_package_visibilities() self.update_action_check_states() @@ -306,8 +304,11 @@ def setup_connections(self): self.on_action_edit_apply_threshold_triggered) self.ui.action_open_preconfigured_instrument_file.triggered.connect( self.on_action_open_preconfigured_instrument_file_triggered) - self.ui.action_physics_package_editor.triggered.connect( - self.on_action_physics_package_editor_triggered + self.ui.action_edit_physics_package.triggered.connect( + self.on_action_edit_physics_package_triggered + ) + self.ui.action_apply_physics_package.toggled.connect( + self.on_action_apply_physics_package_toggled ) self.image_mode_widget.polar_show_snip1d.connect( @@ -394,6 +395,7 @@ def update_action_check_states(self): 'action_show_all_colormaps': 'show_all_colormaps', 'action_apply_absorption_correction': 'apply_absorption_correction', + 'action_apply_physics_package': 'use_physics_package', } for cb_name, attr_name in checkbox_to_hexrd_config_mappings.items(): @@ -441,7 +443,6 @@ def enable_canvas_focus_mode(self, b): def on_instrument_config_loaded(self): self.update_config_gui() - self.update_physics_package_visibilities() def on_action_open_config_file_triggered(self): selected_file, selected_filter = QFileDialog.getOpenFileName( @@ -471,19 +472,6 @@ def on_action_save_config_hexrd_triggered(self): def on_action_save_config_yaml_triggered(self): self._save_config('.yml', 'YAML files (*.yml)') - def update_physics_package_visibilities(self): - instr_type = guess_instrument_type(HexrdConfig().detector_names) - visible = instr_type in ('TARDIS', 'PXRDIP') - - self.ui.action_physics_package_editor.setVisible(visible) - - if not visible: - # Remove the physics package - HexrdConfig().physics_package = None - - # Turn off all detector coatings - HexrdConfig().detector_coatings_dictified = {} - def open_grain_fitting_results(self): selected_file, _ = QFileDialog.getOpenFileName( self.ui, 'Open Grain Fitting File', HexrdConfig().working_dir, @@ -1656,9 +1644,29 @@ def on_action_open_preconfigured_instrument_file_triggered(self): with resource_loader.resource_path(instrument_templates, fname) as f: HexrdConfig().load_instrument_config(Path(f)) - def on_action_physics_package_editor_triggered(self): + def on_action_edit_physics_package_triggered(self): self.physics_package_manager_dialog.show() + def on_action_apply_physics_package_toggled(self, b): + self.ui.action_edit_physics_package.setEnabled(b) + if not b: + # Just turn it off and return + HexrdConfig().use_physics_package = b + return + + # Get the user to select the physics package options + dialog = self.physics_package_manager_dialog + dialog.show() + + dialog.ui.rejected.connect( + # Canceled... uncheck the action. + lambda: self.ui.action_apply_physics_package.setChecked(False) + ) + + # The user should have modified HexrdConfig's physics + # package options already. Just apply it now. + HexrdConfig().use_physics_package = b + def action_apply_absorption_correction_toggled(self, b): if not b: # Just turn it off and return diff --git a/hexrdgui/overlays/powder_overlay.py b/hexrdgui/overlays/powder_overlay.py index c6be2427b..53bc332bf 100644 --- a/hexrdgui/overlays/powder_overlay.py +++ b/hexrdgui/overlays/powder_overlay.py @@ -17,7 +17,9 @@ from hexrdgui.utils.conversions import ( angles_to_cart, angles_to_stereo, cart_to_angles ) -from hexrdgui.utils.physics_package import ask_to_create_physics_package_if_missing +from hexrdgui.utils.physics_package import ( + ask_to_create_physics_package_if_missing +) from hexrdgui.utils.tth_distortion import apply_tth_distortion_if_needed diff --git a/hexrdgui/physics_package_manager_dialog.py b/hexrdgui/physics_package_manager_dialog.py index 7197351b2..cbbde8900 100644 --- a/hexrdgui/physics_package_manager_dialog.py +++ b/hexrdgui/physics_package_manager_dialog.py @@ -75,7 +75,7 @@ def setup_connections(self): lambda index, k=k: self.material_changed(index, k)) HexrdConfig().instrument_config_loaded.connect( self.update_instrument_type) - HexrdConfig().detectors_changed(self.initialize_detector_coatings) + HexrdConfig().detectors_changed.connect(self.initialize_detector_coatings) def initialize_detector_coatings(self): # Reset detector coatings to make sure they're in sync w/ current dets @@ -103,27 +103,22 @@ def load_additional_materials(self): def update_instrument_type(self): new_instr_type = guess_instrument_type(HexrdConfig().detector_names) - if ( - new_instr_type == self.instrument_type or - new_instr_type not in ('TARDIS', 'PXRDIP') - ): + if new_instr_type == self.instrument_type: return self.initialize_detector_coatings() if new_instr_type == 'TARDIS': - HexrdConfig().update_physics_package( - new_instr_type, **PINHOLE_DEFAULTS.TARDIS) + HexrdConfig().update_physics_package(**PINHOLE_DEFAULTS.TARDIS) for det in HexrdConfig().detector_names: HexrdConfig().update_detector_filter( det, **FILTER_DEFAULTS.TARDIS) elif new_instr_type == 'PXRDIP': - HexrdConfig().update_physics_package( - new_instr_type, **PINHOLE_DEFAULTS.PXRDIP) + HexrdConfig().update_physics_package(**PINHOLE_DEFAULTS.PXRDIP) for det in HexrdConfig().detector_names: HexrdConfig().update_detector_filter( det, **FILTER_DEFAULTS.PXRDIP) else: - HexrdConfig().physics_package = None + HexrdConfig().create_default_physics_package() self.instrument_type = new_instr_type def setup_form(self): @@ -137,10 +132,10 @@ def setup_form(self): w.insertSeparator(2 + len(custom_mats)) # Set default values - physics = HexrdConfig().physics_package - if physics is None: + if not HexrdConfig().use_physics_package: return + physics = HexrdConfig().physics_package # PINHOLE self.ui.pinhole_material.setCurrentText(physics.pinhole_material) self.ui.pinhole_density.setValue(physics.pinhole_density) @@ -200,7 +195,7 @@ def material_changed(self, index, category): else: self.density_inputs[category].setValue(0.0) - if HexrdConfig().physics_package is not None: + if HexrdConfig().use_physics_package: self.ui.absorption_length.setValue(HexrdConfig().absorption_length()) def accept_changes(self): @@ -223,7 +218,7 @@ def accept_changes(self): 'pinhole_thickness': self.ui.pinhole_thickness.value(), 'pinhole_density': self.ui.pinhole_density.value(), } - HexrdConfig().update_physics_package(self.instrument_type, **kwargs) + HexrdConfig().update_physics_package(**kwargs) if HexrdConfig().apply_absorption_correction: # Make sure changes are reflected diff --git a/hexrdgui/resources/ui/main_window.ui b/hexrdgui/resources/ui/main_window.ui index 3b6918f1c..9514e8577 100644 --- a/hexrdgui/resources/ui/main_window.ui +++ b/hexrdgui/resources/ui/main_window.ui @@ -889,6 +889,9 @@ + + false + Edit Physics Package diff --git a/hexrdgui/utils/physics_package.py b/hexrdgui/utils/physics_package.py index bd823cbf1..2ae048ef6 100644 --- a/hexrdgui/utils/physics_package.py +++ b/hexrdgui/utils/physics_package.py @@ -4,7 +4,7 @@ def ask_to_create_physics_package_if_missing() -> bool: from hexrdgui.hexrd_config import HexrdConfig # Avoid circular import - if HexrdConfig().physics_package is not None: + if HexrdConfig().use_physics_package: return True msg = ( From 50e0e3c1a404e7d47092cba02281aaf2dc729c3d Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Thu, 9 Jan 2025 11:32:25 -0500 Subject: [PATCH 09/14] Keep use_physics_package in sync with package If "apply physics package" is selected make sure that we have a default physics package set if it was None. If we're setting the physics package to default we can infer we want to apply it as well. Keep the two states in sync. Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 9 ++++++--- hexrdgui/main_window.py | 23 ++++++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index 4ea34de25..351376263 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -3053,7 +3053,11 @@ def use_physics_package(self): @use_physics_package.setter def use_physics_package(self, v): - self._use_physics_package = v + if v != self.use_physics_package: + self._use_physics_package = v + self.physics_package_modified.emit() + if self.use_physics_package and self.physics_package is None: + self.create_default_physics_package() @property def physics_package_dictified(self): @@ -3072,7 +3076,7 @@ def physics_package(self): @physics_package.setter def physics_package(self, value): self._physics_package = value - self.use_physics_package = bool(value is None) + self.use_physics_package = bool(value is not None) def update_physics_package(self, **kwargs): if not self.use_physics_package: @@ -3084,7 +3088,6 @@ def update_physics_package(self, **kwargs): self.physics_package_modified.emit() def create_default_physics_package(self): - self.use_physics_package = True self.physics_package = HEDPhysicsPackage( **PHYSICS_PACKAGE_DEFAULTS.HED) self.physics_package_modified.emit() diff --git a/hexrdgui/main_window.py b/hexrdgui/main_window.py index c39869968..1a3fbb53c 100644 --- a/hexrdgui/main_window.py +++ b/hexrdgui/main_window.py @@ -172,6 +172,8 @@ def __init__(self, parent=None, image_files=None): self.update_action_check_states() + self.update_action_enable_states() + self.set_live_update(HexrdConfig().live_update) self.on_action_show_all_colormaps_toggled(HexrdConfig().show_all_colormaps) @@ -379,6 +381,7 @@ def setup_connections(self): def on_state_loaded(self): self.update_action_check_states() + self.update_action_enable_states() self.materials_panel.update_gui_from_config() def update_action_check_states(self): @@ -403,6 +406,16 @@ def update_action_check_states(self): with block_signals(cb): cb.setChecked(getattr(HexrdConfig(), attr_name)) + def update_action_enable_states(self): + enabled_to_hexrd_config_mappings = { + 'action_edit_physics_package': 'use_physics_package', + } + + for en_name, attr_name in enabled_to_hexrd_config_mappings.items(): + action = getattr(self.ui, en_name) + with block_signals(action): + action.setEnabled(getattr(HexrdConfig(), attr_name)) + def set_icon(self, icon): self.ui.setWindowIcon(icon) @@ -1658,15 +1671,19 @@ def on_action_apply_physics_package_toggled(self, b): dialog = self.physics_package_manager_dialog dialog.show() - dialog.ui.rejected.connect( + def _cancel(): # Canceled... uncheck the action. - lambda: self.ui.action_apply_physics_package.setChecked(False) - ) + self.ui.action_apply_physics_package.setChecked(False) + self.ui.action_edit_physics_package.setEnabled(b) + return + + dialog.ui.rejected.connect(_cancel) # The user should have modified HexrdConfig's physics # package options already. Just apply it now. HexrdConfig().use_physics_package = b + def action_apply_absorption_correction_toggled(self, b): if not b: # Just turn it off and return From aed62aec14297d687405ac29dce7c94a109bc664 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Thu, 9 Jan 2025 11:42:27 -0500 Subject: [PATCH 10/14] Do not update detector coatings for removed detectors This is for backwards compatability. Previously, when detector coatings were set after using the LLNL import tool the "default" detector (used to represent the current detector during import) was not removed after import was complete. This means that some old state files will have this value and try to fetch this detector's information, even though it no longer exists. Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index 351376263..4fed28e97 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -3147,6 +3147,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) @@ -3156,6 +3158,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) @@ -3165,6 +3169,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) From 62a6691aeb568d0a79305ed8c41c35c2e5eaa8d9 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Thu, 9 Jan 2025 11:53:12 -0500 Subject: [PATCH 11/14] Automatically apply Physics Package after LLNL import is complete Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 5 ++--- hexrdgui/llnl_import_tool_dialog.py | 5 +---- hexrdgui/main_window.py | 19 +++++++++---------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index 4fed28e97..484be3733 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -3079,12 +3079,11 @@ def physics_package(self, value): self.use_physics_package = bool(value is not None) def update_physics_package(self, **kwargs): - if not self.use_physics_package: + if 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.deserialize(**kwargs) self.physics_package_modified.emit() def create_default_physics_package(self): diff --git a/hexrdgui/llnl_import_tool_dialog.py b/hexrdgui/llnl_import_tool_dialog.py index 4ad33cc4c..9d6e12d34 100644 --- a/hexrdgui/llnl_import_tool_dialog.py +++ b/hexrdgui/llnl_import_tool_dialog.py @@ -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() @@ -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 @@ -620,8 +619,6 @@ def completed(self): self.ui.instrument.setDisabled(False) HexrdConfig().enable_canvas_toolbar.emit(True) self.cmap.block_updates(False) - HexrdConfig().use_physics_package = True - self.physics_package_manager.show() def show(self): self.ui.show() diff --git a/hexrdgui/main_window.py b/hexrdgui/main_window.py index 1a3fbb53c..44249cc86 100644 --- a/hexrdgui/main_window.py +++ b/hexrdgui/main_window.py @@ -138,7 +138,6 @@ def __init__(self, parent=None, image_files=None): self.simple_image_series_dialog = SimpleImageSeriesDialog(self.ui) self.llnl_import_tool_dialog = LLNLImportToolDialog( self.color_map_editor, - self.physics_package_manager_dialog, self.ui) self.image_stack_dialog = ImageStackDialog( self.ui, self.simple_image_series_dialog) @@ -1559,7 +1558,12 @@ def on_action_hedm_import_tool_triggered(self): self.simple_image_series_dialog.show() def on_action_llnl_import_tool_triggered(self): - self.llnl_import_tool_dialog.show() + dialog = self.llnl_import_tool_dialog + dialog.show() + # Always assume Physics Package is needed for LLNL import + dialog.ui.complete.clicked.connect( + lambda: self.on_action_apply_physics_package_toggled(True) + ) def on_action_image_stack_triggered(self): self.image_stack_dialog.show() @@ -1662,9 +1666,9 @@ def on_action_edit_physics_package_triggered(self): def on_action_apply_physics_package_toggled(self, b): self.ui.action_edit_physics_package.setEnabled(b) + HexrdConfig().use_physics_package = b if not b: # Just turn it off and return - HexrdConfig().use_physics_package = b return # Get the user to select the physics package options @@ -1674,16 +1678,11 @@ def on_action_apply_physics_package_toggled(self, b): def _cancel(): # Canceled... uncheck the action. self.ui.action_apply_physics_package.setChecked(False) - self.ui.action_edit_physics_package.setEnabled(b) - return + self.ui.action_edit_physics_package.setEnabled(False) + HexrdConfig().use_physics_package = False dialog.ui.rejected.connect(_cancel) - # The user should have modified HexrdConfig's physics - # package options already. Just apply it now. - HexrdConfig().use_physics_package = b - - def action_apply_absorption_correction_toggled(self, b): if not b: # Just turn it off and return From 7e3dc2b7da8ac26fd2e8ed6ac67773e4977e5734 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Thu, 9 Jan 2025 11:58:25 -0500 Subject: [PATCH 12/14] PEP8 fixes Signed-off-by: Brianna Major --- hexrdgui/hexrd_config.py | 4 +++- hexrdgui/physics_package_manager_dialog.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index 484be3733..b215a361c 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -27,7 +27,9 @@ from hexrdgui import utils from hexrdgui.masking.constants import MaskType from hexrdgui.singletons import QSingleton -from hexrdgui.utils.physics_package import ask_to_create_physics_package_if_missing +from hexrdgui.utils.physics_package import ( + ask_to_create_physics_package_if_missing +) import hexrdgui.resources.calibration import hexrdgui.resources.indexing diff --git a/hexrdgui/physics_package_manager_dialog.py b/hexrdgui/physics_package_manager_dialog.py index cbbde8900..76b2bc4c9 100644 --- a/hexrdgui/physics_package_manager_dialog.py +++ b/hexrdgui/physics_package_manager_dialog.py @@ -75,7 +75,8 @@ def setup_connections(self): lambda index, k=k: self.material_changed(index, k)) HexrdConfig().instrument_config_loaded.connect( self.update_instrument_type) - HexrdConfig().detectors_changed.connect(self.initialize_detector_coatings) + HexrdConfig().detectors_changed.connect( + self.initialize_detector_coatings) def initialize_detector_coatings(self): # Reset detector coatings to make sure they're in sync w/ current dets From 4a7a949918d4c749a19be214afcf8f54073a7344 Mon Sep 17 00:00:00 2001 From: Brianna Major Date: Thu, 9 Jan 2025 16:50:36 -0500 Subject: [PATCH 13/14] Allow users to disable detector coating, filter or phosphor Signed-off-by: Brianna Major --- .../absorption_correction_options_dialog.py | 43 ++++++++++++++++- hexrdgui/hexrd_config.py | 6 ++- .../absorption_correction_options_dialog.ui | 48 ++++++++++++++++--- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/hexrdgui/absorption_correction_options_dialog.py b/hexrdgui/absorption_correction_options_dialog.py index 5fa5bc13c..a2e13ae33 100644 --- a/hexrdgui/absorption_correction_options_dialog.py +++ b/hexrdgui/absorption_correction_options_dialog.py @@ -79,6 +79,7 @@ def update_gui(self): 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(filter.thickness > 0) # COATING if coating.material not in self.mat_options: self.ui.coating_material_input.setText(coating.material) @@ -86,6 +87,7 @@ def update_gui(self): 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) @@ -93,6 +95,7 @@ def update_gui(self): 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) @@ -106,6 +109,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() @@ -130,8 +136,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() @@ -176,3 +183,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) diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index b215a361c..1e72cc5ff 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -3058,8 +3058,10 @@ def use_physics_package(self, v): if v != self.use_physics_package: self._use_physics_package = v self.physics_package_modified.emit() - if self.use_physics_package and self.physics_package is None: - self.create_default_physics_package() + if self.use_physics_package: + self.create_default_physics_package() + else: + self.physics_package = None @property def physics_package_dictified(self): diff --git a/hexrdgui/resources/ui/absorption_correction_options_dialog.ui b/hexrdgui/resources/ui/absorption_correction_options_dialog.ui index 979a4519c..347f8afe3 100644 --- a/hexrdgui/resources/ui/absorption_correction_options_dialog.ui +++ b/hexrdgui/resources/ui/absorption_correction_options_dialog.ui @@ -6,8 +6,8 @@ 0 0 - 500 - 332 + 347 + 365 @@ -20,16 +20,46 @@ Absorption Correction Editor - + + + + Filter + + + true + + + + + + + Coating + + + true + + + + + + + Phosphor + + + true + + + + - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok - + QTabWidget::North @@ -308,6 +338,13 @@ + + + + Apply: + + + @@ -318,7 +355,6 @@ - tab_widget detectors filter_material filter_material_input From d363b6d0019841f73a783f3905f04c9b81ee7448 Mon Sep 17 00:00:00 2001 From: Patrick Avery Date: Thu, 9 Jan 2025 19:03:36 -0600 Subject: [PATCH 14/14] Some cleanup and simplifications I removed the `use_physics_package` variable from `HexrdConfig()` because it could have been simplified by simply checking if the physics package existed. I also fixed a few issues and cleaned up a few things. Signed-off-by: Patrick Avery --- .../absorption_correction_options_dialog.py | 8 +- hexrdgui/create_hedm_instrument.py | 2 +- hexrdgui/hexrd_config.py | 74 +++++++++---------- hexrdgui/main_window.py | 40 +++++----- hexrdgui/overlays/powder_overlay.py | 7 +- hexrdgui/physics_package_manager_dialog.py | 21 +++++- hexrdgui/pinhole_correction_editor.py | 11 +-- .../absorption_correction_options_dialog.ui | 6 +- hexrdgui/resources/ui/main_window.ui | 6 +- hexrdgui/utils/physics_package.py | 6 +- 10 files changed, 102 insertions(+), 79 deletions(-) diff --git a/hexrdgui/absorption_correction_options_dialog.py b/hexrdgui/absorption_correction_options_dialog.py index a2e13ae33..f72111c71 100644 --- a/hexrdgui/absorption_correction_options_dialog.py +++ b/hexrdgui/absorption_correction_options_dialog.py @@ -45,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) @@ -79,7 +85,7 @@ def update_gui(self): 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(filter.thickness > 0) + 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) diff --git a/hexrdgui/create_hedm_instrument.py b/hexrdgui/create_hedm_instrument.py index 3a513c17a..43bbff78a 100644 --- a/hexrdgui/create_hedm_instrument.py +++ b/hexrdgui/create_hedm_instrument.py @@ -20,7 +20,7 @@ def create_hedm_instrument(): # Make sure that the physics package is included for instruments # that expect it - if HexrdConfig().use_physics_package: + if HexrdConfig().has_physics_package: iconfig['physics_package'] = HexrdConfig().physics_package if HexrdConfig().apply_absorption_correction: for det in HexrdConfig().detector_names: diff --git a/hexrdgui/hexrd_config.py b/hexrdgui/hexrd_config.py index 1e72cc5ff..409064e5b 100644 --- a/hexrdgui/hexrd_config.py +++ b/hexrdgui/hexrd_config.py @@ -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 @@ -27,9 +27,6 @@ from hexrdgui import utils from hexrdgui.masking.constants import MaskType from hexrdgui.singletons import QSingleton -from hexrdgui.utils.physics_package import ( - ask_to_create_physics_package_if_missing -) import hexrdgui.resources.calibration import hexrdgui.resources.indexing @@ -329,7 +326,6 @@ def __init__(self): self._physics_package = None self._detector_coatings = {} self._instrument_rigid_body_params = {} - self._use_physics_package = False # Make sure that the matplotlib font size matches the application self.font_size = self.font_size @@ -435,7 +431,6 @@ def _attributes_to_persist(self): ('_instrument_rigid_body_params', {}), ('recent_state_files', []), ('apply_absorption_correction', False), - ('use_physics_package', False), ('physics_package_dictified', None), ('custom_polar_tth_distortion_object_serialized', None), ('detector_coatings_dictified', {}), @@ -556,8 +551,6 @@ def load_from_state(self, state): self.show_all_colormaps = self.show_all_colormaps == 'true' if not isinstance(self.apply_absorption_correction, bool): self.apply_absorption_correction = self.apply_absorption_correction == 'true' - if not isinstance(self.use_physics_package, bool): - self.use_physics_package = self.use_physics_package == 'true' # This is None sometimes. Make sure it is an empty list instead. if self.recent_state_files is None: @@ -708,7 +701,7 @@ def overlays_dictified(self, v): continue if overlay_dict.get('tth_distortion_type') is not None: - if not self.use_physics_package: + if not self.has_physics_package: # We need to create a default physics package # This is for backward compatibility self.create_default_physics_package() @@ -2440,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 not self.use_physics_package: + if not self.has_physics_package: # This requires a physics package to deserialize self.create_default_physics_package() @@ -3049,29 +3042,31 @@ def apply_absorption_correction(self, v): self._apply_absorption_correction = v self.deep_rerender_needed.emit() - @property - def use_physics_package(self): - return self._use_physics_package - - @use_physics_package.setter - def use_physics_package(self, v): - if v != self.use_physics_package: - self._use_physics_package = v - self.physics_package_modified.emit() - if self.use_physics_package: - self.create_default_physics_package() - else: - self.physics_package = None - @property def physics_package_dictified(self): - if not self.use_physics_package: + if not self.has_physics_package: return None + return self.physics_package.serialize() @physics_package_dictified.setter - def physics_package_dictified(self, v): - self.update_physics_package(**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): @@ -3079,24 +3074,23 @@ def physics_package(self): @physics_package.setter def physics_package(self, value): - self._physics_package = value - self.use_physics_package = bool(value is not None) + if value != self._physics_package: + self._physics_package = value + self.physics_package_modified.emit() - def update_physics_package(self, **kwargs): - if self.physics_package is None: - all_kwargs = PHYSICS_PACKAGE_DEFAULTS.HED - all_kwargs.update(**kwargs) - self.physics_package = HEDPhysicsPackage(**all_kwargs) - self.physics_package.deserialize(**kwargs) - 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 not ask_to_create_physics_package_if_missing(): + if not self.has_physics_package: raise ValueError( f'Cannot calculate absorption length without physics package') return self.physics_package.pinhole_absorption_length( diff --git a/hexrdgui/main_window.py b/hexrdgui/main_window.py index 44249cc86..951d5bfb9 100644 --- a/hexrdgui/main_window.py +++ b/hexrdgui/main_window.py @@ -308,8 +308,8 @@ def setup_connections(self): self.ui.action_edit_physics_package.triggered.connect( self.on_action_edit_physics_package_triggered ) - self.ui.action_apply_physics_package.toggled.connect( - self.on_action_apply_physics_package_toggled + self.ui.action_include_physics_package.toggled.connect( + self.on_action_include_physics_package_toggled ) self.image_mode_widget.polar_show_snip1d.connect( @@ -336,6 +336,8 @@ def setup_connections(self): self.update_mask_region_canvas) HexrdConfig().update_instrument_toolbox.connect( self.update_config_gui) + HexrdConfig().physics_package_modified.connect( + self.on_physics_package_modified) ImageLoadManager().update_needed.connect(self.update_all) ImageLoadManager().new_images_loaded.connect(self.new_images_loaded) @@ -378,6 +380,11 @@ def setup_connections(self): HexrdConfig().enable_canvas_focus_mode.connect( self.enable_canvas_focus_mode) + # Always assume Physics Package is needed for LLNL import + self.llnl_import_tool_dialog.ui.complete.clicked.connect( + lambda: self.on_action_include_physics_package_toggled(True) + ) + def on_state_loaded(self): self.update_action_check_states() self.update_action_enable_states() @@ -397,7 +404,7 @@ def update_action_check_states(self): 'action_show_all_colormaps': 'show_all_colormaps', 'action_apply_absorption_correction': 'apply_absorption_correction', - 'action_apply_physics_package': 'use_physics_package', + 'action_include_physics_package': 'has_physics_package', } for cb_name, attr_name in checkbox_to_hexrd_config_mappings.items(): @@ -407,7 +414,7 @@ def update_action_check_states(self): def update_action_enable_states(self): enabled_to_hexrd_config_mappings = { - 'action_edit_physics_package': 'use_physics_package', + 'action_edit_physics_package': 'has_physics_package', } for en_name, attr_name in enabled_to_hexrd_config_mappings.items(): @@ -1560,10 +1567,6 @@ def on_action_hedm_import_tool_triggered(self): def on_action_llnl_import_tool_triggered(self): dialog = self.llnl_import_tool_dialog dialog.show() - # Always assume Physics Package is needed for LLNL import - dialog.ui.complete.clicked.connect( - lambda: self.on_action_apply_physics_package_toggled(True) - ) def on_action_image_stack_triggered(self): self.image_stack_dialog.show() @@ -1664,24 +1667,27 @@ def on_action_open_preconfigured_instrument_file_triggered(self): def on_action_edit_physics_package_triggered(self): self.physics_package_manager_dialog.show() - def on_action_apply_physics_package_toggled(self, b): + def on_action_include_physics_package_toggled(self, b): self.ui.action_edit_physics_package.setEnabled(b) - HexrdConfig().use_physics_package = b + if b and not HexrdConfig().has_physics_package: + HexrdConfig().create_default_physics_package() + if not b: # Just turn it off and return + HexrdConfig().physics_package = None return # Get the user to select the physics package options dialog = self.physics_package_manager_dialog - dialog.show() + dialog.show(delete_if_canceled=True) - def _cancel(): - # Canceled... uncheck the action. - self.ui.action_apply_physics_package.setChecked(False) - self.ui.action_edit_physics_package.setEnabled(False) - HexrdConfig().use_physics_package = False + def on_physics_package_modified(self): + enable = HexrdConfig().has_physics_package + w = self.ui.action_include_physics_package + with block_signals(w): + w.setChecked(enable) - dialog.ui.rejected.connect(_cancel) + self.ui.action_edit_physics_package.setEnabled(enable) def action_apply_absorption_correction_toggled(self, b): if not b: diff --git a/hexrdgui/overlays/powder_overlay.py b/hexrdgui/overlays/powder_overlay.py index 53bc332bf..c0b63f91f 100644 --- a/hexrdgui/overlays/powder_overlay.py +++ b/hexrdgui/overlays/powder_overlay.py @@ -17,9 +17,6 @@ from hexrdgui.utils.conversions import ( angles_to_cart, angles_to_stereo, cart_to_angles ) -from hexrdgui.utils.physics_package import ( - ask_to_create_physics_package_if_missing -) from hexrdgui.utils.tth_distortion import apply_tth_distortion_if_needed @@ -86,9 +83,9 @@ def validate_tth_distortion_kwargs(self): from hexrdgui.hexrd_config import HexrdConfig if self.tth_distortion_type is not None: - if not ask_to_create_physics_package_if_missing(): + if not HexrdConfig().has_physics_package: # This will require a physics package - return + HexrdConfig().create_default_physics_package() if self.tth_distortion_type == 'SampleLayerDistortion': # We added pinhole_radius later. Set a default if it is missing. diff --git a/hexrdgui/physics_package_manager_dialog.py b/hexrdgui/physics_package_manager_dialog.py index 76b2bc4c9..b9754391c 100644 --- a/hexrdgui/physics_package_manager_dialog.py +++ b/hexrdgui/physics_package_manager_dialog.py @@ -25,6 +25,7 @@ def __init__(self, parent=None): self.ui = loader.load_file('physics_package_manager_dialog.ui', parent) self.additional_materials = {} self.instrument_type = None + self.delete_if_canceled = False canvas = FigureCanvas(Figure(tight_layout=True)) # Get the canvas to take up the majority of the screen most of the time @@ -36,7 +37,8 @@ def __init__(self, parent=None): self.update_instrument_type() self.setup_connections() - def show(self): + def show(self, delete_if_canceled=False): + self.delete_if_canceled = delete_if_canceled self.setup_form() self.ui.show() @@ -78,6 +80,18 @@ def setup_connections(self): HexrdConfig().detectors_changed.connect( self.initialize_detector_coatings) + self.ui.accepted.connect(self.on_accepted) + self.ui.rejected.connect(self.on_rejected) + + def on_accepted(self): + self.delete_if_canceled = False + + def on_rejected(self): + if self.delete_if_canceled: + HexrdConfig().physics_package = None + + self.delete_if_canceled = False + def initialize_detector_coatings(self): # Reset detector coatings to make sure they're in sync w/ current dets HexrdConfig().detector_coatings_dictified = {} @@ -133,7 +147,7 @@ def setup_form(self): w.insertSeparator(2 + len(custom_mats)) # Set default values - if not HexrdConfig().use_physics_package: + if not HexrdConfig().has_physics_package: return physics = HexrdConfig().physics_package @@ -180,6 +194,7 @@ def toggle_pinhole(self, enabled): def material_changed(self, index, category): material = self.material_selectors[category].currentText() + self.material_inputs[category].setEnabled(index == 0) self.density_inputs[category].setEnabled(index == 0) if category == 'pinhole': @@ -196,7 +211,7 @@ def material_changed(self, index, category): else: self.density_inputs[category].setValue(0.0) - if HexrdConfig().use_physics_package: + if HexrdConfig().has_physics_package: self.ui.absorption_length.setValue(HexrdConfig().absorption_length()) def accept_changes(self): diff --git a/hexrdgui/pinhole_correction_editor.py b/hexrdgui/pinhole_correction_editor.py index 73baacebc..2783ef846 100644 --- a/hexrdgui/pinhole_correction_editor.py +++ b/hexrdgui/pinhole_correction_editor.py @@ -154,6 +154,11 @@ def correction_kwargs(self, v): if v is None: return + if not HexrdConfig().has_physics_package: + return + + physics = HexrdConfig().physics_package + vp = v.copy() # These units are in mm, but we display in micrometers for key, value in v.items(): @@ -164,10 +169,6 @@ def correction_kwargs(self, v): vp[key] = value * multiplier - if not ask_to_create_physics_package_if_missing(): - return - physics = HexrdConfig().physics_package - # Values are (key, default) values = { 'sample_layer_standoff': ('layer_standoff', @@ -408,7 +409,7 @@ def enter_manually_idx(self): return 0 def on_rygg_absorption_length_selector_changed(self): - if not ask_to_create_physics_package_if_missing(): + if not HexrdConfig().has_physics_package: # Cannot update return diff --git a/hexrdgui/resources/ui/absorption_correction_options_dialog.ui b/hexrdgui/resources/ui/absorption_correction_options_dialog.ui index 347f8afe3..383838073 100644 --- a/hexrdgui/resources/ui/absorption_correction_options_dialog.ui +++ b/hexrdgui/resources/ui/absorption_correction_options_dialog.ui @@ -7,7 +7,7 @@ 0 0 347 - 365 + 443 @@ -355,6 +355,10 @@ + apply_filters + apply_coating + apply_phosphor + tab_widget detectors filter_material filter_material_input diff --git a/hexrdgui/resources/ui/main_window.ui b/hexrdgui/resources/ui/main_window.ui index 9514e8577..1de087036 100644 --- a/hexrdgui/resources/ui/main_window.ui +++ b/hexrdgui/resources/ui/main_window.ui @@ -217,7 +217,7 @@ Physics Package - + @@ -880,12 +880,12 @@ Preconfigured - + true - Apply Physics Package + Include Physics Package diff --git a/hexrdgui/utils/physics_package.py b/hexrdgui/utils/physics_package.py index 2ae048ef6..6d2787c16 100644 --- a/hexrdgui/utils/physics_package.py +++ b/hexrdgui/utils/physics_package.py @@ -1,10 +1,10 @@ from PySide6.QtWidgets import QMessageBox +from hexrdgui.hexrd_config import HexrdConfig -def ask_to_create_physics_package_if_missing() -> bool: - from hexrdgui.hexrd_config import HexrdConfig # Avoid circular import - if HexrdConfig().use_physics_package: +def ask_to_create_physics_package_if_missing() -> bool: + if HexrdConfig().has_physics_package: return True msg = (