Changeset 13374be in sasview for src/sas/sasgui/perspectives/fitting


Ignore:
Timestamp:
Sep 20, 2017 7:55:53 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, 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, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
fca1f50
Parents:
6d62b7f (diff), 2a399ca (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 'master' into 4_1_issues

Location:
src/sas/sasgui/perspectives/fitting
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r914c49d5 r66acafe  
    18411841            if models.name != "NoStructure": 
    18421842                mlist.append((models.name, models)) 
    1843  
    18441843        # Sort the models 
    18451844        mlist_sorted = sorted(mlist) 
     
    29292928            return False 
    29302929 
     2930 
     2931    def _get_copy_params_details(self): 
     2932        """ 
     2933        Combines polydisperse parameters with self.parameters so that they can 
     2934        be written to the clipboard (for Excel or LaTeX). Also returns a list of 
     2935        the names of parameters that have been fitted 
     2936 
     2937        :returns: all_params - A list of all parameters, in the format of  
     2938        self.parameters 
     2939        :returns: fitted_par_names - A list of the names of parameters that have 
     2940        been fitted 
     2941        """ 
     2942        # Names of params that are being fitted 
     2943        fitted_par_names = [param[1] for param in self.param_toFit] 
     2944        # Names of params with associated polydispersity 
     2945        disp_params = [param[1].split('.')[0] for param in self.fittable_param] 
     2946 
     2947        # Create array of all parameters 
     2948        all_params = copy.copy(self.parameters) 
     2949        for param in self.parameters: 
     2950            if param[1] in disp_params: 
     2951                # Polydisperse params aren't in self.parameters, so need adding 
     2952                # to all_params 
     2953                name = param[1] + ".width" 
     2954                index = all_params.index(param) + 1 
     2955                to_insert = [] 
     2956                if name in fitted_par_names: 
     2957                    # Param is fitted, so already has a param list in self.param_toFit 
     2958                    to_insert = self.param_toFit[fitted_par_names.index(name)] 
     2959                else: 
     2960                    # Param isn't fitted, so mockup a param list 
     2961                    to_insert = [None, name, self.model.getParam(name), None, None] 
     2962                all_params.insert(index, to_insert) 
     2963        return all_params, fitted_par_names 
     2964 
    29312965    def get_copy_excel(self): 
    29322966        """ 
     
    29422976        Get the string copies of the param names and values in the tap 
    29432977        """ 
     2978        if not self.parameters: 
     2979            # Do nothing if parameters doesn't exist 
     2980            return False 
     2981 
    29442982        content = '' 
    2945  
    29462983        crlf = chr(13) + chr(10) 
    29472984        tab = chr(9) 
    29482985 
    2949         # Do it if params exist 
    2950         if self.parameters: 
    2951  
    2952             for param in self.parameters: 
    2953                 content += param[1]  # parameter name 
     2986        all_params, fitted_param_names = self._get_copy_params_details() 
     2987 
     2988        # Construct row of parameter names 
     2989        for param in all_params: 
     2990            name = param[1] # Parameter name 
     2991            content += name 
     2992            content += tab 
     2993            if name in fitted_param_names: 
     2994                # Only print errors for fitted parameters 
     2995                content += name + "_err" 
    29542996                content += tab 
    2955                 content += param[1] + "_err" 
    2956                 content += tab 
    2957  
    2958             content += crlf 
    2959  
    2960             # row of values and errors... 
    2961             for param in self.parameters: 
    2962                 content += param[2].GetValue()  # value 
    2963                 content += tab 
    2964                 content += param[4].GetValue()  # error 
    2965                 content += tab 
    2966  
    2967             return content 
    2968         else: 
    2969             return False 
     2997 
     2998        content += crlf 
     2999 
     3000        # Construct row of parameter values and errors 
     3001        for param in all_params: 
     3002            value = param[2] 
     3003            if hasattr(value, 'GetValue'): 
     3004                # param[2] is a text box 
     3005                value = value.GetValue() 
     3006            else: 
     3007                # param[2] is a float (from our self._get_copy_params_details) 
     3008                value = str(value) 
     3009            content += value 
     3010            content += tab 
     3011            if param[1] in fitted_param_names: 
     3012                # Only print errors for fitted parameters 
     3013                content += param[4].GetValue() 
     3014                content += tab  
     3015 
     3016        return content 
    29703017 
    29713018    def get_copy_latex(self): 
     
    29823029        Get the string copies of the param names and values in the tap 
    29833030        """ 
     3031        if not self.parameters: 
     3032            # Do nothing if self.parameters doesn't exist 
     3033            return False 
     3034         
    29843035        content = '\\begin{table}' 
    29853036        content += '\\begin{tabular}[h]' 
     
    29883039        tab = chr(9) 
    29893040 
    2990         # Do it if params exist 
    2991         if self.parameters: 
    2992  
    2993             content += '{|' 
    2994             for param in self.parameters: 
    2995                 content += 'l|l|' 
    2996             content += '}\hline' 
    2997             content += crlf 
    2998  
    2999             for index, param in enumerate(self.parameters): 
    3000                 content += param[1].replace('_', '\_')  # parameter name 
     3041        all_params, fitted_param_names = self._get_copy_params_details() 
     3042 
     3043        content += '{|' 
     3044        for param in all_params: 
     3045            content += 'l|l|' 
     3046        content += '}\hline' 
     3047        content += crlf 
     3048 
     3049        # Construct row of parameter names 
     3050        for index, param in enumerate(all_params): 
     3051            name = param[1] # Parameter name 
     3052            content += name.replace('_', '\_')  # Escape underscores 
     3053            if name in fitted_param_names: 
     3054                # Only print errors for fitted parameters 
    30013055                content += ' & ' 
    3002                 content += param[1].replace('_', '\_') + "\_err" 
    3003                 if index < len(self.parameters) - 1: 
    3004                     content += ' & ' 
    3005             content += '\\\\ \\hline' 
    3006             content += crlf 
    3007  
    3008             # row of values and errors... 
    3009             for index, param in enumerate(self.parameters): 
    3010                 content += param[2].GetValue()  # parameter value 
     3056                content += name.replace('_', '\_') + "\_err" 
     3057            if index < len(all_params) - 1: 
    30113058                content += ' & ' 
    3012                 content += param[4].GetValue()  # parameter error 
    3013                 if index < len(self.parameters) - 1: 
    3014                     content += ' & ' 
    3015             content += '\\\\ \\hline' 
    3016             content += crlf 
    3017  
    3018             content += '\\end{tabular}' 
    3019             content += '\\end{table}' 
    3020             return content 
    3021         else: 
    3022             return False 
     3059 
     3060        content += '\\\\ \\hline' 
     3061        content += crlf 
     3062 
     3063        # Construct row of values and errors 
     3064        for index, param in enumerate(all_params): 
     3065            value = param[2] 
     3066            if hasattr(value, "GetValue"): 
     3067                # value is a text box 
     3068                value = value.GetValue() 
     3069            else: 
     3070                # value is a float (from self._get_copy_params_details) 
     3071                value = str(value) 
     3072            content += value 
     3073            if param[1] in fitted_param_names: 
     3074                # Only print errors for fitted params 
     3075                content += ' & ' 
     3076                content += param[4].GetValue() 
     3077            if index < len(all_params) - 1: 
     3078                content += ' & ' 
     3079         
     3080        content += '\\\\ \\hline' 
     3081        content += crlf 
     3082        content += '\\end{tabular}' 
     3083        content += '\\end{table}' 
     3084 
     3085        return content 
    30233086 
    30243087    def set_clipboard(self, content=None): 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r6a455cd3 r13374be  
    289289        self.btFitHelp.SetToolTipString("General fitting help.") 
    290290        self.btFitHelp.Bind(wx.EVT_BUTTON, self._onFitHelp) 
    291          
     291 
    292292        # Resolution Smearing Help button (for now use same technique as 
    293293        # used for dI help to get tiniest possible button that works 
     
    303303        self.btSmearHelp.SetToolTipString("Resolution smearing help.") 
    304304        self.btSmearHelp.Bind(wx.EVT_BUTTON, self._onSmearHelp) 
    305          
     305 
    306306        # textcntrl for custom resolution 
    307307        self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY, 
     
    564564        sizer.Add(self.draw_button, 0, 0) 
    565565        sizer.Add((-1, 5)) 
    566          
     566 
    567567        sizer.Add(self.tcChi, 0, 0) 
    568568        sizer.Add(self.Npts_fit, 0, 0) 
     
    570570        sizer.Add(self.btFit, 0, 0) 
    571571        sizer.Add(self.btFitHelp, 0, 0) 
    572          
     572 
    573573        boxsizer_range.Add(sizer_chi2) 
    574574        boxsizer_range.Add(sizer) 
     
    11561156                copy_flag = self.get_copy_params() 
    11571157                is_poly_enabled = self.enable_disp.GetValue() 
    1158  
    1159         self._on_select_model_helper() 
     1158        try: 
     1159            self._on_select_model_helper() 
     1160        except Exception as e: 
     1161            evt = StatusEvent(status=e.message, info="error") 
     1162            wx.PostEvent(self._manager.parent, evt) 
     1163            # Set S(Q) to None 
     1164            self.structurebox.SetSelection(0) 
     1165            self._on_select_model() 
     1166            return 
    11601167        self.set_model_param_sizer(self.model) 
    11611168        if self.model is None: 
     
    21852192        self.save_current_state() 
    21862193 
     2194        if not self.is_mac: 
     2195            self.Layout() 
     2196            self.Refresh() 
    21872197        # plot model ( when drawing, do not update chisqr value again) 
    21882198        self._draw_model(update_chisqr=False, source='fit') 
     
    27792789            else: 
    27802790                return cmp(a.lower(), b.lower()) 
    2781          
     2791 
    27822792        # keys obtained now from ordered dict, so commenting alphabetical 
    27832793        # ordering keys.sort(custom_compare) 
  • src/sas/sasgui/perspectives/fitting/fitpanel.py

    rc9ecd1b r13374be  
    503503            if data is None: 
    504504                return None 
     505        focused_page = self.GetPage(self.GetSelection()) 
    505506        for page in self.opened_pages.values(): 
    506507            # check if the selected data existing in the fitpanel 
    507508            pos = self.GetPageIndex(page) 
    508509            if not check_data_validity(page.get_data()) and not page.batch_on: 
     510                if page.model is not None and page != focused_page: 
     511                    # Page has an active theory and is in background - don't 
     512                    # send data here. 
     513                    continue 
    509514                # make sure data get placed in 1D empty tab if data is 1D 
    510515                # else data get place on 2D tab empty tab 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r2d9526d r66acafe  
    357357                            else: 
    358358                                page.formfactorbox.SetLabel(current_val) 
     359                        if hasattr(page, 'structurebox'): 
     360                            selected_name = page.structurebox.GetStringSelection() 
     361 
     362                            page.structurebox.Clear() 
     363                            page.initialize_combox() 
     364 
     365                            index = page.structurebox.FindString(selected_name) 
     366                            if index == -1: 
     367                                index = 0 
     368                            page.structurebox.SetSelection(index) 
     369                            page._on_select_model() 
    359370        except: 
    360371            logger.error("update_custom_combo: %s", sys.exc_value) 
     
    13261337 
    13271338                is_data2d = issubclass(data.__class__, Data2D) 
    1328                 #check consistency of arrays 
     1339                # Check consistency of arrays 
    13291340                if not is_data2d: 
    13301341                    if len(res.theory) == len(res.index[res.index]) and \ 
     
    13371348                    new_theory[res.index == False] = np.nan 
    13381349                    correct_result = True 
    1339                 #get all fittable parameters of the current model 
     1350                # Get all fittable parameters of the current model 
    13401351                param_list = model.getParamList() 
    13411352                for param in model.getDispParamList(): 
    1342                     if not model.is_fittable(param) and \ 
     1353                    if '.' in param and param in param_list: 
     1354                        # Ensure polydispersity results are displayed 
     1355                        p1, p2 = param.split('.') 
     1356                        if not model.is_fittable(p1) and not (p2 == 'width' and param in res.param_list)\ 
     1357                            and param in param_list: 
     1358                            param_list.remove(param) 
     1359                    elif not model.is_fittable(param) and \ 
    13431360                        param in param_list: 
    13441361                        param_list.remove(param) 
     
    13611378                    batch_outputs["Chi2"].append(ERROR) 
    13621379                    for param in param_list: 
    1363                         # save value of  fixed parameters 
     1380                        # Save value of  fixed parameters 
    13641381                        if param not in res.param_list: 
    13651382                            batch_outputs[str(param)].append(ERROR) 
    13661383                        else: 
    1367                             #save only fitted values 
     1384                            # Save only fitted values 
    13681385                            batch_outputs[param].append(ERROR) 
    13691386                            batch_inputs["error on %s" % str(param)].append(ERROR) 
  • src/sas/sasgui/perspectives/fitting/models.py

    rb682c6a r13374be  
    1414import py_compile 
    1515import shutil 
     16from copy import copy 
    1617# Explicitly import from the pluginmodel module so that py2exe 
    1718# places it in the distribution. The Model1DPlugin class is used 
     
    281282        """ 
    282283 
    283         # regular model names only 
     284        # Regular model names only 
    284285        self.model_name_list = [] 
    285286 
    286         #Build list automagically from sasmodels package 
     287        # Build list automagically from sasmodels package 
    287288        for model in load_standard_models(): 
    288289            self.model_dictionary[model.name] = model 
     
    296297                self.model_name_list.append(model.name) 
    297298 
    298         #Looking for plugins 
     299        # Looking for plugins 
    299300        self.stored_plugins = self.findModels() 
    300301        self.plugins = self.stored_plugins.values() 
    301302        for name, plug in self.stored_plugins.iteritems(): 
    302303            self.model_dictionary[name] = plug 
     304            # TODO: Remove 'hasattr' statements when old style plugin models 
     305            # are no longer supported. All sasmodels models will have 
     306            # the required attributes. 
     307            if hasattr(plug, 'is_structure_factor') and plug.is_structure_factor: 
     308                self.struct_list.append(plug) 
     309                self.plugins.remove(plug) 
     310            elif hasattr(plug, 'is_form_factor') and plug.is_form_factor: 
     311                self.multiplication_factor.append(plug) 
     312            if hasattr(plug, 'is_multiplicity_model') and plug.is_multiplicity_model: 
     313                self.multi_func_list.append(plug) 
    303314 
    304315        self._get_multifunc_models() 
     
    343354        """ 
    344355        self.plugins = [] 
    345         new_plugins = _find_models() 
    346         for name, plug in  new_plugins.iteritems(): 
    347             for stored_name, stored_plug in self.stored_plugins.iteritems(): 
    348                 if name == stored_name: 
    349                     del self.stored_plugins[name] 
    350                     del self.model_dictionary[name] 
    351                     break 
     356        self.stored_plugins = _find_models() 
     357        structure_names = [model.name for model in self.struct_list] 
     358        form_names = [model.name for model in self.multiplication_factor] 
     359 
     360        # Remove all plugin structure factors and form factors 
     361        for name in copy(structure_names): 
     362            if '[plug-in]' in name: 
     363                i = structure_names.index(name) 
     364                del self.struct_list[i] 
     365                structure_names.remove(name) 
     366        for name in copy(form_names): 
     367            if '[plug-in]' in name: 
     368                i = form_names.index(name) 
     369                del self.multiplication_factor[i] 
     370                form_names.remove(name) 
     371 
     372        # Add new plugin structure factors and form factors 
     373        for name, plug in self.stored_plugins.iteritems(): 
     374            if plug.is_structure_factor: 
     375                if name in structure_names: 
     376                    # Delete the old model from self.struct list 
     377                    i = structure_names.index(name) 
     378                    del self.struct_list[i] 
     379                # Add the new model to self.struct_list 
     380                self.struct_list.append(plug) 
     381            elif plug.is_form_factor: 
     382                if name in form_names: 
     383                    # Delete the old model from self.multiplication_factor 
     384                    i = form_names.index(name) 
     385                    del self.multiplication_factor[i] 
     386                # Add the new model to self.multiplication_factor 
     387                self.multiplication_factor.append(plug) 
     388 
     389            # Add references to the updated model 
    352390            self.stored_plugins[name] = plug 
    353             self.plugins.append(plug) 
     391            if not plug.is_structure_factor: 
     392                # Don't show S(Q) models in the 'Plugin Models' dropdown 
     393                self.plugins.append(plug) 
    354394            self.model_dictionary[name] = plug 
    355395 
    356396        self.model_combobox.reset_list("Plugin Models", self.plugins) 
     397        self.model_combobox.reset_list("Structure Factors", self.struct_list) 
     398        self.model_combobox.reset_list("P(Q)*S(Q)", self.multiplication_factor) 
     399 
    357400        return self.model_combobox.get_list() 
    358401 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    r959eb01 rda9b239  
    617617            value = "" 
    618618            content = line.split(":") 
     619            if line == '' or len(content) == 1: 
     620                continue 
    619621            name = content[0] 
    620622            try: 
Note: See TracChangeset for help on using the changeset viewer.