source: sasview/src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py @ 9e587bc

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 9e587bc was b764ae5, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

processEvents() helps with proper chart generation. - SASVIEW-890
Fixed weighing in fitting - SASVIEW-1017
Fixed error bars after fitting - SASVIEW-1004

  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[180bd54]1"""
2Widget/logic for smearing data.
3"""
4import numpy as np
[4992ff2]5from PyQt5 import QtCore
6from PyQt5 import QtGui
7from PyQt5 import QtWidgets
[180bd54]8
[dc5ef15]9from sas.qtgui.Plotting.PlotterData import Data2D
[d6b8a1d]10import sas.qtgui.Utilities.GuiUtils as GuiUtils
[180bd54]11
12# Local UI
[1bc27f1]13from sas.qtgui.Perspectives.Fitting.UI.OptionsWidgetUI import Ui_tabOptions
[180bd54]14
15QMIN_DEFAULT = 0.0005
16QMAX_DEFAULT = 0.5
17NPTS_DEFAULT = 50
18
19MODEL = [
20    'MIN_RANGE',
21    'MAX_RANGE',
22    'NPTS',
23    'LOG_SPACED']
24
[4992ff2]25class DataWidgetMapper(QtWidgets.QDataWidgetMapper):
[180bd54]26    """
27    Custom version of the standard QDataWidgetMapper allowing for proper
28    response to index change in comboboxes
29    """
30    def addMapping(self, widget, section, propertyName=None):
31        if propertyName is None:
32            super(DataWidgetMapper, self).addMapping(widget, section)
33        else:
34            super(DataWidgetMapper, self).addMapping(widget, section, propertyName)
35
[4992ff2]36        if isinstance(widget, QtWidgets.QComboBox):
[180bd54]37            delegate = self.itemDelegate()
38            widget.currentIndexChanged.connect(lambda: delegate.commitData.emit(widget))
39
[4992ff2]40        elif isinstance(widget, QtWidgets.QCheckBox):
[180bd54]41            delegate = self.itemDelegate()
42            widget.stateChanged.connect(lambda: delegate.commitData.emit(widget))
43
[4992ff2]44class OptionsWidget(QtWidgets.QWidget, Ui_tabOptions):
[180bd54]45    plot_signal = QtCore.pyqtSignal()
46    def __init__(self, parent=None, logic=None):
47        super(OptionsWidget, self).__init__()
48
49        self.setupUi(self)
50
51        # Logic component
52        self.logic = logic
[1bc27f1]53        self.parent = parent
[180bd54]54
55        # Weight radio box group
[4992ff2]56        self.weightingGroup = QtWidgets.QButtonGroup()
[180bd54]57        self.weighting = 0
58
59        # Group boxes
60        self.boxWeighting.setEnabled(False)
61        self.cmdMaskEdit.setEnabled(False)
62        # Button groups
63        self.weightingGroup.addButton(self.rbWeighting1)
64        self.weightingGroup.addButton(self.rbWeighting2)
65        self.weightingGroup.addButton(self.rbWeighting3)
66        self.weightingGroup.addButton(self.rbWeighting4)
67
68        # Let only floats in the range edits
[d6b8a1d]69        self.txtMinRange.setValidator(GuiUtils.DoubleValidator())
70        self.txtMaxRange.setValidator(GuiUtils.DoubleValidator())
[180bd54]71        # Let only ints in the number of points edit
72        self.txtNpts.setValidator(QtGui.QIntValidator())
73
74        # Attach slots
75        self.cmdReset.clicked.connect(self.onRangeReset)
76        self.cmdMaskEdit.clicked.connect(self.onMaskEdit)
77        self.chkLogData.stateChanged.connect(self.toggleLogData)
78        # Button groups
79        self.weightingGroup.buttonClicked.connect(self.onWeightingChoice)
80
[b764ae5]81        self.qmin = QMIN_DEFAULT
82        self.qmax = QMAX_DEFAULT
83        self.npts = NPTS_DEFAULT
84        if self.logic.data_is_loaded:
85            self.qmin, self.qmax, self.npts = self.logic.computeDataRange()
[180bd54]86        self.initModel()
87        self.initMapper()
88        self.model.blockSignals(True)
[b764ae5]89        self.updateQRange(self.qmin, self.qmax, self.npts)
90        self.txtMaxRange.setText(str(self.qmax))
91        self.txtMinRange.setText(str(self.qmin))
92        self.txtNpts.setText(str(self.npts))
93        self.txtNptsFit.setText(str(self.npts))
[180bd54]94        self.model.blockSignals(False)
95
[457d961]96        new_font = 'font-family: -apple-system, "Helvetica Neue", "Ubuntu";'
97        self.label_13.setStyleSheet(new_font)
98        self.label_15.setStyleSheet(new_font)
99
[180bd54]100    def initModel(self):
101        """
102        Initialize the state
103        """
104        self.model = QtGui.QStandardItemModel()
[b3e8629]105        for model_item in range(len(MODEL)):
[180bd54]106            self.model.setItem(model_item, QtGui.QStandardItem())
107        # Attach slot
108        self.model.dataChanged.connect(self.onModelChange)
109
110    def initMapper(self):
111        """
112        Initialize model item <-> UI element mapping
113        """
114        self.mapper = DataWidgetMapper(self)
115
116        self.mapper.setModel(self.model)
117        self.mapper.setOrientation(QtCore.Qt.Vertical)
118
[1bc27f1]119        self.mapper.addMapping(self.txtMinRange, MODEL.index('MIN_RANGE'))
120        self.mapper.addMapping(self.txtMaxRange, MODEL.index('MAX_RANGE'))
121        self.mapper.addMapping(self.txtNpts,     MODEL.index('NPTS'))
122        self.mapper.addMapping(self.chkLogData,  MODEL.index('LOG_SPACED'))
[976978b]123
124        self.mapper.toFirst()
[180bd54]125
126    def toggleLogData(self, isChecked):
127        """ Toggles between log and linear data sets """
128        pass
129
130    def onMaskEdit(self):
131        """
132        Callback for running the mask editor
133        """
[c0a3b22e]134        if isinstance(self.logic.data, Data2D):
135            self.parent.communicate.maskEditorSignal.emit(self.logic.data)
[180bd54]136
137    def onRangeReset(self):
138        """
139        Callback for resetting qmin/qmax
140        """
[b764ae5]141        self.updateQRange(self.qmin, self.qmax, self.npts)
[180bd54]142
143    def onWeightingChoice(self, button):
144        """
145        Update weighting in the fit state
146        """
147        button_id = button.group().checkedId()
148        self.weighting = abs(button_id + 2)
[9a7c81c]149        self.plot_signal.emit()
[180bd54]150
151    def onModelChange(self, top, bottom):
152        """
[1bc27f1]153        Respond to model change by updating the plot
[180bd54]154        """
[1bc27f1]155        # "bottom" is unused
[180bd54]156        # update if there's something to update
[61a92d4]157        if str(self.model.item(top.row()).text()):
[180bd54]158            self.plot_signal.emit()
159
160    def setEnablementOnDataLoad(self):
161        """
162        Enable/disable various UI elements based on data loaded
163        """
[c0a3b22e]164        is2Ddata = isinstance(self.logic.data, Data2D)
[180bd54]165        self.boxWeighting.setEnabled(True)
[c0a3b22e]166        self.cmdMaskEdit.setEnabled(is2Ddata)
[180bd54]167        # Switch off txtNpts related controls
168        self.txtNpts.setEnabled(False)
169        self.txtNptsFit.setEnabled(False)
170        self.chkLogData.setEnabled(False)
171        # Weighting controls
[87dfca4]172        if self.logic.di_flag:
173            self.rbWeighting2.setEnabled(True)
174            self.rbWeighting2.setChecked(True)
[180bd54]175        else:
[87dfca4]176            self.rbWeighting2.setEnabled(False)
177            self.rbWeighting1.setChecked(True)
[180bd54]178
179    def updateQRange(self, q_range_min, q_range_max, npts):
180        """
181        Update the local model based on calculated values
182        """
183        self.model.item(MODEL.index('MIN_RANGE')).setText(str(q_range_min))
184        self.model.item(MODEL.index('MAX_RANGE')).setText(str(q_range_max))
185        self.model.item(MODEL.index('NPTS')).setText(str(npts))
[b764ae5]186        self.qmin, self.qmax, self.npts = q_range_min, q_range_max, npts
[180bd54]187
188    def state(self):
189        """
190        Returns current state of controls
191        """
192        q_range_min = float(self.model.item(MODEL.index('MIN_RANGE')).text())
193        q_range_max = float(self.model.item(MODEL.index('MAX_RANGE')).text())
[1bc27f1]194        npts = int(self.model.item(MODEL.index('NPTS')).text())
195        log_points = str(self.model.item(MODEL.index('LOG_SPACED')).text()) == 'true'
[180bd54]196
197        return (q_range_min, q_range_max, npts, log_points, self.weighting)
Note: See TracBrowser for help on using the repository browser.