Changeset 8d3d20a in sasview for src/sas/sasgui/perspectives
- Timestamp:
- Oct 6, 2016 12:35:24 PM (8 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, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 4c3be25
- Parents:
- 0639476 (diff), e32e35a (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:
- Andrew Jackson <andrew.jackson@…> (10/06/16 12:35:24)
- git-committer:
- GitHub <noreply@…> (10/06/16 12:35:24)
- Location:
- src/sas/sasgui/perspectives
- Files:
-
- 19 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/fitting/basepage.py
re4c897b rc65a265 17 17 from wx.lib.scrolledpanel import ScrolledPanel 18 18 19 import sasmodels.sasview_model 19 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 20 20 21 from sas.sasgui.guiframe.panel_base import PanelBase 21 from sas.sasgui.guiframe.utils import format_number, check_float, IdList 22 from sas.sasgui.guiframe.utils import format_number, check_float, IdList, check_int 22 23 from sas.sasgui.guiframe.events import PanelOnFocusEvent 23 24 from sas.sasgui.guiframe.events import StatusEvent … … 626 627 self.disp_help_bt.Bind(wx.EVT_BUTTON, self.on_pd_help_clicked, 627 628 id=self.disp_help_bt.GetId()) 628 self.disp_help_bt.SetToolTipString("Help s for Polydispersion.")629 self.disp_help_bt.SetToolTipString("Help for polydispersion.") 629 630 630 631 self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, … … 932 933 if len(self._disp_obj_dict) > 0: 933 934 for k, v in self._disp_obj_dict.iteritems(): 934 self.state._disp_obj_dict[k] = v 935 self.state._disp_obj_dict[k] = v.type 935 936 936 937 self.state.values = copy.deepcopy(self.values) … … 1009 1010 if len(self._disp_obj_dict) > 0: 1010 1011 for k, v in self._disp_obj_dict.iteritems(): 1011 self.state._disp_obj_dict[k] = v 1012 self.state._disp_obj_dict[k] = v.type 1012 1013 1013 1014 self.state.values = copy.deepcopy(self.values) … … 1123 1124 state.disp_cb_dict[item]) 1124 1125 # Create the dispersion objects 1125 from sas.models.dispersion_models import ArrayDispersion 1126 disp_model = ArrayDispersion() 1126 disp_model = POLYDISPERSITY_MODELS['array']() 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 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 1381 for key, disp_type in state._disp_obj_dict.iteritems(): 1382 #disp_model = disp 1383 disp_model = POLYDISPERSITY_MODELS[disp_type]() 1391 1384 self._disp_obj_dict[key] = disp_model 1392 1385 param_name = key.split('.')[0] … … 1504 1497 is_2Ddata = True 1505 1498 if self.model != None: 1506 try: 1507 is_modified = self._check_value_enter(self.fittable_param, 1508 is_modified) 1509 is_modified = self._check_value_enter(self.fixed_param, 1510 is_modified) 1511 is_modified = self._check_value_enter(self.parameters, 1512 is_modified) 1513 except Exception: 1514 logging.error(traceback.format_exc()) 1499 is_modified = (self._check_value_enter(self.fittable_param) 1500 or self._check_value_enter(self.fixed_param) 1501 or self._check_value_enter(self.parameters)) 1515 1502 1516 1503 # Here we should check whether the boundaries have been modified. … … 1533 1520 else: 1534 1521 self.fitrange = False 1535 1536 if not self.data.is_data:1537 is_modified = True1538 1522 1539 1523 ## if any value is modify draw model with new value … … 1552 1536 self._draw_model() 1553 1537 self.Refresh() 1538 1539 logging.info("is_modified flag set to %g",is_modified) 1554 1540 return is_modified 1555 1541 … … 1561 1547 flag = True 1562 1548 self.fitrange = True 1563 is_modified = False1564 1549 1565 1550 #wx.PostEvent(self._manager.parent, StatusEvent(status=" \ … … 1574 1559 [self.data]) 1575 1560 ##Check the values 1576 self._check_value_enter(self.fittable_param , is_modified)1577 self._check_value_enter(self.fixed_param , is_modified)1578 self._check_value_enter(self.parameters , is_modified)1561 self._check_value_enter(self.fittable_param) 1562 self._check_value_enter(self.fixed_param) 1563 self._check_value_enter(self.parameters) 1579 1564 1580 1565 # If qmin and qmax have been modified, update qmin and qmax and … … 1660 1645 return flag 1661 1646 1662 def _is_modified(self, is_modified):1663 """1664 return to self._is_modified1665 """1666 return is_modified1667 1668 1647 def _reset_parameters_state(self, listtorestore, statelist): 1669 1648 """ … … 1964 1943 wx.PostEvent(self.parent, StatusEvent(status=msg)) 1965 1944 # Flag to register when a parameter has changed. 1966 #is_modified = False1967 1945 if tcrtl.GetValue().lstrip().rstrip() != "": 1968 1946 try: … … 1994 1972 if temp_npts != self.num_points: 1995 1973 self.num_points = temp_npts 1996 #is_modified = True1997 1974 else: 1998 1975 msg = "Cannot plot: No points in Q range!!! " … … 2170 2147 self.Layout() 2171 2148 2149 2172 2150 def _validate_qrange(self, qmin_ctrl, qmax_ctrl): 2173 2151 """ … … 2276 2254 return flag 2277 2255 2278 def _check_value_enter(self, list , modified):2256 def _check_value_enter(self, list): 2279 2257 """ 2280 2258 :param list: model parameter and panel info … … 2286 2264 parameter's maximum value , 2287 2265 parameter's units] 2288 """ 2289 is_modified = modified2290 if len(list) == 0:2291 return is_modified2266 2267 Returns True if the model parameters have changed. 2268 """ 2269 is_modified = False 2292 2270 for item in list: 2293 2271 #skip angle parameters for 1D 2294 if not self.enable2D: 2295 if item in self.orientation_params: 2272 if not self.enable2D and item in self.orientation_params: 2273 continue 2274 2275 value_ctrl = item[2] 2276 if not value_ctrl.IsEnabled(): 2277 # ArrayDispersion disables PD, Min, Max, Npts, Nsigs 2278 continue 2279 2280 name = item[1] 2281 value_str = value_ctrl.GetValue().strip() 2282 if name.endswith(".npts"): 2283 validity = check_int(value_ctrl) 2284 if not validity: 2296 2285 continue 2297 #try: 2298 name = str(item[1]) 2299 2300 if string.find(name, ".npts") == -1 and \ 2301 string.find(name, ".nsigmas") == -1: 2302 ## check model parameters range 2303 param_min = None 2304 param_max = None 2305 2306 ## check minimun value 2307 if item[5] != None and item[5] != "": 2308 if item[5].GetValue().lstrip().rstrip() != "": 2309 try: 2310 param_min = float(item[5].GetValue()) 2311 if not self._validate_qrange(item[5], item[2]): 2312 if numpy.isfinite(param_min): 2313 item[2].SetValue(format_number(param_min)) 2314 2315 item[5].SetBackgroundColour(wx.WHITE) 2316 item[2].SetBackgroundColour(wx.WHITE) 2317 2318 except: 2319 msg = "Wrong fit parameter range entered" 2320 wx.PostEvent(self._manager.parent, 2321 StatusEvent(status=msg)) 2322 raise ValueError, msg 2323 is_modified = True 2324 ## check maximum value 2325 if item[6] != None and item[6] != "": 2326 if item[6].GetValue().lstrip().rstrip() != "": 2327 try: 2328 param_max = float(item[6].GetValue()) 2329 if not self._validate_qrange(item[2], item[6]): 2330 if numpy.isfinite(param_max): 2331 item[2].SetValue(format_number(param_max)) 2332 2333 item[6].SetBackgroundColour(wx.WHITE) 2334 item[2].SetBackgroundColour(wx.WHITE) 2335 except: 2336 msg = "Wrong Fit parameter range entered " 2337 wx.PostEvent(self._manager.parent, 2338 StatusEvent(status=msg)) 2339 raise ValueError, msg 2340 is_modified = True 2341 2342 if param_min != None and param_max != None: 2343 if not self._validate_qrange(item[5], item[6]): 2344 msg = "Wrong Fit range entered for parameter " 2345 msg += "name %s of model %s " % (name, self.model.name) 2346 wx.PostEvent(self._manager.parent, 2347 StatusEvent(status=msg)) 2348 2349 if name in self.model.details.keys(): 2350 self.model.details[name][1:3] = param_min, param_max 2351 is_modified = True 2352 else: 2353 self.model.details[name] = ["", param_min, param_max] 2354 is_modified = True 2355 try: 2356 # Check if the textctr is enabled 2357 if item[2].IsEnabled(): 2358 value = float(item[2].GetValue()) 2359 item[2].SetBackgroundColour("white") 2360 # If the value of the parameter has changed, 2361 # +update the model and set the is_modified flag 2362 if value != self.model.getParam(name) and \ 2363 numpy.isfinite(value): 2364 self.model.setParam(name, value) 2365 except: 2366 item[2].SetBackgroundColour("pink") 2367 msg = "Wrong Fit parameter value entered " 2368 wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 2286 value = int(value_str) 2287 2288 elif name.endswith(".nsigmas"): 2289 validity = check_float(value_ctrl) 2290 if not validity: 2291 continue 2292 value = float(value_str) 2293 2294 else: # value or polydispersity 2295 2296 # Check that min, max and value are floats 2297 min_ctrl, max_ctrl = item[5], item[6] 2298 min_str = min_ctrl.GetValue().strip() 2299 max_str = max_ctrl.GetValue().strip() 2300 validity = check_float(value_ctrl) 2301 if min_str != "": 2302 validity = validity and check_float(min_ctrl) 2303 if max_str != "": 2304 validity = validity and check_float(max_ctrl) 2305 if not validity: 2306 continue 2307 2308 # Check that min is less than max 2309 low = -numpy.inf if min_str == "" else float(min_str) 2310 high = numpy.inf if max_str == "" else float(max_str) 2311 if high < low: 2312 min_ctrl.SetBackgroundColour("pink") 2313 min_ctrl.Refresh() 2314 max_ctrl.SetBackgroundColour("pink") 2315 max_ctrl.Refresh() 2316 #msg = "Invalid fit range for %s: min must be smaller than max"%name 2317 #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 2318 continue 2319 2320 # Force value between min and max 2321 value = float(value_str) 2322 if value < low: 2323 value = low 2324 value_ctrl.SetValue(format_number(value)) 2325 elif value > high: 2326 value = high 2327 value_ctrl.SetValue(format_number(value)) 2328 2329 if name not in self.model.details.keys(): 2330 self.model.details[name] = ["", None, None] 2331 old_low, old_high = self.model.details[name][1:3] 2332 if old_low != low or old_high != high: 2333 # The configuration has changed but it won't change the 2334 # computed curve so no need to set is_modified to True 2335 #is_modified = True 2336 self.model.details[name][1:3] = low, high 2337 2338 # Update value in model if it has changed 2339 if value != self.model.getParam(name): 2340 self.model.setParam(name, value) 2341 is_modified = True 2369 2342 2370 2343 return is_modified … … 2539 2512 self._disp_obj_dict[name1] = disp_model 2540 2513 self.model.set_dispersion(param_name, disp_model) 2541 self.state._disp_obj_dict[name1] = disp_model 2514 self.state._disp_obj_dict[name1] = disp_model.type 2542 2515 2543 2516 value1 = str(format_number(self.model.getParam(name1), True)) … … 2562 2535 item[0].Enable() 2563 2536 item[2].Enable() 2537 item[3].Show(True) 2538 item[4].Show(True) 2564 2539 item[5].Enable() 2565 2540 item[6].Enable() … … 2654 2629 self._disp_obj_dict[name] = disp 2655 2630 self.model.set_dispersion(name.split('.')[0], disp) 2656 self.state._disp_obj_dict[name] = disp 2631 self.state._disp_obj_dict[name] = disp.type 2657 2632 self.values[name] = values 2658 2633 self.weights[name] = weights … … 2722 2697 :param disp_function: dispersion distr. function 2723 2698 """ 2724 # List of the poly_model name in the combobox2725 list = ["RectangleDispersion", "ArrayDispersion",2726 "LogNormalDispersion", "GaussianDispersion",2727 "SchulzDispersion"]2728 2729 2699 # Find the selection 2730 try: 2731 selection = list.index(disp_func.__class__.__name__) 2732 return selection 2733 except: 2734 return 3 2700 if disp_func is not None: 2701 try: 2702 return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 2703 except ValueError: 2704 pass # Fall through to default class 2705 return POLYDISPERSITY_MODELS.keys().index('gaussian') 2735 2706 2736 2707 def on_reset_clicked(self, event): … … 3319 3290 pd = content[name][1] 3320 3291 if name.count('.') > 0: 3292 # If this is parameter.width, then pd may be a floating 3293 # point value or it may be an array distribution. 3294 # Nothing to do for parameter.npts or parameter.nsigmas. 3321 3295 try: 3322 3296 float(pd) 3323 except: 3297 if name.endswith('.npts'): 3298 pd = int(pd) 3299 except Exception: 3324 3300 #continue 3325 3301 if not pd and pd != '': … … 3329 3305 # Only array func has pd == '' case. 3330 3306 item[2].Enable(False) 3307 else: 3308 item[2].Enable(True) 3331 3309 if item[2].__class__.__name__ == "ComboBox": 3332 3310 if content[name][1] in self.model.fun_list: … … 3355 3333 pd = value[0] 3356 3334 if name.count('.') > 0: 3335 # If this is parameter.width, then pd may be a floating 3336 # point value or it may be an array distribution. 3337 # Nothing to do for parameter.npts or parameter.nsigmas. 3357 3338 try: 3358 3339 pd = float(pd) 3340 if name.endswith('.npts'): 3341 pd = int(pd) 3359 3342 except: 3360 3343 #continue … … 3365 3348 # Only array func has pd == '' case. 3366 3349 item[2].Enable(False) 3350 else: 3351 item[2].Enable(True) 3367 3352 if item[2].__class__.__name__ == "ComboBox": 3368 3353 if value[0] in self.model.fun_list: … … 3384 3369 Helps get paste for poly function 3385 3370 3386 :param item: Gui param items 3387 :param value: the values for parameter ctrols 3388 """ 3389 is_array = False 3390 if len(value[1]) > 0: 3391 # Only for dispersion func.s 3392 try: 3393 item[7].SetValue(value[1]) 3394 selection = item[7].GetCurrentSelection() 3395 name = item[7].Name 3396 param_name = name.split('.')[0] 3397 dispersity = item[7].GetClientData(selection) 3398 disp_model = dispersity() 3399 # Only for array disp 3400 try: 3401 pd_vals = numpy.array(value[2]) 3402 pd_weights = numpy.array(value[3]) 3403 if len(pd_vals) > 0 and len(pd_vals) > 0: 3404 if len(pd_vals) == len(pd_weights): 3405 self._set_disp_array_cb(item=item) 3406 self._set_array_disp_model(name=name, 3407 disp=disp_model, 3408 values=pd_vals, 3409 weights=pd_weights) 3410 is_array = True 3411 except Exception: 3412 logging.error(traceback.format_exc()) 3413 if not is_array: 3414 self._disp_obj_dict[name] = disp_model 3415 self.model.set_dispersion(name, 3416 disp_model) 3417 self.state._disp_obj_dict[name] = \ 3418 disp_model 3419 self.model.set_dispersion(param_name, disp_model) 3420 self.state.values = self.values 3421 self.state.weights = self.weights 3422 self.model._persistency_dict[param_name] = \ 3423 [self.state.values, 3424 self.state.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_array_cb(self, item): 3371 *item* is the parameter name 3372 3373 *value* depends on which parameter is being processed, and whether it 3374 has array polydispersity. 3375 3376 For parameters without array polydispersity: 3377 3378 parameter => ['FLOAT', ''] 3379 parameter.width => ['FLOAT', 'DISTRIBUTION', ''] 3380 parameter.npts => ['FLOAT', ''] 3381 parameter.nsigmas => ['FLOAT', ''] 3382 3383 For parameters with array polydispersity: 3384 3385 parameter => ['FLOAT', ''] 3386 parameter.width => ['FILENAME', 'array', [x1, ...], [w1, ...]] 3387 parameter.npts => ['FLOAT', ''] 3388 parameter.nsigmas => ['FLOAT', ''] 3389 """ 3390 # Do nothing if not setting polydispersity 3391 if len(value[1]) == 0: 3392 return 3393 3394 try: 3395 name = item[7].Name 3396 param_name = name.split('.')[0] 3397 item[7].SetValue(value[1]) 3398 selection = item[7].GetCurrentSelection() 3399 dispersity = item[7].GetClientData(selection) 3400 disp_model = dispersity() 3401 3402 if value[1] == 'array': 3403 pd_vals = numpy.array(value[2]) 3404 pd_weights = numpy.array(value[3]) 3405 if len(pd_vals) == 0 or len(pd_vals) != len(pd_weights): 3406 msg = ("bad array distribution parameters for %s" 3407 % param_name) 3408 raise ValueError(msg) 3409 self._set_disp_cb(True, item=item) 3410 self._set_array_disp_model(name=name, 3411 disp=disp_model, 3412 values=pd_vals, 3413 weights=pd_weights) 3414 else: 3415 self._set_disp_cb(False, item=item) 3416 self._disp_obj_dict[name] = disp_model 3417 self.model.set_dispersion(param_name, disp_model) 3418 self.state._disp_obj_dict[name] = disp_model.type 3419 # TODO: It's not an array, why update values and weights? 3420 self.model._persistency_dict[param_name] = \ 3421 [self.values, self.weights] 3422 self.state.values = self.values 3423 self.state.weights = self.weights 3424 3425 except Exception: 3426 logging.error(traceback.format_exc()) 3427 print "Error in BasePage._paste_poly_help: %s" % \ 3428 sys.exc_info()[1] 3429 3430 def _set_disp_cb(self, isarray, item): 3432 3431 """ 3433 3432 Set cb for array disp 3434 3433 """ 3435 item[0].SetValue(False) 3436 item[0].Enable(False) 3437 item[2].Enable(False) 3438 item[3].Show(False) 3439 item[4].Show(False) 3440 item[5].SetValue('') 3441 item[5].Enable(False) 3442 item[6].SetValue('') 3443 item[6].Enable(False) 3434 if isarray: 3435 item[0].SetValue(False) 3436 item[0].Enable(False) 3437 item[2].Enable(False) 3438 item[3].Show(False) 3439 item[4].Show(False) 3440 item[5].SetValue('') 3441 item[5].Enable(False) 3442 item[6].SetValue('') 3443 item[6].Enable(False) 3444 else: 3445 item[0].Enable() 3446 item[2].Enable() 3447 item[3].Show(True) 3448 item[4].Show(True) 3449 item[5].Enable() 3450 item[6].Enable() 3444 3451 3445 3452 def update_pinhole_smear(self): -
src/sas/sasgui/perspectives/fitting/batchfitpage.py
rfc18690 ree4b3cb 256 256 # if self.model != None: 257 257 # ##Check the values 258 # self._check_value_enter( self.fittable_param , is_modified)259 # self._check_value_enter( self.fixed_param , is_modified)260 # self._check_value_enter( self.parameters , is_modified)258 # self._check_value_enter( self.fittable_param) 259 # self._check_value_enter( self.fixed_param) 260 # self._check_value_enter( self.parameters) 261 261 # 262 262 # # If qmin and qmax have been modified, update qmin and qmax and -
src/sas/sasgui/perspectives/fitting/fitpage.py
r934ce649 r6c382da 10 10 import math 11 11 import time 12 import traceback 12 13 13 14 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS … … 1365 1366 try: 1366 1367 tcrtl.SetBackgroundColour(wx.WHITE) 1367 self._check_value_enter(self.fittable_param , is_modified)1368 self._check_value_enter(self.parameters , is_modified)1368 self._check_value_enter(self.fittable_param) 1369 self._check_value_enter(self.parameters) 1369 1370 except: 1370 1371 tcrtl.SetBackgroundColour("pink") … … 2058 2059 msg = "Error: This model state has missing or outdated " 2059 2060 msg += "information.\n" 2060 msg += "%s" % (sys.exc_value)2061 msg += traceback.format_exc() 2061 2062 wx.PostEvent(self._manager.parent, 2062 2063 StatusEvent(status=msg, info="error")) -
src/sas/sasgui/perspectives/fitting/fitting.py
r7673ecd rca4d985 313 313 """ 314 314 event_id = event.GetId() 315 self.update_custom_combo() 315 self.update_custom_combo() 316 316 317 317 def update_custom_combo(self): … … 342 342 page.formfactorbox.SetLabel(current_val) 343 343 except: 344 pass 345 344 logging.error("update_custom_combo: %s", sys.exc_value) 346 345 347 346 def set_edit_menu(self, owner): … … 1666 1665 wx.PostEvent(self.parent, StatusEvent(status=msg, type="update")) 1667 1666 1667 def create_theory_1D(self, x, y, page_id, model, data, state, 1668 data_description, data_id, dy=None): 1669 """ 1670 Create a theory object associate with an existing Data1D 1671 and add it to the data manager. 1672 @param x: x-values of the data 1673 @param y: y_values of the data 1674 @param page_id: fit page ID 1675 @param model: model used for fitting 1676 @param data: Data1D object to create the theory for 1677 @param state: model state 1678 @param data_description: title to use in the data manager 1679 @param data_id: unique data ID 1680 """ 1681 new_plot = Data1D(x=x, y=y) 1682 if dy is None: 1683 new_plot.is_data = False 1684 new_plot.dy = numpy.zeros(len(y)) 1685 # If this is a theory curve, pick the proper symbol to make it a curve 1686 new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 1687 else: 1688 new_plot.is_data = True 1689 new_plot.dy = dy 1690 new_plot.interactive = True 1691 new_plot.dx = None 1692 new_plot.dxl = None 1693 new_plot.dxw = None 1694 _yaxis, _yunit = data.get_yaxis() 1695 _xaxis, _xunit = data.get_xaxis() 1696 new_plot.title = data.name 1697 new_plot.group_id = data.group_id 1698 if new_plot.group_id == None: 1699 new_plot.group_id = data.group_id 1700 new_plot.id = data_id 1701 # Find if this theory was already plotted and replace that plot given 1702 # the same id 1703 self.page_finder[page_id].get_theory_data(fid=data.id) 1704 1705 if data.is_data: 1706 data_name = str(data.name) 1707 else: 1708 data_name = str(model.__class__.__name__) 1709 1710 new_plot.name = data_description + " [" + data_name + "]" 1711 new_plot.xaxis(_xaxis, _xunit) 1712 new_plot.yaxis(_yaxis, _yunit) 1713 self.page_finder[page_id].set_theory_data(data=new_plot, 1714 fid=data.id) 1715 self.parent.update_theory(data_id=data.id, theory=new_plot, 1716 state=state) 1717 return new_plot 1718 1668 1719 def _complete1D(self, x, y, page_id, elapsed, index, model, 1669 1720 weight=None, fid=None, 1670 1721 toggle_mode_on=False, state=None, 1671 1722 data=None, update_chisqr=True, 1672 source='model', plot_result=True): 1673 """ 1674 Complete plotting 1D data 1723 source='model', plot_result=True, 1724 unsmeared_model=None, unsmeared_data=None, 1725 unsmeared_error=None, sq_model=None, pq_model=None): 1726 """ 1727 Complete plotting 1D data 1728 @param unsmeared_model: fit model, without smearing 1729 @param unsmeared_data: data, rescaled to unsmeared model 1730 @param unsmeared_error: data error, rescaled to unsmeared model 1675 1731 """ 1676 1732 try: 1677 1733 numpy.nan_to_num(y) 1678 1679 new_plot = Data1D(x=x, y=y) 1680 new_plot.is_data = False 1681 new_plot.dy = numpy.zeros(len(y)) 1682 new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 1683 _yaxis, _yunit = data.get_yaxis() 1684 _xaxis, _xunit = data.get_xaxis() 1685 new_plot.title = data.name 1686 1687 new_plot.group_id = data.group_id 1688 if new_plot.group_id == None: 1689 new_plot.group_id = data.group_id 1690 new_plot.id = str(page_id) + " " + data.name 1691 #if new_plot.id in self.color_dict: 1692 # new_plot.custom_color = self.color_dict[new_plot.id] 1693 #find if this theory was already plotted and replace that plot given 1694 #the same id 1695 self.page_finder[page_id].get_theory_data(fid=data.id) 1696 1697 if data.is_data: 1698 data_name = str(data.name) 1699 else: 1700 data_name = str(model.__class__.__name__) 1701 1702 new_plot.name = model.name + " [" + data_name + "]" 1703 new_plot.xaxis(_xaxis, _xunit) 1704 new_plot.yaxis(_yaxis, _yunit) 1705 self.page_finder[page_id].set_theory_data(data=new_plot, 1706 fid=data.id) 1707 self.parent.update_theory(data_id=data.id, theory=new_plot, 1708 state=state) 1734 new_plot = self.create_theory_1D(x, y, page_id, model, data, state, 1735 data_description=model.name, 1736 data_id=str(page_id) + " " + data.name) 1737 if unsmeared_model is not None: 1738 self.create_theory_1D(x, unsmeared_model, page_id, model, data, state, 1739 data_description=model.name + " unsmeared", 1740 data_id=str(page_id) + " " + data.name + " unsmeared") 1741 1742 self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 1743 data_description="Data unsmeared", 1744 data_id="Data " + data.name + " unsmeared", 1745 dy=unsmeared_error) 1746 1747 if sq_model is not None and pq_model is not None: 1748 self.create_theory_1D(x, sq_model, page_id, model, data, state, 1749 data_description=model.name + " S(q)", 1750 data_id=str(page_id) + " " + data.name + " S(q)") 1751 self.create_theory_1D(x, pq_model, page_id, model, data, state, 1752 data_description=model.name + " P(q)", 1753 data_id=str(page_id) + " " + data.name + " P(q)") 1754 1755 1709 1756 current_pg = self.fit_panel.get_page_by_id(page_id) 1710 1757 title = new_plot.title -
src/sas/sasgui/perspectives/fitting/media/fitting.rst
rd85c194 r05829fb 18 18 19 19 Information on the SasView Optimisers <optimizer.rst> 20 20 21 Writing a Plugin <plugin.rst> -
src/sas/sasgui/perspectives/fitting/media/fitting_help.rst
rb64b87c r05829fb 132 132 * By :ref:`Writing_a_Plugin` 133 133 134 *NB: Because of the way these options are implemented, it is not possible for them*135 *to use the polydispersity algorithms in SasView. Only models in the model library*136 *can do this. At the time of writing (Release 3.1.0) work is in hand to make it*137 *easier to add new models to the model library.*138 139 134 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 140 135 … … 163 158 the :ref:`Advanced` option. 164 159 160 *NB: "Fit Parameters" has been split into two sections, those which can be 161 polydisperse (shape and orientation parameters) and those which are not 162 (scattering length densities, for example).* 163 165 164 Sum|Multi(p1,p2) 166 165 ^^^^^^^^^^^^^^^^ … … 192 191 *Advanced Custom Model Editor*. 193 192 194 *NB: Unless you are confident about what you are doing, it is recommended that you* 195 *only modify lines denoted with the ## <----- comments!* 193 See :ref:`Writing_a_Plugin` for details on the plugin format. 194 195 *NB: Sum/Product models are still using the SasView 3.x model format. Unless 196 you are confident about what you are doing, it is recommended that you 197 only modify lines denoted with the ## <----- comments!* 196 198 197 199 When editing is complete, select *Run -> Compile* from the *Model Editor* menu bar. An … … 211 213 212 214 *NB: Custom models shipped with SasView cannot be removed in this way.* 213 214 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ215 216 .. _Writing_a_Plugin:217 218 Writing a Plugin219 ----------------220 221 Advanced users can write their own model in Python and save it to the the SasView222 *plugin_models* folder223 224 *C:\\Users\\[username]\\.sasview\\plugin_models* - (on Windows)225 226 in .py format. The next time SasView is started it will compile the plugin and add227 it to the list of *Customized Models*.228 229 It is recommended that existing plugin models be used as templates.230 215 231 216 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ -
src/sas/sasgui/perspectives/fitting/model_thread.py
r934ce649 rca4d985 7 7 import math 8 8 from sas.sascalc.data_util.calcthread import CalcThread 9 from sas.sascalc.fit.MultiplicationModel import MultiplicationModel 9 10 10 11 class Calc2D(CalcThread): … … 166 167 index = (self.qmin <= self.data.x) & (self.data.x <= self.qmax) 167 168 169 # If we use a smearer, also return the unsmeared model 170 unsmeared_output = None 171 unsmeared_data = None 172 unsmeared_error = None 168 173 ##smearer the ouput of the plot 169 174 if self.smearer is not None: … … 171 176 self.qmax) 172 177 mask = self.data.x[first_bin:last_bin+1] 173 output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 174 output = self.smearer(output, first_bin, last_bin) 178 unsmeared_output = numpy.zeros((len(self.data.x))) 179 unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 180 output = self.smearer(unsmeared_output, first_bin, last_bin) 181 182 # Rescale data to unsmeared model 183 unsmeared_data = numpy.zeros((len(self.data.x))) 184 unsmeared_error = numpy.zeros((len(self.data.x))) 185 unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\ 186 * unsmeared_output[first_bin:last_bin+1]\ 187 / output[first_bin:last_bin+1] 188 unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\ 189 * unsmeared_output[first_bin:last_bin+1]\ 190 / output[first_bin:last_bin+1] 191 unsmeared_output=unsmeared_output[index] 192 unsmeared_data=unsmeared_data[index] 193 unsmeared_error=unsmeared_error 175 194 else: 176 195 output[index] = self.model.evalDistribution(self.data.x[index]) 196 197 sq_model = None 198 pq_model = None 199 if isinstance(self.model, MultiplicationModel): 200 sq_model = numpy.zeros((len(self.data.x))) 201 pq_model = numpy.zeros((len(self.data.x))) 202 sq_model[index] = self.model.s_model.evalDistribution(self.data.x[index]) 203 pq_model[index] = self.model.p_model.evalDistribution(self.data.x[index]) 177 204 178 205 elapsed = time.time() - self.starttime … … 187 214 data=self.data, 188 215 update_chisqr=self.update_chisqr, 189 source=self.source) 216 source=self.source, 217 unsmeared_model=unsmeared_output, 218 unsmeared_data=unsmeared_data, 219 unsmeared_error=unsmeared_error, 220 pq_model=pq_model, 221 sq_model=sq_model) 190 222 191 223 def results(self): -
src/sas/sasgui/perspectives/fitting/pagestate.py
r7673ecd r6c382da 24 24 from xml.dom.minidom import parseString 25 25 from lxml import etree 26 27 import sasmodels.weights 26 28 27 29 import sas.sascalc.dataloader … … 474 476 value = content[1] 475 477 except Exception: 476 logging.error(traceback.format_exc()) 478 msg = "Report string expected 'name: value' but got %r"%line 479 logging.error(msg) 477 480 if name.count("State created"): 478 481 repo_time = "" + value … … 516 519 title_name = HEADER % title 517 520 except Exception: 518 logging.error(traceback.format_exc()) 521 msg = "While parsing 'data: ...'\n" 522 logging.error(msg + traceback.format_exc()) 519 523 if name == "model name ": 520 524 try: … … 531 535 q_range = CENTRE % q_name 532 536 except Exception: 533 logging.error(traceback.format_exc()) 537 msg = "While parsing 'Plotting Range: ...'\n" 538 logging.error(msg + traceback.format_exc()) 534 539 paramval = "" 535 540 for lines in param_string.split(":"): … … 711 716 # For self.values ={ disp_param_name: [vals,...],...} 712 717 # and for self.weights ={ disp_param_name: [weights,...],...} 713 value_list = {}714 718 for item in LIST_OF_MODEL_ATTRIBUTES: 715 719 element = newdoc.createElement(item[0]) … … 725 729 726 730 # Create doc for the dictionary of self._disp_obj_dic 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) 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(): 732 735 sub_element = newdoc.createElement(key) 733 736 sub_element.setAttribute('name', str(key)) … … 847 850 # Recover _disp_obj_dict from xml file 848 851 self._disp_obj_dict = {} 849 for item in DISPERSION_LIST: 850 # Get node 851 node = get_content("ns:%s" % item[0], entry) 852 for tagname, varname, tagtype in DISPERSION_LIST: 853 node = get_content("ns:%s" % tagname, entry) 852 854 for attr in node: 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()) 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 868 869 869 870 # get self.values and self.weights dic. if exists 870 for itemin LIST_OF_MODEL_ATTRIBUTES:871 node = get_content("ns:%s" % item[0], entry)871 for tagname, varname in LIST_OF_MODEL_ATTRIBUTES: 872 node = get_content("ns:%s" % tagname, entry) 872 873 dic = {} 873 874 value_list = [] 874 875 for par in node: 875 876 name = par.get('name') 876 values = par.text.split( '\n')877 values = par.text.split() 877 878 # Get lines only with numbers 878 879 for line in values: … … 882 883 except Exception: 883 884 # pass if line is empty (it happens) 884 logging.error(traceback.format_exc()) 885 msg = ("Error reading %r from %s %s\n" 886 % (line, tagname, name)) 887 logging.error(msg + traceback.format_exc()) 885 888 dic[name] = numpy.array(value_list) 886 setattr(self, item[1], dic)889 setattr(self, varname, dic) 887 890 888 891 def set_plot_state(self, figs, canvases): … … 1231 1234 1232 1235 except: 1233 logging.info("XML document does not contain fitting information.\n %s" % sys.exc_value) 1236 logging.info("XML document does not contain fitting information.\n" 1237 + traceback.format_exc()) 1234 1238 1235 1239 return state … … 1569 1573 if output[ind].run_name is not None\ 1570 1574 and len(output[ind].run_name) != 0: 1571 name = output[ind].run_name 1575 if isinstance(output[ind].run_name, dict): 1576 name = output[ind].run_name.keys()[0] 1577 else: 1578 name = output[ind].run_name 1572 1579 else: 1573 1580 name = original_fname -
src/sas/sasgui/perspectives/invariant/invariant_panel.py
rc12f9b4 r654e8e0 250 250 251 251 num = self.state.saved_state['state_num'] 252 if num> 0:252 if int(num) > 0: 253 253 self._set_undo_flag(True) 254 if num< len(state.state_list) - 1:254 if int(num) < len(state.state_list) - 1: 255 255 self._set_redo_flag(True) 256 256 … … 830 830 """ 831 831 try: 832 attr = getattr(self, key) 832 if key in ['compute_num', 'file', 'is_time_machine', 'state_num']: 833 return 834 else: 835 attr = getattr(self, key) 833 836 if attr.__class__.__name__ == "StaticText": 834 837 return 835 if type(value) is not bool: 838 if value in ["True", "False", True, False]: 839 value = bool(value) 840 else: 836 841 value = str(value) 837 842 attr.SetValue(value) … … 1860 1865 (self.button_calculate, 0, 1861 1866 wx.RIGHT | wx.TOP | wx.BOTTOM, 10), 1862 (self.button_help, 0, 1867 (self.button_help, 0, 1863 1868 wx.RIGHT | wx.TOP | wx.BOTTOM, 10),]) 1864 1869 def _do_layout(self): … … 1882 1887 self.SetSizer(self.main_sizer) 1883 1888 self.SetAutoLayout(True) 1884 1889 1885 1890 def on_help(self, event): 1886 1891 """ 1887 Bring up the Invariant Documentation whenever the HELP button is 1892 Bring up the Invariant Documentation whenever the HELP button is 1888 1893 clicked. 1889 1894 -
src/sas/sasgui/perspectives/invariant/invariant_state.py
rc10d9d6c rcb93b40 426 426 if input_field is not None: 427 427 temp_state[item] = val 428 self.state_list[ ind] = temp_state428 self.state_list[str(ind)] = temp_state 429 429 430 430 # Parse current state (ie, saved_state) … … 790 790 doc = state.toXML(datainfo.name, doc=doc, entry_node=sasentry) 791 791 return doc 792 -
src/sas/sasgui/perspectives/pr/media/pr_help.rst
rb64b87c r0391dae 15 15 *P(r)* is set to be equal to an expansion of base functions of the type 16 16 17 |bigphi|\_n(r) = 2.r.sin(|pi|\ .n.r/D_max) 17 .. math:: 18 \Phi_{n(r)} = 2 r sin(\frac{\pi n r}{D_{max}}) 18 19 19 The coefficient of each base function in the expansion is found by performing 20 The coefficient of each base function in the expansion is found by performing 20 21 a least square fit with the following fit function 21 22 22 |chi|\ :sup:`2` = |bigsigma|\ :sub:`i` [ I\ :sub:`meas`\ (Q\ :sub:`i`\ ) - I\ :sub:`th`\ (Q\ :sub:`i`\ ) ] :sup:`2` / (Error) :sup:`2` + Reg_term 23 .. math:: 23 24 24 where I\ :sub:`meas`\ (Q) is the measured scattering intensity and 25 I\ :sub:`th`\ (Q) is the prediction from the Fourier transform of the *P(r)* 26 expansion. 25 \chi^2=\frac{\sum_i (I_{meas}(Q_i)-I_{th}(Q_i))^2}{error^2}+Reg\_term 26 27 27 28 The *Reg_term* term is a regularization term set to the second derivative 29 d\ :sup:`2`\ *P(r)* / dr\ :sup:`2` integrated over *r*. It is used to produce a 30 smooth *P(r)* output. 28 where $I_{meas}(Q_i)$ is the measured scattering intensity and $I_{th}(Q_i)$ is 29 the prediction from the Fourier transform of the *P(r)* expansion. 30 31 The $Reg\_term$ term is a regularization term set to the second derivative 32 $d^2P(r)/d^2r$ integrated over $r$. It is used to produce a smooth *P(r)* output. 31 33 32 34 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ … … 45 47 system. 46 48 49 P(r) inversion requires that the background be perfectly subtracted. This is 50 often difficult to do well and thus many data sets will include a background. 51 For those cases, the user should check the "estimate background" box and the 52 module will do its best to estimate it. 53 54 The P(r) module is constantly computing in the background what the optimum 55 *number of terms* should be as well as the optimum *regularization constant*. 56 These are constantly updated in the buttons next to the entry boxes on the GUI. 57 These are almost always close and unless the user has a good reason to choose 58 differently they should just click on the buttons to accept both. {D_max} must 59 still be set by the user. However, besides looking at the output, the user can 60 click the explore button which will bring up a graph of chi^2 vs Dmax over a 61 range around the current Dmax. The user can change the range and the number of 62 points to explore in that range. They can also choose to plot several other 63 parameters as a function of Dmax including: I0, Rg, Oscillation parameter, 64 background, positive fraction, and 1-sigma positive fraction. 65 47 66 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 48 67 … … 55 74 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 56 75 57 .. note:: This help document was last changed by Steve King, 01May201576 .. note:: This help document was last modified by Paul Butler, 05 September, 2016
Note: See TracChangeset
for help on using the changeset viewer.