Ignore:
Timestamp:
Jan 9, 2018 3:44:55 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:
a3c94b54
Parents:
6b0c2f6
Message:

More functionality for single model constraints SASVIEW-843

File:
1 edited

Legend:

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

    r6b0c2f6 r2109350  
    4545from sas.qtgui.Perspectives.Fitting.ViewDelegate import PolyViewDelegate 
    4646from sas.qtgui.Perspectives.Fitting.ViewDelegate import MagnetismViewDelegate 
     47from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     48from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint 
    4749 
    4850 
     
    8486    Main widget for selecting form and structure factor models 
    8587    """ 
    86     constraintAddedSignal = QtCore.pyqtSignal(list) 
     88    #constraintAddedSignal = QtCore.pyqtSignal(list) 
    8789    def __init__(self, parent=None, data=None, tab_id=1): 
    8890 
     
    457459        # Respond to change in parameters from the UI 
    458460        self._model_model.itemChanged.connect(self.onMainParamsChange) 
    459         self.constraintAddedSignal.connect(self.modifyViewOnConstraint) 
     461        #self.constraintAddedSignal.connect(self.modifyViewOnConstraint) 
    460462        self._poly_model.itemChanged.connect(self.onPolyModelChange) 
    461463        self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 
     
    466468    def showModelContextMenu(self, position): 
    467469 
    468         rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()]) 
     470        #rows = len([s.row() for s in self.lstParams.selectionModel().selectedRows()]) 
     471        rows = [s.row() for s in self.lstParams.selectionModel().selectedRows()] 
    469472        menu = self.showModelDescription() if not rows else self.modelContextMenu(rows) 
    470473        try: 
     
    475478 
    476479    def modelContextMenu(self, rows): 
     480        """ 
     481        Create context menu for the given model 
     482        """ 
    477483        menu = QtWidgets.QMenu() 
    478  
     484        num_rows = len(rows) 
    479485        # Select for fitting 
     486        param_string = "parameter " if num_rows==1 else "parameters " 
     487        to_string = "to its current value" if num_rows==1 else "to their current values" 
     488 
    480489        self.actionSelect = QtWidgets.QAction(self) 
    481490        self.actionSelect.setObjectName("actionSelect") 
    482         self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select parameter for fitting")) 
     491        self.actionSelect.setText(QtCore.QCoreApplication.translate("self", "Select "+param_string+" for fitting")) 
    483492        # Unselect from fitting 
    484493        self.actionDeselect = QtWidgets.QAction(self) 
    485494        self.actionDeselect.setObjectName("actionDeselect") 
    486         self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select parameter from fitting")) 
     495        self.actionDeselect.setText(QtCore.QCoreApplication.translate("self", "De-select "+param_string+" from fitting")) 
    487496 
    488497        self.actionConstrain = QtWidgets.QAction(self) 
    489498        self.actionConstrain.setObjectName("actionConstrain") 
    490         self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain parameter to current value")) 
     499        self.actionConstrain.setText(QtCore.QCoreApplication.translate("self", "Constrain "+param_string + to_string)) 
     500 
     501        self.actionRemoveConstraint = QtWidgets.QAction(self) 
     502        self.actionRemoveConstraint.setObjectName("actionRemoveConstrain") 
     503        self.actionRemoveConstraint.setText(QtCore.QCoreApplication.translate("self", "Remove constraint")) 
    491504 
    492505        self.actionMultiConstrain = QtWidgets.QAction(self) 
     
    498511        self.actionMutualMultiConstrain.setText(QtCore.QCoreApplication.translate("self", "Mutual constrain of selected parameters...")) 
    499512 
    500         #action.setDefaultWidget(label) 
    501513        menu.addAction(self.actionSelect) 
    502514        menu.addAction(self.actionDeselect) 
    503515        menu.addSeparator() 
    504516 
    505         if rows == 1: 
     517        if self.rowHasConstraint(rows[0]): 
     518            menu.addAction(self.actionRemoveConstraint) 
     519        else: 
    506520            menu.addAction(self.actionConstrain) 
    507         elif rows == 2: 
    508             menu.addAction(self.actionMultiConstrain) 
     521        if num_rows == 2: 
    509522            menu.addAction(self.actionMutualMultiConstrain) 
    510         elif rows > 2: 
    511             menu.addAction(self.actionMultiConstrain) 
    512523 
    513524        # Define the callbacks 
    514525        self.actionConstrain.triggered.connect(self.addSimpleConstraint) 
     526        self.actionRemoveConstraint.triggered.connect(self.deleteConstraint) 
    515527        self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstraint) 
    516528        self.actionSelect.triggered.connect(self.selectParameters) 
     
    522534        Show the constraint widget and receive the expression 
    523535        """ 
    524         from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint 
    525         from .Constraints import Constraint 
    526536        selected_rows = self.lstParams.selectionModel().selectedRows() 
     537        assert(len(selected_rows), 2) 
    527538 
    528539        params_list = [s.data() for s in selected_rows] 
     540        # Create and display the widget for param1 and param2 
    529541        mc_widget = MultiConstraint(self, params=params_list) 
    530         mc_widget.exec_() 
     542        if mc_widget.exec_() != QtWidgets.QDialog.Accepted: 
     543            return 
     544 
    531545        constraint = Constraint() 
    532546        c_text = mc_widget.txtConstraint.text() 
    533         # Pass the constraint to the parser 
    534  
    535         self.communicate.statusBarUpdateSignal.emit('Constraints added') 
    536         # Change the colour of the row 
    537         pass 
    538  
    539     def modifyViewOnConstraint(self, row): 
    540         """ 
    541         Add visual cues that the parameter is constrained 
    542         """ 
    543         value = self._model_model.item(row, 1).text() 
    544         # Set min/max to the value constrained 
    545         self._model_model.item(row,2).setText(value) 
    546         self._model_model.item(row,3).setText(value) 
     547 
     548        # widget.params[0] is the parameter we're constraining 
     549        constraint.param = mc_widget.params[0] 
     550        constraint.func = c_text 
     551 
     552        # Create a new item and add the Constraint object as a child 
     553        item = QtGui.QStandardItem() 
     554        item.setData(constraint) 
     555        # Which row is the constrained parameter in? 
     556 
     557        row = self.rowFromName(constraint.param) 
     558        self._model_model.item(row, 1).setChild(0, item) 
     559        #self.constraintAddedSignal.emit([row]) 
     560        # Show visual hints for the constraint 
    547561        font = QtGui.QFont() 
    548562        font.setItalic(True) 
    549563        brush = QtGui.QBrush(QtGui.QColor('blue')) 
     564        self.modifyViewOnRow(row, font=font, brush=brush) 
     565 
     566        # Pass the constraint to the parser 
     567        self.communicate.statusBarUpdateSignal.emit('Constraints added') 
     568 
     569    def rowFromName(self, name): 
     570        """ 
     571        given parameter name get the row number in self._model_model 
     572        """ 
     573        for row in range(self._model_model.rowCount()): 
     574            row_name = self._model_model.item(row).text() 
     575            if row_name == name: 
     576                return row 
     577        return None 
     578 
     579    def modifyViewOnRow(self, row, font=None, brush=None): 
     580        """ 
     581        Chage how the given row of the main model is shown 
     582        """ 
     583        fields_enabled = False 
     584        if font is None: 
     585            font = QtGui.QFont() 
     586            fields_enabled = True 
     587        if brush is None: 
     588            brush = QtGui.QBrush() 
     589            fields_enabled = True 
    550590        self._model_model.blockSignals(True) 
    551591        # Modify font and foreground of affected rows 
     
    553593            self._model_model.item(row, column).setForeground(brush) 
    554594            self._model_model.item(row, column).setFont(font) 
    555             self._model_model.item(row, column).setEditable(False) 
     595            self._model_model.item(row, column).setEditable(fields_enabled) 
    556596        self._model_model.blockSignals(False) 
    557597 
     
    560600        Adds a constraint on a single parameter. 
    561601        """ 
    562         from .Constraints import Constraint 
    563602        for row in self.selectedParameters(): 
    564603            param = self._model_model.item(row, 0).text() 
    565604            value = self._model_model.item(row, 1).text() 
    566             constraint = Constraint(param=param, value=value) 
     605            min = self._model_model.item(row, 2).text() 
     606            max = self._model_model.item(row, 3).text() 
     607            # Create a Constraint object 
     608            constraint = Constraint(param=param, value=value, min=min, max=max) 
     609            # Create a new item and add the Constraint object as a child 
    567610            item = QtGui.QStandardItem() 
    568611            item.setData(constraint) 
    569612            self._model_model.item(row, 1).setChild(0, item) 
     613            # Set min/max to the value constrained 
     614            self._model_model.item(row,2).setText(value) 
     615            self._model_model.item(row,3).setText(value) 
    570616            #self.constraintAddedSignal.emit([row]) 
    571             self.modifyViewOnConstraint(row) 
     617            # Show visual hints for the constraint 
     618            font = QtGui.QFont() 
     619            font.setItalic(True) 
     620            brush = QtGui.QBrush(QtGui.QColor('blue')) 
     621            self.modifyViewOnRow(row, font=font, brush=brush) 
    572622        self.communicate.statusBarUpdateSignal.emit('Constraint added') 
    573623        pass 
     624 
     625    def deleteConstraint(self): 
     626        """ 
     627        Delete constraints from selected parameters. 
     628        """ 
     629        for row in self.selectedParameters(): 
     630            # Get the Constraint object from of the model item 
     631            item = self._model_model.item(row, 1) 
     632            constraint = item.child(0).data() 
     633            # Retrieve old values and put them on the model 
     634            if constraint.min is not None: 
     635                self._model_model.item(row, 2).setText(constraint.min) 
     636            if constraint.max is not None: 
     637                self._model_model.item(row, 3).setText(constraint.max) 
     638            # Remove constraint item 
     639            item.removeRow(0) 
     640            #self.constraintAddedSignal.emit([row]) 
     641            self.modifyViewOnRow(row) 
     642        self.communicate.statusBarUpdateSignal.emit('Constraint removed') 
     643        pass 
     644 
     645    def rowHasConstraint(self, row): 
     646        """ 
     647        Finds out if row of the main model has a constraint child 
     648        """ 
     649        item = self._model_model.item(row,1) 
     650        return True if (item.hasChildren() and isinstance(item.child(0).data(), Constraint)) else False 
    574651 
    575652    def selectParameters(self): 
     
    9641041            np.any(res.pvec is None) or \ 
    9651042            not np.all(np.isfinite(res.pvec)): 
    966             msg = "Fitting did not converge!!!" 
     1043            msg = "Fitting did not converge!" 
    9671044            self.communicate.statusBarUpdateSignal.emit(msg) 
    9681045            logging.error(msg) 
Note: See TracChangeset for help on using the changeset viewer.