Skip to content
Snippets Groups Projects
Commit 3339c377 authored by Owen Arnold's avatar Owen Arnold
Browse files

Merge pull request #437 from mantidproject/11354_horace_style_for_cutmd

Horace style for cutmd
parents 027648d2 cc9e0ac7
No related branches found
No related tags found
No related merge requests found
......@@ -20,6 +20,7 @@
"""
from __future__ import absolute_import
import os, string
import mantid.api as _api
import mantid.kernel as _kernel
......@@ -31,7 +32,7 @@ from mantid.api._aliases import *
#------------------------ Specialized function calls --------------------------
# List of specialized algorithms
__SPECIALIZED_FUNCTIONS__ = ["Load", "Fit"]
__SPECIALIZED_FUNCTIONS__ = ["Load", "Fit", "CutMD"]
# List of specialized algorithms
__MDCOORD_FUNCTIONS__ = ["PeakIntensityVsRadius", "CentroidPeaksMD","IntegratePeaksMD"]
# The "magic" keyword to enable/disable logging
......@@ -257,22 +258,124 @@ def FitDialog(*args, **kwargs):
#--------------------------------------------------- --------------------------
#This dictionary maps algorithm names to functions that preprocess their inputs
#in the simpleapi. The functions take args and kwargs as regular arguments and
#modify them as required.
def CutMD(*args, **kwargs):
"""
Slices multidimensional workspaces using input projection information and binning limits.
"""
(in_wss,) = _get_mandatory_args('CutMD', ["InputWorkspace"], *args, **kwargs)
# If the input isn't a list, wrap it in one so we can iterate easily
if isinstance(in_wss, list):
in_list = in_wss
handling_multiple_workspaces = True
else:
in_list = [in_wss]
handling_multiple_workspaces = False
# Remove from keywords so it is not set twice
if "InputWorkspace" in kwargs:
del kwargs['InputWorkspace']
#Make sure we were given some output workspace names
lhs = _kernel.funcreturns.lhs_info()
if lhs[0] == 0 and 'OutputWorkspace' not in kwargs:
raise RuntimeError("Unable to set output workspace name. Please either assign the output of "
"CutMD to a variable or use the OutputWorkspace keyword.")
#Take what we were given
if "OutputWorkspace" in kwargs:
out_names = kwargs["OutputWorkspace"]
else:
out_names = list(lhs[1])
#Ensure the output names we were given are valid
if handling_multiple_workspaces:
if not isinstance(out_names, list):
raise RuntimeError("Multiple OutputWorkspaces must be given as a list when processing multiple InputWorkspaces.")
else:
#We wrap in a list for our convenience. The user musn't pass us one though.
if not isinstance(out_names, list):
out_names = [out_names]
elif len(out_names) != 1:
raise RuntimeError("Only one OutputWorkspace required")
if len(out_names) != len(in_list):
raise RuntimeError("Different number of input and output workspaces given.")
# Split PBins up into P1Bin, P2Bin, etc.
if "PBins" in kwargs:
bins = kwargs["PBins"]
del kwargs["PBins"]
if isinstance(bins, tuple) or isinstance(bins, list):
for bin in range(len(bins)):
kwargs["P{0}Bin".format(bin+1)] = bins[bin]
# Create and execute
algm = _create_algorithm_object('CutMD')
_set_logging_option(algm, kwargs)
_algorithm_preprocessors = dict()
# Now check that all the kwargs we've got are correct
for key in kwargs.keys():
if key not in algm:
raise RuntimeError("Unknown property: {0}".format(key))
# We're now going to build to_process, which is the list of workspaces we want to process.
to_process = list()
for i in range(len(in_list)):
ws = in_list[i]
if isinstance(ws, _api.Workspace):
#It's a workspace, do nothing to it
to_process.append(ws)
elif isinstance(ws, str):
if ws in mtd:
#It's a name of something in the ads, just take it from the ads
to_process.append(_api.AnalysisDataService[ws])
else:
#Let's try treating it as a filename
load_alg = AlgorithmManager.create("Load")
load_alg.setLogging(True)
load_alg.setAlwaysStoreInADS(False)
load_alg.setProperty("Filename", ws)
load_alg.setProperty("OutputWorkspace", "__loaded_by_cutmd_{0}".format(i+1))
load_alg.execute()
if not load_alg.isExecuted():
raise TypeError("Failed to load " + ws)
wsn = load_alg.getProperty("OutputWorkspace").valueAsStr
to_process.append(_api.AnalysisDataService[wsn])
else:
raise TypeError("Unexpected type: " + type(ws))
#Run the algorithm across the inputs and outputs
for i in range(len(to_process)):
_set_properties(algm, **kwargs)
algm.setProperty('InputWorkspace', to_process[i])
algm.setProperty('OutputWorkspace', out_names[i])
algm.execute()
def _pp_cutmd(args, kwargs):
if "PBins" in kwargs:
bins = kwargs["PBins"]
del kwargs["PBins"]
if isinstance(bins, tuple) or isinstance(bins, list):
#PBin has been provided, we need to split it out into P1Bin, P2Bin, etc.
for bin in range(len(bins)):
kwargs["P{0}Bin".format(bin+1)] = bins[bin]
#Get the workspace objects so we can return them
for i in range(len(out_names)):
out_names[i] = _api.AnalysisDataService[out_names[i]]
_algorithm_preprocessors["CutMD"] = _pp_cutmd
#We should only return a list if we're handling multiple workspaces
if handling_multiple_workspaces:
return out_names
else:
return out_names[0]
# Have a better load signature for autocomplete
_signature = "\bInputWorkspace"
# Getting the code object for Load
_f = CutMD.func_code
# Creating a new code object nearly identical, but with the two variable names replaced
# by the property list.
_c = _f.__new__(_f.__class__, _f.co_argcount, _f.co_nlocals, _f.co_stacksize, _f.co_flags, _f.co_code, _f.co_consts, _f.co_names,\
(_signature, "kwargs"), _f.co_filename, _f.co_name, _f.co_firstlineno, _f.co_lnotab, _f.co_freevars)
# Replace the code object of the wrapper function
CutMD.func_code = _c
#--------------------------------------------------- --------------------------
def _get_function_spec(func):
"""Get the python function signature for the given function object
......@@ -568,10 +671,6 @@ def _create_algorithm_function(algorithm, version, _algm_object):
the proper version of the algorithm without failing.
"""
# If needed, preprocess this algorithm's input
if algorithm in _algorithm_preprocessors:
_algorithm_preprocessors[algorithm](args, kwargs)
_version = version
if "Version" in kwargs:
_version = kwargs["Version"]
......
......@@ -9,11 +9,20 @@
Description
-----------
This algorithm performs slicing of multiDimensional data according to a chosen projection, and binning choice. The algorithm uses :ref:`algm-BinMD` or
:ref:`algm-SliceMD` to achieve the binning of the data. The choice of child algorithm used for the slicing is controlled by the NoPix option.
This algorithm performs slicing of multiDimensional data according to a chosen
projection, and binning choice. The algorithm uses :ref:`algm-BinMD` or
:ref:`algm-SliceMD` to achieve the binning of the data. The choice of child
algorithm used for the slicing is controlled by the NoPix option.
The synax is similar to that used by `Horace <http://horace.isis.rl.ac.uk/Manipulating_and_extracting_data_from_SQW_files_and_objects#cut_sqw>`__.
Unlike most Mantid algorithms, CutMD can accept a list of workspaces as the
input workspace, given as the name of a workspace in the analysis data service
or the path to a workspace, or simply a workspace object in python. These will
all then be processed sequentially with the same options. The only requirement
is that the same number of output workspaces are also given so that CutMD knows
what to call each output workspace created.
Usage
-----
......@@ -39,6 +48,10 @@ Usage
# Apply the cut (PBins property sets the P1Bin, P2Bin, etc. properties for you)
out_md = CutMD(to_cut, Projection=proj_ws, PBins=([0.1], [0.1], [0.1], [-5,5]), NoPix=True)
#Another way we can call CutMD:
#[out1, out2, out3] = CutMD([to_cut, "some_other_file.nxs", "some_workspace_name"], ...)
print 'number of dimensions', out_md.getNumDims()
print 'number of dimensions not integrated', len(out_md.getNonIntegratedDimensions())
dim_dE = out_md.getDimension(3)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment