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

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

Remove all flake8 complaints

  • Property mode set to 100644
File size: 9.5 KB
Line 
1# global
2from PyQt4 import QtCore
3from PyQt4 import QtGui
4
5# sas-global
6import sas.qtgui.Utilities.GuiUtils as GuiUtils
7from sas.sascalc.corfunc.corfunc_calculator import CorfuncCalculator
8
9# local
10from UI.CorfuncPanel import Ui_CorfuncDialog
11# from InvariantDetails import DetailsDialog
12from CorfuncUtils import WIDGETS as W
13
14from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg \
15    as FigureCanvas
16from matplotlib.figure import Figure
17
18
19class MyMplCanvas(FigureCanvas):
20    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
21    def __init__(self, model, width=5, height=4, dpi=100):
22        self.model = model
23        self.fig = Figure(figsize=(width, height), dpi=dpi)
24        self.axes = self.fig.add_subplot(111)
25
26        FigureCanvas.__init__(self, self.fig)
27
28        self.data = None
29        self.extrap = None
30
31    def draw_q_space(self):
32        self.fig.clf()
33
34        self.axes = self.fig.add_subplot(111)
35        self.axes.set_xscale("log")
36        self.axes.set_yscale("log")
37
38        qmin = float(self.model.item(W.W_QMIN).text())
39        qmax1 = float(self.model.item(W.W_QMAX).text())
40        qmax2 = float(self.model.item(W.W_QCUTOFF).text())
41
42        if self.data:
43            self.axes.plot(self.data.x, self.data.y)
44            self.axes.axvline(qmin)
45            self.axes.axvline(qmax1)
46            self.axes.axvline(qmax2)
47            self.axes.set_xlim(min(self.data.x), max(self.data.x) * 1.5 -
48                               0.5 * min(self.data.x))
49        if self.extrap:
50            self.axes.plot(self.extrap.x, self.extrap.y)
51
52        self.draw()
53
54    def draw_real_space(self):
55        self.fig.clf()
56
57        self.axes = self.fig.add_subplot(111)
58        self.axes.set_xscale("linear")
59        self.axes.set_yscale("linear")
60
61        if self.data:
62            self.axes.plot(self.data.x, self.data.y, label="1D Correlation")
63            self.axes.plot(self.data3.x, self.data3.y, label="3D Correlation")
64            self.axes.plot(self.data_idf.x, self.data_idf.y,
65                           label="Interface Distribution Function")
66            self.axes.set_xlim(min(self.data.x), max(self.data.x) / 4)
67            self.axes.legend()
68
69        self.draw()
70
71
72class CorfuncWindow(QtGui.QDialog, Ui_CorfuncDialog):
73    # The controller which is responsible for managing signal slots connections
74    # for the gui and providing an interface to the data model.
75    name = "Corfunc"  # For displaying in the combo box
76
77    def __init__(self, parent=None):
78        super(CorfuncWindow, self).__init__()
79        self.setupUi(self)
80
81        self.setWindowTitle("Corfunc Perspective")
82
83        self.model = QtGui.QStandardItemModel(self)
84        self.communicate = GuiUtils.Communicate()
85        self._calculator = CorfuncCalculator()
86
87        self._canvas = MyMplCanvas(self.model)
88        self._realplot = MyMplCanvas(self.model)
89        self.verticalLayout_7.insertWidget(0, self._canvas)
90        self.verticalLayout_7.insertWidget(1, self._realplot)
91
92        # Connect buttons to slots.
93        # Needs to be done early so default values propagate properly.
94        self.setup_slots()
95
96        # Set up the model.
97        self.setup_model()
98
99        # Set up the mapper
100        self.setup_mapper()
101
102    def setup_slots(self):
103        self.extrapolateBtn.clicked.connect(self.extrapolate)
104        self.transformBtn.clicked.connect(self.transform)
105
106        self.calculateBgBtn.clicked.connect(self.calculateBackground)
107
108        self.model.itemChanged.connect(self.modelChanged)
109
110    def setup_model(self):
111        self.model.setItem(W.W_QMIN,
112                           QtGui.QStandardItem("0.01"))
113        self.model.setItem(W.W_QMAX,
114                           QtGui.QStandardItem("0.20"))
115        self.model.setItem(W.W_QCUTOFF,
116                           QtGui.QStandardItem("0.22"))
117        self.model.setItem(W.W_BACKGROUND,
118                           QtGui.QStandardItem("0"))
119        self.model.setItem(W.W_TRANSFORM,
120                           QtGui.QStandardItem("Fourier"))
121        self.model.setItem(W.W_GUINIERA,
122                           QtGui.QStandardItem("0.0"))
123        self.model.setItem(W.W_GUINIERB,
124                           QtGui.QStandardItem("0.0"))
125        self.model.setItem(W.W_PORODK,
126                           QtGui.QStandardItem("0.0"))
127        self.model.setItem(W.W_PORODSIGMA,
128                           QtGui.QStandardItem("0.0"))
129        self.model.setItem(W.W_CORETHICK, QtGui.QStandardItem(str(0)))
130        self.model.setItem(W.W_INTTHICK, QtGui.QStandardItem(str(0)))
131        self.model.setItem(W.W_HARDBLOCK, QtGui.QStandardItem(str(0)))
132        self.model.setItem(W.W_CRYSTAL, QtGui.QStandardItem(str(0)))
133        self.model.setItem(W.W_POLY, QtGui.QStandardItem(str(0)))
134        self.model.setItem(W.W_PERIOD, QtGui.QStandardItem(str(0)))
135
136    def modelChanged(self, item):
137        self.mapper.toFirst()
138        self._canvas.draw_q_space()
139
140    def _update_calculator(self):
141        self._calculator.lowerq = float(self.model.item(W.W_QMIN).text())
142        qmax1 = float(self.model.item(W.W_QMAX).text())
143        qmax2 = float(self.model.item(W.W_QCUTOFF).text())
144        self._calculator.upperq = (qmax1, qmax2)
145        self._calculator.background = \
146            float(self.model.item(W.W_BACKGROUND).text())
147
148    def extrapolate(self):
149        self._update_calculator()
150        params, extrapolation, _ = self._calculator.compute_extrapolation()
151
152        self.model.setItem(W.W_GUINIERA, QtGui.QStandardItem(str(params['A'])))
153        self.model.setItem(W.W_GUINIERB, QtGui.QStandardItem(str(params['B'])))
154        self.model.setItem(W.W_PORODK, QtGui.QStandardItem(str(params['K'])))
155        self.model.setItem(W.W_PORODSIGMA,
156                           QtGui.QStandardItem(str(params['sigma'])))
157
158        self._canvas.extrap = extrapolation
159        self._canvas.draw_q_space()
160
161    def transform(self):
162        if self.fourierBtn.isChecked():
163            method = "fourier"
164        elif self.hilbertBtn.isChecked():
165            method = "hilbert"
166
167        extrap = self._canvas.extrap
168        bg = float(self.model.item(W.W_BACKGROUND).text())
169
170        def updatefn(*args, **kwargs):
171            pass
172
173        def completefn(transforms):
174            (trans1, trans3, idf) = transforms
175            self._realplot.data = trans1
176            self._realplot.data3 = trans3
177            self._realplot.data_idf = idf
178            self._realplot.draw_real_space()
179            params = self._calculator.extract_parameters(trans1)
180            self.model.setItem(W.W_CORETHICK,
181                               QtGui.QStandardItem(str(params['d0'])))
182            self.model.setItem(W.W_INTTHICK,
183                               QtGui.QStandardItem(str(params['dtr'])))
184            self.model.setItem(W.W_HARDBLOCK,
185                               QtGui.QStandardItem(str(params['Lc'])))
186            self.model.setItem(W.W_CRYSTAL,
187                               QtGui.QStandardItem(str(params['fill'])))
188            self.model.setItem(W.W_POLY,
189                               QtGui.QStandardItem(str(params['A'])))
190            self.model.setItem(W.W_PERIOD,
191                               QtGui.QStandardItem(str(params['max'])))
192
193        self._update_calculator()
194        self._calculator.compute_transform(extrap, method, bg,
195                                           completefn, updatefn)
196
197    def setup_mapper(self):
198        self.mapper = QtGui.QDataWidgetMapper(self)
199        self.mapper.setOrientation(QtCore.Qt.Vertical)
200        self.mapper.setModel(self.model)
201
202        self.mapper.addMapping(self.qMin, W.W_QMIN)
203        self.mapper.addMapping(self.qMax1, W.W_QMAX)
204        self.mapper.addMapping(self.qMax2, W.W_QCUTOFF)
205        self.mapper.addMapping(self.bg, W.W_BACKGROUND)
206
207        self.mapper.addMapping(self.guinierA, W.W_GUINIERA)
208        self.mapper.addMapping(self.guinierB, W.W_GUINIERB)
209        self.mapper.addMapping(self.porodK, W.W_PORODK)
210        self.mapper.addMapping(self.porodSigma, W.W_PORODSIGMA)
211
212        self.mapper.addMapping(self.avgCoreThick, W.W_CORETHICK)
213        self.mapper.addMapping(self.avgIntThick, W.W_INTTHICK)
214        self.mapper.addMapping(self.avgHardBlock, W.W_HARDBLOCK)
215        self.mapper.addMapping(self.polydisp, W.W_POLY)
216        self.mapper.addMapping(self.longPeriod, W.W_PERIOD)
217        self.mapper.addMapping(self.localCrystal, W.W_CRYSTAL)
218
219        self.mapper.toFirst()
220
221    def calculateBackground(self):
222        self._update_calculator()
223        bg = self._calculator.compute_background()
224        temp = QtGui.QStandardItem(str(bg))
225        self.model.setItem(W.W_BACKGROUND, temp)
226
227    def allowBatch(self):
228        """
229        We cannot perform corfunc analysis in batch at this time.
230        """
231        return False
232
233    def setData(self, data_item, is_batch=False):
234        """
235        Obtain a QStandardItem object and dissect it to get Data1D/2D
236        Pass it over to the calculator
237        """
238        if not isinstance(data_item, list):
239            msg = "Incorrect type passed to the Corfunc Perpsective"
240            raise AttributeError(msg)
241
242        if not isinstance(data_item[0], QtGui.QStandardItem):
243            msg = "Incorrect type passed to the Corfunc Perspective"
244            raise AttributeError(msg)
245
246        self._model_item = data_item[0]
247        data = GuiUtils.dataFromItem(self._model_item)
248        self._calculator.set_data(data)
249
250        self._canvas.data = data
251        self._canvas.draw_q_space()
252
253        # self.model.item(WIDGETS.W_FILENAME).setData(QtCoreQVariant(self._model_item.text()))
254
255    def setClosable(self, value=True):
256        """
257        Allow outsiders close this widget
258        """
259        assert isinstance(value, bool)
260
261        self._allow_close = value
Note: See TracBrowser for help on using the repository browser.