Skip to content

Commit

Permalink
refs #5532. Extend tests and calculate scale factor
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Jun 25, 2012
1 parent a56c896 commit d195928
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 38 deletions.
108 changes: 75 additions & 33 deletions Code/Mantid/Framework/PythonAPI/PythonAlgorithms/Stitch1D.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,100 @@

class Stitch1D(PythonAlgorithm):

def __get_first_non_integrated_dimension(self, ws):
for i in range(0, ws.getNumDims()):
dim = ws.getDimension(i)
if not dim.getNBins() == 1:
return dim
raise RuntimeError("No integrated dimension")

def __check_individual_Workspace(self, ws):
if not ws.getNumDims() == 2:
raise ValueError( ws.name() + " must have 2 dimensions" )
raise RuntimeError( ws.name() + " must have 2 dimensions" )
dim1 = ws.getDimension(0)
dim2 = ws.getDimension(1)
if not bool(dim1.getNBins() == 1) ^ bool(dim2.getNBins() == 1):
raise ValueError(ws.name() + " must have one integrated and one unintegrated dimension")
raise RuntimeError(ws.name() + " must have one integrated and one unintegrated dimension")
return None

def __check_both_Workspaces(self, ws1, ws2):
for i in range(0, 2):
ws_1_dim = ws1.getDimension(i)
ws_2_dim = ws2.getDimension(i)
if not ws_1_dim.getNBins() == ws_2_dim.getNBins():
raise ValueError(ws1.name() + " and " + ws2.name() + " do not have the same number of bins.")
raise RuntimeError(ws1.name() + " and " + ws2.name() + " do not have the same number of bins.")
if not ws_1_dim.getName() == ws_2_dim.getName():
raise ValueError("Dimension names do not match up.")
raise RuntimeError("Dimension names do not match up.")
ws1_integrated_dim = self.__get_first_non_integrated_dimension(ws1)
ws2_integrated_dim = self.__get_first_non_integrated_dimension(ws2)
if not ws1_integrated_dim.getMaximum() == ws2_integrated_dim.getMaximum():
raise RuntimeError("Max values in the two non-integrated dimensions of the combining workspaces are not equal")
if not ws1_integrated_dim.getMinimum() == ws2_integrated_dim.getMinimum():
raise RuntimeError("Min values in the two non-integrated dimensions of the combining workspaces are not equal")

def __integrate_over(self, ws, fraction_low, fraction_high):
dim = self.__get_first_non_integrated_dimension(ws)
nbins = dim.getNBins()
# Find the corresponding bin indexes. Truncate to get the exact index.
bin_low = int(nbins * fraction_low)
bin_high = int(nbins * fraction_high)
sum_signal = 0.0
for index in range(bin_low, bin_high):
sum_signal += ws.signalAt(index)
return sum_signal

def category(self):
return "PythonAlgorithms"
return "PythonAlgorithms"
def name(self):
return "Stitch1D"
def PyInit(self):
self.declareProperty(IMDHistoWorkspaceProperty("Workspace1", "", Direction.Input), "Input MD Histo Workspace")
self.declareProperty(IMDHistoWorkspaceProperty("Workspace2", "", Direction.Input), "Input MD Histo Workspace")
self.declareProperty(IMDHistoWorkspaceProperty("OutputWorkspace", "", Direction.Output), "Stitched Ouput Workspace")
overlap_validator = CompositeValidator();
overlap_validator.add(FloatBoundedValidator(lower=0.0, upper=1.0))
overlap_validator.add(FloatMandatoryValidator())

self.declareProperty(name="StartOverlap", defaultValue=0.0, validator=overlap_validator, doc="Fraction along axis to start overlap. 0 to 1.");
self.declareProperty(name="EndOverlap", defaultValue=0.1, validator=overlap_validator, doc="Fraction along axis to end overlap. 0 to 1.");
self.declareProperty(name="ExpectGroupWorkspaces", defaultValue=False, doc="True if the input workspaces expected to be group workspaces.")
self.declareProperty(name="GroupWorkspaceIndex", defaultValue=0, doc="Index of the workspace in the group workspaces")
self.declareProperty(name="ScaleWorkspace1", 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(IMDHistoWorkspaceProperty("Workspace1", "", Direction.Input), "Input MD Histo Workspace")
self.declareProperty(IMDHistoWorkspaceProperty("Workspace2", "", Direction.Input), "Input MD Histo Workspace")
self.declareProperty(IMDHistoWorkspaceProperty("OutputWorkspace", "", Direction.Output), "Stitched Ouput Workspace")
overlap_validator = CompositeValidator();
overlap_validator.add(FloatBoundedValidator(lower=0.0, upper=1.0))
overlap_validator.add(FloatMandatoryValidator())

self.declareProperty(name="StartOverlap", defaultValue=0.0, validator=overlap_validator, doc="Fraction along axis to start overlap. 0 to 1.");
self.declareProperty(name="EndOverlap", defaultValue=0.1, validator=overlap_validator, doc="Fraction along axis to end overlap. 0 to 1.");
self.declareProperty(name="ExpectGroupWorkspaces", defaultValue=False, doc="True if the input workspaces expected to be group workspaces.")
self.declareProperty(name="GroupWorkspaceIndex", defaultValue=0, doc="Index of the workspace in the group workspaces")
self.declareProperty(name="ScaleWorkspace1", 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="AppliedScaleFactor", defaultValue=-1.0, direction = Direction.Output, doc="The actual used value for the scaling factor.");



def PyExec(self):
from mantid.simpleapi import MultiplyMD, DivideMD
workspace1 = mtd[self.getPropertyValue("Workspace1")]
workspace2 = mtd[self.getPropertyValue("Workspace2")]
self.__check_individual_Workspace(workspace1)
self.__check_individual_Workspace(workspace2)
self.__check_both_Workspaces(workspace1, workspace2)
start_overlap = self.getProperty("StartOverlap")
end_overlap = self.getProperty("EndOverlap")
if start_overlap >= end_overlap:
raise RuntimeError("StartOverlap must be < EndOverlap")
#TODO ... actually perform the 1D stiching.
self.setProperty("OutputWorkspace", workspace1)
from mantid.simpleapi import MultiplyMD, DivideMD
workspace1 = mtd[self.getPropertyValue("Workspace1")]
workspace2 = mtd[self.getPropertyValue("Workspace2")]
self.__check_individual_Workspace(workspace1)
self.__check_individual_Workspace(workspace2)
self.__check_both_Workspaces(workspace1, workspace2)
start_overlap = float(self.getPropertyValue("StartOverlap"))
end_overlap = float(self.getPropertyValue("EndOverlap"))

b_scale_workspace1 = bool(self.getProperty("ScaleWorkspace1"))

if start_overlap >= end_overlap:
raise RuntimeError("StartOverlap must be < EndOverlap")

ws1_overlap = self.__integrate_over(workspace1, start_overlap, end_overlap)
ws2_overlap = self.__integrate_over(workspace2, start_overlap, end_overlap)
scale_factor = None
if b_scale_workspace1 == True:
scale_factor = (ws2_overlap / ws1_overlap)
x = workspace2 * scale_factor
else:
scale_factor = (ws1_overlap / ws2_overlap)
x = workspace1 * scale_factor
self.setProperty("AppliedScaleFactor", scale_factor)
#use the start and end positions to 'sum' over the appopriate region in the input workspaces

self.setProperty("OutputWorkspace", workspace1)

registerAlgorithm(Stitch1D())
36 changes: 31 additions & 5 deletions Code/Mantid/Framework/PythonInterface/test/python/Stitch1DTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def setUp(self):
self.__bad_type_of_workspace_name = bad_md_workspace_alg.getPropertyValue("OutputWorkspace")

# Create a workspace that is of the right type and shape
good_workspace_alg = run_algorithm("CreateMDHistoWorkspace",SignalInput='1,2',ErrorInput='1,1',Dimensionality='2',Extents='-1,1,-1,1',NumberOfBins='2,1',Names='A,B',Units='U1,U2',OutputWorkspace='Stitch1D_test_workspace_2')
good_workspace_alg = run_algorithm("CreateMDHistoWorkspace",SignalInput='1,2',ErrorInput='1,2',Dimensionality='2',Extents='-1,1,-1,1',NumberOfBins='2,1',Names='A,B',Units='U1,U2',OutputWorkspace='Stitch1D_test_workspace_2')
self.__good_workspace_name = good_workspace_alg.getPropertyValue("OutputWorkspace")

# Create a workspace that is of the right type, but the wrong shape
Expand Down Expand Up @@ -156,7 +156,7 @@ def __do_test_ws1_and_ws2_have_different_dimension_names_throws(self, ws1_dim_na
mtd.remove(a)
mtd.remove(b)
self.assertTrue(passed)
def test_ws1_and_ws2_dim1_have_different_dimension_names_throws(self):
self.__do_test_ws1_and_ws2_have_different_dimension_names_throws(['A1','B1'], ['A2', 'B1'])

Expand Down Expand Up @@ -198,9 +198,35 @@ def test_end_overlap_too_high(self):
passed = True
finally:
self.assertTrue(passed)




def test_end_overlap_equal_to_start_overlap_throws(self):
passed = False
try:
alg = run_algorithm("Stitch1D", Workspace1=self.__good_workspace_name, Workspace2=self.__good_workspace_name,OutputWorkspace='converted',StartOverlap=0,EndOverlap=0,child=True)
except RuntimeError:
passed = True
finally:
self.assertTrue(passed)

def test_calculates_scaling_factor_correctly(self):
# Signal = 1, 1, 1, but only the middle to the end of the range is marked as overlap, so only 1, 1 used.
alg_a = run_algorithm("CreateMDHistoWorkspace",SignalInput='1,1,1',ErrorInput='1,1,1',Dimensionality='2',Extents='-1,1,-1,1',NumberOfBins='3,1',Names='A,B',Units='U1,U2',OutputWorkspace='flat_signal')
# Signal = 1, 2, 3, but only the middle to the end of the range is marked as overlap, so only 2, 3 used.
alg_b = run_algorithm("CreateMDHistoWorkspace",SignalInput='1,2,3',ErrorInput='1,1,1',Dimensionality='2',Extents='-1,1,-1,1',NumberOfBins='3,1',Names='A,B',Units='U1,U2',OutputWorkspace='rising_signal')

alg = run_algorithm("Stitch1D", Workspace1='flat_signal', Workspace2='rising_signal',OutputWorkspace='converted',StartOverlap=0.5,EndOverlap=1)
self.assertTrue(alg.isExecuted())
scale_factor = float(alg.getPropertyValue("AppliedScaleFactor"))

# 1 * ((2 + 3)/( 1 + 1)) = 2.5

self.assertEqual(2.5, scale_factor)

def test_does_something(self):
# Algorithm isn't complete at this point, but we need to have one success case to verify that all the previous failure cases are genuine failures (i.e. there is a way to get the algorithm to run properly)
alg = run_algorithm("Stitch1D", Workspace1=self.__good_workspace_name, Workspace2=self.__good_workspace_name,OutputWorkspace='converted',StartOverlap=0,EndOverlap=0.5,child=True)
self.assertTrue(alg.isExecuted())
scale_factor = alg.getPropertyValue("AppliedScaleFactor")

if __name__ == '__main__':
unittest.main()

0 comments on commit d195928

Please sign in to comment.