-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/feature/8042_stitch_many'
- Loading branch information
Showing
4 changed files
with
194 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
Code/Mantid/Framework/PythonInterface/plugins/algorithms/Stitch1DMany.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
"""*WIKI* | ||
Stitches single histogram [[MatrixWorkspace|Matrix Workspaces]] together outputing a stitched Matrix Workspace. This algorithm is a wrapper over [[Stitch1DMD]]. | ||
The algorithm expects pairs of StartOverlaps and EndOverlaps values. The order in which these are provided determines the pairing. | ||
There should be N entries in each of these StartOverlaps and EndOverlaps lists, where N = 1 -(No of workspaces to stitch). | ||
StartOverlaps and EndOverlaps are in the same units as the X-axis for the workspace. | ||
*WIKI*""" | ||
#from mantid.simpleapi import * | ||
|
||
from mantid.simpleapi import * | ||
from mantid.api import * | ||
from mantid.kernel import * | ||
import numpy as np | ||
|
||
class Stitch1DMany(PythonAlgorithm): | ||
|
||
def category(self): | ||
return "Reflectometry\\ISIS;PythonAlgorithms" | ||
|
||
def name(self): | ||
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") | ||
|
||
overlap_validator = FloatArrayMandatoryValidator() | ||
|
||
self.declareProperty(FloatArrayProperty(name="StartOverlaps", values=[], validator=overlap_validator), doc="Overlap in Q.") | ||
self.declareProperty(FloatArrayProperty(name="EndOverlaps", values=[], validator=overlap_validator), doc="End overlap in Q.") | ||
self.declareProperty(FloatArrayProperty(name="Params", values=[0.1]), 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()] | ||
|
||
def PyExec(self): | ||
|
||
inputWorkspaces = self.getProperty("InputWorkspaces").value | ||
# Just forward the other properties on. | ||
startOverlaps = self.getProperty('StartOverlaps').value | ||
endOverlaps = self.getProperty('EndOverlaps').value | ||
scaleRHSWorkspace = self.getProperty('ScaleRHSWorkspace').value | ||
useManualScaleFactor = self.getProperty('UseManualScaleFactor').value | ||
manualScaleFactor = self.getProperty('ManualScaleFactor').value | ||
params = self.getProperty("Params").value | ||
|
||
inputWorkspaces = inputWorkspaces.split(',') | ||
numberOfWorkspaces = len(inputWorkspaces) | ||
if not numberOfWorkspaces > 1: | ||
raise ValueError("Too few workspaces to stitch") | ||
if not (len(startOverlaps) == len(endOverlaps)): | ||
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)) | ||
|
||
scaleFactor = None | ||
|
||
# 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. | ||
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) | ||
|
||
self.setProperty('OutScaleFactor', scaleFactor) | ||
return None | ||
|
||
|
||
############################################################################################# | ||
|
||
AlgorithmFactory.subscribe(Stitch1DMany) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/Stitch1DManyTest.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import unittest | ||
import numpy | ||
from mantid.simpleapi import * | ||
from mantid.kernel import * | ||
from mantid.api import * | ||
|
||
class Stitch1DManyTest(unittest.TestCase): | ||
|
||
a = None | ||
b = None | ||
c = None | ||
x = None | ||
e = None | ||
|
||
def setUp(self): | ||
x = numpy.arange(-1, 1.2, 0.2) | ||
e = numpy.arange(-1, 1, 0.2) | ||
e.fill(0) | ||
self.e = e | ||
self.x = x | ||
a = CreateWorkspace(UnitX="1/q", DataX=x, DataY=[0.0,0.0,0.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0], NSpec=1, DataE=e) | ||
b = CreateWorkspace(UnitX="1/q", DataX=x, DataY=[2.0,2.0,2.0,2.0,2.0,2.0,2.0,0.0,0.0,0.0], NSpec=1, DataE=e) | ||
self.a = a | ||
self.b = b | ||
|
||
def tearDown(self): | ||
# Cleanup | ||
DeleteWorkspace(self.a) | ||
DeleteWorkspace(self.b) | ||
|
||
def test_stitch_throws_with_too_few_workspaces(self): | ||
try: | ||
stitched = Stitch1DMany(InputWorkspaces='a', StartOverlaps=[-0.5], EndOverlaps=[0.5], Params=[0.1]) | ||
self.fail("Only one workspace. Should have thrown.") | ||
except RuntimeError: | ||
pass | ||
|
||
def test_stitch_throws_with_wrong_number_of_Start_overlaps(self): | ||
try: | ||
stitched = Stitch1DMany(InputWorkspaces='a, b', StartOverlaps=[-0.5, -0.6], EndOverlaps=[0.5], Params=[0.1]) | ||
self.fail("Two start overlaps, but only two workspaces. Should have thrown.") | ||
except RuntimeError: | ||
pass | ||
|
||
def test_stitch_throws_with_wrong_number_of_End_overlaps(self): | ||
try: | ||
stitched = Stitch1DMany(InputWorkspaces='a, b', StartOverlaps=[-0.5], EndOverlaps=[0.5, 0.6], Params=[0.1]) | ||
self.fail("Two end overlaps, but only two workspaces. Should have thrown.") | ||
except RuntimeError: | ||
pass | ||
|
||
|
||
def do_check_ydata(self, expectedYData, targetWS): | ||
yDataRounded = [ round(elem, 4) for elem in targetWS.readY(0) ] | ||
same = all([(x == y) for x,y in zip(yDataRounded, expectedYData)]) | ||
self.assertTrue(same) | ||
|
||
''' | ||
Cross-check that the result of using Stitch1DMany with two workspaces is the same as using Stitch1D. | ||
''' | ||
def test_stitches_two(self): | ||
stitchedViaStitchMany, scaleFactorMany = Stitch1DMany(InputWorkspaces='a, b', StartOverlaps=[-0.4], EndOverlaps=[0.4], Params=[0.2]) | ||
stitchedViaStitchTwo, scaleFactorTwo = Stitch1D(LHSWorkspace=self.a, RHSWorkspace=self.b, StartOverlap=-0.4, EndOverlap=0.4, Params=[0.2]) | ||
self.assertEquals(scaleFactorTwo, scaleFactorMany) | ||
|
||
expectedYData = [0,0,0,3,3,3,3,0,0,0] | ||
self.do_check_ydata(expectedYData, stitchedViaStitchMany) | ||
|
||
# Do cross compare | ||
isSuccess = CheckWorkspacesMatch(Workspace1=stitchedViaStitchMany, Workspace2=stitchedViaStitchTwo) | ||
self.assertEquals("Success!", isSuccess); | ||
|
||
DeleteWorkspace(stitchedViaStitchMany) | ||
DeleteWorkspace(stitchedViaStitchTwo) | ||
|
||
def test_stitches_three(self): | ||
ws1 = CreateWorkspace(UnitX="1/q", DataX=self.x, DataY=[3.0, 3.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], NSpec=1, DataE=self.e) | ||
ws2 = CreateWorkspace(UnitX="1/q", DataX=self.x, DataY=[0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 2.0, 0.0, 0.0, 0.0], NSpec=1, DataE=self.e) | ||
ws3 = CreateWorkspace(UnitX="1/q", DataX=self.x, DataY=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0], NSpec=1, DataE=self.e) | ||
stitchedViaStitchMany, sf = Stitch1DMany(InputWorkspaces='ws1, ws2, ws3', StartOverlaps=[-0.4,0.2], EndOverlaps=[-0.2,0.4], Params=[0.2]) | ||
|
||
expectedYData = [3,3,3,3,3,3,3,3,3,3] | ||
self.do_check_ydata(expectedYData, stitchedViaStitchMany) | ||
self.assertEquals(3.0, round(sf, 6)) | ||
|
||
DeleteWorkspace(ws1) | ||
DeleteWorkspace(ws2) | ||
DeleteWorkspace(ws3) | ||
DeleteWorkspace(stitchedViaStitchMany) | ||
|
||
def test_stitches_using_manual_scaling(self): | ||
stitchedViaStitchMany, sf = Stitch1DMany(InputWorkspaces='a, b', StartOverlaps=[-0.4], EndOverlaps=[0.4], Params=[0.2], UseManualScaleFactor=True, ManualScaleFactor=2.0) | ||
|
||
self.assertEquals(2.0, round(sf, 6)) | ||
DeleteWorkspace(stitchedViaStitchMany) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |