source: sasview/src/sas/qtgui/Perspectives/Fitting/FittingWidget.py @ 60af928

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

Fitting perspective refactoring for multitab support SASVIEW-345

  • Property mode set to 100755
File size: 13.1 KB
Line 
1import sys
2import json
3import  os
4from collections import defaultdict
5
6from PyQt4 import QtGui
7from PyQt4 import QtCore
8
9from UI.FittingWidgetUI import Ui_FittingWidgetUI
10
11from sasmodels import generate
12from sasmodels import modelinfo
13from sas.sasgui.guiframe.CategoryInstaller import CategoryInstaller
14
15TAB_MAGNETISM = 4
16TAB_POLY = 3
17
18class FittingWidget(QtGui.QWidget, Ui_FittingWidgetUI):
19    """
20    Main window for selecting form and structure factor models
21    """
22    name = "Fitting" # For displaying in the combo box in DataExplorer
23    def __init__(self, manager=None, parent=None, data=None):
24        """
25
26        :param manager:
27        :param parent:
28        :return:
29        """
30        super(FittingWidget, self).__init__()
31
32        self.model_is_loaded = False
33        self._data = data
34        self.is2D = False
35        self.modelHasShells = False
36
37        self.setupUi(self)
38
39        self.setWindowTitle("Fitting")
40
41        # set the main models
42        self._model_model = QtGui.QStandardItemModel()
43        self._poly_model = QtGui.QStandardItemModel()
44        self._magnet_model = QtGui.QStandardItemModel()
45
46        # Param model displayed in param list
47        self.lstParams.setModel(self._model_model)
48        self._readCategoryInfo()
49        self.model_parameters = None
50
51        # Poly model displayed in poly list
52        self.lstPoly.setModel(self._poly_model)
53        self.setPolyModel()
54        self.setTableProperties(self.lstPoly)
55
56        # Magnetism model displayed in magnetism list
57        self.lstMagnetic.setModel(self._magnet_model)
58        self.setMagneticModel()
59        self.setTableProperties(self.lstMagnetic)
60
61        # Fill in the combo boxes
62        structure_factor_list = self.master_category_dict.pop('Structure Factor')
63        for (structure_factor, enabled) in structure_factor_list:
64            self.cbStructureFactor.addItem(structure_factor)
65
66        category_list = sorted(self.master_category_dict.keys())
67        self.cbCategory.addItems(category_list)
68
69        category = self.cbCategory.currentText()
70        model_list = self.master_category_dict[str(category)]
71        for (model, enabled) in model_list:
72            self.cbModel.addItem(model)
73
74        # Connect GUI element signals
75        self.cbStructureFactor.currentIndexChanged.connect(self.selectStructureFactor)
76        self.cbCategory.currentIndexChanged.connect(self.selectCategory)
77        self.cbModel.currentIndexChanged.connect(self.selectModel)
78        self.chk2DView.toggled.connect(self.toggle2D)
79        self.chkPolydispersity.toggled.connect(self.togglePoly)
80        self.chkMagnetism.toggled.connect(self.toggleMagnetism)
81
82        # Set initial control enablement
83        self.cmdFit.setEnabled(False)
84        self.cmdPlot.setEnabled(True)
85        self.chkPolydispersity.setEnabled(True)
86        self.chkPolydispersity.setCheckState(False)
87        self.chk2DView.setEnabled(True)
88        self.chk2DView.setCheckState(False)
89        self.chkMagnetism.setEnabled(False)
90        self.chkMagnetism.setCheckState(False)
91
92        self.tabFitting.setTabEnabled(TAB_POLY, False)
93        self.tabFitting.setTabEnabled(TAB_MAGNETISM, False)
94
95        # set initial labels
96        self.lblMinRangeDef.setText("---")
97        self.lblMaxRangeDef.setText("---")
98        self.lblChi2Value.setText("---")
99
100    @property
101    def data(self):
102        return self._data
103
104    @data.setter
105    def data(self, value):
106        """ data setter """
107        self._data = value
108        # TODO: update ranges, chi2 etc
109
110    def selectCategory(self):
111        """
112        Select Category from list
113        :return:
114        """
115        self.cbModel.clear()
116        category = self.cbCategory.currentText()
117        model_list = self.master_category_dict[str(category)]
118        for (model, enabled) in model_list:
119            self.cbModel.addItem(model)
120
121    def selectModel(self):
122        """
123        Select Model from list
124        :return:
125        """
126        model = self.cbModel.currentText()
127        self.setModelModel(model)
128
129    def selectStructureFactor(self):
130        """
131        Select Structure Factor from list
132        :param:
133        :return:
134        """
135
136    def _readCategoryInfo(self):
137        """
138        Reads the categories in from file
139        """
140        self.master_category_dict = defaultdict(list)
141        self.by_model_dict = defaultdict(list)
142        self.model_enabled_dict = defaultdict(bool)
143
144        try:
145            categorization_file = CategoryInstaller.get_user_file()
146            if not os.path.isfile(categorization_file):
147                categorization_file = CategoryInstaller.get_default_file()
148            cat_file = open(categorization_file, 'rb')
149            self.master_category_dict = json.load(cat_file)
150            self._regenerate_model_dict()
151            cat_file.close()
152        except IOError:
153            raise
154            print 'Problem reading in category file.'
155            print 'We even looked for it, made sure it was there.'
156            print 'An existential crisis if there ever was one.'
157
158    def _regenerate_model_dict(self):
159        """
160        regenerates self.by_model_dict which has each model name as the
161        key and the list of categories belonging to that model
162        along with the enabled mapping
163        """
164        self.by_model_dict = defaultdict(list)
165        for category in self.master_category_dict:
166            for (model, enabled) in self.master_category_dict[category]:
167                self.by_model_dict[model].append(category)
168                self.model_enabled_dict[model] = enabled
169
170       
171    def setModelModel(self, model_name):
172        """
173        Setting model parameters into table based on selected
174        :param model_name:
175        :return:
176        """
177        # Crete/overwrite model items
178        self._model_model.clear()
179        model_name = str(model_name)
180        kernel_module = generate.load_kernel_module(model_name)
181        self.model_parameters = modelinfo.make_parameter_table(getattr(kernel_module, 'parameters', []))
182
183        #TODO: scaale and background are implicit in sasmodels and needs to be added
184        item1 = QtGui.QStandardItem('scale')
185        item1.setCheckable(True)
186        item2 = QtGui.QStandardItem('1.0')
187        item3 = QtGui.QStandardItem('0.0')
188        item4 = QtGui.QStandardItem('inf')
189        item5 = QtGui.QStandardItem('')
190        self._model_model.appendRow([item1, item2, item3, item4, item5])
191
192        item1 = QtGui.QStandardItem('background')
193        item1.setCheckable(True)
194        item2 = QtGui.QStandardItem('0.001')
195        item3 = QtGui.QStandardItem('-inf')
196        item4 = QtGui.QStandardItem('inf')
197        item5 = QtGui.QStandardItem('1/cm')
198        self._model_model.appendRow([item1, item2, item3, item4, item5])
199
200        #TODO: iq_parameters are used here. If orientation paramateres or magnetic are needed kernel_paramters should be used instead
201        #For orientation and magentic parameters param.type needs to be checked
202        for param in self.model_parameters.iq_parameters:
203            item1 = QtGui.QStandardItem(param.name)
204            item1.setCheckable(True)
205            item2 = QtGui.QStandardItem(str(param.default))
206            item3 = QtGui.QStandardItem(str(param.limits[0]))
207            item4 = QtGui.QStandardItem(str(param.limits[1]))
208            item5 = QtGui.QStandardItem(param.units)
209            self._model_model.appendRow([item1, item2, item3, item4, item5])
210
211        self._model_model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
212        self._model_model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("Value"))
213        self._model_model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
214        self._model_model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
215        self._model_model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("[Units]"))
216
217        self.modelHasShells = True # Test
218        if self.modelHasShells:
219            self.addExtraShells()
220
221        self.setPolyModel()
222        self.setMagneticModel()
223        self.model_is_loaded = True
224
225    def setTableProperties(self, table):
226        """
227        Setting table properties
228        :param table:
229        :return:
230        """
231        # Table properties
232        table.verticalHeader().setVisible(False)
233        table.setAlternatingRowColors(True)
234        table.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding)
235        table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
236        # Header
237        header = table.horizontalHeader()
238        header.setResizeMode(QtGui.QHeaderView.Stretch)
239        header.setStretchLastSection(True)
240
241    def setPolyModel(self):
242        """
243        Set polydispersity values
244        """
245        if self.model_parameters:
246            for row, param in enumerate(self.model_parameters.form_volume_parameters):
247                item1 = QtGui.QStandardItem("Distribution of "+param.name)
248                item1.setCheckable(True)
249                item2 = QtGui.QStandardItem("0")
250                item3 = QtGui.QStandardItem("")
251                item4 = QtGui.QStandardItem("")
252                item5 = QtGui.QStandardItem("35")
253                item6 = QtGui.QStandardItem("3")
254                item7 = QtGui.QStandardItem("")
255
256                self._poly_model.appendRow([item1, item2, item3, item4, item5, item6, item7])
257
258                #TODO: Need to find cleaner way to input functions
259                func = QtGui.QComboBox()
260                func.addItems(['rectangle','array','lognormal','gaussian','schulz',])
261                func_index = self.lstPoly.model().index(row,6)
262                self.lstPoly.setIndexWidget(func_index,func)
263
264        self._poly_model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
265        self._poly_model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("PD[ratio]"))
266        self._poly_model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
267        self._poly_model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
268        self._poly_model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("Npts"))
269        self._poly_model.setHeaderData(5, QtCore.Qt.Horizontal, QtCore.QVariant("Nsigs"))
270        self._poly_model.setHeaderData(6, QtCore.Qt.Horizontal, QtCore.QVariant("Function"))
271
272        self.lstPoly.resizeColumnsToContents()
273        header = self.lstPoly.horizontalHeader()
274        header.ResizeMode(QtGui.QHeaderView.Stretch)
275        #header.setStretchLastSection(True)
276
277    def setMagneticModel(self):
278        """
279        Set magnetism values on model
280        """
281        if self.model_parameters:
282            for row, param in enumerate(self.model_parameters.form_volume_parameters):
283                item1 = QtGui.QStandardItem("Distribution of "+param.name)
284                item1.setCheckable(True)
285                item2 = QtGui.QStandardItem("0")
286                item3 = QtGui.QStandardItem("")
287                item4 = QtGui.QStandardItem("")
288                item5 = QtGui.QStandardItem("35")
289                item6 = QtGui.QStandardItem("3")
290                item7 = QtGui.QStandardItem("")
291
292                self._magnet_model.appendRow([item1, item2, item3, item4, item5, item6, item7])
293
294                #TODO: Need to find cleaner way to input functions
295                func = QtGui.QComboBox()
296                func.addItems(['rectangle','array','lognormal','gaussian','schulz',])
297                func_index = self.lstMagnetic.model().index(row,6)
298                self.lstMagnetic.setIndexWidget(func_index,func)
299
300        self._magnet_model.setHeaderData(0, QtCore.Qt.Horizontal, QtCore.QVariant("Parameter"))
301        self._magnet_model.setHeaderData(1, QtCore.Qt.Horizontal, QtCore.QVariant("PD[ratio]"))
302        self._magnet_model.setHeaderData(2, QtCore.Qt.Horizontal, QtCore.QVariant("Min"))
303        self._magnet_model.setHeaderData(3, QtCore.Qt.Horizontal, QtCore.QVariant("Max"))
304        self._magnet_model.setHeaderData(4, QtCore.Qt.Horizontal, QtCore.QVariant("Npts"))
305        self._magnet_model.setHeaderData(5, QtCore.Qt.Horizontal, QtCore.QVariant("Nsigs"))
306        self._magnet_model.setHeaderData(6, QtCore.Qt.Horizontal, QtCore.QVariant("Function"))
307
308        self.lstMagnetic.resizeColumnsToContents()
309        header = self.lstMagnetic.horizontalHeader()
310        header.ResizeMode(QtGui.QHeaderView.Stretch)
311        header.setStretchLastSection(True)
312
313    def addExtraShells(self):
314        """
315        """
316        func = QtGui.QComboBox()
317        func.addItems(['No extra shell','Add 1 shell','Ad 2 shells'])
318
319        item = QtGui.QStandardItem("")
320        self._model_model.appendRow([item])
321
322        shell_row = self._model_model.rowCount()
323        shell_index = self._model_model.index(shell_row-1, 0)
324        self.lstParams.setIndexWidget(shell_index, func)
325        self.lstParams.setSpan(shell_row-1,1,1,4)
326
327    def togglePoly(self, isChecked):
328        """
329        """
330        self.tabFitting.setTabEnabled(TAB_POLY, isChecked)
331
332    def toggleMagnetism(self, isChecked):
333        """
334        """
335        self.tabFitting.setTabEnabled(TAB_MAGNETISM, isChecked)
336
337    def toggle2D(self, isChecked):
338        """
339        """
340        self.chkMagnetism.setEnabled(isChecked)
341        self.is2D = isChecked
342
343if __name__ == "__main__":
344    app = QtGui.QApplication([])
345    dlg = FittingWidget()
346    dlg.show()
347    sys.exit(app.exec_())
Note: See TracBrowser for help on using the repository browser.