diff --git a/qt/python/mantidqt/_common.sip b/qt/python/mantidqt/_common.sip index 0717cc0acd19d6bfabe76c31f3d64803d6eed19c..ffee4cf80aba2f1a764d0eb4b448f101620e70bc 100644 --- a/qt/python/mantidqt/_common.sip +++ b/qt/python/mantidqt/_common.sip @@ -887,6 +887,7 @@ public: QString getText(); QString getFirstFilename() const; void isForRunFiles(bool /*mode*/); + void isForDirectory(bool /*mode*/); bool isSearching() const; bool isValid(); void liveButtonSetChecked(bool); diff --git a/scripts/Engineering/gui/CMakeLists.txt b/scripts/Engineering/gui/CMakeLists.txt index d04e7efbfa29a8b3f80cdfbeacbb2493fa9483a3..62c1f5271a99bb83e2417cbef8c7104fb40003d1 100644 --- a/scripts/Engineering/gui/CMakeLists.txt +++ b/scripts/Engineering/gui/CMakeLists.txt @@ -3,6 +3,10 @@ set(TEST_PY_FILES # Common engineering_diffraction/tabs/common/test/test_vanadium_corrections.py + # Settings + engineering_diffraction/settings/test/test_settings_helper.py + engineering_diffraction/settings/test/test_settings_model.py + engineering_diffraction/settings/test/test_settings_presenter.py # Calibration engineering_diffraction/tabs/calibration/test/test_calib_model.py engineering_diffraction/tabs/calibration/test/test_calib_presenter.py diff --git a/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py b/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py index 3a8dbe99906095ffb77409dd2f222c700fb35310..ba311894e2f91ab1f50a548f22bfb5cef55588a0 100644 --- a/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py +++ b/scripts/Engineering/gui/engineering_diffraction/engineering_diffraction.py @@ -14,6 +14,10 @@ from .tabs.calibration.presenter import CalibrationPresenter from .tabs.focus.model import FocusModel from .tabs.focus.view import FocusView from .tabs.focus.presenter import FocusPresenter +from .settings.settings_model import SettingsModel +from .settings.settings_view import SettingsView +from .settings.settings_presenter import SettingsPresenter +from mantidqt.icons import get_icon from mantidqt.interfacemanager import InterfaceManager from mantidqt.utils.qt import load_ui @@ -35,15 +39,26 @@ class EngineeringDiffractionGui(QtWidgets.QMainWindow, Ui_main_window): self.setFocusPolicy(QtCore.Qt.StrongFocus) self.calibration_presenter = None self.focus_presenter = None + self.settings_presenter = None self.set_on_help_clicked(self.open_help_window) - # Setup Tabs + self.set_on_settings_clicked(self.open_settings) + self.btn_settings.setIcon(get_icon("mdi.settings", "black", 1.2)) + + # Setup Elements + self.setup_settings() self.setup_calibration() self.setup_focus() # Setup notifiers self.setup_calibration_notifier() + def setup_settings(self): + model = SettingsModel() + view = SettingsView(self) + self.settings_presenter = SettingsPresenter(model, view) + self.settings_presenter.load_settings_from_file_or_default() + def setup_calibration(self): cal_model = CalibrationModel() cal_view = CalibrationView(parent=self.tabs) @@ -67,6 +82,9 @@ class EngineeringDiffractionGui(QtWidgets.QMainWindow, Ui_main_window): def set_on_help_clicked(self, slot): self.pushButton_help.clicked.connect(slot) + def set_on_settings_clicked(self, slot): + self.btn_settings.clicked.connect(slot) + def set_on_rb_num_changed(self, slot): self.lineEdit_RBNumber.textChanged.connect(slot) @@ -76,5 +94,9 @@ class EngineeringDiffractionGui(QtWidgets.QMainWindow, Ui_main_window): def open_help_window(self): InterfaceManager().showCustomInterfaceHelp(self.doc) + def open_settings(self): + self.settings_presenter.load_existing_settings() + self.settings_presenter.show() + def get_rb_no(self): return self.lineEdit_RBNumber.text() diff --git a/scripts/Engineering/gui/engineering_diffraction/main_window.ui b/scripts/Engineering/gui/engineering_diffraction/main_window.ui index 3f4cac479e962cf435b3197556a061699c45f4d1..6e3565348930ea8a3108e68cb8b0a7d7cafaaa86 100644 --- a/scripts/Engineering/gui/engineering_diffraction/main_window.ui +++ b/scripts/Engineering/gui/engineering_diffraction/main_window.ui @@ -91,6 +91,13 @@ </property> </widget> </item> + <item> + <widget class="QToolButton" name="btn_settings"> + <property name="text"> + <string/> + </property> + </widget> + </item> <item> <widget class="QStatusBar" name="statusbar"> <property name="sizeGripEnabled"> diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/__init__.py b/scripts/Engineering/gui/engineering_diffraction/settings/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_helper.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_helper.py new file mode 100644 index 0000000000000000000000000000000000000000..020ad2f3032f2d82b3f6a86b7c7bea913d9ca0b4 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_helper.py @@ -0,0 +1,57 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + + +from __future__ import (absolute_import, division, print_function) + +from qtpy.QtCore import QSettings + + +def set_setting(group, prefix, setting_name, value): + """ + Change or add a setting in the mantid .ini file. + :param group: Settings group to pull from. + :param prefix: Acts like a subgroup. + :param setting_name: The key to the setting. + :param value: The value of the setting. + """ + settings = QSettings() + settings.beginGroup(group) + settings.setValue(prefix + setting_name, value) + settings.endGroup() + + +def get_setting(group, prefix, setting_name, return_type=str): + """ + Get a setting from the .ini file of mantid settings. + + NOTE: If you specify an int, but the setting contains a bool, you will get 0 for False + and 1 for True, without a warning. Specifying bool will raise a TypeError if anything + other than a bool or empty string is found in the settings. Not specifying a type will + return a string. If nothing is found then an empty string is returned. + + :param group: Settings group to pull from. + :param prefix: The prefix of the setting, acts like a subgroup. + :param setting_name: Name of the setting. + :param return_type: The type of the setting to get. + :return: The chosen setting. + """ + settings = QSettings() + settings.beginGroup(group) + if return_type is bool: + setting = settings.value(prefix + setting_name, type=str) + if setting == "": + pass + elif setting == "true": + setting = True + elif setting == "false": + setting = False + else: + raise TypeError("Unable to convert string into valid bool") + else: + setting = settings.value(prefix + setting_name, type=return_type) + settings.endGroup() + return setting diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_model.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_model.py new file mode 100644 index 0000000000000000000000000000000000000000..32edb1a5e53230e984cd6a1d543b36bad393a5e7 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_model.py @@ -0,0 +1,32 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + + +from __future__ import (absolute_import, division, print_function) + +from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting, set_setting +from Engineering.gui.engineering_diffraction.tabs.common import path_handling + + +class SettingsModel(object): + def get_settings_dict(self, names_and_types): + settings = {} + for setting_name in names_and_types.keys(): + settings[setting_name] = self.get_setting(setting_name, return_type=names_and_types[setting_name]) + return settings + + def set_settings_dict(self, settings): + for key in settings: + self.set_setting(key, settings[key]) + + @staticmethod + def get_setting(name, return_type=str): + return get_setting(path_handling.INTERFACES_SETTINGS_GROUP, path_handling.ENGINEERING_PREFIX, name, + return_type=return_type) + + @staticmethod + def set_setting(name, value): + set_setting(path_handling.INTERFACES_SETTINGS_GROUP, path_handling.ENGINEERING_PREFIX, name, value) diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_presenter.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_presenter.py new file mode 100644 index 0000000000000000000000000000000000000000..3767e462ccf1f7b08ce43edff8f75c96f2a18936 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_presenter.py @@ -0,0 +1,80 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + +# pylint: disable=invalid-name +from __future__ import (absolute_import, division, print_function) + +from os import path + +SETTINGS_DICT = {"save_location": str, "full_calibration": str, "recalc_vanadium": bool} + +DEFAULT_SETTINGS = { + "full_calibration": "", + "save_location": path.join(path.expanduser("~"), "Engineering_Mantid"), + "recalc_vanadium": False +} + + +class SettingsPresenter(object): + def __init__(self, model, view): + self.model = model + self.view = view + self.settings = {} + + # Connect view signals + self.view.set_on_apply_clicked(self.save_new_settings) + self.view.set_on_ok_clicked(self.save_and_close_dialog) + self.view.set_on_cancel_clicked(self.close_dialog) + + def show(self): + self.view.show() + + def load_existing_settings(self): + self.load_settings_from_file_or_default() + self._show_settings_in_view() + + def close_dialog(self): + self.view.close() + + def save_and_close_dialog(self): + self.save_new_settings() + self.close_dialog() + + def save_new_settings(self): + self._collect_new_settings_from_view() + self._save_settings_to_file() + + def _collect_new_settings_from_view(self): + self.settings["save_location"] = self.view.get_save_location() + self.settings["full_calibration"] = self.view.get_full_calibration() + self.settings["recalc_vanadium"] = self.view.get_van_recalc() + + def _show_settings_in_view(self): + if self._validate_settings(self.settings): + self.view.set_save_location(self.settings["save_location"]) + self.view.set_full_calibration(self.settings["full_calibration"]) + self.view.set_van_recalc(self.settings["recalc_vanadium"]) + + def _save_settings_to_file(self): + if self._validate_settings(self.settings): + self.model.set_settings_dict(self.settings) + + def load_settings_from_file_or_default(self): + self.settings = self.model.get_settings_dict(SETTINGS_DICT) + if not self._validate_settings(self.settings): + self.settings = DEFAULT_SETTINGS.copy() + self._save_settings_to_file() + + @staticmethod + def _validate_settings(settings): + try: + all_keys = settings.keys() == SETTINGS_DICT.keys() + save_location = str(settings["save_location"]) + save_valid = save_location is not "" and save_location is not None + recalc_valid = settings["recalc_vanadium"] is not None + return all_keys and save_valid and recalc_valid + except KeyError: # Settings contained invalid key. + return False diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_view.py b/scripts/Engineering/gui/engineering_diffraction/settings/settings_view.py new file mode 100644 index 0000000000000000000000000000000000000000..3d94d776b522c8d6aa5b6f5fa2ae3128932bb901 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_view.py @@ -0,0 +1,69 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + + +from __future__ import (absolute_import, division, print_function) +from qtpy import QtWidgets + +from mantidqt.utils.qt import load_ui + +Ui_settings, _ = load_ui(__file__, "settings_widget.ui") + + +class SettingsView(QtWidgets.QDialog, Ui_settings): + def __init__(self, parent=None): + super(SettingsView, self).__init__(parent) + self.setupUi(self) + self.setModal(True) + + self.finder_save.setLabelText("Save Location") + self.finder_save.isForRunFiles(False) + self.finder_save.isForDirectory(True) + + self.finder_fullCalib.setLabelText("Full Calibration") + self.finder_fullCalib.isForRunFiles(False) + # TODO: Once it becomes possible to load the .csv containing the full calibration into mantid, + # this can be used. Until then, this option is hidden from the user. + self.finder_fullCalib.hide() + + # =============== + # Slot Connectors + # =============== + + def set_on_apply_clicked(self, slot): + self.btn_apply.clicked.connect(slot) + + def set_on_ok_clicked(self, slot): + self.btn_ok.clicked.connect(slot) + + def set_on_cancel_clicked(self, slot): + self.btn_cancel.clicked.connect(slot) + + # ================= + # Component Getters + # ================= + + def get_save_location(self): + return self.finder_save.getFirstFilename() + + def get_full_calibration(self): + return self.finder_fullCalib.getFirstFilename() + + def get_van_recalc(self): + return self.check_vanRecalc.isChecked() + + # ================= + # Component Setters + # ================= + + def set_save_location(self, text): + self.finder_save.setText(text) + + def set_full_calibration(self, text): + self.finder_fullCalib.setText(text) + + def set_van_recalc(self, checked): + self.check_vanRecalc.setChecked(checked) diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/settings_widget.ui b/scripts/Engineering/gui/engineering_diffraction/settings/settings_widget.ui new file mode 100644 index 0000000000000000000000000000000000000000..f2093a42150a686110609cb89b195dc38c8f769b --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/settings_widget.ui @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>630</width> + <height>184</height> + </rect> + </property> + <property name="windowTitle"> + <string>Engineering Diffraction Analysis</string> + </property> + <property name="styleSheet"> + <string notr="true">QGroupBox { +border: 1px solid grey;border-radius: 10px;margin-top: 1ex; margin-right: 0ex +} +QGroupBox:title { + subcontrol-origin: margin; + subcontrol-position: top center; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 5px; + padding-right: 5px; + color: rgb(56, 56, 56) +}</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="group_general"> + <property name="title"> + <string>General</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="FileFinder" name="finder_save" native="true"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="group_calib"> + <property name="title"> + <string>Calibration</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QCheckBox" name="check_vanRecalc"> + <property name="text"> + <string>Force Vanadium Recalculation</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="FileFinder" name="finder_fullCalib" native="true"/> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QFrame" name="frame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="btn_apply"> + <property name="text"> + <string>Apply</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btn_ok"> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btn_cancel"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>FileFinder</class> + <extends>QWidget</extends> + <header>mantidqt.widgets.filefinder</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/__init__.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_helper.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_helper.py new file mode 100644 index 0000000000000000000000000000000000000000..62a0bf0d145ed963a25d27d06295258523df9bc9 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_helper.py @@ -0,0 +1,160 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + + +from __future__ import (absolute_import, division, print_function) + +from Engineering.gui.engineering_diffraction.settings.settings_helper import set_setting, get_setting + +from qtpy.QtCore import QSettings, QCoreApplication + +from shutil import rmtree +from os.path import dirname + +import unittest + +GROUP = "CustomInterfaces" +PREFIX = "EngineeringDiffraction2/" + + +class SettingsHelperTest(unittest.TestCase): + def tearDown(self): + settings = QSettings() + settings.clear() + rmtree(dirname(settings.fileName())) + + def setUp(self): + settings = QSettings() + settings.clear() + + @classmethod + def setUpClass(cls): + QCoreApplication.setApplicationName("test1") + QCoreApplication.setOrganizationName("org1") + QSettings.setDefaultFormat(QSettings.IniFormat) + + def test_set_setting_with_string(self): + set_setting(GROUP, PREFIX, "something", "value") + + settings = QSettings() + settings.beginGroup(GROUP) + returned = settings.value(PREFIX + "something") + settings.endGroup() + self.assertEqual(returned, "value") + + def test_set_setting_with_bool_false(self): + set_setting(GROUP, PREFIX, "something", False) + + settings = QSettings() + settings.beginGroup("CustomInterfaces") + returned = settings.value("EngineeringDiffraction2/" + "something", type=bool) + settings.endGroup() + self.assertEqual(returned, False) + + def test_set_setting_with_bool_true(self): + set_setting(GROUP, PREFIX, "something", True) + + settings = QSettings() + settings.beginGroup("CustomInterfaces") + returned = settings.value("EngineeringDiffraction2/" + "something", type=bool) + settings.endGroup() + self.assertEqual(returned, True) + + def test_set_setting_with_int(self): + set_setting(GROUP, PREFIX, "something", 10) + + settings = QSettings() + settings.beginGroup(GROUP) + returned = settings.value(PREFIX + "something", type=int) + settings.endGroup() + self.assertEqual(returned, 10) + + def test_get_setting_with_string(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", "value") + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something"), "value") + + def test_get_setting_with_bool_false(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", False) + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=bool), False) + + def test_get_setting_with_bool_true(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", True) + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=bool), True) + + def test_get_setting_with_int(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", 10) + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=int), 10) + + def test_get_setting_with_invalid(self): + self.assertEqual(get_setting(GROUP, PREFIX, "something"), "") + + def test_get_setting_int_without_specifying_type(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", 10) + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something"), "10") + + def test_get_setting_bool_without_specifying_type(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", True) + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something"), "true") + + def test_get_setting_bool_specifying_int(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", True) + settings.endGroup() + + self.assertEqual(get_setting(GROUP, PREFIX, "something", return_type=int), 1) + + def test_get_setting_int_specifying_bool(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", 10) + settings.endGroup() + + self.assertRaises(TypeError, get_setting, GROUP, PREFIX, "something", return_type=bool) + + def test_get_setting_string_specifying_int(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", "some setting") + settings.endGroup() + + self.assertRaises(TypeError, get_setting, GROUP, PREFIX, "something", return_type=int) + + def test_get_setting_string_specifying_bool(self): + settings = QSettings() + settings.beginGroup(GROUP) + settings.setValue(PREFIX + "something", "a") + settings.endGroup() + + self.assertRaises(TypeError, get_setting, GROUP, PREFIX, "something", return_type=bool) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_model.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_model.py new file mode 100644 index 0000000000000000000000000000000000000000..3acd388e063e79e16cf256551c8b8aa144ff587e --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_model.py @@ -0,0 +1,51 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + + +from __future__ import (absolute_import, division, print_function) + +import unittest + +from mantid.py3compat.mock import patch +from Engineering.gui.engineering_diffraction.settings.settings_model import SettingsModel + +dir_path = "Engineering.gui.engineering_diffraction.settings." + + +class SettingsModelTest(unittest.TestCase): + def setUp(self): + self.model = SettingsModel() + + @patch(dir_path + "settings_model.set_setting") + def test_set_setting(self, set_setting_mock): + self.model.set_setting("name", "value") + set_setting_mock.assert_called_with("CustomInterfaces", "EngineeringDiffraction2/", "name", "value") + + @patch(dir_path + "settings_model.get_setting") + def test_get_setting(self, get_setting_mock): + self.model.get_setting("name") + get_setting_mock.assert_called_with("CustomInterfaces", "EngineeringDiffraction2/", "name", return_type=str) + + @patch(dir_path + "settings_model.set_setting") + def test_set_settings_dict(self, set_setting_mock): + self.model.set_settings_dict({"name": "value", "namebool": False, "namenum": 10}) + self.assertEqual(set_setting_mock.call_count, 3) + set_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "name", "value") + set_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "namebool", False) + set_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "namenum", 10) + + @patch(dir_path + "settings_model.get_setting") + def test_get_settings_dict(self, get_setting_mock): + get_setting_mock.return_value = "value" + self.assertEqual(self.model.get_settings_dict({"name1": str, "name2": str}), + {'name1': 'value', 'name2': 'value'}) + self.assertEqual(get_setting_mock.call_count, 2) + get_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "name1", return_type=str) + get_setting_mock.assert_any_call("CustomInterfaces", "EngineeringDiffraction2/", "name2", return_type=str) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_presenter.py b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_presenter.py new file mode 100644 index 0000000000000000000000000000000000000000..f08c8d6a901214837dc9c98dbc964b76997075ba --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/settings/test/test_settings_presenter.py @@ -0,0 +1,95 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2019 ISIS Rutherford Appleton Laboratory UKRI, +# NScD Oak Ridge National Laboratory, European Spallation Source +# & Institut Laue - Langevin +# SPDX - License - Identifier: GPL - 3.0 + +# pylint: disable=invalid-name +from __future__ import (absolute_import, division, print_function) + +import unittest + +from mantid.py3compat import mock + +from Engineering.gui.engineering_diffraction.settings import settings_model, settings_view, settings_presenter + +dir_path = "Engineering.gui.engineering_diffraction.settings." + + +class SettingsPresenterTest(unittest.TestCase): + def setUp(self): + self.model = mock.create_autospec(settings_model.SettingsModel) + self.view = mock.create_autospec(settings_view.SettingsView) + self.presenter = settings_presenter.SettingsPresenter(self.model, self.view) + self.presenter.settings = {} + + def test_load_existing_settings(self): + self.model.get_settings_dict.return_value = { + "save_location": "result", + "full_calibration": "value", + "recalc_vanadium": False + } + + self.presenter.load_existing_settings() + + self.assertEqual(self.presenter.settings, { + "full_calibration": "value", + "save_location": "result", + "recalc_vanadium": False + }) + self.assertEqual(self.view.set_save_location.call_count, 1) + self.assertEqual(self.view.set_full_calibration.call_count, 1) + self.assertEqual(self.view.set_van_recalc.call_count, 1) + + def test_load_invalid_settings(self): + self.model.get_settings_dict.return_value = { + "foo": "dud", + "bar": "result" + } + self.presenter.load_existing_settings() + + self.view.set_save_location.assert_called_with(settings_presenter.DEFAULT_SETTINGS["save_location"]) + self.view.set_full_calibration.assert_called_with(settings_presenter.DEFAULT_SETTINGS["full_calibration"]) + self.view.set_van_recalc.assert_called_with(settings_presenter.DEFAULT_SETTINGS["recalc_vanadium"]) + + def test_save_new_settings(self): + self.view.get_save_location.return_value = "save" + self.view.get_full_calibration.return_value = "cal" + self.view.get_van_recalc.return_value = False + + self.presenter.save_new_settings() + + self.assertEqual(self.presenter.settings, { + "full_calibration": "cal", + "save_location": "save", + "recalc_vanadium": False + }) + self.model.set_settings_dict.assert_called_with({ + "full_calibration": "cal", + "save_location": "save", + "recalc_vanadium": False + }) + self.assertEqual(self.view.close.call_count, 0) + + def test_save_settings_and_close(self): + self.view.get_save_location.return_value = "save" + self.view.get_full_calibration.return_value = "cal" + self.view.get_van_recalc.return_value = False + + self.presenter.save_and_close_dialog() + + self.assertEqual(self.presenter.settings, { + "full_calibration": "cal", + "save_location": "save", + "recalc_vanadium": False + }) + self.model.set_settings_dict.assert_called_with({ + "full_calibration": "cal", + "save_location": "save", + "recalc_vanadium": False + }) + self.assertEqual(self.view.close.call_count, 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py index 6616e2367296727778d173acfd411e730fc61424..24357c27e2aae6f9594e6d75e3eb6cf146cdae74 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py @@ -13,19 +13,18 @@ import matplotlib.pyplot as plt from mantid.api import AnalysisDataService as Ads from mantid.kernel import logger -from mantid.simpleapi import Load, EnggCalibrate, DeleteWorkspace, CloneWorkspace, \ +from mantid.simpleapi import EnggCalibrate, DeleteWorkspace, CloneWorkspace, \ CreateWorkspace, AppendSpectra, CreateEmptyTableWorkspace from Engineering.EnggUtils import write_ENGINX_GSAS_iparam_file from Engineering.gui.engineering_diffraction.tabs.common import vanadium_corrections from Engineering.gui.engineering_diffraction.tabs.common import path_handling +from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting VANADIUM_INPUT_WORKSPACE_NAME = "engggui_vanadium_ws" CURVES_WORKSPACE_NAME = "engggui_vanadium_curves" INTEGRATED_WORKSPACE_NAME = "engggui_vanadium_integration" CALIB_PARAMS_WORKSPACE_NAME = "engggui_calibration_banks_parameters" -CALIBRATION_DIR = path.join(path_handling.OUT_FILES_ROOT_DIR, "Calibration", "") - NORTH_BANK_TEMPLATE_FILE = "template_ENGINX_241391_236516_North_bank.prm" SOUTH_BANK_TEMPLATE_FILE = "template_ENGINX_241391_236516_South_bank.prm" @@ -47,8 +46,14 @@ class CalibrationModel(object): """ van_integration, van_curves = vanadium_corrections.fetch_correction_workspaces( vanadium_path, instrument, rb_num=rb_num) - sample_workspace = self.load_sample(sample_path) - output = self.run_calibration(sample_workspace, van_integration, van_curves) + sample_workspace = path_handling.load_workspace(sample_path) + full_calib_path = get_setting(path_handling.INTERFACES_SETTINGS_GROUP, + path_handling.ENGINEERING_PREFIX, "full_calibration") + if full_calib_path is not None and path.exists(full_calib_path): + full_calib = path_handling.load_workspace(full_calib_path) + output = self.run_calibration(sample_workspace, van_integration, van_curves, full_calib_ws=full_calib) + else: + output = self.run_calibration(sample_workspace, van_integration, van_curves) if plot_output: self._plot_vanadium_curves() for i in range(2): @@ -64,10 +69,10 @@ class CalibrationModel(object): params_table.append([i, difc[i], 0.0, tzero[i]]) self.update_calibration_params_table(params_table) - self.create_output_files(CALIBRATION_DIR, difc, tzero, sample_path, vanadium_path, - instrument) + calib_dir = path.join(path_handling.get_output_path(), "Calibration", "") + self.create_output_files(calib_dir, difc, tzero, sample_path, vanadium_path, instrument) if rb_num: - user_calib_dir = path.join(path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, + user_calib_dir = path.join(path_handling.get_output_path(), "User", rb_num, "Calibration", "") self.create_output_files(user_calib_dir, difc, tzero, sample_path, vanadium_path, instrument) @@ -180,33 +185,31 @@ class CalibrationModel(object): ax.set_xlabel("Expected Peaks Centre(dSpacing, A)") fig.show() - @staticmethod - def load_sample(sample_run_no): - try: - return Load(Filename=sample_run_no, OutputWorkspace="engggui_calibration_sample_ws") - except Exception as e: - logger.error("Error while loading calibration sample data. " - "Could not run the algorithm Load successfully for the calibration sample " - "(run number: " + str(sample_run_no) + "). Error description: " + str(e) + - " Please check also the previous log messages for details.") - raise RuntimeError - - def run_calibration(self, sample_ws, van_integration, van_curves): + def run_calibration(self, sample_ws, van_integration, van_curves, full_calib_ws=None): """ Runs the main Engineering calibration algorithm. :param sample_ws: The workspace with the sample data. :param van_integration: The integration values from the vanadium corrections :param van_curves: The curves from the vanadium corrections. + :param full_calib_ws: Full pixel calibration of the detector (optional) :return: The output of the algorithm. """ output = [None] * 2 for i in range(2): table_name = self._generate_table_workspace_name(i) - output[i] = EnggCalibrate(InputWorkspace=sample_ws, - VanIntegrationWorkspace=van_integration, - VanCurvesWorkspace=van_curves, - Bank=str(i + 1), - FittedPeaks=table_name) + if full_calib_ws is not None: + output[i] = EnggCalibrate(InputWorkspace=sample_ws, + VanIntegrationWorkspace=van_integration, + VanCurvesWorkspace=van_curves, + Bank=str(i + 1), + FittedPeaks=table_name) + else: + output[i] = EnggCalibrate(InputWorkspace=sample_ws, + VanIntegrationWorkspace=van_integration, + VanCurvesWorkspace=van_curves, + Bank=str(i + 1), + FittedPeaks=table_name, + DetectorPositions=full_calib_ws) return output def create_output_files(self, calibration_dir, difc, tzero, sample_path, vanadium_path, diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py index 60e8d530feb89353e116cd204610f5244169e85b..e5ea4fde9e1c83df09746247076e47c28e0698f1 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_calib_model.py @@ -34,7 +34,7 @@ class CalibrationModelTest(unittest.TestCase): @patch(class_path + '.update_calibration_params_table') @patch(class_path + '.create_output_files') @patch(class_path + '.run_calibration') - @patch(class_path + '.load_sample') + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') def test_EnggVanadiumCorrections_algorithm_is_called(self, van, load_sample, calib, output_files, update_table): @@ -44,7 +44,7 @@ class CalibrationModelTest(unittest.TestCase): @patch(class_path + '.update_calibration_params_table') @patch(class_path + '.create_output_files') - @patch(class_path + '.load_sample') + @patch(file_path + ".path_handling.load_workspace") @patch(class_path + '.run_calibration') @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') def test_fetch_vanadium_is_called(self, van_corr, calibrate_alg, load_sample, output_files, @@ -53,9 +53,26 @@ class CalibrationModelTest(unittest.TestCase): self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False, "ENGINX") self.assertEqual(van_corr.call_count, 1) + @patch(file_path + '.path.exists') + @patch(file_path + '.get_setting') @patch(class_path + '.update_calibration_params_table') @patch(class_path + '.create_output_files') - @patch(class_path + '.load_sample') + @patch(file_path + ".path_handling.load_workspace") + @patch(class_path + '.run_calibration') + @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') + def test_having_full_calib_set_uses_file(self, van_corr, calibrate_alg, load_workspace, output_files, + update_table, setting, path): + path.return_value = True + setting.return_value = "mocked/out/path" + van_corr.return_value = ("mocked_integration", "mocked_curves") + load_workspace.return_value = "mocked_workspace" + self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False, "ENGINX") + calibrate_alg.assert_called_with("mocked_workspace", "mocked_integration", "mocked_curves", + full_calib_ws="mocked_workspace") + + @patch(class_path + '.update_calibration_params_table') + @patch(class_path + '.create_output_files') + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') @patch(class_path + '._plot_vanadium_curves') @patch(class_path + '._generate_difc_tzero_workspace') @@ -75,7 +92,7 @@ class CalibrationModelTest(unittest.TestCase): @patch(class_path + '.update_calibration_params_table') @patch(class_path + '.create_output_files') - @patch(class_path + '.load_sample') + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') @patch(class_path + '._plot_vanadium_curves') @patch(class_path + '._plot_difc_tzero') @@ -93,7 +110,7 @@ class CalibrationModelTest(unittest.TestCase): @patch(class_path + '.update_calibration_params_table') @patch(class_path + '.create_output_files') - @patch(class_path + '.load_sample') + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') @patch(class_path + '._plot_vanadium_curves') @patch(class_path + '._plot_difc_tzero') @@ -107,7 +124,7 @@ class CalibrationModelTest(unittest.TestCase): @patch(class_path + '.update_calibration_params_table') @patch(class_path + '.create_output_files') - @patch(class_path + '.load_sample') + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + '.vanadium_corrections.fetch_correction_workspaces') @patch(class_path + '.run_calibration') def test_calibration_params_table_is_updated(self, calibrate_alg, vanadium_alg, load_sample, diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py b/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py index 35da5482bfb72effedfcd22855f0363533fd28c5..ca37e6d9d6ef57218cba4d7db6bba44b5ae3bb7a 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/common/path_handling.py @@ -8,9 +8,29 @@ from __future__ import (absolute_import, division, print_function) from os import path +from mantid.kernel import logger +from mantid.simpleapi import Load +from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting -OUT_FILES_ROOT_DIR = path.join(path.expanduser("~"), "Engineering_Mantid") +INTERFACES_SETTINGS_GROUP = "CustomInterfaces" +ENGINEERING_PREFIX = "EngineeringDiffraction2/" def get_run_number_from_path(run_path, instrument): return path.splitext(path.basename(run_path))[0].replace(instrument, '').lstrip('0') + + +def get_output_path(): + location = get_setting(INTERFACES_SETTINGS_GROUP, ENGINEERING_PREFIX, "save_location") + return location if location is not None else "" + + +def load_workspace(file_path): + try: + return Load(Filename=file_path, OutputWorkspace="engggui_calibration_sample_ws") + except Exception as e: + logger.error("Error while loading workspace. " + "Could not run the algorithm Load successfully for the data file " + "(path: " + str(file_path) + "). Error description: " + str(e) + + " Please check also the previous log messages for details.") + raise RuntimeError diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py b/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py index 9fa9503123401c3611d891c5a1816bc513030851..9468b3183a861f4f355a5410f145b36717f7fd2e 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/common/test/test_vanadium_corrections.py @@ -59,17 +59,19 @@ class VanadiumCorrectionsTest(unittest.TestCase): self.assertEqual(0, van_correction.call_count) self.assertEqual(0, save.call_count) + @patch(dir_path + ".vanadium_corrections.path_handling.get_output_path") @patch(dir_path + ".vanadium_corrections.makedirs") - def test_file_path_generation(self, makedirs): + def test_file_path_generation(self, makedirs, out_path): + out_path.return_value = path.join(path.expanduser("~"), "Test_Directory") vanadium_run_number = "1234" - engineering_path = path.join(path.expanduser("~"), "Engineering_Mantid") + engineering_path = path.join(path.expanduser("~"), "Test_Directory") if path.exists(engineering_path): rmtree(engineering_path) output = vanadium_corrections._generate_saved_workspace_file_paths(vanadium_run_number) self.assertEqual(output, - (path.join(path.expanduser("~"), "Engineering_Mantid", "Vanadium_Runs", + (path.join(path.expanduser("~"), "Test_Directory", "Vanadium_Runs", "1234_precalculated_vanadium_run_integration.nxs"), - path.join(path.expanduser("~"), "Engineering_Mantid", "Vanadium_Runs", + path.join(path.expanduser("~"), "Test_Directory", "Vanadium_Runs", "1234_precalculated_vanadium_run_bank_curves.nxs"))) self.assertEqual(1, makedirs.call_count) diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py b/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py index 2f79c91c4990f585815bb7e6186540be7c01085a..0fa938deb76c981da0d00947a391b6b2882a6e1b 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/common/vanadium_corrections.py @@ -14,6 +14,7 @@ from mantid.simpleapi import logger, Load, EnggVanadiumCorrections, SaveNexus from mantid.simpleapi import AnalysisDataService as Ads from Engineering.gui.engineering_diffraction.tabs.common import path_handling +from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting VANADIUM_INPUT_WORKSPACE_NAME = "engggui_vanadium_ws" CURVES_WORKSPACE_NAME = "engggui_vanadium_curves" @@ -35,7 +36,9 @@ def fetch_correction_workspaces(vanadium_path, instrument, rb_num=""): """ vanadium_number = path_handling.get_run_number_from_path(vanadium_path, instrument) integ_path, curves_path = _generate_saved_workspace_file_paths(vanadium_number) - if path.exists(curves_path) and path.exists(integ_path): # Check if the cached files exist. + force_recalc = get_setting(path_handling.INTERFACES_SETTINGS_GROUP, + path_handling.ENGINEERING_PREFIX, "recalc_vanadium", return_type=bool) + if path.exists(curves_path) and path.exists(integ_path) and not force_recalc: # Check if the cached files exist. try: integ_workspace = Load(Filename=integ_path, OutputWorkspace=INTEGRATED_WORKSPACE_NAME) curves_workspace = Load(Filename=curves_path, OutputWorkspace=CURVES_WORKSPACE_NAME) @@ -48,7 +51,7 @@ def fetch_correction_workspaces(vanadium_path, instrument, rb_num=""): return integ_workspace, curves_workspace except RuntimeError as e: logger.error( - "Problem loading existing vanadium calculations. Creating new cached files. Description: " + "Problem loading existing vanadium calculations. Creating new files. Description: " + str(e)) integ_workspace, curves_workspace = _calculate_vanadium_correction(vanadium_path) _save_correction_files(integ_workspace, integ_path, curves_workspace, curves_path) @@ -113,10 +116,10 @@ def _generate_saved_workspace_file_paths(vanadium_number, rb_num=""): integrated_filename = vanadium_number + SAVED_FILE_INTEG_SUFFIX curves_filename = vanadium_number + SAVED_FILE_CURVE_SUFFIX if rb_num: - vanadium_dir = path.join(path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, + vanadium_dir = path.join(path_handling.get_output_path(), "User", rb_num, VANADIUM_DIRECTORY_NAME) else: - vanadium_dir = path.join(path_handling.OUT_FILES_ROOT_DIR, VANADIUM_DIRECTORY_NAME) + vanadium_dir = path.join(path_handling.get_output_path(), VANADIUM_DIRECTORY_NAME) if not path.exists(vanadium_dir): makedirs(vanadium_dir) return path.join(vanadium_dir, integrated_filename), path.join(vanadium_dir, curves_filename) diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py index 9b67f260aba5d3b9110b2f22c71bc8c6509d1b0a..d4cd2e5f713959ab55c51151c63c049c16522bfd 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py @@ -12,7 +12,8 @@ from matplotlib import gridspec import matplotlib.pyplot as plt from Engineering.gui.engineering_diffraction.tabs.common import vanadium_corrections, path_handling -from mantid.simpleapi import EnggFocus, Load, logger, AnalysisDataService as Ads, SaveNexus, SaveGSS, SaveFocusedXYE +from Engineering.gui.engineering_diffraction.settings.settings_helper import get_setting +from mantid.simpleapi import EnggFocus, logger, AnalysisDataService as Ads, SaveNexus, SaveGSS, SaveFocusedXYE SAMPLE_RUN_WORKSPACE_NAME = "engggui_focusing_input_ws" FOCUSED_OUTPUT_WORKSPACE_NAME = "engggui_focusing_output_ws_bank_" @@ -33,12 +34,18 @@ class FocusModel(object): return integration_workspace = Ads.retrieve(vanadium_corrections.INTEGRATED_WORKSPACE_NAME) curves_workspace = Ads.retrieve(vanadium_corrections.CURVES_WORKSPACE_NAME) - sample_workspace = self._load_focus_sample_run(sample_path) + sample_workspace = path_handling.load_workspace(sample_path) output_workspaces = [] + full_calib_path = get_setting(path_handling.INTERFACES_SETTINGS_GROUP, + path_handling.ENGINEERING_PREFIX, "full_calibration") + if full_calib_path is not None and path.exists(full_calib_path): + full_calib_workspace = path_handling.load_workspace(full_calib_path) + else: + full_calib_workspace = None for name in banks: output_workspace_name = FOCUSED_OUTPUT_WORKSPACE_NAME + str(name) self._run_focus(sample_workspace, output_workspace_name, integration_workspace, - curves_workspace, name) + curves_workspace, name, full_calib_workspace) output_workspaces.append(output_workspace_name) # Save the output to the file system. self._save_output(instrument, sample_path, name, output_workspace_name, rb_num) @@ -47,30 +54,32 @@ class FocusModel(object): self._plot_focused_workspaces(output_workspaces) @staticmethod - def _run_focus(input_workspace, output_workspace, vanadium_integration_ws, vanadium_curves_ws, - bank): + def _run_focus(input_workspace, + output_workspace, + vanadium_integration_ws, + vanadium_curves_ws, + bank, + full_calib_ws=None): try: - return EnggFocus(InputWorkspace=input_workspace, - OutputWorkspace=output_workspace, - VanIntegrationWorkspace=vanadium_integration_ws, - VanCurvesWorkspace=vanadium_curves_ws, - Bank=bank) + if full_calib_ws is not None: + return EnggFocus(InputWorkspace=input_workspace, + OutputWorkspace=output_workspace, + VanIntegrationWorkspace=vanadium_integration_ws, + VanCurvesWorkspace=vanadium_curves_ws, + Bank=bank, + DetectorPositions=full_calib_ws) + else: + return EnggFocus(InputWorkspace=input_workspace, + OutputWorkspace=output_workspace, + VanIntegrationWorkspace=vanadium_integration_ws, + VanCurvesWorkspace=vanadium_curves_ws, + Bank=bank) except RuntimeError as e: logger.error( "Error in focusing, Could not run the EnggFocus algorithm successfully for bank " + str(bank) + ". Error Description: " + str(e)) raise RuntimeError() - @staticmethod - def _load_focus_sample_run(sample_path): - try: - return Load(Filename=sample_path, OutputWorkspace=SAMPLE_RUN_WORKSPACE_NAME) - except RuntimeError as e: - logger.error( - "Error while loading sample data for focusing. Could not load the sample with filename: " - + sample_path + ". Error Description: " + str(e)) - raise RuntimeError - @staticmethod def _plot_focused_workspaces(focused_workspaces): fig = plt.figure() @@ -104,36 +113,36 @@ class FocusModel(object): def _save_focused_output_files_as_gss(self, instrument, sample_path, bank, sample_workspace, rb_num): gss_output_path = path.join( - path_handling.OUT_FILES_ROOT_DIR, "Focus", + path_handling.get_output_path(), "Focus", self._generate_output_file_name(instrument, sample_path, bank, ".gss")) SaveGSS(InputWorkspace=sample_workspace, Filename=gss_output_path) if rb_num is not None: gss_output_path = path.join( - path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, "Focus", + path_handling.get_output_path(), "User", rb_num, "Focus", self._generate_output_file_name(instrument, sample_path, bank, ".gss")) SaveGSS(InputWorkspace=sample_workspace, Filename=gss_output_path) def _save_focused_output_files_as_nexus(self, instrument, sample_path, bank, sample_workspace, rb_num): nexus_output_path = path.join( - path_handling.OUT_FILES_ROOT_DIR, "Focus", + path_handling.get_output_path(), "Focus", self._generate_output_file_name(instrument, sample_path, bank, ".nxs")) SaveNexus(InputWorkspace=sample_workspace, Filename=nexus_output_path) if rb_num is not None: nexus_output_path = path.join( - path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, "Focus", + path_handling.get_output_path(), "User", rb_num, "Focus", self._generate_output_file_name(instrument, sample_path, bank, ".nxs")) SaveNexus(InputWorkspace=sample_workspace, Filename=nexus_output_path) def _save_focused_output_files_as_xye(self, instrument, sample_path, bank, sample_workspace, rb_num): xye_output_path = path.join( - path_handling.OUT_FILES_ROOT_DIR, "Focus", + path_handling.get_output_path(), "Focus", self._generate_output_file_name(instrument, sample_path, bank, ".dat")) SaveFocusedXYE(InputWorkspace=sample_workspace, Filename=xye_output_path, SplitFiles=False) if rb_num is not None: xye_output_path = path.join( - path_handling.OUT_FILES_ROOT_DIR, "User", rb_num, "Focus", + path_handling.get_output_path(), "User", rb_num, "Focus", self._generate_output_file_name(instrument, sample_path, bank, ".dat")) SaveFocusedXYE(InputWorkspace=sample_workspace, Filename=xye_output_path, diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py index 53b8456052a5e0b8d271ec15a95631b49e75e377..bf476ed3a1ed7958cef5c0fb8f38e0f0aafaf309 100644 --- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_focus_model.py @@ -25,7 +25,7 @@ class FocusModelTest(unittest.TestCase): sample_path="this_is_mocked_out_too", instrument="ENGINX") - @patch(file_path + ".FocusModel._load_focus_sample_run") + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + ".vanadium_corrections.Ads.doesExist") def test_focus_cancelled_if_van_wsp_missing(self, ads_exist, load): ads_exist.return_value = False @@ -35,7 +35,7 @@ class FocusModelTest(unittest.TestCase): @patch(file_path + ".Ads") @patch(file_path + ".FocusModel._save_output") @patch(file_path + ".FocusModel._run_focus") - @patch(file_path + ".FocusModel._load_focus_sample_run") + @patch(file_path + ".path_handling.load_workspace") def test_focus_run_for_each_bank(self, load_focus, run_focus, output, ads): ads.retrieve.return_value = "test_wsp" banks = ["1", "2"] @@ -45,13 +45,13 @@ class FocusModelTest(unittest.TestCase): self.assertEqual(len(banks), run_focus.call_count) run_focus.assert_called_with("mocked_sample", model.FOCUSED_OUTPUT_WORKSPACE_NAME + banks[-1], "test_wsp", - "test_wsp", banks[-1]) + "test_wsp", banks[-1], None) @patch(file_path + ".Ads") @patch(file_path + ".FocusModel._save_output") @patch(file_path + ".FocusModel._plot_focused_workspaces") @patch(file_path + ".FocusModel._run_focus") - @patch(file_path + ".FocusModel._load_focus_sample_run") + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + ".vanadium_corrections.fetch_correction_workspaces") def test_focus_plotted_when_checked(self, fetch_van, load_focus, run_focus, plot_focus, output, ads): @@ -67,7 +67,7 @@ class FocusModelTest(unittest.TestCase): @patch(file_path + ".FocusModel._save_output") @patch(file_path + ".FocusModel._plot_focused_workspaces") @patch(file_path + ".FocusModel._run_focus") - @patch(file_path + ".FocusModel._load_focus_sample_run") + @patch(file_path + ".path_handling.load_workspace") @patch(file_path + ".vanadium_corrections.fetch_correction_workspaces") def test_focus_not_plotted_when_not_checked(self, fetch_van, load_focus, run_focus, plot_focus, output, ads): @@ -83,7 +83,7 @@ class FocusModelTest(unittest.TestCase): @patch(file_path + ".SaveNexus") def test_save_output_files_with_no_RB_number(self, nexus, gss, xye): mocked_workspace = "mocked-workspace" - output_file = path.join(path_handling.OUT_FILES_ROOT_DIR, "Focus", + output_file = path.join(path_handling.get_output_path(), "Focus", "ENGINX_123_bank_North.nxs") self.model._save_output("ENGINX", "Path/To/ENGINX000123.whatever", "North",