Changeset 8c945ec in sasview for src/sas/sasgui/perspectives/fitting
- Timestamp:
- Sep 18, 2017 10:07:49 PM (7 years ago)
- 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:
- 66acafe, fca1f50
- Parents:
- 3152a02 (diff), 5c1c486 (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. - git-author:
- Paul Butler <butlerpd@…> (09/18/17 22:07:49)
- git-committer:
- GitHub <noreply@…> (09/18/17 22:07:49)
- Location:
- src/sas/sasgui/perspectives/fitting
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/fitting/basepage.py
r914c49d5 rb76e65a 2929 2929 return False 2930 2930 2931 2932 def _get_copy_params_details(self): 2933 """ 2934 Combines polydisperse parameters with self.parameters so that they can 2935 be written to the clipboard (for Excel or LaTeX). Also returns a list of 2936 the names of parameters that have been fitted 2937 2938 :returns: all_params - A list of all parameters, in the format of 2939 self.parameters 2940 :returns: fitted_par_names - A list of the names of parameters that have 2941 been fitted 2942 """ 2943 # Names of params that are being fitted 2944 fitted_par_names = [param[1] for param in self.param_toFit] 2945 # Names of params with associated polydispersity 2946 disp_params = [param[1].split('.')[0] for param in self.fittable_param] 2947 2948 # Create array of all parameters 2949 all_params = copy.copy(self.parameters) 2950 for param in self.parameters: 2951 if param[1] in disp_params: 2952 # Polydisperse params aren't in self.parameters, so need adding 2953 # to all_params 2954 name = param[1] + ".width" 2955 index = all_params.index(param) + 1 2956 to_insert = [] 2957 if name in fitted_par_names: 2958 # Param is fitted, so already has a param list in self.param_toFit 2959 to_insert = self.param_toFit[fitted_par_names.index(name)] 2960 else: 2961 # Param isn't fitted, so mockup a param list 2962 to_insert = [None, name, self.model.getParam(name), None, None] 2963 all_params.insert(index, to_insert) 2964 return all_params, fitted_par_names 2965 2931 2966 def get_copy_excel(self): 2932 2967 """ … … 2942 2977 Get the string copies of the param names and values in the tap 2943 2978 """ 2979 if not self.parameters: 2980 # Do nothing if parameters doesn't exist 2981 return False 2982 2944 2983 content = '' 2945 2946 2984 crlf = chr(13) + chr(10) 2947 2985 tab = chr(9) 2948 2986 2949 # Do it if params exist 2950 if self.parameters: 2951 2952 for param in self.parameters: 2953 content += param[1] # parameter name 2987 all_params, fitted_param_names = self._get_copy_params_details() 2988 2989 # Construct row of parameter names 2990 for param in all_params: 2991 name = param[1] # Parameter name 2992 content += name 2993 content += tab 2994 if name in fitted_param_names: 2995 # Only print errors for fitted parameters 2996 content += name + "_err" 2954 2997 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 2998 2999 content += crlf 3000 3001 # Construct row of parameter values and errors 3002 for param in all_params: 3003 value = param[2] 3004 if hasattr(value, 'GetValue'): 3005 # param[2] is a text box 3006 value = value.GetValue() 3007 else: 3008 # param[2] is a float (from our self._get_copy_params_details) 3009 value = str(value) 3010 content += value 3011 content += tab 3012 if param[1] in fitted_param_names: 3013 # Only print errors for fitted parameters 3014 content += param[4].GetValue() 3015 content += tab 3016 3017 return content 2970 3018 2971 3019 def get_copy_latex(self): … … 2982 3030 Get the string copies of the param names and values in the tap 2983 3031 """ 3032 if not self.parameters: 3033 # Do nothing if self.parameters doesn't exist 3034 return False 3035 2984 3036 content = '\\begin{table}' 2985 3037 content += '\\begin{tabular}[h]' … … 2988 3040 tab = chr(9) 2989 3041 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 3042 all_params, fitted_param_names = self._get_copy_params_details() 3043 3044 content += '{|' 3045 for param in all_params: 3046 content += 'l|l|' 3047 content += '}\hline' 3048 content += crlf 3049 3050 # Construct row of parameter names 3051 for index, param in enumerate(all_params): 3052 name = param[1] # Parameter name 3053 content += name.replace('_', '\_') # Escape underscores 3054 if name in fitted_param_names: 3055 # Only print errors for fitted parameters 3001 3056 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 3057 content += name.replace('_', '\_') + "\_err" 3058 if index < len(all_params) - 1: 3011 3059 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 3060 3061 content += '\\\\ \\hline' 3062 content += crlf 3063 3064 # Construct row of values and errors 3065 for index, param in enumerate(all_params): 3066 value = param[2] 3067 if hasattr(value, "GetValue"): 3068 # value is a text box 3069 value = value.GetValue() 3070 else: 3071 # value is a float (from self._get_copy_params_details) 3072 value = str(value) 3073 content += value 3074 if param[1] in fitted_param_names: 3075 # Only print errors for fitted params 3076 content += ' & ' 3077 content += param[4].GetValue() 3078 if index < len(all_params) - 1: 3079 content += ' & ' 3080 3081 content += '\\\\ \\hline' 3082 content += crlf 3083 content += '\\end{tabular}' 3084 content += '\\end{table}' 3085 3086 return content 3023 3087 3024 3088 def set_clipboard(self, content=None): -
src/sas/sasgui/perspectives/fitting/fitpage.py
red2276f r0b6f83c 289 289 self.btFitHelp.SetToolTipString("General fitting help.") 290 290 self.btFitHelp.Bind(wx.EVT_BUTTON, self._onFitHelp) 291 291 292 292 # Resolution Smearing Help button (for now use same technique as 293 293 # used for dI help to get tiniest possible button that works … … 303 303 self.btSmearHelp.SetToolTipString("Resolution smearing help.") 304 304 self.btSmearHelp.Bind(wx.EVT_BUTTON, self._onSmearHelp) 305 305 306 306 # textcntrl for custom resolution 307 307 self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY, … … 564 564 sizer.Add(self.draw_button, 0, 0) 565 565 sizer.Add((-1, 5)) 566 566 567 567 sizer.Add(self.tcChi, 0, 0) 568 568 sizer.Add(self.Npts_fit, 0, 0) … … 570 570 sizer.Add(self.btFit, 0, 0) 571 571 sizer.Add(self.btFitHelp, 0, 0) 572 572 573 573 boxsizer_range.Add(sizer_chi2) 574 574 boxsizer_range.Add(sizer) … … 2181 2181 self.save_current_state() 2182 2182 2183 if not self.is_mac: 2184 self.Layout() 2185 self.Refresh() 2183 2186 # plot model ( when drawing, do not update chisqr value again) 2184 2187 self._draw_model(update_chisqr=False, source='fit') … … 2775 2778 else: 2776 2779 return cmp(a.lower(), b.lower()) 2777 2780 2778 2781 # keys obtained now from ordered dict, so commenting alphabetical 2779 2782 # ordering keys.sort(custom_compare) -
src/sas/sasgui/perspectives/fitting/fitpanel.py
r67b0a99 r6f9abd3 501 501 if data is None: 502 502 return None 503 focused_page = self.GetPage(self.GetSelection()) 503 504 for page in self.opened_pages.values(): 504 505 # check if the selected data existing in the fitpanel 505 506 pos = self.GetPageIndex(page) 506 507 if not check_data_validity(page.get_data()) and not page.batch_on: 508 if page.model is not None and page != focused_page: 509 # Page has an active theory and is in background - don't 510 # send data here. 511 continue 507 512 # make sure data get placed in 1D empty tab if data is 1D 508 513 # else data get place on 2D tab empty tab -
src/sas/sasgui/perspectives/fitting/fitting.py
r2d9526d r5c1c486 1326 1326 1327 1327 is_data2d = issubclass(data.__class__, Data2D) 1328 # check consistency of arrays1328 # Check consistency of arrays 1329 1329 if not is_data2d: 1330 1330 if len(res.theory) == len(res.index[res.index]) and \ … … 1337 1337 new_theory[res.index == False] = np.nan 1338 1338 correct_result = True 1339 # get all fittable parameters of the current model1339 # Get all fittable parameters of the current model 1340 1340 param_list = model.getParamList() 1341 1341 for param in model.getDispParamList(): 1342 if not model.is_fittable(param) and \ 1342 if '.' in param and param in param_list: 1343 # Ensure polydispersity results are displayed 1344 p1, p2 = param.split('.') 1345 if not model.is_fittable(p1) and not (p2 == 'width' and param in res.param_list)\ 1346 and param in param_list: 1347 param_list.remove(param) 1348 elif not model.is_fittable(param) and \ 1343 1349 param in param_list: 1344 1350 param_list.remove(param) … … 1361 1367 batch_outputs["Chi2"].append(ERROR) 1362 1368 for param in param_list: 1363 # save value of fixed parameters1369 # Save value of fixed parameters 1364 1370 if param not in res.param_list: 1365 1371 batch_outputs[str(param)].append(ERROR) 1366 1372 else: 1367 # save only fitted values1373 # Save only fitted values 1368 1374 batch_outputs[param].append(ERROR) 1369 1375 batch_inputs["error on %s" % str(param)].append(ERROR) -
src/sas/sasgui/perspectives/fitting/media/fitting_help.rst
r05b0bf6 rca383a0 195 195 the :ref:`Advanced_Plugin_Editor` . 196 196 197 **SasView version 4.2** made it possible to specify whether a plugin created with 198 the *New Plugin Model* dialog is actually a form factor P(Q) or a structure factor 199 S(Q). To do this, simply add one or other of the following lines under the *import* 200 statements. 201 202 For a form factor:: 203 204 form_factor = True 205 206 or for a structure factor:: 207 208 structure_factor = True 209 210 If the plugin is a structure factor it is *also* necessary to add two variables to 211 the parameter list:: 212 213 parameters = [ 214 ['radius_effective', '', 1, [0.0, numpy.inf], 'volume', ''], 215 ['volfraction', '', 1, [0.0, 1.0], '', ''], 216 [...], 217 218 and to the declarations of the functions Iq and Iqxy::: 219 220 def Iq(x , radius_effective, volfraction, ...): 221 222 def Iqxy(x, y, radius_effective, volfraction, ...): 223 224 Such a plugin should then be available in the S(Q) drop-down box on a FitPage (once 225 a P(Q) model has been selected). 226 197 227 Sum|Multi(p1,p2) 198 228 ^^^^^^^^^^^^^^^^ … … 206 236 or:: 207 237 208 Plugin Model = scale_factor * model_1 /* model_2+ background238 Plugin Model = scale_factor * (model1 * model2) + background 209 239 210 240 In the *Easy Sum/Multi Editor* give the new model a function name and brief 211 241 description (to appear under the *Details* button on the *FitPage*). Then select 212 242 two existing models, as p1 and p2, and the required operator, '+' or '*' between 213 them. Finally, click the *Apply* button to generate the model and then click *Close*. 214 215 Any changes to a plugin model generated in this way only become effective *after* it is re-selected from the model drop-down menu on the FitPage. 243 them. Finally, click the *Apply* button to generate and test the model and then click *Close*. 244 245 Any changes to a plugin model generated in this way only become effective *after* it is re-selected 246 from the plugin models drop-down menu on the FitPage. If the model is not listed you can force a 247 recompilation of the plugins by selecting *Fitting* > *Plugin Model Operations* > *Load Plugin Models*. 248 249 **SasView version 4.2** introduced a much simplified and more extensible structure for plugin models 250 generated through the Easy Sum/Multi Editor. For example, the code for a combination of a sphere model 251 with a power law model now looks like this:: 252 253 from sasmodels.core import load_model_info 254 from sasmodels.sasview_model import make_model_from_info 255 256 model_info = load_model_info('sphere+power_law') 257 model_info.name = 'MyPluginModel' 258 model_info.description = 'sphere + power_law' 259 Model = make_model_from_info(model_info) 260 261 To change the models or operators contributing to this plugin it is only necessary to edit the string 262 in the brackets after *load_model_info*, though it would also be a good idea to update the model name 263 and description too!!! 264 265 The model specification string can handle multiple models and combinations of operators (+ or *) which 266 are processed according to normal conventions. Thus 'model1+model2*model3' would be valid and would 267 multiply model2 by model3 before adding model1. In this example, parameters in the *FitPage* would be 268 prefixed A (for model2), B (for model3) and C (for model1). Whilst this might appear a little 269 confusing, unless you were creating a plugin model from multiple instances of the same model the parameter 270 assignments ought to be obvious when you load the plugin. 271 272 If you need to include another plugin model in the model specification string, just prefix the name of 273 that model with *custom*. For instance:: 274 275 sphere+custom.MyPluginModel 276 277 To create a P(Q)*\S(Q) model use the @ symbol instead of * like this:: 278 279 sphere@hardsphere 280 281 This streamlined approach to building complex plugin models from existing library models, or models 282 available on the *Model Marketplace*, also permits the creation of P(Q)*\S(Q) plugin models, something 283 that was not possible in earlier versions of SasView. 216 284 217 285 .. _Advanced_Plugin_Editor: -
src/sas/sasgui/perspectives/fitting/media/plugin.rst
r72100ee re081946 18 18 * By writing a model from scratch outside of SasView (only recommended for 19 19 code monkeys!) 20 21 **What follows below is quite technical. If you just want a helping hand to get 22 started creating your own models see** :ref:`Adding_your_own_models`. 20 23 21 24 Overview
Note: See TracChangeset
for help on using the changeset viewer.