Changeset 51a4d78 in sasview for src/sas/sasgui/perspectives/fitting
- Timestamp:
- Oct 8, 2016 3:33:04 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:
- 1fac6c0
- Parents:
- 7988501 (diff), f7bc948 (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:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/perspectives/fitting/basepage.py
r7988501 r51a4d78 9 9 import copy 10 10 import math 11 import string12 11 import json 13 12 import logging … … 340 339 self.data.detector[index].beam_center.x = qmax 341 340 self.data.detector[index].beam_center.y = qmax 342 ## create x_bins and y_bins of the model 2D343 #pixel_width_x = self.data.detector[index].pixel_size.x344 #pixel_width_y = self.data.detector[index].pixel_size.y345 #center_x = self.data.detector[index].beam_center.x/pixel_width_x346 #center_y = self.data.detector[index].beam_center.y/pixel_width_y347 # theory default: assume the beam348 #center is located at the center of sqr detector349 341 xmax = qmax 350 342 xmin = -qmax … … 365 357 # set all True (standing for unmasked) as default 366 358 mask = numpy.ones(len(qx_data), dtype=bool) 367 # calculate the range of qx and qy: this way,368 # it is a little more independent369 #x_size = xmax - xmin370 #y_size = ymax - ymin371 359 # store x and y bin centers in q space 372 360 x_bins = x 373 361 y_bins = y 374 # bin size: x- & y-directions375 #xstep = x_size / len(x_bins - 1)376 #ystep = y_size / len(y_bins - 1)377 362 378 363 self.data.source = Source() … … 415 400 batch_menu.Enable(self.batch_on and flag) 416 401 417 def set_page_info(self, page_info):418 """419 set some page important information at once420 """421 # THIS METHOD/FUNCTION NO LONGE APPEARS TO BE CALLED. Started up program422 # and started new fit window and PR and Invariant and a fit in fitting423 # but never entered this routine which should be an initialization424 # routine. Leave for a while but probably something to clean up at425 # some point?426 #427 # PDB April 13 2014428 #429 ##window_name430 self.window_name = page_info.window_name431 ##window_caption432 self.window_caption = page_info.window_caption433 ## manager is the fitting plugin434 self._manager = page_info.manager435 ## owner of the page (fitting plugin)436 self.event_owner = page_info.event_owner437 ## current model438 self.model = page_info.model439 ## data440 self.data = page_info.data441 ## dictionary containing list of models442 self.model_list_box = page_info.model_list_box443 ## Data member to store the dispersion object created444 self.populate_box(model_dict=self.model_list_box)445 446 402 def onContextMenu(self, event): 447 403 """ 448 404 Retrieve the state selected state 449 405 """ 450 # Skipping the save state functionality for release 0.9.0451 #return452 453 406 pos = event.GetPosition() 454 407 pos = self.ScreenToClient(pos) 455 456 408 self.PopupMenu(self.popUpMenu, pos) 457 409 … … 570 522 def initialize_combox(self): 571 523 """ 572 put default value in the combobox 573 """ 574 ## fill combox box 575 if self.model_list_box is None: 576 return 577 if len(self.model_list_box) > 0: 578 ## This is obsolete code since form factor box is no longer static. 579 ## It is now set dynamically through _show_combox and _show_combos_helper 580 ## These are called for first time by formfactor_combo_init 581 ## itself called from fitpanel only. If we find that I'm wrong and 582 ## we DO need to initialize somehow here - do it by a call to 583 ## formfactor_combo_init 584 ## self.formfator_combo_init() 585 ## BUT NOT HERE -- make it last line of this 586 ## method so that structure box is populated before _show_comboox_helper 587 ## is called. Otherwise wx will complain mightily:-) 588 ## 589 ## Also change the name to initiatlize_structurebox along with changes 590 ## to other combobox methods (_populate_listbox --> _populate_categorybox 591 ## etc ) 592 ## 593 ## PDB 4/26/2014 594 # self._populate_box(self.formfactorbox, 595 # self.model_list_box["Shapes"]) 524 put default value in the combo box 525 """ 526 if self.model_list_box is not None and len(self.model_list_box) > 0: 596 527 self._populate_box(self.structurebox, 597 528 self.model_list_box["Structure Factors"]) … … 602 533 self.structurebox.Disable() 603 534 self.text2.Disable() 604 605 if self.model.__class__ in self.model_list_box["P(Q)*S(Q)"]:606 self.structurebox.Show()607 self.text2.Show()608 self.structurebox.Enable()609 self.text2.Enable()610 611 535 612 536 def set_dispers_sizer(self): … … 746 670 else: 747 671 wx.CallAfter(self.get_copy) 748 749 672 750 673 def on_paste(self, event): … … 960 883 self.state.orientation_params) 961 884 self._copy_parameters_state(self.orientation_params_disp, 962 885 self.state.orientation_params_disp) 963 886 964 887 self._copy_parameters_state(self.parameters, self.state.parameters) 965 888 self._copy_parameters_state(self.fittable_param, 966 889 self.state.fittable_param) 967 890 self._copy_parameters_state(self.fixed_param, self.state.fixed_param) 968 891 #save chisqr … … 1052 975 self.disp_cb_dict = state.disp_cb_dict 1053 976 self.disp_list = state.disp_list 1054 1055 ## set the state of the radio box1056 #self.shape_rbutton.SetValue(state.shape_rbutton)1057 #self.shape_indep_rbutton.SetValue(state.shape_indep_rbutton)1058 #self.struct_rbutton.SetValue(state.struct_rbutton)1059 #self.plugin_rbutton.SetValue(state.plugin_rbutton)1060 977 1061 978 ## fill model combobox … … 1886 1803 if mod_cat == custom_model: 1887 1804 for model in self.model_list_box[mod_cat]: 1888 str_m = model.id if hasattr(model, 'id') else model.name 1889 m_list.append(self.model_dict[str_m]) 1805 m_list.append(self.model_dict[model.name]) 1890 1806 else: 1891 1807 cat_dic = self.master_category_dict[mod_cat] … … 1893 1809 if enabled: 1894 1810 m_list.append(self.model_dict[model]) 1895 #else:1896 # msg = "This model is disabled by Category Manager."1897 # wx.PostEvent(self.parent.parent,1898 # StatusEvent(status=msg, info="error"))1899 1811 except Exception: 1900 1812 msg = traceback.format_exc() … … 2067 1979 form_factor = self.formfactorbox.GetClientData(f_id) 2068 1980 2069 if not form_factor in self.model_list_box["multiplication"]:1981 if form_factor is None or not form_factor.is_form_factor: 2070 1982 self.structurebox.Hide() 2071 1983 self.text2.Hide() … … 3474 3386 self.by_model_dict = defaultdict(list) 3475 3387 self.model_enabled_dict = defaultdict(bool) 3476 3477 try: 3478 categorization_file = CategoryInstaller.get_user_file() 3479 if not os.path.isfile(categorization_file): 3480 categorization_file = CategoryInstaller.get_default_file() 3481 cat_file = open(categorization_file, 'rb') 3482 self.master_category_dict = json.load(cat_file) 3483 self._regenerate_model_dict() 3484 cat_file.close() 3485 except IOError: 3486 raise 3487 print 'Problem reading in category file.' 3488 print 'We even looked for it, made sure it was there.' 3489 print 'An existential crisis if there ever was one.' 3388 categorization_file = CategoryInstaller.get_user_file() 3389 with open(categorization_file, 'rb') as f: 3390 self.master_category_dict = json.load(f) 3391 self._regenerate_model_dict() 3490 3392 3491 3393 def _regenerate_model_dict(self): -
src/sas/sasgui/perspectives/fitting/fitpanel.py
r05228b0 re6de6b8 10 10 11 11 from sas.sasgui.guiframe.panel_base import PanelBase 12 from sas.sasgui.guiframe.events import PanelOnFocusEvent 13 from sas.sasgui.guiframe.events import StatusEvent 12 from sas.sasgui.guiframe.events import PanelOnFocusEvent, StatusEvent 14 13 from sas.sasgui.guiframe.dataFitting import check_data_validity 14 from sas.sasgui.perspectives.fitting.simfitpage import SimultaneousFitPage 15 15 16 16 import basepage … … 18 18 _BOX_WIDTH = 80 19 19 20 20 21 class FitPanel(nb, PanelBase): 21 22 """ … … 26 27 27 28 """ 28 # #Internal name for the AUI manager29 # Internal name for the AUI manager 29 30 window_name = "Fit panel" 30 # #Title to appear on top of the window31 # Title to appear on top of the window 31 32 window_caption = "Fit Panel " 32 33 CENTER_PANE = True … … 40 41 wx.CLIP_CHILDREN) 41 42 PanelBase.__init__(self, parent) 42 # self.SetWindowStyleFlag(style=nb.FNB_FANCY_TABS)43 # self.SetWindowStyleFlag(style=nb.FNB_FANCY_TABS) 43 44 self._manager = manager 44 45 self.parent = parent 45 46 self.event_owner = None 46 # dictionary of miodel {model class name, model class}47 # dictionary of miodel {model class name, model class} 47 48 self.menu_mng = models.ModelManager() 48 49 self.model_list_box = self.menu_mng.get_model_list() 49 # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING50 # pageClosedEvent = nb.EVT_FLATNOTEBOOK_PAGE_CLOSING 50 51 self.model_dictionary = self.menu_mng.get_model_dictionary() 51 52 self.pageClosedEvent = wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE 52 53 53 54 self.Bind(self.pageClosedEvent, self.on_close_page) 54 # #save the title of the last page tab added55 # save the title of the last page tab added 55 56 self.fit_page_name = {} 56 # #list of existing fit page57 # list of existing fit page 57 58 self.opened_pages = {} 58 # index of fit page59 # index of fit page 59 60 self.fit_page_index = 0 60 # index of batch page61 # index of batch page 61 62 self.batch_page_index = 0 62 # page of simultaneous fit63 # page of simultaneous fit 63 64 self.sim_page = None 64 65 self.batch_page = None 65 # #get the state of a page66 # get the state of a page 66 67 self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate) 67 68 self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo) … … 80 81 """ 81 82 return an xml node containing state of the panel 82 that guiframe can write to file 83 """ 84 msg = "" 83 that guiframe can write to file 84 """ 85 # Iterate through all pages and check for batch fitting 86 batch_state = None 87 if self.sim_page is not None: 88 batch_state = self.sim_page.set_state() 89 85 90 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")) 91 data = page.get_data() 92 # state must be cloned 93 state = page.get_state().clone() 94 if data is not None or page.model is not None: 95 new_doc = self._manager.state_reader.write_toXML(data, 96 state, 97 batch_state) 98 if doc is not None and hasattr(doc, "firstChild"): 99 child = new_doc.firstChild.firstChild 100 doc.firstChild.appendChild(child) 101 else: 102 doc = new_doc 103 108 104 return doc 109 105 … … 179 175 def get_state(self): 180 176 """ 181 177 return the state of the current selected page 182 178 """ 183 179 pos = self.GetSelection() … … 191 187 """ 192 188 193 # get number of pages189 # get number of pages 194 190 nop = self.GetPageCount() 195 # use while-loop, for-loop will not do the job well.191 # use while-loop, for-loop will not do the job well. 196 192 while (nop > 0): 197 # delete the first page until no page exists193 # delete the first page until no page exists 198 194 page = self.GetPage(0) 199 195 if self._manager.parent.panel_on_focus == page: … … 201 197 self._close_helper(selected_page=page) 202 198 self.DeletePage(0) 203 nop = nop - 1 204 205 ## save the title of the last page tab added 199 nop = self.GetPageCount() 200 # Clear list of names 206 201 self.fit_page_name = {} 207 # # list of existing fit page202 # Clear list of opened pages 208 203 self.opened_pages = {} 204 self.fit_page_index = 0 205 self.batch_page_index = 0 209 206 210 207 def set_state(self, state): … … 215 212 if state is not None: 216 213 for uid, panel in self.opened_pages.iteritems(): 217 # Don't return any panel is the exact same page is created214 # Don't return any panel is the exact same page is created 218 215 if uid == panel.uid and panel.data == state.data: 219 216 # the page is still opened … … 223 220 if not page_is_opened: 224 221 if state.data.__class__.__name__ != 'list': 225 # To support older state file format222 # To support older state file format 226 223 list_data = [state.data] 227 224 else: 228 # Todo: need new file format for the list225 # Todo: need new file format for the list 229 226 list_data = state.data 230 227 panel = self._manager.add_fit_page(data=list_data) … … 241 238 Clear and close all panels, used by guimanager 242 239 """ 243 244 #close all panels only when svs file opened 240 # close all panels only when svs file opened 245 241 self.close_all() 246 242 self._manager.mypanels = [] 243 self.sim_page = None 244 self.batch_page = None 247 245 248 246 def on_close_page(self, event=None): … … 253 251 selected_page = self.GetPage(self.GetSelection()) 254 252 if nbr_page == 1: 255 if selected_page.get_data() ==None:253 if selected_page.get_data() is not None: 256 254 if event is not None: 257 255 event.Veto() … … 271 269 272 270 if data is None: 273 # the fitpanel exists and only the initial fit page is open274 # with no selected data271 # the fitpanel exists and only the initial fit page is open 272 # with no selected data 275 273 return 276 274 if data.id == deleted_data.id: … … 284 282 285 283 :param manager: instance of plugin fitting 286 287 284 """ 288 285 self._manager = manager … … 333 330 else: 334 331 self.batch_page = SimultaneousFitPage(self, batch_on=True, 335 332 page_finder=page_finder) 336 333 self.batch_page.window_caption = caption 337 334 self.batch_page.window_name = caption … … 346 343 add an empty page 347 344 """ 348 """349 345 if self.batch_on: 350 346 from batchfitpage import BatchFitPage 351 panel = BatchFitPage(parent=self)352 #Increment index of batch page353 self.batch_page_index += 1354 index = self.batch_page_index355 else:356 """357 from fitpage import FitPage358 from batchfitpage import BatchFitPage359 if self.batch_on:360 347 panel = BatchFitPage(parent=self) 361 348 self.batch_page_index += 1 … … 363 350 panel.set_index_model(self.batch_page_index) 364 351 else: 365 #Increment index of fit page 352 # Increment index of fit page 353 from fitpage import FitPage 366 354 panel = FitPage(parent=self) 367 355 self.fit_page_index += 1 … … 441 429 page = None 442 430 for p in self.opened_pages.values(): 443 # check if there is an empty page to fill up431 # check if there is an empty page to fill up 444 432 if not check_data_validity(p.get_data()) and p.batch_on: 445 433 446 # make sure data get placed in 1D empty tab if data is 1D447 # else data get place on 2D tab empty tab434 # make sure data get placed in 1D empty tab if data is 1D 435 # else data get place on 2D tab empty tab 448 436 enable2D = p.get_view_mode() 449 437 if (data.__class__.__name__ == "Data2D" and enable2D)\ … … 458 446 data_type = dlg.get_data() 459 447 dlg.Destroy() 460 if page 448 if page is None: 461 449 page = self.add_empty_page() 462 450 if data_type == 1: 463 # user has selected only data1D451 # user has selected only data1D 464 452 page.fill_data_combobox(data_1d_list) 465 453 elif data_type == 2: 466 454 page.fill_data_combobox(data_2d_list) 467 455 else: 468 # the batch analysis is canceled456 # the batch analysis is canceled 469 457 dlg.Destroy() 470 458 return None … … 503 491 try: 504 492 data = data_list[0] 505 except :493 except Exception: 506 494 # for 'fitv' files 507 495 data_list = [data] … … 511 499 return None 512 500 for page in self.opened_pages.values(): 513 # check if the selected data existing in the fitpanel501 # check if the selected data existing in the fitpanel 514 502 pos = self.GetPageIndex(page) 515 503 if not check_data_validity(page.get_data()) and not page.batch_on: 516 # make sure data get placed in 1D empty tab if data is 1D517 # else data get place on 2D tab empty tab504 # make sure data get placed in 1D empty tab if data is 1D 505 # else data get place on 2D tab empty tab 518 506 enable2D = page.get_view_mode() 519 507 if (data.__class__.__name__ == "Data2D" and enable2D)\ 520 or (data.__class__.__name__ == "Data1D" and not enable2D):508 or (data.__class__.__name__ == "Data1D" and not enable2D): 521 509 page.batch_on = self.batch_on 522 510 page._set_save_flag(not page.batch_on) 523 511 page.fill_data_combobox(data_list) 524 # caption = "FitPage" + str(self.fit_page_index)512 # caption = "FitPage" + str(self.fit_page_index) 525 513 self.SetPageText(pos, page.window_caption) 526 514 self.SetSelection(pos) 527 515 return page 528 # create new page and add data516 # create new page and add data 529 517 page = self.add_empty_page() 530 518 pos = self.GetPageIndex(page) … … 574 562 Delete the given page from the notebook 575 563 """ 576 # remove hint page577 # if selected_page == self.hint_page:564 # remove hint page 565 # if selected_page == self.hint_page: 578 566 # return 579 # #removing sim_page567 # removing sim_page 580 568 if selected_page == self.sim_page: 581 569 self._manager.sim_page = None … … 584 572 self._manager.batch_page = None 585 573 return 586 """ 587 # The below is not working when delete #5 and still have #6. 588 if selected_page.__class__.__name__ == "FitPage": 589 self.fit_page_index -= 1 590 else: 591 self.batch_page_index -= 1 592 """ 593 ## closing other pages 574 # closing other pages 594 575 state = selected_page.createMemento() 595 576 page_finder = self._manager.get_page_finder() 596 # #removing fit page577 # removing fit page 597 578 data = selected_page.get_data() 598 # Don' t remove plot for 2D579 # Don' t remove plot for 2D 599 580 flag = True 600 581 if data.__class__.__name__ == 'Data2D': 601 582 flag = False 602 583 if selected_page in page_finder: 603 # Delete the name of the page into the list of open page584 # Delete the name of the page into the list of open page 604 585 for uid, list in self.opened_pages.iteritems(): 605 #Don't return any panel is the exact same page is created 606 586 # Don't return any panel is the exact same page is created 607 587 if flag and selected_page.uid == uid: 608 588 self._manager.remove_plot(uid, theory=False) … … 610 590 del page_finder[selected_page] 611 591 612 # Delete the name of the page into the list of open page592 # Delete the name of the page into the list of open page 613 593 for uid, list in self.opened_pages.iteritems(): 614 # Don't return any panel is the exact same page is created594 # Don't return any panel is the exact same page is created 615 595 if selected_page.uid == uid: 616 596 del self.opened_pages[selected_page.uid] 617 597 break 618 # #remove the check box link to the model name of this page (selected_page)598 # remove the check box link to the model name of the selected_page 619 599 try: 620 600 self.sim_page.draw_page() 621 601 except: 622 # #that page is already deleted no need to remove check box on623 # #non existing page602 # that page is already deleted no need to remove check box on 603 # non existing page 624 604 pass 625 605 try: 626 606 self.batch_page.draw_page() 627 607 except: 628 # #that page is already deleted no need to remove check box on629 # #non existing page608 # that page is already deleted no need to remove check box on 609 # non existing page 630 610 pass -
src/sas/sasgui/perspectives/fitting/fitting.py
rca4d985 rff3f5821 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 = [] … … 1740 1742 data_id=str(page_id) + " " + data.name + " unsmeared") 1741 1743 1742 self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 1743 data_description="Data unsmeared", 1744 data_id="Data " + data.name + " unsmeared", 1745 dy=unsmeared_error) 1744 if unsmeared_data is not None and unsmeared_error is not None: 1745 self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 1746 data_description="Data unsmeared", 1747 data_id="Data " + data.name + " unsmeared", 1748 dy=unsmeared_error) 1746 1749 1747 1750 if sq_model is not None and pq_model is not None: -
src/sas/sasgui/perspectives/fitting/model_thread.py
rca4d985 r286c757 179 179 unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 180 180 output = self.smearer(unsmeared_output, first_bin, last_bin) 181 181 182 182 # Rescale data to unsmeared model 183 unsmeared_data = numpy.zeros((len(self.data.x))) 184 unsmeared_error = numpy.zeros((len(self.data.x))) 185 unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\ 186 * unsmeared_output[first_bin:last_bin+1]\ 187 / output[first_bin:last_bin+1] 188 unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\ 189 * unsmeared_output[first_bin:last_bin+1]\ 190 / output[first_bin:last_bin+1] 191 unsmeared_output=unsmeared_output[index] 192 unsmeared_data=unsmeared_data[index] 193 unsmeared_error=unsmeared_error 183 # Check that the arrays are compatible. If we only have a model but no data, 184 # the length of data.y will be zero. 185 if isinstance(self.data.y, numpy.ndarray) and output.shape == self.data.y.shape: 186 unsmeared_data = numpy.zeros((len(self.data.x))) 187 unsmeared_error = numpy.zeros((len(self.data.x))) 188 unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\ 189 * unsmeared_output[first_bin:last_bin+1]\ 190 / output[first_bin:last_bin+1] 191 unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\ 192 * unsmeared_output[first_bin:last_bin+1]\ 193 / output[first_bin:last_bin+1] 194 unsmeared_output=unsmeared_output[index] 195 unsmeared_data=unsmeared_data[index] 196 unsmeared_error=unsmeared_error 194 197 else: 195 198 output[index] = self.model.evalDistribution(self.data.x[index]) -
src/sas/sasgui/perspectives/fitting/models.py
r6fb559d r212bfc2 412 412 """ 413 413 __modelmanager = ModelManagerBase() 414 cat_model_list = [ model_namefor model_name \414 cat_model_list = [__modelmanager.model_dictionary[model_name] for model_name \ 415 415 in __modelmanager.model_dictionary.keys() \ 416 416 if model_name not in __modelmanager.stored_plugins.keys()] -
src/sas/sasgui/perspectives/fitting/pagestate.py
r6c382da re6de6b8 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 … … 381 378 382 379 rep += "State created: %s\n" % time_str 383 rep += "State form factor combobox selection: %s\n" % self.formfactorcombobox 384 rep += "State structure factor combobox selection: %s\n" % self.structurecombobox 380 rep += "State form factor combobox selection: %s\n" % \ 381 self.formfactorcombobox 382 rep += "State structure factor combobox selection: %s\n" % \ 383 self.structurecombobox 385 384 rep += "is data : %s\n" % self.is_data 386 385 rep += "data's name : %s\n" % self.data_name 387 386 rep += "data's id : %s\n" % self.data_id 388 if self.model !=None:387 if self.model is not None: 389 388 m_name = self.model.__class__.__name__ 390 389 if m_name == 'Model': … … 397 396 rep += "model type (Category) selected: %s\n" % self.categorycombobox 398 397 rep += "data : %s\n" % str(self.data) 399 rep += "Plotting Range: min: %s, max: %s, steps: %s\n" % (str(self.qmin),400 398 rep += "Plotting Range: min: %s, max: %s, steps: %s\n" % \ 399 (str(self.qmin),str(self.qmax), str(self.npts)) 401 400 rep += "Dispersion selection : %s\n" % str(self.disp_box) 402 401 rep += "Smearing enable : %s\n" % str(self.enable_smearer) … … 414 413 415 414 rep += "2D enable : %s\n" % str(self.enable2D) 416 rep += "All parameters checkbox selected: %s\n" % (self.cb1)415 rep += "All parameters checkbox selected: %s\n" % str(self.cb1) 417 416 rep += "Value of Chisqr : %s\n" % str(self.tcChi) 418 417 rep += "Smear object : %s\n" % str(self.smearer) 419 rep += "Smear type : %s\n" % (self.smear_type)418 rep += "Smear type : %s\n" % str(self.smear_type) 420 419 rep += "dq_l : %s\n" % self.dq_l 421 420 rep += "dq_r : %s\n" % self.dq_r … … 434 433 if not self.is_2D: 435 434 for item in self.parameters: 436 if not itemin self.orientation_params:435 if item not in self.orientation_params: 437 436 temp_parameters.append(item) 438 437 for item in self.fittable_param: 439 if not itemin self.orientation_params_disp:438 if item not in self.orientation_params_disp: 440 439 temp_fittable_param.append(item) 441 440 else: … … 443 442 temp_fittable_param = self.fittable_param 444 443 445 rep += "number parameters(self.parameters): %s\n" % len(temp_parameters) 444 rep += "number parameters(self.parameters): %s\n" % \ 445 len(temp_parameters) 446 446 rep = self._repr_helper(list=temp_parameters, rep=rep) 447 rep += "number str_parameters(self.str_parameters): %s\n" % len(self.str_parameters) 447 rep += "number str_parameters(self.str_parameters): %s\n" % \ 448 len(self.str_parameters) 448 449 rep = self._repr_helper(list=self.str_parameters, rep=rep) 449 rep += "number fittable_param(self.fittable_param): %s\n" % len(temp_fittable_param) 450 rep += "number fittable_param(self.fittable_param): %s\n" % \ 451 len(temp_fittable_param) 450 452 rep = self._repr_helper(list=temp_fittable_param, rep=rep) 451 453 return rep … … 551 553 paramval_string += CENTRE % param + "\n" 552 554 553 text_string = "\n\n\n%s\n\n%s\n%s\n%s\n\n%s" % (title, file, q_name, chi2, paramval) 555 text_string = "\n\n\n%s\n\n%s\n%s\n%s\n\n%s" % \ 556 (title, file, q_name, chi2, paramval) 554 557 555 558 title_name = self._check_html_format(title_name) … … 632 635 element.appendChild(sub_element) 633 636 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. 637 def toXML(self, file="fitting_state.fitv", doc=None, 638 entry_node=None, batch_fit_state=None): 639 """ 640 Writes the state of the fit panel to file, as XML. 637 641 638 642 Compatible with standalone writing, or appending to an 639 already existing XML document. In that case, the XML document 640 isrequired. An optional entry node in the XML document may also be given.643 already existing XML document. In that case, the XML document is 644 required. An optional entry node in the XML document may also be given. 641 645 642 646 :param file: file to write to 643 647 :param doc: XML document object [optional] 644 :param entry_node: XML node within the XML document at which we will append the data [optional]645 648 :param entry_node: XML node within the XML document at which we 649 will append the data [optional] 646 650 """ 647 651 from xml.dom.minidom import getDOMImplementation … … 691 695 element.setAttributeNode(attr) 692 696 top_element.appendChild(element) 697 693 698 # Inputs 694 699 inputs = newdoc.createElement("Attributes") … … 741 746 for item in LIST_OF_STATE_PARAMETERS: 742 747 element = newdoc.createElement(item[0]) 743 self._toXML_helper(thelist=getattr(self, item[1]), element=element, newdoc=newdoc) 748 self._toXML_helper(thelist=getattr(self, item[1]), 749 element=element, newdoc=newdoc) 744 750 inputs.appendChild(element) 751 752 # Combined and Simultaneous Fit Parameters 753 if batch_fit_state is not None: 754 batch_combo = newdoc.createElement('simultaneous_fit') 755 top_element.appendChild(batch_combo) 756 757 # Simultaneous Fit Number For Linking Later 758 element = newdoc.createElement('sim_fit_number') 759 element.setAttribute('fit_number', str(batch_fit_state.fit_page_no)) 760 batch_combo.appendChild(element) 761 762 # Save constraints 763 constraints = newdoc.createElement('constraints') 764 batch_combo.appendChild(constraints) 765 for constraint in batch_fit_state.constraints_list: 766 if constraint.model_cbox.GetValue() != "": 767 # model_cbox, param_cbox, egal_txt, constraint, btRemove, sizer 768 doc_cons = newdoc.createElement('constraint') 769 doc_cons.setAttribute('model_cbox', 770 str(constraint.model_cbox.GetValue())) 771 doc_cons.setAttribute('param_cbox', 772 str(constraint.param_cbox.GetValue())) 773 doc_cons.setAttribute('egal_txt', 774 str(constraint.egal_txt.GetLabel())) 775 doc_cons.setAttribute('constraint', 776 str(constraint.constraint.GetValue())) 777 constraints.appendChild(doc_cons) 778 779 # Save all models 780 models = newdoc.createElement('model_list') 781 batch_combo.appendChild(models) 782 for model in batch_fit_state.model_list: 783 doc_model = newdoc.createElement('model_list_item') 784 doc_model.setAttribute('checked', str(model[0].GetValue())) 785 keys = model[1].keys() 786 doc_model.setAttribute('name', str(keys[0])) 787 values = model[1].get(keys[0]) 788 doc_model.setAttribute('fit_number', str(model[2])) 789 doc_model.setAttribute('fit_page_source', str(model[3])) 790 doc_model.setAttribute('model_name', str(values.model.id)) 791 models.appendChild(doc_model) 792 793 # Select All Checkbox 794 element = newdoc.createElement('select_all') 795 if batch_fit_state.select_all: 796 element.setAttribute('checked', 'True') 797 else: 798 element.setAttribute('checked', 'False') 799 batch_combo.appendChild(element) 745 800 746 801 # Save the file … … 809 864 :param file: .fitv file 810 865 :param node: node of a XML document to read from 811 812 866 """ 813 867 if file is not None: … … 816 870 raise RuntimeError, msg 817 871 818 if node.get('version') and node.get('version') == '1.0':872 if node.get('version') and node.get('version') == '1.0': 819 873 820 874 # Get file name … … 862 916 value = cls.type 863 917 except Exception: 864 logging.error("unable to load distribution %r for %s"865 918 base = "unable to load distribution %r for %s" 919 logging.error(base % (value, parameter)) 866 920 continue 867 921 _disp_obj_dict = getattr(self, varname) … … 960 1014 self.cansas = cansas 961 1015 self.state = None 1016 # batch fitting params for saving 1017 self.batchfit_params = [] 962 1018 963 1019 def get_state(self): … … 984 1040 raise RuntimeError, "The cansas writer expects a Data2D instance" 985 1041 1042 title = "cansas1d/%s" % self.version 1043 title += "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" 986 1044 doc = xml.dom.minidom.Document() 987 1045 main_node = doc.createElement("SASroot") 988 1046 main_node.setAttribute("version", self.version) 989 1047 main_node.setAttribute("xmlns", "cansas1d/%s" % self.version) 990 main_node.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")991 main_node.setAttribute("xsi:schemaLocation",992 "cansas1d/%s http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" % self.version)1048 main_node.setAttribute("xmlns:xsi", 1049 "http://www.w3.org/2001/XMLSchema-instance") 1050 main_node.setAttribute("xsi:schemaLocation", title) 993 1051 994 1052 doc.appendChild(main_node) … … 999 1057 write_node(doc, entry_node, "Title", datainfo.title) 1000 1058 if datainfo is not None: 1001 write_node(doc, entry_node, "data_class", datainfo.__class__.__name__) 1059 write_node(doc, entry_node, "data_class", 1060 datainfo.__class__.__name__) 1002 1061 for item in datainfo.run: 1003 1062 runname = {} 1004 if datainfo.run_name.has_key(item) and len(str(datainfo.run_name[item])) > 1: 1063 if datainfo.run_name.has_key(item) and \ 1064 len(str(datainfo.run_name[item])) > 1: 1005 1065 runname = {'name': datainfo.run_name[item]} 1006 1066 write_node(doc, entry_node, "Run", item, runname) … … 1219 1279 1220 1280 :param entry: XML node to read from 1221 1222 1281 :return: PageState object 1223 1282 """ … … 1228 1287 nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 1229 1288 namespaces={'ns': CANSAS_NS}) 1230 if nodes != []:1289 if nodes: 1231 1290 # Create an empty state 1232 1291 state = PageState() … … 1238 1297 1239 1298 return state 1299 1300 def _parse_simfit_state(self, entry): 1301 """ 1302 Parses the saved data for a simultaneous fit 1303 :param entry: XML object to read from 1304 :return: XML object for a simultaneous fit or None 1305 """ 1306 nodes = entry.xpath('ns:%s' % FITTING_NODE_NAME, 1307 namespaces={'ns': CANSAS_NS}) 1308 if nodes: 1309 simfitstate = nodes[0].xpath('ns:simultaneous_fit', 1310 namespaces={'ns': CANSAS_NS}) 1311 if simfitstate: 1312 from simfitpage import SimFitPageState 1313 sim_fit_state = SimFitPageState() 1314 simfitstate_0 = simfitstate[0] 1315 all = simfitstate_0.xpath('ns:select_all', 1316 namespaces={'ns': CANSAS_NS}) 1317 atts = all[0].attrib 1318 checked = atts.get('checked') 1319 sim_fit_state.select_all = bool(checked) 1320 model_list = simfitstate_0.xpath('ns:model_list', 1321 namespaces={'ns': CANSAS_NS}) 1322 model_list_items = model_list[0].xpath('ns:model_list_item', 1323 namespaces={'ns': CANSAS_NS}) 1324 for model in model_list_items: 1325 attrs = model.attrib 1326 sim_fit_state.model_list.append(attrs) 1327 1328 constraints = simfitstate_0.xpath('ns:constraints', 1329 namespaces={'ns': CANSAS_NS}) 1330 constraint_list = constraints[0].xpath('ns:constraint', 1331 namespaces={'ns': CANSAS_NS}) 1332 for constraint in constraint_list: 1333 attrs = constraint.attrib 1334 sim_fit_state.constraints_list.append(attrs) 1335 1336 return sim_fit_state 1337 else: 1338 return None 1240 1339 1241 1340 def _parse_save_state_entry(self, dom): … … 1298 1397 data_info.notes.append(note_value) 1299 1398 except Exception: 1300 err_mess = "cansas_reader.read: error processing entry notes\n %s" % sys.exc_value 1399 err_mess = "cansas_reader.read: error processing entry notes\n" 1400 err_mess += " %s" % sys.exc_value 1301 1401 self.errors.append(err_mess) 1302 1402 logging.error(err_mess) … … 1308 1408 1309 1409 self._store_content('ns:SASsample/ns:ID', dom, 'ID', data_info.sample) 1310 self._store_float('ns:SASsample/ns:thickness', dom, 'thickness', data_info.sample) 1311 self._store_float('ns:SASsample/ns:transmission', dom, 'transmission', data_info.sample) 1312 self._store_float('ns:SASsample/ns:temperature', dom, 'temperature', data_info.sample) 1313 1314 nodes = dom.xpath('ns:SASsample/ns:details', namespaces={'ns': CANSAS_NS}) 1410 self._store_float('ns:SASsample/ns:thickness', dom, 'thickness', 1411 data_info.sample) 1412 self._store_float('ns:SASsample/ns:transmission', dom, 'transmission', 1413 data_info.sample) 1414 self._store_float('ns:SASsample/ns:temperature', dom, 'temperature', 1415 data_info.sample) 1416 1417 nodes = dom.xpath('ns:SASsample/ns:details', 1418 namespaces={'ns': CANSAS_NS}) 1315 1419 for item in nodes: 1316 1420 try: … … 1320 1424 data_info.sample.details.append(detail_value) 1321 1425 except Exception: 1322 err_mess = "cansas_reader.read: error processing sample details\n %s" % sys.exc_value 1426 err_mess = "cansas_reader.read: error processing entry notes\n" 1427 err_mess += " %s" % sys.exc_value 1323 1428 self.errors.append(err_mess) 1324 1429 logging.error(err_mess) 1325 1430 1326 1431 # Position (as a vector) 1327 self._store_float('ns:SASsample/ns:position/ns:x', dom, 'position.x', data_info.sample) 1328 self._store_float('ns:SASsample/ns:position/ns:y', dom, 'position.y', data_info.sample) 1329 self._store_float('ns:SASsample/ns:position/ns:z', dom, 'position.z', data_info.sample) 1432 self._store_float('ns:SASsample/ns:position/ns:x', dom, 'position.x', 1433 data_info.sample) 1434 self._store_float('ns:SASsample/ns:position/ns:y', dom, 'position.y', 1435 data_info.sample) 1436 self._store_float('ns:SASsample/ns:position/ns:z', dom, 'position.z', 1437 data_info.sample) 1330 1438 1331 1439 # Orientation (as a vector) … … 1461 1569 process.term.append(term_attr) 1462 1570 except: 1463 err_mess = "cansas_reader.read: error processing process term\n %s" % sys.exc_value 1571 err_mess = "cansas_reader.read: error processing " 1572 err_mess += "entry notes\n %s" % sys.exc_value 1464 1573 self.errors.append(err_mess) 1465 1574 logging.error(err_mess) … … 1476 1585 nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 1477 1586 if len(nodes) > 1: 1478 raise RuntimeError, "CanSAS reader is not compatible with multiple SASdata entries" 1587 raise RuntimeError, "CanSAS reader is not compatible with" + \ 1588 " multiple SASdata entries" 1479 1589 1480 1590 for entry in nodes: … … 1488 1598 value_list = [] 1489 1599 if field is not None: 1490 value_list = [parse_entry_helper(node, item) for node in field] 1600 value_list = \ 1601 [parse_entry_helper(node, item) for node in field] 1491 1602 if len(value_list) < 2: 1492 1603 setattr(data_info, item[0], None) … … 1498 1609 def _read_cansas(self, path): 1499 1610 """ 1500 Load data and P(r)information from a CanSAS XML file.1611 Load data and fitting information from a CanSAS XML file. 1501 1612 1502 1613 :param path: file path 1503 1504 1614 :return: Data1D object if a single SASentry was found, 1505 1615 or a list of Data1D objects if multiple entries were found, 1506 1616 or None of nothing was found 1507 1508 1617 :raise RuntimeError: when the file can't be opened 1509 1618 :raise ValueError: when the length of the data vectors are inconsistent 1510 1511 1619 """ 1512 1620 output = [] 1621 simfitstate = None 1513 1622 basename = os.path.basename(path) 1514 1623 root, extension = os.path.splitext(basename) … … 1516 1625 try: 1517 1626 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 1627 if ext in self.ext or ext == '.xml': 1524 1628 tree = etree.parse(path, parser=etree.ETCompatXMLParser()) 1525 1629 # Check the format version number 1526 # Specifying the namespace will take care of the file format version 1630 # Specifying the namespace will take care of the file 1631 # format version 1527 1632 root = tree.getroot() 1528 1633 entry_list = root.xpath('ns:SASentry', 1529 1634 namespaces={'ns': CANSAS_NS}) 1635 name_map = {} 1530 1636 for entry in entry_list: 1531 1637 try: … … 1535 1641 fitstate = self._parse_state(entry) 1536 1642 1537 # state could be None when .svs file is loaded1538 # in this case, skip appending to output1539 if fitstate !=None:1643 # state could be None when .svs file is loaded 1644 # in this case, skip appending to output 1645 if fitstate is not None: 1540 1646 sas_entry.meta_data['fitstate'] = fitstate 1541 1647 sas_entry.filename = fitstate.file 1542 1648 output.append(sas_entry) 1649 1543 1650 else: 1544 1651 self.call_back(format=ext) … … 1580 1687 name = original_fname 1581 1688 state.data.group_id = name 1582 # store state in fitting1689 # store state in fitting 1583 1690 self.call_back(state=state, 1584 1691 datainfo=output[ind], format=ext) 1585 1692 self.state = state 1693 simfitstate = self._parse_simfit_state(entry) 1694 if simfitstate is not None: 1695 self.call_back(state=simfitstate) 1696 1586 1697 return output 1587 1698 except: … … 1599 1710 """ 1600 1711 # Sanity check 1601 if self.cansas == True:1712 if self.cansas: 1602 1713 # Add fitting information to the XML document 1603 1714 doc = self.write_toXML(datainfo, fitstate) … … 1611 1722 fd.close() 1612 1723 1613 def write_toXML(self, datainfo=None, state=None ):1724 def write_toXML(self, datainfo=None, state=None, batchfit=None): 1614 1725 """ 1615 1726 Write toXML, a helper for write(), … … 1619 1730 """ 1620 1731 1621 if state.data is None:1622 data = sas.sascalc.dataloader.data_info.Data1D(x=[], y=[])1732 self.batchfit_params = batchfit 1733 if state.data is None or not state.data.is_data: 1623 1734 return None 1624 elif not state.data.is_data: 1625 return None 1735 # make sure title and data run are filled. 1736 if state.data.title is None or state.data.title == '': 1737 state.data.title = state.data.name 1738 if state.data.run_name is None or state.data.run_name == {}: 1739 state.data.run = [str(state.data.name)] 1740 state.data.run_name[0] = state.data.name 1741 1742 if issubclass(state.data.__class__, 1743 sas.sascalc.dataloader.data_info.Data1D): 1744 data = state.data 1745 doc, sasentry = self._to_xml_doc(data) 1626 1746 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) 1747 data = state.data 1748 doc, sasentry = self._data2d_to_xml_doc(data) 1641 1749 1642 1750 if state is not None: 1643 doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry) 1751 doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry, 1752 batch_fit_state=self.batchfit_params) 1644 1753 1645 1754 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 r998ca90 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 if fit.fit_panel.sim_page is None: 1054 fit.fit_panel.add_sim_page() 1055 sim_page = fit.fit_panel.sim_page 1056 1057 # Process each model and associate old M# with new M# 1058 i = 0 1059 for model in sim_page.model_list: 1060 model_id = self._format_id(model[1].keys()[0]) 1061 for saved_model in self.model_list: 1062 save_id = saved_model.pop('name') 1063 saved_model['name'] = save_id 1064 save_id = self._format_id(save_id) 1065 if save_id == model_id: 1066 model_map[saved_model.pop('fit_page_source')] = \ 1067 model[3].name 1068 check = bool(saved_model.pop('checked')) 1069 sim_page.model_list[i][0].SetValue(check) 1070 break 1071 i += 1 1072 sim_page.check_model_name(None) 1073 1074 if len(self.constraints_list) > 0: 1075 sim_page.hide_constraint.SetValue(False) 1076 sim_page.show_constraint.SetValue(True) 1077 sim_page._display_constraint(None) 1078 1079 for index, item in enumerate(self.constraints_list): 1080 model_cbox = item.pop('model_cbox') 1081 if model_cbox != "": 1082 constraint_value = item.pop('constraint') 1083 param = item.pop('param_cbox') 1084 equality = item.pop('egal_txt') 1085 for key, value in model_map.iteritems(): 1086 model_cbox.replace(key, value) 1087 constraint_value.replace(key, value) 1088 1089 sim_page.constraints_list[index][0].SetValue(model_cbox) 1090 sim_page._on_select_model(None) 1091 sim_page.constraints_list[index][1].SetValue(param) 1092 sim_page.constraints_list[index][2].SetLabel(equality) 1093 sim_page.constraints_list[index][3].SetValue(constraint_value) 1094 sim_page._on_add_constraint(None) 1095 1096 def _format_id(self, original_id): 1097 original_id = original_id.rstrip('1234567890.') 1098 new_id_list = original_id.split() 1099 new_id = ' '.join(new_id_list) 1100 return new_id -
src/sas/sasgui/perspectives/fitting/fitpage.py
r4c3be25 r7988501 55 55 self.weightbt_string = None 56 56 self.m_name = None 57 # transform implementation 58 self._fill_Trafo_sizer() 59 # self.Trafobt_string() 57 60 # get smear info from data 58 61 self._get_smear_info() … … 92 95 self.parent.on_set_focus(event) 93 96 self.on_tap_focus() 97 98 def onTrafo(self, event): 99 """ 100 On Trafo radio button event, sets the Trafobt_string 101 """ 102 self.Trafobt_string = event.GetEventObject().GetLabelText() 103 self._set_Trafo() 104 105 def _fill_Trafo_sizer(self): 106 107 title = "Transform" 108 box_description_trafo = wx.StaticBox(self, wx.ID_ANY, str(title)) 109 box_description_trafo.SetForegroundColour(wx.BLUE) 110 #boxsizer_trafo = wx.StaticBoxSizer(box_description_trafo, wx.VERTICAL) 111 boxsizer_trafo = wx.StaticBoxSizer(box_description_trafo, wx.HORIZONTAL) 112 #sizer_trafo = wx.StaticBoxSizer(box_description_trafo, wx.HORIZONTAL) 113 #weighting_set_box = wx.StaticBox(self, wx.ID_ANY, 114 # 'Select the type of SESANS analysis') 115 116 #sizer_weighting = wx.BoxSizer(wx.HORIZONTAL) 117 # weighting_box.SetMinSize((_DATA_BOX_WIDTH, 60)) 118 119 #For every radio button (each statement x3): 120 self.no_transform = wx.RadioButton(self, wx.ID_ANY, 121 'None', style=wx.RB_GROUP) 122 123 #self.Bind(wx.EVT_RADIOBUTTON, self.onTrafo, 124 # id=self.no_transform.GetId()) 125 self.hankel = wx.RadioButton(self, wx.ID_ANY, 126 'Hankel') 127 #self.Bind(wx.EVT_RADIOBUTTON, self.onTrafo, 128 # id=self.hankel.GetId()) 129 self.cosine = wx.RadioButton(self, wx.ID_ANY, 130 'Cosine') 131 #self.Bind(wx.EVT_RADIOBUTTON, self.onTrafo, 132 # id=self.cosine.GetId()) 133 134 #Not sure about this (only once though) 135 self.no_transform.SetValue(True) 136 137 #For every radio button (each statement x3): 138 boxsizer_trafo.Add(self.no_transform, 0, wx.LEFT, 10) 139 boxsizer_trafo.Add((14, 10)) 140 boxsizer_trafo.Add(self.hankel) 141 boxsizer_trafo.Add((14, 10)) 142 boxsizer_trafo.Add(self.cosine) 143 boxsizer_trafo.Add((14, 10)) 144 #Default for weighting is False, but these need to be on by default! 145 self.no_transform.Enable(True) 146 147 #Not sure about this (only once though) 148 #weighting_box.Add(sizer_trafo) 149 150 self.sizerTrafo.Clear(True) 151 self.sizerTrafo.Add(boxsizer_trafo, 0, wx.EXPAND | wx.ALL, 10) 152 #self.sizerTrafo.Add(sizer_trafo, 0, wx.EXPAND | wx.ALL, 10) 153 self.sizerTrafo.Layout() 94 154 95 155 def _fill_data_sizer(self): … … 624 684 ## fill a sizer with the combobox to select dispersion type 625 685 model_disp = wx.StaticText(self, wx.ID_ANY, 'Function') 626 CHECK_STATE = False686 CHECK_STATE = self.cb1.GetValue() 627 687 628 688 ix = 0 … … 969 1029 self.state.model = self.model.clone() 970 1030 ## save state into 1031 self.state.cb1 = self.cb1.GetValue() 971 1032 self._copy_parameters_state(self.parameters, self.state.parameters) 972 1033 self._copy_parameters_state(self.orientation_params_disp, … … 979 1040 StatusEvent(status=" Selected Distribution: Gaussian")) 980 1041 #Fill the list of fittable parameters 1042 #self.select_all_param(event=None) 981 1043 self.get_all_checked_params() 982 1044 self.Layout() … … 2693 2755 self._manager.set_param2fit(self.uid, param2fit) 2694 2756 2757 def select_all_param(self, event): 2758 """ 2759 set to true or false all checkBox given the main checkbox value cb1 2760 """ 2761 self.param_toFit = [] 2762 if self.parameters != []: 2763 if self.cb1.GetValue(): 2764 for item in self.parameters: 2765 if item[0].IsShown(): 2766 ## for data2D select all to fit 2767 if self.data.__class__.__name__ == "Data2D" or \ 2768 self.enable2D: 2769 item[0].SetValue(True) 2770 self.param_toFit.append(item) 2771 else: 2772 ## for 1D all parameters except orientation 2773 if not item in self.orientation_params: 2774 item[0].SetValue(True) 2775 self.param_toFit.append(item) 2776 else: 2777 item[0].SetValue(False) 2778 #if len(self.fittable_param)>0: 2779 for item in self.fittable_param: 2780 if item[0].IsShown(): 2781 if self.data.__class__.__name__ == "Data2D" or \ 2782 self.enable2D: 2783 item[0].SetValue(True) 2784 self.param_toFit.append(item) 2785 try: 2786 if len(self.values[item[1]]) > 0: 2787 item[0].SetValue(False) 2788 except: 2789 pass 2790 2791 else: 2792 ## for 1D all parameters except orientation 2793 if not item in self.orientation_params_disp: 2794 item[0].SetValue(True) 2795 self.param_toFit.append(item) 2796 try: 2797 if len(self.values[item[1]]) > 0: 2798 item[0].SetValue(False) 2799 except: 2800 pass 2801 else: 2802 item[0].SetValue(False) 2803 2804 else: 2805 for item in self.parameters: 2806 item[0].SetValue(False) 2807 for item in self.fittable_param: 2808 item[0].SetValue(False) 2809 self.param_toFit = [] 2810 2811 self.save_current_state_fit() 2812 2813 if event != None: 2814 #self._undo.Enable(True) 2815 ## post state to fit panel 2816 event = PageInfoEvent(page=self) 2817 wx.PostEvent(self.parent, event) 2818 param2fit = [] 2819 for item in self.param_toFit: 2820 if item[0] and item[0].IsShown(): 2821 param2fit.append(item[1]) 2822 self.parent._manager.set_param2fit(self.uid, param2fit) 2823 2695 2824 def select_param(self, event): 2696 2825 """ … … 2739 2868 if len(self.fittable_param) > 0: 2740 2869 len_orient_para *= 2 2870 #Set the value of checkbox that selected every checkbox or not 2871 if len(self.parameters) + len(self.fittable_param) - len_orient_para \ 2872 == len(self.param_toFit): 2873 self.cb1.SetValue(True) 2874 else: 2875 self.cb1.SetValue(False) 2741 2876 2742 2877 self.save_current_state_fit() … … 2840 2975 iy = 0 2841 2976 ix = 0 2842 sizer.Add(wx.StaticText(self, wx.ID_ANY, 'Parameter'), 2843 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 2977 select_text = "Select All" 2978 self.cb1 = wx.CheckBox(self, wx.ID_ANY, str(select_text), (10, 10)) 2979 wx.EVT_CHECKBOX(self, self.cb1.GetId(), self.select_all_param) 2980 self.cb1.SetToolTipString("To check/uncheck all the boxes below.") 2981 self.cb1.SetValue(True) 2982 2983 sizer.Add(self.cb1, (iy, ix), (1, 1), \ 2984 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 5) 2844 2985 ix += 1 2845 2986 self.text2_2 = wx.StaticText(self, wx.ID_ANY, 'Value') … … 2868 3009 self.text2_4.Hide() 2869 3010 2870 CHECK_STATE = False3011 CHECK_STATE = self.cb1.GetValue() 2871 3012 for item in keys: 2872 3013
Note: See TracChangeset
for help on using the changeset viewer.