Changeset d2007a8 in sasview


Ignore:
Timestamp:
Oct 17, 2018 7:27:04 AM (4 weeks ago)
Author:
Piotr Rozyczko <piotr.rozyczko@…>
Branches:
ESS_GUI, ESS_GUI_project_save
Children:
dd545d1
Parents:
21fa45b
git-author:
Piotr Rozyczko <piotr.rozyczko@…> (10/17/18 07:11:28)
git-committer:
Piotr Rozyczko <piotr.rozyczko@…> (10/17/18 07:27:04)
Message:

Fitpage state copy/paste reworked. SASVIEW-1053 and SASVIEW-1196

Location:
src/sas/qtgui/Perspectives/Fitting
Files:
3 edited

Legend:

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

    r20f4857 rd2007a8  
    102102 
    103103    def onParamCopy(self): 
    104         self.currentTab.onParameterCopy("") 
     104        self.currentTab.onCopyToClipboard("") 
    105105 
    106106    def onParamPaste(self): 
     
    108108 
    109109    def onExcelCopy(self): 
    110         self.currentTab.onParameterCopy("Excel") 
     110        self.currentTab.onCopyToClipboard("Excel") 
    111111 
    112112    def onLatexCopy(self): 
    113         self.currentTab.onParameterCopy("Latex") 
     113        self.currentTab.onCopyToClipboard("Latex") 
    114114 
    115115    def closeEvent(self, event): 
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    r21fa45b rd2007a8  
    119119        self.tab_id = tab_id 
    120120 
     121        import sys 
     122        sys.excepthook = self.info 
     123 
    121124        # Globals 
    122125        self.initializeGlobals() 
     
    163166        self.label_17.setStyleSheet(new_font) 
    164167        self.label_19.setStyleSheet(new_font) 
     168 
     169    def info(self, type, value, tb): 
     170        logger.error("SasView threw exception: " + str(value)) 
     171        traceback.print_exception(type, value, tb) 
    165172 
    166173    @property 
     
    543550 
    544551        # Respond to change in parameters from the UI 
    545         self._model_model.itemChanged.connect(self.onMainParamsChange) 
    546         #self.constraintAddedSignal.connect(self.modifyViewOnConstraint) 
    547         self._poly_model.itemChanged.connect(self.onPolyModelChange) 
    548         self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 
     552        self._model_model.dataChanged.connect(self.onMainParamsChange) 
     553        self._poly_model.dataChanged.connect(self.onPolyModelChange) 
     554        self._magnet_model.dataChanged.connect(self.onMagnetModelChange) 
    549555        self.lstParams.selectionModel().selectionChanged.connect(self.onSelectionChanged) 
    550556 
     
    12071213        self.cbModel.addItems(sorted([model for (model, _) in model_list])) 
    12081214 
    1209     def onPolyModelChange(self, item): 
     1215    def onPolyModelChange(self, top, bottom): 
    12101216        """ 
    12111217        Callback method for updating the main model and sasmodel 
    12121218        parameters with the GUI values in the polydispersity view 
    12131219        """ 
     1220        item = self._poly_model.itemFromIndex(top) 
    12141221        model_column = item.column() 
    12151222        model_row = item.row() 
     
    12781285            self._model_model.blockSignals(False) 
    12791286 
    1280     def onMagnetModelChange(self, item): 
     1287    def onMagnetModelChange(self, top, bottom): 
    12811288        """ 
    12821289        Callback method for updating the sasmodel magnetic parameters with the GUI values 
    12831290        """ 
     1291        item = self._magnet_model.itemFromIndex(top) 
    12841292        model_column = item.column() 
    12851293        model_row = item.row() 
     
    17161724        # block signals temporarily, so we don't end up 
    17171725        # updating charts with every single model change on the end of fitting 
    1718         self._model_model.itemChanged.disconnect() 
     1726        self._model_model.dataChanged.disconnect() 
    17191727        self.iterateOverModel(updateFittedValues) 
    17201728        self.iterateOverModel(updatePolyValues) 
    1721         self._model_model.itemChanged.connect(self.onMainParamsChange) 
     1729        self._model_model.dataChanged.connect(self.onMainParamsChange) 
    17221730 
    17231731    def iterateOverPolyModel(self, func): 
     
    17711779        # block signals temporarily, so we don't end up 
    17721780        # updating charts with every single model change on the end of fitting 
    1773         self._poly_model.itemChanged.disconnect() 
     1781        self._poly_model.dataChanged.disconnect() 
    17741782        self.iterateOverPolyModel(updateFittedValues) 
    1775         self._poly_model.itemChanged.connect(self.onPolyModelChange) 
     1783        self._poly_model.dataChanged.connect(self.onPolyModelChange) 
    17761784 
    17771785        if self.has_poly_error_column: 
     
    18361844        # block signals temporarily, so we don't end up 
    18371845        # updating charts with every single model change on the end of fitting 
    1838         self._magnet_model.itemChanged.disconnect() 
     1846        self._magnet_model.dataChanged.disconnect() 
    18391847        self.iterateOverMagnetModel(updateFittedValues) 
    1840         self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 
     1848        self._magnet_model.dataChanged.connect(self.onMagnetModelChange) 
    18411849 
    18421850        if self.has_magnet_error_column: 
     
    22722280        return False 
    22732281 
    2274     def onMainParamsChange(self, item): 
     2282    def onMainParamsChange(self, top, bottom): 
    22752283        """ 
    22762284        Callback method for updating the sasmodel parameters with the GUI values 
    22772285        """ 
     2286        item = self._model_model.itemFromIndex(top) 
     2287 
    22782288        model_column = item.column() 
    22792289 
     
    23012311        else: 
    23022312            parameter_name = str(self._model_model.data(name_index)) 
    2303  
    2304         # Update the parameter value - note: this supports +/-inf as well 
    2305         self.kernel_module.params[parameter_name] = value 
    23062313 
    23072314        # Update the parameter value - note: this supports +/-inf as well 
     
    31513158        # Update relevant models 
    31523159        self.setPolyModel() 
    3153         self.setMagneticModel() 
     3160        if self.canHaveMagnetism(): 
     3161            self.setMagneticModel() 
    31543162 
    31553163    def onShowSLDProfile(self): 
     
    34653473        #self._copy_parameters_state(self.fixed_param, self.state.fixed_param) 
    34663474 
    3467     def onParameterCopy(self, format=None): 
     3475    def onCopyToClipboard(self, format=None): 
     3476        """ 
     3477        Copy current fitting parameters into the clipboard 
     3478        using requested formatting: 
     3479        plain, excel, latex 
     3480        """ 
     3481        param_list = self.getFitParameters() 
     3482        if format=="": 
     3483            formatted_output = FittingUtilities.formatParameters(param_list) 
     3484        elif format == "Excel": 
     3485            formatted_output = FittingUtilities.formatParametersExcel(param_list[1:]) 
     3486        elif format == "Latex": 
     3487            formatted_output = FittingUtilities.formatParametersLatex(param_list[1:]) 
     3488        else: 
     3489            raise AttributeError("Bad parameter output format specifier.") 
     3490 
     3491        # Dump formatted_output to the clipboard 
     3492        cb = QtWidgets.QApplication.clipboard() 
     3493        cb.setText(formatted_output) 
     3494 
     3495    def getFitParameters(self, format=None): 
    34683496        """ 
    34693497        Copy current parameters into the clipboard 
     
    34723500        # first - regular params 
    34733501        param_list = [] 
    3474  
    34753502        param_list.append(['model_name', str(self.cbModel.currentText())]) 
    3476  
    3477         try: 
    3478             param_list.append(['structure_factor', str(self.cbStructureFactor.currentText())]) 
    3479         except: 
    3480             pass 
    34813503 
    34823504        def gatherParams(row): 
     
    34863508            param_name = str(self._model_model.item(row, 0).text()) 
    34873509 
    3488             if param_name == str(self.cbModel.currentText()): 
    3489                 pass 
    3490             elif param_name == str(self.cbStructureFactor.currentText()): 
     3510            # Assure this is a parameter - must contain a checkbox 
     3511            if not self._model_model.item(row, 0).isCheckable(): 
     3512                # maybe it is a combobox item (multiplicity) 
     3513                try: 
     3514                    index = self._model_model.index(row, 1) 
     3515                    widget = self.lstParams.indexWidget(index) 
     3516                    if widget is None: 
     3517                        return 
     3518                    if isinstance(widget, QtWidgets.QComboBox): 
     3519                        # find the index of the combobox 
     3520                        current_index = widget.currentIndex() 
     3521                        param_list.append([param_name, 'None', str(current_index)]) 
     3522                except Exception as ex: 
     3523                    pass 
     3524                return 
     3525 
     3526            param_checked = str(self._model_model.item(row, 0).checkState() == QtCore.Qt.Checked) 
     3527            # Value of the parameter. In some cases this is the text of the combobox choice. 
     3528            param_value = str(self._model_model.item(row, 1).text()) 
     3529            param_error = None 
     3530            param_min = None 
     3531            param_max = None 
     3532            column_offset = 0 
     3533            if self.has_error_column: 
     3534                column_offset = 1 
     3535            try: 
     3536                param_min = str(self._model_model.item(row, 2+column_offset).text()) 
     3537                param_max = str(self._model_model.item(row, 3+column_offset).text()) 
     3538            except: 
    34913539                pass 
    34923540            else: 
     
    35013549                    column_offset = 1 
    35023550 
    3503                 try: 
    3504                     param_min = str(self._model_model.item(row, 2 + column_offset).text()) 
    3505                     param_max = str(self._model_model.item(row, 3 + column_offset).text()) 
    3506                 except: 
    3507                     pass 
    3508  
    3509                 param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 
     3551            param_list.append([param_name, param_checked, param_value, param_min, param_max]) 
    35103552 
    35113553        def gatherPolyParams(row): 
     
    35193561            column_offset = 0 
    35203562            if self.has_poly_error_column: 
    3521                 param_error = str(self._poly_model.item(row, 2).text()) 
    35223563                column_offset = 1 
    35233564            param_min   = str(self._poly_model.item(row, 2+column_offset).text()) 
     
    35263567            param_nsigs = str(self._poly_model.item(row, 5+column_offset).text()) 
    35273568            param_fun   = str(self._poly_model.item(row, 6+column_offset).text()).rstrip() 
     3569            index = self._poly_model.index(row, 6+column_offset) 
     3570            widget = self.lstPoly.indexWidget(index) 
     3571            if widget is not None and isinstance(widget, QtWidgets.QComboBox): 
     3572                param_fun = widget.currentText() 
    35283573            # width 
    35293574            name = param_name+".width" 
    3530             param_list.append([name, param_checked, param_value, param_error, 
    3531                                 param_npts, param_nsigs, param_min, param_max, param_fun]) 
     3575            param_list.append([name, param_checked, param_value, param_min, param_max, 
     3576                                param_npts, param_nsigs, param_fun]) 
    35323577 
    35333578        def gatherMagnetParams(row): 
     
    35413586            column_offset = 0 
    35423587            if self.has_magnet_error_column: 
    3543                 param_error = str(self._magnet_model.item(row, 2).text()) 
    35443588                column_offset = 1 
    35453589            param_min = str(self._magnet_model.item(row, 2+column_offset).text()) 
    35463590            param_max = str(self._magnet_model.item(row, 3+column_offset).text()) 
    3547             param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 
     3591            param_list.append([param_name, param_checked, param_value, param_min, param_max]) 
    35483592 
    35493593        self.iterateOverModel(gatherParams) 
     
    35533597            self.iterateOverMagnetModel(gatherMagnetParams) 
    35543598 
    3555         if format=="": 
    3556             formatted_output = FittingUtilities.formatParameters(param_list) 
    3557         elif format == "Excel": 
    3558             formatted_output = FittingUtilities.formatParametersExcel(param_list[2:]) 
    3559         elif format == "Latex": 
    3560             formatted_output = FittingUtilities.formatParametersLatex(param_list[2:]) 
    3561         else: 
    3562             raise AttributeError("Bad format specifier.") 
    3563  
    3564         # Dump formatted_output to the clipboard 
    3565         cb = QtWidgets.QApplication.clipboard() 
    3566         cb.setText(formatted_output) 
     3599        if self.kernel_module.is_multiplicity_model: 
     3600            param_list.append(['multiplicity', str(self.kernel_module.multiplicity)]) 
     3601 
     3602        # option tab 
     3603        param_list.append(['q_range_min', str(self.q_range_min)]) 
     3604        param_list.append(['q_range_max', str(self.q_range_max)]) 
     3605        param_list.append(['q_weighting', str(self.weighting)]) 
     3606 
     3607        # resolution 
     3608        smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 
     3609        index = self.smearing_widget.cbSmearing.currentIndex() 
     3610        param_list.append(['smearing', str(index)]) 
     3611        param_list.append(['smearing_min', str(smearing_min)]) 
     3612        param_list.append(['smearing_max', str(smearing_max)]) 
     3613 
     3614        # checkboxes, if required 
     3615        has_polydisp = self.chkPolydispersity.isChecked() 
     3616        has_magnetism = self.chkMagnetism.isChecked() 
     3617        has_chain = self.chkChainFit.isChecked() 
     3618        has_2D = self.chk2DView.isChecked() 
     3619        param_list.append(['polydisperse_params', str(has_polydisp)]) 
     3620        param_list.append(['magnetic_params', str(has_magnetism)]) 
     3621        param_list.append(['chainfit_params', str(has_chain)]) 
     3622        param_list.append(['2D_params', str(has_2D)]) 
     3623 
     3624        return param_list 
    35673625 
    35683626    def onParameterPaste(self): 
     
    35753633 
    35763634        context = {} 
    3577         # put the text into dictionary 
    35783635        lines = cb_text.split(':') 
    35793636        if lines[0] != 'sasview_parameter_values': 
    35803637            return False 
    35813638 
    3582         model = lines[1].split(',') 
    3583  
    3584         if model[0] != 'model_name': 
     3639        # put the text into dictionary 
     3640        line_dict = {} 
     3641        for line in lines[1:]: 
     3642            content = line.split(',') 
     3643            if len(content) > 1: 
     3644                line_dict[content[0]] = content[1:] 
     3645 
     3646        model = line_dict['model_name'][0] 
     3647 
     3648        if 'model_name' not in line_dict.keys(): 
    35853649            return False 
    35863650 
    3587         StrucFac = lines[2].split(',') 
    3588  
    3589         if StrucFac[0] != 'structure_factor': 
    3590             return False 
    3591  
    3592         context['model_name'] = [model[1]] 
    3593         context['structure_factor'] = [StrucFac[1]] 
    3594  
    3595         for line in lines[3:-1]: 
    3596             if len(line) != 0: 
    3597                 item = line.split(',') 
    3598                 check = item[1] 
    3599                 name = item[0] 
    3600                 value = item[2] 
    3601                 # Transfer the text to content[dictionary] 
    3602                 context[name] = [check, value] 
    3603  
    3604                 # limits 
    3605                 try: 
    3606                     limit_lo = item[3] 
    3607                     context[name].append(limit_lo) 
    3608                     limit_hi = item[4] 
    3609                     context[name].append(limit_hi) 
    3610                 except: 
    3611                     pass 
    3612  
    3613                 # Polydisp 
    3614                 if len(item) > 5: 
    3615                     value = item[5] 
    3616                     context[name].append(value) 
    3617                     try: 
    3618                         value = item[6] 
    3619                         context[name].append(value) 
    3620                         value = item[7] 
    3621                         context[name].append(value) 
    3622                     except IndexError: 
    3623                         pass 
    3624  
    3625         if str(self.cbModel.currentText()) != str(context['model_name'][0]) or \ 
    3626                 str(self.cbStructureFactor.currentText()) != str(context['structure_factor'][0]): 
     3651        if 'multiplicity' in line_dict.keys(): 
     3652            multip = int(line_dict['multiplicity'][0], 0) 
     3653            # reset the model with multiplicity, so further updates are saved 
     3654            if self.kernel_module.is_multiplicity_model: 
     3655                self.kernel_module.multiplicity=multip 
     3656                self.updateMultiplicityCombo(multip) 
     3657 
     3658        if 'polydisperse_params' in line_dict.keys(): 
     3659            self.chkPolydispersity.setChecked(line_dict['polydisperse_params'][0]=='True') 
     3660        if 'magnetic_params' in line_dict.keys(): 
     3661            self.chkMagnetism.setChecked(line_dict['magnetic_params'][0]=='True') 
     3662        if 'chainfit_params' in line_dict.keys(): 
     3663            self.chkChainFit.setChecked(line_dict['chainfit_params'][0]=='True') 
     3664        if '2D_params' in line_dict.keys(): 
     3665            self.chk2DView.setChecked(line_dict['2D_params'][0]=='True') 
     3666 
     3667        # Create the context dictionary for parameters 
     3668        context['model_name'] = model 
     3669        for key, value in line_dict.items(): 
     3670            if len(value) > 2: 
     3671                context[key] = value 
     3672 
     3673        if str(self.cbModel.currentText()) != str(context['model_name']): 
    36273674            msg = QtWidgets.QMessageBox() 
    36283675            msg.setIcon(QtWidgets.QMessageBox.Information) 
     
    36363683                return 
    36373684 
     3685        if 'smearing' in line_dict.keys(): 
     3686            try: 
     3687                index = int(line_dict['smearing'][0]) 
     3688                self.smearing_widget.cbSmearing.setCurrentIndex(index) 
     3689            except ValueError: 
     3690                pass 
     3691        if 'smearing_min' in line_dict.keys(): 
     3692            try: 
     3693                self.smearing_widget.dq_l = float(line_dict['smearing_min'][0]) 
     3694            except ValueError: 
     3695                pass 
     3696        if 'smearing_max' in line_dict.keys(): 
     3697            try: 
     3698                self.smearing_widget.dq_r = float(line_dict['smearing_max'][0]) 
     3699            except ValueError: 
     3700                pass 
     3701 
     3702        if 'q_range_max' in line_dict.keys(): 
     3703            try: 
     3704                self.q_range_min = float(line_dict['q_range_min'][0]) 
     3705                self.q_range_max = float(line_dict['q_range_max'][0]) 
     3706            except ValueError: 
     3707                pass 
     3708        self.options_widget.updateQRange(self.q_range_min, self.q_range_max, self.npts) 
     3709 
    36383710        self.updateFullModel(context) 
    36393711        self.updateFullPolyModel(context) 
     3712        self.updateFullMagnetModel(context) 
     3713 
     3714    def updateMultiplicityCombo(self, multip): 
     3715        """ 
     3716        Find and update the multiplicity combobox 
     3717        """ 
     3718        index = self._model_model.index(self._n_shells_row, 1) 
     3719        widget = self.lstParams.indexWidget(index) 
     3720        if widget is not None and isinstance(widget, QtWidgets.QComboBox): 
     3721            widget.setCurrentIndex(widget.findText(str(multip))) 
     3722        self.current_shell_displayed = multip 
    36403723 
    36413724    def updateFullModel(self, param_dict): 
     
    36533736            if param_name not in list(param_dict.keys()): 
    36543737                return 
     3738            # Special case of combo box in the cell (multiplicity) 
     3739            param_line = param_dict[param_name] 
     3740            if len(param_line) == 1: 
     3741                # modify the shells value 
     3742                try: 
     3743                    combo_index = int(param_line[0]) 
     3744                except ValueError: 
     3745                    # quietly pass 
     3746                    return 
     3747                index = self._model_model.index(row, 1) 
     3748                widget = self.lstParams.indexWidget(index) 
     3749                if widget is not None and isinstance(widget, QtWidgets.QComboBox): 
     3750                    #widget.setCurrentIndex(combo_index) 
     3751                    return 
    36553752            # checkbox state 
    36563753            param_checked = QtCore.Qt.Checked if param_dict[param_name][0] == "True" else QtCore.Qt.Unchecked 
    36573754            self._model_model.item(row, 0).setCheckState(param_checked) 
    36583755 
    3659             # modify the param value 
    3660             param_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 
    3661             self._model_model.item(row, 1).setText(param_repr) 
     3756            # parameter value can be either just a value or text on the combobox 
     3757            param_text = param_dict[param_name][1] 
     3758            index = self._model_model.index(row, 1) 
     3759            widget = self.lstParams.indexWidget(index) 
     3760            if widget is not None and isinstance(widget, QtWidgets.QComboBox): 
     3761                # Find the right index based on text 
     3762                combo_index = int(param_text, 0) 
     3763                widget.setCurrentIndex(combo_index) 
     3764            else: 
     3765                # modify the param value 
     3766                param_repr = GuiUtils.formatNumber(param_text, high=True) 
     3767                self._model_model.item(row, 1).setText(param_repr) 
    36623768 
    36633769            # Potentially the error column 
     
    36653771            if len(param_dict[param_name])>4 and self.has_error_column: 
    36663772                # error values are not editable - no need to update 
    3667                 #error_repr = GuiUtils.formatNumber(param_dict[param_name][2], high=True) 
    3668                 #self._model_model.item(row, 2).setText(error_repr) 
    36693773                ioffset = 1 
    36703774            # min/max 
     
    36793783            self.setFocus() 
    36803784 
    3681         # block signals temporarily, so we don't end up 
    3682         # updating charts with every single model change on the end of fitting 
    3683         self._model_model.blockSignals(True) 
    36843785        self.iterateOverModel(updateFittedValues) 
    3685         self._model_model.blockSignals(False) 
    3686  
    36873786 
    36883787    def updateFullPolyModel(self, param_dict): 
     
    37313830            self.setFocus() 
    37323831 
    3733         # block signals temporarily, so we don't end up 
    3734         # updating charts with every single model change on the end of fitting 
    3735         self._poly_model.blockSignals(True) 
    37363832        self.iterateOverPolyModel(updateFittedValues) 
    3737         self._poly_model.blockSignals(False) 
    3738  
    3739  
    3740  
     3833 
     3834    def updateFullMagnetModel(self, param_dict): 
     3835        """ 
     3836        Update the magnetism model with new parameters, create the errors column 
     3837        """ 
     3838        assert isinstance(param_dict, dict) 
     3839        if not dict: 
     3840            return 
     3841 
     3842        def updateFittedValues(row): 
     3843            # Utility function for main model update 
     3844            # internal so can use closure for param_dict 
     3845            if row >= self._magnet_model.rowCount(): 
     3846                return 
     3847            param_name = str(self._magnet_model.item(row, 0).text()).rsplit()[-1] 
     3848            if param_name not in list(param_dict.keys()): 
     3849                return 
     3850            # checkbox state 
     3851            param_checked = QtCore.Qt.Checked if param_dict[param_name][0] == "True" else QtCore.Qt.Unchecked 
     3852            self._magnet_model.item(row,0).setCheckState(param_checked) 
     3853 
     3854            # modify the param value 
     3855            param_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 
     3856            self._magnet_model.item(row, 1).setText(param_repr) 
     3857 
     3858            # Potentially the error column 
     3859            ioffset = 0 
     3860            if len(param_dict[param_name])>4 and self.has_magnet_error_column: 
     3861                ioffset = 1 
     3862            # min 
     3863            param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 
     3864            self._magnet_model.item(row, 2+ioffset).setText(param_repr) 
     3865            # max 
     3866            param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 
     3867            self._magnet_model.item(row, 3+ioffset).setText(param_repr) 
     3868 
     3869        self.iterateOverMagnetModel(updateFittedValues) 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py

    ra4b9b7a rd2007a8  
    10101010 
    10111011        # Change another parameter 
    1012         self.widget._model_model.item(2, 1).setText("3.0") 
     1012        self.widget._model_model.item(3, 1).setText("3.0") 
     1013 
    10131014        # Check that the stack is updated 
    10141015        self.assertEqual(len(self.widget.page_stack), 2) 
Note: See TracChangeset for help on using the changeset viewer.