Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/8951_stitch_groups'
Browse files Browse the repository at this point in the history
  • Loading branch information
gesnerpassos committed Feb 14, 2014
2 parents 5742a90 + c8a3932 commit 6b64122
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,34 @@ def has_non_zero_errors(self, ws):
count = len(errors.nonzero()[0])
return count > 0


def __run_as_child(self, name, **kwargs):
"""Run a named algorithm and return the
algorithm handle
Parameters:
name - The name of the algorithm
kwargs - A dictionary of property name:value pairs
"""
alg = AlgorithmManager.createUnmanaged(name)
alg.initialize()
alg.setChild(True)

if 'OutputWorkspace' in alg:
alg.setPropertyValue("OutputWorkspace","UNUSED_NAME_FOR_CHILD")

alg.setRethrows(True)
for key, value in kwargs.iteritems():
alg.setProperty(key, value)

alg.execute()
return alg.getProperty("OutputWorkspace").value

def __to_single_value_ws(self, value):
value_ws = self.__run_as_child("CreateSingleValuedWorkspace", DataValue=value)
return value_ws


def __find_indexes_start_end(self, startOverlap, endOverlap, workspace):
a1=workspace.binIndexOf(startOverlap)
a2=workspace.binIndexOf(endOverlap)
Expand Down Expand Up @@ -104,8 +132,8 @@ def PyExec(self):

params = self.__create_rebin_parameters()
print params
lhs_rebinned = Rebin(InputWorkspace=self.getProperty("LHSWorkspace").value, Params=params)
rhs_rebinned = Rebin(InputWorkspace=self.getProperty("RHSWorkspace").value, Params=params)
lhs_rebinned = self.__run_as_child("Rebin", InputWorkspace=self.getProperty("LHSWorkspace").value, Params=params)
rhs_rebinned = self.__run_as_child("Rebin", InputWorkspace=self.getProperty("RHSWorkspace").value, Params=params)

xRange = lhs_rebinned.readX(0)
minX = xRange[0]
Expand All @@ -121,56 +149,58 @@ def PyExec(self):
a1, a2 = self.__find_indexes_start_end(startOverlap, endOverlap, lhs_rebinned)

if not useManualScaleFactor:
lhsOverlapIntegrated = Integration(InputWorkspace=lhs_rebinned, RangeLower=startOverlap, RangeUpper=endOverlap)
rhsOverlapIntegrated = Integration(InputWorkspace=rhs_rebinned, RangeLower=startOverlap, RangeUpper=endOverlap)

lhsOverlapIntegrated = self.__run_as_child("Integration", InputWorkspace=lhs_rebinned, RangeLower=startOverlap, RangeUpper=endOverlap)
rhsOverlapIntegrated = self.__run_as_child("Integration", InputWorkspace=rhs_rebinned, RangeLower=startOverlap, RangeUpper=endOverlap)

y1=lhsOverlapIntegrated.readY(0)
y2=rhsOverlapIntegrated.readY(0)
if scaleRHSWorkspace:
rhs_rebinned *= (lhsOverlapIntegrated/rhsOverlapIntegrated)
ratio = self.__run_as_child("Divide", LHSWorkspace=lhsOverlapIntegrated, RHSWorkspace=rhsOverlapIntegrated)
rhs_rebinned = self.__run_as_child("Multiply", LHSWorkspace=rhs_rebinned, RHSWorkspace=ratio)
scalefactor = y1[0]/y2[0]
else:
lhs_rebinned *= (rhsOverlapIntegrated/lhsOverlapIntegrated)

ratio = self.__run_as_child("Divide", RHSWorkspace=lhsOverlapIntegrated, LHSWorkspace=rhsOverlapIntegrated)
lhs_rebinned = self.__run_as_child("Multiply", LHSWorkspace=lhs_rebinned, RHSWorkspace=ratio)
scalefactor = y2[0]/y1[0]
DeleteWorkspace(lhsOverlapIntegrated)
DeleteWorkspace(rhsOverlapIntegrated)
else:
manualScaleFactorWS = self.__to_single_value_ws(manualScaleFactor)
if scaleRHSWorkspace:
rhs_rebinned *= manualScaleFactor
rhs_rebinned = self.__run_as_child("Multiply", LHSWorkspace=rhs_rebinned, RHSWorkspace=manualScaleFactorWS)
else:
lhs_rebinned *= manualScaleFactor
lhs_rebinned = self.__run_as_child("Multiply", LHSWorkspace=lhs_rebinned, RHSWorkspace=manualScaleFactorWS)
scalefactor = manualScaleFactor

# Mask out everything BUT the overlap region as a new workspace.
overlap1 = MultiplyRange(InputWorkspace=lhs_rebinned, StartBin=0,EndBin=a1,Factor=0)
overlap1 = MultiplyRange(InputWorkspace=overlap1,StartBin=a2,Factor=0)
overlap1 = self.__run_as_child("MultiplyRange", InputWorkspace=lhs_rebinned, StartBin=0,EndBin=a1,Factor=0)
overlap1 = self.__run_as_child("MultiplyRange", InputWorkspace=overlap1,StartBin=a2,Factor=0)

# Mask out everything BUT the overlap region as a new workspace.
overlap2 = MultiplyRange(InputWorkspace=rhs_rebinned,StartBin=0,EndBin=a1,Factor=0)#-1
overlap2 = MultiplyRange(InputWorkspace=overlap2,StartBin=a2,Factor=0)
overlap2 = self.__run_as_child("MultiplyRange", InputWorkspace=rhs_rebinned,StartBin=0,EndBin=a1,Factor=0)
overlap2 = self.__run_as_child("MultiplyRange", InputWorkspace=overlap2,StartBin=a2,Factor=0)

# Mask out everything AFTER the start of the overlap region
lhs_rebinned=MultiplyRange(InputWorkspace=lhs_rebinned, StartBin=a1+1, Factor=0)
lhs_rebinned = self.__run_as_child("MultiplyRange", InputWorkspace=lhs_rebinned, StartBin=a1+1, Factor=0)

# Mask out everything BEFORE the end of the overlap region
rhs_rebinned=MultiplyRange(InputWorkspace=rhs_rebinned,StartBin=0,EndBin=a2-1,Factor=0)
rhs_rebinned = self.__run_as_child("MultiplyRange",InputWorkspace=rhs_rebinned,StartBin=0,EndBin=a2-1,Factor=0)

# Calculate a weighted mean for the overlap region
overlapave = None
if self.has_non_zero_errors(overlap1) and self.has_non_zero_errors(overlap2):
overlapave = WeightedMean(InputWorkspace1=overlap1,InputWorkspace2=overlap2)
overlapave = self.__run_as_child("WeightedMean", InputWorkspace1=overlap1,InputWorkspace2=overlap2)
else:
self.log().information("Using un-weighted mean for Stitch1D overlap mean")
overlapave = (overlap1 + overlap2)/2
# Calculate the mean.
sum = self.__run_as_child("Plus", LHSWorkspace=overlap1, RHSWorkspace=overlap2)
denominator = self.__to_single_value_ws(2.0)
overlapave = self.__run_as_child("Divide", LHSWorkspace=sum, RHSWorkspace=denominator)

# Add the Three masked workspaces together to create a complete x-range
result = lhs_rebinned + overlapave + rhs_rebinned
RenameWorkspace(InputWorkspace=result, OutputWorkspace=self.getPropertyValue("OutputWorkspace"))

# Cleanup
DeleteWorkspace(lhs_rebinned)
DeleteWorkspace(rhs_rebinned)
DeleteWorkspace(overlap1)
DeleteWorkspace(overlap2)
DeleteWorkspace(overlapave)
result = self.__run_as_child("Plus", LHSWorkspace=lhs_rebinned, RHSWorkspace=overlapave)
result = self.__run_as_child("Plus", LHSWorkspace=rhs_rebinned, RHSWorkspace=result)
#RenameWorkspace(InputWorkspace=result, OutputWorkspace=self.getPropertyValue("OutputWorkspace"))

self.setProperty('OutputWorkspace', result)
self.setProperty('OutScaleFactor', scalefactor)
Expand Down
125 changes: 105 additions & 20 deletions Code/Mantid/Framework/PythonInterface/plugins/algorithms/Stitch1DMany.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,31 @@ def category(self):
return "Reflectometry\\ISIS;PythonAlgorithms"

def name(self):
return "Stitch1D"
return "Stitch1D"

def PyInit(self):

input_validator = StringMandatoryValidator()

self.declareProperty(name="InputWorkspaces", defaultValue="", direction=Direction.Input, validator=input_validator, doc="Input workspaces")
self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output stitched workspace")
self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output stitched workspace")

self.declareProperty(FloatArrayProperty(name="StartOverlaps", values=[]), doc="Overlap in Q.")
self.declareProperty(FloatArrayProperty(name="EndOverlaps", values=[]), doc="End overlap in Q.")
self.declareProperty(FloatArrayProperty(name="Params", values=[0.1]), doc="Rebinning Parameters. See Rebin for format.")
self.declareProperty(FloatArrayProperty(name="Params", validator=FloatArrayMandatoryValidator()), doc="Rebinning Parameters. See Rebin for format.")
self.declareProperty(name="ScaleRHSWorkspace", defaultValue=True, doc="Scaling either with respect to workspace 1 or workspace 2.")
self.declareProperty(name="UseManualScaleFactor", defaultValue=False, doc="True to use a provided value for the scale factor.")
self.declareProperty(name="ManualScaleFactor", defaultValue=1.0, doc="Provided value for the scale factor.")
self.declareProperty(name="OutScaleFactor", defaultValue=-2.0, direction = Direction.Output, doc="The actual used value for the scaling factor.")

def __workspace_from_split_name(self, list_of_names, index):
return mtd[list_of_names[index].strip()]
return mtd[list_of_names[index].strip()]

def __workspaces_from_split_name(self, list_of_names):
workspaces = list()
for name in list_of_names:
workspaces.append(mtd[name.strip()])
return workspaces

'''
If the property value has been provided, use that. If default, then create an array of Nones so that Stitch1D can still be correctly looped over.
Expand All @@ -53,7 +59,47 @@ def __input_or_safe_default(self, property_name, n_entries):
property_value.append(None)
return property_value



def __do_stitch_workspace(self, lhs_ws, rhs_ws, start_overlap, end_overlap, params, scale_rhs_ws, use_manual_scale_factor, manual_scale_factor):
out_name = lhs_ws.name() + rhs_ws.name()

alg = self.createChildAlgorithm("Stitch1D")
alg.initialize()
alg.setProperty("LHSWorkspace", lhs_ws)
alg.setProperty("RHSWorkspace", rhs_ws)
if start_overlap:
alg.setProperty("StartOverlap", start_overlap)
if end_overlap:
alg.setProperty("EndOverlap", end_overlap)
alg.setProperty("Params", params)
alg.setProperty("ScaleRHSWorkspace", scale_rhs_ws)
alg.setProperty("UseManualScaleFactor", use_manual_scale_factor)
if manual_scale_factor:
alg.setProperty("ManualScaleFactor", manual_scale_factor)
alg.setProperty("OutputWorkspace", "from_sub_alg" + out_name)
alg.execute()
out_ws = alg.getProperty("OutputWorkspace").value
scale_factor = alg.getProperty("OutScaleFactor").value


#out_ws, scale_factor = Stitch1D(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, StartOverlap=start_overlap, EndOverlap=end_overlap,
# Params=params, ScaleRHSWorkspace=scale_rhs_ws, UseManualScaleFactor=use_manual_scale_factor, ManualScaleFactor=manual_scale_factor, OutputWorkspace=out_name)
return (out_ws, scale_factor)

def __check_workspaces_are_common(self, input_workspace_names):
workspaces = self.__workspaces_from_split_name(input_workspace_names)
exemplar = workspaces[0]
for i in range(1, len(workspaces)):
test_ws = workspaces[i]
if type(exemplar) != type(test_ws):
raise RuntimeError("Input Workspaces must all be of the same type.")
if isinstance(test_ws, WorkspaceGroup):
if test_ws.size() != exemplar.size():
raise RuntimeError("Group Workspaces as InputWorkspaces must have the same number of sub-workspaces.")

def __are_processing_groups(self, input_workspace_names):
test_ws = self.__workspace_from_split_name(input_workspace_names, 0)
return isinstance(test_ws, WorkspaceGroup)

def PyExec(self):

Expand All @@ -77,25 +123,64 @@ def PyExec(self):
raise ValueError("StartOverlaps and EndOverlaps are different lengths")
if not (len(startOverlaps) == (numberOfWorkspaces- 1)):
raise ValueError("Wrong number of StartOverlaps, should be %i not %i" % (numberOfWorkspaces - 1, startOverlaps))
self.__check_workspaces_are_common(inputWorkspaces)

scaleFactor = None
comma_separator = ","
no_separator = str()

# Iterate forward through the workspaces
if scaleRHSWorkspace:
lhsWS = self.__workspace_from_split_name(inputWorkspaces, 0)
for i in range(1, numberOfWorkspaces, 1):
rhsWS = self.__workspace_from_split_name(inputWorkspaces, i)
lhsWS, scaleFactor = Stitch1D(LHSWorkspace=lhsWS, RHSWorkspace=rhsWS, StartOverlap=startOverlaps[i-1], EndOverlap=endOverlaps[i-1], Params=params, ScaleRHSWorkspace=scaleRHSWorkspace, UseManualScaleFactor=useManualScaleFactor, ManualScaleFactor=manualScaleFactor)
self.setProperty('OutputWorkspace', lhsWS)
DeleteWorkspace(lhsWS)
# Iterate backwards through the workspaces.
# Identify and process as group workspaces
if self.__are_processing_groups(inputWorkspaces):
workspace_groups = self.__workspaces_from_split_name(inputWorkspaces)

out_group_separator = no_separator
out_group_workspaces = str()

n_sub_workspaces = workspace_groups[0].size()
for i in range(n_sub_workspaces):

to_process = str()
out_name = str()
separator = no_separator

for j in range(0, numberOfWorkspaces, 1):

to_process += separator + workspace_groups[j][i].name()
out_name += workspace_groups[j][i].name()
separator=comma_separator

startOverlaps = self.getProperty("StartOverlaps").value
endOverlaps = self.getProperty("EndOverlaps").value

stitched, scaleFactor = Stitch1DMany(InputWorkspaces=to_process, OutputWorkspace=out_name, StartOverlaps=startOverlaps, EndOverlaps=endOverlaps,
Params=params, ScaleRHSWorkspace=scaleRHSWorkspace, UseManualScaleFactor=useManualScaleFactor,
ManualScaleFactor=manualScaleFactor)

out_group_workspaces += out_group_separator + out_name
out_group_separator = comma_separator

out_workspace_name = self.getPropertyValue("OutputWorkspace")
out_group = GroupWorkspaces(InputWorkspaces=out_group_workspaces, OutputWorkspace=out_workspace_name)
self.setProperty("OutputWorkspace", out_group)

else:
rhsWS = self.__workspace_from_split_name(inputWorkspaces, -1)
for i in range(0, numberOfWorkspaces-1, 1):
lhsWS = self.__workspace_from_split_name(inputWorkspaces, i)
rhsWS, scaleFactor = Stitch1D(LHSWorkspace=lhsWS, RHSWorkspace=rhsWS, StartOverlap=startOverlaps[i-1], EndOverlap=endOverlaps[i-1], Params=params, ScaleRHSWorkspace=scaleRHSWorkspace, UseManualScaleFactor=useManualScaleFactor, ManualScaleFactor=manualScaleFactor)
self.setProperty('OutputWorkspace', rhsWS)
DeleteWorkspace(rhsWS)

# Iterate forward through the workspaces
if scaleRHSWorkspace:
lhsWS = self.__workspace_from_split_name(inputWorkspaces, 0)

for i in range(1, numberOfWorkspaces, 1):
rhsWS = self.__workspace_from_split_name(inputWorkspaces, i)
lhsWS, scaleFactor = self.__do_stitch_workspace(lhsWS, rhsWS, startOverlaps[i-1], endOverlaps[i-1], params, scaleRHSWorkspace, useManualScaleFactor, manualScaleFactor)
self.setProperty('OutputWorkspace', lhsWS)

# Iterate backwards through the workspaces.
else:
rhsWS = self.__workspace_from_split_name(inputWorkspaces, -1)
for i in range(0, numberOfWorkspaces-1, 1):
lhsWS = self.__workspace_from_split_name(inputWorkspaces, i)
rhsWS, scaleFactor = Stitch1D(LHSWorkspace=lhsWS, RHSWorkspace=rhsWS, StartOverlap=startOverlaps[i-1], EndOverlap=endOverlaps[i-1], Params=params, ScaleRHSWorkspace=scaleRHSWorkspace, UseManualScaleFactor=useManualScaleFactor, ManualScaleFactor=manualScaleFactor)
self.setProperty('OutputWorkspace', rhsWS)

self.setProperty('OutScaleFactor', scaleFactor)
return None
Expand Down
Loading

0 comments on commit 6b64122

Please sign in to comment.