Changeset 378e808 in sasview for src/sas


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

Initial commit for constrained & simultaneous fitting functionality SASVIEW-277

Location:
src/sas/qtgui/Perspectives/Fitting
Files:
2 added
2 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 
  • src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui

    rd1955d67 r378e808  
    77    <x>0</x> 
    88    <y>0</y> 
    9     <width>434</width> 
    10     <height>466</height> 
     9    <width>448</width> 
     10    <height>526</height> 
    1111   </rect> 
    1212  </property> 
     
    2626   <string>FittingWidget</string> 
    2727  </property> 
    28   <layout class="QGridLayout" name="gridLayout_4"> 
    29    <item row="0" column="0" colspan="4"> 
     28  <layout class="QGridLayout" name="gridLayout_5"> 
     29   <item row="0" column="0"> 
    3030    <layout class="QHBoxLayout" name="horizontalLayout"> 
    3131     <item> 
     
    7272    </layout> 
    7373   </item> 
    74    <item row="1" column="0" colspan="4"> 
     74   <item row="1" column="0"> 
    7575    <widget class="QTabWidget" name="tabFitting"> 
    7676     <property name="currentIndex"> 
     
    8181       <string>Model</string> 
    8282      </attribute> 
    83       <layout class="QGridLayout" name="gridLayout_19"> 
     83      <layout class="QGridLayout" name="gridLayout_4"> 
    8484       <item row="0" column="0" colspan="4"> 
    8585        <widget class="QGroupBox" name="groupBox_6"> 
     
    161161          <string>Options </string> 
    162162         </property> 
    163          <layout class="QGridLayout" name="gridLayout_16"> 
    164           <item row="0" column="0"> 
     163         <layout class="QVBoxLayout" name="verticalLayout"> 
     164          <item> 
    165165           <widget class="QCheckBox" name="chkPolydispersity"> 
    166166            <property name="enabled"> 
     
    178178           </widget> 
    179179          </item> 
    180           <item row="1" column="0"> 
     180          <item> 
    181181           <widget class="QCheckBox" name="chk2DView"> 
    182182            <property name="enabled"> 
     
    194194           </widget> 
    195195          </item> 
    196           <item row="2" column="0"> 
     196          <item> 
    197197           <widget class="QCheckBox" name="chkMagnetism"> 
    198198            <property name="enabled"> 
     
    204204            <property name="text"> 
    205205             <string>Magnetism</string> 
     206            </property> 
     207            <property name="checkable"> 
     208             <bool>true</bool> 
     209            </property> 
     210           </widget> 
     211          </item> 
     212          <item> 
     213           <widget class="QCheckBox" name="chkChainFit"> 
     214            <property name="enabled"> 
     215             <bool>true</bool> 
     216            </property> 
     217            <property name="toolTip"> 
     218             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Switch on magnetic scattering parameters.&lt;/p&gt;&lt;p&gt;This option is available only for 2D models.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> 
     219            </property> 
     220            <property name="text"> 
     221             <string>Chain fit</string> 
    206222            </property> 
    207223            <property name="checkable"> 
     
    412428   </item> 
    413429   <item row="2" column="0"> 
    414     <spacer name="horizontalSpacer"> 
    415      <property name="orientation"> 
    416       <enum>Qt::Horizontal</enum> 
    417      </property> 
    418      <property name="sizeHint" stdset="0"> 
    419       <size> 
    420        <width>273</width> 
    421        <height>20</height> 
    422       </size> 
    423      </property> 
    424     </spacer> 
    425    </item> 
    426    <item row="2" column="1"> 
    427     <widget class="QPushButton" name="cmdPlot"> 
    428      <property name="sizePolicy"> 
    429       <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 
    430        <horstretch>0</horstretch> 
    431        <verstretch>0</verstretch> 
    432       </sizepolicy> 
    433      </property> 
    434      <property name="minimumSize"> 
    435       <size> 
    436        <width>75</width> 
    437        <height>23</height> 
    438       </size> 
    439      </property> 
    440      <property name="text"> 
    441       <string>Show Plot</string> 
    442      </property> 
    443     </widget> 
    444    </item> 
    445    <item row="2" column="2"> 
    446     <widget class="QPushButton" name="cmdFit"> 
    447      <property name="sizePolicy"> 
    448       <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 
    449        <horstretch>0</horstretch> 
    450        <verstretch>0</verstretch> 
    451       </sizepolicy> 
    452      </property> 
    453      <property name="minimumSize"> 
    454       <size> 
    455        <width>75</width> 
    456        <height>23</height> 
    457       </size> 
    458      </property> 
    459      <property name="text"> 
    460       <string>Fit</string> 
    461      </property> 
    462     </widget> 
    463    </item> 
    464    <item row="2" column="3"> 
    465     <widget class="QPushButton" name="cmdHelp"> 
    466      <property name="sizePolicy"> 
    467       <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 
    468        <horstretch>0</horstretch> 
    469        <verstretch>0</verstretch> 
    470       </sizepolicy> 
    471      </property> 
    472      <property name="minimumSize"> 
    473       <size> 
    474        <width>75</width> 
    475        <height>23</height> 
    476       </size> 
    477      </property> 
    478      <property name="text"> 
    479       <string>Help</string> 
    480      </property> 
    481     </widget> 
     430    <layout class="QHBoxLayout" name="horizontalLayout_3"> 
     431     <item> 
     432      <spacer name="horizontalSpacer"> 
     433       <property name="orientation"> 
     434        <enum>Qt::Horizontal</enum> 
     435       </property> 
     436       <property name="sizeHint" stdset="0"> 
     437        <size> 
     438         <width>273</width> 
     439         <height>20</height> 
     440        </size> 
     441       </property> 
     442      </spacer> 
     443     </item> 
     444     <item> 
     445      <widget class="QPushButton" name="cmdPlot"> 
     446       <property name="sizePolicy"> 
     447        <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 
     448         <horstretch>0</horstretch> 
     449         <verstretch>0</verstretch> 
     450        </sizepolicy> 
     451       </property> 
     452       <property name="minimumSize"> 
     453        <size> 
     454         <width>75</width> 
     455         <height>23</height> 
     456        </size> 
     457       </property> 
     458       <property name="text"> 
     459        <string>Show Plot</string> 
     460       </property> 
     461      </widget> 
     462     </item> 
     463     <item> 
     464      <widget class="QPushButton" name="cmdFit"> 
     465       <property name="sizePolicy"> 
     466        <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 
     467         <horstretch>0</horstretch> 
     468         <verstretch>0</verstretch> 
     469        </sizepolicy> 
     470       </property> 
     471       <property name="minimumSize"> 
     472        <size> 
     473         <width>75</width> 
     474         <height>23</height> 
     475        </size> 
     476       </property> 
     477       <property name="text"> 
     478        <string>Fit</string> 
     479       </property> 
     480      </widget> 
     481     </item> 
     482     <item> 
     483      <widget class="QPushButton" name="cmdHelp"> 
     484       <property name="sizePolicy"> 
     485        <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> 
     486         <horstretch>0</horstretch> 
     487         <verstretch>0</verstretch> 
     488        </sizepolicy> 
     489       </property> 
     490       <property name="minimumSize"> 
     491        <size> 
     492         <width>75</width> 
     493         <height>23</height> 
     494        </size> 
     495       </property> 
     496       <property name="text"> 
     497        <string>Help</string> 
     498       </property> 
     499      </widget> 
     500     </item> 
     501    </layout> 
    482502   </item> 
    483503  </layout> 
Note: See TracChangeset for help on using the changeset viewer.