From d665388b448a4bc22b97547b76a5355bb8abcec3 Mon Sep 17 00:00:00 2001
From: Conor Finn <conor.finn@stfc.ac.uk>
Date: Mon, 21 Oct 2019 17:19:13 +0100
Subject: [PATCH] RE #27012 Make focusing save to the file system

Creating a new focus now saves a nexus file to the file system. The old GUI saves multiple file types, but since I'm not sure what they actually use, nexus seems like a safe proof of concept for now.
---
 .../tabs/focus/model.py                       | 37 ++++++++++++++++---
 .../tabs/focus/test/test_model.py             | 30 +++++++++++++--
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py
index 27ca38e70c7..904dbffbeb8 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/model.py
@@ -7,8 +7,11 @@
 
 from __future__ import (absolute_import, division, print_function)
 
-from Engineering.gui.engineering_diffraction.tabs.common import vanadium_corrections
-from mantid.simpleapi import EnggFocus, Load, logger, AnalysisDataService as Ads
+from os import path
+from os import makedirs
+
+from Engineering.gui.engineering_diffraction.tabs.common import vanadium_corrections, path_handling
+from mantid.simpleapi import EnggFocus, Load, logger, AnalysisDataService as Ads, SaveNexus
 from mantidqt.plotting.functions import plot
 
 SAMPLE_RUN_WORKSPACE_NAME = "engggui_focusing_input_ws"
@@ -25,13 +28,18 @@ class FocusModel(object):
         sample_workspace = self._load_focus_sample_run(sample_path)
         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)
+            self._run_focus(sample_workspace, output_workspace_name, integration_workspace,
+                            curves_workspace, name)
+            # Plot the output
             if plot_output:
                 self._plot_focused_workspace(output_workspace_name)
+            # Save the output to the file system.
+            self.save_focused_output_files_as_nexus(instrument, sample_path, name,
+                                                    output_workspace_name, rb_number)
 
     @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):
         try:
             return EnggFocus(InputWorkspace=input_workspace,
                              OutputWorkspace=output_workspace,
@@ -57,4 +65,21 @@ class FocusModel(object):
     @staticmethod
     def _plot_focused_workspace(focused):
         focused_wsp = Ads.retrieve(focused)
-        plot([focused_wsp], wksp_indices=[0])
\ No newline at end of file
+        plot([focused_wsp], wksp_indices=[0])
+
+    def save_focused_output_files_as_nexus(self, instrument, sample_path, bank, sample_workspace,
+                                           rb_number):
+        nexus_output_path = path.join(
+            path_handling.OUT_FILES_ROOT_DIR, "Focus",
+            self.generate_output_file_name(instrument, sample_path, bank, ".nxs"))
+        SaveNexus(InputWorkspace=sample_workspace, Filename=nexus_output_path)
+        if rb_number is not None:
+            nexus_output_path = path.join(
+                path_handling.OUT_FILES_ROOT_DIR, "User", rb_number, "Focus",
+                self.generate_output_file_name(instrument, sample_path, bank, ".nxs"))
+            SaveNexus(InputWorkspace=sample_workspace, Filename=nexus_output_path)
+
+    @staticmethod
+    def generate_output_file_name(instrument, sample_path, bank, suffix):
+        run_no = path_handling.get_run_number_from_path(sample_path, instrument)
+        return instrument + "_" + run_no + "_bank_" + bank + suffix
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_model.py b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_model.py
index 6ede0137ddf..b21953fdf7e 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_model.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/focus/test/test_model.py
@@ -8,9 +8,11 @@
 from __future__ import (absolute_import, division, print_function)
 
 import unittest
+from os import path
 
 from mantid.py3compat.mock import patch
 from Engineering.gui.engineering_diffraction.tabs.focus import model
+from Engineering.gui.engineering_diffraction.tabs.common import path_handling
 
 file_path = "Engineering.gui.engineering_diffraction.tabs.focus.model"
 
@@ -37,10 +39,11 @@ class FocusModelTest(unittest.TestCase):
         self.model.focus_run("305761", ["1", "2"], False, "ENGINX", "0", blank_calibration)
         self.assertEqual(fetch_van.call_count, 0)
 
+    @patch(file_path + ".FocusModel.save_focused_output_files_as_nexus")
     @patch(file_path + ".FocusModel._run_focus")
     @patch(file_path + ".FocusModel._load_focus_sample_run")
     @patch(file_path + ".vanadium_corrections.fetch_correction_workspaces")
-    def test_focus_run_for_each_bank(self, fetch_van, load_focus, run_focus):
+    def test_focus_run_for_each_bank(self, fetch_van, load_focus, run_focus, output):
         fetch_van.return_value = ("mocked_integ", "mocked_curves")
         banks = ["1", "2"]
         load_focus.return_value = "mocked_sample"
@@ -51,11 +54,12 @@ class FocusModelTest(unittest.TestCase):
                                      model.FOCUSED_OUTPUT_WORKSPACE_NAME + banks[-1],
                                      "mocked_integ", "mocked_curves", banks[-1])
 
+    @patch(file_path + ".FocusModel.save_focused_output_files_as_nexus")
     @patch(file_path + ".FocusModel._plot_focused_workspace")
     @patch(file_path + ".FocusModel._run_focus")
     @patch(file_path + ".FocusModel._load_focus_sample_run")
     @patch(file_path + ".vanadium_corrections.fetch_correction_workspaces")
-    def test_focus_plotted_when_checked(self, fetch_van, load_focus, run_focus, plot_focus):
+    def test_focus_plotted_when_checked(self, fetch_van, load_focus, run_focus, plot_focus, output):
         fetch_van.return_value = ("mocked_integ", "mocked_curves")
         banks = ["1", "2"]
         load_focus.return_value = "mocked_sample"
@@ -63,14 +67,34 @@ class FocusModelTest(unittest.TestCase):
         self.model.focus_run("305761", banks, True, "ENGINX", "0", self.current_calibration)
         self.assertEqual(len(banks), plot_focus.call_count)
 
+    @patch(file_path + ".FocusModel.save_focused_output_files_as_nexus")
     @patch(file_path + ".FocusModel._plot_focused_workspace")
     @patch(file_path + ".FocusModel._run_focus")
     @patch(file_path + ".FocusModel._load_focus_sample_run")
     @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):
+    def test_focus_not_plotted_when_not_checked(self, fetch_van, load_focus, run_focus, plot_focus,
+                                                output):
         fetch_van.return_value = ("mocked_integ", "mocked_curves")
         banks = ["1", "2"]
         load_focus.return_value = "mocked_sample"
 
         self.model.focus_run("305761", banks, False, "ENGINX", "0", self.current_calibration)
         self.assertEqual(0, plot_focus.call_count)
+
+    @patch(file_path + ".SaveNexus")
+    def test_save_output_files_nexus_with_no_RB_number(self, save):
+        mocked_workspace = "mocked-workspace"
+        output_file = path.join(path_handling.OUT_FILES_ROOT_DIR, "Focus",
+                                "ENGINX_123_bank_North.nxs")
+        self.model.save_focused_output_files_as_nexus("ENGINX", "Path/To/ENGINX000123.whatever",
+                                                      "North", mocked_workspace, None)
+
+        self.assertEqual(1, save.call_count)
+        save.assert_called_with(mocked_workspace, output_file)
+
+    @patch(file_path + ".SaveNexus")
+    def test_save_output_files_nexus_with_no_RB_number(self, save):
+        self.model.save_focused_output_files_as_nexus("ENGINX", "Path/To/ENGINX000123.whatever",
+                                                      "North", "mocked-workspace",
+                                                      "An Experiment Number")
+        self.assertEqual(2, save.call_count)
-- 
GitLab