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

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 0215e0a was 83eb5208, checked in by Piotr Rozyczko <rozyczko@…>, 8 years ago

Putting files in more ordered fashion

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