Ignore:
File:
1 edited

Legend:

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

    rc4c4957 r442a9ae  
    11import logging 
    2 import copy 
    32 
    43from twisted.internet import threads 
     
    2322    Constraints Dialog to select the desired parameter/model constraints. 
    2423    """ 
     24    fitCompleteSignal = QtCore.pyqtSignal(tuple) 
     25    batchCompleteSignal = QtCore.pyqtSignal(tuple) 
     26    fitFailedSignal = QtCore.pyqtSignal(tuple) 
    2527 
    2628    def __init__(self, parent=None): 
     
    3234        # To keep with previous SasView values, use 300 as the start offset 
    3335        self.page_id = 301 
     36        self.tab_id = self.page_id 
    3437 
    3538        # Are we chain fitting? 
     
    6063        Set up various widget states 
    6164        """ 
     65        # disable special cases until properly defined 
     66        self.label.setVisible(False) 
     67        self.cbCases.setVisible(False) 
     68 
    6269        labels = ['FitPage', 'Model', 'Data', 'Mnemonic'] 
    6370        # tab widget - headers 
     
    7986        self.tblConstraints.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) 
    8087        self.tblConstraints.setEnabled(False) 
     88        header = self.tblConstraints.horizontalHeaderItem(0) 
     89        header.setToolTip("Double click a row below to edit the constraint.") 
    8190 
    8291        self.tblConstraints.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
     
    93102        self.cmdFit.clicked.connect(self.onFit) 
    94103        self.cmdHelp.clicked.connect(self.onHelp) 
     104        self.cmdAdd.clicked.connect(self.showMultiConstraint) 
    95105        self.chkChain.toggled.connect(self.onChainFit) 
    96106 
     
    100110        self.tblConstraints.cellChanged.connect(self.onConstraintChange) 
    101111 
     112        # Internal signals 
     113        self.fitCompleteSignal.connect(self.fitComplete) 
     114        self.batchCompleteSignal.connect(self.batchComplete) 
     115        self.fitFailedSignal.connect(self.fitFailed) 
     116 
    102117        # External signals 
    103118        self.parent.tabsModifiedSignal.connect(self.initializeFitList) 
     
    156171        fitter = Fit() 
    157172        fitter.fitter_id = self.page_id 
    158  
    159         # Notify the parent about fitting started 
    160         self.parent.fittingStartedSignal.emit(tabs_to_fit) 
    161173 
    162174        # prepare fitting problems for each tab 
     
    168180        try: 
    169181            for tab in tabs_to_fit: 
     182                if not self.isTabImportable(tab): continue 
    170183                tab_object = ObjectLibrary.getObject(tab) 
    171184                if tab_object is None: 
     
    177190        except ValueError: 
    178191            # No parameters selected in one of the tabs 
    179             no_params_msg = "Fitting can not be performed.\n" +\ 
     192            no_params_msg = "Fitting cannot be performed.\n" +\ 
    180193                            "Not all tabs chosen for fitting have parameters selected for fitting." 
    181194            QtWidgets.QMessageBox.warning(self, 
     
    200213        batch_inputs = {} 
    201214        batch_outputs = {} 
     215 
     216        # Notify the parent about fitting started 
     217        self.parent.fittingStartedSignal.emit(tabs_to_fit) 
    202218 
    203219        # new fit thread object 
     
    223239 
    224240        #disable the Fit button 
     241        self.cmdFit.setStyleSheet('QPushButton {color: red;}') 
    225242        self.cmdFit.setText('Running...') 
    226243        self.parent.communicate.statusBarUpdateSignal.emit('Fitting started...') 
     
    292309        """ 
    293310        item = self.tblConstraints.item(row, column) 
    294         if column == 0: 
    295             # Update the tabs for fitting list 
    296             constraint = self.available_constraints[row] 
    297             constraint.active = (item.checkState() == QtCore.Qt.Checked) 
     311        if column != 0: return 
     312        # Update the tabs for fitting list 
     313        constraint = self.available_constraints[row] 
     314        constraint.active = (item.checkState() == QtCore.Qt.Checked) 
     315        # Update the constraint formula 
     316        constraint = self.available_constraints[row] 
     317        function = item.text() 
     318        # remove anything left of '=' to get the constraint 
     319        function = function[function.index('=')+1:] 
     320        # No check on function here - trust the user (R) 
     321        if function != constraint.func: 
     322            # This becomes rather difficult to validate now. 
     323            # Turn off validation for Edit Constraint 
     324            constraint.func = function 
     325            constraint.validate = False 
    298326 
    299327    def onTabCellEntered(self, row, column): 
     
    308336    def onFitComplete(self, result): 
    309337        """ 
     338        Send the fit complete signal to main thread 
     339        """ 
     340        self.fitCompleteSignal.emit(result) 
     341 
     342    def fitComplete(self, result): 
     343        """ 
    310344        Respond to the successful fit complete signal 
    311345        """ 
    312346        #re-enable the Fit button 
     347        self.cmdFit.setStyleSheet('QPushButton {color: black;}') 
    313348        self.cmdFit.setText("Fit") 
    314349        self.cmdFit.setEnabled(True) 
     
    347382    def onBatchFitComplete(self, result): 
    348383        """ 
     384        Send the fit complete signal to main thread 
     385        """ 
     386        self.batchCompleteSignal.emit(result) 
     387 
     388    def batchComplete(self, result): 
     389        """ 
    349390        Respond to the successful batch fit complete signal 
    350391        """ 
    351392        #re-enable the Fit button 
     393        self.cmdFit.setStyleSheet('QPushButton {color: black;}') 
    352394        self.cmdFit.setText("Fit") 
    353395        self.cmdFit.setEnabled(True) 
     
    365407 
    366408        # Show the grid panel 
    367         page_name = "ConstSimulPage" 
    368         results = copy.deepcopy(result[0]) 
    369         results.append(page_name) 
    370         self.parent.communicate.sendDataToGridSignal.emit(results) 
     409        self.parent.communicate.sendDataToGridSignal.emit(result[0]) 
    371410 
    372411        msg = "Fitting completed successfully in: %s s.\n" % GuiUtils.formatNumber(elapsed) 
     
    375414    def onFitFailed(self, reason): 
    376415        """ 
     416        Send the fit failed signal to main thread 
     417        """ 
     418        self.fitFailedSignal.emit(result) 
     419 
     420    def fitFailed(self, reason): 
     421        """ 
    377422        Respond to fitting failure. 
    378423        """ 
    379424        #re-enable the Fit button 
     425        self.cmdFit.setStyleSheet('QPushButton {color: black;}') 
    380426        self.cmdFit.setText("Fit") 
    381427        self.cmdFit.setEnabled(True) 
     
    386432        msg = "Fitting failed: %s s.\n" % reason 
    387433        self.parent.communicate.statusBarUpdateSignal.emit(msg) 
    388   
     434 
    389435    def isTabImportable(self, tab): 
    390436        """ 
     
    599645            # Show the text in the constraint table 
    600646            item = self.uneditableItem(label) 
     647            item = QtWidgets.QTableWidgetItem(label) 
    601648            item.setFlags(item.flags() ^ QtCore.Qt.ItemIsUserCheckable) 
    602649            item.setCheckState(QtCore.Qt.Checked) 
     
    667714        return None 
    668715 
     716    def onAcceptConstraint(self, con_tuple): 
     717        """ 
     718        Receive constraint tuple from the ComplexConstraint dialog and adds contraint 
     719        """ 
     720        #"M1, M2, M3" etc 
     721        model_name, constraint = con_tuple 
     722        constrained_tab = self.getObjectByName(model_name) 
     723        if constrained_tab is None: 
     724            return 
     725 
     726        # Find the constrained parameter row 
     727        constrained_row = constrained_tab.getRowFromName(constraint.param) 
     728 
     729        # Update the tab 
     730        constrained_tab.addConstraintToRow(constraint, constrained_row) 
     731 
     732        # Select this parameter for adjusting/fitting 
     733        constrained_tab.selectCheckbox(constrained_row) 
     734 
     735 
    669736    def showMultiConstraint(self): 
    670737        """ 
     
    672739        """ 
    673740        selected_rows = self.selectedParameters(self.tblTabList) 
    674         assert(len(selected_rows)==2) 
     741        if len(selected_rows)!=2: 
     742            msg = "Please select two fit pages from the Source Choice table." 
     743            msgbox = QtWidgets.QMessageBox(self.parent) 
     744            msgbox.setIcon(QtWidgets.QMessageBox.Warning) 
     745            msgbox.setText(msg) 
     746            msgbox.setWindowTitle("2 fit page constraints") 
     747            retval = msgbox.exec_() 
     748            return 
    675749 
    676750        tab_list = [ObjectLibrary.getObject(self.tblTabList.item(s, 0).data(0)) for s in selected_rows] 
    677751        # Create and display the widget for param1 and param2 
    678752        cc_widget = ComplexConstraint(self, tabs=tab_list) 
     753        cc_widget.constraintReadySignal.connect(self.onAcceptConstraint) 
     754 
    679755        if cc_widget.exec_() != QtWidgets.QDialog.Accepted: 
    680756            return 
    681757 
    682         constraint = Constraint() 
    683         model1, param1, operator, constraint_text = cc_widget.constraint() 
    684  
    685         constraint.func = constraint_text 
    686         # param1 is the parameter we're constraining 
    687         constraint.param = param1 
    688  
    689         # Find the right tab 
    690         constrained_tab = self.getObjectByName(model1) 
    691         if constrained_tab is None: 
    692             return 
    693  
    694         # Find the constrained parameter row 
    695         constrained_row = constrained_tab.getRowFromName(param1) 
    696  
    697         # Update the tab 
    698         constrained_tab.addConstraintToRow(constraint, constrained_row) 
     758    def getFitPage(self): 
     759        """ 
     760        Retrieves the state of this page 
     761        """ 
     762        param_list = [] 
     763 
     764        param_list.append(['is_constraint', 'True']) 
     765        param_list.append(['data_id', "cs_tab"+str(self.page_id)]) 
     766        param_list.append(['current_type', self.currentType]) 
     767        param_list.append(['is_chain_fitting', str(self.is_chain_fitting)]) 
     768        param_list.append(['special_case', self.cbCases.currentText()]) 
     769 
     770        return param_list 
     771 
     772    def getFitModel(self): 
     773        """ 
     774        Retrieves current model 
     775        """ 
     776        model_list = [] 
     777 
     778        checked_models = {} 
     779        for row in range(self.tblTabList.rowCount()): 
     780            model_name = self.tblTabList.item(row,1).data(0) 
     781            active = self.tblTabList.item(row,0).checkState()# == QtCore.Qt.Checked 
     782            checked_models[model_name] = str(active) 
     783 
     784        checked_constraints = {} 
     785        for row in range(self.tblConstraints.rowCount()): 
     786            model_name = self.tblConstraints.item(row,0).data(0) 
     787            active = self.tblConstraints.item(row,0).checkState()# == QtCore.Qt.Checked 
     788            checked_constraints[model_name] = str(active) 
     789 
     790        model_list.append(['checked_models', checked_models]) 
     791        model_list.append(['checked_constraints', checked_constraints]) 
     792        return model_list 
     793 
     794    def createPageForParameters(self, parameters=None): 
     795        """ 
     796        Update the page with passed parameter values 
     797        """ 
     798        # checked models 
     799        if not 'checked_models' in parameters: 
     800            return 
     801        models = parameters['checked_models'][0] 
     802        for model, check_state in models.items(): 
     803            for row in range(self.tblTabList.rowCount()): 
     804                model_name = self.tblTabList.item(row,1).data(0) 
     805                if model_name != model: 
     806                    continue 
     807                # check/uncheck item 
     808                self.tblTabList.item(row,0).setCheckState(int(check_state)) 
     809 
     810        if not 'checked_constraints' in parameters: 
     811            return 
     812        # checked constraints 
     813        models = parameters['checked_constraints'][0] 
     814        for model, check_state in models.items(): 
     815            for row in range(self.tblConstraints.rowCount()): 
     816                model_name = self.tblConstraints.item(row,0).data(0) 
     817                if model_name != model: 
     818                    continue 
     819                # check/uncheck item 
     820                self.tblConstraints.item(row,0).setCheckState(int(check_state)) 
     821 
     822        # fit/batch radio 
     823        isBatch = parameters['current_type'][0] == 'BatchPage' 
     824        if isBatch: 
     825            self.btnBatch.toggle() 
     826 
     827        # chain 
     828        is_chain = parameters['is_chain_fitting'][0] == 'True' 
     829        if isBatch: 
     830            self.chkChain.setChecked(is_chain) 
Note: See TracChangeset for help on using the changeset viewer.