Changeset f32d144 in sasview for fittingview/src/sans/perspectives/fitting/fitting.py
- Timestamp:
- Apr 27, 2012 4:20:33 PM (13 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, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- f992a06
- Parents:
- 9e07bc4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fittingview/src/sans/perspectives/fitting/fitting.py
ra5f6748 rf32d144 2 2 Fitting perspective 3 3 """ 4 5 4 ################################################################################ 6 5 #This software was developed by the University of Tennessee as part of the 7 6 #Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 8 #project funded by the US National Science Foundation. 7 #project funded by the US National Science Foundation. 9 8 # 10 9 #See the license text in license.txt … … 12 11 #copyright 2009, University of Tennessee 13 12 ################################################################################ 14 15 16 13 import re 17 14 import sys … … 48 45 SANS_F_TOL = 5e-05 49 46 50 (PageInfoEvent, EVT_PAGE_INFO) 51 52 53 if sys.platform.count("darwin") ==0:47 (PageInfoEvent, EVT_PAGE_INFO) = wx.lib.newevent.NewEvent() 48 49 50 if sys.platform.count("darwin") == 0: 54 51 ON_MAC = False 55 52 else: 56 ON_MAC = True 53 ON_MAC = True 54 57 55 58 56 class Plugin(PluginBase): 59 57 """ 60 Fitting plugin is used to perform fit 58 Fitting plugin is used to perform fit 61 59 """ 62 60 def __init__(self, standalone=False): … … 78 76 self.elapsed = 0.022 79 77 # the type of optimizer selected, park or scipy 80 self.fitter 78 self.fitter = None 81 79 self.fit_panel = None 82 80 #let fit ready … … 84 82 #Flag to let the plug-in know that it is running stand alone 85 83 self.standalone = True 86 ## dictionary of page closed and id 84 ## dictionary of page closed and id 87 85 self.closed_page_dict = {} 88 86 ## Fit engine … … 106 104 self.test_model_color = None 107 105 #Create a reader for fit page's state 108 self.state_reader = None 106 self.state_reader = None 109 107 self._extensions = '.fitv' 110 108 self.scipy_id = wx.NewId() … … 119 117 self.page_finder = {} 120 118 # Log startup 121 logging.info("Fitting plug-in started") 119 logging.info("Fitting plug-in started") 122 120 self.batch_capable = self.get_batch_capable() 123 121 … … 169 167 id1 = wx.NewId() 170 168 simul_help = "Add new fit panel" 171 self.menu1.Append(id1, '&New Fit Page', simul_help)169 self.menu1.Append(id1, '&New Fit Page', simul_help) 172 170 wx.EVT_MENU(owner, id1, self.on_add_new_page) 173 171 self.menu1.AppendSeparator() 174 172 self.id_simfit = wx.NewId() 175 173 simul_help = "Simultaneous Fit" 176 self.menu1.Append(self.id_simfit, '&Simultaneous Fit', simul_help)174 self.menu1.Append(self.id_simfit, '&Simultaneous Fit', simul_help) 177 175 wx.EVT_MENU(owner, self.id_simfit, self.on_add_sim_page) 178 176 self.sim_menu = self.menu1.FindItemById(self.id_simfit) 179 self.sim_menu.Enable(False) 177 self.sim_menu.Enable(False) 180 178 #combined Batch 181 179 self.id_batchfit = wx.NewId() 182 180 batch_help = "Combined Batch" 183 181 self.menu1.Append(self.id_batchfit, '&Combine Batch Fit', batch_help) 184 wx.EVT_MENU(owner, self.id_batchfit, 182 wx.EVT_MENU(owner, self.id_batchfit, self.on_add_sim_page) 185 183 self.batch_menu = self.menu1.FindItemById(self.id_batchfit) 186 self.batch_menu.Enable(False) 184 self.batch_menu.Enable(False) 187 185 self.menu1.AppendSeparator() 188 186 #Set park engine 189 187 scipy_help = "Scipy Engine: Perform Simple fit. More in Help window...." 190 188 self.menu1.AppendCheckItem(self.scipy_id, "Simple FitEngine [LeastSq]", 191 scipy_help) 192 wx.EVT_MENU(owner, self.scipy_id, 189 scipy_help) 190 wx.EVT_MENU(owner, self.scipy_id, self._onset_engine_scipy) 193 191 194 192 park_help = "Park Engine: Perform Complex fit. More in Help window...." 195 193 self.menu1.AppendCheckItem(self.park_id, "Complex FitEngine [ParkMC]", 196 park_help) 197 wx.EVT_MENU(owner, self.park_id, 194 park_help) 195 wx.EVT_MENU(owner, self.park_id, self._onset_engine_park) 198 196 199 197 self.menu1.FindItemById(self.scipy_id).Check(True) … … 202 200 self.id_tol = wx.NewId() 203 201 ftol_help = "Change the current FTolerance (=%s) " % str(self.ftol) 204 ftol_help += "of Simple FitEngine..." 205 self.menu1.Append(self.id_tol, "Change FTolerance", 206 ftol_help) 207 wx.EVT_MENU(owner, self.id_tol, 202 ftol_help += "of Simple FitEngine..." 203 self.menu1.Append(self.id_tol, "Change FTolerance", 204 ftol_help) 205 wx.EVT_MENU(owner, self.id_tol, self.show_ftol_dialog) 208 206 self.menu1.AppendSeparator() 209 207 210 208 self.id_reset_flag = wx.NewId() 211 209 resetf_help = "BatchFit: If checked, the initial param values will be " 212 resetf_help += "propagated from the previous results. " 210 resetf_help += "propagated from the previous results. " 213 211 resetf_help += "Otherwise, the same initial param values will be used " 214 resetf_help += "for all fittings." 215 self.menu1.AppendCheckItem(self.id_reset_flag, 216 "Chain Fitting [BatchFit Only]", 217 resetf_help) 218 wx.EVT_MENU(owner, self.id_reset_flag, 212 resetf_help += "for all fittings." 213 self.menu1.AppendCheckItem(self.id_reset_flag, 214 "Chain Fitting [BatchFit Only]", 215 resetf_help) 216 wx.EVT_MENU(owner, self.id_reset_flag, self.on_reset_batch_flag) 219 217 chain_menu = self.menu1.FindItemById(self.id_reset_flag) 220 218 chain_menu.Check(not self.batch_reset_flag) … … 230 228 231 229 self.id_edit = wx.NewId() 232 editmodel_help = "Edit customized model sample file" 233 self.menu1.AppendMenu(self.id_edit, "Edit Custom Model", 230 editmodel_help = "Edit customized model sample file" 231 self.menu1.AppendMenu(self.id_edit, "Edit Custom Model", 234 232 self.edit_model_menu, editmodel_help) 235 233 #create menubar items … … 244 242 from sans.perspectives.calculator.pyconsole import PyConsole 245 243 filename = os.path.join(models.find_plugins_dir(), label) 246 frame = PyConsole(parent=self.parent, manager=self, panel= self.fit_panel, 247 title='Advanced Custom Model Editor', filename=filename) 244 frame = PyConsole(parent=self.parent, manager=self, 245 panel=self.fit_panel, 246 title='Advanced Custom Model Editor', 247 filename=filename) 248 248 self.put_icon(frame) 249 frame.Show(True) 249 frame.Show(True) 250 250 251 251 def delete_custom_model(self, event): … … 276 276 """ 277 277 id = event.GetId() 278 model_list = []279 278 model_manager = models.ModelManager() 280 279 model_list = model_manager.get_model_name_list() … … 283 282 model_list, plug_dir) 284 283 self.put_icon(textdial) 285 dial = textdial.ShowModal() 286 284 textdial.ShowModal() 287 285 textdial.Destroy() 288 286 289 287 def make_new_model(self, event): 290 288 """ 291 Make new model 289 Make new model 292 290 """ 293 291 if self.new_model_frame != None and self.new_model_frame.IsShown(): … … 297 295 dir_path = models.find_plugins_dir() 298 296 title = "New Custom Model Function" 299 self.new_model_frame = EditorWindow(parent=self, base=self, 297 self.new_model_frame = EditorWindow(parent=self, base=self, 300 298 path=dir_path, title=title) 301 299 self.put_icon(self.new_model_frame) … … 328 326 329 327 330 def set_edit_menu(self, owner): 328 def set_edit_menu(self, owner): 331 329 """ 332 330 Set list of the edit model menu labels … … 334 332 id = wx.NewId() 335 333 #new_model_menu = wx.Menu() 336 self.edit_model_menu.Append(id, 'New', 337 'Add a new model function')#, 338 #new_model_menu) 339 wx.EVT_MENU(owner, id, self.make_new_model) 334 self.edit_model_menu.Append(id, 'New', 335 'Add a new model function') 336 wx.EVT_MENU(owner, id, self.make_new_model) 340 337 id = wx.NewId() 341 self.edit_model_menu.Append(id, 'Sum(p1, p2)', 342 'Sum of two model functions') 343 wx.EVT_MENU(owner, id, 338 self.edit_model_menu.Append(id, 'Sum(p1, p2)', 339 'Sum of two model functions') 340 wx.EVT_MENU(owner, id, self.make_sum_model) 344 341 e_id = wx.NewId() 345 self.edit_menu = wx.Menu()342 self.edit_menu = wx.Menu() 346 343 self.edit_model_menu.AppendMenu(e_id, 347 344 'Advanced', self.edit_menu) … … 349 346 350 347 d_id = wx.NewId() 351 self.delete_menu = wx.Menu()352 self.edit_model_menu.AppendMenu(d_id, 353 'Delete', self.delete_menu)348 self.delete_menu = wx.Menu() 349 self.edit_model_menu.AppendMenu(d_id, 350 'Delete', self.delete_menu) 354 351 self.set_edit_menu_helper(owner, self.delete_custom_model) 355 352 … … 365 362 name = os.path.basename(f_item) 366 363 toks = os.path.splitext(name) 367 if toks[-1] =='.py' and not toks[0] =='__init__':364 if toks[-1] == '.py' and not toks[0] == '__init__': 368 365 if menu == self.edit_custom_model: 369 if toks[0] == 'easy_sum_of_p1_p2':366 if toks[0] == 'easy_sum_of_p1_p2': 370 367 continue 371 368 submenu = self.edit_menu 372 369 else: 373 370 submenu = self.delete_menu 374 #name = toks[0]375 371 has_file = False 376 372 for item in submenu.GetMenuItems(): … … 379 375 if not has_file: 380 376 id = wx.NewId() 381 submenu.Append(id, name) 382 wx.EVT_MENU(owner, id, 377 submenu.Append(id, name) 378 wx.EVT_MENU(owner, id, menu) 383 379 has_file = False 384 380 … … 393 389 frame.SetIcon(icon) 394 390 except: 395 pass 396 391 pass 392 397 393 def on_add_sim_page(self, event): 398 394 """ … … 423 419 def help(self, evt): 424 420 """ 425 Show a general help dialog. 421 Show a general help dialog. 426 422 """ 427 423 from help_panel import HelpWindow 428 frame = HelpWindow(None, -1, 'HelpWindow') 424 frame = HelpWindow(None, -1, 'HelpWindow') 429 425 if hasattr(frame, "IsIconized"): 430 426 if not frame.IsIconized(): … … 433 429 frame.SetIcon(icon) 434 430 except: 435 pass 431 pass 436 432 frame.Show(True) 437 433 … … 445 441 :return: a list of menu items with call-back function 446 442 447 :note: if Data1D was generated from Theory1D 443 :note: if Data1D was generated from Theory1D 448 444 the fitting option is not allowed 449 445 … … 456 452 return [] 457 453 item = plotpanel.plots[graph.selected_plottable] 458 if item.__class__.__name__ is "Data2D": 459 if hasattr(item, "is_data"):454 if item.__class__.__name__ is "Data2D": 455 if hasattr(item, "is_data"): 460 456 if item.is_data: 461 457 return [[fit_option, fit_hint, self._onSelect]] … … 467 463 # if is_data is true , this in an actual data loaded 468 464 #else it is a data created from a theory model 469 if hasattr(item, "is_data"):465 if hasattr(item, "is_data"): 470 466 if item.is_data: 471 return [[fit_option, fit_hint, 472 self._onSelect]] 467 return [[fit_option, fit_hint, self._onSelect]] 473 468 else: 474 return [] 475 return [] 476 469 return [] 470 return [] 477 471 478 472 def get_panels(self, parent): … … 493 487 #index number to create random model name 494 488 self.index_model = 0 495 self.index_theory = 0489 self.index_theory = 0 496 490 self.parent.Bind(EVT_SLICER_PANEL, self._on_slicer_event) 497 491 self.parent.Bind(EVT_SLICER_PARS_UPDATE, self._onEVT_SLICER_PANEL) 498 self.parent._mgr.Bind(wx.aui.EVT_AUI_PANE_CLOSE,self._onclearslicer) 492 self.parent._mgr.Bind(wx.aui.EVT_AUI_PANE_CLOSE,self._onclearslicer) 499 493 #Create reader when fitting panel are created 500 self.state_reader = Reader(self.set_state) 501 #append that reader to list of available reader 494 self.state_reader = Reader(self.set_state) 495 #append that reader to list of available reader 502 496 loader = Loader() 503 497 loader.associate_file_reader(".fitv", self.state_reader) 504 #loader.associate_file_reader(".svs", self.state_reader)505 #from sans.perspectives.calculator.sld_panel import SldPanel506 498 #Send the fitting panel to guiframe 507 self.mypanels.append(self.fit_panel) 508 #self.mypanels.append(SldPanel(parent=self.parent, base=self.parent)) 499 self.mypanels.append(self.fit_panel) 509 500 return self.mypanels 510 501 … … 517 508 """ 518 509 Call back method that True to notify the parent that the current plug-in 519 can be set as default 520 when returning False, the plug-in is not candidate for an automatic 510 can be set as default perspective. 511 when returning False, the plug-in is not candidate for an automatic 521 512 default perspective setting 522 513 """ … … 571 562 572 563 573 def set_theory(self, 564 def set_theory(self, theory_list=None): 574 565 """ 575 566 """ … … 582 573 msg = "Fitting: cannot deal with the theory received" 583 574 logging.error("set_theory " + msg + "\n" + str(sys.exc_value)) 584 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 575 wx.PostEvent(self.parent, 576 StatusEvent(status=msg, info="error")) 585 577 586 578 def set_state(self, state=None, datainfo=None, format=None): … … 596 588 state = state.clone() 597 589 # store fitting state in temp_state 598 self.temp_state.append(state) 590 self.temp_state.append(state) 599 591 else: 600 592 self.temp_state = [] … … 606 598 self.on_set_state_helper(event=None) 607 599 608 def on_set_state_helper(self, event=None):609 """ 610 Set_state_helper. This actually sets state 600 def on_set_state_helper(self, event=None): 601 """ 602 Set_state_helper. This actually sets state 611 603 after plotting data from state file. 612 604 613 : event: FitStateUpdateEvent called 605 : event: FitStateUpdateEvent called 614 606 by dataloader.plot_data from guiframe 615 607 """ 616 608 if len(self.temp_state) == 0: 617 if self.state_index ==0 and len(self.mypanels) <= 0 \618 and self.sfile_ext == '.svs':609 if self.state_index == 0 and len(self.mypanels) <= 0 \ 610 and self.sfile_ext == '.svs': 619 611 #TODO: Why was the following line left in the code 620 612 # if add_default_pages doesn't exist? … … 635 627 data = self.parent.create_gui_data(state.data) 636 628 data.group_id = state.data.group_id 637 self.parent.add_data(data_list={data.id: data})629 self.parent.add_data(data_list={data.id: data}) 638 630 wx.PostEvent(self.parent, NewPlotEvent(plot=data, 639 631 title=data.title)) … … 641 633 #to panel 642 634 state.data = data 643 page = self.fit_panel.set_state(state) 635 page = self.fit_panel.set_state(state) 644 636 else: 645 637 #just set data because set_state won't work 646 638 data = self.parent.create_gui_data(state.data) 647 639 data.group_id = state.data.group_id 648 self.parent.add_data(data_list={data.id: data})640 self.parent.add_data(data_list={data.id: data}) 649 641 wx.PostEvent(self.parent, NewPlotEvent(plot=data, 650 642 title=data.title)) 651 643 page = self.add_fit_page([data]) 652 644 caption = page.window_caption 653 self.store_data(uid=page.uid, data_list=page.get_data_list(), 645 self.store_data(uid=page.uid, data_list=page.get_data_list(), 654 646 caption=caption) 655 self.mypanels.append(page) 647 self.mypanels.append(page) 656 648 657 649 # get ready for the next set_state 658 650 self.state_index += 1 659 651 660 #reset state variables to default when all set_state is finished. 652 #reset state variables to default when all set_state is finished. 661 653 if len(self.temp_state) == self.state_index: 662 654 … … 664 656 #self.state_index = 0 665 657 # Make sure the user sees the fitting panel after loading 666 #self.parent.set_perspective(self.perspective) 658 #self.parent.set_perspective(self.perspective) 667 659 self.on_perspective(event=None) 668 660 except: 669 self.state_index ==0661 self.state_index = 0 670 662 self.temp_state = [] 671 663 raise … … 687 679 Set graph_id for fitprobelm 688 680 """ 689 return self.page_finder[uid].get_graph_id() 681 return self.page_finder[uid].get_graph_id() 690 682 691 def save_fit_state(self, filepath, fitstate): 683 def save_fit_state(self, filepath, fitstate): 692 684 """ 693 685 save fit page state into file … … 698 690 """ 699 691 Set the fit weights of a given page for all 700 its data by default. If fid is provide then set the range 692 its data by default. If fid is provide then set the range 701 693 only for the data with fid as id 702 694 :param uid: id corresponding to a fit page … … 710 702 """ 711 703 Set the fitting range of a given page for all 712 its data by default. If fid is provide then set the range 704 its data by default. If fid is provide then set the range 713 705 only for the data with fid as id 714 706 :param uid: id corresponding to a fit page … … 720 712 self.page_finder[uid].set_range(qmin=qmin, qmax=qmax, fid=fid) 721 713 722 def schedule_for_fit(self, value=0, uid=None): 714 def schedule_for_fit(self, value=0, uid=None): 723 715 """ 724 716 Set the fit problem field to 0 or 1 to schedule that problem to fit. 725 Schedule the specified fitproblem or get the fit problem related to 717 Schedule the specified fitproblem or get the fit problem related to 726 718 the current page and set value. 727 :param value: integer 0 or 1 719 :param value: integer 0 or 1 728 720 :param uid: the id related to a page contaning fitting information 729 721 """ 730 if uid in self.page_finder.keys(): 722 if uid in self.page_finder.keys(): 731 723 self.page_finder[uid].schedule_tofit(value) 732 724 … … 734 726 """ 735 727 return self.page_finder used also by simfitpage.py 736 """ 737 return self.page_finder 728 """ 729 return self.page_finder 738 730 739 def set_page_finder(self, modelname,names,values):731 def set_page_finder(self, modelname, names, values): 740 732 """ 741 733 Used by simfitpage.py to reset a parameter given the string constrainst. 742 734 743 :param modelname: the name ot the model for with the parameter 735 :param modelname: the name ot the model for with the parameter 744 736 has to reset 745 737 :param value: can be a string in this case. … … 748 740 :note: expecting park used for fit. 749 741 750 """ 742 """ 751 743 sim_page_id = self.sim_page.uid 752 744 for uid, value in self.page_finder.iteritems(): … … 758 750 break 759 751 760 def split_string(self, item):752 def split_string(self, item): 761 753 """ 762 754 receive a word containing dot and split it. used to split parameterset … … 769 761 if item.find(".") >= 0: 770 762 param_names = re.split("\.", item) 771 model_name = param_names[0] 763 model_name = param_names[0] 772 764 ##Assume max len is 3; eg., M0.radius.width 773 765 if len(param_names) == 3: 774 766 param_name = param_names[1] + "." + param_names[2] 775 767 else: 776 param_name = param_names[1] 768 param_name = param_names[1] 777 769 return model_name, param_name 778 770 779 771 def set_ftol(self, ftol=None): 780 772 """ 781 Set ftol: Relative error desired in the sum of chi squares. 773 Set ftol: Relative error desired in the sum of chi squares. 782 774 """ 783 775 # check if it is flaot … … 791 783 # update ftol menu help strings 792 784 ftol_help = "Change the current FTolerance (=%s) " % str(self.ftol) 793 ftol_help += "of Simple FitEngine..." 785 ftol_help += "of Simple FitEngine..." 794 786 if self.menu1 != None: 795 787 self.menu1.SetHelpString(self.id_tol, ftol_help) … … 839 831 :param qmax: the maximum value of the theory plotting range 840 832 :param draw: Determine if the theory needs to be plot 841 """ 833 """ 842 834 if uid not in self.page_finder.keys(): 843 835 return … … 846 838 if draw: 847 839 ## draw model 1D with smeared data 848 data = 840 data = self.page_finder[uid].get_fit_data(fid=fid) 849 841 if data is None: 850 842 msg = "set_mearer requires at least data.\n" … … 874 866 """ 875 867 if ON_MAC: 876 time.sleep(sec)868 time.sleep(sec) 877 869 878 870 def draw_model(self, model, page_id, data=None, smearer=None, … … 881 873 fid=None, 882 874 toggle_mode_on=False, 883 qmin=None, qmax=None, 875 qmin=None, qmax=None, 884 876 update_chisqr=True, weight=None, source='model'): 885 877 """ … … 899 891 """ 900 892 #self.weight = weight 901 if issubclass(data.__class__, Data1D) or not enable2D: 893 if issubclass(data.__class__, Data1D) or not enable2D: 902 894 ## draw model 1D with no loaded data 903 self._draw_model1D(model=model, 895 self._draw_model1D(model=model, 904 896 data=data, 905 897 page_id=page_id, 906 enable1D=enable1D, 898 enable1D=enable1D, 907 899 smearer=smearer, 908 900 qmin=qmin, 909 qmax=qmax, 901 qmax=qmax, 910 902 fid=fid, 911 903 weight=weight, … … 914 906 update_chisqr=update_chisqr, 915 907 source=source) 916 else: 908 else: 917 909 ## draw model 2D with no initial data 918 910 self._draw_model2D(model=model, … … 933 925 """ 934 926 Get series of data, model, associates parameters and range and send then 935 to series of fit engines. Fit data and model, display result to 936 corresponding panels. 927 to series of fit engines. Fit data and model, display result to 928 corresponding panels. 937 929 :param uid: id related to the panel currently calling this fit function. 938 930 """ 939 931 flag = True 940 ## count the number of fitproblem schedule to fit 932 ## count the number of fitproblem schedule to fit 941 933 fitproblem_count = 0 942 934 for value in self.page_finder.values(): 943 935 if value.get_scheduled() == 1: 944 936 fitproblem_count += 1 945 self._gui_engine = self._return_engine_type() 946 self.fitproblem_count = fitproblem_count 937 self._gui_engine = self._return_engine_type() 938 self.fitproblem_count = fitproblem_count 947 939 if self._fit_engine == "park": 948 940 engineType = "Simultaneous Fit" 949 941 else: 950 942 engineType = "Single Fit" 951 fitter_list = [] 952 sim_fitter = None 943 fitter_list = [] 944 sim_fitter = None 953 945 is_single_fit = True 954 946 batch_on = False 955 947 if self.sim_page is not None and self.sim_page.uid == uid: 956 #simulatanous fit only one engine need to be created 948 #simulatanous fit only one engine need to be created 957 949 ## if simultaneous fit change automatically the engine to park 958 self._on_change_engine(engine='park') 959 sim_fitter = Fit(self._fit_engine) 950 self._on_change_engine(engine='park') 951 sim_fitter = Fit(self._fit_engine) 960 952 sim_fitter.fitter_id = self.sim_page.uid 961 fitter_list.append(sim_fitter) 953 fitter_list.append(sim_fitter) 962 954 is_single_fit = False 963 955 batch_on = self.sim_page.batch_on 964 956 965 966 self.fitproblem_count = fitproblem_count 957 self.fitproblem_count = fitproblem_count 967 958 if self._fit_engine == "park": 968 959 engineType = "Simultaneous Fit" … … 990 981 templist = [] 991 982 page = self.fit_panel.get_page_by_id(page_id) 992 self.set_fit_weight(uid=page.uid, 983 self.set_fit_weight(uid=page.uid, 993 984 flag=page.get_weight_flag(), 994 is2d =page._is_2D())985 is2d=page._is_2D()) 995 986 templist = page.get_param_list() 996 flag = page._update_paramv_on_fit() 987 flag = page._update_paramv_on_fit() 997 988 if not flag: 998 989 msg = "Fitting range or parameter values are" 999 msg += " invalid in %s" % \990 msg += " invalid in %s" % \ 1000 991 page.window_caption 1001 wx.PostEvent(page.parent.parent, 1002 StatusEvent(status= 992 wx.PostEvent(page.parent.parent, 993 StatusEvent(status=msg, info="error", 1003 994 type="stop")) 1004 995 return flag … … 1009 1000 for fitproblem in fitproblem_list: 1010 1001 if sim_fitter is None: 1011 fitter = Fit(self._fit_engine) 1002 fitter = Fit(self._fit_engine) 1012 1003 fitter.fitter_id = page_id 1013 self._fit_helper(fitproblem=fitproblem, 1014 pars=pars,1015 1016 fit_id=fit_id,1017 1018 1019 fitter_list.append(fitter) 1004 self._fit_helper(fitproblem=fitproblem, 1005 pars=pars, 1006 fitter=fitter, 1007 fit_id=fit_id, 1008 batch_inputs=batch_inputs, 1009 batch_outputs=batch_outputs) 1010 fitter_list.append(fitter) 1020 1011 else: 1021 1012 fitter = sim_fitter 1022 self._fit_helper(fitproblem=fitproblem, 1023 pars=pars,1024 1025 fit_id=fit_id,1026 1027 1013 self._fit_helper(fitproblem=fitproblem, 1014 pars=pars, 1015 fitter=fitter, 1016 fit_id=fit_id, 1017 batch_inputs=batch_inputs, 1018 batch_outputs=batch_outputs) 1028 1019 fit_id += 1 1029 1020 list_page_id.append(page_id) … … 1032 1023 except: 1033 1024 flag = False 1034 msg = "%s error: %s" % (engineType, sys.exc_value)1025 msg = "%s error: %s" % (engineType, sys.exc_value) 1035 1026 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error", 1036 1027 type="stop")) … … 1040 1031 # self.calc_fit.stop() 1041 1032 msg = "Fitting is in progress..." 1042 wx.PostEvent( self.parent, StatusEvent(status=msg, type="progress"))1033 wx.PostEvent(self.parent, StatusEvent(status=msg, type="progress")) 1043 1034 1044 1035 #Handler used for park engine displayed message … … 1053 1044 except: 1054 1045 try: 1055 #if the id cannot be found then we deal with a self.sim_page 1046 #if the id cannot be found then we deal with a self.sim_page 1056 1047 #or a self.batch_page 1057 1048 if self.sim_page is not None and uid == self.sim_page.uid: … … 1060 1051 batch_on = self.batch_page.batch_on 1061 1052 except: 1062 batch_on = False 1063 #raise 1064 1053 batch_on = False 1054 1065 1055 # batch fit 1066 1056 if batch_on: 1067 calc_fit = FitThread(handler =handler,1068 1069 1070 1071 1072 1073 1074 1075 1057 calc_fit = FitThread(handler=handler, 1058 fn=fitter_list, 1059 pars=pars, 1060 batch_inputs=batch_inputs, 1061 batch_outputs=batch_outputs, 1062 page_id=list_page_id, 1063 completefn=self._batch_fit_complete, 1064 ftol=self.ftol, 1065 reset_flag=self.batch_reset_flag) 1076 1066 else: 1077 # single fit: not batch and not simul fit 1067 # single fit: not batch and not simul fit 1078 1068 if not is_single_fit: 1079 1069 current_page_id = self.sim_page.uid … … 1090 1080 calc_fit.queue() 1091 1081 msg = "Fitting is in progress..." 1092 wx.PostEvent( self.parent, StatusEvent(status=msg, type="progress"))1082 wx.PostEvent(self.parent, StatusEvent(status=msg, type="progress")) 1093 1083 1094 1084 self.ready_fit(calc_fit=calc_fit) … … 1123 1113 group_id = data.group_id 1124 1114 wx.PostEvent(self.parent, NewPlotEvent(id=plot_id, 1125 1126 1115 group_id=group_id, 1116 action='remove')) 1127 1117 1128 1118 def store_data(self, uid, data_list=None, caption=None): … … 1147 1137 try: 1148 1138 page = self.fit_panel.add_empty_page() 1149 page_caption = page.window_caption1150 1139 # add data associated to the page created 1151 if page != None: 1140 if page != None: 1152 1141 wx.PostEvent(self.parent, StatusEvent(status="Page Created", 1153 1142 info="info")) … … 1171 1160 if page == None: 1172 1161 return page 1173 page_caption = page.window_caption1174 1162 #append Data1D to the panel containing its theory 1175 1163 #if theory already plotted … … 1181 1169 if theory_data is not None: 1182 1170 group_id = str(page.uid) + " Model1D" 1183 wx.PostEvent(self.parent, 1171 wx.PostEvent(self.parent, 1184 1172 NewPlotEvent(group_id=group_id, 1185 1173 action="delete")) 1186 1174 self.parent.update_data(prev_data=theory_data, 1187 new_data=data) 1175 new_data=data) 1188 1176 else: 1189 1177 if theory_data is not None: … … 1194 1182 action="delete")) 1195 1183 self.parent.update_data(prev_data=theory_data, 1196 new_data=data) 1197 self.store_data(uid=page.uid, data_list=page.get_data_list(), 1184 new_data=data) 1185 self.store_data(uid=page.uid, data_list=page.get_data_list(), 1198 1186 caption=page.window_caption) 1199 1187 if self.sim_page is not None and not self.batch_on: … … 1206 1194 def _onEVT_SLICER_PANEL(self, event): 1207 1195 """ 1208 receive and event telling to update a panel with a name starting with 1209 event.panel_name. this method update slicer panel 1196 receive and event telling to update a panel with a name starting with 1197 event.panel_name. this method update slicer panel 1210 1198 for a given interactor. 1211 1199 1212 :param event: contains type of slicer , paramaters for updating 1200 :param event: contains type of slicer , paramaters for updating 1213 1201 the panel and panel_name to find the slicer 's panel concerned. 1214 1202 """ … … 1220 1208 self.parent._mgr.Update() 1221 1209 1222 def _closed_fitpage(self, event): 1223 """ 1224 request fitpanel to close a given page when its unique data is removed 1210 def _closed_fitpage(self, event): 1211 """ 1212 request fitpanel to close a given page when its unique data is removed 1225 1213 from the plot. close fitpage only when the a loaded data is removed 1226 """ 1214 """ 1227 1215 if event is None or event.data is None: 1228 1216 return 1229 if hasattr(event.data, "is_data"):1217 if hasattr(event.data, "is_data"): 1230 1218 if not event.data.is_data or \ 1231 1219 event.data.__class__.__name__ == "Data1D": 1232 self.fit_panel.close_page_with_data(event.data) 1220 self.fit_panel.close_page_with_data(event.data) 1233 1221 1234 1222 def _reset_schedule_problem(self, value=0, uid=None): … … 1251 1239 :param pars: list of fittable parameters 1252 1240 :param fitter_list: list of fit engine 1253 :param value: structure storing data mapped to their model, range etc. .1241 :param value: structure storing data mapped to their model, range etc. 1254 1242 """ 1255 1243 data = fitproblem.get_fit_data() … … 1265 1253 ## check if constraint 1266 1254 if item[0] != None and item[1] != None: 1267 listOfConstraint.append((item[0], item[1]))1268 new_model = model #deepcopy(model)1255 listOfConstraint.append((item[0], item[1])) 1256 new_model = model 1269 1257 fitter.set_model(new_model, fit_id, pars, data=data, 1270 1258 constraints=listOfConstraint) 1271 fitter.set_data(data=data, id=fit_id, smearer=smearer, qmin=qmin, 1259 fitter.set_data(data=data, id=fit_id, smearer=smearer, qmin=qmin, 1272 1260 qmax=qmax) 1273 1261 fitter.select_problem_for_fit(id=fit_id, value=1) 1274 1262 1275 1276 def _onSelect(self,event): 1277 """ 1278 when Select data to fit a new page is created .Its reference is 1263 def _onSelect(self, event): 1264 """ 1265 when Select data to fit a new page is created .Its reference is 1279 1266 added to self.page_finder 1280 1267 """ … … 1304 1291 print "update_fit result", result 1305 1292 1306 1307 def _batch_fit_complete(self, result, pars, page_id, 1293 def _batch_fit_complete(self, result, pars, page_id, 1308 1294 batch_outputs, batch_inputs, elapsed=None): 1309 1295 """ 1310 Display fit result in batch 1296 Display fit result in batch 1311 1297 :param result: list of objects received fromt fit engines 1312 1298 :param pars: list of fitted parameters names … … 1317 1303 uid = page_id[0] 1318 1304 if uid in self.fit_thread_list.keys(): 1319 del self.fit_thread_list[uid] 1305 del self.fit_thread_list[uid] 1320 1306 1321 1307 self._update_fit_button(page_id) … … 1325 1311 msg += "Duration time: %s s.\n" % str(elapsed) 1326 1312 wx.PostEvent(self.parent, StatusEvent(status=msg, info="info", 1327 1313 type="stop")) 1328 1314 1329 1315 if batch_outputs is None: … … 1333 1319 batch_outputs["Chi2"] = [] 1334 1320 #Don't like these loops 1335 # Need to create dictionary of all fitted parameters 1321 # Need to create dictionary of all fitted parameters 1336 1322 # since the number of parameters can differ between each fit result 1337 1323 for list_res in result: … … 1376 1362 new_theory = copy_data.data 1377 1363 new_theory[res.index] = res.theory 1378 new_theory[res.index == False] = numpy.nan 1364 new_theory[res.index == False] = numpy.nan 1379 1365 correct_result = True 1380 1366 #get all fittable parameters of the current model … … 1383 1369 if not model.is_fittable(param) and \ 1384 1370 param in param_list: 1385 param_list.remove(param) 1371 param_list.remove(param) 1386 1372 if not correct_result or res.fitness is None or \ 1387 1373 not numpy.isfinite(res.fitness) or \ … … 1394 1380 if model is not None: 1395 1381 model_name = str(model.name) 1396 msg += "Data %s and Model %s did not fit.\n" % (data_name, 1382 msg += "Data %s and Model %s did not fit.\n" % (data_name, 1397 1383 model_name) 1398 1384 ERROR = numpy.NAN … … 1410 1396 batch_inputs["error on %s" % str(param)].append(ERROR) 1411 1397 else: 1412 # ToDo: Why sometimes res.pvec comes with numpy.float64? 1398 # ToDo: Why sometimes res.pvec comes with numpy.float64? 1413 1399 # Need to fix it within ScipyEngine 1414 if res.pvec.__class__ == numpy.float64:1400 if res.pvec.__class__ == numpy.float64: 1415 1401 res.pvec = [res.pvec] 1416 1402 … … 1435 1421 batch_inputs["error on %s" % param].append('-') 1436 1422 model.setParam(param, res.pvec[index]) 1437 #fill the batch result with emtpy value if not in the current 1423 #fill the batch result with emtpy value if not in the current 1438 1424 #model 1439 1425 EMPTY = "-" … … 1441 1427 if key not in param_list and key not in ["Chi2", "Data"]: 1442 1428 batch_outputs[key].append(EMPTY) 1443 #for key in batch_inputs.keys():1444 #if key not in param_list and key not in ["Chi2", "Data"]:1445 #batch_inputs[key].append(EMPTY)1446 1429 1447 1430 self.page_finder[pid].set_batch_result(batch_inputs=batch_inputs, 1448 batch_outputs=batch_outputs)1431 batch_outputs=batch_outputs) 1449 1432 1450 1433 cpage = self.fit_panel.get_page_by_id(pid) … … 1456 1439 if correct_result: 1457 1440 if not is_data2d: 1458 self._complete1D(x=data.x, y=res.theory, page_id=pid, 1459 elapsed=None,1460 index=res.index, model=model,1461 weight=None, fid=data.id,1462 toggle_mode_on=False, state=None,1463 data=data, update_chisqr=False,1464 source='fit', plot_result =plot_result)1441 self._complete1D(x=data.x, y=res.theory, page_id=pid, 1442 elapsed=None, 1443 index=res.index, model=model, 1444 weight=None, fid=data.id, 1445 toggle_mode_on=False, state=None, 1446 data=data, update_chisqr=False, 1447 source='fit', plot_result=plot_result) 1465 1448 else: 1466 1449 self._complete2D(image=new_theory, data=data, 1467 model=model,1468 page_id=pid, elapsed=None,1469 index=res.index,1470 qmin=qmin,1471 qmax=qmax, fid=data.id, weight=None,1472 toggle_mode_on=False, state=None,1473 update_chisqr=False,1474 source='fit', plot_result =plot_result)1475 self.on_set_batch_result(page_id=pid, 1476 fid=data.id, 1477 batch_outputs=batch_outputs, 1450 model=model, 1451 page_id=pid, elapsed=None, 1452 index=res.index, 1453 qmin=qmin, 1454 qmax=qmax, fid=data.id, weight=None, 1455 toggle_mode_on=False, state=None, 1456 update_chisqr=False, 1457 source='fit', plot_result=plot_result) 1458 self.on_set_batch_result(page_id=pid, 1459 fid=data.id, 1460 batch_outputs=batch_outputs, 1478 1461 batch_inputs=batch_inputs) 1479 1462 1480 1463 wx.PostEvent(self.parent, StatusEvent(status=msg, error="error", 1481 1464 type="stop")) 1482 1465 # Remove parameters that are not shown 1483 1466 cpage = self.fit_panel.get_page_by_id(uid) … … 1485 1468 shownkeystr = cpage.get_copy_params() 1486 1469 for key in batch_outputs.keys(): 1487 if key in ["Chi2", "Data"] or shownkeystr.count(key) >0:1470 if key in ["Chi2", "Data"] or shownkeystr.count(key) > 0: 1488 1471 tbatch_outputs[key] = batch_outputs[key] 1489 1472 1490 wx.CallAfter(self.parent.on_set_batch_result,tbatch_outputs, 1491 batch_inputs, 1492 self.sub_menu) 1473 wx.CallAfter(self.parent.on_set_batch_result, tbatch_outputs, 1474 batch_inputs, self.sub_menu) 1493 1475 1494 1476 def on_set_batch_result(self, page_id, fid, batch_outputs, batch_inputs): 1495 1477 """ 1496 1478 """ 1497 1498 pid = page_id 1479 pid = page_id 1499 1480 if fid not in self.page_finder[pid]: 1500 1481 return 1501 1482 fitproblem = self.page_finder[pid][fid] 1502 1483 index = self.page_finder[pid].nbr_residuals_computed - 1 1503 residuals = 1484 residuals = fitproblem.get_residuals() 1504 1485 theory_data = fitproblem.get_theory_data() 1505 1486 data = fitproblem.get_fit_data() … … 1544 1525 if hasattr(data.sample, param): 1545 1526 if param not in batch_inputs.keys(): 1546 1527 batch_inputs[param] = [] 1547 1528 batch_inputs[param].append(data.sample.temperature) 1548 1529 1549 1550 1530 def _fit_completed(self, result, page_id, batch_outputs, 1551 batch_inputs=None, 1552 pars=None, 1553 elapsed=None): 1531 batch_inputs=None, pars=None, elapsed=None): 1554 1532 """ 1555 1533 Display result of the fit on related panel(s). … … 1573 1551 if page_id is None: 1574 1552 page_id = [] 1575 ## fit more than 1 model at the same time 1576 self._mac_sleep(0.2) 1553 ## fit more than 1 model at the same time 1554 self._mac_sleep(0.2) 1577 1555 try: 1578 1556 index = 0 … … 1584 1562 not numpy.all(numpy.isfinite(res.pvec)): 1585 1563 msg = "Fitting did not converge!!!" 1586 wx.PostEvent(self.parent, 1587 StatusEvent(status=msg, 1564 wx.PostEvent(self.parent, 1565 StatusEvent(status=msg, 1588 1566 info="warning", 1589 1567 type="stop")) … … 1591 1569 else: 1592 1570 #set the panel when fit result are float not list 1593 if res.pvec.__class__ == numpy.float64:1571 if res.pvec.__class__ == numpy.float64: 1594 1572 pvec = [res.pvec] 1595 1573 else: 1596 1574 pvec = res.pvec 1597 if res.stderr.__class__ == numpy.float64:1575 if res.stderr.__class__ == numpy.float64: 1598 1576 stderr = [res.stderr] 1599 1577 else: 1600 1578 stderr = res.stderr 1601 1579 cpage = self.fit_panel.get_page_by_id(uid) 1602 # Make sure we got all results 1580 # Make sure we got all results 1603 1581 #(CallAfter is important to MAC) 1604 1582 try: 1605 1583 #if res != None: 1606 wx.CallAfter(cpage.onsetValues, res.fitness, res.param_list, 1584 wx.CallAfter(cpage.onsetValues, res.fitness, 1585 res.param_list, 1607 1586 pvec, stderr) 1608 1587 index += 1 … … 1610 1589 except: 1611 1590 msg = "Singular point: Fitting Error occurred." 1612 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error", 1613 type="stop")) 1591 wx.PostEvent(self.parent, StatusEvent(status=msg, 1592 info="error", 1593 type="stop")) 1614 1594 1615 1595 except: … … 1627 1607 if page_id.__class__.__name__ != 'list': 1628 1608 page_id = [page_id] 1629 for uid in page_id: 1609 for uid in page_id: 1630 1610 page = self.fit_panel.get_page_by_id(uid) 1631 1611 page._on_fit_complete() … … 1654 1634 ## post a message to status bar 1655 1635 msg = "Set Chain Fitting: %s" % str(not self.batch_reset_flag) 1656 wx.PostEvent(self.parent, 1636 wx.PostEvent(self.parent, 1657 1637 StatusEvent(status=msg)) 1658 1638 1659 def _onset_engine_park(self, event):1639 def _onset_engine_park(self, event): 1660 1640 """ 1661 1641 set engine to park … … 1663 1643 self._on_change_engine('park') 1664 1644 1665 def _onset_engine_scipy(self, event):1645 def _onset_engine_scipy(self, event): 1666 1646 """ 1667 1647 set engine to scipy … … 1671 1651 def _on_slicer_event(self, event): 1672 1652 """ 1673 Receive a panel as event and send it to guiframe 1653 Receive a panel as event and send it to guiframe 1674 1654 1675 1655 :param event: event containing a panel … … 1682 1662 event_id = self.parent.popup_panel(new_panel) 1683 1663 new_panel.uid = event_id 1684 self.mypanels.append(new_panel) 1664 self.mypanels.append(new_panel) 1685 1665 1686 1666 def _onclearslicer(self, event): … … 1688 1668 Clear the boxslicer when close the panel associate with this slicer 1689 1669 """ 1690 name = event.GetPane().caption1670 name = event.GetPane().caption 1691 1671 1692 1672 for panel in self.slicer_panels: 1693 if panel.window_caption ==name:1673 if panel.window_caption == name: 1694 1674 1695 1675 for item in self.parent.panels: 1696 1676 if hasattr(self.parent.panels[item], "uid"): 1697 if self.parent.panels[item].uid == panel.base.uid:1677 if self.parent.panels[item].uid == panel.base.uid: 1698 1678 self.parent.panels[item].onClearSlicer(event) 1699 1679 self.parent._mgr.Update() 1700 break 1680 break 1701 1681 break 1702 1682 … … 1707 1687 return self._fit_engine 1708 1688 1709 1710 1689 def _on_change_engine(self, engine='park'): 1711 1690 """ 1712 Allow to select the type of engine to perform fit 1691 Allow to select the type of engine to perform fit 1713 1692 1714 1693 :param engine: the key work of the engine … … 1726 1705 ## post a message to status bar 1727 1706 msg = "Engine set to: %s" % self._fit_engine 1728 wx.PostEvent(self.parent, 1707 wx.PostEvent(self.parent, 1729 1708 StatusEvent(status=msg)) 1730 1709 ## send the current engine type to fitpanel 1731 1710 self.fit_panel._on_engine_change(name=self._fit_engine) 1732 1711 1733 1734 1712 def _on_model_panel(self, evt): 1735 1713 """ … … 1740 1718 """ 1741 1719 model = evt.model 1742 uid = evt.uid 1720 uid = evt.uid 1743 1721 qmin = evt.qmin 1744 1722 qmax = evt.qmax 1745 smearer = evt.smearer1746 1723 caption = evt.caption 1747 1724 enable_smearer = evt.enable_smearer … … 1765 1742 """ 1766 1743 msg = "Plot updating ... " 1767 wx.PostEvent(self.parent, StatusEvent(status=msg, type="update"))1744 wx.PostEvent(self.parent, StatusEvent(status=msg, type="update")) 1768 1745 1769 1746 def _complete1D(self, x, y, page_id, elapsed, index, model, 1770 1747 weight=None, fid=None, 1771 toggle_mode_on=False, state=None, 1772 data=None, update_chisqr=True, 1748 toggle_mode_on=False, state=None, 1749 data=None, update_chisqr=True, 1773 1750 source='model', plot_result=True): 1774 1751 """ 1775 1752 Complete plotting 1D data 1776 """ 1753 """ 1777 1754 try: 1778 1755 numpy.nan_to_num(y) … … 1782 1759 new_plot.dy = numpy.zeros(len(y)) 1783 1760 new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 1784 _yaxis, _yunit = data.get_yaxis() 1785 _xaxis, _xunit = data.get_xaxis() 1761 _yaxis, _yunit = data.get_yaxis() 1762 _xaxis, _xunit = data.get_xaxis() 1786 1763 new_plot.title = data.name 1787 1764 1788 new_plot.group_id = data.group_id #self.page_finder[page_id].get_graph_id()1765 new_plot.group_id = data.group_id 1789 1766 if new_plot.group_id == None: 1790 1767 new_plot.group_id = data.group_id 1791 new_plot.id = 1768 new_plot.id = str(page_id) + "model-" + data.name 1792 1769 #if new_plot.id in self.color_dict: 1793 # new_plot.custom_color = self.color_dict[new_plot.id] 1770 # new_plot.custom_color = self.color_dict[new_plot.id] 1794 1771 #find if this theory was already plotted and replace that plot given 1795 1772 #the same id … … 1801 1778 data_name = str(model.__class__.__name__) 1802 1779 1803 new_plot.name = model.name + " [" + data_name +"]"1780 new_plot.name = model.name + " [" + data_name +"]" 1804 1781 new_plot.xaxis(_xaxis, _xunit) 1805 1782 new_plot.yaxis(_yaxis, _yunit) 1806 self.page_finder[page_id].set_theory_data(data=new_plot, 1783 self.page_finder[page_id].set_theory_data(data=new_plot, 1807 1784 fid=data.id) 1808 1785 self.parent.update_theory(data_id=data.id, theory=new_plot, 1809 state=state) 1786 state=state) 1810 1787 current_pg = self.fit_panel.get_page_by_id(page_id) 1811 1788 title = new_plot.title … … 1818 1795 if data.id == top_data_id: 1819 1796 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1820 title=str(title))) 1797 title=str(title))) 1821 1798 caption = current_pg.window_caption 1822 1799 self.page_finder[page_id].set_fit_tab_caption(caption=caption) 1823 1800 1824 self.page_finder[page_id].set_theory_data(data=new_plot, 1801 self.page_finder[page_id].set_theory_data(data=new_plot, 1825 1802 fid=data.id) 1826 1803 if toggle_mode_on: 1827 wx.PostEvent(self.parent, 1804 wx.PostEvent(self.parent, 1828 1805 NewPlotEvent(group_id=str(page_id) + " Model2D", 1829 1806 action="Hide")) 1830 1807 else: 1831 1808 if update_chisqr: … … 1839 1816 else: 1840 1817 self._plot_residuals(page_id=page_id, data=data, fid=fid, 1841 1818 index=index, weight=weight) 1842 1819 1843 1820 msg = "Computation completed!" 1844 wx.PostEvent( self.parent, StatusEvent(status=msg, type="stop"))1821 wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop")) 1845 1822 except: 1846 1823 raise 1847 #msg = " Error occurred when drawing %s Model 1D: " % new_plot.name1848 #msg += " %s" % sys.exc_value1849 #wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))1850 1824 1851 def _update2D(self, output, time=None):1825 def _update2D(self, output, time=None): 1852 1826 """ 1853 1827 Update the output of plotting model … … 1857 1831 #self.ready_fit() 1858 1832 1859 def _complete2D(self, image, data, model, page_id, 1860 qmax, fid=None, weight=None, toggle_mode_on=False, state=None, 1833 def _complete2D(self, image, data, model, page_id, elapsed, index, qmin, 1834 qmax, fid=None, weight=None, toggle_mode_on=False, state=None, 1861 1835 update_chisqr=True, source='model', plot_result=True): 1862 1836 """ … … 1865 1839 """ 1866 1840 numpy.nan_to_num(image) 1867 new_plot = Data2D(image=image, err_image=data.err_data)1841 new_plot = Data2D(image=image, err_image=data.err_data) 1868 1842 new_plot.name = model.name 1869 1843 new_plot.title = "Analytical model 2D " … … 1872 1846 new_plot.detector = data.detector 1873 1847 new_plot.source = data.source 1874 new_plot.is_data = False 1848 new_plot.is_data = False 1875 1849 new_plot.qx_data = data.qx_data 1876 1850 new_plot.qy_data = data.qy_data … … 1897 1871 theory_data.name = "Unknown" 1898 1872 1899 self.page_finder[page_id].set_theory_data(data=theory_data, fid=data.id) 1900 self.parent.update_theory(data_id=data.id, 1873 self.page_finder[page_id].set_theory_data(data=theory_data, 1874 fid=data.id) 1875 self.parent.update_theory(data_id=data.id, 1901 1876 theory=new_plot, 1902 state=state) 1877 state=state) 1903 1878 current_pg = self.fit_panel.get_page_by_id(page_id) 1904 1879 title = new_plot.title 1905 batch_on = self.fit_panel.get_page_by_id(page_id).batch_on1906 1880 if not source == 'fit' and plot_result: 1907 1881 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1908 1882 title=title)) 1909 #self.page_finder[page_id].set_theory_data(data=new_plot, fid=data.id)1910 1883 if toggle_mode_on: 1911 wx.PostEvent(self.parent, 1884 wx.PostEvent(self.parent, 1912 1885 NewPlotEvent(group_id=str(page_id) + " Model1D", 1913 1886 action="Hide")) … … 1954 1927 if (self.calc_2D is not None) and self.calc_2D.isrunning(): 1955 1928 self.calc_2D.stop() 1956 self.calc_2D = Calc2D(model=model, 1929 self.calc_2D = Calc2D(model=model, 1957 1930 data=data, 1958 1931 page_id=page_id, … … 1967 1940 update_chisqr=update_chisqr, source=source) 1968 1941 self.calc_2D.queue() 1969 1970 1942 except: 1971 1943 raise 1972 #msg = " Error occurred when drawing %s Model 2D: " % model.name 1973 #msg += " %s" % sys.exc_value 1974 #wx.PostEvent(self.parent, StatusEvent(status=msg)) 1975 1976 def _draw_model1D(self, model, page_id, data, 1944 1945 def _draw_model1D(self, model, page_id, data, 1977 1946 qmin, qmax, smearer=None, 1978 1947 state=None, 1979 1948 weight=None, 1980 fid=None, 1949 fid=None, 1981 1950 toggle_mode_on=False, update_chisqr=True, source='model', 1982 1951 enable1D=True): … … 1989 1958 """ 1990 1959 if not enable1D: 1991 return 1960 return 1992 1961 try: 1993 1962 from model_thread import Calc1D … … 2015 1984 wx.PostEvent(self.parent, StatusEvent(status=msg)) 2016 1985 2017 2018 2019 def _cal_chisqr(self, page_id, data, weight, fid=None, index=None): 1986 def _cal_chisqr(self, page_id, data, weight, fid=None, index=None): 2020 1987 """ 2021 1988 Get handy Chisqr using the output from draw1D and 2D, 2022 1989 instead of calling expansive CalcChisqr in guithread 2023 1990 """ 2024 data_copy = deepcopy(data) 1991 data_copy = deepcopy(data) 2025 1992 # default chisqr 2026 1993 chisqr = None … … 2032 1999 # Get data: data I, theory I, and data dI in order 2033 2000 if data_copy.__class__.__name__ == "Data2D": 2034 if index == None: 2035 index = numpy.ones(len(data_copy.data), ntype=bool)2001 if index == None: 2002 index = numpy.ones(len(data_copy.data), ntype=bool) 2036 2003 if weight != None: 2037 2004 data_copy.err_data = weight 2038 2005 # get rid of zero error points 2039 index = index & (data_copy.err_data != 0) 2040 index = index & (numpy.isfinite(data_copy.data)) 2041 fn = data_copy.data[index] 2006 index = index & (data_copy.err_data != 0) 2007 index = index & (numpy.isfinite(data_copy.data)) 2008 fn = data_copy.data[index] 2042 2009 theory_data = self.page_finder[page_id].get_theory_data(fid=data_copy.id) 2043 if theory_data == None:2010 if theory_data == None: 2044 2011 return chisqr 2045 2012 gn = theory_data.data[index] … … 2057 2024 # But this should be corrected later. 2058 2025 dy = deepcopy(data_copy.dy) 2059 dy[dy ==0] = 12060 fn = data_copy.y[index] 2026 dy[dy == 0] = 1 2027 fn = data_copy.y[index] 2061 2028 2062 2029 theory_data = self.page_finder[page_id].get_theory_data(fid=data_copy.id) 2063 if theory_data == None:2030 if theory_data == None: 2064 2031 return chisqr 2065 2032 gn = theory_data.y … … 2072 2039 chisqr = numpy.average(residuals * residuals) 2073 2040 2074 self._plot_residuals(page_id=page_id, data=data_copy, 2041 self._plot_residuals(page_id=page_id, data=data_copy, 2075 2042 fid=fid, 2076 2043 weight=weight, index=index) … … 2079 2046 2080 2047 def _plot_residuals(self, page_id, weight, fid=None, 2081 data=None, index=None): 2048 data=None, index=None): 2082 2049 """ 2083 2050 Plot the residuals 2084 2051 2085 2052 :param data: data 2086 :param index: index array (bool) 2053 :param index: index array (bool) 2087 2054 : Note: this is different from the residuals in cal_chisqr() 2088 2055 """ … … 2096 2063 data_copy.clone_without_data(len(data_copy.data), residuals) 2097 2064 residuals.data = None 2098 fn = data_copy.data #[index]2065 fn = data_copy.data 2099 2066 theory_data = self.page_finder[page_id].get_theory_data(fid=data_copy.id) 2100 gn = theory_data.data #[index]2067 gn = theory_data.data 2101 2068 if weight == None: 2102 2069 en = data_copy.err_data 2103 2070 else: 2104 2071 en = weight 2105 residuals.data = (fn - gn) / en 2106 residuals.qx_data = data_copy.qx_data #[index]2107 residuals.qy_data = data_copy.qy_data #[index]2108 residuals.q_data = data_copy.q_data #[index]2109 residuals.err_data = numpy.ones(len(residuals.data)) #[index]2072 residuals.data = (fn - gn) / en 2073 residuals.qx_data = data_copy.qx_data 2074 residuals.qy_data = data_copy.qy_data 2075 residuals.q_data = data_copy.q_data 2076 residuals.err_data = numpy.ones(len(residuals.data)) 2110 2077 residuals.xmin = min(residuals.qx_data) 2111 2078 residuals.xmax = max(residuals.qx_data) 2112 2079 residuals.ymin = min(residuals.qy_data) 2113 2080 residuals.ymax = max(residuals.qy_data) 2114 residuals.q_data = data_copy.q_data #[index]2081 residuals.q_data = data_copy.q_data 2115 2082 residuals.mask = data_copy.mask 2116 2083 residuals.scale = 'linear' … … 2125 2092 if weight == None: 2126 2093 dy = numpy.ones(len(data_copy.y)) 2127 ## Set consitently w/AbstractFitengine: 2094 ## Set consitently w/AbstractFitengine: 2128 2095 ## But this should be corrected later. 2129 2096 else: 2130 dy = weight #deepcopy(data_copy.dy)2131 dy[dy ==0] = 12132 fn = data_copy.y[index] 2097 dy = weight 2098 dy[dy == 0] = 1 2099 fn = data_copy.y[index] 2133 2100 theory_data = self.page_finder[page_id].get_theory_data(fid=data_copy.id) 2134 2101 gn = theory_data.y … … 2147 2114 residuals.yaxis('\\rm{Residuals} ', 'normalized') 2148 2115 new_plot = residuals 2149 new_plot.name = "Residuals for " + str(theory_data.name.split()[0]) + "[" + str(data.name) +"]"2116 new_plot.name = "Residuals for " + str(theory_data.name.split()[0]) + "[" + str(data.name) +"]" 2150 2117 ## allow to highlight data when plotted 2151 2118 new_plot.interactive = True 2152 2119 ## when 2 data have the same id override the 1 st plotted 2153 new_plot.id = "res" + str(data_copy.id) #name + " residuals"2120 new_plot.id = "res" + str(data_copy.id) 2154 2121 ##group_id specify on which panel to plot this data 2155 2122 group_id = self.page_finder[page_id].get_graph_id() 2156 2123 if group_id == None: 2157 2124 group_id = data.group_id 2158 new_plot.group_id = "res" + str(group_id)2125 new_plot.group_id = "res" + str(group_id) 2159 2126 #new_plot.is_data = True 2160 2127 ##post data to plot 2161 title = new_plot.name 2162 self.page_finder[page_id].set_residuals(residuals=new_plot, fid=data.id) 2128 title = new_plot.name 2129 self.page_finder[page_id].set_residuals(residuals=new_plot, 2130 fid=data.id) 2163 2131 self.parent.update_theory(data_id=data.id, theory=new_plot) 2164 2132 batch_on = self.fit_panel.get_page_by_id(page_id).batch_on 2165 2133 if not batch_on: 2166 2134 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=title)) 2167 2168 2169 #def profile(fn, *args, **kw):2170 # import cProfile, pstats, os2171 # global call_result2172 # def call():2173 # global call_result2174 # call_result = fn(*args, **kw)2175 # cProfile.runctx('call()', dict(call=call), {}, 'profile.out')2176 # stats = pstats.Stats('profile.out')2177 # #stats.sort_stats('time')2178 # stats.sort_stats('calls')2179 # stats.print_stats()2180 # os.unlink('profile.out')2181 # return call_result2182 if __name__ == "__main__":2183 i = Plugin()2184 2185 2186 2187
Note: See TracChangeset
for help on using the changeset viewer.