Changes in / [c79304b:a235f715] in sasview
- Files:
-
- 2 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
docs/sphinx-docs/source/user/sasgui/perspectives/invariant/invariant_help.rst
r9bbc074 r5f5c596 4 4 .. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 5 5 6 Invariant Calculation 7 ===================== 6 Invariant Calculation Perspective 7 ================================= 8 8 9 9 Description … … 19 19 .. image:: image001.gif 20 20 21 where *g = q* for pinhole geometry (SAS) and *g = q*\ :sub:`v`(the slit height) for21 where *g = Q* for pinhole geometry (SAS) and *g = Qv* (the slit height) for 22 22 slit geometry (USAS). 23 23 … … 45 45 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 46 46 47 Using invariant analysis48 --------------------- ---47 Using the perspective 48 --------------------- 49 49 50 50 1) Select *Invariant* from the *Analysis* menu on the SasView toolbar. … … 53 53 54 54 3) Select a dataset and use the *Send To* button on the *Data Explorer* to load 55 the dataset into the *Invariant* p anel.55 the dataset into the *Invariant* perspective. 56 56 57 4) Use the *Customised Input* boxes on the *Invariant* p anelto subtract57 4) Use the *Customised Input* boxes on the *Invariant* perspective to subtract 58 58 any background, specify the contrast (i.e. difference in SLDs - this must be 59 59 specified for the eventual value of Q*\ to be on an absolute scale), or to … … 73 73 74 74 8) If the value of Q*\ calculated with the extrapolated regions is invalid, a 75 red warning will appear at the top of the *Invariant* p anel.75 red warning will appear at the top of the *Invariant* perspective panel. 76 76 77 77 The details of the calculation are available by clicking the *Details* -
docs/sphinx-docs/source/user/user.rst
r20a3c55 r5a71761 14 14 15 15 Working with SasView <working> 16 17 Computations with GPU <gpu_computations> -
sasview/local_config.py
r9bbc074 rd85c194 82 82 _corner_image = os.path.join(icon_path, "angles_flat.png") 83 83 _welcome_image = os.path.join(icon_path, "SVwelcome.png") 84 _copyright = "(c) 2009 - 201 6, UTK, UMD, NIST, ORNL, ISIS, ESS and ILL"84 _copyright = "(c) 2009 - 2013, UTK, UMD, NIST, ORNL, ISIS, ESS and ILL" 85 85 86 86 -
sasview/setup_exe.py
r9bbc074 r525aaa2 165 165 self.version = local_config.__version__ 166 166 self.company_name = "SasView.org" 167 self.copyright = "copyright 2009 - 201 6"167 self.copyright = "copyright 2009 - 2013" 168 168 self.name = "SasView" 169 169 -
src/sas/sasgui/guiframe/utils.py
ra0373d5 rd85c194 46 46 return flag 47 47 48 49 def check_int(item): 50 """ 51 :param item: txtcrtl containing a value 52 """ 53 flag = True 54 try: 55 mini = int(item.GetValue()) 56 item.SetBackgroundColour(wx.WHITE) 57 item.Refresh() 58 except: 59 flag = False 60 item.SetBackgroundColour("pink") 61 item.Refresh() 62 return flag 63 64 48 65 49 class PanelMenu(wx.Menu): 66 50 """ -
src/sas/sasgui/perspectives/fitting/basepage.py
r6c382da ree4b3cb 17 17 from wx.lib.scrolledpanel import ScrolledPanel 18 18 19 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 20 19 import sasmodels.sasview_model 21 20 from sas.sasgui.guiframe.panel_base import PanelBase 22 from sas.sasgui.guiframe.utils import format_number, check_float, IdList , check_int21 from sas.sasgui.guiframe.utils import format_number, check_float, IdList 23 22 from sas.sasgui.guiframe.events import PanelOnFocusEvent 24 23 from sas.sasgui.guiframe.events import StatusEvent … … 627 626 self.disp_help_bt.Bind(wx.EVT_BUTTON, self.on_pd_help_clicked, 628 627 id=self.disp_help_bt.GetId()) 629 self.disp_help_bt.SetToolTipString("Help for polydispersion.")628 self.disp_help_bt.SetToolTipString("Helps for Polydispersion.") 630 629 631 630 self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, … … 933 932 if len(self._disp_obj_dict) > 0: 934 933 for k, v in self._disp_obj_dict.iteritems(): 935 self.state._disp_obj_dict[k] = v .type934 self.state._disp_obj_dict[k] = v 936 935 937 936 self.state.values = copy.deepcopy(self.values) … … 1010 1009 if len(self._disp_obj_dict) > 0: 1011 1010 for k, v in self._disp_obj_dict.iteritems(): 1012 self.state._disp_obj_dict[k] = v .type1011 self.state._disp_obj_dict[k] = v 1013 1012 1014 1013 self.state.values = copy.deepcopy(self.values) … … 1124 1123 state.disp_cb_dict[item]) 1125 1124 # Create the dispersion objects 1126 disp_model = POLYDISPERSITY_MODELS['array']() 1125 from sas.models.dispersion_models import ArrayDispersion 1126 disp_model = ArrayDispersion() 1127 1127 if hasattr(state, "values") and \ 1128 1128 self.disp_cb_dict[item].GetValue() == True: … … 1379 1379 self.weights = copy.deepcopy(state.weights) 1380 1380 1381 for key, disp_type in state._disp_obj_dict.iteritems(): 1382 #disp_model = disp 1383 disp_model = POLYDISPERSITY_MODELS[disp_type]() 1381 for key, disp in state._disp_obj_dict.iteritems(): 1382 # From saved file, disp_model can not be sent in model obj. 1383 # it will be sent as a string here, then converted to model object. 1384 if disp.__class__.__name__ == 'str': 1385 disp_model = None 1386 com_str = "from sasmodels.weights " 1387 com_str += "import %s as disp_func \ndisp_model = disp_func()" 1388 exec com_str % disp 1389 else: 1390 disp_model = disp 1384 1391 self._disp_obj_dict[key] = disp_model 1385 1392 param_name = key.split('.')[0] … … 2274 2281 continue 2275 2282 2276 value_ctrl = item[2] 2277 if not value_ctrl.IsEnabled(): 2278 # ArrayDispersion disables PD, Min, Max, Npts, Nsigs 2283 name = str(item[1]) 2284 if name.endswith(".npts") or name.endswith(".nsigmas"): 2279 2285 continue 2280 2286 2281 name = item[1] 2287 # Check that min, max and value are floats 2288 value_ctrl, min_ctrl, max_ctrl = item[2], item[5], item[6] 2289 min_str = min_ctrl.GetValue().strip() 2290 max_str = max_ctrl.GetValue().strip() 2282 2291 value_str = value_ctrl.GetValue().strip() 2283 if name.endswith(".npts"): 2284 validity = check_int(value_ctrl) 2285 if not validity: 2286 continue 2287 value = int(value_str) 2288 2289 elif name.endswith(".nsigmas"): 2290 validity = check_float(value_ctrl) 2291 if not validity: 2292 continue 2293 value = float(value_str) 2294 2295 else: # value or polydispersity 2296 2297 # Check that min, max and value are floats 2298 min_ctrl, max_ctrl = item[5], item[6] 2299 min_str = min_ctrl.GetValue().strip() 2300 max_str = max_ctrl.GetValue().strip() 2301 validity = check_float(value_ctrl) 2302 if min_str != "": 2303 validity = validity and check_float(min_ctrl) 2304 if max_str != "": 2305 validity = validity and check_float(max_ctrl) 2306 if not validity: 2307 continue 2308 2309 # Check that min is less than max 2310 low = -numpy.inf if min_str == "" else float(min_str) 2311 high = numpy.inf if max_str == "" else float(max_str) 2312 if high < low: 2313 min_ctrl.SetBackgroundColour("pink") 2314 min_ctrl.Refresh() 2315 max_ctrl.SetBackgroundColour("pink") 2316 max_ctrl.Refresh() 2317 #msg = "Invalid fit range for %s: min must be smaller than max"%name 2318 #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 2319 continue 2320 2321 # Force value between min and max 2322 value = float(value_str) 2323 if value < low: 2324 value = low 2325 value_ctrl.SetValue(format_number(value)) 2326 elif value > high: 2327 value = high 2328 value_ctrl.SetValue(format_number(value)) 2329 2330 if name not in self.model.details.keys(): 2331 self.model.details[name] = ["", None, None] 2332 old_low, old_high = self.model.details[name][1:3] 2333 if old_low != low or old_high != high: 2334 # The configuration has changed but it won't change the 2335 # computed curve so no need to set is_modified to True 2336 #is_modified = True 2337 self.model.details[name][1:3] = low, high 2292 validity = check_float(value_ctrl) 2293 if min_str != "": 2294 validity = validity and check_float(min_ctrl) 2295 if max_str != "": 2296 validity = validity and check_float(max_ctrl) 2297 if not validity: 2298 continue 2299 2300 # Check that min is less than max 2301 low = -numpy.inf if min_str == "" else float(min_str) 2302 high = numpy.inf if max_str == "" else float(max_str) 2303 if high < low: 2304 min_ctrl.SetBackgroundColour("pink") 2305 min_ctrl.Refresh() 2306 max_ctrl.SetBackgroundColour("pink") 2307 max_ctrl.Refresh() 2308 #msg = "Invalid fit range for %s: min must be smaller than max"%name 2309 #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 2310 continue 2311 2312 # Force value between min and max 2313 value = float(value_str) 2314 if value < low: 2315 value = low 2316 value_ctrl.SetValue(format_number(value)) 2317 elif value > high: 2318 value = high 2319 value_ctrl.SetValue(format_number(value)) 2338 2320 2339 2321 # Update value in model if it has changed … … 2341 2323 self.model.setParam(name, value) 2342 2324 is_modified = True 2325 2326 if name not in self.model.details.keys(): 2327 self.model.details[name] = ["", None, None] 2328 old_low, old_high = self.model.details[name][1:3] 2329 if old_low != low or old_high != high: 2330 # The configuration has changed but it won't change the 2331 # computed curve so no need to set is_modified to True 2332 #is_modified = True 2333 self.model.details[name][1:3] = low, high 2343 2334 2344 2335 return is_modified … … 2513 2504 self._disp_obj_dict[name1] = disp_model 2514 2505 self.model.set_dispersion(param_name, disp_model) 2515 self.state._disp_obj_dict[name1] = disp_model .type2506 self.state._disp_obj_dict[name1] = disp_model 2516 2507 2517 2508 value1 = str(format_number(self.model.getParam(name1), True)) … … 2536 2527 item[0].Enable() 2537 2528 item[2].Enable() 2538 item[3].Show(True)2539 item[4].Show(True)2540 2529 item[5].Enable() 2541 2530 item[6].Enable() … … 2630 2619 self._disp_obj_dict[name] = disp 2631 2620 self.model.set_dispersion(name.split('.')[0], disp) 2632 self.state._disp_obj_dict[name] = disp .type2621 self.state._disp_obj_dict[name] = disp 2633 2622 self.values[name] = values 2634 2623 self.weights[name] = weights … … 2698 2687 :param disp_function: dispersion distr. function 2699 2688 """ 2689 # List of the poly_model name in the combobox 2690 list = ["RectangleDispersion", "ArrayDispersion", 2691 "LogNormalDispersion", "GaussianDispersion", 2692 "SchulzDispersion"] 2693 2700 2694 # Find the selection 2701 if disp_func is not None: 2702 try: 2703 return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 2704 except ValueError: 2705 pass # Fall through to default class 2706 return POLYDISPERSITY_MODELS.keys().index('gaussian') 2695 try: 2696 selection = list.index(disp_func.__class__.__name__) 2697 return selection 2698 except: 2699 return 3 2707 2700 2708 2701 def on_reset_clicked(self, event): … … 3291 3284 pd = content[name][1] 3292 3285 if name.count('.') > 0: 3293 # If this is parameter.width, then pd may be a floating3294 # point value or it may be an array distribution.3295 # Nothing to do for parameter.npts or parameter.nsigmas.3296 3286 try: 3297 3287 float(pd) 3298 if name.endswith('.npts'): 3299 pd = int(pd) 3300 except Exception: 3288 except: 3301 3289 #continue 3302 3290 if not pd and pd != '': … … 3306 3294 # Only array func has pd == '' case. 3307 3295 item[2].Enable(False) 3308 else:3309 item[2].Enable(True)3310 3296 if item[2].__class__.__name__ == "ComboBox": 3311 3297 if content[name][1] in self.model.fun_list: … … 3334 3320 pd = value[0] 3335 3321 if name.count('.') > 0: 3336 # If this is parameter.width, then pd may be a floating3337 # point value or it may be an array distribution.3338 # Nothing to do for parameter.npts or parameter.nsigmas.3339 3322 try: 3340 3323 pd = float(pd) 3341 if name.endswith('.npts'):3342 pd = int(pd)3343 3324 except: 3344 3325 #continue … … 3349 3330 # Only array func has pd == '' case. 3350 3331 item[2].Enable(False) 3351 else:3352 item[2].Enable(True)3353 3332 if item[2].__class__.__name__ == "ComboBox": 3354 3333 if value[0] in self.model.fun_list: … … 3370 3349 Helps get paste for poly function 3371 3350 3372 *item* is the parameter name 3373 3374 *value* depends on which parameter is being processed, and whether it 3375 has array polydispersity. 3376 3377 For parameters without array polydispersity: 3378 3379 parameter => ['FLOAT', ''] 3380 parameter.width => ['FLOAT', 'DISTRIBUTION', ''] 3381 parameter.npts => ['FLOAT', ''] 3382 parameter.nsigmas => ['FLOAT', ''] 3383 3384 For parameters with array polydispersity: 3385 3386 parameter => ['FLOAT', ''] 3387 parameter.width => ['FILENAME', 'array', [x1, ...], [w1, ...]] 3388 parameter.npts => ['FLOAT', ''] 3389 parameter.nsigmas => ['FLOAT', ''] 3390 """ 3391 # Do nothing if not setting polydispersity 3392 if len(value[1]) == 0: 3393 return 3394 3395 try: 3396 name = item[7].Name 3397 param_name = name.split('.')[0] 3398 item[7].SetValue(value[1]) 3399 selection = item[7].GetCurrentSelection() 3400 dispersity = item[7].GetClientData(selection) 3401 disp_model = dispersity() 3402 3403 if value[1] == 'array': 3404 pd_vals = numpy.array(value[2]) 3405 pd_weights = numpy.array(value[3]) 3406 if len(pd_vals) == 0 or len(pd_vals) != len(pd_weights): 3407 msg = ("bad array distribution parameters for %s" 3408 % param_name) 3409 raise ValueError(msg) 3410 self._set_disp_cb(True, item=item) 3411 self._set_array_disp_model(name=name, 3412 disp=disp_model, 3413 values=pd_vals, 3414 weights=pd_weights) 3415 else: 3416 self._set_disp_cb(False, item=item) 3417 self._disp_obj_dict[name] = disp_model 3418 self.model.set_dispersion(param_name, disp_model) 3419 self.state._disp_obj_dict[name] = disp_model.type 3420 # TODO: It's not an array, why update values and weights? 3421 self.model._persistency_dict[param_name] = \ 3422 [self.values, self.weights] 3423 self.state.values = self.values 3424 self.state.weights = self.weights 3425 3426 except Exception: 3427 logging.error(traceback.format_exc()) 3428 print "Error in BasePage._paste_poly_help: %s" % \ 3429 sys.exc_info()[1] 3430 3431 def _set_disp_cb(self, isarray, item): 3351 :param item: Gui param items 3352 :param value: the values for parameter ctrols 3353 """ 3354 is_array = False 3355 if len(value[1]) > 0: 3356 # Only for dispersion func.s 3357 try: 3358 item[7].SetValue(value[1]) 3359 selection = item[7].GetCurrentSelection() 3360 name = item[7].Name 3361 param_name = name.split('.')[0] 3362 dispersity = item[7].GetClientData(selection) 3363 disp_model = dispersity() 3364 # Only for array disp 3365 try: 3366 pd_vals = numpy.array(value[2]) 3367 pd_weights = numpy.array(value[3]) 3368 if len(pd_vals) > 0 and len(pd_vals) > 0: 3369 if len(pd_vals) == len(pd_weights): 3370 self._set_disp_array_cb(item=item) 3371 self._set_array_disp_model(name=name, 3372 disp=disp_model, 3373 values=pd_vals, 3374 weights=pd_weights) 3375 is_array = True 3376 except Exception: 3377 logging.error(traceback.format_exc()) 3378 if not is_array: 3379 self._disp_obj_dict[name] = disp_model 3380 self.model.set_dispersion(name, 3381 disp_model) 3382 self.state._disp_obj_dict[name] = \ 3383 disp_model 3384 self.model.set_dispersion(param_name, disp_model) 3385 self.state.values = self.values 3386 self.state.weights = self.weights 3387 self.model._persistency_dict[param_name] = \ 3388 [self.state.values, 3389 self.state.weights] 3390 3391 except Exception: 3392 logging.error(traceback.format_exc()) 3393 print "Error in BasePage._paste_poly_help: %s" % \ 3394 sys.exc_info()[1] 3395 3396 def _set_disp_array_cb(self, item): 3432 3397 """ 3433 3398 Set cb for array disp 3434 3399 """ 3435 if isarray: 3436 item[0].SetValue(False) 3437 item[0].Enable(False) 3438 item[2].Enable(False) 3439 item[3].Show(False) 3440 item[4].Show(False) 3441 item[5].SetValue('') 3442 item[5].Enable(False) 3443 item[6].SetValue('') 3444 item[6].Enable(False) 3445 else: 3446 item[0].Enable() 3447 item[2].Enable() 3448 item[3].Show(True) 3449 item[4].Show(True) 3450 item[5].Enable() 3451 item[6].Enable() 3400 item[0].SetValue(False) 3401 item[0].Enable(False) 3402 item[2].Enable(False) 3403 item[3].Show(False) 3404 item[4].Show(False) 3405 item[5].SetValue('') 3406 item[5].Enable(False) 3407 item[6].SetValue('') 3408 item[6].Enable(False) 3452 3409 3453 3410 def update_pinhole_smear(self): -
src/sas/sasgui/perspectives/fitting/fitpage.py
r6c382da ree4b3cb 10 10 import math 11 11 import time 12 import traceback13 12 14 13 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS … … 2059 2058 msg = "Error: This model state has missing or outdated " 2060 2059 msg += "information.\n" 2061 msg += traceback.format_exc()2060 msg += "%s" % (sys.exc_value) 2062 2061 wx.PostEvent(self._manager.parent, 2063 2062 StatusEvent(status=msg, info="error")) -
src/sas/sasgui/perspectives/fitting/media/plugin.rst
re925f61 r05829fb 1 1 .. _Writing_a_Plugin: 2 2 3 Writing a Plugin Model 4 ====================== 5 6 Overview 7 ^^^^^^^^ 8 9 You can write your own model and save it to the the SasView 3 Writing a Plugin 4 ================ 5 6 Users can write their own models and save it to the the SasView 10 7 *plugin_models* folder 11 8 12 *C:\\Users\\[username]\\.sasview\\plugin_models* (on Windows)9 *C:\\Users\\[username]\\.sasview\\plugin_models* - (on Windows) 13 10 14 11 The next time SasView is started it will compile the plugin and add 15 it to the list of *Customized Models* in a FitPage. It is recommended that an12 it to the list of *Customized Models*. It is recommended that an 16 13 existing model be used as a template. 14 15 This page was originally written by our MOST experienced developers, 16 but has subsequently been edited by our LEAST experienced developer who felt 17 some instructions could have been clearer, and learnt one or two things that 18 were missing altogether! But they succeeded in converting a model that passed 19 testing, so there is no reason why you should not be able to do the same. 17 20 18 21 SasView has three ways of writing models: … … 26 29 `cylinder.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/cylinder.c>`_ 27 30 28 The built-in modules are available in the *sasmodels-data\\models* subdirectory 29 of your SasView installation folder. On Windows, this will be something like 30 *C:\\Program Files (x86)\\SasView\\sasmodels-data\\models*. On Mac OSX, these will be within 31 Many models are available for download from the 32 `model marketplace <http://marketplace.sasview.org/>`_. 33 34 The builtin modules are available in the *sasmodels-data/models* subdirectory 35 of the sasview distribution. On Windows, this will be something like 36 *C:\Program Files (x86)\SasView\models*. On MacOSX, these will be within 31 37 the application bundle as 32 38 */Applications/SasView 4.0.app/Contents/Resources/sasmodels-data/models*. 33 39 34 Other models are available for download from our35 `Model Marketplace <http://marketplace.sasview.org/>`_. You can contribute your own models to the36 Marketplace aswell.37 38 40 Create New Model Files 39 41 ^^^^^^^^^^^^^^^^^^^^^^ 40 42 41 In the *~ \\.sasview\\plugin_models* directory, copy the appropriate files43 In the *~/.sasview/plugin_models* directory, copy the appropriate files 42 44 (using the examples above as templates) to mymodel.py (and mymodel.c, etc) 43 45 as required, where "mymodel" is the name for the model you are creating. … … 45 47 *Please follow these naming rules:* 46 48 47 - No capitalization and thus no CamelCase 48 - If necessary use underscore to separate words(i.e. barbell not BarBell or49 - No capitalization and thus no CamelCase. 50 - If necessary use underscore to separate (i.e. barbell not BarBell or 49 51 broad_peak not BroadPeak) 50 - Do not include âmodelâ in the name (i.e. barbell not BarBellModel)52 - Don't include âmodelâ in the name (i.e. barbell not BarBellModel) 51 53 52 54 53 55 Edit New Model Files 54 56 ^^^^^^^^^^^^^^^^^^^^ 55 56 Model Contents57 ..............58 57 59 58 The model interface definition is in the .py file. This file contains: … … 66 65 - without spaces (use underscores to separate words instead) 67 66 - without any capitalization or CamelCase 68 - without incorporating the word "model"67 - without incorporating the word 'model' 69 68 - examples: *barbell* **not** *BarBell*; *broad_peak* **not** *BroadPeak*; 70 69 *barbell* **not** *BarBellModel* … … 73 72 - this is the **title** string in the *.py* file 74 73 - this is a one or two line description of the model, which will appear 75 at the start of the model documentation and as a tooltip in the SasViewGUI74 at the start of the model documentation and as a tooltip in the GUI 76 75 77 76 - a **short discription**: 78 77 - this is the **description** string in the *.py* file 79 78 - this is a medium length description which appears when you click 80 *Description* on the model FitPage79 *Description* on the model fit page 81 80 82 81 - a **parameter table**: … … 86 85 - this is ReStructuredText enclosed between the r""" and """ delimiters 87 86 at the top of the *.py* file 88 - what you write here is abstracted into the SasView help documentation89 - this is what other users will refer to when they want to know what your model does;90 so please be helpful!91 87 92 88 - a **definition** of the model: … … 101 97 102 98 - a **plot** of the function, with a **figure caption**: 103 - this is automatically generated from yourdefault parameters99 - this is automatically generated from the default parameters 104 100 105 101 - at least one **reference**: … … 111 107 - the *.py* file should also contain a comment identifying *who* 112 108 converted/created the model file 113 114 Models that do not conform to these requirements will *never* be incorporated115 into the built-in library.116 109 117 110 More complete documentation for the sasmodels package can be found at … … 177 170 178 171 The model should include a **formula** written using LaTeX markup. 179 The example above uses the *math* command to make a displayed equation. You172 The above example uses the *math* command to make a displayed equation. You 180 173 can also use *\$formula\$* for an inline formula. This is handy for defining 181 174 the relationship between the model parameters and formula variables, such 182 175 as the phrase "\$r\$ is the radius" used above. The live demo MathJax 183 176 page `<http://www.mathjax.org/>`_ is handy for checking that the equations 184 will look like you intend.177 will look like you expect. 185 178 186 179 Math layout uses the `amsmath <http://www.ams.org/publications/authors/tex/amslatex>`_ … … 214 207 215 208 name = "sphere" # optional: defaults to the filename without .py 216 217 209 title = "Spheres with uniform scattering length density" 218 219 210 description = """\ 220 211 P(q)=(scale/V)*[3V(sld-sld_solvent)*(sin(qr)-qr cos(qr)) … … 225 216 sld_solvent: the SLD of the solvent 226 217 """ 227 228 218 category = "shape:sphere" 229 230 219 single = True # optional: defaults to True 231 232 220 opencl = False # optional: defaults to False 233 234 221 structure_factor = False # optional: defaults to False 235 222 … … 242 229 **title = "short description"** is short description of the model which 243 230 is included after the model name in the automatically generated documentation. 244 The title can also be used for a tooltip .231 The title can also be used for a tooltip, for example. 245 232 246 233 **description = """doc string"""** is a longer description of the model. It 247 shows up when you press the "Description" button of the SasView FitPage.234 shows up when you press the "Description" button of the SasView fit page. 248 235 It should give a brief description of the equation and the parameters 249 236 without the need to read the entire model documentation. The triple quotes 250 237 allow you to write the description over multiple lines. Keep the lines 251 238 short since the GUI will wrap each one separately if they are too long. 252 **Make sure the parameter names in the description match the model definition !**239 **Make sure the parameter names in the description match the model definition.** 253 240 254 241 **category = "shape:sphere"** defines where the model will appear in the 255 242 model documentation. In this example, the model will appear alphabetically 256 in the list of spheroid models in the *Shape* category.243 in the list of spheroid models. 257 244 258 245 **single = True** indicates that the model can be run using single … … 288 275 ["radius", "Ang", 50, [0, inf], "volume", "Sphere radius"], 289 276 ] 290 # pylint: enable=bad-whitespace, line-too-long277 # pylint: disable=bad-whitespace, line-too-long 291 278 292 279 **parameters = [["name", "units", default, [min,max], "type", "tooltip"],...]** 293 defines the parameters that form the model. 294 295 **Note: The order of the parameters in the definition will be the order of the 296 parameters in the user interface and the order of the parameters in Iq(), 297 Iqxy() and form_volume(). And** *scale* **and** *background* **parameters are 298 implicit to all models, so they do not need to be included in the parameter table.** 299 300 - **"name"** is the name of the parameter shown on the FitPage. 280 defines the parameters form the model. 281 282 - **the order of the parameters in the definition will be the order of 283 the parameters in the user interface and the order of the parameters 284 in Iq(), Iqxy() and form_volume().** 285 286 - **scale and background parameters are implicit to all models, so 287 they do not need to be included in the parameter table** 288 289 - **"name"** is the name of the parameter shown on the fit screen 301 290 302 291 - parameter names should follow the mathematical convention; e.g., 303 *radius_core* not *core_radius*, or *sld_solvent* not *solvent_sld*. 304 292 *radius_core* not *core_radius*, or *sld_solvent* not *solvent_sld* 305 293 - model parameter names should be consistent between different models, 306 294 so *sld_solvent*, for example, should have exactly the same name 307 in every model. 308 295 in every model 309 296 - to see all the parameter names currently in use, type the following in the 310 297 python shell/editor under the Tools menu:: … … 314 301 315 302 *re-use* as many as possible!!! 316 317 303 - use "name[n]" for multiplicity parameters, where *n* is the name of 318 304 the parameter defining the number of shells/layers/segments, etc. … … 320 306 - **"units"** are displayed along with the parameter name 321 307 322 - every parameter should have units; use "None" if there are no units. 323 308 - every parameter should have units; use "None" if there are no units 324 309 - **sld's should be given in units of 1e-6/Ang^2, and not simply 325 310 1/Ang^2 to be consistent with the builtin models. Adjust your formulas 326 311 appropriately.** 327 328 312 - fancy units markup is available for some units, including:: 329 313 … … 338 322 and using negative exponents instead of the / operator, though 339 323 the unit name should use the / operator for consistency. 340 - p lease post a message to the SasView developers mailing list with your changes.341 342 - **default** is the initial value for the parameter .324 - post a message to the sasview developers list with the changes 325 326 - **default** is the initial value for the parameter 343 327 344 328 - **the parameter default values are used to auto-generate a plot of 345 329 the model function in the documentation.** 346 330 347 - **[min, max]** are the lower and upper limits on the parameter. 348 349 - lower and upper limits can be any number, or *-inf* or *inf*. 350 331 - **[min, max]** are the lower and upper limits on the parameter 332 333 - lower and upper limits can be any number, or -inf or inf. 351 334 - the limits will show up as the default limits for the fit making it easy, 352 335 for example, to force the radius to always be greater than zero. 353 336 354 - **"type"** can be one of: "", "sld", "volume", or "orientation" .337 - **"type"** can be one of: "", "sld", "volume", or "orientation" 355 338 356 339 - "sld" parameters can have magnetic moments when fitting magnetic models; 357 340 depending on the spin polarization of the beam and the $q$ value being 358 341 examined, the effective sld for that material will be used to compute the 359 scattered intensity. 360 342 scattered intensity 361 343 - "volume" parameters are passed to Iq(), Iqxy(), and form_volume(), and 362 344 have polydispersity loops generated automatically. 363 364 345 - "orientation" parameters are only passed to Iqxy(), and have angular 365 346 dispersion. … … 399 380 ............. 400 381 401 For pure python models, define the *Iq* function::382 For pure python models, define the Iq funtion:: 402 383 403 384 import numpy as np … … 410 391 The parameters *par1, par2, ...* are the list of non-orientation parameters 411 392 to the model in the order that they appear in the parameter table. 412 **Note that the autogenerated model file uses ** *x* **rather than** *q*.393 **Note that the autogenerated model file uses *x* rather than *q*.** 413 394 414 395 The *.py* file should import trigonometric and exponential functions from 415 numpy rather tha nfrom math. This lets us evaluate the model for the whole396 numpy rather that from math. This lets us evaluate the model for the whole 416 397 range of $q$ values at once rather than looping over each $q$ separately in 417 398 python. With $q$ as a vector, you cannot use if statements, but must instead … … 449 430 list includes the *volume* parameters in order. This is used for a weighted 450 431 volume normalization so that scattering is on an absolute scale. If 451 *form_volume* is not defin ed, then the default *form_volume = 1.0* will be432 *form_volume* is not definded, then the default *form_volume = 1.0* will be 452 433 used. 453 434 … … 455 436 ................. 456 437 457 Like pure python models, inline C models need todefine an *Iq* function::438 Like pure python models, inline C models need define an *Iq* function:: 458 439 459 440 Iq = """ … … 535 516 These functions have been tuned to be fast and numerically stable down 536 517 to $q=0$ even in single precision. In some cases they work around bugs 537 which appear on some platforms but not others. So use them where needed!!!518 which appear on some platforms but not others. 538 519 539 520 Models are defined using double precision declarations for the 540 521 parameters and return values. Declarations and constants will be converted 541 522 to float or long double depending on the precision requested. 542 543 523 **Floating point constants must include the decimal point.** This allows us 544 524 to convert values such as 1.0 (double precision) to 1.0f (single precision) … … 560 540 561 541 A value defined as SAS_DOUBLE will stay double precision; this should 562 not be used since some graphics card s do not support double precision.542 not be used since some graphics card don't support double precision. 563 543 564 544 … … 577 557 Form Factors 578 558 ............ 559 560 :: 561 562 def ER(radius, thickness): 563 """Effective radius of a core-shell sphere.""" 564 return radius + thickness 579 565 580 566 Away from the dilute limit you can estimate scattering including … … 586 572 form averaged over all the polydispersity values. 587 573 588 :: 589 590 def ER(radius, thickness): 591 """Effective radius of a core-shell sphere.""" 592 return radius + thickness 593 594 Now consider the *core_shell_sphere*, which has a simple effective radius 574 Consider the *core_shell_sphere*, which has a simple effective radius 595 575 equal to the radius of the core plus the thickness of the shell, as 596 576 shown above. Given polydispersity over *(r1, r2, ..., rm)* in radius and … … 617 597 one return value for each point in the mesh grid. 618 598 619 *NOTE: we may be removing or modifying this feature soon. As of the620 time of writing, core-shell sphere returns (1., 1.) for VR, giving a volume621 ratio of 1.0. *599 *NOTE: we may be removing or modifying this feature soon.* As of this 600 writing, core-shell sphere returns (1., 1.) for *VR*, giving a volume 601 ratio of 1.0. 622 602 623 603 Unit Tests … … 660 640 ^^^^^^^^^^^^^^^^^^^ 661 641 662 Installed SasView663 .................664 665 642 If you are editing your model from the SasView GUI, you can test it 666 by selecting *Run > Compile* from the *Model Editor* menu bar. An643 by selecting *Run -> Compile* from the *Model Editor* menu bar. An 667 644 *Info* box will appear with the results of the compilation and a 668 645 check that the model runs. 669 646 670 671 Built SasView672 .............673 674 647 If the model compiles and runs, you can next run the unit tests that 675 you have added using the **test 648 you have added using the **test=** values. Switch to the *Shell* tab 676 649 and type the following:: 677 650 … … 713 686 For the random models, 714 687 715 - *sld* will be in the range(-0.5,10.5),716 - angles ( *theta, phi, psi*) will be in the range(-180,180),717 - angular dispersion will be in the range(0,45),718 - polydispersity will be in the range(0,1)719 - other values will be in the range (0, 2\ *v*), where *v*is the value of the parameter in demo.720 721 Dispersion parameters *n*\, *sigma* and *type*will be unchanged from demo so that688 - sld will be in(-0.5,10.5), 689 - angles (theta, phi, psi) will be in (-180,180), 690 - angular dispersion will be in (0,45), 691 - polydispersity will be in (0,1) 692 - other values will be in (0, 2*v) where v is the value of the parameter in demo. 693 694 Dispersion parameters n, sigma and type will be unchanged from demo so that 722 695 run times are predictable. 723 696 … … 728 701 729 702 730 Clean Lint - (Developer Version Only)731 ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^732 733 **NB: For now we are not providing pylint with the installer version of SasView;734 so unless you have a SasView build environment available, you can ignore this section!**703 Clean Lint 704 ^^^^^^^^^^ 705 706 **NB: For now we are not providing pylint with SasView; unless you have a 707 SasView development environment available, you can ignore this section.** 735 708 736 709 Run the lint check with:: … … 744 717 for standard model functions *Iq*, *Iqxy*, etc. 745 718 746 We will have delinting sessions at the SasView Code Camps, where we can719 We will have delinting sessions at the SasView code camps, where we can 747 720 decide on standards for model files, parameter names, etc. 748 721 749 For now, you can tell pylint to ignore things. For example, to align you r722 For now, you can tell pylint to ignore things. For example, to align you 750 723 parameters in blocks:: 751 724 … … 765 738 Don't put in too many pylint statements, though, since they make the code ugly. 766 739 767 Check The Docs - (Developer Version Only)768 ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^740 Check The Docs 741 ^^^^^^^^^^^^^^ 769 742 770 743 You can get a rough idea of how the documentation will look using the … … 783 756 - `amsmath <http://www.ams.org/publications/authors/tex/amslatex>`_ 784 757 785 There is also a neat online WYSIWYG ReStructuredText editor at http://rst.ninjs.org\ . 786 787 Share Your Model! 788 ^^^^^^^^^^^^^^^^^ 758 Finally 759 ^^^^^^^ 789 760 790 761 Once compare and the unit test(s) pass properly and everything is done, 791 762 consider adding your model to the 792 `Model Marketplace <http://marketplace.sasview.org/>`_ so that others may use it! 763 `model marketplace <http://marketplace.sasview.org/>`_. 764 -
src/sas/sasgui/perspectives/fitting/pagestate.py
r6c382da r654e8e0 24 24 from xml.dom.minidom import parseString 25 25 from lxml import etree 26 27 import sasmodels.weights28 26 29 27 import sas.sascalc.dataloader … … 476 474 value = content[1] 477 475 except Exception: 478 msg = "Report string expected 'name: value' but got %r"%line 479 logging.error(msg) 476 logging.error(traceback.format_exc()) 480 477 if name.count("State created"): 481 478 repo_time = "" + value … … 519 516 title_name = HEADER % title 520 517 except Exception: 521 msg = "While parsing 'data: ...'\n" 522 logging.error(msg + traceback.format_exc()) 518 logging.error(traceback.format_exc()) 523 519 if name == "model name ": 524 520 try: … … 535 531 q_range = CENTRE % q_name 536 532 except Exception: 537 msg = "While parsing 'Plotting Range: ...'\n" 538 logging.error(msg + traceback.format_exc()) 533 logging.error(traceback.format_exc()) 539 534 paramval = "" 540 535 for lines in param_string.split(":"): … … 716 711 # For self.values ={ disp_param_name: [vals,...],...} 717 712 # and for self.weights ={ disp_param_name: [weights,...],...} 713 value_list = {} 718 714 for item in LIST_OF_MODEL_ATTRIBUTES: 719 715 element = newdoc.createElement(item[0]) … … 729 725 730 726 # Create doc for the dictionary of self._disp_obj_dic 731 for tagname, varname, tagtype in DISPERSION_LIST: 732 element = newdoc.createElement(tagname) 733 value_list = getattr(self, varname) 734 for key, value in value_list.iteritems(): 727 for item in DISPERSION_LIST: 728 element = newdoc.createElement(item[0]) 729 value_list = getattr(self, item[1]) 730 for key, val in value_list.iteritems(): 731 value = repr(val) 735 732 sub_element = newdoc.createElement(key) 736 733 sub_element.setAttribute('name', str(key)) … … 850 847 # Recover _disp_obj_dict from xml file 851 848 self._disp_obj_dict = {} 852 for tagname, varname, tagtype in DISPERSION_LIST: 853 node = get_content("ns:%s" % tagname, entry) 849 for item in DISPERSION_LIST: 850 # Get node 851 node = get_content("ns:%s" % item[0], entry) 854 852 for attr in node: 855 parameter = str(attr.get('name')) 856 value = attr.get('value') 857 if value.startswith("<"): 858 try: 859 # <path.to.NamedDistribution object/instance...> 860 cls_name = value[1:].split()[0].split('.')[-1] 861 cls = getattr(sasmodels.weights, cls_name) 862 value = cls.type 863 except Exception: 864 logging.error("unable to load distribution %r for %s" 865 % (value, parameter)) 866 continue 867 _disp_obj_dict = getattr(self, varname) 868 _disp_obj_dict[parameter] = value 853 name = str(attr.get('name')) 854 val = attr.get('value') 855 value = val.split(" instance")[0] 856 disp_name = value.split("<")[1] 857 try: 858 # Try to recover disp_model object from strings 859 com = "from sas.models.dispersion_models " 860 com += "import %s as disp" 861 com_name = disp_name.split(".")[3] 862 exec com % com_name 863 disp_model = disp() 864 attribute = getattr(self, item[1]) 865 attribute[name] = com_name 866 except Exception: 867 logging.error(traceback.format_exc()) 869 868 870 869 # get self.values and self.weights dic. if exists 871 for tagname, varnamein LIST_OF_MODEL_ATTRIBUTES:872 node = get_content("ns:%s" % tagname, entry)870 for item in LIST_OF_MODEL_ATTRIBUTES: 871 node = get_content("ns:%s" % item[0], entry) 873 872 dic = {} 874 873 value_list = [] 875 874 for par in node: 876 875 name = par.get('name') 877 values = par.text.split( )876 values = par.text.split('\n') 878 877 # Get lines only with numbers 879 878 for line in values: … … 883 882 except Exception: 884 883 # pass if line is empty (it happens) 885 msg = ("Error reading %r from %s %s\n" 886 % (line, tagname, name)) 887 logging.error(msg + traceback.format_exc()) 884 logging.error(traceback.format_exc()) 888 885 dic[name] = numpy.array(value_list) 889 setattr(self, varname, dic)886 setattr(self, item[1], dic) 890 887 891 888 def set_plot_state(self, figs, canvases): … … 1234 1231 1235 1232 except: 1236 logging.info("XML document does not contain fitting information.\n" 1237 + traceback.format_exc()) 1233 logging.info("XML document does not contain fitting information.\n %s" % sys.exc_value) 1238 1234 1239 1235 return state
Note: See TracChangeset
for help on using the changeset viewer.