Unverified Commit b1d6167c authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony Committed by GitHub
Browse files

Merge pull request #28393 from mantidproject/28360_eng_focusing_output

Improve Outputs When Focusing in Eng Diff 2 GUI
parents d306fe4f 21c844b3
......@@ -121,7 +121,8 @@ a plot for each bank and cropped focusing generates a plot for the single bank o
Clicking the focus button will begin the focusing algorithm for the selected run files. The button and plotting checkbox
will be disabled until the fitting algorithm is complete.
The focused output files are saved in NeXus, GSS, and raw XYE format to:
The focused output files are saved in NeXus, GSS, and TOPAS format. The process will also output a CSV file containing
all numerical sample logs. All of these files are saved to:
`<CHOSEN_OUTPUT_DIRECTORY>/Focus/`
......
......@@ -14,6 +14,10 @@ Powder Diffraction
Engineering Diffraction
-----------------------
Improvements
^^^^^^^^^^^^
- TOPAS files (`.abc`) have replaced the `.dat` files generated when focusing using the GUI.
- Focusing with the GUI will now generate a CSV containing the averaged values of all numerical sample logs.
Single Crystal Diffraction
--------------------------
......
......@@ -6,7 +6,8 @@
# SPDX - License - Identifier: GPL - 3.0 +
from __future__ import (absolute_import, division, print_function)
from os import path
import csv
from os import path, makedirs
from matplotlib import gridspec
import matplotlib.pyplot as plt
......@@ -55,6 +56,7 @@ class FocusModel(object):
# Save the output to the file system.
self._save_output(instrument, sample_path, name, output_workspace_name, rb_num)
output_workspaces.append(workspaces_for_run)
self._output_sample_logs(instrument, run_no, sample_workspace, rb_num)
else:
for sample_path in sample_paths:
sample_workspace = path_handling.load_workspace(sample_path)
......@@ -64,6 +66,7 @@ class FocusModel(object):
curves_workspace, None, full_calib_workspace, spectrum_numbers)
output_workspaces.append([output_workspace_name])
self._save_output(instrument, sample_path, "cropped", output_workspace_name, rb_num)
self._output_sample_logs(instrument, run_no, sample_workspace, rb_num)
# Plot the output
if plot_output:
for ws_names in output_workspaces:
......@@ -126,8 +129,8 @@ class FocusModel(object):
rb_num)
self._save_focused_output_files_as_gss(instrument, sample_path, bank, sample_workspace,
rb_num)
self._save_focused_output_files_as_xye(instrument, sample_path, bank, sample_workspace,
rb_num)
self._save_focused_output_files_as_topas_xye(instrument, sample_path, bank, sample_workspace,
rb_num)
def _save_focused_output_files_as_gss(self, instrument, sample_path, bank, sample_workspace,
rb_num):
......@@ -153,19 +156,53 @@ class FocusModel(object):
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):
def _save_focused_output_files_as_topas_xye(self, instrument, sample_path, bank,
sample_workspace, rb_num):
xye_output_path = path.join(
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)
self._generate_output_file_name(instrument, sample_path, bank, ".abc"))
SaveFocusedXYE(InputWorkspace=sample_workspace,
Filename=xye_output_path,
SplitFiles=False,
Format="TOPAS")
if rb_num:
xye_output_path = path.join(
path_handling.get_output_path(), "User", rb_num, "Focus",
self._generate_output_file_name(instrument, sample_path, bank, ".dat"))
self._generate_output_file_name(instrument, sample_path, bank, ".abc"))
SaveFocusedXYE(InputWorkspace=sample_workspace,
Filename=xye_output_path,
SplitFiles=False)
SplitFiles=False,
Format="TOPAS")
@staticmethod
def _output_sample_logs(instrument, run_number, workspace, rb_num):
def write_to_file():
with open(output_path, "w", newline="") as logfile:
writer = csv.writer(logfile, ["Sample Log", "Avg Value"])
for log in output_dict:
writer.writerow([log, output_dict[log]])
output_dict = {}
sample_run = workspace.getRun()
log_names = sample_run.keys()
# Collect numerical sample logs.
for name in log_names:
try:
output_dict[name] = sample_run.getPropertyAsSingleValue(name)
except ValueError:
logger.information(f"Could not convert {name} to a numerical value. It will not be included in the "
f"sample logs output file.")
focus_dir = path.join(path_handling.get_output_path(), "Focus")
if not path.exists(focus_dir):
makedirs(focus_dir)
output_path = path.join(focus_dir, (instrument + "_" + run_number + "_sample_logs.csv"))
write_to_file()
if rb_num:
focus_user_dir = path.join(path_handling.get_output_path(), "User", rb_num, "Focus")
if not path.exists(focus_user_dir):
makedirs(focus_user_dir)
output_path = path.join(focus_user_dir, (instrument + "_" + run_number + "_sample_logs.csv"))
write_to_file()
@staticmethod
def _generate_output_file_name(instrument, sample_path, bank, suffix):
......
......@@ -7,9 +7,12 @@
from __future__ import (absolute_import, division, print_function)
import unittest
import tempfile
import shutil
from os import path
from mantid.py3compat.mock import patch
from mantid.py3compat.mock import patch, MagicMock
from mantid.simpleapi import CreateSampleWorkspace
from Engineering.gui.engineering_diffraction.tabs.focus import model
from Engineering.gui.engineering_diffraction.tabs.common import path_handling
from Engineering.gui.engineering_diffraction.tabs.common.calibration_info import CalibrationInfo
......@@ -19,11 +22,15 @@ file_path = "Engineering.gui.engineering_diffraction.tabs.focus.model"
class FocusModelTest(unittest.TestCase):
def setUp(self):
self.test_dir = tempfile.mkdtemp()
self.model = model.FocusModel()
self.current_calibration = CalibrationInfo(vanadium_path="/mocked/out/anyway",
sample_path="this_is_mocked_out_too",
instrument="ENGINX")
def tearDown(self):
shutil.rmtree(self.test_dir)
@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):
......@@ -31,11 +38,12 @@ class FocusModelTest(unittest.TestCase):
self.model.focus_run("307593", ["1", "2"], False, "ENGINX", "0", None)
self.assertEqual(load.call_count, 0)
@patch(file_path + ".FocusModel._output_sample_logs")
@patch(file_path + ".Ads")
@patch(file_path + ".FocusModel._save_output")
@patch(file_path + ".FocusModel._run_focus")
@patch(file_path + ".path_handling.load_workspace")
def test_focus_run_for_each_bank(self, load_focus, run_focus, output, ads):
def test_focus_run_for_each_bank(self, load_focus, run_focus, output, ads, logs):
ads.retrieve.return_value = "test_wsp"
banks = ["1", "2"]
load_focus.return_value = "mocked_sample"
......@@ -47,11 +55,12 @@ class FocusModelTest(unittest.TestCase):
"305761_" + model.FOCUSED_OUTPUT_WORKSPACE_NAME + banks[-1],
"test_wsp", "test_wsp", banks[-1], None)
@patch(file_path + ".FocusModel._output_sample_logs")
@patch(file_path + ".Ads")
@patch(file_path + ".FocusModel._save_output")
@patch(file_path + ".FocusModel._run_focus")
@patch(file_path + ".path_handling.load_workspace")
def test_focus_run_for_custom_spectra(self, load_focus, run_focus, output, ads):
def test_focus_run_for_custom_spectra(self, load_focus, run_focus, output, ads, logs):
ads.retrieve.return_value = "test_wsp"
spectra = "20-50"
load_focus.return_value = "mocked_sample"
......@@ -63,6 +72,7 @@ class FocusModelTest(unittest.TestCase):
"305761_" + model.FOCUSED_OUTPUT_WORKSPACE_NAME + "cropped",
"test_wsp", "test_wsp", None, None, spectra)
@patch(file_path + ".FocusModel._output_sample_logs")
@patch(file_path + ".Ads")
@patch(file_path + ".FocusModel._save_output")
@patch(file_path + ".FocusModel._plot_focused_workspaces")
......@@ -70,7 +80,7 @@ class FocusModelTest(unittest.TestCase):
@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):
ads, logs):
ads.doesExist.return_value = True
fetch_van.return_value = ("mocked_integ", "mocked_curves")
banks = ["1", "2"]
......@@ -80,6 +90,7 @@ class FocusModelTest(unittest.TestCase):
self.assertEqual(1, plot_focus.call_count)
@patch(file_path + ".FocusModel._output_sample_logs")
@patch(file_path + ".Ads")
@patch(file_path + ".FocusModel._save_output")
@patch(file_path + ".FocusModel._plot_focused_workspaces")
......@@ -87,7 +98,7 @@ class FocusModelTest(unittest.TestCase):
@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):
output, ads, logs):
fetch_van.return_value = ("mocked_integ", "mocked_curves")
banks = ["1", "2"]
load_focus.return_value = "mocked_sample"
......@@ -121,6 +132,36 @@ class FocusModelTest(unittest.TestCase):
self.assertEqual(gss.call_count, 2)
self.assertEqual(xye.call_count, 2)
@patch(file_path + ".logger")
@patch(file_path + ".path_handling.get_output_path")
@patch(file_path + ".csv")
def test_output_sample_logs_with_rb_number(self, mock_csv, mock_path, mock_logger):
mock_writer = MagicMock()
mock_csv.writer.return_value = mock_writer
mock_path.return_value = self.test_dir
ws = CreateSampleWorkspace()
self.model._output_sample_logs("ENGINX", "00000", ws, "0")
self.assertEqual(5, len(ws.getRun().keys()))
self.assertEqual(1, mock_logger.information.call_count)
self.assertEqual(8, mock_writer.writerow.call_count)
@patch(file_path + ".logger")
@patch(file_path + ".path_handling.get_output_path")
@patch(file_path + ".csv")
def test_output_sample_logs_without_rb_number(self, mock_csv, mock_path, mock_logger):
mock_writer = MagicMock()
mock_csv.writer.return_value = mock_writer
mock_path.return_value = self.test_dir
ws = CreateSampleWorkspace()
self.model._output_sample_logs("ENGINX", "00000", ws, None)
self.assertEqual(5, len(ws.getRun().keys()))
self.assertEqual(1, mock_logger.information.call_count)
self.assertEqual(4, mock_writer.writerow.call_count)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment