Ignore:
Timestamp:
Nov 21, 2018 6:39:24 AM (5 years ago)
Author:
Piotr Rozyczko <piotr.rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
f2e199e
Parents:
44c15fc (diff), fb39f28 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'ESS_GUI_project_save' into ESS_GUI

File:
1 edited

Legend:

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

    r7f41584 r21e71f1  
    5252TAB_POLY = 3 
    5353CATEGORY_DEFAULT = "Choose category..." 
     54MODEL_DEFAULT = "Choose model..." 
    5455CATEGORY_STRUCTURE = "Structure Factor" 
    5556CATEGORY_CUSTOM = "Plugin Models" 
     
    574575        # Signals from other widgets 
    575576        self.communicate.customModelDirectoryChanged.connect(self.onCustomModelChange) 
    576         self.communicate.saveAnalysisSignal.connect(self.savePageState) 
    577         #self.communicate.loadAnalysisSignal.connect(self.loadPageState) 
    578577        self.smearing_widget.smearingChangedSignal.connect(self.onSmearingOptionsUpdate) 
    579578 
     
    623622        to_string = "to its current value" if num_rows == 1 else "to their current values" 
    624623        has_constraints = any([self.rowHasConstraint(i) for i in rows]) 
     624        has_real_constraints = any([self.rowHasActiveConstraint(i) for i in rows]) 
    625625 
    626626        self.actionSelect = QtWidgets.QAction(self) 
     
    640640        self.actionRemoveConstraint.setText(QtCore.QCoreApplication.translate("self", "Remove constraint")) 
    641641 
     642        self.actionEditConstraint = QtWidgets.QAction(self) 
     643        self.actionEditConstraint.setObjectName("actionEditConstrain") 
     644        self.actionEditConstraint.setText(QtCore.QCoreApplication.translate("self", "Edit constraint")) 
     645 
    642646        self.actionMultiConstrain = QtWidgets.QAction(self) 
    643647        self.actionMultiConstrain.setObjectName("actionMultiConstrain") 
     
    654658        if has_constraints: 
    655659            menu.addAction(self.actionRemoveConstraint) 
     660            if num_rows == 1 and has_real_constraints: 
     661                menu.addAction(self.actionEditConstraint) 
    656662            #if num_rows == 1: 
    657663            #    menu.addAction(self.actionEditConstraint) 
     
    664670        self.actionConstrain.triggered.connect(self.addSimpleConstraint) 
    665671        self.actionRemoveConstraint.triggered.connect(self.deleteConstraint) 
     672        self.actionEditConstraint.triggered.connect(self.editConstraint) 
    666673        self.actionMutualMultiConstrain.triggered.connect(self.showMultiConstraint) 
    667674        self.actionSelect.triggered.connect(self.selectParameters) 
     
    701708        new_func = c_text.replace(param_used, updated_param_used) 
    702709        constraint.func = new_func 
     710        constraint.value_ex = updated_param_used 
    703711        # Which row is the constrained parameter in? 
    704712        row = self.getRowFromName(constraint.param) 
     713 
     714        # what is the parameter to constraint to? 
     715        constraint.value = param_used 
     716 
     717        # Should the new constraint be validated? 
     718        constraint.validate = mc_widget.validate 
    705719 
    706720        # Create a new item and add the Constraint object as a child 
     
    799813        self.communicate.statusBarUpdateSignal.emit('Constraint added') 
    800814 
     815    def editConstraint(self): 
     816        """ 
     817        Delete constraints from selected parameters. 
     818        """ 
     819        params_list = [s.data() for s in self.lstParams.selectionModel().selectedRows() 
     820                   if self.isCheckable(s.row())] 
     821        assert len(params_list) == 1 
     822        row = self.lstParams.selectionModel().selectedRows()[0].row() 
     823        constraint = self.getConstraintForRow(row) 
     824        # Create and display the widget for param1 and param2 
     825        mc_widget = MultiConstraint(self, params=params_list, constraint=constraint) 
     826        # Check if any of the parameters are polydisperse 
     827        if not np.any([FittingUtilities.isParamPolydisperse(p, self.model_parameters, is2D=self.is2D) for p in params_list]): 
     828            # no parameters are pd - reset the text to not show the warning 
     829            mc_widget.lblWarning.setText("") 
     830        if mc_widget.exec_() != QtWidgets.QDialog.Accepted: 
     831            return 
     832 
     833        constraint = Constraint() 
     834        c_text = mc_widget.txtConstraint.text() 
     835 
     836        # widget.params[0] is the parameter we're constraining 
     837        constraint.param = mc_widget.params[0] 
     838        # parameter should have the model name preamble 
     839        model_name = self.kernel_module.name 
     840        # param_used is the parameter we're using in constraining function 
     841        param_used = mc_widget.params[1] 
     842        # Replace param_used with model_name.param_used 
     843        updated_param_used = model_name + "." + param_used 
     844        # Update constraint with new values 
     845        constraint.func = c_text 
     846        constraint.value_ex = updated_param_used 
     847        constraint.value = param_used 
     848        # Should the new constraint be validated? 
     849        constraint.validate = mc_widget.validate 
     850 
     851        # Which row is the constrained parameter in? 
     852        row = self.getRowFromName(constraint.param) 
     853 
     854        # Create a new item and add the Constraint object as a child 
     855        self.addConstraintToRow(constraint=constraint, row=row) 
     856 
    801857    def deleteConstraint(self): 
    802858        """ 
     
    853909            return None 
    854910 
     911    def allParamNames(self): 
     912        """ 
     913        Returns a list of all parameter names defined on the current model 
     914        """ 
     915        all_params = self.kernel_module._model_info.parameters.kernel_parameters 
     916        all_param_names = [param.name for param in all_params] 
     917        # Assure scale and background are always included 
     918        if 'scale' not in all_param_names: 
     919            all_param_names.append('scale') 
     920        if 'background' not in all_param_names: 
     921            all_param_names.append('background') 
     922        return all_param_names 
     923 
     924    def paramHasConstraint(self, param=None): 
     925        """ 
     926        Finds out if the given parameter in the main model has a constraint child 
     927        """ 
     928        if param is None: return False 
     929        if param not in self.allParamNames(): return False 
     930 
     931        for row in range(self._model_model.rowCount()): 
     932            if self._model_model.item(row,0).text() != param: continue 
     933            return self.rowHasConstraint(row) 
     934 
     935        # nothing found 
     936        return False 
     937 
    855938    def rowHasConstraint(self, row): 
    856939        """ 
     
    10181101        Checks if the current model has magnetic scattering implemented 
    10191102        """ 
    1020         has_params = False 
     1103        has_mag_params = False 
    10211104        if self.kernel_module: 
    10221105            has_mag_params = len(self.kernel_module.magnetic_params) > 0 
     
    10291112        model = self.cbModel.currentText() 
    10301113 
     1114        if model == MODEL_DEFAULT: 
     1115            # if the previous category was not the default, keep it. 
     1116            # Otherwise, just return 
     1117            if self._previous_model_index != 0: 
     1118                # We need to block signals, or else state changes on perceived unchanged conditions 
     1119                self.cbModel.blockSignals(True) 
     1120                self.cbModel.setCurrentIndex(self._previous_model_index) 
     1121                self.cbModel.blockSignals(False) 
     1122            return 
     1123 
    10311124        # Assure the control is active 
    10321125        if not self.cbModel.isEnabled(): 
     
    10351128        if not model: 
    10361129            return 
     1130 
     1131        self.chkMagnetism.setEnabled(self.canHaveMagnetism()) 
     1132        self.chkMagnetism.setEnabled(self.canHaveMagnetism()) 
     1133        self.tabFitting.setTabEnabled(TAB_MAGNETISM, self.chkMagnetism.isChecked() and self.canHaveMagnetism()) 
     1134        self._previous_model_index = self.cbModel.currentIndex() 
    10371135 
    10381136        # Reset parameters to fit 
     
    12131311            self._model_model.clear() 
    12141312            return 
    1215  
     1313        # Wipe out the parameter model 
     1314        self._model_model.clear() 
    12161315        # Safely clear and enable the model combo 
    12171316        self.cbModel.blockSignals(True) 
     
    12251324        model_list = self.master_category_dict[category] 
    12261325        # Populate the models combobox 
     1326        self.cbModel.blockSignals(True) 
     1327        self.cbModel.addItem(MODEL_DEFAULT) 
    12271328        self.cbModel.addItems(sorted([model for (model, _) in model_list])) 
     1329        self.cbModel.blockSignals(False) 
    12281330 
    12291331    def onPolyModelChange(self, top, bottom): 
     
    19372039        Emits plotRequestedSignal for all plots found in the given model under the provided item name. 
    19382040        """ 
    1939         fitpage_name = "" if self.tab_id is None else "M"+str(self.tab_id) 
     2041        fitpage_name = self.kernel_module.name 
    19402042        plots = GuiUtils.plotsFromFilename(item_name, item_model) 
    19412043        # Has the fitted data been shown? 
     
    24252527    def isCheckable(self, row): 
    24262528        return self._model_model.item(row, 0).isCheckable() 
     2529 
     2530    def selectCheckbox(self, row): 
     2531        """ 
     2532        Select the checkbox in given row. 
     2533        """ 
     2534        assert 0<= row <= self._model_model.rowCount() 
     2535        index = self._model_model.index(row, 0) 
     2536        item = self._model_model.itemFromIndex(index) 
     2537        item.setCheckState(QtCore.Qt.Checked) 
    24272538 
    24282539    def checkboxSelected(self, item): 
     
    34303541        return report_logic.reportList() 
    34313542 
    3432     def savePageState(self): 
    3433         """ 
    3434         Create and serialize local PageState 
    3435         """ 
    3436         filepath = self.saveAsAnalysisFile() 
    3437         if filepath is None or filepath == "": 
    3438             return 
    3439  
    3440         fitpage_state = self.getFitPage() 
    3441         fitpage_state += self.getFitModel() 
    3442  
    3443         with open(filepath, 'w') as statefile: 
    3444             for line in fitpage_state: 
    3445                 statefile.write(str(line)) 
    3446  
    3447         self.communicate.statusBarUpdateSignal.emit('Analysis saved.') 
    3448  
    3449     def saveAsAnalysisFile(self): 
    3450         """ 
    3451         Show the save as... dialog and return the chosen filepath 
    3452         """ 
    3453         default_name = "FitPage"+str(self.tab_id)+".fitv" 
    3454  
    3455         wildcard = "fitv files (*.fitv)" 
    3456         kwargs = { 
    3457             'caption'   : 'Save As', 
    3458             'directory' : default_name, 
    3459             'filter'    : wildcard, 
    3460             'parent'    : None, 
    3461         } 
    3462         # Query user for filename. 
    3463         filename_tuple = QtWidgets.QFileDialog.getSaveFileName(**kwargs) 
    3464         filename = filename_tuple[0] 
    3465         return filename 
    3466  
    34673543    def loadPageStateCallback(self,state=None, datainfo=None, format=None): 
    34683544        """ 
     
    35493625 
    35503626        param_list.append(['is_data', str(self.data_is_loaded)]) 
    3551         if self.data_is_loaded: 
    3552             param_list.append(['data_id', str(self.logic.data.id)]) 
    3553             param_list.append(['data_name', str(self.logic.data.filename)]) 
    3554  
     3627        data_ids = [] 
     3628        filenames = [] 
     3629        if self.is_batch_fitting: 
     3630            for item in self.all_data: 
     3631                # need item->data->data_id 
     3632                data = GuiUtils.dataFromItem(item) 
     3633                data_ids.append(data.id) 
     3634                filenames.append(data.filename) 
     3635        else: 
     3636            if self.data_is_loaded: 
     3637                data_ids = [str(self.logic.data.id)] 
     3638                filenames = [str(self.logic.data.filename)] 
     3639        param_list.append(['is_batch_fitting', str(self.is_batch_fitting)]) 
     3640        param_list.append(['data_name', filenames]) 
     3641        param_list.append(['data_id', data_ids]) 
     3642        param_list.append(['tab_name', self.modelName()]) 
    35553643        # option tab 
    35563644        param_list.append(['q_range_min', str(self.q_range_min)]) 
     
    35833671        """ 
    35843672        param_list = [] 
     3673        if self.kernel_module is None: 
     3674            return param_list 
     3675 
    35853676        param_list.append(['model_name', str(self.cbModel.currentText())]) 
    35863677 
     
    36223713            except: 
    36233714                pass 
    3624  
    3625             param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 
     3715            # Do we have any constraints on this parameter? 
     3716            constraint = self.getConstraintForRow(row) 
     3717            cons = () 
     3718            if constraint is not None: 
     3719                value = constraint.value 
     3720                func = constraint.func 
     3721                value_ex = constraint.value_ex 
     3722                param = constraint.param 
     3723                validate = constraint.validate 
     3724 
     3725                cons = (value, param, value_ex, validate, func) 
     3726 
     3727            param_list.append([param_name, param_checked, param_value,param_error, param_min, param_max, cons]) 
    36263728 
    36273729        def gatherPolyParams(row): 
     
    36873789        cb_text = cb.text() 
    36883790 
    3689         context = {} 
    36903791        lines = cb_text.split(':') 
    36913792        if lines[0] != 'sasview_parameter_values': 
     
    36993800                line_dict[content[0]] = content[1:] 
    37003801 
     3802        self.updatePageWithParameters(line_dict) 
     3803 
     3804    def createPageForParameters(self, line_dict): 
     3805        """ 
     3806        Sets up page with requested model/str factor 
     3807        and fills it up with sent parameters 
     3808        """ 
     3809        if 'fitpage_category' in line_dict: 
     3810            self.cbCategory.setCurrentIndex(self.cbCategory.findText(line_dict['fitpage_category'][0])) 
     3811        if 'fitpage_model' in line_dict: 
     3812            self.cbModel.setCurrentIndex(self.cbModel.findText(line_dict['fitpage_model'][0])) 
     3813        if 'fitpage_structure' in line_dict: 
     3814            self.cbStructureFactor.setCurrentIndex(self.cbStructureFactor.findText(line_dict['fitpage_structure'][0])) 
     3815 
     3816        # Now that the page is ready for parameters, fill it up 
     3817        self.updatePageWithParameters(line_dict) 
     3818 
     3819    def updatePageWithParameters(self, line_dict): 
     3820        """ 
     3821        Update FitPage with parameters in line_dict 
     3822        """ 
     3823        if 'model_name' not in line_dict.keys(): 
     3824            return 
    37013825        model = line_dict['model_name'][0] 
    3702  
    3703         if 'model_name' not in line_dict.keys(): 
    3704             return False 
     3826        context = {} 
    37053827 
    37063828        if 'multiplicity' in line_dict.keys(): 
     
    37113833                self.updateMultiplicityCombo(multip) 
    37123834 
     3835        if 'tab_name' in line_dict.keys(): 
     3836            self.kernel_module.name = line_dict['tab_name'][0] 
    37133837        if 'polydisperse_params' in line_dict.keys(): 
    37143838            self.chkPolydispersity.setChecked(line_dict['polydisperse_params'][0]=='True') 
     
    38333957            ioffset = 0 
    38343958            joffset = 0 
    3835             if len(param_dict[param_name])>4: 
     3959            if len(param_dict[param_name])>5: 
    38363960                # error values are not editable - no need to update 
    38373961                ioffset = 1 
     
    38463970            except: 
    38473971                pass 
     3972 
     3973            # constraints 
     3974            cons = param_dict[param_name][4+ioffset] 
     3975            if cons is not None and len(cons)==5: 
     3976                value = cons[0] 
     3977                param = cons[1] 
     3978                value_ex = cons[2] 
     3979                validate = cons[3] 
     3980                function = cons[4] 
     3981                constraint = Constraint() 
     3982                constraint.value = value 
     3983                constraint.func = function 
     3984                constraint.param = param 
     3985                constraint.value_ex = value_ex 
     3986                constraint.validate = validate 
     3987                self.addConstraintToRow(constraint=constraint, row=row) 
    38483988 
    38493989            self.setFocus() 
Note: See TracChangeset for help on using the changeset viewer.