Changeset 1dbdb83 in sasview for src/sas/sasgui
- Timestamp:
- Oct 6, 2016 3:49:02 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:
- 4fea1df
- Parents:
- e89aed5 (diff), be4cb41 (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
- Files:
-
- 18 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/events.py
rd85c194 r6ffa0dd 8 8 # plot Qrange 9 9 (PlotQrangeEvent, EVT_PLOT_QRANGE) = wx.lib.newevent.NewEvent() 10 # set plot limits 11 (PlotLimitEvent, EVT_PLOT_LIM) = wx.lib.newevent.NewEvent() 10 12 # print the messages on statusbar 11 13 (StatusEvent, EVT_STATUS) = wx.lib.newevent.NewEvent() 12 #create a panel slicer 14 #create a panel slicer 13 15 (SlicerPanelEvent, EVT_SLICER_PANEL) = wx.lib.newevent.NewEvent() 14 #print update paramaters for panel slicer 16 #print update paramaters for panel slicer 15 17 (SlicerParamUpdateEvent, EVT_SLICER_PARS_UPDATE) = wx.lib.newevent.NewEvent() 16 #update the slicer from the panel 18 #update the slicer from the panel 17 19 (SlicerParameterEvent, EVT_SLICER_PARS) = wx.lib.newevent.NewEvent() 18 20 #slicer event -
src/sas/sasgui/guiframe/gui_statusbar.py
rd85c194 r3a22ce7 6 6 import sys 7 7 import logging 8 import datetime 8 9 from wx import StatusBar as wxStatusB 9 10 from wx.lib import newevent … … 46 47 47 48 self.msg_txt.SetEditable(False) 48 self.msg_txt.SetValue('No message available') 49 timestamp = datetime.datetime.now() 50 status = '{:%Y-%m-%d %H:%M:%S} : No message available'.format(timestamp) 51 self.msg_txt.SetValue(status) 49 52 self.sizer.Add(self.msg_txt, 1, wx.EXPAND|wx.ALL, 10) 50 53 self.SetSizer(self.sizer) … … 60 63 if status.strip() == "": 61 64 return 65 # Add timestamp 66 timestamp = datetime.datetime.now() 67 status = '{:%Y-%m-%d %H:%M:%S} : '.format(timestamp) + status 62 68 color = (0, 0, 0) #black 63 69 icon_bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_TOOLBAR) -
src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py
r895c9cb r245ae18 95 95 self.parent.SetFocus() 96 96 97 # If true, there are 3 qrange bars 98 self.is_corfunc = False 99 97 100 98 101 def get_symbol_label(self): … … 214 217 if active_ctrl == None: 215 218 return 219 if hasattr(event, 'is_corfunc'): 220 self.is_corfunc = event.is_corfunc 216 221 if event.id in self.plots.keys(): 217 222 ctrl = event.ctrl … … 222 227 values = [max(x_data.min(), float(ctrl[0].GetValue())), 223 228 min(x_data.max(), float(ctrl[1].GetValue()))] 229 if len(ctrl) == 3: 230 colors.append('purple') 231 values.append(min(x_data.max(), float(ctrl[2].GetValue()))) 224 232 if self.ly == None: 225 233 self.ly = [] … … 232 240 xval = float(active_ctrl.GetValue()) 233 241 position = self.get_data_xy_vals(xval) 234 if position != None :242 if position != None and not self.is_corfunc: 235 243 wx.PostEvent(self.parent, StatusEvent(status=position)) 236 244 except: … … 293 301 ly0x = ly[0].get_xdata() 294 302 ly1x = ly[1].get_xdata() 303 ly2x = None 304 if self.is_corfunc: ly2x = ly[2].get_xdata() 295 305 self.q_ctrl[0].SetBackgroundColour('white') 296 306 self.q_ctrl[1].SetBackgroundColour('white') … … 306 316 self.q_ctrl[0].SetValue(str(pos_x)) 307 317 self.q_ctrl[1].SetBackgroundColour('pink') 318 elif ly2x is not None and ly1x >= ly2x: 319 if self.vl_ind == 1: 320 ly[2].set_xdata(posx) 321 ly[2].set_zorder(nop) 322 self.q_ctrl[2].SetValue(str(pos_x)) 323 elif self.vl_ind == 2: 324 ly[1].set_xdata(posx) 325 ly[1].set_zorder(nop) 326 self.q_ctrl[1].SetValue(str(pos_x)) 327 308 328 309 329 def _get_cusor_lines(self, event): … … 325 345 dqmin = math.fabs(event.xdata - self.ly[0].get_xdata()) 326 346 dqmax = math.fabs(event.xdata - self.ly[1].get_xdata()) 327 is_qmax = dqmin > dqmax 328 if is_qmax: 329 self.vl_ind = 1 347 if not self.is_corfunc: 348 is_qmax = dqmin > dqmax 349 if is_qmax: 350 self.vl_ind = 1 351 else: 352 self.vl_ind = 0 330 353 else: 331 self.vl_ind = 0 354 dqmax2 = math.fabs(event.xdata - self.ly[2].get_xdata()) 355 closest = min(dqmin, dqmax, dqmax2) 356 self.vl_ind = { dqmin: 0, dqmax: 1, dqmax2: 2 }.get(closest) 332 357 333 358 def cusor_line(self, event): -
src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py
rd85c194 r6ffa0dd 16 16 from sas.sasgui.guiframe.events import EVT_NEW_PLOT 17 17 from sas.sasgui.guiframe.events import EVT_PLOT_QRANGE 18 from sas.sasgui.guiframe.events import EVT_PLOT_LIM 18 19 from sas.sasgui.guiframe.events import DeletePlotPanelEvent 19 20 from sas.sasgui.guiframe.plugin_base import PluginBase … … 79 80 self.parent.Bind(EVT_NEW_PLOT, self._on_plot_event) 80 81 self.parent.Bind(EVT_PLOT_QRANGE, self._on_plot_qrange) 82 self.parent.Bind(EVT_PLOT_LIM, self._on_plot_lim) 81 83 # We have no initial panels for this plug-in 82 84 return [] … … 95 97 return 96 98 panel.on_plot_qrange(event) 99 100 def _on_plot_lim(self, event=None): 101 if event == None: 102 return 103 if event.id in self.plot_panels.keys(): 104 panel = self.plot_panels[event.id] 105 elif event.group_id in self.plot_panels.keys(): 106 panel = self.plot_panels[event.group_id] 107 else: 108 return 109 if hasattr(event, 'xlim'): 110 panel.subplot.set_xlim(event.xlim) 111 if hasattr(event, 'ylim'): 112 panel.subplot.set_ylim(event.ylim) 113 97 114 98 115 def _on_show_panel(self, event): … … 312 329 new_panel = self.create_2d_panel(data, group_id) 313 330 self.create_panel_helper(new_panel, data, group_id, title) 331 if hasattr(event, 'xlim'): 332 new_panel.subplot.set_xlim(event.xlim) 333 if hasattr(event, 'ylim'): 334 new_panel.subplot.set_ylim(event.ylim) 314 335 return -
src/sas/sasgui/guiframe/media/data_formats_help.rst
rd85c194 r280f929 3 3 .. This is a port of the original SasView html help file to ReSTructured text 4 4 .. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 5 .. WG Bouwman, DUT, added during CodeCamp-V in Oct 2016 the SESANS data format 5 6 6 7 .. _Formats: … … 9 10 ============ 10 11 11 SasView reads several different 1D (I(Q) vs Q) and 2D (I(Qx,Qy) vs (Qx,Qy)) 12 SasView reads several different 1D (I(Q) vs Q), 2D SANS(I(Qx,Qy) vs (Qx,Qy)) 13 and SESANS (P(z) vs z) 12 14 data files. But please note that SasView does not at present load data where 13 15 the Q and I(Q) data are in separate files. 14 16 15 1D Formats 16 ---------- 17 1D Formats SANS 18 --------------- 17 19 18 20 SasView will read files with 2 to 4 columns of numbers in the following order: … … 46 48 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 47 49 48 2D Formats 49 ---------- 50 2D Formats SANS 51 --------------- 50 52 51 53 SasView will only read files in the NIST 2D format with the extensions … … 60 62 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 61 63 62 .. note:: This help document was last changed by Steve King, 01May2015 64 SESANS Format 65 ------------- 66 67 The current file extension is .ses or .sesans (not case sensitive). 68 69 The file format is to have a list of name-value pairs as a header at the top of the file, detailing general experimental parameters necessary for fitting and analyzing data. This list should contain all information necessary for the file to be 'portable' between users. 70 71 Following that is a 6 column list of instrument experimental variables: 72 73 - Spin echo length (z, in Angstroms) 74 - Spin echo length error (:math:`\Delta` z, in Angstroms) (experimental resolution) 75 - neutron wavelength (:math:`\lambda`, in Angstroms) (essential for ToF instruments) 76 - neutron wavelength error (:math:`\Delta \lambda`, in Angstroms) 77 - Normalized polarization (:math:`P/P_0`, unitless) 78 - Normalized polarization error (:math:`\Delta(P/P_0)`, unitless) (measurement error) 79 80 81 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 82 83 .. note:: This help document was last changed by Wim Bouwman, 05Oct2016 -
src/sas/sasgui/perspectives/calculator/pyconsole.py
r7673ecd rf1cbae7 9 9 import wx 10 10 from wx.lib.dialogs import ScrolledMessageDialog 11 from wx.lib import layoutf 12 11 13 import wx.py.editor as editor 12 14 … … 63 65 title, icon = "Info", wx.ICON_INFORMATION 64 66 text = "\n".join(parts) 65 dlg = ScrolledMessageDialog(parent, text, title, size=((550, 250)))67 dlg = ResizableScrolledMessageDialog(parent, text, title, size=((550, 250))) 66 68 fnt = wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL) 67 69 dlg.GetChildren()[0].SetFont(fnt) … … 70 72 dlg.Destroy() 71 73 return errmsg is None 74 75 class ResizableScrolledMessageDialog(wx.Dialog): 76 """ 77 Custom version of wx ScrolledMessageDialog, allowing border resize 78 """ 79 def __init__(self, parent, msg, caption, 80 pos=wx.DefaultPosition, size=(500,300), 81 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER ): 82 # Notice, that style can be overrriden in the caller. 83 wx.Dialog.__init__(self, parent, -1, caption, pos, size, style) 84 x, y = pos 85 if x == -1 and y == -1: 86 self.CenterOnScreen(wx.BOTH) 87 88 text = wx.TextCtrl(self, -1, msg, style=wx.TE_MULTILINE | wx.TE_READONLY) 89 ok = wx.Button(self, wx.ID_OK, "OK") 90 91 # Mysterious constraint layouts from 92 # https://www.wxpython.org/docs/api/wx.lib.layoutf.Layoutf-class.html 93 lc = layoutf.Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok)) 94 text.SetConstraints(lc) 95 lc = layoutf.Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,)) 96 ok.SetConstraints(lc) 97 98 self.SetAutoLayout(1) 99 self.Layout() 72 100 73 101 class PyConsole(editor.EditorNotebookFrame): -
src/sas/sasgui/perspectives/fitting/basepage.py
rc65a265 r4c3be25 143 143 self.theory_qmin_x = None 144 144 self.theory_qmax_x = None 145 self.cb1 = None146 145 self.btEditMask = None 147 146 self.btFit = None … … 1197 1196 # set data, etc. from the state 1198 1197 # reset page between theory and fitting from bookmarking 1199 #if state.data == None:1200 # data = None1201 #else:1202 1198 data = state.data 1203 1199 … … 1225 1221 self.disp_cb_dict = state.disp_cb_dict 1226 1222 self.disp_list = state.disp_list 1227 1228 ## set the state of the radio box1229 #self.shape_rbutton.SetValue(state.shape_rbutton)1230 #self.shape_indep_rbutton.SetValue(state.shape_indep_rbutton)1231 #self.struct_rbutton.SetValue(state.struct_rbutton)1232 #self.plugin_rbutton.SetValue(state.plugin_rbutton)1233 1223 1234 1224 ## fill model combobox … … 1286 1276 else: 1287 1277 self.model_view.SetLabel("1D Mode") 1288 1289 ## set the select all check box to the a given state1290 self.cb1.SetValue(state.cb1)1291 1278 1292 1279 ## reset state of checkbox,textcrtl and regular parameters value … … 1418 1405 except Exception: 1419 1406 logging.error(traceback.format_exc()) 1420 1421 # Make sure the check box updated when all checked1422 if self.cb1.GetValue():1423 self.select_all_param(None)1424 1407 1425 1408 def _selectDlg(self): … … 2557 2540 item[2].Enable() 2558 2541 2559 # Make sure the check box updated when all checked 2560 if self.cb1.GetValue(): 2561 #self.select_all_param(None) 2562 self.get_all_checked_params() 2542 # Make sure the check box updated 2543 self.get_all_checked_params() 2563 2544 2564 2545 # update params … … 3715 3696 call back for model selection if implemented 3716 3697 """ 3717 def select_all_param(self, event):3718 """3719 set to true or false all checkBox if implemented3720 """3721 3698 def get_weight_flag(self): 3722 3699 """ -
src/sas/sasgui/perspectives/fitting/fitpage.py
r6c382da r4c3be25 624 624 ## fill a sizer with the combobox to select dispersion type 625 625 model_disp = wx.StaticText(self, wx.ID_ANY, 'Function') 626 CHECK_STATE = self.cb1.GetValue()626 CHECK_STATE = False 627 627 628 628 ix = 0 … … 969 969 self.state.model = self.model.clone() 970 970 ## save state into 971 self.state.cb1 = self.cb1.GetValue()972 971 self._copy_parameters_state(self.parameters, self.state.parameters) 973 972 self._copy_parameters_state(self.orientation_params_disp, … … 980 979 StatusEvent(status=" Selected Distribution: Gaussian")) 981 980 #Fill the list of fittable parameters 982 #self.select_all_param(event=None)983 981 self.get_all_checked_params() 984 982 self.Layout() … … 2695 2693 self._manager.set_param2fit(self.uid, param2fit) 2696 2694 2697 def select_all_param(self, event):2698 """2699 set to true or false all checkBox given the main checkbox value cb12700 """2701 self.param_toFit = []2702 if self.parameters != []:2703 if self.cb1.GetValue():2704 for item in self.parameters:2705 if item[0].IsShown():2706 ## for data2D select all to fit2707 if self.data.__class__.__name__ == "Data2D" or \2708 self.enable2D:2709 item[0].SetValue(True)2710 self.param_toFit.append(item)2711 else:2712 ## for 1D all parameters except orientation2713 if not item in self.orientation_params:2714 item[0].SetValue(True)2715 self.param_toFit.append(item)2716 else:2717 item[0].SetValue(False)2718 #if len(self.fittable_param)>0:2719 for item in self.fittable_param:2720 if item[0].IsShown():2721 if self.data.__class__.__name__ == "Data2D" or \2722 self.enable2D:2723 item[0].SetValue(True)2724 self.param_toFit.append(item)2725 try:2726 if len(self.values[item[1]]) > 0:2727 item[0].SetValue(False)2728 except:2729 pass2730 2731 else:2732 ## for 1D all parameters except orientation2733 if not item in self.orientation_params_disp:2734 item[0].SetValue(True)2735 self.param_toFit.append(item)2736 try:2737 if len(self.values[item[1]]) > 0:2738 item[0].SetValue(False)2739 except:2740 pass2741 else:2742 item[0].SetValue(False)2743 2744 else:2745 for item in self.parameters:2746 item[0].SetValue(False)2747 for item in self.fittable_param:2748 item[0].SetValue(False)2749 self.param_toFit = []2750 2751 self.save_current_state_fit()2752 2753 if event != None:2754 #self._undo.Enable(True)2755 ## post state to fit panel2756 event = PageInfoEvent(page=self)2757 wx.PostEvent(self.parent, event)2758 param2fit = []2759 for item in self.param_toFit:2760 if item[0] and item[0].IsShown():2761 param2fit.append(item[1])2762 self.parent._manager.set_param2fit(self.uid, param2fit)2763 2764 2695 def select_param(self, event): 2765 2696 """ … … 2808 2739 if len(self.fittable_param) > 0: 2809 2740 len_orient_para *= 2 2810 #Set the value of checkbox that selected every checkbox or not2811 if len(self.parameters) + len(self.fittable_param) - len_orient_para \2812 == len(self.param_toFit):2813 self.cb1.SetValue(True)2814 else:2815 self.cb1.SetValue(False)2816 2741 2817 2742 self.save_current_state_fit() … … 2915 2840 iy = 0 2916 2841 ix = 0 2917 select_text = "Select All" 2918 self.cb1 = wx.CheckBox(self, wx.ID_ANY, str(select_text), (10, 10)) 2919 wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param) 2920 self.cb1.SetToolTipString("To check/uncheck all the boxes below.") 2921 self.cb1.SetValue(True) 2922 2923 sizer.Add(self.cb1, (iy, ix), (1, 1), \ 2924 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 5) 2842 sizer.Add(wx.StaticText(self, wx.ID_ANY, 'Parameter'), 2843 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 2925 2844 ix += 1 2926 2845 self.text2_2 = wx.StaticText(self, wx.ID_ANY, 'Value') … … 2949 2868 self.text2_4.Hide() 2950 2869 2951 CHECK_STATE = self.cb1.GetValue()2870 CHECK_STATE = False 2952 2871 for item in keys: 2953 2872 -
src/sas/sasgui/perspectives/fitting/media/plugin.rst
rcbbb6a4 rb2a3814 3 3 Writing a Plugin Model 4 4 ====================== 5 6 .. note:: If some code blocks are not readable, expand the documentation window 5 7 6 8 Overview -
src/sas/sasgui/perspectives/fitting/fitpanel.py
r05228b0 ra95ae9a 13 13 from sas.sasgui.guiframe.events import StatusEvent 14 14 from sas.sasgui.guiframe.dataFitting import check_data_validity 15 from sas.sasgui.perspectives.fitting.simfitpage import SimultaneousFitPage 15 16 16 17 import basepage … … 18 19 _BOX_WIDTH = 80 19 20 21 20 22 class FitPanel(nb, PanelBase): 21 23 """ … … 26 28 27 29 """ 28 # #Internal name for the AUI manager30 # Internal name for the AUI manager 29 31 window_name = "Fit panel" 30 # #Title to appear on top of the window32 # Title to appear on top of the window 31 33 window_caption = "Fit Panel " 32 34 CENTER_PANE = True … … 40 42 wx.CLIP_CHILDREN) 41 43 PanelBase.__init__(self, parent) 42 # self.SetWindowStyleFlag(style=nb.FNB_FANCY_TABS)44 # self.SetWindowStyleFlag(style=nb.FNB_FANCY_TABS) 43 45 self._manager = manager 44 46 self.parent = parent 45 47 self.event_owner = None 46 # dictionary of miodel {model class name, model class}48 # dictionary of miodel {model class name, model class} 47 49 self.menu_mng = models.ModelManager() 48 50 self.model_list_box = self.menu_mng.get_model_list() 49 # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING51 # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING 50 52 self.model_dictionary = self.menu_mng.get_model_dictionary() 51 53 self.pageClosedEvent = wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE 52 54 53 55 self.Bind(self.pageClosedEvent, self.on_close_page) 54 # #save the title of the last page tab added56 # save the title of the last page tab added 55 57 self.fit_page_name = {} 56 # #list of existing fit page58 # list of existing fit page 57 59 self.opened_pages = {} 58 # index of fit page60 # index of fit page 59 61 self.fit_page_index = 0 60 # index of batch page62 # index of batch page 61 63 self.batch_page_index = 0 62 # page of simultaneous fit64 # page of simultaneous fit 63 65 self.sim_page = None 64 66 self.batch_page = None 65 # #get the state of a page67 # get the state of a page 66 68 self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate) 67 69 self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo) … … 80 82 """ 81 83 return an xml node containing state of the panel 82 that guiframe can write to file 83 """ 84 msg = "" 84 that guiframe can write to file 85 """ 86 # Iterate through all pages and check for batch fitting 87 batch_state = None 88 if self.sim_page is not None: 89 batch_state = self.sim_page.set_state() 90 85 91 for uid, page in self.opened_pages.iteritems(): 86 if page.batch_on: 87 pos = self.GetPageIndex(page) 88 if pos != -1 and page not in [self.sim_page, self.batch_page]: 89 msg += "%s .\n" % str(self.GetPageText(pos)) 90 else: 91 data = page.get_data() 92 # state must be cloned 93 state = page.get_state().clone() 94 if data is not None and page.model is not None: 95 new_doc = self._manager.state_reader.write_toXML(data, 96 state) 97 if doc != None and hasattr(doc, "firstChild"): 98 child = new_doc.firstChild.firstChild 99 doc.firstChild.appendChild(child) 100 else: 101 doc = new_doc 102 if msg.strip() != "": 103 temp = "Save Project is not supported for Batch page.\n" 104 temp += "The following pages will not be save:\n" 105 message = temp + msg 106 wx.PostEvent(self._manager.parent, StatusEvent(status=message, 107 info="warning")) 92 data = page.get_data() 93 # state must be cloned 94 state = page.get_state().clone() 95 if data is not None or page.model is not None: 96 new_doc = self._manager.state_reader.write_toXML(data, 97 state, 98 batch_state) 99 if doc is not None and hasattr(doc, "firstChild"): 100 child = new_doc.firstChild.firstChild 101 doc.firstChild.appendChild(child) 102 else: 103 doc = new_doc 104 108 105 return doc 109 106 … … 363 360 panel.set_index_model(self.batch_page_index) 364 361 else: 365 # Increment index of fit page362 # Increment index of fit page 366 363 panel = FitPage(parent=self) 367 364 self.fit_page_index += 1 … … 526 523 self.SetSelection(pos) 527 524 return page 528 # create new page and add data525 # create new page and add data 529 526 page = self.add_empty_page() 530 527 pos = self.GetPageIndex(page) -
src/sas/sasgui/perspectives/fitting/fitting.py
rca4d985 re89aed5 593 593 : param datainfo: data 594 594 """ 595 #state = self.state_reader.get_state() 596 if state != None: 595 from pagestate import PageState 596 from simfitpage import SimFitPageState 597 if isinstance(state, PageState): 597 598 state = state.clone() 598 # store fitting state in temp_state599 599 self.temp_state.append(state) 600 elif isinstance(state, SimFitPageState): 601 state.load_from_save_state(self) 600 602 else: 601 603 self.temp_state = [] -
src/sas/sasgui/perspectives/fitting/pagestate.py
r6c382da re89aed5 2 2 Class that holds a fit page state 3 3 """ 4 # TODO: Refactor code so we don't need to use getattr/setattr4 # TODO: Refactor code so we don't need to use getattr/setattr 5 5 ################################################################################ 6 # This software was developed by the University of Tennessee as part of the7 # Distributed Data Analysis of Neutron Scattering Experiments (DANSE)8 # project funded by the US National Science Foundation.6 # This software was developed by the University of Tennessee as part of the 7 # Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 8 # project funded by the US National Science Foundation. 9 9 # 10 # See the license text in license.txt10 # See the license text in license.txt 11 11 # 12 # copyright 2009, University of Tennessee12 # copyright 2009, University of Tennessee 13 13 ################################################################################ 14 14 import time … … 30 30 from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader 31 31 from sas.sascalc.dataloader.readers.cansas_reader import get_content, write_node 32 from sas.sascalc.dataloader.data_info import Data2D 33 from sas.sascalc.dataloader.data_info import Collimation 34 from sas.sascalc.dataloader.data_info import Detector 35 from sas.sascalc.dataloader.data_info import Process 36 from sas.sascalc.dataloader.data_info import Aperture 37 #Information to read/write state as xml 32 from sas.sascalc.dataloader.data_info import Data2D, Collimation, Detector 33 from sas.sascalc.dataloader.data_info import Process, Aperture 34 # Information to read/write state as xml 38 35 FITTING_NODE_NAME = 'fitting_plug_in' 39 36 CANSAS_NS = "cansas1d/1.0" … … 123 120 try: 124 121 return node.get(item[0]).strip() == "True" 125 126 122 except: 127 123 return None … … 146 142 """ 147 143 self.file = None 148 # Time of state creation144 # Time of state creation 149 145 self.timestamp = time.time() 150 # #Data member to store the dispersion object created146 # Data member to store the dispersion object created 151 147 self._disp_obj_dict = {} 152 # ------------------------153 # Data used for fitting148 # ------------------------ 149 # Data used for fitting 154 150 self.data = data 155 151 # model data 156 152 self.theory_data = None 157 # Is 2D153 # Is 2D 158 154 self.is_2D = False 159 155 self.images = None 160 156 161 #save additional information on data that dataloader.reader does not read 157 # save additional information on data that dataloader.reader 158 # does not read 162 159 self.is_data = None 163 160 self.data_name = "" … … 172 169 self.data_group_id = self.data.group_id 173 170 174 # # reset True change the state of exsiting button171 # reset True change the state of existing button 175 172 self.reset = False 176 173 … … 180 177 self.model = model 181 178 self.m_name = None 182 # list of process done to model179 # list of process done to model 183 180 self.process = [] 184 # fit page manager181 # fit page manager 185 182 self.manager = None 186 # Store the parent of this panel parent183 # Store the parent of this panel parent 187 184 # For this application fitpanel is the parent 188 185 self.parent = parent 189 186 # Event_owner is the owner of model event 190 187 self.event_owner = None 191 # #page name188 # page name 192 189 self.page_name = "" 193 190 # Contains link between model, all its parameters, and panel organization … … 196 193 self.str_parameters = [] 197 194 # Contains list of parameters that cannot be fitted and reference to 198 # panel objects195 # panel objects 199 196 self.fixed_param = [] 200 197 # Contains list of parameters with dispersity and reference to 201 # panel objects198 # panel objects 202 199 self.fittable_param = [] 203 # #orientation parameters200 # orientation parameters 204 201 self.orientation_params = [] 205 # #orientation parameters for gaussian dispersity202 # orientation parameters for gaussian dispersity 206 203 self.orientation_params_disp = [] 207 # #smearer info204 # smearer info 208 205 self.smearer = None 209 206 self.smear_type = None … … 214 211 self.dxl = None 215 212 self.dxw = None 216 # list of dispersion parameters213 # list of dispersion parameters 217 214 self.disp_list = [] 218 215 if self.model is not None: … … 223 220 self.weights = {} 224 221 225 # contains link between a model and selected parameters to fit222 # contains link between a model and selected parameters to fit 226 223 self.param_toFit = [] 227 # #dictionary of model type and model class224 # dictionary of model type and model class 228 225 self.model_list_box = None 229 # #save the state of the context menu226 # save the state of the context menu 230 227 self.saved_states = {} 231 # #save selection of combobox228 # save selection of combobox 232 229 self.formfactorcombobox = None 233 230 self.categorycombobox = None 234 231 self.structurecombobox = None 235 232 236 # #radio box to select type of model237 # self.shape_rbutton = False238 # self.shape_indep_rbutton = False239 # self.struct_rbutton = False240 # self.plugin_rbutton = False241 # #the indice of the current selection233 # radio box to select type of model 234 # self.shape_rbutton = False 235 # self.shape_indep_rbutton = False 236 # self.struct_rbutton = False 237 # self.plugin_rbutton = False 238 # the indice of the current selection 242 239 self.disp_box = 0 243 # #Qrange244 # #Q range240 # Qrange 241 # Q range 245 242 self.qmin = 0.001 246 243 self.qmax = 0.1 247 # reset data range244 # reset data range 248 245 self.qmax_x = None 249 246 self.qmin_x = None … … 253 250 self.multi_factor = None 254 251 self.magnetic_on = False 255 # #enable smearering state252 # enable smearering state 256 253 self.enable_smearer = False 257 254 self.disable_smearer = True … … 263 260 self.dI_sqrdata = False 264 261 self.dI_idata = False 265 # #disperity selection262 # disperity selection 266 263 self.enable_disp = False 267 264 self.disable_disp = True 268 265 269 # #state of selected all check button266 # state of selected all check button 270 267 self.cb1 = False 271 # #store value of chisqr268 # store value of chisqr 272 269 self.tcChi = None 273 270 … … 293 290 obj.structurecombobox = self.structurecombobox 294 291 295 # obj.shape_rbutton = self.shape_rbutton296 # obj.shape_indep_rbutton = self.shape_indep_rbutton297 # obj.struct_rbutton = self.struct_rbutton298 # obj.plugin_rbutton = self.plugin_rbutton292 # obj.shape_rbutton = self.shape_rbutton 293 # obj.shape_indep_rbutton = self.shape_indep_rbutton 294 # obj.struct_rbutton = self.struct_rbutton 295 # obj.plugin_rbutton = self.plugin_rbutton 299 296 300 297 obj.manager = self.manager … … 386 383 rep += "data's name : %s\n" % self.data_name 387 384 rep += "data's id : %s\n" % self.data_id 388 if self.model !=None:385 if self.model is not None: 389 386 m_name = self.model.__class__.__name__ 390 387 if m_name == 'Model': … … 397 394 rep += "model type (Category) selected: %s\n" % self.categorycombobox 398 395 rep += "data : %s\n" % str(self.data) 399 rep += "Plotting Range: min: %s, max: %s, steps: %s\n" % (str(self.qmin),400 396 rep += "Plotting Range: min: %s, max: %s, steps: %s\n" % \ 397 (str(self.qmin),str(self.qmax), str(self.npts)) 401 398 rep += "Dispersion selection : %s\n" % str(self.disp_box) 402 399 rep += "Smearing enable : %s\n" % str(self.enable_smearer) … … 414 411 415 412 rep += "2D enable : %s\n" % str(self.enable2D) 416 rep += "All parameters checkbox selected: %s\n" % (self.cb1)413 rep += "All parameters checkbox selected: %s\n" % str(self.cb1) 417 414 rep += "Value of Chisqr : %s\n" % str(self.tcChi) 418 415 rep += "Smear object : %s\n" % str(self.smearer) 419 rep += "Smear type : %s\n" % (self.smear_type)416 rep += "Smear type : %s\n" % str(self.smear_type) 420 417 rep += "dq_l : %s\n" % self.dq_l 421 418 rep += "dq_r : %s\n" % self.dq_r … … 434 431 if not self.is_2D: 435 432 for item in self.parameters: 436 if not itemin self.orientation_params:433 if item not in self.orientation_params: 437 434 temp_parameters.append(item) 438 435 for item in self.fittable_param: 439 if not itemin self.orientation_params_disp:436 if item not in self.orientation_params_disp: 440 437 temp_fittable_param.append(item) 441 438 else: … … 443 440 temp_fittable_param = self.fittable_param 444 441 445 rep += "number parameters(self.parameters): %s\n" % len(temp_parameters) 442 rep += "number parameters(self.parameters): %s\n" % \ 443 len(temp_parameters) 446 444 rep = self._repr_helper(list=temp_parameters, rep=rep) 447 rep += "number str_parameters(self.str_parameters): %s\n" % len(self.str_parameters) 445 rep += "number str_parameters(self.str_parameters): %s\n" % \ 446 len(self.str_parameters) 448 447 rep = self._repr_helper(list=self.str_parameters, rep=rep) 449 rep += "number fittable_param(self.fittable_param): %s\n" % len(temp_fittable_param) 448 rep += "number fittable_param(self.fittable_param): %s\n" % \ 449 len(temp_fittable_param) 450 450 rep = self._repr_helper(list=temp_fittable_param, rep=rep) 451 451 return rep … … 551 551 paramval_string += CENTRE % param + "\n" 552 552 553 text_string = "\n\n\n%s\n\n%s\n%s\n%s\n\n%s" % (title, file, q_name, chi2, paramval) 553 text_string = "\n\n\n%s\n\n%s\n%s\n%s\n\n%s" % \ 554 (title, file, q_name, chi2, paramval) 554 555 555 556 title_name = self._check_html_format(title_name) … … 632 633 element.appendChild(sub_element) 633 634 634 def toXML(self, file="fitting_state.fitv", doc=None, entry_node=None): 635 """ 636 Writes the state of the InversionControl panel to file, as XML. 635 def toXML(self, file="fitting_state.fitv", doc=None, 636 entry_node=None, batch_fit_state=None): 637 """ 638 Writes the state of the fit panel to file, as XML. 637 639 638 640 Compatible with standalone writing, or appending to an … … 691 693 element.setAttributeNode(attr) 692 694 top_element.appendChild(element) 695 693 696 # Inputs 694 697 inputs = newdoc.createElement("Attributes") … … 743 746 self._toXML_helper(thelist=getattr(self, item[1]), element=element, newdoc=newdoc) 744 747 inputs.appendChild(element) 748 749 # Combined and Simultaneous Fit Parameters 750 if batch_fit_state is not None: 751 batch_combo = newdoc.createElement('simultaneous_fit') 752 top_element.appendChild(batch_combo) 753 754 # Simultaneous Fit Number For Linking Later 755 element = newdoc.createElement('sim_fit_number') 756 element.setAttribute('fit_number', str(batch_fit_state.fit_page_no)) 757 batch_combo.appendChild(element) 758 759 # Save constraints 760 constraints = newdoc.createElement('constraints') 761 batch_combo.appendChild(constraints) 762 for constraint in batch_fit_state.constraints_list: 763 # model_cbox, param_cbox, egal_txt, constraint, btRemove, sizer 764 doc_cons = newdoc.createElement('constraint') 765 doc_cons.setAttribute('model_cbox', 766 str(constraint.model_cbox.GetValue())) 767 doc_cons.setAttribute('param_cbox', 768 str(constraint.param_cbox.GetValue())) 769 doc_cons.setAttribute('egal_txt', 770 str(constraint.egal_txt.GetLabel())) 771 doc_cons.setAttribute('constraint', 772 str(constraint.constraint.GetValue())) 773 constraints.appendChild(doc_cons) 774 775 # Save all models 776 models = newdoc.createElement('model_list') 777 batch_combo.appendChild(models) 778 for model in batch_fit_state.model_list: 779 doc_model = newdoc.createElement('model_list_item') 780 doc_model.setAttribute('checked', str(model[0].GetValue())) 781 keys = model[1].keys() 782 doc_model.setAttribute('name', str(keys[0])) 783 values = model[1].get(keys[0]) 784 doc_model.setAttribute('fit_number', str(model[2])) 785 doc_model.setAttribute('fit_page_source', str(model[3])) 786 doc_model.setAttribute('model_name', str(values.model.id)) 787 models.appendChild(doc_model) 788 789 # Select All Checkbox 790 element = newdoc.createElement('select_all') 791 if batch_fit_state.select_all: 792 element.setAttribute('checked', 'True') 793 else: 794 element.setAttribute('checked', 'False') 795 batch_combo.appendChild(element) 745 796 746 797 # Save the file … … 809 860 :param file: .fitv file 810 861 :param node: node of a XML document to read from 811 812 862 """ 813 863 if file is not None: … … 816 866 raise RuntimeError, msg 817 867 818 if node.get('version') and node.get('version') == '1.0':868 if node.get('version') and node.get('version') == '1.0': 819 869 820 870 # Get file name … … 960 1010 self.cansas = cansas 961 1011 self.state = None 1012 # batch fitting params for saving 1013 self.batchfit_params = [] 962 1014 963 1015 def get_state(self): … … 1219 1271 1220 1272 :param entry: XML node to read from 1221 1222 1273 :return: PageState object 1223 1274 """ … … 1228 1279 nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 1229 1280 namespaces={'ns': CANSAS_NS}) 1230 if nodes != []:1281 if nodes: 1231 1282 # Create an empty state 1232 1283 state = PageState() … … 1238 1289 1239 1290 return state 1291 1292 def _parse_simfit_state(self, entry): 1293 """ 1294 Parses the saved data for a simultaneous fit 1295 :param entry: XML object to read from 1296 :return: XML object for a simultaneous fit or None 1297 """ 1298 nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 1299 namespaces={'ns': CANSAS_NS}) 1300 if nodes: 1301 simfitstate = nodes[0].xpath('ns:simultaneous_fit', 1302 namespaces={'ns': CANSAS_NS}) 1303 if simfitstate: 1304 from simfitpage import SimFitPageState 1305 sim_fit_state = SimFitPageState() 1306 simfitstate_0 = simfitstate[0] 1307 all = simfitstate_0.xpath('ns:select_all', 1308 namespaces={'ns': CANSAS_NS}) 1309 atts = all[0].attrib 1310 checked = atts.get('checked') 1311 sim_fit_state.select_all = bool(checked) 1312 model_list = simfitstate_0.xpath('ns:model_list', 1313 namespaces={'ns': CANSAS_NS}) 1314 model_list_items = model_list[0].xpath('ns:model_list_item', 1315 namespaces={'ns': CANSAS_NS}) 1316 for model in model_list_items: 1317 attrs = model.attrib 1318 sim_fit_state.model_list.append(attrs) 1319 constraints = simfitstate_0.xpath('ns:constraints', 1320 namespaces={'ns': CANSAS_NS}) 1321 constraint_list = constraints[0].xpath('ns:constraint', 1322 namespaces={'ns': CANSAS_NS}) 1323 for constraint in constraint_list: 1324 attrs = constraint.attrib 1325 sim_fit_state.constraints_list.append(attrs) 1326 1327 return sim_fit_state 1328 else: 1329 return None 1240 1330 1241 1331 def _parse_save_state_entry(self, dom): … … 1476 1566 nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 1477 1567 if len(nodes) > 1: 1478 raise RuntimeError, "CanSAS reader is not compatible with multiple SASdata entries" 1568 raise RuntimeError, "CanSAS reader is not compatible with" + \ 1569 " multiple SASdata entries" 1479 1570 1480 1571 for entry in nodes: … … 1498 1589 def _read_cansas(self, path): 1499 1590 """ 1500 Load data and P(r)information from a CanSAS XML file.1591 Load data and fitting information from a CanSAS XML file. 1501 1592 1502 1593 :param path: file path 1503 1504 1594 :return: Data1D object if a single SASentry was found, 1505 1595 or a list of Data1D objects if multiple entries were found, 1506 1596 or None of nothing was found 1507 1508 1597 :raise RuntimeError: when the file can't be opened 1509 1598 :raise ValueError: when the length of the data vectors are inconsistent 1510 1511 1599 """ 1512 1600 output = [] 1601 simfitstate = None 1513 1602 basename = os.path.basename(path) 1514 1603 root, extension = os.path.splitext(basename) … … 1516 1605 try: 1517 1606 if os.path.isfile(path): 1518 1519 #TODO: eventually remove the check for .xml once 1520 # the P(r) writer/reader is truly complete. 1521 if ext in self.ext or \ 1522 ext == '.xml': 1523 1607 if ext in self.ext or ext == '.xml': 1524 1608 tree = etree.parse(path, parser=etree.ETCompatXMLParser()) 1525 1609 # Check the format version number 1526 # Specifying the namespace will take care of the file format version 1610 # Specifying the namespace will take care of the file 1611 # format version 1527 1612 root = tree.getroot() 1528 1613 entry_list = root.xpath('ns:SASentry', … … 1534 1619 raise 1535 1620 fitstate = self._parse_state(entry) 1536 1537 #state could be None when .svs file is loaded 1538 #in this case, skip appending to output 1539 if fitstate != None: 1621 simfitstate = self._parse_simfit_state(entry) 1622 1623 # state could be None when .svs file is loaded 1624 # in this case, skip appending to output 1625 if fitstate is not None: 1540 1626 sas_entry.meta_data['fitstate'] = fitstate 1541 1627 sas_entry.filename = fitstate.file 1542 1628 output.append(sas_entry) 1629 1543 1630 else: 1544 1631 self.call_back(format=ext) … … 1580 1667 name = original_fname 1581 1668 state.data.group_id = name 1582 # store state in fitting1669 # store state in fitting 1583 1670 self.call_back(state=state, 1584 1671 datainfo=output[ind], format=ext) 1585 1672 self.state = state 1673 if simfitstate is not None: 1674 self.call_back(state=simfitstate) 1675 1586 1676 return output 1587 1677 except: … … 1599 1689 """ 1600 1690 # Sanity check 1601 if self.cansas == True:1691 if self.cansas: 1602 1692 # Add fitting information to the XML document 1603 1693 doc = self.write_toXML(datainfo, fitstate) … … 1611 1701 fd.close() 1612 1702 1613 def write_toXML(self, datainfo=None, state=None ):1703 def write_toXML(self, datainfo=None, state=None, batchfit=None): 1614 1704 """ 1615 1705 Write toXML, a helper for write(), … … 1619 1709 """ 1620 1710 1621 if state.data is None:1622 data = sas.sascalc.dataloader.data_info.Data1D(x=[], y=[])1711 self.batchfit_params = batchfit 1712 if state.data is None or not state.data.is_data: 1623 1713 return None 1624 elif not state.data.is_data: 1625 return None 1714 # make sure title and data run are filled. 1715 if state.data.title is None or state.data.title == '': 1716 state.data.title = state.data.name 1717 if state.data.run_name is None or state.data.run_name == {}: 1718 state.data.run = [str(state.data.name)] 1719 state.data.run_name[0] = state.data.name 1720 1721 if issubclass(state.data.__class__, 1722 sas.sascalc.dataloader.data_info.Data1D): 1723 data = state.data 1724 doc, sasentry = self._to_xml_doc(data) 1626 1725 else: 1627 #make sure title and data run is filled up. 1628 if state.data.title == None or state.data.title == '': 1629 state.data.title = state.data.name 1630 if state.data.run_name == None or state.data.run_name == {}: 1631 state.data.run = [str(state.data.name)] 1632 state.data.run_name[0] = state.data.name 1633 1634 if issubclass(state.data.__class__, 1635 sas.sascalc.dataloader.data_info.Data1D): 1636 data = state.data 1637 doc, sasentry = self._to_xml_doc(data) 1638 else: 1639 data = state.data 1640 doc, sasentry = self._data2d_to_xml_doc(data) 1726 data = state.data 1727 doc, sasentry = self._data2d_to_xml_doc(data) 1641 1728 1642 1729 if state is not None: 1643 doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry) 1730 doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry, 1731 batch_fit_state=self.batchfit_params) 1644 1732 1645 1733 return doc 1646 1647 # Simple html report templet1648 HEADER = "<html>\n"1649 HEADER += "<head>\n"1650 HEADER += "<meta http-equiv=Content-Type content='text/html; "1651 HEADER += "charset=windows-1252'> \n"1652 HEADER += "<meta name=Generator >\n"1653 HEADER += "</head>\n"1654 HEADER += "<body lang=EN-US>\n"1655 HEADER += "<div class=WordSection1>\n"1656 HEADER += "<p class=MsoNormal><b><span ><center><font size='4' >"1657 HEADER += "%s</font></center></span></center></b></p>"1658 HEADER += "<p class=MsoNormal> </p>"1659 PARA = "<p class=MsoNormal><font size='4' > %s \n"1660 PARA += "</font></p>"1661 CENTRE = "<p class=MsoNormal><center><font size='4' > %s \n"1662 CENTRE += "</font></center></p>"1663 FEET_1 = \1664 """1665 <p class=MsoNormal> </p>1666 <br>1667 <p class=MsoNormal><b><span ><center> <font size='4' > Graph1668 </font></span></center></b></p>1669 <p class=MsoNormal> </p>1670 <center>1671 <br><font size='4' >Model Computation</font>1672 <br><font size='4' >Data: "%s"</font><br>1673 """1674 FEET_2 = \1675 """1676 <img src="%s" >1677 </img>1678 """1679 FEET_3 = \1680 """1681 </center>1682 </div>1683 </body>1684 </html>1685 """1686 ELINE = "<p class=MsoNormal> </p>"1687 1688 if __name__ == "__main__":1689 state = PageState(parent=None)1690 #state.toXML()1691 """1692 1693 file = open("test_state", "w")1694 pickle.dump(state, file)1695 print pickle.dumps(state)1696 state.data_name = "hello---->"1697 pickle.dump(state, file)1698 file = open("test_state", "r")1699 new_state= pickle.load(file)1700 print "new state", new_state1701 new_state= pickle.load(file)1702 print "new state", new_state1703 #print "state", state1704 """1705 import bsddb1706 import pickle1707 db = bsddb.btopen('file_state.db', 'c')1708 val = (pickle.dumps(state), "hello", "hi")1709 db['state1'] = pickle.dumps(val)1710 print pickle.loads(db['state1'])1711 state.data_name = "hello---->22"1712 db['state2'] = pickle.dumps(state)1713 state.data_name = "hello---->2"1714 db['state3'] = pickle.dumps(state)1715 del db['state3']1716 state.data_name = "hello---->3"1717 db['state4'] = pickle.dumps(state)1718 new_state = pickle.loads(db['state1'])1719 #print db.last()1720 db.set_location('state2')1721 state.data_name = "hello---->5"1722 db['aastate5'] = pickle.dumps(state)1723 db.keys().sort()1724 print pickle.loads(db['state2'])1725 1726 db.close() -
src/sas/sasgui/perspectives/fitting/simfitpage.py
r4cafdff re89aed5 9 9 from wx.lib.scrolledpanel import ScrolledPanel 10 10 11 from sas.sasgui.guiframe.events import StatusEvent 11 from sas.sasgui.guiframe.events import StatusEvent, PanelOnFocusEvent 12 12 from sas.sasgui.guiframe.panel_base import PanelBase 13 from sas.sasgui.guiframe.events import PanelOnFocusEvent14 13 from sas.sasgui.guiframe.utils import IdList 15 14 from sas.sasgui.guiframe.documentation_window import DocumentationWindow 16 15 17 # Control panel width16 # Control panel width 18 17 if sys.platform.count("darwin") == 0: 19 18 PANEL_WID = 420 … … 29 28 'model_cbox param_cbox egal_txt constraint btRemove sizer') 30 29 30 31 31 def get_fittableParam(model): 32 32 """ … … 47 47 return fittable_param 48 48 49 49 50 class SimultaneousFitPage(ScrolledPanel, PanelBase): 50 51 """ … … 53 54 two data members window_name and window_caption 54 55 """ 55 # #Internal name for the AUI manager56 window_name = " simultaneous Fit page"57 # #Title to appear on top of the window56 # Internal name for the AUI manager 57 window_name = "Simultaneous Fit Page" 58 # Title to appear on top of the window 58 59 window_caption = "Simultaneous Fit Page" 59 60 ID_DOC = wx.NewId() … … 74 75 self._ids = iter(self._id_pool) 75 76 self.SetupScrolling() 76 # #Font size77 # Font size 77 78 self.SetWindowVariant(variant=FONT_VARIANT) 78 79 self.uid = wx.NewId() 79 80 self.parent = parent 80 81 self.batch_on = batch_on 81 # #store page_finder82 # store page_finder 82 83 self.page_finder = page_finder 83 # #list containing info to set constraint84 # #look like self.constraint_dict[page_id]= page84 # list containing info to set constraint 85 # look like self.constraint_dict[page_id]= page 85 86 self.constraint_dict = {} 86 # #item list87 # #self.constraints_list=[combobox1, combobox2,=,textcrtl, button ]87 # item list 88 # self.constraints_list=[combobox1, combobox2,=,textcrtl, button ] 88 89 self.constraints_list = [] 89 # #list of current model90 # list of current model 90 91 self.model_list = [] 91 # # selected mdoel to fit92 self.model_to Fit = []93 # #Control the fit state92 # selected model to fit 93 self.model_to_fit = [] 94 # Control the fit state 94 95 self.fit_started = False 95 # #number of constraint96 # number of constraint 96 97 self.nb_constraint = 0 98 self.state = SimFitPageState() 97 99 self.model_cbox_left = None 98 100 self.model_cbox_right = None 99 # #draw page101 # draw page 100 102 self.define_page_structure() 101 103 self.draw_page() … … 107 109 """ 108 110 self.vbox = wx.BoxSizer(wx.VERTICAL) 109 self. sizer1= wx.BoxSizer(wx.VERTICAL)110 self. sizer2= wx.BoxSizer(wx.VERTICAL)111 self. sizer3= wx.BoxSizer(wx.VERTICAL)112 113 self. sizer1.SetMinSize((PANEL_WID, -1))114 self. sizer2.SetMinSize((PANEL_WID, -1))115 self. sizer3.SetMinSize((PANEL_WID, -1))116 self.vbox.Add(self. sizer1)117 self.vbox.Add(self. sizer2)118 self.vbox.Add(self. sizer3)111 self.data_selection_sizer = wx.BoxSizer(wx.VERTICAL) 112 self.constraints_sizer = wx.BoxSizer(wx.VERTICAL) 113 self.run_fit_sizer = wx.BoxSizer(wx.VERTICAL) 114 115 self.data_selection_sizer.SetMinSize((PANEL_WID, -1)) 116 self.constraints_sizer.SetMinSize((PANEL_WID, -1)) 117 self.run_fit_sizer.SetMinSize((PANEL_WID, -1)) 118 self.vbox.Add(self.data_selection_sizer) 119 self.vbox.Add(self.constraints_sizer) 120 self.vbox.Add(self.run_fit_sizer) 119 121 self.SetSizer(self.vbox) 120 122 self.Centre() 123 124 def set_state(self): 125 """ 126 Define a set of state parameters for saving simultaneous fits. 127 """ 128 self._set_constraint() 129 self.state.fit_page_no = self.uid 130 self.state.select_all = self.cb1.GetValue() 131 self.state.model_list = self.model_list 132 self.state.model_to_fit = self.model_to_fit 133 self.state.no_constraint = self.nb_constraint 134 self.state.constraint_dict = self.constraint_dict 135 self.state.constraints_list = self.constraints_list 136 return self.get_state() 137 138 def get_state(self): 139 """ 140 Return the state of the current page 141 :return: self.state 142 """ 143 return self.state 121 144 122 145 def draw_page(self): … … 131 154 # create blank list of constraints 132 155 self.model_list = [] 133 self.model_to Fit = []156 self.model_to_fit = [] 134 157 self.constraints_list = [] 135 158 self.constraint_dict = {} … … 144 167 145 168 #------------------------------------------------------- 146 # #setup sizer1 (which fitpages to include)147 self. sizer1.Clear(True)169 # setup sizer1 (which fitpages to include) 170 self.data_selection_sizer.Clear(True) 148 171 box_description = wx.StaticBox(self, wx.ID_ANY, "Fit Combinations") 149 172 boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) … … 151 174 sizer_couples = wx.GridBagSizer(5, 5) 152 175 153 # This if statement should be obsolete and can be removed in version 4154 # Leave it here for now as no time to thoroughly test. However if no155 # fit page is found the menu item that calls this page is inactive156 # Nov. 22 2015 --PDB176 # The wx GUI has a flag to enable a menu item, but can still be 177 # reached via scripting. There is no guearantee future GUI 178 # implementations force this check, either. 179 # IMHO, this if statement should stay -- JRK 2016-OCT-05 157 180 if len(self.page_finder) == 0: 158 181 msg = " No fit combinations are found! \n\n" … … 161 184 sizer_title.Add(wx.StaticText(self, wx.ID_ANY, msg)) 162 185 else: 163 # #store model186 # store model 164 187 self._store_model() 165 188 … … 171 194 wx.TOP | wx.BOTTOM | wx.EXPAND | wx.ADJUST_MINSIZE, border=5) 172 195 sizer_title.Add(self.cb1, 0, 173 wx.TOP | wx.BOTTOM | wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, border=5) 174 175 ## draw list of model and data names 196 wx.TOP | wx.BOTTOM | wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 197 border=5) 198 199 # draw list of model and data names 176 200 self._fill_sizer_model_list(sizer_couples) 177 201 178 202 boxsizer1.Add(sizer_title, flag=wx.TOP | wx.BOTTOM, border=5) 179 203 boxsizer1.Add(sizer_couples, 1, flag=wx.TOP | wx.BOTTOM, border=5) 180 self. sizer1.Add(boxsizer1, 1, wx.EXPAND | wx.ALL, 10)181 #self.sizer1.Layout()204 self.data_selection_sizer.Add(boxsizer1, 1, wx.EXPAND | wx.ALL, 10) 205 # self.sizer1.Layout() 182 206 183 207 #-------------------------------------------------------- 184 ## set up the other 2 sizers: the constraints list and the 185 ## buttons (fit, help etc) sizer at the bottom of the page. 186 ## Note: the if statement should be removed along with the above 187 ## if statement as soon as it can be properly tested. 188 ## Nov. 22 2015 --PDB 208 # set up the other 2 sizers: the constraints list and the 209 # buttons (fit, help etc) sizer at the bottom of the page. 210 # Note: the if statement should be removed along with the above 211 # if statement as soon as it can be properly tested. 212 # Nov. 22 2015 --PDB 213 # As above, this page can be accessed through other means than the 214 # base SasView GUI. 215 # Oct. 5, 2016 --JRK 189 216 if len(self.page_finder) > 0: 190 # #draw the sizer containing constraint info217 # draw the sizer containing constraint info 191 218 if not self.batch_on: 192 219 self._fill_sizer_constraint() 193 # #draw fit button sizer220 # draw fit button sizer 194 221 self._fill_sizer_fit() 195 196 222 197 223 def _fill_sizer_model_list(self, sizer): … … 201 227 ix = 0 202 228 iy = 0 203 list = []204 229 sizer.Clear(True) 205 230 … … 209 234 new_name.SetForegroundColour(wx.WHITE) 210 235 sizer.Add(new_name, (iy, ix), (1, 1), 211 236 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 212 237 ix += 2 213 238 model_type = wx.StaticText(self, wx.ID_ANY, ' Model ') … … 215 240 model_type.SetForegroundColour(wx.WHITE) 216 241 sizer.Add(model_type, (iy, ix), (1, 1), 217 242 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 218 243 ix += 1 219 244 data_used = wx.StaticText(self, wx.ID_ANY, ' Data ') … … 221 246 data_used.SetForegroundColour(wx.WHITE) 222 247 sizer.Add(data_used, (iy, ix), (1, 1), 223 248 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 224 249 ix += 1 225 250 tab_used = wx.StaticText(self, wx.ID_ANY, ' FitPage ') … … 302 327 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 303 328 304 self. sizer2.Clear(True)329 self.constraints_sizer.Clear(True) 305 330 if self.batch_on: 306 if self. sizer2.IsShown():307 self. sizer2.Show(False)331 if self.constraints_sizer.IsShown(): 332 self.constraints_sizer.Show(False) 308 333 return 309 334 box_description = wx.StaticBox(self, wx.ID_ANY, "Fit Constraints") 310 box sizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL)335 box_sizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 311 336 sizer_title = wx.BoxSizer(wx.HORIZONTAL) 312 337 self.sizer_all_constraints = wx.BoxSizer(wx.HORIZONTAL) … … 338 363 339 364 self.btAdd = wx.Button(self, self.ID_ADD, 'Add') 340 self.btAdd.Bind(wx.EVT_BUTTON, self._on Add_constraint,365 self.btAdd.Bind(wx.EVT_BUTTON, self._on_add_constraint, 341 366 id=self.btAdd.GetId()) 342 367 self.btAdd.SetToolTipString("Add another constraint?") … … 344 369 345 370 text_hint = wx.StaticText(self, wx.ID_ANY, 346 "Example: [M0][param ter] = M1.parameter")371 "Example: [M0][parameter] = M1.parameter") 347 372 sizer_button.Add(text_hint, 0, 348 373 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 10) … … 350 375 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 10) 351 376 352 boxsizer1.Add(sizer_title, flag=wx.TOP | wx.BOTTOM, border=10) 353 boxsizer1.Add(self.sizer_all_constraints, flag=wx.TOP | wx.BOTTOM, 354 border=10) 355 boxsizer1.Add(self.sizer_constraints, flag=wx.TOP | wx.BOTTOM, 356 border=10) 357 boxsizer1.Add(sizer_button, flag=wx.TOP | wx.BOTTOM, border=10) 358 359 self.sizer2.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10) 360 377 box_sizer1.Add(sizer_title, flag=wx.TOP | wx.BOTTOM, border=10) 378 box_sizer1.Add(self.sizer_all_constraints, flag=wx.TOP | wx.BOTTOM, 379 border=10) 380 box_sizer1.Add(self.sizer_constraints, flag=wx.TOP | wx.BOTTOM, 381 border=10) 382 box_sizer1.Add(sizer_button, flag=wx.TOP | wx.BOTTOM, border=10) 383 384 self.constraints_sizer.Add(box_sizer1, 0, wx.EXPAND | wx.ALL, 10) 361 385 362 386 def _fill_sizer_fit(self): … … 364 388 Draw fit button 365 389 """ 366 self. sizer3.Clear(True)390 self.run_fit_sizer.Clear(True) 367 391 box_description = wx.StaticBox(self, wx.ID_ANY, "Fit ") 368 392 boxsizer1 = wx.StaticBoxSizer(box_description, wx.VERTICAL) 369 393 sizer_button = wx.BoxSizer(wx.HORIZONTAL) 370 394 371 # Fit button395 # Fit button 372 396 self.btFit = wx.Button(self, self.ID_FIT, 'Fit', size=wx.DefaultSize) 373 self.btFit.Bind(wx.EVT_BUTTON, self.on Fit, id=self.btFit.GetId())397 self.btFit.Bind(wx.EVT_BUTTON, self.on_fit, id=self.btFit.GetId()) 374 398 self.btFit.SetToolTipString("Perform fit.") 375 399 376 # General Help button400 # General Help button 377 401 self.btHelp = wx.Button(self, wx.ID_HELP, 'HELP') 378 402 self.btHelp.SetToolTipString("Simultaneous/Constrained Fitting help.") 379 self.btHelp.Bind(wx.EVT_BUTTON, self._on Help)380 381 # hint text on button line403 self.btHelp.Bind(wx.EVT_BUTTON, self._on_help) 404 405 # hint text on button line 382 406 if self.batch_on: 383 407 text = " Fit in Parallel all Data sets\n" … … 393 417 394 418 boxsizer1.Add(sizer_button, flag=wx.TOP | wx.BOTTOM, border=10) 395 self. sizer3.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10)396 397 def on Remove(self, event):419 self.run_fit_sizer.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10) 420 421 def on_remove(self, event): 398 422 """ 399 423 Remove constraint fields … … 406 430 return 407 431 wx.CallAfter(self._remove_after, event.GetId()) 408 # self._onAdd_constraint(None)432 # self._onAdd_constraint(None) 409 433 410 434 def _remove_after(self, id): … … 416 440 self.constraints_list.remove(item) 417 441 self.nb_constraint -= 1 418 self. sizer2.Layout()442 self.constraints_sizer.Layout() 419 443 self.FitInside() 420 444 break 421 445 422 def on Fit(self, event):446 def on_fit(self, event): 423 447 """ 424 448 signal for fitting … … 435 459 flag = (self._manager.sim_page.uid == self.uid) 436 460 437 # #making sure all parameters content a constraint461 # making sure all parameters content a constraint 438 462 if not self.batch_on and self.show_constraint.GetValue(): 439 463 if not self._set_constraint(): 440 464 return 441 # #model was actually selected from this page to be fit442 if len(self.model_to Fit) >= 1:465 # model was actually selected from this page to be fit 466 if len(self.model_to_fit) >= 1: 443 467 self.manager._reset_schedule_problem(value=0) 444 468 for item in self.model_list: … … 456 480 msg = "Select at least one model check box to fit " 457 481 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 482 self.set_state() 458 483 459 484 def _on_fit_complete(self): … … 467 492 """ 468 493 Attempt to stop the fitting thread 469 """ 470 if event != None: 494 495 :param event: Event handler when stop fit is clicked 496 """ 497 if event is not None: 471 498 event.Skip() 472 499 self.manager.stop_fit(self.uid) … … 485 512 self.btFit.Enable(True) 486 513 487 def _on Help(self, event):514 def _on_help(self, event): 488 515 """ 489 516 Bring up the simultaneous Fitting Documentation whenever the HELP … … 494 521 versions of Wx (before 2.9) and thus not the release version of 495 522 installers, the help comes up at the top level of the file as 496 web browser does not pass anything past the # to the browser when it is523 web browser does not pass anything past the # to the browser when it is 497 524 running "file:///...." 498 525 499 :param ev t: Triggers on clicking the help button526 :param event: Triggers on clicking the help button 500 527 """ 501 528 _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" … … 510 537 511 538 :param manager: instance of plugin fitting 512 513 539 """ 514 540 self.manager = manager … … 518 544 check all models names 519 545 """ 520 self.model_to Fit = []521 if self.cb1.GetValue() == True:546 self.model_to_fit = [] 547 if self.cb1.GetValue(): 522 548 for item in self.model_list: 523 549 if item[0].IsEnabled(): 524 550 item[0].SetValue(True) 525 self.model_to Fit.append(item)526 527 # #constraint info551 self.model_to_fit.append(item) 552 553 # constraint info 528 554 self._store_model() 529 555 if not self.batch_on: 530 # #display constraint fields556 # display constraint fields 531 557 if (self.show_constraint.GetValue() and 532 558 len(self.constraints_list) == 0): … … 538 564 539 565 if not self.batch_on: 540 # #constraint info566 # constraint info 541 567 self._hide_constraint() 542 568 … … 544 570 self.FitInside() 545 571 546 547 572 def check_model_name(self, event): 548 573 """ 549 574 Save information related to checkbox and their states 550 575 """ 551 self.model_toFit = [] 552 cbox = event.GetEventObject() 576 self.model_to_fit = [] 553 577 for item in self.model_list: 554 if item[0].GetValue() == True:555 self.model_to Fit.append(item)578 if item[0].GetValue(): 579 self.model_to_fit.append(item) 556 580 else: 557 if item in self.model_to Fit:558 self.model_to Fit.remove(item)581 if item in self.model_to_fit: 582 self.model_to_fit.remove(item) 559 583 self.cb1.SetValue(False) 560 584 561 # #display constraint fields562 if len(self.model_to Fit) >= 1:585 # display constraint fields 586 if len(self.model_to_fit) >= 1: 563 587 self._store_model() 564 588 if not self.batch_on and self.show_constraint.GetValue() and\ … … 567 591 self._show_constraint() 568 592 569 elif len(self.model_to Fit) < 1:570 # #constraint info593 elif len(self.model_to_fit) < 1: 594 # constraint info 571 595 self._hide_constraint() 572 596 573 597 self._update_easy_setup_cb() 574 # #set the value of the main check button575 if len(self.model_list) == len(self.model_to Fit):598 # set the value of the main check button 599 if len(self.model_list) == len(self.model_to_fit): 576 600 self.cb1.SetValue(True) 577 601 self.FitInside() … … 585 609 Update easy setup combobox on selecting a model 586 610 """ 587 if self.model_cbox_left == None or self.model_cbox_right ==None:588 return 589 590 models = [(item[3].name, item[3]) for item in self.model_to Fit]611 if self.model_cbox_left is None or self.model_cbox_right is None: 612 return 613 614 models = [(item[3].name, item[3]) for item in self.model_to_fit] 591 615 setComboBoxItems(self.model_cbox_left, models) 592 616 setComboBoxItems(self.model_cbox_right, models) … … 595 619 if self.model_cbox_left.GetSelection() == wx.NOT_FOUND: 596 620 self.model_cbox_left.SetSelection(0) 597 self. sizer2.Layout()621 self.constraints_sizer.Layout() 598 622 599 623 def _store_model(self): … … 601 625 Store selected model 602 626 """ 603 if len(self.model_to Fit) < 1:604 return 605 for item in self.model_to Fit:627 if len(self.model_to_fit) < 1: 628 return 629 for item in self.model_to_fit: 606 630 model = item[3] 607 631 page_id = item[2] … … 612 636 Show fields to add constraint 613 637 """ 614 if len(self.model_to Fit) < 1:638 if len(self.model_to_fit) < 1: 615 639 msg = "Select at least 1 model to add constraint " 616 640 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 617 # #hide button641 # hide button 618 642 self._hide_constraint() 619 643 return … … 632 656 """ 633 657 box_description = wx.StaticBox(self, wx.ID_ANY, "Easy Setup ") 634 box sizer = wx.StaticBoxSizer(box_description, wx.HORIZONTAL)658 box_sizer = wx.StaticBoxSizer(box_description, wx.HORIZONTAL) 635 659 sizer_constraint = wx.BoxSizer(wx.HORIZONTAL) 636 660 self.model_cbox_left = wx.ComboBox(self, wx.ID_ANY, style=wx.CB_READONLY) … … 650 674 651 675 for id, model in self.constraint_dict.iteritems(): 652 # #check if all parameters have been selected for constraint653 # #then do not allow add constraint on parameters676 # check if all parameters have been selected for constraint 677 # then do not allow add constraint on parameters 654 678 self.model_cbox_left.Append(str(model.name), model) 655 679 self.model_cbox_left.Select(0) 656 680 for id, model in self.constraint_dict.iteritems(): 657 # #check if all parameters have been selected for constraint658 # #then do not allow add constraint on parameters681 # check if all parameters have been selected for constraint 682 # then do not allow add constraint on parameters 659 683 self.model_cbox_right.Append(str(model.name), model) 660 box sizer.Add(self.model_cbox_left,684 box_sizer.Add(self.model_cbox_left, 661 685 flag=wx.RIGHT | wx.EXPAND, border=10) 662 # boxsizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"),686 # box_sizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"), 663 687 # flag=wx.RIGHT | wx.EXPAND, border=5) 664 box sizer.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5)665 box sizer.Add(self.model_cbox_right,688 box_sizer.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 689 box_sizer.Add(self.model_cbox_right, 666 690 flag=wx.RIGHT | wx.EXPAND, border=10) 667 # boxsizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"),691 # box_sizer.Add(wx.StaticText(self, wx.ID_ANY, ".parameters"), 668 692 # flag=wx.RIGHT | wx.EXPAND, border=5) 669 box sizer.Add((20, -1))670 box sizer.Add(self.set_button, flag=wx.RIGHT | wx.EXPAND, border=5)671 sizer_constraint.Add(box sizer, flag=wx.RIGHT | wx.EXPAND, border=5)693 box_sizer.Add((20, -1)) 694 box_sizer.Add(self.set_button, flag=wx.RIGHT | wx.EXPAND, border=5) 695 sizer_constraint.Add(box_sizer, flag=wx.RIGHT | wx.EXPAND, border=5) 672 696 self.sizer_all_constraints.Insert(before=0, 673 697 item=sizer_constraint, … … 699 723 return 700 724 param_list = [] 701 param_list B= []725 param_list_b = [] 702 726 selection = self.model_cbox_left.GetCurrentSelection() 703 727 model_left = self.model_cbox_left.GetValue() 704 728 model = self.model_cbox_left.GetClientData(selection) 705 selection B= self.model_cbox_right.GetCurrentSelection()729 selection_b = self.model_cbox_right.GetCurrentSelection() 706 730 model_right = self.model_cbox_right.GetValue() 707 model B = self.model_cbox_right.GetClientData(selectionB)731 model_b = self.model_cbox_right.GetClientData(selection_b) 708 732 for id, dic_model in self.constraint_dict.iteritems(): 709 733 if model == dic_model: 710 734 param_list = self.page_finder[id].get_param2fit() 711 if model B== dic_model:712 param_list B= self.page_finder[id].get_param2fit()713 if len(param_list) > 0 and len(param_list B) > 0:735 if model_b == dic_model: 736 param_list_b = self.page_finder[id].get_param2fit() 737 if len(param_list) > 0 and len(param_list_b) > 0: 714 738 break 715 739 num_cbox = 0 … … 717 741 for param in param_list: 718 742 num_cbox += 1 719 if param in param_list B:743 if param in param_list_b: 720 744 item = self.constraints_list[-1] 721 745 item.model_cbox.SetStringSelection(model_left) … … 744 768 """ 745 769 Show constraint fields 770 :param dict: dictionary mapping constraint values 746 771 """ 747 772 self.btAdd.Show(True) … … 750 775 for id, model in self.constraint_dict.iteritems(): 751 776 nb_fit_param += len(self.page_finder[id].get_param2fit()) 752 # #Don't add anymore777 # Don't add anymore 753 778 if len(self.constraints_list) == nb_fit_param: 754 779 msg = "Cannot add another constraint. Maximum of number " … … 756 781 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 757 782 self.sizer_constraints.Layout() 758 self. sizer2.Layout()783 self.constraints_sizer.Layout() 759 784 return 760 if len(self.model_to Fit) < 1:785 if len(self.model_to_fit) < 1: 761 786 msg = "Select at least 1 model to add constraint " 762 787 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 763 788 self.sizer_constraints.Layout() 764 self. sizer2.Layout()789 self.constraints_sizer.Layout() 765 790 return 766 791 … … 771 796 model_cbox.Clear() 772 797 for id, model in self.constraint_dict.iteritems(): 773 # #check if all parameters have been selected for constraint774 # #then do not allow add constraint on parameters798 # check if all parameters have been selected for constraint 799 # then do not allow add constraint on parameters 775 800 model_cbox.Append(str(model.name), model) 776 801 wx.EVT_COMBOBOX(model_cbox, wx.ID_ANY, self._on_select_model) … … 789 814 # Remove button 790 815 #btRemove = wx.Button(self, self.ID_REMOVE, 'Remove') 791 bt Remove = wx.Button(self, self._ids.next(), 'Remove')792 bt Remove.Bind(wx.EVT_BUTTON, self.onRemove,793 id=bt Remove.GetId())794 bt Remove.SetToolTipString("Remove constraint.")795 bt Remove.Hide()816 bt_remove = wx.Button(self, self._ids.next(), 'Remove') 817 bt_remove.Bind(wx.EVT_BUTTON, self.on_remove, 818 id=bt_remove.GetId()) 819 bt_remove.SetToolTipString("Remove constraint.") 820 bt_remove.Hide() 796 821 797 822 # Hid the add button, if it exists … … 804 829 sizer_constraint.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 805 830 sizer_constraint.Add(constraint, flag=wx.RIGHT | wx.EXPAND, border=10) 806 sizer_constraint.Add(bt Remove, flag=wx.RIGHT | wx.EXPAND, border=10)831 sizer_constraint.Add(bt_remove, flag=wx.RIGHT | wx.EXPAND, border=10) 807 832 808 833 self.sizer_constraints.Insert(before=self.nb_constraint, … … 810 835 border=5) 811 836 c = ConstraintLine(model_cbox, param_cbox, egal_txt, 812 constraint, bt Remove, sizer_constraint)837 constraint, bt_remove, sizer_constraint) 813 838 self.constraints_list.append(c) 814 839 815 840 self.nb_constraint += 1 816 841 self.sizer_constraints.Layout() 817 self. sizer2.Layout()818 self.Layout 842 self.constraints_sizer.Layout() 843 self.Layout() 819 844 820 845 def _hide_constraint(self): … … 841 866 self.sizer_constraints.Clear(True) 842 867 self.sizer_constraints.Layout() 843 self. sizer2.Layout()844 self.Layout 868 self.constraints_sizer.Layout() 869 self.Layout() 845 870 self.FitInside() 846 871 847 872 def _on_select_model(self, event): 848 873 """ 849 fill combo xbox with list of parameters874 fill combo box with list of parameters 850 875 """ 851 876 if not self.constraints_list: 852 877 return 853 878 854 # #This way PC/MAC both work, instead of using event.GetClientData().879 # This way PC/MAC both work, instead of using event.GetClientData(). 855 880 model_cbox = self.constraints_list[-1].model_cbox 856 881 n = model_cbox.GetCurrentSelection() … … 867 892 param_cbox = self.constraints_list[-1].param_cbox 868 893 param_cbox.Clear() 869 # #insert only fittable paramaters894 # insert only fittable paramaters 870 895 for param in param_list: 871 896 param_cbox.Append(str(param), model) 872 897 param_cbox.Show(True) 873 898 874 bt Remove = self.constraints_list[-1].btRemove875 bt Remove.Show(True)899 bt_remove = self.constraints_list[-1].btRemove 900 bt_remove.Show(True) 876 901 self.btAdd.Show(True) 877 902 # self.Layout() … … 882 907 Store the appropriate constraint in the page_finder 883 908 """ 884 # #This way PC/MAC both work, instead of using event.GetClientData().885 # n = self.param_cbox.GetCurrentSelection()886 # model = self.param_cbox.GetClientData(n)887 # param = event.GetString()909 # This way PC/MAC both work, instead of using event.GetClientData(). 910 # n = self.param_cbox.GetCurrentSelection() 911 # model = self.param_cbox.GetClientData(n) 912 # param = event.GetString() 888 913 889 914 if self.constraints_list: … … 891 916 self.constraints_list[-1].constraint.Show(True) 892 917 893 def _on Add_constraint(self, event):918 def _on_add_constraint(self, event): 894 919 """ 895 920 Add another line for constraint … … 899 924 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 900 925 return 901 # #check that a constraint is added926 # check that a constraint is added 902 927 # before allow to add another constraint 903 928 for item in self.constraints_list: … … 913 938 model = item.param_cbox.GetClientData( 914 939 item.param_cbox.GetCurrentSelection()) 915 if model !=None:940 if model is not None: 916 941 msg = " Enter a constraint for %s.%s! " % (model.name, 917 942 item.param_cbox.GetString(0)) … … 920 945 wx.PostEvent(self.parent.parent, StatusEvent(status=msg)) 921 946 return 922 # #some model or parameters can be constrained947 # some model or parameters can be constrained 923 948 self._show_constraint() 924 949 self.FitInside() … … 980 1005 def on_set_focus(self, event=None): 981 1006 """ 982 The 1007 The derivative class is on focus if implemented 983 1008 """ 984 1009 if self.parent is not None: … … 995 1020 cbox.Append(name, value) 996 1021 cbox.SetStringSelection(selected) 1022 1023 1024 class SimFitPageState: 1025 """ 1026 State of the simultaneous fit page for saving purposes 1027 """ 1028 1029 def __init__(self): 1030 # Sim Fit Page Number 1031 self.fit_page_no = None 1032 # Select all data 1033 self.select_all = False 1034 # Data sets sent to fit page 1035 self.model_list = [] 1036 # Data sets to be fit 1037 self.model_to_fit = [] 1038 # Number of constraints 1039 self.no_constraint = 0 1040 # Dictionary of constraints 1041 self.constraint_dict = {} 1042 # List of constraints 1043 self.constraints_list = [] 1044 1045 def load_from_save_state(self, fit): 1046 """ 1047 Load in a simultaneous/constrained fit from a save state 1048 :param fit: Fitpanel object 1049 :return: None 1050 """ 1051 1052 model_map = {} 1053 fit.fit_panel.add_sim_page() 1054 1055 # Process each model and associate old M# with new M# 1056 i = 0 1057 for model in fit.fit_panel.sim_page.model_list: 1058 model_id = self._format_id(model[1].keys()[0]) 1059 for saved_model in self.model_list: 1060 save_id = saved_model.pop('name') 1061 saved_model['name'] = save_id 1062 save_id = self._format_id(save_id) 1063 if save_id == model_id: 1064 model_map[saved_model.pop('fit_page_source')] = \ 1065 model[3].name 1066 check = bool(saved_model.pop('checked')) 1067 fit.fit_panel.sim_page.model_list[i][0].SetValue(check) 1068 continue 1069 i += 1 1070 fit.fit_panel.sim_page.check_model_name(None) 1071 1072 if len(self.constraints_list) > 0: 1073 fit.fit_panel.sim_page.hide_constraint.SetValue(False) 1074 fit.fit_panel.sim_page.show_constraint.SetValue(True) 1075 fit.fit_panel.sim_page._display_constraint(None) 1076 1077 for constraint in self.constraints_list: 1078 model_cbox = constraint.pop('model_cbox') 1079 constraint_value = constraint.pop('constraint') 1080 for key, value in model_map.iteritems(): 1081 model_cbox.replace(key, value) 1082 constraint_value.replace(key, value) 1083 1084 bt_remove = wx.Button(fit.fit_panel.sim_page, 1085 fit.fit_panel.sim_page._ids.next(), 'Remove') 1086 bt_remove.Bind(wx.EVT_BUTTON, fit.fit_panel.sim_page.on_remove, 1087 id=bt_remove.GetId()) 1088 bt_remove.SetToolTipString("Remove constraint.") 1089 param_cbox = wx.ComboBox(fit.fit_panel.sim_page, wx.ID_ANY, 1090 style=wx.CB_READONLY, size=(100, -1)) 1091 egal_txt = wx.StaticText(fit.fit_panel.sim_page, wx.ID_ANY, " = ") 1092 # Model list 1093 model_cbox_sizer = wx.ComboBox(fit.fit_panel.sim_page, 1094 wx.ID_ANY, style=wx.CB_READONLY) 1095 model_cbox_sizer.Clear() 1096 wx.EVT_COMBOBOX(model_cbox_sizer, wx.ID_ANY, 1097 fit.fit_panel.sim_page._on_select_model) 1098 constraint_sizer = wx.TextCtrl(fit.fit_panel.sim_page, wx.ID_ANY) 1099 sizer_constraint = wx.BoxSizer(wx.HORIZONTAL) 1100 sizer_constraint.Add((5, -1)) 1101 sizer_constraint.Add(model_cbox_sizer, flag=wx.RIGHT | wx.EXPAND, 1102 border=10) 1103 sizer_constraint.Add(param_cbox, flag=wx.RIGHT | wx.EXPAND, 1104 border=5) 1105 sizer_constraint.Add(egal_txt, flag=wx.RIGHT | wx.EXPAND, border=5) 1106 sizer_constraint.Add(constraint_sizer, flag=wx.RIGHT | wx.EXPAND, 1107 border=10) 1108 sizer_constraint.Add(bt_remove, flag=wx.RIGHT | wx.EXPAND, 1109 border=10) 1110 new_const = ConstraintLine(model_cbox=model_cbox_sizer, 1111 param_cbox=constraint.pop('param_cbox'), 1112 egal_txt=constraint.pop('egal_txt'), 1113 constraint=constraint_value, 1114 btRemove=bt_remove, 1115 sizer=sizer_constraint 1116 ) 1117 # ConstraintLine = namedtuple('ConstraintLine', 1118 # 'model_cbox param_cbox egal_txt constraint btRemove sizer') 1119 fit.fit_panel.sim_page.sizer_constraints.Insert( 1120 before=fit.fit_panel.sim_page.nb_constraint, 1121 item=sizer_constraint, flag=wx.TOP | wx.BOTTOM | wx.EXPAND, 1122 border=5) 1123 fit.fit_panel.sim_page.constraints_list.append(new_const) 1124 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.