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

Last change on this file since ff8cb73 was 457d961, checked in by Celine Durniak <celine.durniak@…>, 7 years ago

Corrected bugs in display of new GUI (angstrom, size of line edit)

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