-
Janik Zikovsky authored
from python to launch an algorithm asynchronously. The problem was that a non-gui thread was launching an observer method in a GUI thread. Something martyn changed fixed this (apparently :) )
Janik Zikovsky authoredfrom python to launch an algorithm asynchronously. The problem was that a non-gui thread was launching an observer method in a GUI thread. Something martyn changed fixed this (apparently :) )
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SliceViewerPythonInterfaceTest.py 16.98 KiB
import sys
import sys
import os
import unittest
import time
from PyQt4 import QtCore, QtGui
#from PyQt4.QtTest import QTest
# Import the Mantid framework
import MantidFramework
from MantidFramework import mtd
from mantidsimple import *
import mantidqtpython
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()
pass
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")
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_setWorkspace(self):
sv = self.sv
assert (sv is not None)
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_mdhisto",
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_mdhisto")
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?
sv.setSlicePoint(2, 7.6)
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])
#sv.show()
#app.exec_()
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)
#==========================================================================
#======================= 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)