source: sasview/src/sas/qtgui/Calculators/UnitTesting/GenericScatteringCalculatorTest.py @ dc5ef15

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since dc5ef15 was dc5ef15, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Removed qtgui dependency on sasgui and wx SASVIEW-590

  • Property mode set to 100755
File size: 20.2 KB
Line 
1import sys
2import time
3import numpy
4import unittest
5from PyQt4 import QtGui
6from PyQt4.QtTest import QTest
7
8from PyQt4.QtCore import Qt
9from mock import MagicMock
10from mock import patch
11
12# set up import paths
13import path_prepare
14
15from mpl_toolkits.mplot3d import Axes3D
16from UnitTesting.TestUtils import QtSignalSpy
17from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
18from sas.qtgui.Calculators.GenericScatteringCalculator import GenericScatteringCalculator
19from sas.qtgui.Calculators.GenericScatteringCalculator import Plotter3D
20
21from sas.qtgui.MainWindow.DataManager import DataManager
22from sas.qtgui.MainWindow.GuiManager import GuiManager
23from sas.qtgui.Utilities.GuiUtils import *
24from sas.sascalc.calculator import sas_gen
25
26app = QtGui.QApplication(sys.argv)
27
28
29class GenericScatteringCalculatorTest(unittest.TestCase):
30    """Test the GenericScatteringCalculator"""
31    def setUp(self):
32        """Create the GenericScatteringCalculator"""
33        class dummy_manager(object):
34            def communicator(self):
35                return Communicate()
36
37        self.widget = GenericScatteringCalculator(dummy_manager())
38
39    def tearDown(self):
40        """Destroy the GenericScatteringCalculator"""
41        self.widget.close()
42        self.widget = None
43
44
45    def testDefaults(self):
46        """Test the GUI in its default state"""
47        self.assertIsInstance(self.widget, QtGui.QWidget)
48        self.assertEqual(self.widget.windowTitle(), "Generic SAS Calculator")
49
50        self.assertIn('trigger_plot_3d', dir(self.widget))
51
52        # Buttons
53        self.assertEqual(self.widget.txtData.text(), "Default SLD Profile")
54        self.assertEqual(self.widget.cmdLoad.text(), "Load")
55        self.assertEqual(self.widget.cmdDraw.text(), "Draw")
56        self.assertEqual(self.widget.cmdCompute.text(), "Compute")
57        self.assertEqual(self.widget.cmdReset.text(), "Reset")
58        self.assertEqual(self.widget.cmdClose.text(), "Close")
59        self.assertEqual(self.widget.cmdHelp.text(), "Help")
60        self.assertEqual(self.widget.cmdDrawpoints.text(), "Draw Points")
61        self.assertEqual(self.widget.cmdSave.text(), "Save SLD Data")
62
63        self.assertEqual(self.widget.txtBackground.text(), '0.0')
64        self.assertEqual(self.widget.txtScale.text(), '1.0')
65        self.assertEqual(self.widget.txtSolventSLD.text(), '0.0')
66        self.assertEqual(self.widget.txtTotalVolume.text(), '216000.0')
67        self.assertEqual(self.widget.txtUpFracIn.text(), '1.0')
68        self.assertEqual(self.widget.txtUpFracOut.text(), '1.0')
69        self.assertEqual(self.widget.txtUpTheta.text(), '0.0')
70        self.assertEqual(self.widget.txtNoQBins.text(), '50')
71        self.assertEqual(self.widget.txtQxMax.text(), '0.3')
72        self.assertEqual(self.widget.txtNoPixels.text(), '1000')
73        self.assertEqual(self.widget.txtMx.text(), '0')
74        self.assertEqual(self.widget.txtMy.text(), '0')
75        self.assertEqual(self.widget.txtMz.text(), '0')
76        self.assertEqual(self.widget.txtNucl.text(), '6.97e-06')
77        self.assertEqual(self.widget.txtXnodes.text(), '10')
78        self.assertEqual(self.widget.txtYnodes.text(), '10')
79        self.assertEqual(self.widget.txtZnodes.text(), '10')
80        self.assertEqual(self.widget.txtXstepsize.text(), '6')
81        self.assertEqual(self.widget.txtYstepsize.text(), '6')
82        self.assertEqual(self.widget.txtZstepsize.text(), '6')
83
84        # Comboboxes
85        self.assertFalse(self.widget.cbOptionsCalc.isVisible())
86        self.assertFalse(self.widget.cbOptionsCalc.isEditable())
87        self.assertEqual(self.widget.cbOptionsCalc.count(), 2)
88        self.assertEqual(self.widget.cbOptionsCalc.currentIndex(), 0)
89        self.assertListEqual([self.widget.cbOptionsCalc.itemText(i) for i in
90                              range(self.widget.cbOptionsCalc.count())],
91                             ['Fixed orientation', 'Debye full avg.'])
92
93        self.assertEqual(self.widget.cbShape.count(), 2)
94        self.assertEqual(self.widget.cbShape.currentIndex(), 0)
95        self.assertListEqual([self.widget.cbShape.itemText(i) for i in
96                              range(self.widget.cbShape.count())],
97                             ['Rectangular', 'Ellipsoid'])
98        self.assertFalse(self.widget.cbShape.isEditable())
99        # disable buttons
100        self.assertFalse(self.widget.cmdSave.isEnabled())
101        self.assertFalse(self.widget.cmdDraw.isEnabled())
102        self.assertFalse(self.widget.cmdDrawpoints.isEnabled())
103
104    def testHelpButton(self):
105        """ Assure help file is shown """
106        self.widget.onHelp()
107
108    def testValidator(self):
109        """ Test the inputs when validators had been defined """
110        # Background, Volume and Scale should be positive
111        txtEdit_positive = [self.widget.txtBackground,
112                            self.widget.txtTotalVolume,
113                            self.widget.txtScale]
114
115        for item in txtEdit_positive:
116            item.setText('-1')
117            state = item.validator().validate(item.text(), 0)[0]
118            self.assertEqual(state, QtGui.QValidator.Invalid)
119
120        for item in txtEdit_positive:
121            item.setText('2')
122            state = item.validator().validate(item.text(), 0)[0]
123            self.assertEqual(state, QtGui.QValidator.Acceptable)
124
125        for item in txtEdit_positive:
126            item.setText('abc')
127            state = item.validator().validate(item.text(), 0)[0]
128            self.assertEqual(state, QtGui.QValidator.Invalid)
129
130        # Fraction of spin up between 0 and 1
131        txtEdit_0_1 = [self.widget.txtUpFracIn, self.widget.txtUpFracOut]
132
133        for item in txtEdit_0_1:
134            item.setText('-1.04546')
135            state = item.validator().validate(item.text(), 0)[0]
136            self.assertEqual(state, QtGui.QValidator.Invalid)
137
138        for item in txtEdit_0_1:
139            item.setText('2.00000')
140            state = item.validator().validate(item.text(), 0)[0]
141            self.assertEqual(state, QtGui.QValidator.Invalid)
142
143        for item in txtEdit_0_1:
144            item.setText('0.000000005')
145            state = item.validator().validate(item.text(), 0)[0]
146            self.assertEqual(state, QtGui.QValidator.Acceptable)
147
148        # Test text edits related to Q:
149        # 0< Qmax < 1000, 2 <= Qbins <= 1000
150        txtEdit_q_values = [self.widget.txtNoQBins, self.widget.txtQxMax]
151        for item in txtEdit_q_values:
152            item.setText('-1.01')
153            state = item.validator().validate(item.text(), 0)[0]
154            self.assertEqual(state, QtGui.QValidator.Invalid)
155
156        for item in txtEdit_q_values:
157            item.setText('1500.01')
158            state = item.validator().validate(item.text(), 0)[0]
159            self.assertEqual(state, QtGui.QValidator.Invalid)
160
161        self.widget.txtNoQBins.setText('1.5')
162        self.assertEqual(
163            self.widget.txtNoQBins.validator().validate(item.text(), 0)[0],
164            QtGui.QValidator.Invalid)
165
166        self.widget.txtQxMax.setText('1.5')
167        self.assertEqual(
168            self.widget.txtQxMax.validator().validate(item.text(), 0)[0],
169            QtGui.QValidator.Acceptable)
170
171    def testLoadedSLDData(self):
172        """
173        Load sld data and check modifications of GUI
174        """
175        filename = os.path.join("UnitTesting", "sld_file.sld")
176        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
177        self.widget.loadFile()
178
179        # check modification of text in Load button
180        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
181        # wait a bit for data to be loaded
182        time.sleep(0.1)
183        # check updated values in ui, read from loaded file
184        self.assertEqual(self.widget.txtData.text(), 'sld_file.sld')
185        self.assertEqual(self.widget.txtTotalVolume.text(), '402408.0')
186        self.assertEqual(self.widget.txtNoPixels.text(), '552')
187        self.assertFalse(self.widget.txtNoPixels.isEnabled())
188
189        # check disabled TextEdits according to data format
190        self.assertFalse(self.widget.txtUpFracIn.isEnabled())
191        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
192        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
193        self.assertFalse(self.widget.txtNoPixels.isEnabled())
194
195        # check enabled draw buttons
196        self.assertTrue(self.widget.cmdDraw.isEnabled())
197        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
198        self.widget.show()
199        self.assertTrue(self.widget.isVisible())
200        self.assertFalse(self.widget.cbOptionsCalc.isVisible())
201
202        # check that text of loadButton is back to initial state
203        self.assertEqual(self.widget.cmdLoad.text(), 'Load')
204        # check values and enabled / disabled for
205        # Mx,y,z x,y,znodes and x,y,zstepsize buttons
206        self.assertFalse(self.widget.txtMx.isEnabled())
207        self.assertAlmostEqual(float(self.widget.txtMx.text()), 8.0795e-07, 4)
208        self.assertFalse(self.widget.txtMy.isEnabled())
209        self.assertAlmostEqual(float(self.widget.txtMy.text()), 8.0795e-07, 4)
210        self.assertFalse(self.widget.txtMz.isEnabled())
211        self.assertAlmostEqual(float(self.widget.txtMz.text()), 3.1739e-07, 4)
212        self.assertTrue(self.widget.txtNucl.isEnabled())
213        self.assertEqual(self.widget.txtNucl.text(), '0')
214
215        self.assertFalse(self.widget.txtXnodes.isEnabled())
216        self.assertEqual(self.widget.txtXnodes.text(), '10')
217        self.assertFalse(self.widget.txtYnodes.isEnabled())
218        self.assertEqual(self.widget.txtYnodes.text(), '10')
219        self.assertFalse(self.widget.txtZnodes.isEnabled())
220        self.assertEqual(self.widget.txtZnodes.text(), '10')
221
222        self.assertFalse(self.widget.txtXstepsize.isEnabled())
223        self.assertEqual(self.widget.txtXstepsize.text(), '9')
224        self.assertFalse(self.widget.txtYstepsize.isEnabled())
225        self.assertEqual(self.widget.txtYstepsize.text(), '9')
226        self.assertFalse(self.widget.txtZstepsize.isEnabled())
227        self.assertEqual(self.widget.txtZstepsize.text(), '9')
228
229        self.assertTrue(self.widget.sld_data.is_data)
230
231        # self.assertTrue(self.widget.trigger_plot_3d)
232
233
234    def testLoadedPDBButton(self):
235        """
236        Load pdb data and check modifications of GUI
237        """
238        filename = os.path.join("UnitTesting", "diamdsml.pdb")
239
240        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
241        self.widget.loadFile()
242
243        # check modification of text in Load button
244        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
245
246        time.sleep(1)
247        # check updated values in ui, read from loaded file
248        # TODO to be changed
249        self.assertEqual(self.widget.txtData.text(), 'diamdsml.pdb')
250        self.assertEqual(self.widget.txtTotalVolume.text(), '170.950584161')
251        self.assertEqual(self.widget.txtNoPixels.text(), '18')
252
253        # check disabled TextEdits according to data format
254        self.assertFalse(self.widget.txtUpFracIn.isEnabled())
255        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
256        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
257        self.assertFalse(self.widget.txtNoPixels.isEnabled())
258        # check enabled draw buttons
259        self.assertTrue(self.widget.cmdDraw.isEnabled())
260        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
261        # fixed orientation
262        self.widget.show()
263        self.assertTrue(self.widget.isVisible())
264        self.assertTrue(self.widget.cbOptionsCalc.isVisible())
265        # check that text of loadButton is back to initial state
266        self.assertEqual(self.widget.cmdLoad.text(), 'Load')
267        self.assertTrue(self.widget.cmdLoad.isEnabled())
268
269        # check values and enabled / disabled for
270        # Mx,y,z x,y,znodes and x,y,zstepsize buttons
271        self.assertFalse(self.widget.txtMx.isEnabled())
272        self.assertEqual(self.widget.txtMx.text(), '0')
273        self.assertFalse(self.widget.txtMy.isEnabled())
274        self.assertEqual(self.widget.txtMy.text(), '0')
275        self.assertFalse(self.widget.txtMz.isEnabled())
276        self.assertEqual(self.widget.txtMz.text(), '0')
277        self.assertFalse(self.widget.txtNucl.isEnabled())
278        self.assertAlmostEqual(float(self.widget.txtNucl.text()), 7.0003e-06, 4)
279
280        self.assertFalse(self.widget.txtXnodes.isEnabled())
281        self.assertEqual(self.widget.txtXnodes.text(), 'NaN')
282        self.assertFalse(self.widget.txtYnodes.isEnabled())
283        self.assertEqual(self.widget.txtYnodes.text(), 'NaN')
284        self.assertFalse(self.widget.txtZnodes.isEnabled())
285        self.assertEqual(self.widget.txtZnodes.text(), 'NaN')
286
287        self.assertFalse(self.widget.txtXstepsize.isEnabled())
288        self.assertEqual(self.widget.txtXstepsize.text(), 'NaN')
289        self.assertFalse(self.widget.txtYstepsize.isEnabled())
290        self.assertEqual(self.widget.txtYstepsize.text(), 'NaN')
291        self.assertFalse(self.widget.txtZstepsize.isEnabled())
292        self.assertEqual(self.widget.txtZstepsize.text(), 'NaN')
293
294        self.assertTrue(self.widget.sld_data.is_data)
295
296    # TODO
297    def testLoadedOMFButton(self):
298        """
299        Load omf data and check modifications of GUI
300        """
301        filename = os.path.join("UnitTesting", "A_Raw_Example-1.omf")
302
303        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
304        self.widget.loadFile()
305        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
306        time.sleep(1)
307
308        self.assertEqual(self.widget.txtData.text(), 'A_Raw_Example-1.omf')
309        self.assertEqual(self.widget.txtTotalVolume.text(), '128000000.0')
310        self.assertEqual(self.widget.txtNoPixels.text(), '16000')
311
312        # check disabled TextEdits according to data format
313        self.assertFalse(self.widget.txtUpFracIn.isEnabled())
314        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
315        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
316        self.assertFalse(self.widget.txtNoPixels.isEnabled())
317
318        # check enabled draw buttons
319        self.assertTrue(self.widget.cmdDraw.isEnabled())
320        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
321
322        # check that text of loadButton is back to initial state
323        self.assertEqual(self.widget.cmdLoad.text(), 'Load')
324        self.assertTrue(self.widget.cmdLoad.isEnabled())
325
326        # check values and enabled / disabled for
327        # Mx,y,z x,y,znodes and x,y,zstepsize buttons
328        self.assertFalse(self.widget.txtMx.isEnabled())
329        self.assertAlmostEqual(float(self.widget.txtMx.text()), 7.855e-09, 4)
330        self.assertFalse(self.widget.txtMy.isEnabled())
331        self.assertAlmostEqual(float(self.widget.txtMy.text()), 4.517e-08, 4)
332        self.assertFalse(self.widget.txtMz.isEnabled())
333        self.assertAlmostEqual(float(self.widget.txtMz.text()), 9.9511e-10, 4)
334        self.assertTrue(self.widget.txtNucl.isEnabled())
335        self.assertEqual(self.widget.txtNucl.text(), '0')
336
337        self.assertFalse(self.widget.txtXnodes.isEnabled())
338        self.assertEqual(self.widget.txtXnodes.text(), '40')
339        self.assertFalse(self.widget.txtYnodes.isEnabled())
340        self.assertEqual(self.widget.txtYnodes.text(), '40')
341        self.assertFalse(self.widget.txtZnodes.isEnabled())
342        self.assertEqual(self.widget.txtZnodes.text(), '10')
343
344        self.assertFalse(self.widget.txtXstepsize.isEnabled())
345        self.assertEqual(self.widget.txtXstepsize.text(), '20')
346        self.assertFalse(self.widget.txtYstepsize.isEnabled())
347        self.assertEqual(self.widget.txtYstepsize.text(), '20')
348        self.assertFalse(self.widget.txtZstepsize.isEnabled())
349        self.assertEqual(self.widget.txtZstepsize.text(), '20')
350
351    def testReset(self):
352        """
353        Test reset button when GUI has been modified
354        """
355        # modify gui
356        self.widget.txtBackground.setText('50.0')
357        # apply reset
358        self.widget.onReset()
359        # check that we get back to the initial state
360        self.assertEqual(self.widget.txtBackground.text(), '0.0')
361
362    # TODO check plots
363    def testCompute(self):
364        """
365        Test compute button
366        """
367        # load data
368        filename = os.path.join("UnitTesting", "diamdsml.pdb")
369
370        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
371        self.widget.loadFile()
372        time.sleep(1)
373        QTest.mouseClick(self.widget.cmdCompute, Qt.LeftButton)
374        # check modification of text of Compute button
375        self.assertEqual(self.widget.cmdCompute.text(), 'Wait...')
376        self.assertFalse(self.widget.cmdCompute.isEnabled())
377
378        self.widget.complete([numpy.ones(1), numpy.zeros(1), numpy.zeros(1)], update=None)
379        self.assertEqual(self.widget.cmdCompute.text(), 'Compute')
380        self.assertTrue(self.widget.cmdCompute.isEnabled())
381
382    # TODO
383    def testDrawButton(self):
384        """
385        Test Draw buttons for 3D plots with and without arrows
386        """
387        self.assertFalse(self.widget.cmdDraw.isEnabled())
388        filename = os.path.join("UnitTesting", "diamdsml.pdb")
389        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
390        self.widget.loadFile()
391        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
392        time.sleep(1)
393        self.assertTrue(self.widget.cmdDraw.isEnabled())
394        QTest.mouseClick(self.widget.cmdDraw, Qt.LeftButton)
395
396        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
397        QTest.mouseClick(self.widget.cmdDrawpoints, Qt.LeftButton)
398
399    def testCloseButton(self):
400        closeButton = self.widget.cmdClose
401        QTest.mouseClick(closeButton, Qt.LeftButton)
402
403    def testSaveFile(self):
404        """
405        Test Save feature to .sld file
406        """
407        filename = os.path.join("UnitTesting", "sld_file.sld")
408
409        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
410        self.widget.loadFile()
411
412        time.sleep(0.1)
413
414        filename1 = "test"
415        QtGui.QFileDialog.getSaveFileName = MagicMock(return_value=filename1)
416
417        QTest.mouseClick(self.widget.cmdSave, Qt.LeftButton)
418        self.widget.onSaveFile()
419        self.assertTrue(os.path.isfile(filename1 + '.sld'))
420        self.assertTrue(os.path.getsize(filename1 + '.sld') > 0)
421
422        os.remove("test.sld")
423
424
425class Plotter3DTest(unittest.TestCase):
426    """ Test 3D plots in real space.
427    The implementation is temporarily in the same script as the Generic SAS
428    calculator"""
429    def setUp(self):
430        """create"""
431        parent_test = MagicMock()
432        self.plotter = Plotter3D(parent=parent_test, graph_title='test')
433        self.data = sas_gen.MagSLD(numpy.array([1.0, 2.0, 3.0, 4.0]),
434                                   numpy.array([10.0, 11.0, 12.0, 13.0]),
435                                   numpy.array([0.1, 0.2, 0.3, 0.4]),
436                                   numpy.zeros(4),
437                                   numpy.zeros(4),
438                                   numpy.zeros(4),
439                                   numpy.zeros(4))
440        self.data.sld_n = [0, 6.97e-06, 6.97e-06, 6.97e-06]
441        self.data.set_pix_type('pixel')
442        self.data.pix_symbol = numpy.repeat('pixel', 4)
443
444    def tearDown(self):
445        """ Destroy"""
446        self.plotter = None
447        self.data = None
448
449    def testDataProperty(self):
450        self.plotter.data = self.data
451        self.assertEqual(self.plotter.data, self.data)
452        self.assertTrue(self.plotter.graph_title, 'test')
453        self.assertFalse(self.plotter.data.has_conect)
454
455    def testShowNoPlot(self):
456        FigureCanvas.draw_idle = MagicMock()
457        FigureCanvas.draw = MagicMock()
458        self.plotter.showPlot(data=None)
459        self.assertFalse(FigureCanvas.draw_idle.called)
460        self.assertFalse(FigureCanvas.draw.called)
461
462    def testShow3DPlot(self):
463        FigureCanvas.draw = MagicMock()
464        Axes3D.plot = MagicMock()
465
466        self.plotter.data = self.data
467        self.plotter.showPlot(data=self.plotter.data)
468        self.assertTrue(Axes3D.plot.called)
469        self.assertTrue(FigureCanvas.draw.called)
470
471
472if __name__ == "__main__":
473    unittest.main()
Note: See TracBrowser for help on using the repository browser.