source: sasview/src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py @ 4992ff2

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 4992ff2 was 4992ff2, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

Initial, in-progress version. Not really working atm. SASVIEW-787

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