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

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

Remove a bunch of pylint

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