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

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 28a09b0 was 28a09b0, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Merged Celine's implementation of the generic scattering calculator

  • Property mode set to 100755
File size: 20.1 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 GenericScatteringCalculator import GenericScatteringCalculator
19from GenericScatteringCalculator import Plotter3D
20
21from sas.sasgui.guiframe.data_manager import DataManager
22from GuiManager import GuiManager
23from sas.qtgui.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 = "../../../sasview/test/save_states/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.assertEqual(self.widget.txtMx.text(), '8.0795e-07')
208        self.assertFalse(self.widget.txtMy.isEnabled())
209        self.assertEqual(self.widget.txtMy.text(), '8.0795e-07')
210        self.assertFalse(self.widget.txtMz.isEnabled())
211        self.assertEqual(self.widget.txtMz.text(), '3.1739e-07')
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 = "diamdsml.pdb"
239        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
240        self.widget.loadFile()
241
242        # check modification of text in Load button
243        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
244
245        time.sleep(1)
246        # check updated values in ui, read from loaded file
247        # TODO to be changed
248        self.assertEqual(self.widget.txtData.text(), 'diamdsml.pdb')
249        self.assertEqual(self.widget.txtTotalVolume.text(), '170.950584161')
250        self.assertEqual(self.widget.txtNoPixels.text(), '18')
251
252        # check disabled TextEdits according to data format
253        self.assertFalse(self.widget.txtUpFracIn.isEnabled())
254        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
255        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
256        self.assertFalse(self.widget.txtNoPixels.isEnabled())
257        # check enabled draw buttons
258        self.assertTrue(self.widget.cmdDraw.isEnabled())
259        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
260        # fixed orientation
261        self.widget.show()
262        self.assertTrue(self.widget.isVisible())
263        self.assertTrue(self.widget.cbOptionsCalc.isVisible())
264        # check that text of loadButton is back to initial state
265        self.assertEqual(self.widget.cmdLoad.text(), 'Load')
266        self.assertTrue(self.widget.cmdLoad.isEnabled())
267
268        # check values and enabled / disabled for
269        # Mx,y,z x,y,znodes and x,y,zstepsize buttons
270        self.assertFalse(self.widget.txtMx.isEnabled())
271        self.assertEqual(self.widget.txtMx.text(), '0')
272        self.assertFalse(self.widget.txtMy.isEnabled())
273        self.assertEqual(self.widget.txtMy.text(), '0')
274        self.assertFalse(self.widget.txtMz.isEnabled())
275        self.assertEqual(self.widget.txtMz.text(), '0')
276        self.assertFalse(self.widget.txtNucl.isEnabled())
277        self.assertEqual(self.widget.txtNucl.text(), '7.0003e-06')
278
279        self.assertFalse(self.widget.txtXnodes.isEnabled())
280        self.assertEqual(self.widget.txtXnodes.text(), 'NaN')
281        self.assertFalse(self.widget.txtYnodes.isEnabled())
282        self.assertEqual(self.widget.txtYnodes.text(), 'NaN')
283        self.assertFalse(self.widget.txtZnodes.isEnabled())
284        self.assertEqual(self.widget.txtZnodes.text(), 'NaN')
285
286        self.assertFalse(self.widget.txtXstepsize.isEnabled())
287        self.assertEqual(self.widget.txtXstepsize.text(), 'NaN')
288        self.assertFalse(self.widget.txtYstepsize.isEnabled())
289        self.assertEqual(self.widget.txtYstepsize.text(), 'NaN')
290        self.assertFalse(self.widget.txtZstepsize.isEnabled())
291        self.assertEqual(self.widget.txtZstepsize.text(), 'NaN')
292
293        self.assertTrue(self.widget.sld_data.is_data)
294
295    # TODO
296    def testLoadedOMFButton(self):
297        """
298        Load omf data and check modifications of GUI
299        """
300        filename = "../../../sasview/test/1d_data/A_Raw_Example-1.omf"
301        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
302        self.widget.loadFile()
303        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
304        time.sleep(1)
305
306        self.assertEqual(self.widget.txtData.text(), 'A_Raw_Example-1.omf')
307        self.assertEqual(self.widget.txtTotalVolume.text(), '128000000.0')
308        self.assertEqual(self.widget.txtNoPixels.text(), '16000')
309
310        # check disabled TextEdits according to data format
311        self.assertFalse(self.widget.txtUpFracIn.isEnabled())
312        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
313        self.assertFalse(self.widget.txtUpFracOut.isEnabled())
314        self.assertFalse(self.widget.txtNoPixels.isEnabled())
315
316        # check enabled draw buttons
317        self.assertTrue(self.widget.cmdDraw.isEnabled())
318        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
319
320        # check that text of loadButton is back to initial state
321        self.assertEqual(self.widget.cmdLoad.text(), 'Load')
322        self.assertTrue(self.widget.cmdLoad.isEnabled())
323
324        # check values and enabled / disabled for
325        # Mx,y,z x,y,znodes and x,y,zstepsize buttons
326        self.assertFalse(self.widget.txtMx.isEnabled())
327        self.assertEqual(self.widget.txtMx.text(), '7.855e-09')
328        self.assertFalse(self.widget.txtMy.isEnabled())
329        self.assertEqual(self.widget.txtMy.text(), '4.5169e-08')
330        self.assertFalse(self.widget.txtMz.isEnabled())
331        self.assertEqual(self.widget.txtMz.text(), '9.9511e-10')
332        self.assertTrue(self.widget.txtNucl.isEnabled())
333        self.assertEqual(self.widget.txtNucl.text(), '0')
334
335        self.assertFalse(self.widget.txtXnodes.isEnabled())
336        self.assertEqual(self.widget.txtXnodes.text(), '40')
337        self.assertFalse(self.widget.txtYnodes.isEnabled())
338        self.assertEqual(self.widget.txtYnodes.text(), '40')
339        self.assertFalse(self.widget.txtZnodes.isEnabled())
340        self.assertEqual(self.widget.txtZnodes.text(), '10')
341
342        self.assertFalse(self.widget.txtXstepsize.isEnabled())
343        self.assertEqual(self.widget.txtXstepsize.text(), '20')
344        self.assertFalse(self.widget.txtYstepsize.isEnabled())
345        self.assertEqual(self.widget.txtYstepsize.text(), '20')
346        self.assertFalse(self.widget.txtZstepsize.isEnabled())
347        self.assertEqual(self.widget.txtZstepsize.text(), '20')
348
349    def testReset(self):
350        """
351        Test reset button when GUI has been modified
352        """
353        # modify gui
354        self.widget.txtBackground.setText('50.0')
355        # apply reset
356        self.widget.onReset()
357        # check that we get back to the initial state
358        self.assertEqual(self.widget.txtBackground.text(), '0.0')
359
360    # TODO check plots
361    def testCompute(self):
362        """
363        Test compute button
364        """
365        # load data
366        filename = "diamdsml.pdb"
367        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
368        self.widget.loadFile()
369        time.sleep(1)
370        QTest.mouseClick(self.widget.cmdCompute, Qt.LeftButton)
371        # check modification of text of Compute button
372        self.assertEqual(self.widget.cmdCompute.text(), 'Wait...')
373        self.assertFalse(self.widget.cmdCompute.isEnabled())
374
375        self.widget.complete([numpy.ones(1), numpy.zeros(1), numpy.zeros(1)], update=None)
376        self.assertEqual(self.widget.cmdCompute.text(), 'Compute')
377        self.assertTrue(self.widget.cmdCompute.isEnabled())
378
379    # TODO
380    def testDrawButton(self):
381        """
382        Test Draw buttons for 3D plots with and without arrows
383        """
384        self.assertFalse(self.widget.cmdDraw.isEnabled())
385        # filename = "../../../sasview/test/upcoming_formats/dna.pdb"
386        filename = "diamdsml.pdb"
387        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
388        self.widget.loadFile()
389        self.assertEqual(self.widget.cmdLoad.text(), 'Loading...')
390        time.sleep(1)
391        self.assertTrue(self.widget.cmdDraw.isEnabled())
392        QTest.mouseClick(self.widget.cmdDraw, Qt.LeftButton)
393
394        self.assertTrue(self.widget.cmdDrawpoints.isEnabled())
395        QTest.mouseClick(self.widget.cmdDrawpoints, Qt.LeftButton)
396
397    def testCloseButton(self):
398        closeButton = self.widget.cmdClose
399        QTest.mouseClick(closeButton, Qt.LeftButton)
400
401    def testSaveFile(self):
402        """
403        Test Save feature to .sld file
404        """
405        filename = "../../../sasview/test/save_states/sld_file.sld"
406        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=filename)
407        self.widget.loadFile()
408
409        time.sleep(0.1)
410
411        filename1 = "../../../sasview/test/save_states/test"
412        QtGui.QFileDialog.getSaveFileName = MagicMock(return_value=filename1)
413
414        QTest.mouseClick(self.widget.cmdSave, Qt.LeftButton)
415        self.widget.onSaveFile()
416        self.assertTrue(os.path.isfile(filename1 + '.sld'))
417        self.assertTrue(os.path.getsize(filename1 + '.sld') > 0)
418
419        os.remove("../../../sasview/test/save_states/test.sld")
420
421
422class Plotter3DTest(unittest.TestCase):
423    """ Test 3D plots in real space.
424    The implementation is temporarily in the same script as the Generic SAS
425    calculator"""
426    def setUp(self):
427        """create"""
428        parent_test = MagicMock()
429        self.plotter = Plotter3D(parent=parent_test, graph_title='test')
430        self.data = sas_gen.MagSLD(numpy.array([1.0, 2.0, 3.0, 4.0]),
431                                   numpy.array([10.0, 11.0, 12.0, 13.0]),
432                                   numpy.array([0.1, 0.2, 0.3, 0.4]),
433                                   numpy.zeros(4),
434                                   numpy.zeros(4),
435                                   numpy.zeros(4),
436                                   numpy.zeros(4))
437        self.data.sld_n = [0, 6.97e-06, 6.97e-06, 6.97e-06]
438        self.data.set_pix_type('pixel')
439        self.data.pix_symbol = numpy.repeat('pixel', 4)
440
441    def tearDown(self):
442        """ Destroy"""
443        self.plotter = None
444        self.data = None
445
446    def testDataProperty(self):
447        self.plotter.data = self.data
448        self.assertEqual(self.plotter.data, self.data)
449        self.assertTrue(self.plotter.graph_title, 'test')
450        self.assertFalse(self.plotter.data.has_conect)
451
452    def testShowNoPlot(self):
453        FigureCanvas.draw_idle = MagicMock()
454        FigureCanvas.draw = MagicMock()
455        self.plotter.showPlot(data=None)
456        self.assertFalse(FigureCanvas.draw_idle.called)
457        self.assertFalse(FigureCanvas.draw.called)
458
459    def testShow3DPlot(self):
460        FigureCanvas.draw = MagicMock()
461        Axes3D.plot = MagicMock()
462
463        self.plotter.data = self.data
464        self.plotter.showPlot(data=self.plotter.data)
465        self.assertTrue(Axes3D.plot.called)
466        self.assertTrue(FigureCanvas.draw.called)
467
468
469if __name__ == "__main__":
470    unittest.main()
Note: See TracBrowser for help on using the repository browser.