From 3eb662f8212f23a94dc932c0a30dc8fa67684b42 Mon Sep 17 00:00:00 2001
From: Owen Arnold <owen.arnold@stfc.ac.uk>
Date: Wed, 1 Apr 2015 09:39:52 +0100
Subject: [PATCH] refs #11304. Set goniometer angles from arrays.

---
 .../algorithms/WorkflowAlgorithms/CreateMD.py | 85 +++++++++++++++----
 .../test/python/mantid/api/CreateMDTest.py    | 64 ++++++++++++++
 2 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py
index 7a63ebdb42f..a94380fe831 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py
@@ -79,12 +79,12 @@ class CreateMD(DataProcessorAlgorithm):
     def _single_run(self, input_workspace, emode,  psi, gl, gs, alatt=None, angdeg=None, u=None, v=None,):
         import numpy as np
         ub_params = map(any, [alatt, angdeg, u, v])
-        goniometer_params = map(lambda x : x != 0.0, [psi, gl, gs])
+        goniometer_params = map(lambda x : x != None, [psi, gl, gs])
         if any(ub_params) and not all(ub_params):
             raise ValueError("Either specify all of alatt, angledeg, u, v or none of them")
         elif all(ub_params):
             if input_workspace.sample().hasOrientedLattice():
-                self.g_log.warning("Sample already has a UB. This will not be overwritten by %s. Use ClearUB.", self.name())
+                self.g_log.warning("Sample already has a UB. This will not be overwritten by %s. Use ClearUB and re-run.", self.name())
             else:
                 self._set_ub(workspace=input_workspace, a=alatt[0], b=alatt[1], c=alatt[2], alpha=angdeg[0], beta=angdeg[1], gamma=angdeg[2], u=u, v=v)
 
@@ -117,42 +117,95 @@ class CreateMD(DataProcessorAlgorithm):
 
         self.declareProperty(FloatArrayProperty('v', values=[], validator=FloatArrayMandatoryValidator(), direction=Direction.Input ), doc='Lattice vector perpendicular to neutron beam in the horizontal plane' )
 
-        self.declareProperty('Psi', defaultValue=0.0, direction=Direction.Input, doc='Psi rotation in degrees' )
+        self.declareProperty(FloatArrayProperty('Psi', values=[], direction=Direction.Input), doc='Psi rotation in degrees. Optional or one entry per run.' )
 
-        self.declareProperty('Gl', defaultValue=0.0, direction=Direction.Input, doc='gl rotation in degrees' )
+        self.declareProperty(FloatArrayProperty('Gl', values=[], direction=Direction.Input), doc='gl rotation in degrees. Optional or one entry per run.' )
 
-        self.declareProperty('Gs', defaultValue=0.0, direction=Direction.Input, doc='gs rotation in degrees' )
+        self.declareProperty(FloatArrayProperty('Gs', values=[], direction=Direction.Input), doc='gs rotation in degrees. Optional or one entry per run.' )
 
         self.declareProperty(IMDWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output ), doc='Output MDWorkspace')
 
-    def PyExec(self):
-
-        logger.warning('You are running algorithm %s that is the beta stage of development' % (self.name()))
-
+    def _validate_inputs(self):
+    
         emode = self.getProperty('Emode').value
         alatt = self.getProperty('Alatt').value
         angdeg = self.getProperty('Angdeg').value
         u = self.getProperty('u').value
         v = self.getProperty('v').value
-        psi = self.getProperty('psi').value
-        gl = self.getProperty('gl').value
-        gs = self.getProperty('gs').value 
+        psi = self.getProperty('Psi').value
+        gl = self.getProperty('Gl').value
+        gs = self.getProperty('Gs').value        
 
         input_workspaces = self.getProperty("InputWorkspaces").value
-        if len(input_workspaces) < 1:
+        
+        ws_entries = len(input_workspaces)
+        
+        if ws_entries < 1:
             raise ValueError("Need one or more input workspace")
+            
+        if len(u) != 3:
+            raise ValueError("u must have 3 components")
+            
+        if len(v) != 3:
+            raise ValueError("v must have 3 components")
+            
+        if len(alatt) != 3:
+            raise ValueError("lattice parameters must have 3 components")
+            
+        if len(angdeg) != 3:
+            raise ValueError("Angle must have 3 components")
 
         if not emode in self._possible_emodes():
             raise ValueError("Unknown emode %s Allowed values are %s" % (emode, self._possible_emodes()))
+            
+        if len(psi) > 0 and len(psi) != ws_entries:
+            raise ValueError("If Psi is given a entry should be provided for every input workspace")
+        
+        if len(gl) > 0 and len(gl) != ws_entries:
+            raise ValueError("If Gl is given a entry should be provided for every input workspace")
+            
+        if len(gs) > 0 and len(gs) != ws_entries:
+            raise ValueError("If Gs is given a entry should be provided for every input workspace")
+         
+            
+    def PyExec(self):
+
+        logger.warning('You are running algorithm %s that is the beta stage of development' % (self.name()))
+
+        emode = self.getProperty('Emode').value
+        alatt = self.getProperty('Alatt').value
+        angdeg = self.getProperty('Angdeg').value
+        u = self.getProperty('u').value
+        v = self.getProperty('v').value
+        psi = self.getProperty('Psi').value
+        gl = self.getProperty('Gl').value
+        gs = self.getProperty('Gs').value        
+
+        input_workspaces = self.getProperty("InputWorkspaces").value
+        
+        ws_entries = len(input_workspaces)
+        
+        self._validate_inputs()
+            
+        if not psi:
+            psi = [None] * ws_entries
+            
+        if not gl:
+            gl = [None] * ws_entries
+            
+        if not gs:
+            gs = [None] * ws_entries
     
         output_workspace = None
         run_md = None
 
         to_merge_names = list()
-        for ws_name in input_workspaces:
-
+        
+        run_data = zip(input_workspaces, psi, gl, gs)
+        for run_entry in run_data:
+                ws_name, psi_entry, gl_entry, gs_entry = run_entry
                 ws = AnalysisDataService.retrieve(ws_name)
-                run_md = self._single_run(input_workspace=ws, emode=emode, alatt=alatt, angdeg=angdeg, u=u, v=v, psi=psi, gl=gl, gs=gs)
+                run_md = self._single_run(input_workspace=ws, emode=emode, alatt=alatt, angdeg=angdeg, u=u, v=v, psi=psi_entry, gl=gl_entry, gs=gs_entry)
                 to_merge_name = ws_name + "_md"
                 AnalysisDataService.addOrReplace(to_merge_name, run_md)
                 to_merge_names.append(to_merge_name)
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py
index 9206d21d5b8..956a403cbc2 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py
@@ -29,6 +29,70 @@ class CreateMDTest(unittest.TestCase):
         alg.setProperty("Angdeg", [90,90,90])
         alg.setProperty("u", [0,0,1])
         alg.setProperty("v", [1,0,0])
+        
+    def test_psi_right_size(self):
+    
+        input_workspace = CreateSampleWorkspace(NumBanks=1, BinWidth=2000)
+        AddSampleLog(input_workspace, LogName='Ei', LogText='12.0', LogType='Number')
+        
+        alg = AlgorithmManager.create("CreateMD")
+        alg.setRethrows(True)
+        alg.initialize()
+        alg.setPropertyValue("OutputWorkspace", "mdworkspace")
+        alg.setProperty("InputWorkspaces", ['input_workspace'])
+        alg.setProperty("Emode", "Direct")
+        alg.setProperty("Alatt", [1,1,1])
+        alg.setProperty("Angdeg", [90,90,90])
+        alg.setProperty("u", [0,0,1])
+        alg.setProperty("v", [1,0,0])
+        alg.setProperty("Psi", [0, 0, 0]) # Too large
+        alg.setProperty("Gl", [0]) # Right size
+        alg.setProperty("Gs", [0]) # Right size
+        self.assertRaises(RuntimeError, alg.execute)
+        DeleteWorkspace(input_workspace)
+        
+    def test_gl_right_size(self):
+    
+        input_workspace = CreateSampleWorkspace(NumBanks=1, BinWidth=2000)
+        AddSampleLog(input_workspace, LogName='Ei', LogText='12.0', LogType='Number')
+        
+        alg = AlgorithmManager.create("CreateMD")
+        alg.setRethrows(True)
+        alg.initialize()
+        alg.setPropertyValue("OutputWorkspace", "mdworkspace")
+        alg.setProperty("InputWorkspaces", ['input_workspace'])
+        alg.setProperty("Emode", "Direct")
+        alg.setProperty("Alatt", [1,1,1])
+        alg.setProperty("Angdeg", [90,90,90])
+        alg.setProperty("u", [0,0,1])
+        alg.setProperty("v", [1,0,0])
+        alg.setProperty("Psi", [0]) # Right size
+        alg.setProperty("Gl", [0, 0]) # Too many
+        alg.setProperty("Gs", [0]) # Right size
+        self.assertRaises(RuntimeError, alg.execute)
+        DeleteWorkspace(input_workspace)
+        
+    def test_gs_right_size(self):
+    
+        input_workspace = CreateSampleWorkspace(NumBanks=1, BinWidth=2000)
+        AddSampleLog(input_workspace, LogName='Ei', LogText='12.0', LogType='Number')
+        
+        alg = AlgorithmManager.create("CreateMD")
+        alg.setRethrows(True)
+        alg.initialize()
+        alg.setPropertyValue("OutputWorkspace", "mdworkspace")
+        alg.setProperty("InputWorkspaces", ['input_workspace'])
+        alg.setProperty("Emode", "Direct")
+        alg.setProperty("Alatt", [1,1,1])
+        alg.setProperty("Angdeg", [90,90,90])
+        alg.setProperty("u", [0,0,1])
+        alg.setProperty("v", [1,0,0])
+        alg.setProperty("Psi", [0]) # Right size
+        alg.setProperty("Gl", [0]) # Right size
+        alg.setProperty("Gs", [0,0]) # Too large
+        self.assertRaises(RuntimeError, alg.execute)
+        DeleteWorkspace(input_workspace)
+        
 
     def test_execute_single_workspace(self):
         
-- 
GitLab