Ignore:
Timestamp:
Nov 29, 2017 6:57:29 AM (6 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:
6b0c2f6
Parents:
19fce84
Message:

Initial commit for constrained & simultaneous fitting functionality SASVIEW-277

File:
1 edited

Legend:

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

    r0261bc1 r378e808  
    182182        # Batch/single fitting 
    183183        self.is_batch_fitting = False 
     184        self.is_chain_fitting = False 
    184185        # Current SasModel in view 
    185186        self.kernel_module = None 
     
    305306        self.lstParams.setStyleSheet(stylesheet) 
    306307        self.lstParams.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
    307         self.lstParams.customContextMenuRequested.connect(self.showModelDescription) 
     308        self.lstParams.customContextMenuRequested.connect(self.showModelContextMenu) 
    308309        self.lstParams.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False) 
    309310        # Poly model displayed in poly list 
     
    354355                self.cbFileNames.addItem(filename) 
    355356            self.cbFileNames.setVisible(True) 
     357            self.chkChainFit.setEnabled(True) 
     358            self.chkChainFit.setVisible(True) 
    356359            # This panel is not designed to view individual fits, so disable plotting 
    357360            self.cmdPlot.setVisible(False) 
     
    393396        """ Enable/disable the magnetism tab """ 
    394397        self.tabFitting.setTabEnabled(TAB_MAGNETISM, isChecked) 
     398 
     399    def toggleChainFit(self, isChecked): 
     400        """ Enable/disable chain fitting """ 
     401        self.is_chain_fitting = isChecked 
    395402 
    396403    def toggle2D(self, isChecked): 
     
    416423        self.chkMagnetism.setEnabled(False) 
    417424        self.chkMagnetism.setCheckState(False) 
     425        self.chkChainFit.setEnabled(False) 
     426        self.chkChainFit.setVisible(False) 
    418427        # Tabs 
    419428        self.tabFitting.setTabEnabled(TAB_POLY, False) 
     
    438447        self.chkPolydispersity.toggled.connect(self.togglePoly) 
    439448        self.chkMagnetism.toggled.connect(self.toggleMagnetism) 
     449        self.chkChainFit.toggled.connect(self.toggleChainFit) 
    440450        # Buttons 
    441451        self.cmdFit.clicked.connect(self.onFit) 
     
    452462        self.options_widget.plot_signal.connect(self.onOptionsUpdate) 
    453463 
    454     def showModelDescription(self, position): 
    455         """ 
    456         Shows a window with model description, when right clicked in the treeview 
     464    def showModelContextMenu(self, position): 
     465 
     466        rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()]) 
     467        menu = self.showModelDescription() if not rows else self.modelContextMenu(rows) 
     468        try: 
     469            menu.exec_(self.lstParams.viewport().mapToGlobal(position)) 
     470        except AttributeError as ex: 
     471            logging.error("Error generating context menu: %s" % ex) 
     472        return 
     473 
     474    def modelContextMenu(self, rows): 
     475        menu = QtWidgets.QMenu() 
     476 
     477        # Select for fitting 
     478        self.actionSelect = QtWidgets.QAction(self) 
     479        self.actionSelect.setObjectName("actionSelect") 
     480        self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select parameter for fitting")) 
     481        # Unselect from fitting 
     482        self.actionDeselect = QtWidgets.QAction(self) 
     483        self.actionDeselect.setObjectName("actionDeselect") 
     484        self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select parameter from fitting")) 
     485 
     486        self.actionConstrain = QtWidgets.QAction(self) 
     487        self.actionConstrain.setObjectName("actionConstrain") 
     488        self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain parameter to current value")) 
     489 
     490        self.actionMultiConstrain = QtWidgets.QAction(self) 
     491        self.actionMultiConstrain.setObjectName("actionMultiConstrain") 
     492        self.actionMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain selected parameters to their current values")) 
     493 
     494        self.actionMutualMultiConstrain = QtWidgets.QAction(self) 
     495        self.actionMutualMultiConstrain.setObjectName("actionMutualMultiConstrain") 
     496        self.actionMutualMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Mutual constrain of selected parameters...")) 
     497 
     498        #action.setDefaultWidget(label) 
     499        menu.addAction(self.actionSelect) 
     500        menu.addAction(self.actionDeselect) 
     501        menu.addSeparator() 
     502 
     503        if rows == 1: 
     504            menu.addAction(self.actionConstrain) 
     505        elif rows == 2: 
     506            menu.addAction(self.actionMultiConstrain) 
     507            menu.addAction(self.actionMutualMultiConstrain) 
     508        elif rows > 2: 
     509            menu.addAction(self.actionMultiConstrain) 
     510 
     511        # Define the callbacks 
     512        self.actionConstrain.triggered.connect(self.addConstraint) 
     513        self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstrain) 
     514        self.actionSelect.triggered.connect(self.selectParameters) 
     515        self.actionDeselect.triggered.connect(self.deselectParameters) 
     516        return menu 
     517 
     518    def showMultiConstrain(self): 
     519        """ 
     520        Show the constraint widget and receive the expression 
     521        """ 
     522        from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint 
     523        params_list = [s.data() for s in self.lstParams.selectionModel().selectedRows()] 
     524        mc_widget = MultiConstraint(self, params=params_list) 
     525        mc_widget.exec_() 
     526        constraint = mc_widget.txtConstraint.text() 
     527        # Pass the constraint to the parser 
     528        self.communicate.statusBarUpdateSignal.emit('Constraints added') 
     529        pass 
     530 
     531    def addConstraint(self): 
     532        """ 
     533        Adds a constraint on a single parameter. 
     534        """ 
     535        self.communicate.statusBarUpdateSignal.emit('Constraint added') 
     536        pass 
     537 
     538    def selectParameters(self): 
     539        """ 
     540        Selected parameters are chosen for fitting 
     541        """ 
     542        status = QtCore.Qt.Checked 
     543        self.setParameterSelection(status) 
     544 
     545    def deselectParameters(self): 
     546        """ 
     547        Selected parameters are removed for fitting 
     548        """ 
     549        status = QtCore.Qt.Unchecked 
     550        self.setParameterSelection(status) 
     551 
     552    def selectedParameters(self): 
     553        """ Returns list of selected (highlighted) parameters """ 
     554        return [s.row() for s in self.lstParams.selectionModel().selectedRows() if self.isCheckable(s.row())] 
     555 
     556    def setParameterSelection(self, status=QtCore.Qt.Unchecked): 
     557        """ 
     558        Selected parameters are chosen for fitting 
     559        """ 
     560        # Convert to proper indices and set requested enablement 
     561        for row in self.selectedParameters(): 
     562            self._model_model.item(row, 0).setCheckState(status) 
     563        pass 
     564 
     565    def showModelDescription(self): 
     566        """ 
     567        Creates a window with model description, when right clicked in the treeview 
    457568        """ 
    458569        msg = 'Model description:\n' 
     
    470581        action.setDefaultWidget(label) 
    471582        menu.addAction(action) 
    472         menu.exec_(self.lstParams.viewport().mapToGlobal(position)) 
     583        return menu 
    473584 
    474585    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.