Ignore:
File:
1 edited

Legend:

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

    r8b480d27 re4c475b7  
    2424import sas.qtgui.Utilities.GuiUtils as GuiUtils 
    2525import sas.qtgui.Utilities.LocalConfig as LocalConfig 
    26 from sas.qtgui.Utilities.GridPanel import BatchOutputPanel 
    2726from sas.qtgui.Utilities.CategoryInstaller import CategoryInstaller 
    2827from sas.qtgui.Plotting.PlotterData import Data1D 
     
    3736from sas.qtgui.Perspectives.Fitting.FittingLogic import FittingLogic 
    3837from sas.qtgui.Perspectives.Fitting import FittingUtilities 
    39 from sas.qtgui.Perspectives.Fitting import ModelUtilities 
    4038from sas.qtgui.Perspectives.Fitting.SmearingWidget import SmearingWidget 
    4139from sas.qtgui.Perspectives.Fitting.OptionsWidget import OptionsWidget 
     
    5250CATEGORY_DEFAULT = "Choose category..." 
    5351CATEGORY_STRUCTURE = "Structure Factor" 
    54 CATEGORY_CUSTOM = "Plugin Models" 
    5552STRUCTURE_DEFAULT = "None" 
    5653 
     
    8683    constraintAddedSignal = QtCore.pyqtSignal(list) 
    8784    newModelSignal = QtCore.pyqtSignal() 
    88     fittingFinishedSignal = QtCore.pyqtSignal(tuple) 
    89     batchFittingFinishedSignal = QtCore.pyqtSignal(tuple) 
    90  
    9185    def __init__(self, parent=None, data=None, tab_id=1): 
    9286 
     
    217211        self.page_stack = [] 
    218212        self.all_data = [] 
    219         # custom plugin models 
    220         # {model.name:model} 
    221         self.custom_models = self.customModels() 
    222213        # Polydisp widget table default index for function combobox 
    223214        self.orig_poly_index = 3 
     
    424415            self.onSelectModel() 
    425416 
    426     @classmethod 
    427     def customModels(cls): 
    428         """ Reads in file names in the custom plugin directory """ 
    429         return ModelUtilities._find_models() 
    430  
    431417    def initializeControls(self): 
    432418        """ 
     
    479465        self._poly_model.itemChanged.connect(self.onPolyModelChange) 
    480466        self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 
    481         self.lstParams.selectionModel().selectionChanged.connect(self.onSelectionChanged) 
    482  
    483         # Local signals 
    484         self.batchFittingFinishedSignal.connect(self.batchFitComplete) 
    485         self.fittingFinishedSignal.connect(self.fitComplete) 
    486467 
    487468        # Signals from separate tabs asking for replot 
    488469        self.options_widget.plot_signal.connect(self.onOptionsUpdate) 
    489  
    490         # Signals from other widgets 
    491         self.communicate.customModelDirectoryChanged.connect(self.onCustomModelChange) 
    492470 
    493471    def modelName(self): 
     
    598576        # widget.params[0] is the parameter we're constraining 
    599577        constraint.param = mc_widget.params[0] 
    600         # parameter should have the model name preamble 
     578        # Function should have the model name preamble 
    601579        model_name = self.kernel_module.name 
    602         # param_used is the parameter we're using in constraining function 
    603         param_used = mc_widget.params[1] 
    604         # Replace param_used with model_name.param_used 
    605         updated_param_used = model_name + "." + param_used 
    606         new_func = c_text.replace(param_used, updated_param_used) 
    607         constraint.func = new_func 
     580        constraint.func = model_name + "." + c_text 
    608581        # Which row is the constrained parameter in? 
    609582        row = self.getRowFromName(constraint.param) 
     
    704677        Delete constraints from selected parameters. 
    705678        """ 
    706         params =  [s.data() for s in self.lstParams.selectionModel().selectedRows() 
    707                    if self.isCheckable(s.row())] 
    708         for param in params: 
    709             self.deleteConstraintOnParameter(param=param) 
     679        self.deleteConstraintOnParameter(param=None) 
    710680 
    711681    def deleteConstraintOnParameter(self, param=None): 
     
    716686        max_col = self.lstParams.itemDelegate().param_max 
    717687        for row in range(self._model_model.rowCount()): 
    718             if not self.rowHasConstraint(row): 
    719                 continue 
    720688            # Get the Constraint object from of the model item 
    721689            item = self._model_model.item(row, 1) 
    722             constraint = self.getConstraintForRow(row) 
     690            if not item.hasChildren(): 
     691                continue 
     692            constraint = item.child(0).data() 
    723693            if constraint is None: 
    724694                continue 
     
    846816        return constraints 
    847817 
    848     def getConstraintsForFitting(self): 
    849         """ 
    850         Return a list of constraints in format ready for use in fiting 
    851         """ 
    852         # Get constraints 
    853         constraints = self.getComplexConstraintsForModel() 
    854         # See if there are any constraints across models 
    855         multi_constraints = [cons for cons in constraints if self.isConstraintMultimodel(cons[1])] 
    856  
    857         if multi_constraints: 
    858             # Let users choose what to do 
    859             msg = "The current fit contains constraints relying on other fit pages.\n" 
    860             msg += "Parameters with those constraints are:\n" +\ 
    861                 '\n'.join([cons[0] for cons in multi_constraints]) 
    862             msg += "\n\nWould you like to remove these constraints or cancel fitting?" 
    863             msgbox = QtWidgets.QMessageBox(self) 
    864             msgbox.setIcon(QtWidgets.QMessageBox.Warning) 
    865             msgbox.setText(msg) 
    866             msgbox.setWindowTitle("Existing Constraints") 
    867             # custom buttons 
    868             button_remove = QtWidgets.QPushButton("Remove") 
    869             msgbox.addButton(button_remove, QtWidgets.QMessageBox.YesRole) 
    870             button_cancel = QtWidgets.QPushButton("Cancel") 
    871             msgbox.addButton(button_cancel, QtWidgets.QMessageBox.RejectRole) 
    872             retval = msgbox.exec_() 
    873             if retval == QtWidgets.QMessageBox.RejectRole: 
    874                 # cancel fit 
    875                 raise ValueError("Fitting cancelled") 
    876             else: 
    877                 # remove constraint 
    878                 for cons in multi_constraints: 
    879                     self.deleteConstraintOnParameter(param=cons[0]) 
    880                 # re-read the constraints 
    881                 constraints = self.getComplexConstraintsForModel() 
    882  
    883         return constraints 
    884  
    885818    def showModelDescription(self): 
    886819        """ 
     
    941874        self.respondToModelStructure(model=model, structure_factor=structure) 
    942875 
    943     def onCustomModelChange(self): 
    944         """ 
    945         Reload the custom model combobox 
    946         """ 
    947         self.custom_models = self.customModels() 
    948         self.readCustomCategoryInfo() 
    949         # See if we need to update the combo in-place 
    950         if self.cbCategory.currentText() != CATEGORY_CUSTOM: return 
    951  
    952         current_text = self.cbModel.currentText() 
    953         self.cbModel.blockSignals(True) 
    954         self.cbModel.clear() 
    955         self.cbModel.blockSignals(False) 
    956         self.enableModelCombo() 
    957         self.disableStructureCombo() 
    958         # Retrieve the list of models 
    959         model_list = self.master_category_dict[CATEGORY_CUSTOM] 
    960         # Populate the models combobox 
    961         self.cbModel.addItems(sorted([model for (model, _) in model_list])) 
    962         new_index = self.cbModel.findText(current_text) 
    963         if new_index != -1: 
    964             self.cbModel.setCurrentIndex(self.cbModel.findText(current_text)) 
    965  
    966     def onSelectionChanged(self): 
    967         """ 
    968         React to parameter selection 
    969         """ 
    970         rows = self.lstParams.selectionModel().selectedRows() 
    971         # Clean previous messages 
    972         self.communicate.statusBarUpdateSignal.emit("") 
    973         if len(rows) == 1: 
    974             # Show constraint, if present 
    975             row = rows[0].row() 
    976             if self.rowHasConstraint(row): 
    977                 func = self.getConstraintForRow(row).func 
    978                 if func is not None: 
    979                     self.communicate.statusBarUpdateSignal.emit("Active constrain: "+func) 
    980  
    981876    def replaceConstraintName(self, old_name, new_name=""): 
    982877        """ 
     
    991886                    new_func = func.replace(old_name, new_name) 
    992887                    self._model_model.item(row, 1).child(0).data().func = new_func 
    993  
    994     def isConstraintMultimodel(self, constraint): 
    995         """ 
    996         Check if the constraint function text contains current model name 
    997         """ 
    998         current_model_name = self.kernel_module.name 
    999         if current_model_name in constraint: 
    1000             return False 
    1001         else: 
    1002             return True 
    1003888 
    1004889    def updateData(self): 
     
    12201105        except ValueError as ex: 
    12211106            # This should not happen! GUI explicitly forbids this situation 
    1222             self.communicate.statusBarUpdateSignal.emit(str(ex)) 
     1107            self.communicate.statusBarUpdateSignal.emit('Fitting attempt without parameters.') 
    12231108            return 
    12241109 
    12251110        # Create the fitting thread, based on the fitter 
    1226         completefn = self.batchFittingCompleted if self.is_batch_fitting else self.fittingCompleted 
     1111        completefn = self.batchFitComplete if self.is_batch_fitting else self.fitComplete 
    12271112 
    12281113        calc_fit = FitThread(handler=handler, 
     
    12611146        pass 
    12621147 
    1263     def batchFittingCompleted(self, result): 
    1264         """ 
    1265         Send the finish message from calculate threads to main thread 
    1266         """ 
    1267         self.batchFittingFinishedSignal.emit(result) 
    1268  
    12691148    def batchFitComplete(self, result): 
    12701149        """ 
     
    12731152        #re-enable the Fit button 
    12741153        self.setFittingStopped() 
    1275         # Show the grid panel 
    1276         self.grid_window = BatchOutputPanel(parent=self, output_data=result[0]) 
    1277         self.grid_window.show() 
    1278  
    1279     def fittingCompleted(self, result): 
    1280         """ 
    1281         Send the finish message from calculate threads to main thread 
    1282         """ 
    1283         self.fittingFinishedSignal.emit(result) 
    12841154 
    12851155    def fitComplete(self, result): 
     
    12921162 
    12931163        if result is None: 
    1294             msg = "Fitting failed." 
     1164            msg = "Fitting failed after: %s s.\n" % GuiUtils.formatNumber(elapsed) 
    12951165            self.communicate.statusBarUpdateSignal.emit(msg) 
    12961166            return 
     
    13581228        smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 
    13591229 
    1360         # Get the constraints. 
    13611230        constraints = self.getComplexConstraintsForModel() 
    1362         if fitter is None: 
    1363             # For single fits - check for inter-model constraints 
    1364             constraints = self.getConstraintsForFitting() 
    1365  
    13661231        smearer = None 
    13671232        handler = None 
     
    13771242                             constraints=constraints) 
    13781243            except ValueError as ex: 
    1379                 raise ValueError("Setting model parameters failed with: %s" % ex) 
     1244                logging.error("Setting model parameters failed with: %s" % ex) 
     1245                return 
    13801246 
    13811247            qmin, qmax, _ = self.logic.computeRangeFromData(data) 
     
    15431409        if not dict: 
    15441410            return 
    1545         if self._magnet_model.rowCount() == 0: 
     1411        if self._model_model.rowCount() == 0: 
    15461412            return 
    15471413 
     
    16891555            self.models[model.name] = model 
    16901556 
    1691         self.readCustomCategoryInfo() 
    1692  
    1693     def readCustomCategoryInfo(self): 
    1694         """ 
    1695         Reads the custom model category 
    1696         """ 
    1697         #Looking for plugins 
    1698         self.plugins = list(self.custom_models.values()) 
    1699         plugin_list = [] 
    1700         for name, plug in self.custom_models.items(): 
    1701             self.models[name] = plug 
    1702             plugin_list.append([name, True]) 
    1703         self.master_category_dict[CATEGORY_CUSTOM] = plugin_list 
    1704  
    17051557    def regenerateModelDict(self): 
    17061558        """ 
     
    18101662        Setting model parameters into QStandardItemModel based on selected _model_ 
    18111663        """ 
    1812         name = model_name 
    1813         if self.cbCategory.currentText() == CATEGORY_CUSTOM: 
    1814             # custom kernel load requires full path 
    1815             name = os.path.join(ModelUtilities.find_plugins_dir(), model_name+".py") 
    1816         kernel_module = generate.load_kernel_module(name) 
     1664        kernel_module = generate.load_kernel_module(model_name) 
    18171665        self.model_parameters = modelinfo.make_parameter_table(getattr(kernel_module, 'parameters', [])) 
    18181666 
Note: See TracChangeset for help on using the changeset viewer.