Ignore:
Timestamp:
Jan 10, 2018 5:13:56 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
0595bb7
Parents:
e90988c
git-author:
Piotr Rozyczko <rozyczko@…> (11/29/17 08:57:29)
git-committer:
Piotr Rozyczko <rozyczko@…> (01/10/18 05:13:56)
Message:

Initial commit for constrained & simultaneous fitting functionality SASVIEW-277

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    re90988c r7fd20fc  
    178178        # Batch/single fitting 
    179179        self.is_batch_fitting = False 
     180        self.is_chain_fitting = False 
    180181        # Current SasModel in view 
    181182        self.kernel_module = None 
     
    301302        self.lstParams.setStyleSheet(stylesheet) 
    302303        self.lstParams.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
    303         self.lstParams.customContextMenuRequested.connect(self.showModelDescription) 
     304        self.lstParams.customContextMenuRequested.connect(self.showModelContextMenu) 
    304305        self.lstParams.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False) 
    305306        # Poly model displayed in poly list 
     
    350351                self.cbFileNames.addItem(filename) 
    351352            self.cbFileNames.setVisible(True) 
     353            self.chkChainFit.setEnabled(True) 
     354            self.chkChainFit.setVisible(True) 
    352355            # This panel is not designed to view individual fits, so disable plotting 
    353356            self.cmdPlot.setVisible(False) 
     
    389392        """ Enable/disable the magnetism tab """ 
    390393        self.tabFitting.setTabEnabled(TAB_MAGNETISM, isChecked) 
     394 
     395    def toggleChainFit(self, isChecked): 
     396        """ Enable/disable chain fitting """ 
     397        self.is_chain_fitting = isChecked 
    391398 
    392399    def toggle2D(self, isChecked): 
     
    412419        self.chkMagnetism.setEnabled(False) 
    413420        self.chkMagnetism.setCheckState(False) 
     421        self.chkChainFit.setEnabled(False) 
     422        self.chkChainFit.setVisible(False) 
    414423        # Tabs 
    415424        self.tabFitting.setTabEnabled(TAB_POLY, False) 
     
    434443        self.chkPolydispersity.toggled.connect(self.togglePoly) 
    435444        self.chkMagnetism.toggled.connect(self.toggleMagnetism) 
     445        self.chkChainFit.toggled.connect(self.toggleChainFit) 
    436446        # Buttons 
    437447        self.cmdFit.clicked.connect(self.onFit) 
     
    448458        self.options_widget.plot_signal.connect(self.onOptionsUpdate) 
    449459 
    450     def showModelDescription(self, position): 
    451         """ 
    452         Shows a window with model description, when right clicked in the treeview 
     460    def showModelContextMenu(self, position): 
     461 
     462        rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()]) 
     463        menu = self.showModelDescription() if not rows else self.modelContextMenu(rows) 
     464        try: 
     465            menu.exec_(self.lstParams.viewport().mapToGlobal(position)) 
     466        except AttributeError as ex: 
     467            logging.error("Error generating context menu: %s" % ex) 
     468        return 
     469 
     470    def modelContextMenu(self, rows): 
     471        menu = QtWidgets.QMenu() 
     472 
     473        # Select for fitting 
     474        self.actionSelect = QtWidgets.QAction(self) 
     475        self.actionSelect.setObjectName("actionSelect") 
     476        self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select parameter for fitting")) 
     477        # Unselect from fitting 
     478        self.actionDeselect = QtWidgets.QAction(self) 
     479        self.actionDeselect.setObjectName("actionDeselect") 
     480        self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select parameter from fitting")) 
     481 
     482        self.actionConstrain = QtWidgets.QAction(self) 
     483        self.actionConstrain.setObjectName("actionConstrain") 
     484        self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain parameter to current value")) 
     485 
     486        self.actionMultiConstrain = QtWidgets.QAction(self) 
     487        self.actionMultiConstrain.setObjectName("actionMultiConstrain") 
     488        self.actionMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain selected parameters to their current values")) 
     489 
     490        self.actionMutualMultiConstrain = QtWidgets.QAction(self) 
     491        self.actionMutualMultiConstrain.setObjectName("actionMutualMultiConstrain") 
     492        self.actionMutualMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Mutual constrain of selected parameters...")) 
     493 
     494        #action.setDefaultWidget(label) 
     495        menu.addAction(self.actionSelect) 
     496        menu.addAction(self.actionDeselect) 
     497        menu.addSeparator() 
     498 
     499        if rows == 1: 
     500            menu.addAction(self.actionConstrain) 
     501        elif rows == 2: 
     502            menu.addAction(self.actionMultiConstrain) 
     503            menu.addAction(self.actionMutualMultiConstrain) 
     504        elif rows > 2: 
     505            menu.addAction(self.actionMultiConstrain) 
     506 
     507        # Define the callbacks 
     508        self.actionConstrain.triggered.connect(self.addConstraint) 
     509        self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstrain) 
     510        self.actionSelect.triggered.connect(self.selectParameters) 
     511        self.actionDeselect.triggered.connect(self.deselectParameters) 
     512        return menu 
     513 
     514    def showMultiConstrain(self): 
     515        """ 
     516        Show the constraint widget and receive the expression 
     517        """ 
     518        from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint 
     519        params_list = [s.data() for s in self.lstParams.selectionModel().selectedRows()] 
     520        mc_widget = MultiConstraint(self, params=params_list) 
     521        mc_widget.exec_() 
     522        constraint = mc_widget.txtConstraint.text() 
     523        # Pass the constraint to the parser 
     524        self.communicate.statusBarUpdateSignal.emit('Constraints added') 
     525        pass 
     526 
     527    def addConstraint(self): 
     528        """ 
     529        Adds a constraint on a single parameter. 
     530        """ 
     531        self.communicate.statusBarUpdateSignal.emit('Constraint added') 
     532        pass 
     533 
     534    def selectParameters(self): 
     535        """ 
     536        Selected parameters are chosen for fitting 
     537        """ 
     538        status = QtCore.Qt.Checked 
     539        self.setParameterSelection(status) 
     540 
     541    def deselectParameters(self): 
     542        """ 
     543        Selected parameters are removed for fitting 
     544        """ 
     545        status = QtCore.Qt.Unchecked 
     546        self.setParameterSelection(status) 
     547 
     548    def selectedParameters(self): 
     549        """ Returns list of selected (highlighted) parameters """ 
     550        return [s.row() for s in self.lstParams.selectionModel().selectedRows() if self.isCheckable(s.row())] 
     551 
     552    def setParameterSelection(self, status=QtCore.Qt.Unchecked): 
     553        """ 
     554        Selected parameters are chosen for fitting 
     555        """ 
     556        # Convert to proper indices and set requested enablement 
     557        for row in self.selectedParameters(): 
     558            self._model_model.item(row, 0).setCheckState(status) 
     559        pass 
     560 
     561    def showModelDescription(self): 
     562        """ 
     563        Creates a window with model description, when right clicked in the treeview 
    453564        """ 
    454565        msg = 'Model description:\n' 
     
    466577        action.setDefaultWidget(label) 
    467578        menu.addAction(action) 
    468         menu.exec_(self.lstParams.viewport().mapToGlobal(position)) 
     579        return menu 
    469580 
    470581    def onSelectModel(self): 
     
    13441455        self.updateUndo() 
    13451456 
     1457    def isCheckable(self, row): 
     1458        return self._model_model.item(row, 0).isCheckable() 
     1459 
    13461460    def checkboxSelected(self, item): 
    13471461        # Assure we're dealing with checkboxes 
     
    13501464        status = item.checkState() 
    13511465 
    1352         def isCheckable(row): 
    1353             return self._model_model.item(row, 0).isCheckable() 
    1354  
    13551466        # If multiple rows selected - toggle all of them, filtering uncheckable 
    1356         rows = [s.row() for s in self.lstParams.selectionModel().selectedRows() if isCheckable(s.row())] 
    1357  
    13581467        # Switch off signaling from the model to avoid recursion 
    13591468        self._model_model.blockSignals(True) 
    13601469        # Convert to proper indices and set requested enablement 
    1361         [self._model_model.item(row, 0).setCheckState(status) for row in rows] 
     1470        self.setParameterSelection(status) 
     1471        #[self._model_model.item(row, 0).setCheckState(status) for row in self.selectedParameters()] 
    13621472        self._model_model.blockSignals(False) 
    13631473 
Note: See TracChangeset for help on using the changeset viewer.