Changeset 9be22cd in sasview for src/sas/sasgui/perspectives/fitting
- Timestamp:
- Sep 27, 2017 10:50:02 AM (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:
- fca1f50
- Parents:
- 69a6897 (diff), 83db1cc (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. - Location:
- src/sas/sasgui/perspectives/fitting
- Files:
-
- 1 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/fitting/basepage.py
r53b8266 rd3b0c77 6 6 import sys 7 7 import os 8 import wx9 import numpy as np10 8 import time 11 9 import copy … … 14 12 import logging 15 13 import traceback 16 17 14 from Queue import Queue 18 15 from threading import Thread 19 16 from collections import defaultdict 17 18 import numpy as np 19 20 import wx 20 21 from wx.lib.scrolledpanel import ScrolledPanel 21 22 23 from sasmodels.sasview_model import MultiplicationModel 22 24 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 25 from sasmodels.weights import GaussianDispersion 26 27 from sas.sascalc.dataloader.data_info import Detector 28 from sas.sascalc.dataloader.data_info import Source 29 from sas.sascalc.fit.pagestate import PageState 30 from sas.sascalc.fit.models import PLUGIN_NAME_BASE 23 31 24 32 from sas.sasgui.guiframe.panel_base import PanelBase … … 32 40 from sas.sasgui.guiframe.dataFitting import check_data_validity 33 41 from sas.sasgui.guiframe.gui_style import GUIFRAME_ID 34 from sas.sascalc.dataloader.data_info import Detector35 from sas.sascalc.dataloader.data_info import Source36 from sas.sasgui.perspectives.fitting.pagestate import PageState37 42 from sas.sasgui.guiframe.CategoryInstaller import CategoryInstaller 38 43 from sas.sasgui.guiframe.documentation_window import DocumentationWindow 44 45 from .report_dialog import ReportDialog 46 from .utils import get_weight 39 47 40 48 logger = logging.getLogger(__name__) … … 155 163 self.disp_cb_dict = {} 156 164 157 # self.state = PageState( parent=parent)165 # self.state = PageState() 158 166 # dictionary containing list of models 159 167 self.model_list_box = {} … … 202 210 self.fitrange = True 203 211 # Create memento to save the current state 204 self.state = PageState(parent=self.parent, 205 model=self.model, data=self.data) 212 self.state = PageState(model=self.model, data=self.data) 206 213 # flag to determine if state has change 207 214 self.state_change = False … … 295 302 """ 296 303 x = np.linspace(start=self.qmin_x, stop=self.qmax_x, 297 304 num=self.npts_x, endpoint=True) 298 305 self.data = Data1D(x=x) 299 306 self.data.xaxis('\\rm{Q}', "A^{-1}") … … 321 328 322 329 x = np.logspace(start=qmin, stop=qmax, 323 330 num=self.npts_x, endpoint=True, base=10.0) 324 331 self.data = Data1D(x=x) 325 332 self.data.xaxis('\\rm{Q}', "A^{-1}") … … 510 517 self.state.manager = manager 511 518 512 def populate_box(self, model_ dict):519 def populate_box(self, model_list_box): 513 520 """ 514 521 Store list of model 515 522 516 :param model_dict: dictionary containing list of models 517 518 """ 519 self.model_list_box = model_dict 520 self.state.model_list_box = self.model_list_box 523 :param model_list_box: dictionary containing categorized models 524 """ 525 self.model_list_box = model_list_box 521 526 self.initialize_combox() 522 527 523 def set_model_dictionary(self, model_dict ):528 def set_model_dictionary(self, model_dictionary): 524 529 """ 525 530 Store a dictionary linking model name -> model object 526 531 527 :param model_dict : dictionary containing list ofmodels528 """ 529 self.model_dict = model_dict532 :param model_dictionary: dictionary containing all models 533 """ 534 self.model_dictionary = model_dictionary 530 535 531 536 def initialize_combox(self): … … 533 538 put default value in the combo box 534 539 """ 535 if self.model_list_box is not None and len(self.model_list_box) > 0:540 if self.model_list_box: 536 541 self._populate_box(self.structurebox, 537 542 self.model_list_box["Structure Factors"]) … … 632 637 # Get plot image from plotpanel 633 638 images, canvases = self.get_images() 634 # get the report dialog 635 self.state.report(images, canvases) 639 imgRAM, images, refs = self._build_plots_for_report(images, canvases) 640 641 # get the strings for report 642 report_str, text_str = self.state.report(fig_urls=refs) 643 644 # Show the dialog 645 report_list = [report_str, text_str, images] 646 dialog = ReportDialog(report_list, None, wx.ID_ANY, "") 647 dialog.Show() 648 649 def _build_plots_for_report(self, figs, canvases): 650 """ 651 Build image state that wx.html understand 652 by plotting, putting it into wx.FileSystem image object 653 """ 654 images = [] 655 refs = [] 656 657 # For no figures in the list, prepare empty plot 658 if figs is None or len(figs) == 0: 659 figs = [None] 660 661 # Loop over the list of figures 662 # use wx.MemoryFSHandler 663 imgRAM = wx.MemoryFSHandler() 664 for fig in figs: 665 if fig is not None: 666 ind = figs.index(fig) 667 canvas = canvases[ind] 668 669 # store the image in wx.FileSystem Object 670 wx.FileSystem.AddHandler(wx.MemoryFSHandler()) 671 672 # index of the fig 673 ind = figs.index(fig) 674 675 # AddFile, image can be retrieved with 'memory:filename' 676 name = 'img_fit%s.png' % ind 677 refs.append('memory:' + name) 678 imgRAM.AddFile(name, canvas.bitmap, wx.BITMAP_TYPE_PNG) 679 680 # append figs 681 images.append(fig) 682 683 return imgRAM, images, refs 684 636 685 637 686 def on_save(self, event): … … 855 904 self.state.disable_disp = self.disable_disp.GetValue() 856 905 857 self.state.smearer = copy.deepcopy(self.current_smearer)858 906 if hasattr(self, "enable_smearer"): 859 907 self.state.enable_smearer = \ … … 871 919 if len(self._disp_obj_dict) > 0: 872 920 for k, v in self._disp_obj_dict.iteritems(): 873 self.state. _disp_obj_dict[k] = v.type921 self.state.disp_obj_dict[k] = v.type 874 922 875 923 self.state.values = copy.deepcopy(self.values) … … 889 937 self.state.str_parameters) 890 938 self._copy_parameters_state(self.orientation_params, 891 939 self.state.orientation_params) 892 940 self._copy_parameters_state(self.orientation_params_disp, 893 941 self.state.orientation_params_disp) … … 920 968 self.state.disable_disp = self.disable_disp.GetValue() 921 969 922 self.state.smearer = copy.deepcopy(self.current_smearer)923 970 if hasattr(self, "enable_smearer"): 924 971 self.state.enable_smearer = \ … … 944 991 try: 945 992 self.state.disp_cb_dict[k] = v.GetValue() 946 except :993 except Exception: 947 994 self.state.disp_cb_dict[k] = None 948 995 if len(self._disp_obj_dict) > 0: 949 996 for k, v in self._disp_obj_dict.iteritems(): 950 self.state. _disp_obj_dict[k] = v.type997 self.state.disp_obj_dict[k] = v.type 951 998 952 999 self.state.values = copy.deepcopy(self.values) … … 990 1037 # to support older version 991 1038 category_pos = int(state.categorycombobox) 992 except :1039 except Exception: 993 1040 category_pos = 0 994 1041 for ind_cat in range(self.categorybox.GetCount()): … … 1002 1049 # to support older version 1003 1050 formfactor_pos = int(state.formfactorcombobox) 1004 except :1051 except Exception: 1005 1052 formfactor_pos = 0 1006 1053 for ind_form in range(self.formfactorbox.GetCount()): … … 1015 1062 # to support older version 1016 1063 structfactor_pos = int(state.structurecombobox) 1017 except :1064 except Exception: 1018 1065 structfactor_pos = 0 1019 1066 for ind_struct in range(self.structurebox.GetCount()): … … 1182 1229 self.categorybox.Select(category_pos) 1183 1230 self._show_combox(None) 1184 from models import PLUGIN_NAME_BASE 1185 if self.categorybox.GetValue() == CUSTOM_MODEL \ 1186 and PLUGIN_NAME_BASE not in state.formfactorcombobox: 1231 if (self.categorybox.GetValue() == CUSTOM_MODEL 1232 and PLUGIN_NAME_BASE not in state.formfactorcombobox): 1187 1233 state.formfactorcombobox = \ 1188 1234 PLUGIN_NAME_BASE + state.formfactorcombobox 1189 1235 formfactor_pos = 0 1190 1236 for ind_form in range(self.formfactorbox.GetCount()): 1191 if self.formfactorbox.GetString(ind_form) == \1192 (state.formfactorcombobox):1237 if (self.formfactorbox.GetString(ind_form) 1238 == state.formfactorcombobox): 1193 1239 formfactor_pos = int(ind_form) 1194 1240 break … … 1200 1246 state.structurecombobox = unicode(state.structurecombobox) 1201 1247 for ind_struct in range(self.structurebox.GetCount()): 1202 if self.structurebox.GetString(ind_struct) == \1203 (state.structurecombobox):1248 if (self.structurebox.GetString(ind_struct) 1249 == state.structurecombobox): 1204 1250 structfactor_pos = int(ind_struct) 1205 1251 break … … 1252 1298 self.dI_sqrdata.SetValue(state.dI_sqrdata) 1253 1299 self.dI_idata.SetValue(state.dI_idata) 1254 except :1300 except Exception: 1255 1301 # to support older state file formats 1256 1302 self.dI_noweight.SetValue(False) … … 1308 1354 self.weights = copy.deepcopy(state.weights) 1309 1355 1310 for key, disp_type in state. _disp_obj_dict.iteritems():1356 for key, disp_type in state.disp_obj_dict.iteritems(): 1311 1357 # disp_model = disp 1312 1358 disp_model = POLYDISPERSITY_MODELS[disp_type]() … … 1542 1588 try: 1543 1589 self.npts_x = float(self.Npts_total.GetValue()) 1544 except :1590 except Exception: 1545 1591 flag = False 1546 1592 return flag … … 1583 1629 return 1584 1630 1585 for j in range(len(listtorestore)):1631 for item_page in listtorestore: 1586 1632 for param in statelist: 1587 if param[1] == listtorestore[j][1]: 1588 item_page = listtorestore[j] 1633 if param[1] == item_page[1]: 1589 1634 item_page_info = param 1590 1635 if (item_page_info[1] == "theta" or item_page_info[1] == … … 1632 1677 listtorestore = copy.deepcopy(statelist) 1633 1678 1634 for j in range(len(listtorestore)): 1635 item_page = listtorestore[j] 1636 item_page_info = statelist[j] 1679 for item_page, item_page_info in zip(listtorestore, statelist): 1637 1680 # change the state of the check box for simple parameters 1638 1639 1681 if item_page[0] is not None: 1640 1682 item_page[0].SetValue(format_number(item_page_info[0], True)) … … 1741 1783 temp_smear = self.current_smearer 1742 1784 # compute weight for the current data 1743 from sas.sasgui.perspectives.fitting.utils import get_weight1744 1785 flag = self.get_weight_flag() 1745 1786 weight = get_weight(data=self.data, is2d=self._is_2D(), flag=flag) … … 1768 1809 1769 1810 from sas.sasgui.plottools import Data1D as pf_data1d 1770 # from sas.sasgui.perspectives.theory.profile_dialog import SLDPanel1771 1811 from sas.sasgui.guiframe.local_perspectives.plotting.profile_dialog \ 1772 1812 import SLDPanel … … 1829 1869 if mod_cat == CUSTOM_MODEL: 1830 1870 for model in self.model_list_box[mod_cat]: 1831 m_list.append(self.model_dict [model.name])1871 m_list.append(self.model_dictionary[model.name]) 1832 1872 else: 1833 1873 cat_dic = self.master_category_dict[mod_cat] 1834 for (model, enabled)in cat_dic:1874 for model, enabled in cat_dic: 1835 1875 if enabled: 1836 m_list.append(self.model_dict [model])1876 m_list.append(self.model_dictionary[model]) 1837 1877 except Exception: 1838 1878 msg = traceback.format_exc() … … 1906 1946 wx.PostEvent(self.parent, StatusEvent(status=msg)) 1907 1947 return 1908 except :1948 except Exception: 1909 1949 tcrtl.SetBackgroundColour("pink") 1910 1950 msg = "Model Error: wrong value entered: %s" % sys.exc_info()[1] … … 1963 2003 wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 1964 2004 return 1965 except :2005 except Exception: 1966 2006 tcrtl.SetBackgroundColour("pink") 1967 2007 msg = "Model Error: wrong value entered: %s" % sys.exc_info()[1] … … 2063 2103 2064 2104 if struct_factor is not None: 2065 from sasmodels.sasview_model import MultiplicationModel2066 2105 self.model = MultiplicationModel(form_factor(self.multi_factor), 2067 2106 struct_factor()) … … 2141 2180 # q value from qx and qy 2142 2181 radius = np.sqrt(data.qx_data * data.qx_data + 2143 2182 data.qy_data * data.qy_data) 2144 2183 # get unmasked index 2145 2184 index_data = (float(self.qmin.GetValue()) <= radius) & \ … … 2370 2409 put gaussian dispersity into current model 2371 2410 """ 2372 if len(self.param_toFit) > 0:2411 if self.param_toFit: 2373 2412 for item in self.fittable_param: 2374 2413 if item in self.param_toFit: … … 2385 2424 self.weights = {} 2386 2425 2387 # from sas.models.dispersion_models import GaussianDispersion 2388 from sasmodels.weights import GaussianDispersion 2389 if len(self.disp_cb_dict) == 0: 2390 self.save_current_state() 2426 if not self.disp_cb_dict: 2391 2427 self.sizer4_4.Clear(True) 2392 self.Layout() 2393 return 2394 if (len(self.disp_cb_dict) > 0): 2428 else: 2395 2429 for p in self.disp_cb_dict: 2396 2430 # The parameter was un-selected. … … 2465 2499 self._disp_obj_dict[name1] = disp_model 2466 2500 self.model.set_dispersion(param_name, disp_model) 2467 self.state. _disp_obj_dict[name1] = disp_model.type2501 self.state.disp_obj_dict[name1] = disp_model.type 2468 2502 2469 2503 value1 = str(format_number(self.model.getParam(name1), True)) … … 2580 2614 self._disp_obj_dict[name] = disp 2581 2615 self.model.set_dispersion(name.split('.')[0], disp) 2582 self.state. _disp_obj_dict[name] = disp.type2616 self.state.disp_obj_dict[name] = disp.type 2583 2617 self.values[name] = values 2584 2618 self.weights[name] = weights … … 2938 2972 # go through the parameters 2939 2973 strings = self._get_copy_helper(self.parameters, 2940 self.orientation_params)2974 self.orientation_params) 2941 2975 content += strings 2942 2976 2943 2977 # go through the fittables 2944 2978 strings = self._get_copy_helper(self.fittable_param, 2945 self.orientation_params_disp)2979 self.orientation_params_disp) 2946 2980 content += strings 2947 2981 2948 2982 # go through the fixed params 2949 2983 strings = self._get_copy_helper(self.fixed_param, 2950 self.orientation_params_disp)2984 self.orientation_params_disp) 2951 2985 content += strings 2952 2986 2953 2987 # go through the str params 2954 2988 strings = self._get_copy_helper(self.str_parameters, 2955 self.orientation_params)2989 self.orientation_params) 2956 2990 content += strings 2957 2991 return content … … 2966 3000 the names of parameters that have been fitted 2967 3001 2968 :returns: all_params - A list of all parameters, in the format of 3002 :returns: all_params - A list of all parameters, in the format of 2969 3003 self.parameters 2970 3004 :returns: fitted_par_names - A list of the names of parameters that have … … 3043 3077 # Only print errors for fitted parameters 3044 3078 content += param[4].GetValue() 3045 content += tab 3079 content += tab 3046 3080 3047 3081 return content … … 3063 3097 # Do nothing if self.parameters doesn't exist 3064 3098 return False 3065 3066 content = '\\begin{table}'3067 content += '\\begin{tabular}[h]'3099 3100 content = r'\begin{table}' 3101 content += r'\begin{tabular}[h]' 3068 3102 3069 3103 crlf = chr(13) + chr(10) … … 3075 3109 for param in all_params: 3076 3110 content += 'l|l|' 3077 content += '}\hline'3111 content += r'}\hline' 3078 3112 content += crlf 3079 3113 … … 3081 3115 for index, param in enumerate(all_params): 3082 3116 name = param[1] # Parameter name 3083 content += name.replace('_', '\_') # Escape underscores3117 content += name.replace('_', r'\_') # Escape underscores 3084 3118 if name in fitted_param_names: 3085 3119 # Only print errors for fitted parameters 3086 3120 content += ' & ' 3087 content += name.replace('_', '\_') +"\_err"3121 content += name.replace('_', r'\_') + r"\_err" 3088 3122 if index < len(all_params) - 1: 3089 3123 content += ' & ' 3090 3124 3091 content += '\\\\ \\hline'3125 content += r'\\ \hline' 3092 3126 content += crlf 3093 3127 … … 3108 3142 if index < len(all_params) - 1: 3109 3143 content += ' & ' 3110 3111 content += '\\\\ \\hline'3144 3145 content += r'\\ \hline' 3112 3146 content += crlf 3113 content += '\\end{tabular}'3114 content += '\\end{table}'3147 content += r'\end{tabular}' 3148 content += r'\end{table}' 3115 3149 3116 3150 return content … … 3369 3403 if name.endswith('.npts'): 3370 3404 pd = int(pd) 3371 except :3405 except Exception: 3372 3406 # continue 3373 3407 if not pd and pd != '': … … 3455 3489 self._disp_obj_dict[name] = disp_model 3456 3490 self.model.set_dispersion(param_name, disp_model) 3457 self.state. _disp_obj_dict[name] = disp_model.type3491 self.state.disp_obj_dict[name] = disp_model.type 3458 3492 # TODO: It's not an array, why update values and weights? 3459 3493 self.model._persistency_dict[param_name] = \ … … 3555 3589 self.model_box.Clear() 3556 3590 3557 if category == 'Plugin Models':3591 if category == CUSTOM_MODEL: 3558 3592 for model in self.model_list_box[category]: 3559 3593 str_m = str(model).split(".")[0] … … 3561 3595 3562 3596 else: 3563 for (model, enabled)in sorted(self.master_category_dict[category],3564 3565 if (enabled):3597 for model, enabled in sorted(self.master_category_dict[category], 3598 key=lambda name: name[0]): 3599 if enabled: 3566 3600 self.model_box.Append(model) 3567 3601 … … 3804 3838 self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus) 3805 3839 self.Bind(wx.EVT_KILL_FOCUS, self._silent_kill_focus 3806 if kill_focus_callback is None else kill_focus_callback)3840 if kill_focus_callback is None else kill_focus_callback) 3807 3841 self.Bind(wx.EVT_TEXT_ENTER, parent._onparamEnter 3808 if text_enter_callback is None else text_enter_callback)3842 if text_enter_callback is None else text_enter_callback) 3809 3843 if not ON_MAC: 3810 3844 self.Bind(wx.EVT_LEFT_UP, self._highlight_text 3811 if mouse_up_callback is None else mouse_up_callback)3845 if mouse_up_callback is None else mouse_up_callback) 3812 3846 3813 3847 def _on_set_focus(self, event): -
src/sas/sasgui/perspectives/fitting/batchfitpage.py
r7432acb r50fcb09 5 5 import wx.lib.newevent 6 6 import math 7 8 from sas.sascalc.fit.qsmearing import smear_selection 9 7 10 from sas.sasgui.guiframe.events import StatusEvent 8 11 from sas.sasgui.guiframe.events import NewPlotEvent 12 from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent 13 from sas.sasgui.perspectives.fitting.fitpage import FitPage 14 from sas.sasgui.perspectives.fitting.fitpage import check_data_validity 9 15 10 16 (Chi2UpdateEvent, EVT_CHI2_UPDATE) = wx.lib.newevent.NewEvent() … … 13 19 SMEAR_SIZE_L = 0.00 14 20 SMEAR_SIZE_H = 0.00 15 16 from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent17 from sas.sascalc.data_util.qsmearing import smear_selection18 from sas.sasgui.perspectives.fitting.fitpage import FitPage19 from sas.sasgui.perspectives.fitting.fitpage import check_data_validity20 21 21 22 class BatchFitPage(FitPage): … … 76 77 # """ 77 78 # is_2Ddata = False 78 # 79 # 79 80 # # Check if data is 2D 80 81 # if self.data.__class__.__name__ == "Data2D" or \ 81 82 # self.enable2D: 82 83 # is_2Ddata = True 83 # 84 # title = "Fitting" 84 # 85 # title = "Fitting" 85 86 # self._get_smear_info() 86 # 87 # 87 88 # #Sizers 88 89 # box_description_range = wx.StaticBox(self, wx.ID_ANY, str(title)) 89 # boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL) 90 # boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL) 90 91 # self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL) 91 92 # #sizer_smearer = wx.BoxSizer(wx.HORIZONTAL) … … 93 94 # self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL) 94 95 # sizer_chi2 = wx.BoxSizer(wx.VERTICAL) 95 # 96 # 96 97 # sizer_fit = wx.GridSizer(2, 4, 2, 6) 97 98 # #Fit button … … 100 101 # self.btFit.Bind(wx.EVT_BUTTON, self._onFit, id= self.btFit.GetId()) 101 102 # self.btFit.SetToolTipString("Start fitting.") 102 # 103 # 103 104 # # Update and Draw button 104 105 # self.draw_button = wx.Button(self, self._ids.next(), 'Compute', size=(88, 24)) 105 106 # self.draw_button.Bind(wx.EVT_BUTTON, \ 106 107 # self._onDraw,id=self.draw_button.GetId()) 107 # self.draw_button.SetToolTipString("Compute and Draw.") 108 # self.draw_button.SetToolTipString("Compute and Draw.") 108 109 # sizer_fit.Add(self.draw_button, 0, 0) 109 # sizer_fit.Add(self.btFit, 0, 0) 110 # sizer_fit.Add(self.btFit, 0, 0) 110 111 # sizer_chi2.Add((-1, 5)) 111 112 # # get smear_selection … … 114 115 # #2D data? default 115 116 # is_2Ddata = False 116 # 117 # 117 118 # #check if it is 2D data 118 119 # if self.data.__class__.__name__ == "Data2D" or \ 119 120 # self.enable2D: 120 121 # is_2Ddata = True 121 # 122 # 122 123 # self.sizer5.Clear(True) 123 # 124 # 124 125 # self.qmin = ModelTextCtrl(self, wx.ID_ANY, size=(_BOX_WIDTH, 20), 125 # style=wx.TE_PROCESS_ENTER, 126 # style=wx.TE_PROCESS_ENTER, 126 127 # text_enter_callback = self._onQrangeEnter) 127 128 # self.qmin.SetValue(str(self.qmin_x)) 128 129 # self.qmin.SetToolTipString("Minimun value of Q in linear scale.") 129 # 130 # 130 131 # self.qmax = ModelTextCtrl(self, wx.ID_ANY, size=(_BOX_WIDTH, 20), 131 # style=wx.TE_PROCESS_ENTER, 132 # style=wx.TE_PROCESS_ENTER, 132 133 # text_enter_callback=self._onQrangeEnter) 133 134 # self.qmax.SetValue(str(self.qmax_x)) 134 135 # self.qmax.SetToolTipString("Maximum value of Q in linear scale.") 135 # 136 # 136 137 # id = self._ids.next() 137 138 # self.reset_qrange =wx.Button(self, id, 'Reset', size=(77, 20)) 138 # 139 # 139 140 # self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked, id=id) 140 141 # self.reset_qrange.SetToolTipString(\ 141 142 # "Reset Q range to the default values") 142 # 143 # 143 144 # sizer_horizontal = wx.BoxSizer(wx.HORIZONTAL) 144 145 # sizer = wx.GridSizer(2, 4, 2, 6) 145 # 146 # 146 147 # self.btEditMask = wx.Button(self, self._ids.next(),'Editor', size=(88, 23)) 147 # self.btEditMask.Bind(wx.EVT_BUTTON, 148 # self.btEditMask.Bind(wx.EVT_BUTTON, 148 149 # self._onMask,id=self.btEditMask.GetId()) 149 150 # self.btEditMask.SetToolTipString("Edit Mask.") 150 151 # self.EditMask_title = wx.StaticText(self, wx.ID_ANY, ' Masking(2D)') 151 # 152 # 152 153 # sizer.Add(wx.StaticText(self, wx.ID_ANY, 'Q range')) 153 154 # sizer.Add(wx.StaticText(self, wx.ID_ANY, ' Min[1/A]')) 154 155 # sizer.Add(wx.StaticText(self, wx.ID_ANY, ' Max[1/A]')) 155 156 # sizer.Add(self.EditMask_title) 156 # 157 # sizer.Add(self.reset_qrange) 157 # 158 # sizer.Add(self.reset_qrange) 158 159 # sizer.Add(self.qmin) 159 160 # sizer.Add(self.qmax) 160 # 161 # 161 162 # sizer.Add(self.btEditMask) 162 # boxsizer_range.Add(sizer_chi2) 163 # boxsizer_range.Add(sizer_chi2) 163 164 # boxsizer_range.Add((10, 10)) 164 165 # boxsizer_range.Add(sizer) 165 # 166 # 166 167 # boxsizer_range.Add((10, 15)) 167 168 # boxsizer_range.Add(sizer_fit) 168 169 # if is_2Ddata: 169 # self.btEditMask.Enable() 170 # self.EditMask_title.Enable() 170 # self.btEditMask.Enable() 171 # self.EditMask_title.Enable() 171 172 # else: 172 # self.btEditMask.Disable() 173 # self.btEditMask.Disable() 173 174 # self.EditMask_title.Disable() 174 # 175 # 175 176 # ## save state 176 177 # #self.save_current_state() 177 # 178 # 178 179 # self.sizer5.Add(boxsizer_range, 0, wx.EXPAND | wx.ALL, 10) 179 180 # self.sizer5.Layout() 180 # 181 # def _on_select_model(self, event=None): 181 # 182 # def _on_select_model(self, event=None): 182 183 # """ 183 184 # call back for model selection 184 # """ 185 # 186 # self.Show(False) 187 # self._on_select_model_helper() 188 # self.set_model_param_sizer(self.model) 185 # """ 186 # 187 # self.Show(False) 188 # self._on_select_model_helper() 189 # self.set_model_param_sizer(self.model) 189 190 # if self.model is None: 190 191 # self._set_bookmark_flag(False) … … 199 200 # self.state.structurecombobox = self.structurebox.GetCurrentSelection() 200 201 # self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection() 201 # 202 # 202 203 # if self.model is not None: 203 204 # self._set_copy_flag(True) … … 206 207 # self._set_bookmark_flag(False) 207 208 # self._keep.Enable(False) 208 # 209 # 209 210 # temp_smear = None 210 211 # ## event to post model to fit to fitting plugins 211 212 # (ModelEventbox, _) = wx.lib.newevent.NewEvent() 212 # 213 # ## set smearing value whether or not 213 # 214 # ## set smearing value whether or not 214 215 # # the data contain the smearing info 215 # evt = ModelEventbox(model=self.model, 216 # smearer=temp_smear, 216 # evt = ModelEventbox(model=self.model, 217 # smearer=temp_smear, 217 218 # qmin=float(self.qmin_x), 218 219 # uid=self.uid, 219 # qmax=float(self.qmax_x)) 220 # 220 # qmax=float(self.qmax_x)) 221 # 221 222 # self._manager._on_model_panel(evt=evt) 222 223 # self.mbox_description.SetLabel("Model [%s]" % str(self.model.name)) 223 224 # self.state.model = self.model.clone() 224 225 # self.state.model.name = self.model.name 225 # 226 # 226 # 227 # 227 228 # if event is not None: 228 229 # ## post state to fit panel 229 230 # new_event = PageInfoEvent(page = self) 230 # wx.PostEvent(self.parent, new_event) 231 # wx.PostEvent(self.parent, new_event) 231 232 # #update list of plugins if new plugin is available 232 233 # if self.plugin_rbutton.GetValue(): … … 243 244 # self._draw_model() 244 245 # self.SetupScrolling() 245 # self.Show(True) 246 # 246 # self.Show(True) 247 # 247 248 # def _update_paramv_on_fit(self): 248 249 # """ … … 253 254 # self.fitrange = True 254 255 # is_modified = False 255 # 256 # 256 257 # if self.model is not None: 257 258 # ##Check the values … … 259 260 # self._check_value_enter( self.fixed_param) 260 261 # self._check_value_enter( self.parameters) 261 # 262 # # If qmin and qmax have been modified, update qmin and qmax and 262 # 263 # # If qmin and qmax have been modified, update qmin and qmax and 263 264 # # Here we should check whether the boundaries have been modified. 264 # # If qmin and qmax have been modified, update qmin and qmax and 265 # # If qmin and qmax have been modified, update qmin and qmax and 265 266 # # set the is_modified flag to True 266 267 # self.fitrange = self._validate_qrange(self.qmin, self.qmax) … … 273 274 # self.qmax_x = tempmax 274 275 # if tempmax == tempmin: 275 # flag = False 276 # flag = False 276 277 # #temp_smearer = None 277 278 # if self._is_2D(): 278 # # only 2D case set mask 279 # # only 2D case set mask 279 280 # flag = self._validate_Npts() 280 281 # if not flag: 281 282 # return flag 282 283 # else: flag = False 283 # else: 284 # else: 284 285 # flag = False 285 # 286 # #For invalid q range, disable the mask editor and fit button, vs. 286 # 287 # #For invalid q range, disable the mask editor and fit button, vs. 287 288 # if not self.fitrange: 288 289 # #self.btFit.Disable() … … 293 294 # if self._is_2D() and self.data is not None: 294 295 # self.btEditMask.Enable(True) 295 # 296 # 296 297 # if not flag: 297 298 # msg = "Cannot Plot or Fit :Must select a " 298 299 # msg += " model or Fitting range is not valid!!! " 299 300 # wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 300 # 301 # 301 302 # self.save_current_state() 302 # 303 # return flag 303 # 304 # return flag 304 305 # def save_current_state(self): 305 306 # """ 306 307 # Currently no save option implemented for batch page 307 308 # """ 308 # pass 309 # pass 309 310 # def save_current_state_fit(self): 310 311 # """ … … 314 315 # def set_data(self, data): 315 316 # """ 316 # reset the current data 317 # reset the current data 317 318 # """ 318 319 # #id = None … … 340 341 # self._set_save_flag(False) 341 342 # self._set_preview_flag(True) 342 # 343 # 343 344 # self.formfactorbox.Enable() 344 345 # self.structurebox.Enable() … … 346 347 # #set maximum range for x in linear scale 347 348 # if not hasattr(self.data,"data"): #Display only for 1D data fit 348 # # Minimum value of data 349 # # Minimum value of data 349 350 # data_min = min(self.data.x) 350 # # Maximum value of data 351 # # Maximum value of data 351 352 # data_max = max(self.data.x) 352 # self.btEditMask.Disable() 353 # self.btEditMask.Disable() 353 354 # self.EditMask_title.Disable() 354 355 # else: 355 # 356 # ## Minimum value of data 356 # 357 # ## Minimum value of data 357 358 # data_min = 0 358 # x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 359 # x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 359 360 # y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax)) 360 # ## Maximum value of data 361 # ## Maximum value of data 361 362 # data_max = math.sqrt(x*x + y*y) 362 # self.btEditMask.Enable() 363 # self.EditMask_title.Enable() 364 # 363 # self.btEditMask.Enable() 364 # self.EditMask_title.Enable() 365 # 365 366 # self.dataSource.SetValue(data_name) 366 367 # self.qmin_x = data_min … … 375 376 # self.state.qmin = self.qmin_x 376 377 # self.state.qmax = self.qmax_x 377 # 378 # 378 379 # #update model plot with new data information 379 380 # if flag: … … 385 386 # self.enable2D = False 386 387 # self.model_view.SetLabel("1D Mode") 387 # 388 # 388 389 # self.model_view.Disable() 389 # 390 # wx.PostEvent(self._manager.parent, 390 # 391 # wx.PostEvent(self._manager.parent, 391 392 # NewPlotEvent(group_id=group_id, 392 393 # action="delete")) 393 394 # #plot the current selected data 394 # wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, 395 # wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, 395 396 # title=str(self.data.title))) 396 397 # self._manager.store_data(uid=self.uid, data=data, -
src/sas/sasgui/perspectives/fitting/fit_thread.py
r959eb01 rba8d326 29 29 worktime=0.03, 30 30 reset_flag=False): 31 CalcThread.__init__(self, 32 completefn, 33 updatefn, 34 yieldtime, 35 worktime) 31 CalcThread.__init__(self, completefn, updatefn, yieldtime, worktime) 36 32 self.handler = handler 37 33 self.fitter = fn … … 93 89 # Real code should not print, but this is an example... 94 90 #print "keyboard exception" 95 #Stop on exception during fitting. Todo: need to put 91 #Stop on exception during fitting. Todo: need to put 96 92 #some mssg and reset progress bar. 97 93 … … 100 96 if self.handler is not None: 101 97 self.handler.stop(msg=msg) 102 except: 98 except: # catch-all: show every exception which stops the thread 103 99 import traceback 104 100 if self.handler is not None: -
src/sas/sasgui/perspectives/fitting/fitpage.py
r48154abb r0315b63 14 14 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 15 15 16 from sas.sascalc.fit.qsmearing import smear_selection 17 16 18 from sas.sasgui.guiframe.events import StatusEvent, NewPlotEvent, \ 17 19 PlotQrangeEvent … … 23 25 from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent as \ 24 26 PageInfoEvent 25 from sas.sascalc.data_util.qsmearing import smear_selection26 27 from .basepage import ModelTextCtrl 27 28 … … 1142 1143 self.model.name = "M" + str(self.index_model) 1143 1144 1144 def _on_select_model(self, event=None ):1145 def _on_select_model(self, event=None, keep_pars=False): 1145 1146 """ 1146 1147 call back for model selection 1147 1148 """ 1148 1149 self.Show(False) 1149 copy_flag = False1150 is_poly_enabled = None1151 1150 if event is not None: 1152 if (event.GetEventObject() == self.formfactorbox 1153 and self.structurebox.GetLabel() != 'None')\ 1154 or event.GetEventObject() == self.structurebox\ 1155 or event.GetEventObject() == self.multifactorbox: 1156 copy_flag = self.get_copy_params() 1157 is_poly_enabled = self.enable_disp.GetValue() 1151 control = event.GetEventObject() 1152 if ((control == self.formfactorbox 1153 and self.structurebox.GetLabel() != 'None') 1154 or control == self.structurebox 1155 or control == self.multifactorbox): 1156 keep_pars = True 1157 1158 if keep_pars: 1159 saved_pars = self.get_copy_params() 1160 is_poly_enabled = self.enable_disp.GetValue() 1161 else: 1162 saved_pars = None 1163 is_poly_enabled = None 1164 1158 1165 try: 1159 1166 self._on_select_model_helper() … … 1177 1184 try: 1178 1185 self.set_dispers_sizer() 1179 except :1186 except Exception: 1180 1187 pass 1181 1188 self.state.enable_disp = self.enable_disp.GetValue() … … 1238 1245 self.state.model.name = self.model.name 1239 1246 1247 # when select a model only from guictr/button 1248 if is_poly_enabled is not None: 1249 self.enable_disp.SetValue(is_poly_enabled) 1250 self.disable_disp.SetValue(not is_poly_enabled) 1251 self._set_dipers_Param(event=None) 1252 self.state.enable_disp = self.enable_disp.GetValue() 1253 self.state.disable_disp = self.disable_disp.GetValue() 1254 1255 # Keep the previous param values 1256 if saved_pars: 1257 self.get_paste_params(saved_pars) 1258 1240 1259 if event is not None: 1260 # update list of plugins if new plugin is available 1261 # mod_cat = self.categorybox.GetStringSelection() 1262 # if mod_cat == CUSTOM_MODEL: 1263 # temp = self.parent.update_model_list() 1264 # for v in self.parent.model_dictionary.values(): 1265 # if v.id == self.model.id: 1266 # self.model = v() 1267 # break 1268 # if temp: 1269 # self.model_list_box = temp 1270 # current_val = self.formfactorbox.GetLabel() 1271 # pos = self.formfactorbox.GetSelection() 1272 # self._show_combox_helper() 1273 # self.formfactorbox.SetStringSelection(current_val) 1274 # self.formfactorbox.SetValue(current_val) 1241 1275 # post state to fit panel 1242 1276 new_event = PageInfoEvent(page=self) 1243 1277 wx.PostEvent(self.parent, new_event) 1244 # update list of plugins if new plugin is available1245 mod_cat = self.categorybox.GetStringSelection()1246 if mod_cat == CUSTOM_MODEL:1247 temp_id = self.model.id1248 temp = self.parent.update_model_list()1249 for v in self.parent.model_dictionary.values():1250 if v.id == temp_id:1251 self.model = v()1252 break1253 if temp:1254 self.model_list_box = temp1255 current_val = self.formfactorbox.GetLabel()1256 pos = self.formfactorbox.GetSelection()1257 self._show_combox_helper()1258 self.formfactorbox.SetSelection(pos)1259 self.formfactorbox.SetValue(current_val)1260 # when select a model only from guictr/button1261 if is_poly_enabled is not None:1262 self.enable_disp.SetValue(is_poly_enabled)1263 self.disable_disp.SetValue(not is_poly_enabled)1264 self._set_dipers_Param(event=None)1265 self.state.enable_disp = self.enable_disp.GetValue()1266 self.state.disable_disp = self.disable_disp.GetValue()1267 1268 # Keep the previous param values1269 if copy_flag:1270 self.get_paste_params(copy_flag)1271 1278 wx.CallAfter(self._onDraw, None) 1272 1279 … … 1726 1733 ind = 0 1727 1734 while(ind < len(list)): 1728 for key, val in list.ite ritems():1729 if (val == ind):1735 for key, val in list.items(): 1736 if val == ind: 1730 1737 fun_box.Append(key, val) 1731 1738 break -
src/sas/sasgui/perspectives/fitting/fitpanel.py
r13374be r69363c7 9 9 from wx.aui import AuiNotebook as nb 10 10 11 from sas.sascalc.fit.models import ModelManager 12 11 13 from sas.sasgui.guiframe.panel_base import PanelBase 12 14 from sas.sasgui.guiframe.events import PanelOnFocusEvent, StatusEvent 13 15 from sas.sasgui.guiframe.dataFitting import check_data_validity 14 from sas.sasgui.perspectives.fitting.simfitpage import SimultaneousFitPage 15 16 import basepage 17 import models 16 17 18 from . import basepage 19 from .fitpage import FitPage 20 from .simfitpage import SimultaneousFitPage 21 from .batchfitpage import BatchFitPage 22 from .fitting_widgets import BatchDataDialog 23 18 24 _BOX_WIDTH = 80 19 25 … … 46 52 self.event_owner = None 47 53 # dictionary of miodel {model class name, model class} 48 self.menu_mng = models.ModelManager()54 self.menu_mng = ModelManager() 49 55 self.model_list_box = self.menu_mng.get_model_list() 50 56 # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING … … 114 120 """ 115 121 temp = self.menu_mng.update() 116 if len(temp):122 if temp: 117 123 self.model_list_box = temp 118 124 return temp … … 121 127 """ 122 128 """ 123 temp = self.menu_mng.plugins_reset() 124 if len(temp): 125 self.model_list_box = temp 126 return temp 129 self.model_list_box = self.menu_mng.plugins_reset() 130 return self.model_list_box 127 131 128 132 def get_page_by_id(self, uid): … … 298 302 self.model_list_box = dict 299 303 300 def set_model_dict (self, m_dict):304 def set_model_dictionary(self, model_dictionary): 301 305 """ 302 306 copy a dictionary of model name -> model object 303 307 304 :param m _dict: dictionary linking model name -> model object308 :param model_dictionary: dictionary linking model name -> model object 305 309 """ 306 310 … … 316 320 Add the simultaneous fit page 317 321 """ 318 from simfitpage import SimultaneousFitPage319 322 page_finder = self._manager.get_page_finder() 320 323 if caption == "Const & Simul Fit": … … 344 347 """ 345 348 if self.batch_on: 346 from batchfitpage import BatchFitPage347 349 panel = BatchFitPage(parent=self) 348 350 self.batch_page_index += 1 … … 351 353 else: 352 354 # Increment index of fit page 353 from fitpage import FitPage354 355 panel = FitPage(parent=self) 355 356 self.fit_page_index += 1 … … 359 360 panel._set_save_flag(not panel.batch_on) 360 361 panel.set_model_dictionary(self.model_dictionary) 361 panel.populate_box(model_ dict=self.model_list_box)362 panel.populate_box(model_list_box=self.model_list_box) 362 363 panel.formfactor_combo_init() 363 364 panel.set_manager(self._manager) … … 445 446 if data_1d_list and data_2d_list: 446 447 # need to warning the user that this batch is a special case 447 from sas.sasgui.perspectives.fitting.fitting_widgets import \448 BatchDataDialog449 448 dlg = BatchDataDialog(self) 450 449 if dlg.ShowModal() == wx.ID_OK: -
src/sas/sasgui/perspectives/fitting/fitproblem.py
r959eb01 r251ef684 14 14 ################################################################################ 15 15 import copy 16 from sas.sascalc.data_util.qsmearing import smear_selection 17 18 class FitProblemComponent(object): 16 17 from sas.sascalc.fit.qsmearing import smear_selection 18 19 class FitProblem(object): 19 20 """ 20 Inferface containing information to store data, model, range of data, etc... 21 and retreive this information. This is an inferface 22 for a fitProblem i.e relationship between data and model. 21 Define the relationship between data and model, including range, weights, 22 etc. 23 23 """ 24 def __init__(self): 25 """ 26 contains information about data and model to fit 27 """ 28 ## data used for fitting 29 self.fit_data = None 30 self.theory_data = None 31 self.residuals = None 32 # original data: should not be modified 33 self.original_data = None 34 ## the current model 35 self.model = None 36 ## if 1 this fit problem will be selected to fit , if 0 37 ## it will not be selected for fit 38 self.schedule = 0 39 ##list containing parameter name and value 40 self.list_param = [] 41 self.list_param2fit = [] 42 ## smear object to smear or not data1D 43 self.smearer_computed = False 44 self.smearer_enable = False 45 self.smearer_computer_value = None 46 ## fitting range 47 self.qmin = None 48 self.qmax = None 49 # fit weight 50 self.weight = None 51 self.result = None 52 self.fit_tab_caption = None 53 self.name_per_page = None 54 24 55 def enable_smearing(self, flag=False): 25 56 """ … … 27 58 flag is 0 ingore smear value. 28 59 """ 60 self.smearer_enable = flag 61 62 def set_smearer(self, smearer): 63 """ 64 save reference of smear object on fitdata 65 66 :param smear: smear object from DataLoader 67 68 """ 69 self.smearer_computer_value = smearer 29 70 30 71 def get_smearer(self): … … 32 73 return smear object 33 74 """ 75 if not self.smearer_enable: 76 return None 77 if not self.smearer_computed: 78 #smeari_selection should be call only once per fitproblem 79 self.smearer_computer_value = smear_selection(self.fit_data, 80 self.model) 81 self.smearer_computed = True 82 return self.smearer_computer_value 83 34 84 def save_model_name(self, name): 35 85 """ 36 86 """ 87 self.name_per_page = name 37 88 38 89 def get_name(self): 39 90 """ 40 91 """ 92 return self.name_per_page 41 93 42 94 def set_model(self, model): … … 46 98 :param name: name created for model 47 99 """ 100 self.model = model 101 self.smearer_computer_value = smear_selection(self.fit_data, 102 self.model) 103 self.smearer_computed = True 48 104 49 105 def get_model(self): … … 51 107 :return: saved model 52 108 """ 109 return self.model 53 110 54 111 def set_residuals(self, residuals): … … 57 114 :param data: data selected 58 115 """ 116 self.residuals = residuals 59 117 60 118 def get_residuals(self): … … 62 120 :return: residuals 63 121 """ 122 return self.residuals 64 123 65 124 def set_theory_data(self, data): 66 125 """ 67 126 save a copy of the data select to fit 127 68 128 :param data: data selected 69 """ 129 130 """ 131 self.theory_data = copy.deepcopy(data) 70 132 71 133 def get_theory_data(self): 72 134 """ 73 :return: list of data dList 74 """ 135 :return: theory generated with the current model and data of this class 136 """ 137 return self.theory_data 75 138 76 139 def set_fit_data(self, data): 77 140 """ 78 Store of list of data and create by create new fitproblem of each data 79 id, if there was existing information about model, this information 80 get copy to the new fitproblem 141 Store data associated with this class 81 142 :param data: list of data selected 82 143 """ 144 self.original_data = None 145 self.fit_data = None 146 # original data: should not be modified 147 self.original_data = data 148 # fit data: used for fit and can be modified for convenience 149 self.fit_data = copy.deepcopy(data) 150 self.smearer_computer_value = smear_selection(self.fit_data, self.model) 151 self.smearer_computed = True 152 self.result = None 83 153 84 154 def get_fit_data(self): 85 155 """ 86 """ 156 :return: data associate with this class 157 """ 158 return self.fit_data 159 160 def get_origin_data(self): 161 """ 162 """ 163 return self.original_data 164 165 def set_weight(self, is2d, flag=None): 166 """ 167 Received flag and compute error on data. 168 :param flag: flag to transform error of data. 169 :param is2d: flag to distinguish 1D to 2D Data 170 """ 171 from sas.sasgui.perspectives.fitting.utils import get_weight 172 # send original data for weighting 173 self.weight = get_weight(data=self.original_data, is2d=is2d, flag=flag) 174 if is2d: 175 self.fit_data.err_data = self.weight 176 else: 177 self.fit_data.dy = self.weight 178 179 def get_weight(self): 180 """ 181 returns weight array 182 """ 183 return self.weight 184 185 def set_param2fit(self, list): 186 """ 187 Store param names to fit (checked) 188 :param list: list of the param names 189 """ 190 self.list_param2fit = list 191 192 def get_param2fit(self): 193 """ 194 return the list param names to fit 195 """ 196 return self.list_param2fit 87 197 88 198 def set_model_param(self, name, value=None): … … 92 202 :param value: value of that parameter 93 203 """ 94 95 def set_param2fit(self, list): 96 """ 97 Store param names to fit (checked) 98 :param list: list of the param names 99 """ 100 101 def get_param2fit(self): 102 """ 103 return the list param names to fit 104 """ 204 self.list_param.append([name, value]) 105 205 106 206 def get_model_param(self): … … 108 208 return list of couple of parameter name and value 109 209 """ 210 return self.list_param 110 211 111 212 def schedule_tofit(self, schedule=0): … … 113 214 set schedule to true to decide if this fit must be performed 114 215 """ 216 self.schedule = schedule 115 217 116 218 def get_scheduled(self): … … 118 220 return true or false if a problem as being schedule for fitting 119 221 """ 222 return self.schedule 120 223 121 224 def set_range(self, qmin=None, qmax=None): 122 225 """ 123 226 set fitting range 124 """ 227 :param qmin: minimum value to consider for the fit range 228 :param qmax: maximum value to consider for the fit range 229 """ 230 self.qmin = qmin 231 self.qmax = qmax 125 232 126 233 def get_range(self): 127 234 """ 128 235 :return: fitting range 129 """ 130 131 def set_weight(self, flag=None): 132 """ 133 set fitting range 134 """ 135 136 def get_weight(self): 137 """ 138 get fitting weight 139 """ 236 237 """ 238 return self.qmin, self.qmax 140 239 141 240 def clear_model_param(self): … … 143 242 clear constraint info 144 243 """ 244 self.list_param = [] 145 245 146 246 def set_fit_tab_caption(self, caption): 147 247 """ 148 store the caption of the page associated with object149 """248 """ 249 self.fit_tab_caption = str(caption) 150 250 151 251 def get_fit_tab_caption(self): 152 252 """ 153 Return the caption of the page associated with object154 """253 """ 254 return self.fit_tab_caption 155 255 156 256 def set_graph_id(self, id): … … 158 258 Set graph id (from data_group_id at the time the graph produced) 159 259 """ 260 self.graph_id = id 160 261 161 262 def get_graph_id(self): … … 163 264 Get graph_id 164 265 """ 266 return self.graph_id 165 267 166 268 def set_result(self, result): 167 269 """ 168 270 """ 271 self.result = result 169 272 170 273 def get_result(self): … … 172 275 get result 173 276 """ 174 175 176 class FitProblemDictionary(FitProblemComponent, dict): 277 return self.result 278 279 280 class FitProblemDictionary(dict): 177 281 """ 178 282 This module implements a dictionary of fitproblem objects 179 283 """ 180 284 def __init__(self): 181 FitProblemComponent.__init__(self)182 285 dict.__init__(self) 183 286 ## the current model … … 206 309 self._smear_on = flag 207 310 if fid is None: 208 for value in self. itervalues():311 for value in self.values(): 209 312 value.enable_smearing(flag) 210 else: 211 if fid in self.iterkeys(): 212 self[fid].enable_smearing(flag) 313 elif fid in self: 314 self[fid].enable_smearing(flag) 213 315 214 316 def set_smearer(self, smearer, fid=None): … … 218 320 """ 219 321 if fid is None: 220 for value in self. itervalues():322 for value in self.values(): 221 323 value.set_smearer(smearer) 222 else: 223 if fid in self.iterkeys(): 224 self[fid].set_smearer(smearer) 324 elif fid in self: 325 self[fid].set_smearer(smearer) 225 326 226 327 def get_smearer(self, fid=None): … … 228 329 return smear object 229 330 """ 230 if fid in self .iterkeys():331 if fid in self: 231 332 return self[fid].get_smearer() 232 333 … … 235 336 """ 236 337 if fid is None: 237 for value in self. itervalues():338 for value in self.values(): 238 339 value.save_model_name(name) 239 else: 240 if fid in self.iterkeys(): 241 self[fid].save_model_name(name) 340 elif fid in self: 341 self[fid].save_model_name(name) 242 342 243 343 def get_name(self, fid=None): … … 246 346 result = [] 247 347 if fid is None: 248 for value in self. itervalues():348 for value in self.values(): 249 349 result.append(value.get_name()) 250 else: 251 if fid in self.iterkeys(): 252 result.append(self[fid].get_name()) 350 elif fid in self: 351 result.append(self[fid].get_name()) 253 352 return result 254 353 … … 261 360 self.model = model 262 361 if fid is None: 263 for value in self. itervalues():362 for value in self.values(): 264 363 value.set_model(self.model) 265 else: 266 if fid in self.iterkeys(): 267 self[fid].set_model(self.model) 364 elif fid in self: 365 self[fid].set_model(self.model) 268 366 269 367 def get_model(self, fid): … … 271 369 :return: saved model 272 370 """ 273 if fid in self .iterkeys():371 if fid in self: 274 372 return self[fid].get_model() 275 373 … … 291 389 :param data: data selected 292 390 """ 293 if fid in self .iterkeys():391 if fid in self: 294 392 self[fid].set_residuals(residuals) 295 393 … … 298 396 :return: residuals 299 397 """ 300 if fid in self .iterkeys():398 if fid in self: 301 399 return self[fid].get_residuals() 302 400 … … 306 404 :param data: data selected 307 405 """ 308 if fid in self .iterkeys():406 if fid in self: 309 407 self[fid].set_theory_data(data) 310 408 … … 313 411 :return: list of data dList 314 412 """ 315 if fid in self .iterkeys():413 if fid in self: 316 414 return self[fid].get_theory_data() 317 415 … … 322 420 :note: only data changes in the fit problem 323 421 """ 324 if data.id not in self .iterkeys():422 if data.id not in self: 325 423 self[data.id] = FitProblem() 326 424 self[data.id].set_fit_data(data) … … 336 434 data = [] 337 435 for d in data: 338 if (d is not None):339 if (d.id not in self.iterkeys()):436 if d is not None: 437 if d.id not in self: 340 438 self[d.id] = FitProblem() 341 439 self[d.id].set_fit_data(d) … … 348 446 :param fid: key representing a fitproblem, usually extract from data id 349 447 """ 350 if fid in self .iterkeys():448 if fid in self: 351 449 return self[fid].get_fit_data() 352 450 … … 358 456 """ 359 457 if fid is None: 360 for value in self. itervalues():458 for value in self.values(): 361 459 value.set_model_param(name, value) 362 else: 363 if fid in self.iterkeys(): 364 self[fid].set_model_param(name, value) 460 elif fid in self: 461 self[fid].set_model_param(name, value) 365 462 366 463 def get_model_param(self, fid): … … 368 465 return list of couple of parameter name and value 369 466 """ 370 if fid in self .iterkeys():467 if fid in self: 371 468 return self[fid].get_model_param() 372 469 … … 389 486 """ 390 487 self.scheduled = schedule 391 for value in self. itervalues():488 for value in self.values(): 392 489 value.schedule_tofit(schedule) 393 490 … … 405 502 self.qmax = qmax 406 503 if fid is None: 407 for value in self. itervalues():504 for value in self.values(): 408 505 value.set_range(self.qmin, self.qmax) 409 else: 410 if fid in self.iterkeys(): 411 self[fid].value.set_range(self.qmin, self.qmax) 506 elif fid in self: 507 self[fid].value.set_range(self.qmin, self.qmax) 412 508 413 509 def get_range(self, fid): … … 415 511 :return: fitting range 416 512 """ 417 if fid in self .iterkeys():513 if fid in self: 418 514 return self[fid].get_range() 419 515 … … 423 519 """ 424 520 if fid is None: 425 for value in self. itervalues():521 for value in self.values(): 426 522 value.set_weight(flag=flag, is2d=is2d) 427 else: 428 if fid in self.iterkeys(): 429 self[fid].set_weight(flag=flag, is2d=is2d) 523 elif fid in self: 524 self[fid].set_weight(flag=flag, is2d=is2d) 430 525 431 526 def get_weight(self, fid=None): … … 433 528 return fit weight 434 529 """ 435 if fid in self .iterkeys():530 if fid in self: 436 531 return self[fid].get_weight() 437 532 … … 441 536 """ 442 537 if fid is None: 443 for value in self. itervalues():538 for value in self.values(): 444 539 value.clear_model_param() 445 else: 446 if fid in self.iterkeys(): 447 self[fid].clear_model_param() 540 elif fid in self: 541 self[fid].clear_model_param() 448 542 449 543 def get_fit_problem(self): … … 451 545 return fitproblem contained in this dictionary 452 546 """ 453 return self. itervalues()547 return self.values() 454 548 455 549 def set_result(self, result, fid): 456 550 """ 457 551 """ 458 if fid in self .iterkeys():552 if fid in self: 459 553 self[fid].set_result(result) 460 554 … … 470 564 get result 471 565 """ 472 if fid in self .iterkeys():566 if fid in self: 473 567 return self[fid].get_result() 474 568 … … 490 584 """ 491 585 return self.graph_id 492 493 494 class FitProblem(FitProblemComponent):495 """496 FitProblem class allows to link a model with the new name created in _on_model,497 a name theory created with that model and the data fitted with the model.498 FitProblem is mostly used as value of the dictionary by fitting module.499 """500 def __init__(self):501 FitProblemComponent.__init__(self)502 """503 contains information about data and model to fit504 """505 ## data used for fitting506 self.fit_data = None507 self.theory_data = None508 self.residuals = None509 # original data: should not be modified510 self.original_data = None511 ## the current model512 self.model = None513 ## if 1 this fit problem will be selected to fit , if 0514 ## it will not be selected for fit515 self.schedule = 0516 ##list containing parameter name and value517 self.list_param = []518 ## smear object to smear or not data1D519 self.smearer_computed = False520 self.smearer_enable = False521 self.smearer_computer_value = None522 ## fitting range523 self.qmin = None524 self.qmax = None525 # fit weight526 self.weight = None527 self.result = None528 529 def enable_smearing(self, flag=False):530 """531 :param flag: bool.When flag is 1 get the computer smear value. When532 flag is 0 ingore smear value.533 """534 self.smearer_enable = flag535 536 def set_smearer(self, smearer):537 """538 save reference of smear object on fitdata539 540 :param smear: smear object from DataLoader541 542 """543 self.smearer_computer_value = smearer544 545 def get_smearer(self):546 """547 return smear object548 """549 if not self.smearer_enable:550 return None551 if not self.smearer_computed:552 #smeari_selection should be call only once per fitproblem553 self.smearer_computer_value = smear_selection(self.fit_data,554 self.model)555 self.smearer_computed = True556 return self.smearer_computer_value557 558 def save_model_name(self, name):559 """560 """561 self.name_per_page = name562 563 def get_name(self):564 """565 """566 return self.name_per_page567 568 def set_model(self, model):569 """570 associates each model with its new created name571 :param model: model selected572 :param name: name created for model573 """574 self.model = model575 self.smearer_computer_value = smear_selection(self.fit_data,576 self.model)577 self.smearer_computed = True578 579 def get_model(self):580 """581 :return: saved model582 """583 return self.model584 585 def set_residuals(self, residuals):586 """587 save a copy of residual588 :param data: data selected589 """590 self.residuals = residuals591 592 def get_residuals(self):593 """594 :return: residuals595 """596 return self.residuals597 598 def set_theory_data(self, data):599 """600 save a copy of the data select to fit601 602 :param data: data selected603 604 """605 self.theory_data = copy.deepcopy(data)606 607 def get_theory_data(self):608 """609 :return: theory generated with the current model and data of this class610 """611 return self.theory_data612 613 def set_fit_data(self, data):614 """615 Store data associated with this class616 :param data: list of data selected617 """618 self.original_data = None619 self.fit_data = None620 # original data: should not be modified621 self.original_data = data622 # fit data: used for fit and can be modified for convenience623 self.fit_data = copy.deepcopy(data)624 self.smearer_computer_value = smear_selection(self.fit_data,625 self.model)626 self.smearer_computed = True627 self.result = None628 629 def get_fit_data(self):630 """631 :return: data associate with this class632 """633 return self.fit_data634 635 def get_origin_data(self):636 """637 """638 return self.original_data639 640 def set_weight(self, is2d, flag=None):641 """642 Received flag and compute error on data.643 :param flag: flag to transform error of data.644 :param is2d: flag to distinguish 1D to 2D Data645 """646 from sas.sasgui.perspectives.fitting.utils import get_weight647 # send original data for weighting648 self.weight = get_weight(data=self.original_data, is2d=is2d, flag=flag)649 if is2d:650 self.fit_data.err_data = self.weight651 else:652 self.fit_data.dy = self.weight653 654 def get_weight(self):655 """656 returns weight array657 """658 return self.weight659 660 def set_param2fit(self, list):661 """662 Store param names to fit (checked)663 :param list: list of the param names664 """665 self.list_param2fit = list666 667 def get_param2fit(self):668 """669 return the list param names to fit670 """671 return self.list_param2fit672 673 def set_model_param(self, name, value=None):674 """675 Store the name and value of a parameter of this fitproblem's model676 :param name: name of the given parameter677 :param value: value of that parameter678 """679 self.list_param.append([name, value])680 681 def get_model_param(self):682 """683 return list of couple of parameter name and value684 """685 return self.list_param686 687 def schedule_tofit(self, schedule=0):688 """689 set schedule to true to decide if this fit must be performed690 """691 self.schedule = schedule692 693 def get_scheduled(self):694 """695 return true or false if a problem as being schedule for fitting696 """697 return self.schedule698 699 def set_range(self, qmin=None, qmax=None):700 """701 set fitting range702 :param qmin: minimum value to consider for the fit range703 :param qmax: maximum value to consider for the fit range704 """705 self.qmin = qmin706 self.qmax = qmax707 708 def get_range(self):709 """710 :return: fitting range711 712 """713 return self.qmin, self.qmax714 715 def clear_model_param(self):716 """717 clear constraint info718 """719 self.list_param = []720 721 def set_fit_tab_caption(self, caption):722 """723 """724 self.fit_tab_caption = str(caption)725 726 def get_fit_tab_caption(self):727 """728 """729 return self.fit_tab_caption730 731 def set_graph_id(self, id):732 """733 Set graph id (from data_group_id at the time the graph produced)734 """735 self.graph_id = id736 737 def get_graph_id(self):738 """739 Get graph_id740 """741 return self.graph_id742 743 def set_result(self, result):744 """745 """746 self.result = result747 748 def get_result(self):749 """750 get result751 """752 return self.result -
src/sas/sasgui/perspectives/fitting/fitting.py
r66acafe r9706d88 23 23 import traceback 24 24 25 import bumps.options 26 from bumps.gui.fit_dialog import show_fit_config 27 try: 28 from bumps.gui.fit_dialog import EVT_FITTER_CHANGED 29 except ImportError: 30 # CRUFT: bumps 0.7.5.8 and below 31 EVT_FITTER_CHANGED = None # type: wx.PyCommandEvent 32 25 33 from sas.sascalc.dataloader.loader import Loader 34 from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit 35 from sas.sascalc.fit.pagestate import Reader, PageState, SimFitPageState 36 from sas.sascalc.fit import models 37 26 38 from sas.sasgui.guiframe.dataFitting import Data2D 27 39 from sas.sasgui.guiframe.dataFitting import Data1D … … 34 46 from sas.sasgui.guiframe.plugin_base import PluginBase 35 47 from sas.sasgui.guiframe.data_processor import BatchCell 36 from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit 37 from sas.sasgui.perspectives.fitting.console import ConsoleUpdate 38 from sas.sasgui.perspectives.fitting.fitproblem import FitProblemDictionary 39 from sas.sasgui.perspectives.fitting.fitpanel import FitPanel 40 from sas.sasgui.perspectives.fitting.resultpanel import ResultPanel, PlotResultEvent 41 42 from sas.sasgui.perspectives.fitting.fit_thread import FitThread 43 from sas.sasgui.perspectives.fitting.pagestate import Reader 44 from sas.sasgui.perspectives.fitting.fitpage import Chi2UpdateEvent 48 from sas.sasgui.guiframe.gui_manager import MDIFrame 49 from sas.sasgui.guiframe.documentation_window import DocumentationWindow 50 45 51 from sas.sasgui.perspectives.calculator.model_editor import TextDialog 46 52 from sas.sasgui.perspectives.calculator.model_editor import EditorWindow 47 from sas.sasgui.guiframe.gui_manager import MDIFrame 48 from sas.sasgui.guiframe.documentation_window import DocumentationWindow 49 from sas.sasgui.perspectives.fitting.gpu_options import GpuOptions 50 51 from . import models 53 from sas.sasgui.perspectives.calculator.pyconsole import PyConsole 54 55 from .fitting_widgets import DataDialog 56 from .fit_thread import FitThread 57 from .fitpage import Chi2UpdateEvent 58 from .console import ConsoleUpdate 59 from .fitproblem import FitProblemDictionary 60 from .fitpanel import FitPanel 61 from .model_thread import Calc1D, Calc2D 62 from .resultpanel import ResultPanel, PlotResultEvent 63 from .gpu_options import GpuOptions 52 64 53 65 logger = logging.getLogger(__name__) … … 63 75 ON_MAC = True 64 76 65 import bumps.options66 from bumps.gui.fit_dialog import show_fit_config67 try:68 from bumps.gui.fit_dialog import EVT_FITTER_CHANGED69 except ImportError:70 # CRUFT: bumps 0.7.5.8 and below71 EVT_FITTER_CHANGED = None # type: wx.PyCommandEvent72 77 73 78 class Plugin(PluginBase): … … 240 245 event_id = event.GetId() 241 246 label = self.edit_menu.GetLabel(event_id) 242 from sas.sasgui.perspectives.calculator.pyconsole import PyConsole243 247 filename = os.path.join(models.find_plugins_dir(), label) 244 248 frame = PyConsole(parent=self.parent, manager=self, … … 290 294 break 291 295 except Exception: 292 import traceback;traceback.print_exc()296 traceback.print_exc() 293 297 msg = 'Delete Error: \nCould not delete the file; Check if in use.' 294 298 wx.MessageBox(msg, 'Error') … … 300 304 event_id = event.GetId() 301 305 model_manager = models.ModelManager() 302 model_list = model_manager. get_model_name_list()306 model_list = model_manager.composable_models() 303 307 plug_dir = models.find_plugins_dir() 304 308 textdial = TextDialog(None, self, wx.ID_ANY, 'Easy Sum/Multi(p1, p2) Editor', … … 340 344 self.set_edit_menu_helper(self.parent, self.edit_custom_model) 341 345 self.set_edit_menu_helper(self.parent, self.delete_custom_model) 342 temp = self.fit_panel.reset_pmodel_list() 343 if temp: 344 # Set the new plugin model list for all fit pages 345 for uid, page in self.fit_panel.opened_pages.iteritems(): 346 if hasattr(page, "formfactorbox"): 347 page.model_list_box = temp 348 current_val = page.formfactorbox.GetLabel() 349 #if page.plugin_rbutton.GetValue(): 350 mod_cat = page.categorybox.GetStringSelection() 351 if mod_cat == custom_model: 352 #pos = page.formfactorbox.GetSelection() 353 page._show_combox_helper() 354 new_val = page.formfactorbox.GetLabel() 355 if current_val != new_val and new_val != '': 356 page.formfactorbox.SetLabel(new_val) 357 else: 358 page.formfactorbox.SetLabel(current_val) 359 if hasattr(page, 'structurebox'): 360 selected_name = page.structurebox.GetStringSelection() 361 362 page.structurebox.Clear() 363 page.initialize_combox() 364 365 index = page.structurebox.FindString(selected_name) 366 if index == -1: 367 index = 0 368 page.structurebox.SetSelection(index) 369 page._on_select_model() 370 except: 346 new_pmodel_list = self.fit_panel.reset_pmodel_list() 347 if not new_pmodel_list: 348 return 349 # Set the new plugin model list for all fit pages 350 for uid, page in self.fit_panel.opened_pages.iteritems(): 351 if hasattr(page, "formfactorbox"): 352 page.model_list_box = new_pmodel_list 353 mod_cat = page.categorybox.GetStringSelection() 354 if mod_cat == custom_model: 355 box = page.formfactorbox 356 model_name = box.GetValue() 357 model = (box.GetClientData(box.GetCurrentSelection()) 358 if model_name else None) 359 page._show_combox_helper() 360 new_index = box.FindString(model_name) 361 new_model = (box.GetClientData(new_index) 362 if new_index >= 0 else None) 363 if new_index >= 0: 364 box.SetStringSelection(model_name) 365 else: 366 box.SetStringSelection('') 367 if model and new_model != model: 368 page._on_select_model(keep_pars=True) 369 if hasattr(page, "structurebox"): 370 selected_name = page.structurebox.GetStringSelection() 371 372 page.structurebox.Clear() 373 page.initialize_combox() 374 375 index = page.structurebox.FindString(selected_name) 376 if index == -1: 377 index = 0 378 page.structurebox.SetSelection(index) 379 page._on_select_model() 380 except Exception: 371 381 logger.error("update_custom_combo: %s", sys.exc_value) 372 382 … … 378 388 #new_model_menu = wx.Menu() 379 389 self.edit_model_menu.Append(wx_id, 'New Plugin Model', 380 'Add a new model function')390 'Add a new model function') 381 391 wx.EVT_MENU(owner, wx_id, self.make_new_model) 382 392 … … 575 585 else: 576 586 if len(data_list) > MAX_NBR_DATA: 577 from fitting_widgets import DataDialog578 587 dlg = DataDialog(data_list=data_list, nb_data=MAX_NBR_DATA) 579 588 if dlg.ShowModal() == wx.ID_OK: … … 620 629 : param datainfo: data 621 630 """ 622 from pagestate import PageState623 from simfitpage import SimFitPageState624 631 if isinstance(state, PageState): 625 632 state = state.clone() 626 633 self.temp_state.append(state) 627 634 elif isinstance(state, SimFitPageState): 628 state.load_from_save_state(self) 635 if self.fit_panel.sim_page is None: 636 self.fit_panel.add_sim_page() 637 self.fit_panel.sim_page.load_from_save_state(state) 629 638 else: 630 639 self.temp_state = [] … … 661 670 self.parent.add_data(data_list={data.id: data}) 662 671 wx.PostEvent(self.parent, NewPlotEvent(plot=data, 663 672 title=data.title)) 664 673 #need to be fix later make sure we are sendind guiframe.data 665 674 #to panel … … 672 681 self.parent.add_data(data_list={data.id: data}) 673 682 wx.PostEvent(self.parent, NewPlotEvent(plot=data, 674 683 title=data.title)) 675 684 page = self.add_fit_page([data]) 676 685 caption = page.window_caption 677 686 self.store_data(uid=page.uid, data_list=page.get_data_list(), 678 caption=caption)687 caption=caption) 679 688 self.mypanels.append(page) 680 689 … … 793 802 """ 794 803 if item.find(".") >= 0: 795 param_names = re.split( "\.", item)804 param_names = re.split(r"\.", item) 796 805 model_name = param_names[0] 797 806 ##Assume max len is 3; eg., M0.radius.width … … 896 905 897 906 self.draw_model(model=model, data=data, page_id=uid, smearer=smear, 898 enable1D=enable1D, enable2D=enable2D,899 qmin=qmin, qmax=qmax, weight=weight)907 enable1D=enable1D, enable2D=enable2D, 908 qmin=qmin, qmax=qmax, weight=weight) 900 909 901 910 def draw_model(self, model, page_id, data=None, smearer=None, … … 940 949 ## draw model 2D with no initial data 941 950 self._draw_model2D(model=model, 942 943 944 945 946 947 948 949 950 951 952 953 951 page_id=page_id, 952 data=data, 953 enable2D=enable2D, 954 smearer=smearer, 955 qmin=qmin, 956 qmax=qmax, 957 fid=fid, 958 weight=weight, 959 state=state, 960 toggle_mode_on=toggle_mode_on, 961 update_chisqr=update_chisqr, 962 source=source) 954 963 955 964 def onFit(self, uid): … … 960 969 :param uid: id related to the panel currently calling this fit function. 961 970 """ 962 if uid is None: raise RuntimeError("no page to fit") # Should never happen 971 if uid is None: 972 raise RuntimeError("no page to fit") # Should never happen 963 973 964 974 sim_page_uid = getattr(self.sim_page, 'uid', None) … … 994 1004 page = self.fit_panel.get_page_by_id(page_id) 995 1005 self.set_fit_weight(uid=page.uid, 996 flag=page.get_weight_flag(),997 is2d=page._is_2D())1006 flag=page.get_weight_flag(), 1007 is2d=page._is_2D()) 998 1008 if not page.param_toFit: 999 1009 msg = "No fitting parameters for %s" % page.window_caption … … 1019 1029 fitter = sim_fitter 1020 1030 self._add_problem_to_fit(fitproblem=fitproblem, 1021 pars=pars,1022 fitter=fitter,1023 fit_id=fit_id)1031 pars=pars, 1032 fitter=fitter, 1033 fit_id=fit_id) 1024 1034 fit_id += 1 1025 1035 list_page_id.append(page_id) … … 1068 1078 ## Perform more than 1 fit at the time 1069 1079 calc_fit = FitThread(handler=handler, 1070 1071 1072 1073 1074 1075 1080 fn=fitter_list, 1081 batch_inputs=batch_inputs, 1082 batch_outputs=batch_outputs, 1083 page_id=list_page_id, 1084 updatefn=handler.update_fit, 1085 completefn=self._fit_completed) 1076 1086 #self.fit_thread_list[current_page_id] = calc_fit 1077 1087 self.fit_thread_list[uid] = calc_fit … … 1134 1144 evt = StatusEvent(status=msg, info="warning") 1135 1145 wx.PostEvent(self.parent, evt) 1136 except :1146 except Exception: 1137 1147 msg = "Creating Fit page: %s" % sys.exc_value 1138 1148 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) … … 1158 1168 group_id = str(page.uid) + " Model1D" 1159 1169 wx.PostEvent(self.parent, 1160 NewPlotEvent(group_id=group_id,1161 1170 NewPlotEvent(group_id=group_id, 1171 action="delete")) 1162 1172 self.parent.update_data(prev_data=theory_data, 1163 1173 new_data=data) 1164 1174 else: 1165 1175 if theory_data is not None: … … 1167 1177 data.group_id = theory_data.group_id 1168 1178 wx.PostEvent(self.parent, 1169 NewPlotEvent(group_id=group_id,1170 1179 NewPlotEvent(group_id=group_id, 1180 action="delete")) 1171 1181 self.parent.update_data(prev_data=theory_data, 1172 1182 new_data=data) 1173 1183 self.store_data(uid=page.uid, data_list=page.get_data_list(), 1174 1184 caption=page.window_caption) … … 1479 1489 if "Data" not in batch_outputs.keys(): 1480 1490 batch_outputs["Data"] = [] 1481 from sas.sasgui.guiframe.data_processor import BatchCell1482 1491 cell = BatchCell() 1483 1492 cell.label = data.name … … 1579 1588 except KeyboardInterrupt: 1580 1589 fit_msg += "\nSingular point: Fitting stopped." 1581 except :1590 except Exception: 1582 1591 fit_msg += "\nSingular point: Fitting error occurred." 1583 1592 if fit_msg: 1584 evt = StatusEvent(status=fit_msg, info="warning", type="stop")1585 wx.PostEvent(self.parent, evt)1586 1587 except :1593 evt = StatusEvent(status=fit_msg, info="warning", type="stop") 1594 wx.PostEvent(self.parent, evt) 1595 1596 except Exception: 1588 1597 msg = ("Fit completed but the following error occurred: %s" 1589 1598 % sys.exc_value) 1590 # import traceback;msg = "\n".join((traceback.format_exc(), msg))1599 #msg = "\n".join((traceback.format_exc(), msg)) 1591 1600 evt = StatusEvent(status=msg, info="warning", type="stop") 1592 1601 wx.PostEvent(self.parent, evt) … … 1743 1752 fid=data.id) 1744 1753 self.parent.update_theory(data_id=data.id, theory=new_plot, 1745 1754 state=state) 1746 1755 return new_plot 1747 1756 … … 1767 1776 # Create the new theories 1768 1777 if unsmeared_model is not None: 1769 unsmeared_model_plot = self.create_theory_1D(x, unsmeared_model, 1778 unsmeared_model_plot = self.create_theory_1D(x, unsmeared_model, 1770 1779 page_id, model, data, state, 1771 1780 data_description=model.name + " unsmeared", … … 1774 1783 1775 1784 if unsmeared_data is not None and unsmeared_error is not None: 1776 unsmeared_data_plot = self.create_theory_1D(x, unsmeared_data, 1785 unsmeared_data_plot = self.create_theory_1D(x, unsmeared_data, 1777 1786 page_id, model, data, state, 1778 1787 data_description="Data unsmeared", … … 1792 1801 plots_to_update.append(pq_plot) 1793 1802 # Update the P(Q), S(Q) and unsmeared theory plots if they exist 1794 wx.PostEvent(self.parent, NewPlotEvent(plots=plots_to_update, 1803 wx.PostEvent(self.parent, NewPlotEvent(plots=plots_to_update, 1795 1804 action='update')) 1796 1805 … … 1808 1817 1809 1818 self.page_finder[page_id].set_theory_data(data=new_plot, 1810 1819 fid=data.id) 1811 1820 if toggle_mode_on: 1812 1821 wx.PostEvent(self.parent, 1813 1822 NewPlotEvent(group_id=str(page_id) + " Model2D", 1814 1823 action="Hide")) 1815 1824 else: 1816 1825 if update_chisqr: 1817 wx.PostEvent(current_pg, 1818 Chi2UpdateEvent(output=self._cal_chisqr( 1819 data=data, 1820 fid=fid, 1821 weight=weight, 1822 page_id=page_id, 1823 index=index))) 1826 output = self._cal_chisqr(data=data, 1827 fid=fid, 1828 weight=weight, 1829 page_id=page_id, 1830 index=index) 1831 wx.PostEvent(current_pg, Chi2UpdateEvent(output=output)) 1824 1832 else: 1825 1833 self._plot_residuals(page_id=page_id, data=data, fid=fid, … … 1829 1837 logger.error("Using the present parameters the model does not return any finite value. ") 1830 1838 msg = "Computing Error: Model did not return any finite value." 1831 wx.PostEvent(self.parent, StatusEvent(status =msg, info="error"))1839 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 1832 1840 else: 1833 1841 msg = "Computation completed!" … … 1854 1862 1855 1863 def _complete2D(self, image, data, model, page_id, elapsed, index, qmin, 1856 qmax, fid=None, weight=None, toggle_mode_on=False, state=None,1857 1864 qmax, fid=None, weight=None, toggle_mode_on=False, state=None, 1865 update_chisqr=True, source='model', plot_result=True): 1858 1866 """ 1859 1867 Complete get the result of modelthread and create model 2D … … 1896 1904 fid=data.id) 1897 1905 self.parent.update_theory(data_id=data.id, 1898 1899 1906 theory=new_plot, 1907 state=state) 1900 1908 current_pg = self.fit_panel.get_page_by_id(page_id) 1901 1909 title = new_plot.title 1902 1910 if not source == 'fit' and plot_result: 1903 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1904 title=title)) 1911 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=title)) 1905 1912 if toggle_mode_on: 1906 1913 wx.PostEvent(self.parent, 1907 1908 1914 NewPlotEvent(group_id=str(page_id) + " Model1D", 1915 action="Hide")) 1909 1916 else: 1910 1917 # Chisqr in fitpage 1911 1918 if update_chisqr: 1912 wx.PostEvent(current_pg,1913 Chi2UpdateEvent(output=self._cal_chisqr(data=data,1914 weight=weight,1915 fid=fid,1916 page_id=page_id,1917 index=index)))1919 output = self._cal_chisqr(data=data, 1920 weight=weight, 1921 fid=fid, 1922 page_id=page_id, 1923 index=index) 1924 wx.PostEvent(current_pg, Chi2UpdateEvent(output=output)) 1918 1925 else: 1919 1926 self._plot_residuals(page_id=page_id, data=data, fid=fid, 1920 1927 index=index, weight=weight) 1921 1928 1922 1929 if not number_finite: 1923 1930 logger.error("Using the present parameters the model does not return any finite value. ") 1924 1931 msg = "Computing Error: Model did not return any finite value." 1925 wx.PostEvent(self.parent, StatusEvent(status =msg, info="error"))1932 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 1926 1933 else: 1927 1934 msg = "Computation completed!" … … 1939 1946 weight=None, 1940 1947 toggle_mode_on=False, 1941 1948 update_chisqr=True, source='model'): 1942 1949 """ 1943 1950 draw model in 2D … … 1954 1961 return None 1955 1962 try: 1956 from model_thread import Calc2D1957 1963 ## If a thread is already started, stop it 1958 1964 if (self.calc_2D is not None) and self.calc_2D.isrunning(): … … 1986 1992 def _draw_model1D(self, model, page_id, data, 1987 1993 qmin, qmax, smearer=None, 1988 state=None, 1989 weight=None, 1990 fid=None, 1991 toggle_mode_on=False, update_chisqr=True, source='model', 1992 enable1D=True): 1994 state=None, weight=None, fid=None, 1995 toggle_mode_on=False, update_chisqr=True, source='model', 1996 enable1D=True): 1993 1997 """ 1994 1998 Draw model 1D from loaded data1D … … 2001 2005 return 2002 2006 try: 2003 from model_thread import Calc1D2004 2007 ## If a thread is already started, stop it 2005 2008 if (self.calc_1D is not None) and self.calc_1D.isrunning(): -
src/sas/sasgui/perspectives/fitting/model_thread.py
r0f9ea1c r69363c7 1 1 """ 2 2 Calculation thread for modeling 3 3 """ 4 4 5 5 import time 6 import math 7 6 8 import numpy as np 7 import math 9 8 10 from sas.sascalc.data_util.calcthread import CalcThread 9 11 from sas.sascalc.fit.MultiplicationModel import MultiplicationModel … … 28 30 worktime=0.04, 29 31 exception_handler=None, 30 32 ): 31 33 CalcThread.__init__(self, completefn, updatefn, yieldtime, worktime, 32 34 exception_handler=exception_handler) … … 57 59 if self.qmax is None: 58 60 if self.data is not None: 59 newx = math.pow(max(math.fabs(self.data.xmax), 60 math.fabs(self.data.xmin)), 2) 61 newy = math.pow(max(math.fabs(self.data.ymax), 62 math.fabs(self.data.ymin)), 2) 63 self.qmax = math.sqrt(newx + newy) 61 newx = max(math.fabs(self.data.xmax), math.fabs(self.data.xmin)) 62 newy = max(math.fabs(self.data.ymax), math.fabs(self.data.ymin)) 63 self.qmax = math.sqrt(newx**2 + newy**2) 64 64 65 65 if self.data is None: … … 68 68 69 69 # Define matrix where data will be plotted 70 radius = np.sqrt((self.data.qx_data * self.data.qx_data) + \ 71 (self.data.qy_data * self.data.qy_data)) 70 radius = np.sqrt(self.data.qx_data**2 + self.data.qy_data**2) 72 71 73 72 # For theory, qmax is based on 1d qmax 74 73 # so that must be mulitified by sqrt(2) to get actual max for 2d 75 74 index_model = (self.qmin <= radius) & (radius <= self.qmax) 76 index_model = index_model &self.data.mask77 index_model = index_model &np.isfinite(self.data.data)75 index_model &= self.data.mask 76 index_model &= np.isfinite(self.data.data) 78 77 79 78 if self.smearer is not None: … … 101 100 elapsed = time.time() - self.starttime 102 101 self.complete(image=output, 103 104 105 106 107 108 109 110 111 112 113 114 115 116 102 data=self.data, 103 page_id=self.page_id, 104 model=self.model, 105 state=self.state, 106 toggle_mode_on=self.toggle_mode_on, 107 elapsed=elapsed, 108 index=index_model, 109 fid=self.fid, 110 qmin=self.qmin, 111 qmax=self.qmax, 112 weight=self.weight, 113 #qstep=self.qstep, 114 update_chisqr=self.update_chisqr, 115 source=self.source) 117 116 118 117 … … 138 137 worktime=0.01, 139 138 exception_handler=None, 140 139 ): 141 140 """ 142 141 """ … … 193 192 * unsmeared_output[first_bin:last_bin+1]\ 194 193 / output[first_bin:last_bin+1] 195 unsmeared_output =unsmeared_output[index]196 unsmeared_data =unsmeared_data[index]197 unsmeared_error =unsmeared_error194 unsmeared_output = unsmeared_output[index] 195 unsmeared_data = unsmeared_data[index] 196 unsmeared_error = unsmeared_error 198 197 else: 199 198 output[index] = self.model.evalDistribution(self.data.x[index]) … … 243 242 class CalcCommandline: 244 243 def __init__(self, n=20000): 245 #print thread.get_ident()246 from sas.models.CylinderModel import CylinderModel 247 248 model = CylinderModel()249 250 251 print model.runXY([0.01, 0.02])244 #print(thread.get_ident()) 245 246 from sasmodels.sasview_model import _make_standard_model 247 cylinder = _make_standard_model('cylinder') 248 model = cylinder() 249 250 print(model.runXY([0.01, 0.02])) 252 251 253 252 qmax = 0.01 … … 258 257 y = numpy.arange(-qmax, qmax+qstep*0.01, qstep) 259 258 260 261 259 calc_thread_2D = Calc2D(x, y, None, model.clone(),None, 262 260 -qmax, qmax,qstep, 263 264 265 261 completefn=self.complete, 262 updatefn=self.update , 263 yieldtime=0.0) 266 264 267 265 calc_thread_2D.queue() … … 272 270 273 271 def update(self,output): 274 print "update"272 print("update") 275 273 276 274 def complete(self, image, data, model, elapsed, qmin, qmax,index, qstep ): 277 print "complete"275 print("complete") 278 276 self.done = True 279 277 -
src/sas/sasgui/perspectives/fitting/report_dialog.py
r7432acb r69a6897 38 38 # number of images of plot 39 39 self.nimages = len(self.report_list[2]) 40 41 if self.report_list[2] is not None: 42 # put image path in the report string 43 if len(self.report_list[2]) == 1: 44 self.report_html = self.report_list[0] % \ 45 "memory:img_fit0.png" 46 elif len(self.report_list[2]) == 2: 47 self.report_html = self.report_list[0] % \ 48 ("memory:img_fit0.png", 49 "memory:img_fit1.png") 50 # allows up to three images 51 else: 52 self.report_html = self.report_list[0] % \ 53 ("memory:img_fit0.png", 54 "memory:img_fit1.png", 55 "memory:img_fit2.png") 56 else: 57 self.report_html = self.report_list[0] 40 self.report_html = self.report_list[0] 58 41 # layout 59 42 self._setup_layout() … … 74 57 75 58 fName = dlg.GetPath() 59 basename = os.path.splitext(fName)[0] 76 60 ext_num = dlg.GetFilterIndex() 61 dlg.Destroy() 62 63 if ext_num == 0 and self.index_offset == 0: # has pdf 64 ext = ".pdf" 65 elif ext_num == 1 - self.index_offset: 66 ext = ".html" 67 elif ext_num == 2 - self.index_offset: 68 ext = ".txt" 69 else: 70 logger.warn("unknown export format in report dialog") 71 return 72 filename = basename + ext 73 74 # save figures 75 pictures = [] 76 for num in range(self.nimages): 77 pic_name = basename + '_img%s.png' % num 78 # save the image for use with pdf writer 79 self.report_list[2][num].savefig(pic_name) 80 pictures.append(pic_name) 81 82 # translate png references int html from in-memory name to on-disk name 83 html = self.report_html.replace("memory:img_fit", basename+'_img') 77 84 78 85 #set file extensions 79 86 img_ext = [] 80 pic_fname = [] 81 #PDF 82 if ext_num == (0 + 2 * self.index_offset): 83 # TODO: Sort this case out 84 ext = '.pdf' 87 if ext == ".pdf": 88 # write pdf as a pdf file 89 pdf = self.HTML2PDF(data=html, filename=filename) 85 90 86 fName = os.path.splitext(fName)[0] + ext 87 dlg.Destroy() 88 #pic (png) file path/name 89 for num in range(self.nimages): 90 im_ext = '_img%s.png' % num 91 #img_ext.append(im_ext) 92 pic_name = os.path.splitext(fName)[0] + im_ext 93 pic_fname.append(pic_name) 94 # save the image for use with pdf writer 95 self.report_list[2][num].savefig(pic_name) 91 # delete images used to create the pdf 92 for pic_name in pictures: 93 os.remove(pic_name) 96 94 97 #put the image path in html string 98 report_frame = self.report_list[0] 99 #put image name strings into the html file 100 #Note:The str for pic_fname shouldn't be removed. 101 if self.nimages == 1: 102 html = report_frame % str(pic_fname[0]) 103 elif self.nimages == 2: 104 html = report_frame % (str(pic_fname[0]), str(pic_fname[1])) 105 elif self.nimages == 3: 106 html = report_frame % (str(pic_fname[0]), str(pic_fname[1]), 107 str(pic_fname[2])) 108 109 # make/open file in case of absence 110 f = open(fName, 'w') 111 f.close() 112 # write pdf as a pdf file 113 pdf = self.HTML2PDF(data=html, filename=fName) 114 115 #open pdf 95 #open pdf viewer 116 96 if pdf: 117 97 try: 118 #Windows 119 os.startfile(str(fName)) 120 except: 121 try: 122 #Mac 98 if os.name == 'nt': # Windows 99 os.startfile(fName) 100 elif sys.platform == "darwin": # Mac 123 101 os.system("open %s" % fName) 124 except: 125 #DO not open 126 pass 127 #delete image file 128 for num in range(self.nimages): 129 os.remove(pic_fname[num]) 130 return 131 #HTML + png(graph) 132 elif ext_num == (1 - self.index_offset): 133 ext = '.html' 134 for num in range(self.nimages): 135 img_ext.append('_img4html%s.png' % num) 136 report_frame = self.report_list[0] 137 #TEXT + pdf(graph) 138 elif ext_num == (2 - self.index_offset): 139 ext = '.txt' 140 # changing the image extension actually changes the image 141 # format on saving 142 for num in range(self.nimages): 143 img_ext.append('_img4txt%s.pdf' % num) 144 report = self.report_list[1] 145 else: 146 return 102 except Exception as exc: 103 # cannot open pdf 104 logging.error(str(exc)) 147 105 148 #file name149 fName = os.path.splitext(fName)[0] + ext150 dlg.Destroy()106 elif ext == ".html": 107 with open(filename, 'w') as f: 108 f.write(html) 151 109 152 #pic (png) file path/name 153 for num in range(self.nimages): 154 pic_name = os.path.splitext(fName)[0] + img_ext[num] 155 pic_fname.append(pic_name) 156 #put the image path in html string 157 if ext_num == (1 - self.index_offset): 158 if self.nimages == 1: 159 report = report_frame % os.path.basename(pic_fname[0]) 160 elif self.nimages == 2: 161 report = report_frame % (os.path.basename(pic_fname[0]), 162 os.path.basename(pic_fname[1])) 163 elif self.nimages == 3: 164 report = report_frame % (os.path.basename(pic_fname[0]), 165 os.path.basename(pic_fname[1]), 166 os.path.basename(pic_fname[2])) 167 f = open(fName, 'w') 168 f.write(report) 169 f.close() 110 elif ext == ".txt": 111 with open(filename, 'w') as f: 112 f.write(self.report_list[1]) 113 170 114 self.Update() 171 #save png file using pic_fname172 for num in range(self.nimages):173 self.report_list[2][num].savefig(pic_fname[num]) -
src/sas/sasgui/perspectives/fitting/simfitpage.py
r9804394 r24d9e84 2 2 Simultaneous or Batch fit page 3 3 """ 4 # Note that this is used for both Simultaneous/Constrained fit AND for 4 # Note that this is used for both Simultaneous/Constrained fit AND for 5 5 # combined batch fit. This is done through setting of the batch_on parameter. 6 # There are the a half dozen or so places where an if statement is used as in 6 # There are the a half dozen or so places where an if statement is used as in 7 7 # if not batch_on: 8 8 # xxxx … … 11 11 # This is just wrong but dont have time to fix this go. Proper approach would be 12 12 # to strip all parts of the code that depend on batch_on and create the top 13 # level class from which a contrained/simultaneous fit page and a combined 13 # level class from which a contrained/simultaneous fit page and a combined 14 14 # batch page inherit. 15 15 # … … 23 23 from wx.lib.scrolledpanel import ScrolledPanel 24 24 25 from sas.sascalc.fit.pagestate import SimFitPageState 25 26 from sas.sasgui.guiframe.events import StatusEvent, PanelOnFocusEvent 26 27 from sas.sasgui.guiframe.panel_base import PanelBase … … 60 61 61 62 return fittable_param 62 63 63 64 64 class SimultaneousFitPage(ScrolledPanel, PanelBase): … … 157 157 return self.state 158 158 159 def load_from_save_state(self, sim_state): 160 """ 161 Load in a simultaneous/constrained fit from a save state 162 :param fit: Fitpanel object 163 :return: None 164 """ 165 init_map = {} 166 final_map = {} 167 # Process each model and associate old M# with new M# 168 i = 0 169 for model in self.model_list: 170 model_id = self._format_id(model[1].keys()[0]) 171 for saved_model in sim_state.model_list: 172 save_id = saved_model.pop('name') 173 saved_model['name'] = save_id 174 save_id = self._format_id(save_id) 175 if save_id == model_id: 176 model_map[saved_model.pop('fit_page_source')] = \ 177 model[3].name 178 check = bool(saved_model.pop('checked')) 179 self.model_list[i][0].SetValue(check) 180 inter_id = str(i)*5 181 init_map[saved_model.pop('fit_page_source')] = inter_id 182 final_map[inter_id] = model[3].name 183 check = bool(saved_model.pop('checked')) 184 self.model_list[i][0].SetValue(check) 185 break 186 i += 1 187 188 self.check_model_name(None) 189 190 if len(sim_state.constraints_list) > 0: 191 self.hide_constraint.SetValue(False) 192 self.show_constraint.SetValue(True) 193 self._display_constraint(None) 194 195 for index, item in enumerate(sim_state.constraints_list): 196 model_cbox = item.pop('model_cbox') 197 if model_cbox != "": 198 constraint_value = item.pop('constraint') 199 param = item.pop('param_cbox') 200 equality = item.pop('egal_txt') 201 for key, value in init_map.items(): 202 model_cbox = model_cbox.replace(key, value) 203 constraint_value = constraint_value.replace(key, value) 204 for key, value in final_map.items(): 205 model_cbox = model_cbox.replace(key, value) 206 constraint_value = constraint_value.replace(key, value) 207 208 self.constraints_list[index][0].SetValue(model_cbox) 209 self._on_select_model(None) 210 self.constraints_list[index][1].SetValue(param) 211 self.constraints_list[index][2].SetLabel(equality) 212 self.constraints_list[index][3].SetValue(constraint_value) 213 self._on_add_constraint(None) 214 self._manager.sim_page = self 215 216 def _format_id(self, original_id): 217 original_id = original_id.rstrip('1234567890.') 218 new_id_list = original_id.split() 219 new_id = ' '.join(new_id_list) 220 return new_id 221 222 223 159 224 def draw_page(self): 160 225 """ 161 226 Construct the Simultaneous/Constrained fit page. fills the first 162 region (sizer1) with the list of available fit page pairs of data 227 region (sizer1) with the list of available fit page pairs of data 163 228 and models. Then fills sizer2 with the checkbox for adding 164 229 constraints, and finally fills sizer3 with the fit button and … … 1043 1108 cbox.Append(name, value) 1044 1109 cbox.SetStringSelection(selected) 1045 1046 1047 class SimFitPageState:1048 """1049 State of the simultaneous fit page for saving purposes1050 """1051 1052 def __init__(self):1053 # Sim Fit Page Number1054 self.fit_page_no = None1055 # Select all data1056 self.select_all = False1057 # Data sets sent to fit page1058 self.model_list = []1059 # Data sets to be fit1060 self.model_to_fit = []1061 # Number of constraints1062 self.no_constraint = 01063 # Dictionary of constraints1064 self.constraint_dict = {}1065 # List of constraints1066 self.constraints_list = []1067 1068 def load_from_save_state(self, fit):1069 """1070 Load in a simultaneous/constrained fit from a save state1071 :param fit: Fitpanel object1072 :return: None1073 """1074 1075 init_map = {}1076 final_map = {}1077 if fit.fit_panel.sim_page is None:1078 fit.fit_panel.add_sim_page()1079 sim_page = fit.fit_panel.sim_page1080 1081 # Process each model and associate old M# with new M#1082 i = 01083 for model in sim_page.model_list:1084 model_id = self._format_id(model[1].keys()[0])1085 for saved_model in self.model_list:1086 save_id = saved_model.pop('name')1087 saved_model['name'] = save_id1088 save_id = self._format_id(save_id)1089 if save_id == model_id:1090 inter_id = str(i) + str(i) + str(i) + str(i) + str(i)1091 init_map[saved_model.pop('fit_page_source')] = inter_id1092 final_map[inter_id] = model[3].name1093 check = bool(saved_model.pop('checked'))1094 sim_page.model_list[i][0].SetValue(check)1095 break1096 i += 11097 sim_page.check_model_name(None)1098 1099 if len(self.constraints_list) > 0:1100 sim_page.hide_constraint.SetValue(False)1101 sim_page.show_constraint.SetValue(True)1102 sim_page._display_constraint(None)1103 1104 for index, item in enumerate(self.constraints_list):1105 model_cbox = item.pop('model_cbox')1106 if model_cbox != "":1107 constraint_value = item.pop('constraint')1108 param = item.pop('param_cbox')1109 equality = item.pop('egal_txt')1110 for key, value in init_map.items():1111 model_cbox = model_cbox.replace(key, value)1112 constraint_value = constraint_value.replace(key, value)1113 for key, value in final_map.items():1114 model_cbox = model_cbox.replace(key, value)1115 constraint_value = constraint_value.replace(key, value)1116 1117 sim_page.constraints_list[index][0].SetValue(model_cbox)1118 sim_page._on_select_model(None)1119 sim_page.constraints_list[index][1].SetValue(param)1120 sim_page.constraints_list[index][2].SetLabel(equality)1121 sim_page.constraints_list[index][3].SetValue(constraint_value)1122 sim_page._on_add_constraint(None)1123 sim_page._manager.sim_page = sim_page1124 1125 def _format_id(self, original_id):1126 original_id = original_id.rstrip('1234567890.')1127 new_id_list = original_id.split()1128 new_id = ' '.join(new_id_list)1129 return new_id
Note: See TracChangeset
for help on using the changeset viewer.