Skip to content

Commit

Permalink
Merge pull request #1728 from HEXRD/wppf-fixes
Browse files Browse the repository at this point in the history
Add a variety of fixes and improvements to WPPF
  • Loading branch information
psavery authored Sep 26, 2024
2 parents e9a0174 + cac118b commit 83fbb0f
Show file tree
Hide file tree
Showing 16 changed files with 994 additions and 450 deletions.
99 changes: 7 additions & 92 deletions hexrdgui/calibration/calibration_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import yaml

from PySide6.QtCore import QObject, Qt, Signal
from PySide6.QtGui import QColor
from PySide6.QtWidgets import QComboBox, QDoubleSpinBox, QMessageBox, QSpinBox

from hexrd.fitting.calibration.lmfit_param_handling import (
Expand All @@ -12,11 +11,15 @@
)

from hexrdgui import resource_loader
from hexrdgui.calibration.tree_item_models import (
DefaultCalibrationTreeItemModel,
DeltaCalibrationTreeItemModel,
)
from hexrdgui.constants import ViewType
from hexrdgui.hexrd_config import HexrdConfig
from hexrdgui.pinhole_correction_editor import PinholeCorrectionEditor
from hexrdgui.tree_views.multi_column_dict_tree_view import (
MultiColumnDictTreeItemModel, MultiColumnDictTreeView
MultiColumnDictTreeView
)
from hexrdgui.ui_loader import UiLoader
from hexrdgui.utils.dialog import add_help_url
Expand Down Expand Up @@ -557,97 +560,9 @@ def tree_view_columns(self):
@property
def tree_view_model_class(self):
if self.delta_boundaries:
return DeltaTreeItemModel
return DeltaCalibrationTreeItemModel
else:
return DefaultTreeItemModel


def _tree_columns_to_indices(columns):
return {
'Key': 0,
**{
k: list(columns).index(k) + 1 for k in columns
}
}


class TreeItemModel(MultiColumnDictTreeItemModel):
"""Subclass the tree item model so we can customize some behavior"""

def set_config_val(self, path, value):
super().set_config_val(path, value)
# Now set the parameter too
param_path = path[:-1] + ['_param']
try:
param = self.config_val(param_path)
except KeyError:
raise Exception('Failed to set parameter!', param_path)

# Now set the attribute on the param
attribute = path[-1].removeprefix('_')

setattr(param, attribute, value)


class DefaultTreeItemModel(TreeItemModel):
"""This model uses minimum/maximum for the boundary constraints"""
COLUMNS = {
'Value': '_value',
'Vary': '_vary',
'Minimum': '_min',
'Maximum': '_max',
}
COLUMN_INDICES = _tree_columns_to_indices(COLUMNS)

VALUE_IDX = COLUMN_INDICES['Value']
MAX_IDX = COLUMN_INDICES['Maximum']
MIN_IDX = COLUMN_INDICES['Minimum']
BOUND_INDICES = (VALUE_IDX, MAX_IDX, MIN_IDX)

def data(self, index, role):
if role == Qt.ForegroundRole and index.column() in self.BOUND_INDICES:
# If a value hit the boundary, color both the boundary and the
# value red.
item = self.get_item(index)
if not item.child_items:
atol = 1e-3
pairs = [
(self.VALUE_IDX, self.MAX_IDX),
(self.VALUE_IDX, self.MIN_IDX),
]
for pair in pairs:
if index.column() not in pair:
continue

if abs(item.data(pair[0]) - item.data(pair[1])) < atol:
return QColor('red')

return super().data(index, role)


class DeltaTreeItemModel(TreeItemModel):
"""This model uses the delta for the parameters"""
COLUMNS = {
'Value': '_value',
'Vary': '_vary',
'Delta': '_delta',
}
COLUMN_INDICES = _tree_columns_to_indices(COLUMNS)

VALUE_IDX = COLUMN_INDICES['Value']
DELTA_IDX = COLUMN_INDICES['Delta']
BOUND_INDICES = (VALUE_IDX, DELTA_IDX)

def data(self, index, role):
if role == Qt.ForegroundRole and index.column() in self.BOUND_INDICES:
# If a delta is zero, color both the delta and the value red.
item = self.get_item(index)
if not item.child_items:
atol = 1e-3
if abs(item.data(self.DELTA_IDX)) < atol:
return QColor('red')

return super().data(index, role)
return DefaultCalibrationTreeItemModel


TILT_LABELS_EULER = {
Expand Down
94 changes: 94 additions & 0 deletions hexrdgui/calibration/tree_item_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from PySide6.QtCore import Qt
from PySide6.QtGui import QColor

from hexrdgui.tree_views.multi_column_dict_tree_view import (
MultiColumnDictTreeItemModel
)


def _tree_columns_to_indices(columns):
return {
'Key': 0,
**{
k: list(columns).index(k) + 1 for k in columns
}
}


class CalibrationTreeItemModel(MultiColumnDictTreeItemModel):
"""Subclass the tree item model so we can customize some behavior"""

def set_config_val(self, path, value):
super().set_config_val(path, value)
# Now set the parameter too
param_path = path[:-1] + ['_param']
try:
param = self.config_val(param_path)
except KeyError:
raise Exception('Failed to set parameter!', param_path)

# Now set the attribute on the param
attribute = path[-1].removeprefix('_')

setattr(param, attribute, value)


class DefaultCalibrationTreeItemModel(CalibrationTreeItemModel):
"""This model uses minimum/maximum for the boundary constraints"""
COLUMNS = {
'Value': '_value',
'Vary': '_vary',
'Minimum': '_min',
'Maximum': '_max',
}
COLUMN_INDICES = _tree_columns_to_indices(COLUMNS)

VALUE_IDX = COLUMN_INDICES['Value']
MAX_IDX = COLUMN_INDICES['Maximum']
MIN_IDX = COLUMN_INDICES['Minimum']
BOUND_INDICES = (VALUE_IDX, MAX_IDX, MIN_IDX)

def data(self, index, role):
if role == Qt.ForegroundRole and index.column() in self.BOUND_INDICES:
# If a value hit the boundary, color both the boundary and the
# value red.
item = self.get_item(index)
if not item.child_items:
atol = 1e-3
pairs = [
(self.VALUE_IDX, self.MAX_IDX),
(self.VALUE_IDX, self.MIN_IDX),
]
for pair in pairs:
if index.column() not in pair:
continue

if abs(item.data(pair[0]) - item.data(pair[1])) < atol:
return QColor('red')

return super().data(index, role)


class DeltaCalibrationTreeItemModel(CalibrationTreeItemModel):
"""This model uses the delta for the parameters"""
COLUMNS = {
'Value': '_value',
'Vary': '_vary',
'Delta': '_delta',
}
COLUMN_INDICES = _tree_columns_to_indices(COLUMNS)

VALUE_IDX = COLUMN_INDICES['Value']
DELTA_IDX = COLUMN_INDICES['Delta']
BOUND_INDICES = (VALUE_IDX, DELTA_IDX)

def data(self, index, role):
if role == Qt.ForegroundRole and index.column() in self.BOUND_INDICES:
# If a delta is zero, color both the delta and the value red.
item = self.get_item(index)
if not item.child_items:
atol = 1e-3
if abs(item.data(self.DELTA_IDX)) < atol:
return QColor('red')

return super().data(index, role)
Loading

0 comments on commit 83fbb0f

Please sign in to comment.