source: sasview/src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py @ b1e36a3

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

FittingWidget? code review SASVIEW-561

  • Property mode set to 100644
File size: 24.2 KB
Line 
1# global
2import sys
3import os
4from PyQt4 import QtCore
5from PyQt4 import QtGui
6from PyQt4 import QtWebKit
7
8from twisted.internet import threads
9from twisted.internet import reactor
10
11# sas-global
12from sas.sascalc.invariant import invariant
13from sas.sasgui.guiframe.dataFitting import Data1D
14#import GuiUtils
15import sas.qtgui.GuiUtils as GuiUtils
16
17# local
18from UI.TabbedInvariantUI import Ui_tabbedInvariantUI
19from InvariantDetails import DetailsDialog
20from InvariantUtils import WIDGETS
21
22# The minimum q-value to be used when extrapolating
23Q_MINIMUM = 1e-5
24# The maximum q-value to be used when extrapolating
25Q_MAXIMUM = 10
26# the ratio of maximum q value/(qmax of data) to plot the theory data
27Q_MAXIMUM_PLOT = 3
28
29
30class MyModel(object):
31    def __init__(self):
32        self._model = QtGui.QStandardItemModel(self)
33
34    def addItem(self, item):
35        item = QtGui.QStandardItem(str(item))
36        self._model.appendRow(item)
37
38class InvariantWindow(QtGui.QDialog, Ui_tabbedInvariantUI):
39    # The controller which is responsible for managing signal slots connections
40    # for the gui and providing an interface to the data model.
41    name = "Invariant" # For displaying in the combo box
42    #def __init__(self, manager=None, parent=None):
43    def __init__(self, parent=None):
44        #super(InvariantWindow, self).__init__(parent)
45        super(InvariantWindow, self).__init__()
46        self.setupUi(self)
47
48        self.setWindowTitle("Invariant Perspective")
49
50        # initial input params
51        self._background = 0.0
52        self._scale = 1.0
53        self._contrast = 1.0
54        self._porod = 1.0
55        self._npoints_low = 10
56        self._npoints_high = 10
57        self._power_low = 4
58
59        self._manager = parent
60        #self._manager = manager
61        self._reactor = self._manager.reactor()
62        self._model_item = QtGui.QStandardItem()
63
64        self._helpView = QtWebKit.QWebView()
65        self.detailsDialog = DetailsDialog(self)
66
67        self._low_extrapolate = False
68        self._low_guinier  = True
69        self._low_fit  = True
70        self._high_extrapolate = False
71        self._high_power_value  = False
72
73        # no reason to have this widget resizable
74        self.setFixedSize(self.minimumSizeHint())
75
76        self.communicate = GuiUtils.Communicate()
77
78        self._data = None
79        self._path = ""
80
81        self._allow_close = False
82
83        # Mask file selector
84        ###################################################
85        #self._path = "cyl_400_20.txt"
86        #from sas.sascalc.dataloader.loader import  Loader
87        #loader = Loader()
88        #try:
89        #    self._data = loader.load(self._path)
90        #except:
91        #    raise
92        ###################################################
93
94        self.lineEdit_8.setText(str(Q_MINIMUM))
95        self.lineEdit_9.setText(str(Q_MAXIMUM))
96
97        # Let's choose the Standard Item Model.
98        self.model = QtGui.QStandardItemModel(self)
99
100        # Connect buttons to slots.
101        # Needs to be done early so default values propagate properly.
102        self.setupSlots()
103
104        # Set up the model.
105        self.setupModel()
106
107        # Set up the mapper
108        self.setupMapper()
109
110    def setClosable(self, value=True):
111        """
112        Allow outsiders close this widget
113        """
114        assert isinstance(value, bool)
115
116        self._allow_close = value
117
118    def closeEvent(self, event):
119        """
120        Overwrite QDialog close method to allow for custom widget close
121        """
122        if self._allow_close:
123            # reset the closability flag
124            self.setClosable(value=False)
125            event.accept()
126        else:
127            event.ignore()
128            # Maybe we should just minimize
129            self.setWindowState(QtCore.Qt.WindowMinimized)
130
131    def communicator(self):
132        """ Getter for the communicator """
133        return self.communicate
134
135    def updateFromModel(self):
136        """
137        update the globals based on the data in the model
138        """
139        self._background = float(self.model.item(WIDGETS.W_BACKGROUND).text())
140        self._contrast   = float(self.model.item(WIDGETS.W_CONTRAST).text())
141        self._scale      = float(self.model.item(WIDGETS.W_SCALE).text())
142
143        # High extrapolate
144        self._low_extrapolate = ( str(self.model.item(WIDGETS.W_ENABLE_LOWQ).text()) == 'true')
145        self._low_points = float(self.model.item(WIDGETS.W_NPTS_LOWQ).text())
146        self._low_guinier  = ( str(self.model.item(WIDGETS.W_LOWQ_GUINIER).text()) == 'true')
147        self._low_fit  = ( str(self.model.item(WIDGETS.W_LOWQ_FIT).text()) == 'true')
148        self._low_power_value  = float(self.model.item(WIDGETS.W_LOWQ_POWER_VALUE).text())
149
150        # High extrapolating
151        self._high_extrapolate = ( str(self.model.item(WIDGETS.W_ENABLE_HIGHQ).text()) == 'true')
152        self._high_points  = float(self.model.item(WIDGETS.W_NPTS_HIGHQ).text())
153        self._high_fit  = ( str(self.model.item(WIDGETS.W_HIGHQ_FIT).text()) == 'true')
154        self._high_power_value  = float(self.model.item(WIDGETS.W_HIGHQ_POWER_VALUE).text())
155
156    def calculateInvariant(self):
157        """
158        Use twisted to thread the calculations away.
159        """
160        # Find out if extrapolation needs to be used.
161        extrapolation = None
162        if self._low_extrapolate  and not self._high_extrapolate:
163            extrapolation = "low"
164        elif not self._low_extrapolate  and self._high_extrapolate:
165            extrapolation = "high"
166        elif self._low_extrapolate and self._high_extrapolate:
167            extrapolation = "both"
168        try:
169            # modify the Calculate button to indicate background process
170            self.pushButton.setText("Calculating...")
171            self.pushButton.setEnabled(False)
172            self.style = self.pushButton.styleSheet()
173            self.pushButton.setStyleSheet("background-color: rgb(255, 255, 0); color: rgb(0, 0, 0)")
174            # Send the calculations to separate thread.
175            d = threads.deferToThread(self.calculateThread, extrapolation)
176            # Add deferred callback for call return
177            d.addCallback(self.plotResult)
178        except Exception as ex:
179            # Set the button back to available
180            self.pushButton.setEnabled(True)
181            self.pushButton.setText("Calculate")
182            self.pushButton.setStyleSheet(self.style)
183
184
185    def plotResult(self, model):
186        """
187        """
188        self.model = model
189        self.mapper.toFirst()
190
191        # Set the button back to available
192        self.pushButton.setEnabled(True)
193        self.pushButton.setText("Calculate")
194        self.pushButton.setStyleSheet(self.style)
195
196        # Send the modified model item to DE for keeping in the model
197        self.communicate.updateModelFromPerspectiveSignal.emit(self._model_item)
198
199
200    def calculateThread(self, extrapolation):
201        """
202        Perform Invariant calculations.
203
204        TODO: Create a dictionary of results to be sent to DE on completion.
205        """
206        self.updateFromModel()
207
208        qstar_low = 0.0
209        qstar_low_err = 0.0
210        qstar_high = 0.0
211        qstar_high_err = 0.0
212        qstar_total = 0.0
213        qstar_total_low_err = 0.0
214
215        # Prepare the invariant object
216        inv = invariant.InvariantCalculator(data=self._data,
217                                            background = self._background,
218                                            scale = self._scale)
219
220        if self._low_extrapolate:
221            function_low = "power_law"
222            if self._low_guinier:
223                function_low = "guinier"
224            if self._low_fit:
225                self._low_power_value = None
226            inv.set_extrapolation(range="low",
227                                  npts=self._low_points,
228                                  function=function_low,
229                                  power=self._low_power_value)
230
231        if self._high_extrapolate:
232            function_low = "power_law"
233            inv.set_extrapolation(range="high",
234                                  npts=self._high_points,
235                                  function=function_low,
236                                  power=self._low_power_value)
237
238        #Compute invariant
239        # TODO: proper exception handling and logic -
240        # display info, update lineedits, don't run extrapolations etc.
241        calculation_failed = False
242        try:
243            qstar_total, qstar_total_error         = inv.get_qstar_with_error()
244        except Exception as ex:
245            calculation_failed = True
246            # Display relevant information
247            item = QtGui.QStandardItem("ERROR")
248            self.model.setItem(WIDGETS.W_INVARIANT, item)
249            item = QtGui.QStandardItem("ERROR")
250            self.model.setItem(WIDGETS.W_INVARIANT_ERR, item)
251        try:
252            volume_fraction, volume_fraction_error = \
253                inv.get_volume_fraction_with_error(self._contrast)
254        except Exception as ex:
255            calculation_failed = True
256            # Display relevant information
257            item = QtGui.QStandardItem("ERROR")
258            self.model.setItem(WIDGETS.W_VOLUME_FRACTION, item)
259            item = QtGui.QStandardItem("ERROR")
260            self.model.setItem(WIDGETS.W_VOLUME_FRACTION_ERR, item)
261        try:
262            surface, surface_error = \
263                inv.get_surface_with_error(self._contrast, self._porod)
264        except Exception as ex:
265            calculation_failed = True
266            # Display relevant information
267            item = QtGui.QStandardItem("ERROR")
268            self.model.setItem(WIDGETS.W_SPECIFIC_SURFACE, item)
269            item = QtGui.QStandardItem("ERROR")
270            self.model.setItem(WIDGETS.W_SPECIFIC_SURFACE_ERR, item)
271
272        if(calculation_failed):
273            # TODO: NOTIFY THE GUI MANAGER!!
274            self.mapper.toFirst()
275            return self.model
276
277        if self._low_extrapolate:
278            # for presentation in InvariantDetails
279            qstar_low, qstar_low_err = inv.get_qstar_low()
280            extrapolated_data = inv.get_extra_data_low(self._low_points)
281            power_low = inv.get_extrapolation_power(range='low')
282
283            #inv.data = extrapolated_data
284            #qstar_total, qstar_total_error = inv.get_qstar_with_error()
285
286            # Plot the chart
287            title = "Low-Q extrapolation"
288
289            # Convert the data into plottable
290            extrapolated_data = self._manager.createGuiData(extrapolated_data)
291            extrapolated_data.name = title
292            extrapolated_data.title = title
293
294            # Add the plot to the model item
295            # variant_item = QtCore.QVariant(self._plotter)
296            variant_item = QtCore.QVariant(extrapolated_data)
297
298            # This needs to run in the main thread
299            reactor.callFromThread(GuiUtils.updateModelItemWithPlot,
300                    self._model_item, variant_item, title)
301
302        if self._high_extrapolate:
303            # for presentation in InvariantDetails
304            qmax_plot = Q_MAXIMUM_PLOT * max(self._data.x)
305            if qmax_plot > Q_MAXIMUM:
306                qmax_plot = Q_MAXIMUM
307            qstar_high, qstar_high_err = inv.get_qstar_high()
308            power_high = inv.get_extrapolation_power(range='high')
309            high_out_data = inv.get_extra_data_high(q_end=qmax_plot, npts=500)
310
311            # Plot the chart
312            title = "High-Q extrapolation"
313
314            # Convert the data into plottable
315            high_out_data = self._manager.createGuiData(high_out_data)
316            high_out_data.name = title
317            high_out_data.title = title
318
319            # Add the plot to the model item
320            # variant_item = QtCore.QVariant(self._plotter)
321            variant_item = QtCore.QVariant(high_out_data)
322            # This needs to run in the main thread
323            reactor.callFromThread(GuiUtils.updateModelItemWithPlot,
324                    self._model_item, variant_item, title)
325
326        item = QtGui.QStandardItem(str(float('%.5g'% volume_fraction)))
327        self.model.setItem(WIDGETS.W_VOLUME_FRACTION, item)
328        item = QtGui.QStandardItem(str(float('%.5g'% volume_fraction_error)))
329        self.model.setItem(WIDGETS.W_VOLUME_FRACTION_ERR, item)
330        item = QtGui.QStandardItem(str(float('%.5g'% surface)))
331        self.model.setItem(WIDGETS.W_SPECIFIC_SURFACE, item)
332        item = QtGui.QStandardItem(str(float('%.5g'% surface_error)))
333        self.model.setItem(WIDGETS.W_SPECIFIC_SURFACE_ERR, item)
334        item = QtGui.QStandardItem(str(float('%.5g'% qstar_total)))
335        self.model.setItem(WIDGETS.W_INVARIANT, item)
336        item = QtGui.QStandardItem(str(float('%.5g'% qstar_total_error)))
337        self.model.setItem(WIDGETS.W_INVARIANT_ERR, item)
338
339        #item = QtGui.QStandardItem(str(float('%.5g'% qstar_total)))
340        #self.model.setItem(WIDGETS.D_TOTAL_QSTAR, item)
341        #item = QtGui.QStandardItem(str(float('%.5g'% qstar_total_err)))
342        #self.model.setItem(WIDGETS.D_TOTAL_QSTAR_ERR, item)
343        item = QtGui.QStandardItem(str(float('%.5g'% qstar_low)))
344        self.model.setItem(WIDGETS.D_LOW_QSTAR, item)
345        item = QtGui.QStandardItem(str(float('%.5g'% qstar_low_err)))
346        self.model.setItem(WIDGETS.D_LOW_QSTAR_ERR, item)
347        item = QtGui.QStandardItem(str(float('%.5g'% qstar_high)))
348        self.model.setItem(WIDGETS.D_HIGH_QSTAR, item)
349        item = QtGui.QStandardItem(str(float('%.5g'% qstar_high_err)))
350        self.model.setItem(WIDGETS.D_HIGH_QSTAR_ERR, item)
351
352        self.mapper.toFirst()
353
354        return self.model
355               
356    def title(self):
357        """
358        Perspective name
359        """
360        return "Invariant panel"
361
362    def status(self):
363        """
364        """
365        self.detailsDialog.setModel(self.model)
366        self.detailsDialog.showDialog()
367
368    def help(self):
369        """
370        """
371        _TreeLocation = self._manager.HELP_DIRECTORY_LOCATION + \
372            "/user/sasgui/perspectives/invariant/invariant_help.html"
373        self._helpView.load(QtCore.QUrl(_TreeLocation))
374        self._helpView.show()
375
376    def setupSlots(self):
377        self.pushButton.clicked.connect(self.calculateInvariant)
378        self.pushButton_2.clicked.connect(self.status)
379        self.pushButton_3.clicked.connect(self.help)
380
381        self.radioButton.toggled.connect(self.lowGuinierAndPowerToggle)
382        self.radioButton_8.toggled.connect(self.hiFitAndFixToggle)
383
384        self.radioButton_3.toggled.connect(self.lowFitAndFixToggle)
385
386        # Bug workaround for QDataWidgetMapper() not reacting to checkbox clicks.
387        # https://bugreports.qt.io/browse/QTBUG-1818
388        self.checkBox.clicked.connect(self.setFocus)
389        self.checkBox_2.clicked.connect(self.setFocus)
390
391        self.model.itemChanged.connect(self.modelChanged)
392
393    def modelChanged(self, item):
394        """
395        """
396        if item.row() == WIDGETS.W_ENABLE_LOWQ:
397            toggle = (str(item.text()) == 'true')
398            self._low_extrapolate = toggle
399            self.lowQToggle(toggle)
400        elif item.row() == WIDGETS.W_ENABLE_HIGHQ:
401            toggle = (str(item.text()) == 'true')
402            self._high_extrapolate = toggle
403            self.highQToggle(toggle)
404       
405    def lowGuinierAndPowerToggle(self, toggle):
406        """
407        """
408        self._low_guinier = toggle
409        toggle = not toggle
410        self.lineEdit_11.setEnabled(toggle)
411        self.radioButton_3.setEnabled(toggle)
412        self.radioButton_4.setEnabled(toggle)
413        self.lineEdit_11.setEnabled(toggle and (not self._low_fit))
414
415    def lowFitAndFixToggle(self, toggle):
416        """
417        """
418        self._low_fit = toggle
419        toggle = not toggle
420        self.lineEdit_11.setEnabled(toggle)
421
422    def hiFitAndFixToggle(self, toggle):
423        """
424        """
425        self.lineEdit_13.setEnabled(toggle)
426
427    def highQToggle(self, clicked):
428        """
429        Disable/enable High Q extrapolation
430        """
431        self.radioButton_7.setEnabled(clicked)
432        self.radioButton_8.setEnabled(clicked)
433        self.lineEdit_12.setEnabled(clicked)
434        self.lineEdit_13.setEnabled(clicked)
435
436    def lowQToggle(self, clicked):
437        """
438        Disable/enable Low Q extrapolation
439        """
440        self.radioButton.setEnabled(clicked)
441        self.radioButton_2.setEnabled(clicked)
442        self.lineEdit_11.setEnabled(clicked and not self._low_fit)
443
444        # Enable subelements
445        self.radioButton_3.setEnabled(clicked and not self._low_guinier)
446        self.radioButton_4.setEnabled(clicked and not self._low_guinier)
447        self.lineEdit_10.setEnabled(clicked and not self._low_guinier)
448
449    def setupModel(self):
450
451        # filename
452        item = QtGui.QStandardItem(self._path)
453        self.model.setItem(WIDGETS.W_FILENAME, item)
454
455        # add Q parameters to the model
456        #qmin = min(self._data.x)
457        qmin = 0.0
458        item = QtGui.QStandardItem(str(qmin))
459        self.model.setItem(WIDGETS.W_QMIN, item)
460        qmax = 0.0
461        item = QtGui.QStandardItem(str(qmax))
462        self.model.setItem(WIDGETS.W_QMAX, item)
463
464        # add custom input params
465        item = QtGui.QStandardItem(str(self._background))
466        self.model.setItem(WIDGETS.W_BACKGROUND, item)
467        item = QtGui.QStandardItem(str(self._contrast))
468        self.model.setItem(WIDGETS.W_CONTRAST, item)
469        item = QtGui.QStandardItem(str(self._scale))
470        self.model.setItem(WIDGETS.W_SCALE, item)
471       
472        # Dialog elements
473        itemf = QtGui.QStandardItem("false")
474        self.model.setItem(WIDGETS.W_ENABLE_HIGHQ, itemf)
475        itemf = QtGui.QStandardItem("false")
476        self.model.setItem(WIDGETS.W_ENABLE_LOWQ, itemf)
477
478        item = QtGui.QStandardItem(str(self._npoints_low))
479        self.model.setItem(WIDGETS.W_NPTS_LOWQ, item)
480        item = QtGui.QStandardItem(str(self._npoints_high))
481        self.model.setItem(WIDGETS.W_NPTS_HIGHQ, item)
482
483        itemt = QtGui.QStandardItem("true")
484        self.model.setItem(WIDGETS.W_LOWQ_GUINIER, itemt)
485
486        itemt = QtGui.QStandardItem("true")
487        self.model.setItem(WIDGETS.W_LOWQ_FIT, itemt)
488        item = QtGui.QStandardItem(str(self._power_low))
489        self.model.setItem(WIDGETS.W_LOWQ_POWER_VALUE, item)
490
491        itemt = QtGui.QStandardItem("true")
492        self.model.setItem(WIDGETS.W_HIGHQ_FIT, itemt)
493        item = QtGui.QStandardItem(str(self._power_low))
494        self.model.setItem(WIDGETS.W_HIGHQ_POWER_VALUE, item)
495
496
497    def setupMapper(self):
498        # Set up the mapper.
499        self.mapper = QtGui.QDataWidgetMapper(self)
500        self.mapper.setOrientation(QtCore.Qt.Vertical)
501        self.mapper.setModel(self.model)
502
503        # Set up the view on the model for testing
504        # self.tableView.setModel(self.model)
505
506        # Filename
507        self.mapper.addMapping(self.lineEdit, WIDGETS.W_FILENAME)
508        # Qmin/Qmax
509        self.mapper.addMapping(self.lineEdit_2, WIDGETS.W_QMIN)
510        self.mapper.addMapping(self.lineEdit_3, WIDGETS.W_QMAX)
511
512        # Background
513        self.mapper.addMapping(self.lineEdit_4, WIDGETS.W_BACKGROUND)
514        # Scale
515        self.mapper.addMapping(self.lineEdit_5, WIDGETS.W_SCALE)
516        # Contrast
517        self.mapper.addMapping(self.lineEdit_6, WIDGETS.W_CONTRAST)
518
519        # Lowq/Highq items
520        self.mapper.addMapping(self.checkBox, WIDGETS.W_ENABLE_LOWQ)
521        self.mapper.addMapping(self.checkBox_2, WIDGETS.W_ENABLE_HIGHQ)
522
523        self.mapper.addMapping(self.lineEdit_10, WIDGETS.W_NPTS_LOWQ)
524        self.mapper.addMapping(self.radioButton, WIDGETS.W_LOWQ_GUINIER)
525
526        self.mapper.addMapping(self.radioButton_3, WIDGETS.W_LOWQ_FIT)
527        self.mapper.addMapping(self.lineEdit_11, WIDGETS.W_LOWQ_POWER_VALUE)
528
529        self.mapper.addMapping(self.radioButton_7, WIDGETS.W_HIGHQ_FIT)
530        self.mapper.addMapping(self.lineEdit_13, WIDGETS.W_HIGHQ_POWER_VALUE)
531   
532        # Output
533        self.mapper.addMapping(self.lineEdit_14, WIDGETS.W_VOLUME_FRACTION)
534        self.mapper.addMapping(self.lineEdit_15, WIDGETS.W_VOLUME_FRACTION_ERR)
535        self.mapper.addMapping(self.lineEdit_16, WIDGETS.W_SPECIFIC_SURFACE)
536        self.mapper.addMapping(self.lineEdit_17, WIDGETS.W_SPECIFIC_SURFACE_ERR)
537        self.mapper.addMapping(self.lineEdit_19, WIDGETS.W_INVARIANT)
538        self.mapper.addMapping(self.lineEdit_18, WIDGETS.W_INVARIANT_ERR)
539
540        self.mapper.toFirst()
541
542    def setData(self, data_item):
543        """
544        Obtain a QStandardItem object and dissect it to get Data1D/2D
545        Pass it over to the calculator
546        """
547        if not isinstance(data_item, list):
548            msg = "Incorrect type passed to the Invariant Perspective"
549            raise AttributeError, msg
550
551        if not isinstance(data_item[0], QtGui.QStandardItem):
552            msg = "Incorrect type passed to the Invariant Perspective"
553            raise AttributeError, msg
554
555        self._model_item = data_item[0]
556
557        # Extract data on 1st child - this is the Data1D/2D component
558        data = GuiUtils.dataFromItem(self._model_item)
559        self.model.item(WIDGETS.W_FILENAME).setData(QtCore.QVariant(self._model_item.text()))
560
561        ##### DEBUG ####
562        # set data in the debug tree view window
563        self.treeView.setModel(self.model)
564
565        self.calculate(data_list=[data])
566       
567    def calculate(self, data_list=None):
568        """
569        receive a list of data and compute invariant
570
571        TODO: pass warnings/messages to log
572        """
573        msg = ""
574        data = None
575        if data_list is None:
576            data_list = []
577        if len(data_list) >= 1:
578            if len(data_list) == 1:
579                data = data_list[0]
580            else:
581                data_1d_list = []
582                data_2d_list = []
583                error_msg = ""
584                # separate data into data1d and data2d list
585                for data in data_list:
586                    if data is not None:
587                        if issubclass(data.__class__, Data1D):
588                            data_1d_list.append(data)
589                        else:
590                            error_msg += " %s  type %s \n" % (str(data.name),
591                                                              str(data.__class__.__name__))
592                            data_2d_list.append(data)
593                if len(data_2d_list) > 0:
594                    msg = "Invariant does not support the following data types:\n"
595                    msg += error_msg
596                if len(data_1d_list) == 0:
597                    # remake this as a qt event
598                    #wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
599                    return
600
601                # TODO: add msgbox for data choice
602                #msg += "Invariant panel does not allow multiple data!\n"
603                #msg += "Please select one.\n"
604                #if len(data_list) > 1:
605                    #from invariant_widgets import DataDialog
606                    #dlg = DataDialog(data_list=data_1d_list, text=msg)
607                    #if dlg.ShowModal() == wx.ID_OK:
608                    #    data = dlg.get_data()
609                    #else:
610                    #    data = None
611                    #dlg.Destroy()
612
613            if data is None:
614                msg += "invariant receives no data. \n"
615                #wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
616                return
617            if not issubclass(data.__class__, Data1D):
618                msg += "invariant cannot be computed for data of "
619                msg += "type %s\n" % (data.__class__.__name__)
620                #wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
621                return
622            else:
623                #wx.PostEvent(self.parent, NewPlotEvent(plot=data, title=data.title))
624                try:
625                    self._data = data
626                    self._path = "unique path"
627                    self.calculateInvariant()
628                except:
629                    msg = "Invariant Set_data: " + str(sys.exc_value)
630                    #wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
631        else:
632            msg = "invariant cannot be computed for data of "
633            msg += "type %s" % (data.__class__.__name__)
634            #wx.PostEvent(self.parent, StatusEvent(status=msg, info='error'))
635
636    def allowBatch(self):
637        """
638        Tell the caller that we don't accept multiple data instances
639        """
640        return False
641
642if __name__ == "__main__":
643    app = QtGui.QApplication([])
644    import qt4reactor
645    qt4reactor.install()
646    # DO NOT move the following import to the top!
647    # (unless you know what you're doing)
648    from twisted.internet import reactor
649    dlg = InvariantWindow(reactor)
650    dlg.show()
651    reactor.run()
Note: See TracBrowser for help on using the repository browser.