diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py new file mode 100644 index 000000000000..c459a31bbb98 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateMD.py @@ -0,0 +1,111 @@ +#pylint: disable=invalid-name,no-init +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * +import numpy as np +import __builtin__ + + +class CreateMD(DataProcessorAlgorithm): + + def __possible_emodes(self): + return ['Elastic', 'Direct', 'Indirect'] + + def __single_gen_sqw(self, input_workspace, emode, alatt=[], angdeg=[], u=[], v=[], psi=None, gl=None, gs=None): + import numpy as np + ub_params = [any(alatt), any(angdeg), any(u), any(v)] + goniometer_params = [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): + SetUB(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) + if any(goniometer_params) and not all(goniometer_params): + raise ValueError("Either specify all of psi, gl, gs or none of them") + elif all(goniometer_params): + if input_workspace.sample().hasOrientedLattice(): + self.g_log.warning("Goniometer has already been set. It will not be overwritten by %s ", self.name()) + else: + AddSampleLog(Workspace=input_workspace, LogName='gl', LogText=gl, LogType='Number') + AddSampleLog(Workspace=input_workspace, LogName='gs', LogText=gs, LogType='Number') + AddSampleLog(Workspace=input_workspace, LogName='psi', LogText=psi, LogType='Number') + + axis0 = 'gl' + ','.join(map(str, [0,0,1])) + axis1 = 'gs' + ','.join(map(str, [1,0,0])) + axis2 = 'psi' + ','.join(map(str, [0,1,0])) + + SetGoniometer(Workspace=input_workspace, Axis0=axis0, Axis1=axis1, Axis2=axis2) + + min_extents, max_extents = ConvertToMDMinMaxLocal(InputWorkspace=input_workspace,QDimensions='Q3D',dEAnalysisMode=emode) + output_workspace = ConvertToMD(InputWorkspace=input_workspace, QDimensions='Q3D', QConversionScales='HKL',dEAnalysisMode=emode, MinValues=min_extents, MaxValues=max_extents) + return output_workspace + + def category(self): + return 'MDAlgorithms' + + def summary(self): + return 'Creates a mutlidimensional workspace by transforming and combining individual runs.' + + def PyInit(self): + self.declareProperty(StringArrayProperty('InputWorkspaces', values=[], direction=Direction.Input, validator=StringArrayMandatoryValidator()), + doc='Matrix workspace to slice') + + self.declareProperty('Emode', defaultValue='Direct', validator=StringListValidator(self.__possible_emodes()), direction=Direction.Input, doc='Analysis mode ' + str(self.__possible_emodes()) ) + + self.declareProperty(FloatArrayProperty('Alatt', values=[], validator=FloatArrayMandatoryValidator(), direction=Direction.Input ), doc='Lattice parameters' ) + + self.declareProperty(FloatArrayProperty('Angdeg', values=[], validator=FloatArrayMandatoryValidator(), direction=Direction.Input ), doc='Lattice angles' ) + + self.declareProperty(FloatArrayProperty('u', values=[], validator=FloatArrayMandatoryValidator(), direction=Direction.Input ), doc='Lattice vector parallel to neutron beam' ) + + 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('gl', defaultValue=0.0, direction=Direction.Input, doc='gl rotation in degrees' ) + + self.declareProperty('gs', defaultValue=0.0, direction=Direction.Input, doc='gs rotation in degrees' ) + + 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())) + + 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 + if len(input_workspaces) < 1: + raise ValueError("Need one or more input workspace") + + + + if not emode in self.__possible_emodes(): + raise ValueError("Unknown emode %s Allowed values are %s" % (emode, self.__possible_emodes())) + + output_workspaces = list() + for ws in input_workspaces: + out_ws = self.__single_gen_sqw(input_workspace=ws, emode=emode, alatt=alatt, angdeg=angdeg, u=u, v=v, psi=psi, gl=gl, gs=gs) + output_workspaces.append(out_ws) + # TODO. Need to merge runs. + + if len(input_workspaces) > 1: + raise RuntimeError("Merging not implmented yet") + # TODO We will need to merge everything + # TODO We should offer to merge file-backed + + self.setProperty("OutputWorkspace", output_workspaces[0]) + + + + + + + +AlgorithmFactory.subscribe(CreateMD) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt index 0c6113c925d9..8b459c06619d 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt @@ -11,6 +11,7 @@ set ( TEST_PY_FILES AxisTest.py CatalogManagerTest.py CutMDTest.py + CreateMDTest.py DataProcessorAlgorithmTest.py DeprecatedAlgorithmCheckerTest.py ExperimentInfoTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py new file mode 100644 index 000000000000..76f79668705b --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CreateMDTest.py @@ -0,0 +1,70 @@ +import unittest +import testhelpers +import numpy as np +from mantid.simpleapi import * +from mantid.api import AlgorithmManager, IMDHistoWorkspace, IMDEventWorkspace + + +class CreateMDTest(unittest.TestCase): + + + def setUp(self): + pass + + def tearDown(self): + pass + #DeleteWorkspace(self.__in_md ) + + def test_init(self): + alg = AlgorithmManager.create("CreateMD") + alg.initialize() + + def test_must_have_more_than_one_input_workspace(self): + alg = AlgorithmManager.create("CreateMD") + alg.setRethrows(True) + alg.initialize() + self.assertRaises(ValueError, alg.setProperty, "InputWorkspaces", []) + + def test_set_up_madatory(self): + + alg = AlgorithmManager.create("CreateMD") + alg.setRethrows(True) + alg.initialize() + alg.setPropertyValue("OutputWorkspace", "mdworkspace") + alg.setProperty("InputWorkspaces", ['a', 'b']) + 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]) + + def test_execute_single_workspace(self): + input_workspace = CreateSampleWorkspace() + AddSampleLog(input_workspace, LogName='Ei', LogText='12.0', LogType='Number') + + alg = AlgorithmManager.create("CreateMD") + alg.setRethrows(True) + alg.setChild(True) + alg.initialize() + alg.setPropertyValue("OutputWorkspace", "mdworkspace") + alg.setProperty("InputWorkspaces", ['input_workspace']) + 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.execute() + out_ws = alg.getProperty("OutputWorkspace").value + + self.assertTrue(isinstance(out_ws, IMDEventWorkspace), "Expected an MDEventWorkspace back") + + + + + + + + + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file