Skip to content

Commit 1798d46

Browse files
Glasspre-commit-ci[bot]
andauthored
Add UI element for Instrument Settings (#141)
* Add UI element for Instrument Settings * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * wow flake is picky * Add instrument_settings to global settings, some formatting * add release notes * fix from_xml for mypy * add unit test for ui element and model * line deleted * working through adding tests * add loading config tests * Save instrument settings in XML, some formatting * change defaults and precision * fix tests * Add deprecation warning to SF Calculator * add test_instrument_settings.xml to test data * update user docs * add default settings dict, apply default if not in xml * convert defaults to dataclass, fix mypy test --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 6bdfd16 commit 1798d46

23 files changed

+1664
-296
lines changed

RefRed/about_dialog.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99

1010
class AboutDialog(object):
11-
1211
parent = None
1312

1413
def __init__(self, parent=None):
@@ -22,29 +21,20 @@ def display(self):
2221
qt_version = QT_VERSION
2322
pyqt_version = PYQT_VERSION
2423

25-
message = '''RefRed - Liquids Reflectrometry Reduction program
24+
message = f"""RefRed - Liquids Reflectrometry Reduction program
2625
27-
RefRed version %s
28-
Reduction version %s
26+
RefRed version {RefRed_version_str}
27+
Reduction version {lr_reduction.__version__}
2928
3029
Library versions:
31-
- Python: %s
32-
- Numpy: %s
33-
- Mantid: %s
34-
- Matplotlib: %s
35-
- Qt: %s
36-
- PyQt: %s''' % (
37-
RefRed_version_str,
38-
lr_reduction.__version__,
39-
python_version,
40-
numpy_version,
41-
mantid_version,
42-
matplotlib_version,
43-
qt_version,
44-
pyqt_version,
45-
)
46-
47-
QtWidgets.QMessageBox.about(self.parent, 'About RefRed', message)
30+
- Python: {python_version}
31+
- Numpy: {numpy_version}
32+
- Mantid: {mantid_version}
33+
- Matplotlib: {matplotlib_version}
34+
- Qt: {qt_version}
35+
- PyQt: {pyqt_version}"""
36+
37+
QtWidgets.QMessageBox.about(self.parent, "About RefRed", message)
4838

4939
def get_python_version(self):
5040
str_version = sys.version_info

RefRed/configuration/export_xml_config.py

Lines changed: 74 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
# package imports
1212
import RefRed
1313
from RefRed.calculations.lr_data import LRData
14-
from RefRed.reduction.global_reduction_settings_handler import GlobalReductionSettingsHandler
14+
from RefRed.reduction.global_reduction_settings_handler import (
15+
GlobalReductionSettingsHandler,
16+
)
1517

1618

1719
class ExportXMLConfig(object):
@@ -21,33 +23,31 @@ def __init__(self, parent=None):
2123

2224
def header_part(self):
2325
str_array = self.str_array
24-
str_array.append('<Reduction>\n')
25-
str_array.append(' <instrument_name>REFL</instrument_name>\n')
26-
str_array.append(' <timestamp>' + datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p") + '</timestamp>\n')
27-
str_array.append(' <version>%s</version>\n' % lr_reduction.__version__)
28-
str_array.append(' <mantid_version>' + mantid.__version__ + '</mantid_version>\n')
29-
str_array.append('<generator>RefRed-%s</generator>\n' % RefRed.__version__)
26+
str_array.append("<Reduction>\n")
27+
str_array.append(" <instrument_name>REFL</instrument_name>\n")
28+
str_array.append(" <timestamp>" + datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p") + "</timestamp>\n")
29+
str_array.append(" <version>%s</version>\n" % lr_reduction.__version__)
30+
str_array.append(" <mantid_version>" + mantid.__version__ + "</mantid_version>\n")
31+
str_array.append("<generator>RefRed-%s</generator>\n" % RefRed.__version__)
3032

3133
# metadata
32-
str_array.append(' <DataSeries>\n')
34+
str_array.append(" <DataSeries>\n")
3335

3436
self.str_array = str_array
3537

3638
def main_part(self):
37-
3839
str_array = self.str_array
3940
_big_table_data = self.parent.big_table_data
4041
nbr_row = self.parent.REDUCTIONTABLE_MAX_ROWCOUNT
4142
o_general_settings = GlobalReductionSettingsHandler(parent=self.parent)
4243

4344
for row in range(nbr_row):
44-
4545
_data: LRData = _big_table_data[row, 0]
4646
if _data is None:
4747
break # we found the first empty row in the reduction table. No more runs available
4848

49-
str_array.append(' <RefLData>\n')
50-
str_array.append(' <peak_selection_type>narrow</peak_selection_type>\n')
49+
str_array.append(" <RefLData>\n")
50+
str_array.append(" <peak_selection_type>narrow</peak_selection_type>\n")
5151

5252
data_peak = _data.peak
5353
data_back = _data.back
@@ -85,79 +85,79 @@ def main_part(self):
8585
norm_low_res_flag = False
8686
norm_lambda_requested = -1
8787

88-
str_array.append(' <from_peak_pixels>' + str(data_peak[0]) + '</from_peak_pixels>\n')
89-
str_array.append(' <to_peak_pixels>' + str(data_peak[1]) + '</to_peak_pixels>\n')
90-
str_array.append(' <peak_discrete_selection>N/A</peak_discrete_selection>\n')
91-
str_array.append(' <background_flag>' + str(data_back_flag) + '</background_flag>\n')
92-
str_array.append(' <two_backgrounds>' + str(data_two_backgrounds) + '</two_backgrounds>\n')
93-
str_array.append(' <back_roi1_from>' + str(data_back[0]) + '</back_roi1_from>\n')
94-
str_array.append(' <back_roi1_to>' + str(data_back[1]) + '</back_roi1_to>\n')
95-
str_array.append(' <back_roi2_from>' + str(data_back2[0]) + '</back_roi2_from>\n')
96-
str_array.append(' <back_roi2_to>' + str(data_back2[1]) + '</back_roi2_to>\n')
97-
str_array.append(' <tof_range_flag>True</tof_range_flag>\n')
98-
str_array.append(' <from_tof_range>' + str(tof[0]) + '</from_tof_range>\n')
99-
str_array.append(' <to_tof_range>' + str(tof[1]) + '</to_tof_range>\n')
100-
str_array.append(' <from_q_range>' + str(q_range[0]) + '</from_q_range>\n')
101-
str_array.append(' <to_q_range>' + str(q_range[1]) + '</to_q_range>\n')
102-
str_array.append(' <from_lambda_range>' + str(lambda_range[0]) + '</from_lambda_range>\n')
103-
str_array.append(' <to_lambda_range>' + str(lambda_range[1]) + '</to_lambda_range>\n')
104-
str_array.append(' <incident_angle>' + str(incident_angle) + '</incident_angle>\n')
88+
str_array.append(" <from_peak_pixels>" + str(data_peak[0]) + "</from_peak_pixels>\n")
89+
str_array.append(" <to_peak_pixels>" + str(data_peak[1]) + "</to_peak_pixels>\n")
90+
str_array.append(" <peak_discrete_selection>N/A</peak_discrete_selection>\n")
91+
str_array.append(" <background_flag>" + str(data_back_flag) + "</background_flag>\n")
92+
str_array.append(" <two_backgrounds>" + str(data_two_backgrounds) + "</two_backgrounds>\n")
93+
str_array.append(" <back_roi1_from>" + str(data_back[0]) + "</back_roi1_from>\n")
94+
str_array.append(" <back_roi1_to>" + str(data_back[1]) + "</back_roi1_to>\n")
95+
str_array.append(" <back_roi2_from>" + str(data_back2[0]) + "</back_roi2_from>\n")
96+
str_array.append(" <back_roi2_to>" + str(data_back2[1]) + "</back_roi2_to>\n")
97+
str_array.append(" <tof_range_flag>True</tof_range_flag>\n")
98+
str_array.append(" <from_tof_range>" + str(tof[0]) + "</from_tof_range>\n")
99+
str_array.append(" <to_tof_range>" + str(tof[1]) + "</to_tof_range>\n")
100+
str_array.append(" <from_q_range>" + str(q_range[0]) + "</from_q_range>\n")
101+
str_array.append(" <to_q_range>" + str(q_range[1]) + "</to_q_range>\n")
102+
str_array.append(" <from_lambda_range>" + str(lambda_range[0]) + "</from_lambda_range>\n")
103+
str_array.append(" <to_lambda_range>" + str(lambda_range[1]) + "</to_lambda_range>\n")
104+
str_array.append(" <incident_angle>" + str(incident_angle) + "</incident_angle>\n")
105105

106106
_data_run_number = str(self.parent.ui.reductionTable.item(row, 1).text())
107-
str_array.append(' <data_sets>' + _data_run_number + '</data_sets>\n')
107+
str_array.append(" <data_sets>" + _data_run_number + "</data_sets>\n")
108108
# if type(data_full_file_name) == type([]):
109109
# data_full_file_name = ','.join(data_full_file_name)
110110
# str_array.append(' <data_full_file_name>' + data_full_file_name + '</data_full_file_name>\n')
111111

112-
str_array.append(' <x_min_pixel>' + str(data_low_res[0]) + '</x_min_pixel>\n')
113-
str_array.append(' <x_max_pixel>' + str(data_low_res[1]) + '</x_max_pixel>\n')
114-
str_array.append(' <x_range_flag>' + str(data_low_res_flag) + '</x_range_flag>\n')
112+
str_array.append(" <x_min_pixel>" + str(data_low_res[0]) + "</x_min_pixel>\n")
113+
str_array.append(" <x_max_pixel>" + str(data_low_res[1]) + "</x_max_pixel>\n")
114+
str_array.append(" <x_range_flag>" + str(data_low_res_flag) + "</x_range_flag>\n")
115115

116116
tthd = str(self.parent.ui.metadatatthdValue.text())
117-
str_array.append(' <tthd_value>' + tthd + '</tthd_value>\n')
117+
str_array.append(" <tthd_value>" + tthd + "</tthd_value>\n")
118118
ths = str(self.parent.ui.metadatathiValue.text())
119-
str_array.append(' <ths_value>' + ths + '</ths_value>\n')
120-
str_array.append(' <data_lambda_requested>' + str(data_lambda_requested) + '</data_lambda_requested>\n')
121-
122-
str_array.append(' <norm_flag>' + str(norm_flag) + '</norm_flag>\n')
123-
str_array.append(' <norm_x_range_flag>' + str(norm_low_res_flag) + '</norm_x_range_flag>\n')
124-
str_array.append(' <norm_x_max>' + str(norm_low_res[1]) + '</norm_x_max>\n')
125-
str_array.append(' <norm_x_min>' + str(norm_low_res[0]) + '</norm_x_min>\n')
126-
str_array.append(' <norm_from_peak_pixels>' + str(norm_peak[0]) + '</norm_from_peak_pixels>\n')
127-
str_array.append(' <norm_to_peak_pixels>' + str(norm_peak[1]) + '</norm_to_peak_pixels>\n')
128-
str_array.append(' <norm_background_flag>' + str(norm_back_flag) + '</norm_background_flag>\n')
129-
str_array.append(' <norm_two_backgrounds>' + str(norm_two_backgrounds) + '</norm_two_backgrounds>\n')
130-
str_array.append(' <norm_from_back_pixels>' + str(norm_back[0]) + '</norm_from_back_pixels>\n')
131-
str_array.append(' <norm_to_back_pixels>' + str(norm_back[1]) + '</norm_to_back_pixels>\n')
132-
str_array.append(' <norm_from_back2_pixels>' + str(norm_back2[0]) + '</norm_from_back2_pixels>\n')
133-
str_array.append(' <norm_to_back2_pixels>' + str(norm_back2[1]) + '</norm_to_back2_pixels>\n')
134-
str_array.append(' <norm_lambda_requested>' + str(norm_lambda_requested) + '</norm_lambda_requested>\n')
119+
str_array.append(" <ths_value>" + ths + "</ths_value>\n")
120+
str_array.append(" <data_lambda_requested>" + str(data_lambda_requested) + "</data_lambda_requested>\n")
121+
122+
str_array.append(" <norm_flag>" + str(norm_flag) + "</norm_flag>\n")
123+
str_array.append(" <norm_x_range_flag>" + str(norm_low_res_flag) + "</norm_x_range_flag>\n")
124+
str_array.append(" <norm_x_max>" + str(norm_low_res[1]) + "</norm_x_max>\n")
125+
str_array.append(" <norm_x_min>" + str(norm_low_res[0]) + "</norm_x_min>\n")
126+
str_array.append(" <norm_from_peak_pixels>" + str(norm_peak[0]) + "</norm_from_peak_pixels>\n")
127+
str_array.append(" <norm_to_peak_pixels>" + str(norm_peak[1]) + "</norm_to_peak_pixels>\n")
128+
str_array.append(" <norm_background_flag>" + str(norm_back_flag) + "</norm_background_flag>\n")
129+
str_array.append(" <norm_two_backgrounds>" + str(norm_two_backgrounds) + "</norm_two_backgrounds>\n")
130+
str_array.append(" <norm_from_back_pixels>" + str(norm_back[0]) + "</norm_from_back_pixels>\n")
131+
str_array.append(" <norm_to_back_pixels>" + str(norm_back[1]) + "</norm_to_back_pixels>\n")
132+
str_array.append(" <norm_from_back2_pixels>" + str(norm_back2[0]) + "</norm_from_back2_pixels>\n")
133+
str_array.append(" <norm_to_back2_pixels>" + str(norm_back2[1]) + "</norm_to_back2_pixels>\n")
134+
str_array.append(" <norm_lambda_requested>" + str(norm_lambda_requested) + "</norm_lambda_requested>\n")
135135

136136
_norm_run_number_cell = self.parent.ui.reductionTable.item(row, 2).text()
137-
if str(_norm_run_number_cell) != '':
137+
if str(_norm_run_number_cell) != "":
138138
_norm_run_number = str(_norm_run_number_cell)
139139
else:
140-
_norm_run_number = '0'
141-
str_array.append(' <norm_dataset>' + _norm_run_number + '</norm_dataset>\n')
140+
_norm_run_number = "0"
141+
str_array.append(" <norm_dataset>" + _norm_run_number + "</norm_dataset>\n")
142142
# if type(norm_full_file_name) == type([]):
143143
# norm_full_file_name = ','.join(norm_full_file_name)
144144
# str_array.append(' <norm_full_file_name>' + norm_full_file_name + '</norm_full_file_name>\n')
145145

146-
str_array.append(' <auto_q_binning>False</auto_q_binning>\n')
146+
str_array.append(" <auto_q_binning>False</auto_q_binning>\n")
147147

148148
# The angle offset is currently not exposed in the UI, so we set it to 0.
149-
str_array.append(' <angle_offset> 0 </angle_offset>\n')
150-
str_array.append(' <angle_offset_error> 0 </angle_offset_error>\n')
149+
str_array.append(" <angle_offset> 0 </angle_offset>\n")
150+
str_array.append(" <angle_offset_error> 0 </angle_offset_error>\n")
151151

152152
q_step = str(self.parent.ui.qStep.text())
153-
str_array.append(' <q_step>' + q_step + '</q_step>\n')
154-
q_min = str(self.parent.gui_metadata['q_min'])
155-
str_array.append(' <q_min>' + q_min + '</q_min>\n')
153+
str_array.append(" <q_step>" + q_step + "</q_step>\n")
154+
q_min = str(self.parent.gui_metadata["q_min"])
155+
str_array.append(" <q_min>" + q_min + "</q_min>\n")
156156

157157
scalingFactorFlag = self.parent.ui.scalingFactorFlag.isChecked()
158-
str_array.append(' <scaling_factor_flag>' + str(scalingFactorFlag) + '</scaling_factor_flag>\n')
158+
str_array.append(" <scaling_factor_flag>" + str(scalingFactorFlag) + "</scaling_factor_flag>\n")
159159
scalingFactorFile = o_general_settings.scaling_factor_file
160-
str_array.append(' <scaling_factor_file>' + scalingFactorFile + '</scaling_factor_file>\n')
160+
str_array.append(" <scaling_factor_file>" + scalingFactorFile + "</scaling_factor_file>\n")
161161

162162
# incident medium
163163
allItems = [
@@ -166,23 +166,27 @@ def main_part(self):
166166
]
167167
finalList = allItems[1:]
168168
strFinalList = ",".join(finalList)
169-
str_array.append(' <incident_medium_list>' + strFinalList + '</incident_medium_list>\n')
169+
str_array.append(" <incident_medium_list>" + strFinalList + "</incident_medium_list>\n")
170170

171171
imIndex = self.parent.ui.selectIncidentMediumList.currentIndex()
172172
str_array.append(
173-
' <incident_medium_index_selected>' + str(imIndex - 1) + '</incident_medium_index_selected>\n'
173+
" <incident_medium_index_selected>" + str(imIndex - 1) + "</incident_medium_index_selected>\n"
174174
)
175175

176-
str_array.append(' <slits_width_flag>True</slits_width_flag>\n')
176+
str_array.append(" <slits_width_flag>True</slits_width_flag>\n")
177+
178+
# dead time settings
179+
str_array.append(o_general_settings.dead_time.to_xml(indent=" ") + "\n")
177180

178-
str_array.append(o_general_settings.dead_time.to_xml(indent=" ") + "\n") # dead time settings
181+
# instrument settings
182+
str_array.append(o_general_settings.instrument_settings.to_xml(indent=" ") + "\n")
179183

180-
str_array.append(' <const_q>' + str(const_q) + '</const_q>\n')
184+
str_array.append(" <const_q>" + str(const_q) + "</const_q>\n")
181185

182-
str_array.append(' </RefLData>\n')
186+
str_array.append(" </RefLData>\n")
183187

184-
str_array.append(' </DataSeries>\n')
185-
str_array.append('</Reduction>\n')
188+
str_array.append(" </DataSeries>\n")
189+
str_array.append("</Reduction>\n")
186190
self.str_array = str_array
187191

188192
def save(self, filename: str):
@@ -198,7 +202,7 @@ def save(self, filename: str):
198202

199203
if os.path.isfile(filename):
200204
os.remove(filename)
201-
with open(filename, 'w') as outfile:
205+
with open(filename, "w") as outfile:
202206
outfile.writelines(self.str_array)
203207

204208
logging.info(f"Config is saved to {filename}.")

RefRed/configuration/load_reduction_table_from_lconfigdataset.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from qtpy import QtGui, QtWidgets
2+
3+
import RefRed.colors
24
from RefRed.calculations.add_list_nexus import AddListNexus
3-
from RefRed.calculations.lr_data import LRData
45
from RefRed.calculations.locate_list_run import LocateListRun
5-
from RefRed.calculations.update_reduction_table_metadata import UpdateReductionTableMetadata
6+
from RefRed.calculations.lr_data import LRData
7+
from RefRed.calculations.update_reduction_table_metadata import (
8+
UpdateReductionTableMetadata,
9+
)
10+
from RefRed.gui_handling.gui_utility import GuiUtility
611
from RefRed.gui_handling.progressbar_handler import ProgressBarHandler
712
from RefRed.plot.display_plots import DisplayPlots
8-
from RefRed.gui_handling.gui_utility import GuiUtility
9-
import RefRed.colors
1013

1114

1215
class LoadReductionTableFromLConfigDataSet(object):
@@ -29,7 +32,7 @@ def __init__(self, parent=None):
2932
list_data_run = lconfig.data_sets
3033
o_list_data_nexus = LocateListRun(list_run=list_data_run)
3134
list_data_nexus = o_list_data_nexus.list_nexus_found
32-
# list_data_nexus= o_list_data_nexus.list_run_found
35+
# list_data_nexus= o_list_data_nexus.list_run_found
3336
_add_data_nexus = AddListNexus(
3437
list_nexus=list_data_nexus,
3538
list_run=list_data_run,

RefRed/configuration/loading_configuration.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ def run(self):
5656
try:
5757
self.loading()
5858
message = "Done!"
59-
except:
59+
except Exception as e:
60+
logging.error(f"Error loading file: {e}")
6061
message = "Error loading file: aborted"
6162
else:
6263
message = "Loading aborted"
@@ -187,6 +188,12 @@ def populate_main_gui_general_settings(self):
187188
self.parent.deadtime_settings.from_xml(node_0)
188189
self.parent.ui.deadtime_entry.applyCheckBox.setChecked(self.parent.deadtime_settings.apply_deadtime)
189190

191+
# initialize the instrument settings
192+
self.parent.instrument_settings.from_xml(node_0)
193+
self.parent.ui.instrument_settings_entry.applyCheckBox.setChecked(
194+
self.parent.instrument_settings.apply_instrument_settings
195+
)
196+
190197
def getMetadataObject(self, node) -> LConfigDataset:
191198
r"""Populate an instance of type LConfigDataset using the information contained in one of the
192199
'RefLData XML blocks within a configuration file."""

RefRed/configuration/saving_configuration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def __init__(self, parent=None, filename=''):
1717
StatusMessageHandler(parent=self.parent, message='Saving config ...', is_threaded=False)
1818

1919
def run(self):
20+
2021
if self.filename == '':
2122
_path = self.parent.path_config
2223
_filter = "XML (*.xml);; All Files (*.*)"

RefRed/interfaces/deadtime_entry.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
# third party imports
21
from qtpy.QtWidgets import QGroupBox, QHBoxLayout, QCheckBox, QPushButton
32

43

54
class DeadTimeEntryPoint(QGroupBox):
6-
def __init__(self, title='Dead Time Correction'):
5+
def __init__(self, title="Dead Time Correction"):
76
super().__init__(title)
87
self.initUI()
98

@@ -22,16 +21,19 @@ def initUI(self):
2221
"}"
2322
)
2423

25-
self.applyCheckBox = QCheckBox('Apply', self)
24+
self.applyCheckBox = QCheckBox("Apply", self)
2625
self.applyCheckBox.stateChanged.connect(self.toggleSettingsButton)
27-
self.settingsButton = QPushButton('Settings', self)
28-
self.settingsButton.setEnabled(self.applyCheckBox.isChecked()) # enabled if we use the correction
26+
self.settingsButton = QPushButton("Settings", self)
27+
self.settingsButton.setEnabled(
28+
# enabled if we use the correction
29+
self.applyCheckBox.isChecked()
30+
)
2931

3032
# Create a horizontal layout for the checkbox and settings button
3133
hbox = QHBoxLayout()
3234
hbox.addWidget(self.applyCheckBox)
3335
hbox.addWidget(self.settingsButton)
34-
hbox.addStretch(1) # This adds a stretchable space after the button (optional)
36+
# hbox.addStretch(1) # This adds a stretchable space after the button (optional)
3537

3638
# Set the layout for the group box
3739
self.setLayout(hbox)

0 commit comments

Comments
 (0)