From 9790ccb1a0a4e56a84020a1a7565e0ebce96eaf8 Mon Sep 17 00:00:00 2001
From: Ross Whitfield <whitfieldre@ornl.gov>
Date: Fri, 4 May 2018 11:58:34 -0400
Subject: [PATCH] Allow LoadWAND to load multiple file

And group the loaded files. Also add option to load by setting IPTS and run numbers.
---
 .../algorithms/WorkflowAlgorithms/LoadWAND.py | 79 +++++++++++++------
 docs/source/algorithms/LoadWAND-v1.rst        | 54 +++++++++++--
 2 files changed, 102 insertions(+), 31 deletions(-)

diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py
index 195d865e6b8..f447ddaffea 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/LoadWAND.py
@@ -1,7 +1,8 @@
 from __future__ import absolute_import, division, print_function
-from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, FileProperty, FileAction, WorkspaceProperty
-from mantid.kernel import Direction, UnitConversion, Elastic
-from mantid.simpleapi import LoadEventNexus, Integration, mtd, SetGoniometer, DeleteWorkspace, AddSampleLog, MaskBTP
+from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MultipleFileProperty, FileAction, WorkspaceProperty
+from mantid.kernel import Direction, UnitConversion, Elastic, Property, IntArrayProperty
+from mantid.simpleapi import (LoadEventNexus, Integration, mtd, SetGoniometer, DeleteWorkspace, AddSampleLog,
+                              MaskBTP, RenameWorkspace, GroupWorkspaces)
 from six.moves import range
 
 
@@ -16,40 +17,68 @@ class LoadWAND(DataProcessorAlgorithm):
         return 'Loads Event Nexus file, integrates events, sets wavelength, mask, and goniometer, and sets proton charge to monitor counts'
 
     def PyInit(self):
-        self.declareProperty(FileProperty(name="Filename", defaultValue="", action=FileAction.Load, extensions=[".nxs.h5"]))
+        self.declareProperty(MultipleFileProperty(name="Filename", action=FileAction.OptionalLoad, extensions=[".nxs.h5"]), "Files to Load")
+        self.declareProperty('IPTS', Property.EMPTY_INT, "IPTS number to load from")
+        self.declareProperty(IntArrayProperty("RunNumbers", []), 'Run numbers to load')
         self.declareProperty("Wavelength", 1.488, doc="Wavelength to set the workspace")
         self.declareProperty("ApplyMask", True, "If True standard masking will be applied to the workspace")
         self.declareProperty(WorkspaceProperty(name="OutputWorkspace", defaultValue="", direction=Direction.Output))
 
+    def validateInputs(self):
+        issues = dict()
+
+        if not self.getProperty("Filename").value:
+            if (self.getProperty("IPTS").value == Property.EMPTY_INT) or len(self.getProperty("RunNumbers").value) is 0:
+                issues["Filename"] = 'Must specify either Filename or IPTS AND RunNumbers'
+
+        return issues
+
     def PyExec(self):
-        filename = self.getProperty("Filename").value
+        runs = self.getProperty("Filename").value
+
+        if not runs:
+            ipts = self.getProperty("IPTS").value
+            runs = ['/HFIR/HB2C/IPTS-{}/nexus/HB2C_{}.nxs.h5'.format(ipts, run) for run in self.getProperty("RunNumbers").value]
+
         wavelength = self.getProperty("wavelength").value
         outWS = self.getPropertyValue("OutputWorkspace")
+        group_names = []
 
-        LoadEventNexus(Filename=filename, OutputWorkspace=outWS, LoadMonitors=True, EnableLogging=False)
-        Integration(InputWorkspace=outWS, OutputWorkspace=outWS, EnableLogging=False)
+        for run in runs:
+            LoadEventNexus(Filename=run, OutputWorkspace='__tmp_load', LoadMonitors=True, EnableLogging=False)
+            Integration(InputWorkspace='__tmp_load', OutputWorkspace='__tmp_load', EnableLogging=False)
 
-        if self.getProperty("ApplyMask").value:
-            MaskBTP(outWS, Pixel='1,2,511,512', EnableLogging=False)
-            if mtd[outWS].getRunNumber() > 26600: # They changed pixel mapping and bank name order here
-                MaskBTP(outWS, Bank='1', Tube='479-480', EnableLogging=False)
-                MaskBTP(outWS, Bank='8', Tube='1-2', EnableLogging=False)
-            else:
-                MaskBTP(outWS, Bank='8', Tube='475-480', EnableLogging=False)
+            if self.getProperty("ApplyMask").value:
+                MaskBTP('__tmp_load', Pixel='1,2,511,512', EnableLogging=False)
+                if mtd['__tmp_load'].getRunNumber() > 26600: # They changed pixel mapping and bank name order here
+                    MaskBTP('__tmp_load', Bank='1', Tube='479-480', EnableLogging=False)
+                    MaskBTP('__tmp_load', Bank='8', Tube='1-2', EnableLogging=False)
+                else:
+                    MaskBTP('__tmp_load', Bank='8', Tube='475-480', EnableLogging=False)
 
-        mtd[outWS].getAxis(0).setUnit("Wavelength")
-        w = [wavelength-0.001, wavelength+0.001]
-        for idx in range(mtd[outWS].getNumberHistograms()):
-            mtd[outWS].setX(idx, w)
+            mtd['__tmp_load'].getAxis(0).setUnit("Wavelength")
+            w = [wavelength-0.001, wavelength+0.001]
+            for idx in range(mtd['__tmp_load'].getNumberHistograms()):
+                mtd['__tmp_load'].setX(idx, w)
 
-        SetGoniometer(outWS, Axis0="HB2C:Mot:s1,0,1,0,1", EnableLogging=False)
-        AddSampleLog(outWS, LogName="gd_prtn_chrg", LogType='Number', NumberType='Double',
-                     LogText=str(mtd[outWS+'_monitors'].getNumberEvents()), EnableLogging=False)
-        DeleteWorkspace(outWS+'_monitors', EnableLogging=False)
+            SetGoniometer('__tmp_load', Axis0="HB2C:Mot:s1,0,1,0,1", EnableLogging=False)
+            AddSampleLog('__tmp_load', LogName="gd_prtn_chrg", LogType='Number', NumberType='Double',
+                         LogText=str(mtd['__tmp_load'+'_monitors'].getNumberEvents()), EnableLogging=False)
+            DeleteWorkspace('__tmp_load'+'_monitors', EnableLogging=False)
+
+            AddSampleLog('__tmp_load', LogName="Wavelength", LogType='Number', NumberType='Double',
+                         LogText=str(wavelength), EnableLogging=False)
+            AddSampleLog('__tmp_load', LogName="Ei", LogType='Number', NumberType='Double',
+                         LogText=str(UnitConversion.run('Wavelength', 'Energy', wavelength, 0, 0, 0, Elastic, 0)), EnableLogging=False)
+            if len(runs) == 1:
+                RenameWorkspace('__tmp_load', outWS, EnableLogging=False)
+            else:
+                outName = outWS+"_"+str(mtd['__tmp_load'].getRunNumber())
+                group_names.append(outName)
+                RenameWorkspace('__tmp_load', outName, EnableLogging=False)
 
-        AddSampleLog(outWS, LogName="Wavelength", LogType='Number', NumberType='Double', LogText=str(wavelength), EnableLogging=False)
-        AddSampleLog(outWS, LogName="Ei", LogType='Number', NumberType='Double',
-                     LogText=str(UnitConversion.run('Wavelength', 'Energy', wavelength, 0, 0, 0, Elastic, 0)), EnableLogging=False)
+        if len(runs) > 1:
+            GroupWorkspaces(group_names, OutputWorkspace=outWS, EnableLogging=False)
 
         self.setProperty('OutputWorkspace', outWS)
 
diff --git a/docs/source/algorithms/LoadWAND-v1.rst b/docs/source/algorithms/LoadWAND-v1.rst
index 4fe9bb3c3f5..e42fefb113a 100644
--- a/docs/source/algorithms/LoadWAND-v1.rst
+++ b/docs/source/algorithms/LoadWAND-v1.rst
@@ -20,11 +20,18 @@ last 6 columns for run numbers up to 26600 or the first and last 2
 columns for larger run numbers.
 
 After this algorithm loads the workspace it can be correctly converted
-to Q sample or HKL using :ref:`algm-ConvertToMD`.
+to Q sample or HKL using :ref:`algm-ConvertToMD`. If it's a powder
+sample it can be reduced with :ref:`algm-WANDPowderReduction`.
 
 If you need to do event filtering don't use this algorithm, simply use
 :ref:`algm-LoadEventNexus` and convert to data manually.
 
+You can specify multiple files in the filename property or set the
+IPTS and RunNumbers, where RunNumbers can be a range or list of
+numbers, see Usage example bellow. If multiple files are loaded they
+will be named 'OutputWorkspace'+'_runnumber' and be grouped in
+'OutputWorkspace'.
+
 Usage
 -----
 
@@ -32,16 +39,51 @@ Usage
 
 .. code-block:: python
 
-    ws = LoadWAND('HB2C_7000.nxs.h5')
-    print("ws has {0} spectrum and {1} point in units {2}".format(ws.getNumberHistograms(),
-                                                                  ws.blocksize(),
-                                                                  ws.getXDimension().name))
+    silicon = LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26506.nxs.h5')
+    print("Workspace has {0} spectrum and {1} point in units {2}".format(silicon.getNumberHistograms(),
+                                                                         silicon.blocksize(),
+                                                                         silicon.getXDimension().name))
+
+Output:
+
+.. code-block:: none
+
+    Workspace has 1966080 spectrum and 1 point in units Wavelength
+
+**Load using Multiple file**
+
+.. code-block:: python
+
+    silicon = LoadWAND('/HFIR/HB2C/IPTS-7776/nexus/HB2C_26506.nxs.h5,/HFIR/HB2C/IPTS-7776/nexus/HB2C_26507.nxs.h5')
+    print("Workspace group {0} has {1} workspaces {2} and {3}".format(silicon.name(),
+                                                                      silicon.getNumberOfEntries(),
+                                                                      silicon.getNames()[0],
+                                                                      silicon.getNames()[1]))
+
+Output:
+
+.. code-block:: none
+
+    Workspace group silicon has 2 workspaces silicon_26506 and silicon_26507
+
+**Load using IPTS and run numbers**
+
+.. code-block:: python
+
+    # Comma-separated list
+    silicon = LoadWAND(IPTS=7776,RunNumbers='26506,26507')
+    # or range
+    silicon = LoadWAND(IPTS=7776,RunNumbers='26506-26507')
+    print("Workspace group {0} has {1} workspaces {2} and {3}".format(silicon.name(),
+                                                                      silicon.getNumberOfEntries(),
+                                                                      silicon.getNames()[0],
+                                                                      silicon.getNames()[1]))
 
 Output:
 
 .. code-block:: none
 
-    ws has 1966080 spectrum and 1 point in units Wavelength
+    Workspace group silicon has 2 workspaces silicon_26506 and silicon_26507
 
 .. categories::
 
-- 
GitLab