From 2e8d9966234025505e1a24d484a6e348b3c6c570 Mon Sep 17 00:00:00 2001 From: Conor Finn <conor.finn@stfc.ac.uk> Date: Mon, 23 Sep 2019 10:11:23 +0100 Subject: [PATCH] RE #26846 Engineering model and tests created --- .../Properties/Mantid.properties.template | 2 +- .../PythonInterface/mantid/kernel/_aliases.py | 2 +- scripts/CMakeLists.txt | 1 + scripts/Engineering/gui/CMakeLists.txt | 11 ++ scripts/Engineering/gui/__init__.py | 0 .../gui/engineering_diffraction/__init__.py | 0 .../engineering_diffraction/tabs/__init__.py | 0 .../tabs/calibration/__init__.py | 0 .../tabs/calibration/model.py | 135 ++++++++++++++++++ .../tabs/calibration/test/__init__.py | 0 .../tabs/calibration/test/test_model.py | 60 ++++++++ scripts/Engineering_Diffraction.py | 0 12 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 scripts/Engineering/gui/CMakeLists.txt create mode 100644 scripts/Engineering/gui/__init__.py create mode 100644 scripts/Engineering/gui/engineering_diffraction/__init__.py create mode 100644 scripts/Engineering/gui/engineering_diffraction/tabs/__init__.py create mode 100644 scripts/Engineering/gui/engineering_diffraction/tabs/calibration/__init__.py create mode 100644 scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py create mode 100644 scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/__init__.py create mode 100644 scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_model.py create mode 100644 scripts/Engineering_Diffraction.py diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template index 791b1a46247..7c083967d01 100644 --- a/Framework/Properties/Mantid.properties.template +++ b/Framework/Properties/Mantid.properties.template @@ -21,7 +21,7 @@ Q.convention = Inelastic # Set of PyQt interfaces to add to the Interfaces menu, separated by a space. Interfaces are seperated from their respective categories by a "/". -mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py Direct/PyChop.py Direct/MSlice.py SANS/ORNL_SANS.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry_Old.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_4Circle_Reduction.py Utility/QECoverage.py SANS/ISIS_SANS.py Muon/Frequency_Domain_Analysis.py Muon/Elemental_Analysis.py Muon/Frequency_Domain_Analysis_Old.py Muon/Muon_Analysis_2.py +mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py Direct/PyChop.py Direct/MSlice.py SANS/ORNL_SANS.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry_Old.py Diffraction/Powder_Diffraction_Reduction.py Diffraction/Engineering_Diffraction.py Utility/FilterEvents.py Diffraction/HFIR_4Circle_Reduction.py Utility/QECoverage.py SANS/ISIS_SANS.py Muon/Frequency_Domain_Analysis.py Muon/Elemental_Analysis.py Muon/Frequency_Domain_Analysis_Old.py Muon/Muon_Analysis_2.py # Directory containing the above startup scripts mantidqt.python_interfaces_directory = @MANTID_ROOT@/scripts diff --git a/Framework/PythonInterface/mantid/kernel/_aliases.py b/Framework/PythonInterface/mantid/kernel/_aliases.py index b6ac466b9d7..11e69e16a28 100644 --- a/Framework/PythonInterface/mantid/kernel/_aliases.py +++ b/Framework/PythonInterface/mantid/kernel/_aliases.py @@ -1,4 +1,4 @@ -# Mantid Repository : https://github.com/mantidproject/mantid +# Mantid Repository : https://github.com/mantidproject/mantmatrixWorkspaceid # # Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, # NScD Oak Ridge National Laboratory, European Spallation Source diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index c213cef13a5..ad119467cfd 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -87,6 +87,7 @@ install(FILES ${_scripts_pth_install} # Testing add_subdirectory(test) add_subdirectory(Diffraction/isis_powder) +add_subdirectory(Engineering/gui) # Ensure we don't get stale pyc files around clean_orphaned_pyc_files(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/scripts/Engineering/gui/CMakeLists.txt b/scripts/Engineering/gui/CMakeLists.txt new file mode 100644 index 00000000000..d6b317c2b8b --- /dev/null +++ b/scripts/Engineering/gui/CMakeLists.txt @@ -0,0 +1,11 @@ +# Tests for ISIS Powder + +set(TEST_PY_FILES + # Calibration + engineering_diffraction/tabs/calibration/test/test_model.py +) + +check_tests_valid(${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES}) + +pyunittest_add_test(${CMAKE_CURRENT_SOURCE_DIR} python.EngineeringDiffraction + ${TEST_PY_FILES}) \ No newline at end of file diff --git a/scripts/Engineering/gui/__init__.py b/scripts/Engineering/gui/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/Engineering/gui/engineering_diffraction/__init__.py b/scripts/Engineering/gui/engineering_diffraction/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/__init__.py b/scripts/Engineering/gui/engineering_diffraction/tabs/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/__init__.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py new file mode 100644 index 00000000000..1ef299eabc4 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/model.py @@ -0,0 +1,135 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2018 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 mantid.api import AnalysisDataService as Ads +from mantid.kernel import logger +from mantid.simpleapi import Load, EnggVanadiumCorrections, EnggCalibrate, DeleteWorkspace, CloneWorkspace, \ + CreateWorkspace, AppendSpectra +from mantidqt.plotting.functions import plot +from qtpy import QtCore + + +class CalibrationModel(object): + def __init__(self): + self.VANADIUM_INPUT_WORKSPACE_NAME = "engggui_vanadium_ws" + self.CURVES_WORKSPACE_NAME = "engggui_vanadium_curves" + self.INTEGRATED_WORKSPACE_NAME = "engggui_vanadium_integration" + + def create_new_calibration(self, vanadium_run_no, ceria_run_no, plot_output): + vanadium_corrections = self.calculate_vanadium_correction(vanadium_run_no) + van_integration = vanadium_corrections[0] + van_curves = vanadium_corrections[1] + ceria_workspace = self.load_ceria(ceria_run_no) + difc, tzero = [0] * 2 + self.run_calibration(ceria_workspace, van_integration, van_curves, difc, tzero) + if plot_output: + self.plot_vanadium_curves() + self._plot_difc_zero(difc, tzero) + + @staticmethod + def plot_vanadium_curves(): + van_curve_twin_ws = "__engggui_vanadium_curves_twin_ws" + + if Ads.doesExist(van_curve_twin_ws): + DeleteWorkspace(van_curve_twin_ws) + CloneWorkspace(InputWorkspace="engggui_vanadium_curves", OutputWorkspace=van_curve_twin_ws) + van_curves_ws = Ads.retrieve(van_curve_twin_ws) + for i in range(1, 3): + if i == 1: + curve_plot_bank_1 = plot([van_curves_ws], [0, 1, 2]).activeLayer() + curve_plot_bank_1.setTitle("Engg GUI Vanadium Curves Bank 1") + if i == 2: + curve_plot_bank_2 = plot([van_curves_ws], [3, 4, 5]).activeLayer() + curve_plot_bank_2.setTitle("Engg GUI Vanadium Curves Bank 2") + + @staticmethod + def _plot_difc_zero(difc, tzero): + for i in range(1, 3): + bank_ws = Ads.retrieve("engggui_calibration_bank_" + str(i)) + + x_val = [] + y_val = [] + y2_val = [] + + if i == 1: + difc_to_plot = difc[0] + tzero_to_plot = tzero[0] + else: + difc_to_plot = difc[1] + tzero_to_plot = tzero[1] + + for irow in range(0, bank_ws.rowCount()): + x_val.append(bank_ws.cell(irow, 0)) + y_val.append(bank_ws.cell(irow, 5)) + y2_val.append(x_val[irow] * difc_to_plot + tzero_to_plot) + + ws1 = CreateWorkspace(DataX=x_val, + DataY=y_val, + UnitX="Expected Peaks Centre (dSpacing A)", + YUnitLabel="Fitted Peaks Centre(TOF, us)") + ws2 = CreateWorkspace(DataX=x_val, DataY=y2_val) + + output_ws = "engggui_difc_zero_peaks_bank_" + str(i) + if Ads.doesExist(output_ws): + DeleteWorkspace(output_ws) + + AppendSpectra(ws1, ws2, OutputWorkspace=output_ws) + DeleteWorkspace(ws1) + DeleteWorkspace(ws2) + + difc_zero_ws = Ads.retreive(output_ws) + # Create plot + difc_zero_plot = plot(difc_zero_ws, [0, 1]).activeLayer() + difc_zero_plot.setTitle("Engg Gui Difc Zero Peaks Bank " + str(i)) + difc_zero_plot.setCurveTitle(0, "Peaks Fitted") + difc_zero_plot.setCurveTitle(1, "DifC/TZero Fitted Straight Line") + difc_zero_plot.xlabel("Expected Peaks Centre(dSpacing, A)") + difc_zero_plot.setCurveLineStyly(0, QtCore.Qt.DotLine) + + def load_ceria(self, ceria_run_no): + try: + return Load(Filename=ceria_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 succesfully for the calibration sample " + "(run number: " + str(ceria_run_no) + "). Error description: " + str(e) + + " Please check also the previous log messages for details.") + raise RuntimeError + + def run_calibration(self, ceria_ws, van_integration, van_curves, difc, tzero): + for i in range(2): + table_name = self._generate_table_workspace_name(i) + EnggCalibrate(InputWorkspace=ceria_ws, + VanIntegrationWorkspace=van_integration, + VanCurvesWorkspace=van_curves, + Bank=i, + FittedPeaks=table_name, + OutputParametersTableName=table_name, + DIFC=difc[i], + TZERO=tzero[i]) + + def calculate_vanadium_correction(self, vanadium_run_no): + try: + Load(Filename=vanadium_run_no, OutputWorkspace=self.VANADIUM_INPUT_WORKSPACE_NAME) + except Exception as e: + logger.error("Error when loading vanadium sample data. " + "Could not run Load algorithm with vanadium run number: " + + str(vanadium_run_no) + ". Error description: " + str(e)) + raise RuntimeError + EnggVanadiumCorrections(VanadiumWorkspace=self.VANADIUM_INPUT_WORKSPACE_NAME, + OutIntegrationWorkspace=self.INTEGRATED_WORKSPACE_NAME, + OutCurvesWorkspace=self.CURVES_WORKSPACE_NAME) + Ads.remove(self.VANADIUM_INPUT_WORKSPACE_NAME) + integrated_workspace = Ads.Instance().retrive(self.INTEGRATED_WORKSPACE_NAME) + curves_workspace = Ads.Instance().retrieve(self.CURVES_WORKSPACE_NAME) + return integrated_workspace, curves_workspace + + @staticmethod + def _generate_table_workspace_name(bank_num): + return "engggui_calibration_bank_" + str(bank_num + 1) diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/__init__.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_model.py new file mode 100644 index 00000000000..e1ae5491361 --- /dev/null +++ b/scripts/Engineering/gui/engineering_diffraction/tabs/calibration/test/test_model.py @@ -0,0 +1,60 @@ +# Mantid Repository : https://github.com/mantidproject/mantid +# +# Copyright © 2018 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, MagicMock +from Engineering.gui.engineering_diffraction.tabs.calibration.model import CalibrationModel + +VANADIUM_NUMBER = 307521 +CERIUM_NUMBER = 305738 +INTEGRATED_WORKSPACE_NAME = "engggui_vanadium_integration" +CURVES_WORKSPACE_NAME = "engggui_vanadium_curves" +INPUT_WORKSPACE_NAME = "engggui_vanadium_ws" +class_path = 'Engineering.gui.engineering_diffraction.tabs.calibration.model.CalibrationModel' + + +class CalibrationModelTest(unittest.TestCase): + def setUp(self): + self.model = CalibrationModel() + + def test_fails_on_invalid_run_number(self): + self.assertRaises(RuntimeError, self.model.create_new_calibration, "FAIL", 305738, True) + self.assertRaises(RuntimeError, self.model.create_new_calibration, 307521, "FAIL", True) + + @patch(class_path + '.run_calibration') + @patch(class_path + '.load_ceria') + @patch(class_path + '.calculate_vanadium_correction') + def test_EnggVanadiumCorrections_algorithm_is_called(self, alg, load_ceria, calib): + self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False) + alg.assert_called_once() + + @patch(class_path + '.load_ceria') + @patch(class_path + '.calculate_vanadium_correction') + @patch(class_path + '.run_calibration') + def test_EnggCalibrate_algorithm_is_called(self, calibrate_alg, vanadium_alg, load_ceria): + self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False) + self.assertEqual(calibrate_alg.call_count, 1) + + @patch(class_path + '.load_ceria') + @patch(class_path + '.calculate_vanadium_correction') + @patch(class_path + '.plot_vanadium_curves') + @patch(class_path + '._plot_difc_zero') + @patch(class_path + '.run_calibration') + def test_plotting_check(self, calib, plot_difc_zero, plot_van, van, ceria): + self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, False) + plot_van.assert_not_called() + plot_difc_zero.assert_not_called() + self.model.create_new_calibration(VANADIUM_NUMBER, CERIUM_NUMBER, True) + plot_van.assert_called_once() + plot_difc_zero.assert_called_once() + + +if __name__ == '__main__': + unittest.main() diff --git a/scripts/Engineering_Diffraction.py b/scripts/Engineering_Diffraction.py new file mode 100644 index 00000000000..e69de29bb2d -- GitLab