source: sasview/src/sas/qtgui/Perspectives/Corfunc/CorfuncPerspective.py @ f159d1b

Last change on this file since f159d1b was f159d1b, checked in by Adam Washington <adam.washington@…>, 6 years ago

Live update drawing

  • Property mode set to 100644
File size: 7.6 KB
Line 
1# global
2import sys
3from PyQt4 import QtCore
4from PyQt4 import QtGui
5from PyQt4 import QtWebKit
6
7from twisted.internet import threads
8from twisted.internet import reactor
9
10# sas-global
11from sas.qtgui.Plotting.PlotterData import Data1D
12import sas.qtgui.Utilities.GuiUtils as GuiUtils
13from sas.sascalc.corfunc.corfunc_calculator import CorfuncCalculator
14
15# local
16from UI.CorfuncPanel import Ui_CorfuncDialog
17# from InvariantDetails import DetailsDialog
18from CorfuncUtils import WIDGETS as W
19
20from matplotlib.backends import qt_compat
21from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
22from matplotlib.figure import Figure
23
24
25class MyMplCanvas(FigureCanvas):
26    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
27    def __init__(self, parent=None, width=5, height=4, dpi=100):
28        self.fig = Figure(figsize=(width, height), dpi=dpi)
29        self.axes = self.fig.add_subplot(111)
30
31        FigureCanvas.__init__(self, self.fig)
32        # self.reparent(parent, QPoint(0, 0))
33
34        # FigureCanvas.setSizePolicy(self,
35        #                            QSizePolicy.Expanding,
36        #                            QSizePolicy.Expanding)
37        # FigureCanvas.updateGeometry(self)
38
39        self.data = None
40        self.qmin = None
41        self.qmax1 = None
42        self.qmax2 = None
43        self.extrap = None
44
45    def drawQSpace(self):
46        self.fig.clf()
47
48        self.axes = self.fig.add_subplot(111)
49        self.axes.set_xscale("log")
50        self.axes.set_yscale("log")
51
52        if self.data:
53            self.axes.plot(self.data.x, self.data.y)
54        if self.qmin:
55            self.axes.axvline(self.qmin)
56        if self.qmax1:
57            self.axes.axvline(self.qmax1)
58        if self.qmax2:
59            self.axes.axvline(self.qmax2)
60        if self.extrap:
61            print(self.extrap)
62            self.axes.plot(self.extrap.x, self.extrap.y)
63
64        self.draw()
65
66
67
68    # def sizeHint(self):
69    #     w, h = self.get_width_height()
70    #     return QSize(w, h)
71
72    # def minimumSizeHint(self):
73    #     return QSize(10, 10)
74
75
76class CorfuncWindow(QtGui.QDialog, Ui_CorfuncDialog):
77    # The controller which is responsible for managing signal slots connections
78    # for the gui and providing an interface to the data model.
79    name = "Corfunc" # For displaying in the combo box
80    #def __init__(self, manager=None, parent=None):
81    def __init__(self, parent=None):
82        #super(InvariantWindow, self).__init__(parent)
83        super(CorfuncWindow, self).__init__()
84        self.setupUi(self)
85
86        self.setWindowTitle("Corfunc Perspective")
87
88        self.model = QtGui.QStandardItemModel(self)
89        self.communicate = GuiUtils.Communicate()
90        self._calculator = CorfuncCalculator()
91
92        self._canvas = MyMplCanvas(self)
93        self.verticalLayout_7.insertWidget(0,self._canvas)
94
95        # Connect buttons to slots.
96        # Needs to be done early so default values propagate properly.
97        self.setupSlots()
98
99        # Set up the model.
100        self.setupModel()
101
102        # Set up the mapper
103        self.setupMapper()
104
105    def setupSlots(self):
106        self.extractBtn.clicked.connect(self.action)
107        self.extrapolateBtn.clicked.connect(self.extrapolate)
108        self.transformBtn.clicked.connect(self.action)
109
110        self.calculateBgBtn.clicked.connect(self.calculateBackground)
111
112        self.hilbertBtn.clicked.connect(self.action)
113        self.fourierBtn.clicked.connect(self.action)
114
115        self.model.itemChanged.connect(self.modelChanged)
116
117    def setupModel(self):
118        self.model.setItem(W.W_QMIN,
119                           QtGui.QStandardItem("0"))
120        self.model.setItem(W.W_QMAX,
121                           QtGui.QStandardItem("0"))
122        self.model.setItem(W.W_QCUTOFF,
123                           QtGui.QStandardItem("0"))
124        self.model.setItem(W.W_BACKGROUND,
125                           QtGui.QStandardItem("0"))
126        self.model.setItem(W.W_TRANSFORM,
127                           QtGui.QStandardItem("Fourier"))
128
129    def modelChanged(self, item):
130        if item.row() == W.W_QMIN:
131            value = float(self.model.item(W.W_QMIN).text())
132            self.qMin.setValue(value)
133            self._calculator.lowerq = value
134            self._canvas.qmin = value
135        elif item.row() == W.W_QMAX:
136            value = float(self.model.item(W.W_QMAX).text())
137            self.qMax1.setValue(value)
138            self._calculator.upperq = (value, self._calculator.upperq[1])
139            self._canvas.qmax1 = value
140        elif item.row() == W.W_QCUTOFF:
141            value = float(self.model.item(W.W_QCUTOFF).text())
142            self.qMax2.setValue(value)
143            self._calculator.upperq = (self._calculator.upperq[0], value)
144            self._canvas.qmax2 = value
145        elif item.row() == W.W_BACKGROUND:
146            value = float(self.model.item(W.W_BACKGROUND).text())
147            self.bg.setValue(value)
148            self._calculator.background = value
149        else:
150            print("{} Changed".format(item))
151
152        self._canvas.drawQSpace()
153
154
155    def extrapolate(self):
156        params, extrapolation = self._calculator.compute_extrapolation()
157        self.guinierA.setValue(params['A'])
158        self.guinierB.setValue(params['B'])
159        self.porodK.setValue(params['K'])
160        self.porodSigma.setValue(params['sigma'])
161        print(params)
162        self._canvas.extrap = extrapolation
163        self._canvas.drawQSpace()
164
165
166
167    def setupMapper(self):
168        self.mapper = QtGui.QDataWidgetMapper(self)
169        self.mapper.setOrientation(QtCore.Qt.Vertical)
170        self.mapper.setModel(self.model)
171
172        self.mapper.addMapping(self.qMin, W.W_QMIN)
173        self.mapper.addMapping(self.qMax1, W.W_QMAX)
174        self.mapper.addMapping(self.qMax2, W.W_QCUTOFF)
175        self.mapper.addMapping(self.bg, W.W_BACKGROUND)
176
177        self.mapper.toFirst()
178
179    def calculateBackground(self):
180        bg = self._calculator.compute_background()
181        print(bg)
182        self.model.setItem(W.W_BACKGROUND, QtGui.QStandardItem(str(bg)))
183
184    def action(self):
185        print("Called an action!")
186        print(self.model)
187        print(self.mapper)
188
189    def allowBatch(self):
190        """
191        We cannot perform corfunc analysis in batch at this time.
192        """
193        return False
194
195    def setData(self, data_item, is_batch=False):
196        """
197        Obtain a QStandardItem object and dissect it to get Data1D/2D
198        Pass it over to the calculator
199        """
200        if not isinstance(data_item, list):
201            msg = "Incorrect type passed to the Corfunc Perpsective"
202            raise AttributeError(msg)
203
204        if not isinstance(data_item[0], QtGui.QStandardItem):
205            msg = "Incorrect type passed to the Corfunc Perspective"
206            raise AttributeError(msg)
207
208        self._model_item = data_item[0]
209        data = GuiUtils.dataFromItem(self._model_item)
210        self._calculator.lowerq = 1e-3
211        self._calculator.upperq = (2e-1, 3e-1)
212        self._calculator.set_data(data)
213
214        self._canvas.data = data
215        self._canvas.drawQSpace()
216
217        # self.model.item(WIDGETS.W_FILENAME).setData(QtCoreQVariant(self._model_item.text()))
218
219    def setClosable(self, value=True):
220        """
221        Allow outsiders close this widget
222        """
223        assert isinstance(value, bool)
224
225        self._allow_close = value
226
227
228if __name__ == "__main__":
229    app = QtGui.QApplication([])
230    import qt4reactor
231    # qt4reactor.install()
232    # DO NOT move the following import to the top!
233    # (unless you know what you're doing)
234    from twisted.internet import reactor
235    dlg = CorfuncWindow(reactor)
236    print(dlg)
237    dlg.show()
238    # print(reactor)
239    # reactor.run()
240    sys.exit(app.exec_())
Note: See TracBrowser for help on using the repository browser.