Newer
Older
import sys
import sys
import os
import unittest
import time
#from PyQt4.QtTest import QTest
# Import the Mantid framework
import MantidFramework
from MantidFramework import mtd
from mantidsimple import *
from mantidqtpython import StdRuntimeError, StdInvalidArgument
# Create the application only once per test; otherwise I get a segfault
app = QtGui.QApplication(sys.argv)
class SliceViewerPythonInterfaceTest(unittest.TestCase):
"""Test for accessing SliceViewer widgets from MantidPlot
python interpreter"""
def setUp(self):
""" Set up and create a SliceViewer widget """
# Create a test data set
CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='x,y,z',
Units='m,m,m',SplitInto='5',SplitThreshold=100, MaxRecursionDepth='20',OutputWorkspace='mdw')
FakeMDEventData("mdw", UniformParams="1e4")
FakeMDEventData("mdw", PeakParams="1e3, 1, 2, 3, 1.0")
BinMD(InputWorkspace="mdw", OutputWorkspace="uniform", AxisAligned=1, AlignedDim0="x,0,10,30", AlignedDim1="y,0,10,30", AlignedDim2="z,0,10,30", IterateEvents="1", Parallel="0")
CreateWorkspace('workspace2d', '1,2,3', '2,3,4')
CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='x,y,z', Units='m,m,m',SplitInto='5',SplitThreshold=100, MaxRecursionDepth='20',OutputWorkspace='empty')
# Get the factory to create the SliceViewerWindow in C++
self.svw = mantidqtpython.MantidQt.Factory.WidgetFactory.Instance().createSliceViewerWindow("uniform", "")
# Retrieve the SliceViewer widget alone.
self.sv = self.svw.getSlicer()
def setUpXML(self):
"""Special set up for the XML version """
CreateMDWorkspace(Dimensions='3',Extents='-15,15, -15,15, -15,15',Names='Q_lab_x,Q_lab_y,Q_lab_z',
Units='m,m,m',SplitInto='5',SplitThreshold=100, MaxRecursionDepth='20',OutputWorkspace='TOPAZ_3680')
CreateMDWorkspace(Dimensions='4',Extents='-15,15, -15,15, -15,15, -10, 100',Names='Q_x,Q_y,Q_z,E',
Units='A,A,A,meV',SplitInto='5',SplitThreshold=100, MaxRecursionDepth='20',OutputWorkspace='WS_4D')
FakeMDEventData("TOPAZ_3680", UniformParams="1e4")
FakeMDEventData("WS_4D", UniformParams="1e4")
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
self.xml_3d = """<MDInstruction><MDWorkspaceName>TOPAZ_3680</MDWorkspaceName>
<DimensionSet>
<Dimension ID="Q_lab_x"><Name>Q_lab_x</Name><Units>Angstroms^-1</Units><UpperBounds>15.0000</UpperBounds><LowerBounds>-15.0000</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<Dimension ID="Q_lab_y"><Name>Q_lab_y</Name><Units>Angstroms^-1</Units><UpperBounds>15.0000</UpperBounds><LowerBounds>-15.0000</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<Dimension ID="Q_lab_z"><Name>Q_lab_z</Name><Units>Angstroms^-1</Units><UpperBounds>15.0000</UpperBounds><LowerBounds>-15.0000</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<XDimension><RefDimensionId>Q_lab_x</RefDimensionId></XDimension>
<YDimension><RefDimensionId>Q_lab_y</RefDimensionId></YDimension>
<ZDimension><RefDimensionId>Q_lab_z</RefDimensionId></ZDimension>
<TDimension><RefDimensionId/></TDimension>
</DimensionSet>
<Function><Type>PlaneImplicitFuction</Type>
<ParameterList>
<Parameter><Type>NormalParameter</Type><Value>1 0 0</Value></Parameter>
<Parameter><Type>OriginParameter</Type><Value>4.84211 0 0</Value></Parameter>
</ParameterList></Function>
</MDInstruction>"""
self.xml_4d = """<MDInstruction><MDWorkspaceName>WS_4D</MDWorkspaceName>
<DimensionSet>
<Dimension ID="Q_x"><Name>Q_x</Name><Units>Ang</Units><UpperBounds>5.7415</UpperBounds><LowerBounds>-1.5197</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<Dimension ID="Q_y"><Name>Q_y</Name><Units>Ang</Units><UpperBounds>6.7070</UpperBounds><LowerBounds>-6.6071</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<Dimension ID="Q_z"><Name>Q_z</Name><Units>Ang</Units><UpperBounds>6.6071</UpperBounds><LowerBounds>-6.6071</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<Dimension ID="E"><Name>E</Name><Units>MeV</Units><UpperBounds>150.0000</UpperBounds><LowerBounds>0.0000</LowerBounds><NumberOfBins>10</NumberOfBins></Dimension>
<XDimension><RefDimensionId>Q_x</RefDimensionId></XDimension>
<YDimension><RefDimensionId>Q_y</RefDimensionId></YDimension>
<ZDimension><RefDimensionId>E</RefDimensionId></ZDimension>
<TDimension><RefDimensionId>Q_z</RefDimensionId><Value>4.567</Value></TDimension>
</DimensionSet>
<Function><Type>PlaneImplicitFuction</Type><ParameterList>
<Parameter><Type>NormalParameter</Type><Value>0 1 0</Value></Parameter>
<Parameter><Type>OriginParameter</Type><Value>0 1.234 0</Value></Parameter>
</ParameterList></Function></MDInstruction>"""
def tearDown(self):
""" Close the created widget """
# This is crucial! Forces the object to be deleted NOW, not when python exits
# This prevents a segfault in Ubuntu 10.04, and is good practice.
self.svw.deleteLater()
#self.svw.show()
# Schedule quit at the next event
QtCore.QTimer.singleShot(0, app, QtCore.SLOT("quit()"))
# This is required for deleteLater() to do anything (it deletes at the next event loop)
app.quitOnLastWindowClosed = True
app.exec_()
#==========================================================================
#======================= Basic Tests ======================================
#==========================================================================
def test_getWorkspace(self):
sv = self.sv
self.assertEqual(sv.getWorkspaceName(), "uniform")
assert (sv is not None)
def test_setWorkspace_MDEventWorkspace(self):
sv = self.sv
sv.setWorkspace('mdw')
def test_setWorkspace_throwsOnBadInputs(self):
sv = self.sv
#sv.setWorkspace('workspace2d')
self.assertRaises(StdRuntimeError, sv.setWorkspace, '')
self.assertRaises(StdRuntimeError, sv.setWorkspace, 'non_existent_workspace')
self.assertRaises(StdRuntimeError, sv.setWorkspace, 'workspace2d')
#==========================================================================
#======================= XML Tests ========================================
#==========================================================================
def test_openFromXML_3D(self):
sv = self.sv
self.setUpXML()
# Read the XML and set the view
sv.openFromXML(self.xml_3d)
# Check the settings
self.assertEqual(sv.getWorkspaceName(), "TOPAZ_3680")
self.assertEqual(sv.getDimX(), 1)
self.assertEqual(sv.getDimY(), 2)
self.assertAlmostEqual( sv.getSlicePoint(0), 4.84211, 3)
pass
def test_openFromXML_4D(self):
sv = self.sv
self.setUpXML()
# Read the XML and set the view
sv.openFromXML(self.xml_4d)
# Check the settings
self.assertEqual(sv.getWorkspaceName(), "WS_4D")
self.assertEqual(sv.getDimX(), 0) # Q_x is X dimension
self.assertEqual(sv.getDimY(), 3) # Energy is Y
self.assertAlmostEqual( sv.getSlicePoint(1), 1.234, 3) # Slice point in Q_y
self.assertAlmostEqual( sv.getSlicePoint(2), 4.567, 3) # Slice point in Q_z
def test_openFromXML_3D_binned(self):
sv = self.sv
self.setUpXML()
BinMD(InputWorkspace="TOPAZ_3680", OutputWorkspace="TOPAZ_3680_visual_md",
AxisAligned=1, AlignedDim0="Q_lab_x,0,10,20", AlignedDim1="Q_lab_y,0,10,20", AlignedDim2="Q_lab_z,0,10,20")
# Read the XML and set the view
sv.openFromXML(self.xml_3d)
# Check the settings
# Automatically grabbed the histo version
self.assertEqual(sv.getWorkspaceName(), "TOPAZ_3680_visual_md")
self.assertEqual(sv.getDimX(), 1)
self.assertEqual(sv.getDimY(), 2)
self.assertAlmostEqual( sv.getSlicePoint(0), 4.84211, 3)
pass
#==========================================================================
#======================= Setting Dimensions, etc ==========================
#==========================================================================
def test_setXYDim(self):
sv = self.sv
sv.setXYDim(0,2)
self.assertEqual( sv.getDimX(), 0, "X dimension was set")
self.assertEqual( sv.getDimY(), 2, "Y dimension was set")
#sv.show()
#app.exec_()
def test_setXYDim_strings(self):
sv = self.sv
sv.setXYDim("x", "z")
self.assertEqual( sv.getDimX(), 0, "X dimension was set")
self.assertEqual( sv.getDimY(), 2, "Y dimension was set")
def test_setXYDim_strings_throwsOnBadInputs(self):
sv = self.sv
self.assertRaises(StdRuntimeError, sv.setXYDim, "monkey", "y")
self.assertRaises(StdRuntimeError, sv.setXYDim, "x", "monkey")
def test_setXYDim_throwsOnBadInputs(self):
sv = self.sv
self.assertRaises(StdInvalidArgument, sv.setXYDim, -1, 0)
self.assertRaises(StdInvalidArgument, sv.setXYDim, 5, 0)
self.assertRaises(StdInvalidArgument, sv.setXYDim, 0, -1)
self.assertRaises(StdInvalidArgument, sv.setXYDim, 0, 3)
self.assertRaises(StdInvalidArgument, sv.setXYDim, 0, 0)
def test_setSlicePoint(self):
sv = self.sv
# Set the slice point and got back the value?
self.assertAlmostEqual( sv.getSlicePoint(2), 7.6, 2)
# Go to too small a value
sv.setSlicePoint(2, -12.3)
self.assertAlmostEqual( sv.getSlicePoint(2), 0.0, 2)
# Go to too big a value
sv.setSlicePoint(2, 22.3)
self.assertAlmostEqual( sv.getSlicePoint(2), 10.0, 2)
def test_setSlicePoint_strings(self):
sv = self.sv
sv.setSlicePoint("z", 7.6)
self.assertAlmostEqual( sv.getSlicePoint("z"), 7.6, 2)
def test_setSlicePoint_strings_throwsOnBadInputs(self):
sv = self.sv
self.assertRaises(StdRuntimeError, sv.setSlicePoint, "monkey", 2.34)
self.assertRaises(StdRuntimeError, sv.getSlicePoint, "monkey")
def test_setSlicePoint_throwsOnBadInputs(self):
sv = self.sv
self.assertRaises(StdInvalidArgument, sv.setSlicePoint, -1, 7.6)
self.assertRaises(StdInvalidArgument, sv.setSlicePoint, 3, 7.6)
def test_getSlicePoint_throwsOnBadInputs(self):
sv = self.sv
self.assertRaises(StdInvalidArgument, sv.getSlicePoint, -1)
self.assertRaises(StdInvalidArgument, sv.getSlicePoint, 3)
def test_setXYLimits(self):
sv = self.sv
sv.setXYLimits(5,10, 7,8)
sv.setXYLimits(5,2, 7, 8)
self.assertEqual(sv.getXLimits(), [5, 2])
self.assertEqual(sv.getYLimits(), [7, 8])
def test_zoomBy(self):
sv = self.sv
self.assertEqual(sv.getXLimits(), [0, 10])
self.assertEqual(sv.getYLimits(), [0, 10])
# Zoom in by a factor of 2
sv.zoomBy(2.0)
self.assertEqual(sv.getXLimits(), [2.5, 7.5])
self.assertEqual(sv.getYLimits(), [2.5, 7.5])
# Zoom out to the original size
sv.zoomBy(0.5)
self.assertEqual(sv.getXLimits(), [0, 10])
self.assertEqual(sv.getYLimits(), [0, 10])
def test_setXYCenter(self):
sv = self.sv
self.assertEqual(sv.getXLimits(), [0, 10])
self.assertEqual(sv.getYLimits(), [0, 10])
# Move to a new spot
sv.setXYCenter(2.0, 6.0)
self.assertEqual(sv.getXLimits(), [-3, 7])
self.assertEqual(sv.getYLimits(), [1, 11])
def test_resetZoom(self):
sv = self.sv
sv.zoomBy(2.0)
self.assertEqual(sv.getXLimits(), [2.5, 7.5])
self.assertEqual(sv.getYLimits(), [2.5, 7.5])
# Go back automatically to full range
sv.resetZoom()
self.assertEqual(sv.getXLimits(), [0, 10])
self.assertEqual(sv.getYLimits(), [0, 10])
#==========================================================================
#======================= ColorMap and range ===============================
#==========================================================================
def test_loadColorMap(self):
""" Needs an absolute path - can't readily do unit test """
sv = self.sv
#sv.loadColorMap('')
def test_setColorScale(self):
sv = self.sv
sv.setColorScale(10, 30, False)
self.assertEqual(sv.getColorScaleMin(), 10)
self.assertEqual(sv.getColorScaleMax(), 30)
self.assertEqual(sv.getColorScaleLog(), False)
sv.setColorScale(20, 1000, True)
self.assertEqual(sv.getColorScaleMin(), 20)
self.assertEqual(sv.getColorScaleMax(), 1000)
self.assertEqual(sv.getColorScaleLog(), True)
def test_setColorScale_throwsOnBadInputs(self):
sv = self.sv
self.assertRaises(StdInvalidArgument, sv.setColorScale, 10, 5, False)
self.assertRaises(StdInvalidArgument, sv.setColorScale, 0, 5, True)
self.assertRaises(StdInvalidArgument, sv.setColorScale, -3, -1, True)
def test_setColorScaleAutoFull(self):
sv = self.sv
sv.setNormalization(1) # Make sure volume normalization is set
sv.setColorScaleAutoFull()
self.assertAlmostEqual(sv.getColorScaleMin(), 27.0, 3)
self.assertAlmostEqual(sv.getColorScaleMax(), 540.0, 3)
def test_setColorScaleAutoSlice(self):
sv = self.sv
sv.setNormalization(1) # Make sure volume normalization is set
sv.setColorScaleAutoSlice()
self.assertAlmostEqual(sv.getColorScaleMin(), 27.0, 3)
self.assertAlmostEqual(sv.getColorScaleMax(), 81.0, 3)
def test_setNormalization(self):
sv = self.sv
sv.setNormalization(0)
self.assertEqual(sv.getNormalization(), 0)
sv.setNormalization(1)
self.assertEqual(sv.getNormalization(), 1)
sv.setNormalization(2)
self.assertEqual(sv.getNormalization(), 2)
#==========================================================================
#======================= Screenshots etc. =================================
#==========================================================================
def test_setFastRender(self):
sv = self.sv
self.assertTrue(sv.getFastRender(), "Fast rendering mode is TRUE by default")
sv.setFastRender(False)
self.assertFalse(sv.getFastRender(), "Fast rendering mode is set to false")
#==========================================================================
#======================= LineViewer =======================================
#==========================================================================
def test_make_a_line(self):
svw = self.svw
sv = self.sv
sv.toggleLineMode(True)
liner = svw.getLiner()
liner.setStartXY(1, 1)
liner.setEndXY(5, 4)
liner.setNumBins(200)
liner.apply()
# Check that the values are there
self.assertEqual(liner.getNumBins(), 200)
# Length of 5 with 200 bins = 0.025 width
self.assertAlmostEqual(liner.getBinWidth(), 0.025, 3)
def test_setThickness(self):
svw = self.svw
self.sv.toggleLineMode(True)
liner = self.svw.getLiner()
liner.setPlanarWidth(1.5)
self.assertAlmostEqual(liner.getPlanarWidth(), 1.5, 3)
liner.setThickness(2, 0.75)
# Not yet a method to get the width in any dimension
def test_fixedBinWidth(self):
svw = self.svw
sv = self.sv
sv.toggleLineMode(True)
liner = svw.getLiner()
liner.setFixedBinWidthMode(True, 0.025)
liner.setStartXY(1, 1)
liner.setEndXY(5, 4)
liner.setPlanarWidth(1)
liner.apply()
# Length of 5, bin width of 0.025 = 200 bins
self.assertEqual(liner.getNumBins(), 200)
self.assertAlmostEqual(liner.getBinWidth(), 0.025, 3)
#Helper method to find the name of the plot's x axis.
def _getPlotXAxisName(self, lv, ws):
index = lv.getXAxisDimensionIndex()
dim = ws.getDimension(index)
return dim.getName()
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
def test_autoAxisAssignmentWhenNoIntegration(self):
CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='A,B,C',Units='A,A,A',OutputWorkspace='original')
FakeMDEventData(InputWorkspace='original',UniformParams='10000',PeakParams='10000,2,2,2,1',RandomizeSignal='1')
#Note that all axis have 10 bins below.
SliceMD(InputWorkspace='original',AlignedDim0='A,0,10,10',AlignedDim1='B,0,10,10',AlignedDim2='C,0,10,10',OutputWorkspace='binned_ws')
binned_ws = mtd['binned_ws']
sv = self.sv
sv.setWorkspace('binned_ws')
sv.setXYDim("A","B")
#should toggle to 'A' axis as that is now the longest
lv = self.svw.getLiner()
lv.setStartXY(0, 0)
lv.setEndXY(10,5)
self.assertEquals("A", self._getPlotXAxisName(lv, binned_ws))
#should toggle to 'B' axis as that is now the longest
lv.setStartXY(0, 0)
lv.setEndXY(5,10)
self.assertEquals("B", self._getPlotXAxisName(lv, binned_ws))
def test_autoAxisAssignmentWhenAnAxisIsIntegrated(self):
CreateMDWorkspace(Dimensions='3',Extents='0,10,0,10,0,10',Names='A,B,C',Units='A,A,A',OutputWorkspace='original')
FakeMDEventData(InputWorkspace='original',UniformParams='10000',PeakParams='10000,2,2,2,1',RandomizeSignal='1')
#Note that the 'A' axis is now integrated (see call below)
SliceMD(InputWorkspace='original',AlignedDim0='A,0,10,1',AlignedDim1='B,0,10,10',AlignedDim2='C,0,10,10',OutputWorkspace='binned_ws')
binned_ws = mtd['binned_ws']
sv = self.sv
sv.setWorkspace('binned_ws')
sv.setXYDim("A","B")
#should toggle to 'B' axis as the 'A' axis is integrated, even though 'A' is the longest.
lv = self.svw.getLiner()
lv.setStartXY(0, 0)
lv.setEndXY(10,5)
self.assertEquals("B", self._getPlotXAxisName(lv, binned_ws))
#should toggle to 'B' axis as that is now the longest and also because 'A' is integrated.
lv.setStartXY(0, 0)
lv.setEndXY(5,10)
self.assertEquals("B", self._getPlotXAxisName(lv, binned_ws))
#==========================================================================
#======================= Dynamic Rebinning ================================
#==========================================================================
def test_DynamicRebinning(self):
sv = self.sv
sv.setRebinThickness(2, 1.0)
sv.setRebinNumBins(50, 200)
sv.refreshRebin()
sv.setRebinMode(True, True)
time.sleep(1)
self.assertTrue(mtd.workspaceExists('uniform_rebinned'), 'Dynamically rebinned workspace was created.')
ws = mtd['uniform_rebinned']
self.assertEqual(ws.getNumDims(), 3)
self.assertEqual(ws.getNPoints(), 50*200*1)