Changeset 2dbffcc in sasview for fittingview
- Timestamp:
- Aug 26, 2011 8:20:28 AM (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:
- 7e7e806
- Parents:
- 3e3ab46
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fittingview/src/sans/perspectives/fitting/fitting.py
r0625b79 r2dbffcc 27 27 from sans.guiframe.dataFitting import Data2D 28 28 from sans.guiframe.dataFitting import Data1D 29 from sans.guiframe.dataFitting import check_data_validity 29 30 from sans.guiframe.events import NewPlotEvent 30 31 from sans.guiframe.events import StatusEvent … … 33 34 from sans.guiframe.gui_style import GUIFRAME_ID 34 35 from sans.guiframe.plugin_base import PluginBase 35 36 from sans.fit.Fitting import Fit 36 37 from .console import ConsoleUpdate 37 from .fitproblem import FitProblem 38 from .fitproblem import FitProblemDictionary 38 39 from .fitpanel import FitPanel 39 40 from .fit_thread import FitThread … … 41 42 from .fitpage import Chi2UpdateEvent 42 43 43 DEFAULT_BEAM = 0.00544 DEFAULT_QMIN = 0.00145 DEFAULT_QMAX = 0.1346 DEFAULT_NPTS = 5047 44 MAX_NBR_DATA = 4 48 45 SANS_F_TOL = 5e-05 … … 112 109 logging.info("Fitting plug-in started") 113 110 111 def create_fit_problem(self, page_id): 112 """ 113 Given an ID create a fitproblem container 114 """ 115 self.page_finder[page_id] = FitProblemDictionary() 116 117 def delete_fit_problem(self, page_id): 118 """ 119 Given an ID create a fitproblem container 120 """ 121 if page_id in self.page_finder.iterkeys(): 122 del self.page_finder[page_id] 123 114 124 def add_color(self, color, id): 115 125 """ … … 123 133 """ 124 134 self.batch_on = flag 125 if self.batch_on: 126 if self.fit_panel is not None: 127 self.fit_panel.batch_on = flag 135 if self.fit_panel is not None: 136 self.fit_panel.batch_on = self.batch_on 128 137 129 138 def populate_menu(self, owner): … … 214 223 return [] 215 224 item = plotpanel.plots[graph.selected_plottable] 216 self.test_model_color = item.custom_color217 print "Self.test_model_color has been set to ",self.test_model_color218 225 if item.__class__.__name__ is "Data2D": 219 226 if hasattr(item,"is_data"): … … 397 404 title=data.title)) 398 405 page = self.add_fit_page([data]) 399 caption = page.window_name 400 self.store_data(uid=page.uid, data=page.get_data(), 401 data_list=page.get_data_list(), 402 caption=page.window_name) 406 caption = page.window_caption 407 self.store_data(uid=page.uid, data_list=page.get_data_list(), 408 caption=caption) 403 409 self.mypanels.append(page) 404 410 … … 425 431 self.state_reader.write(filename=filepath, fitstate=fitstate) 426 432 427 def set_fit_range(self, uid, qmin, qmax): 428 """ 429 Set the fitting range of a given page 430 """ 431 self.page_finder[uid].set_range(qmin=qmin, qmax=qmax) 433 def set_fit_range(self, uid, qmin, qmax, fid=None): 434 """ 435 Set the fitting range of a given page for all 436 its data by default. If fid is provide then set the range 437 only for the data with fid as id 438 :param uid: id corresponding to a fit page 439 :param fid: id corresponding to a fit problem (data, model) 440 :param qmin: minimum value of the fit range 441 :param qmax: maximum value of the fit range 442 """ 443 if uid in self.page_finder.keys(): 444 self.page_finder[uid].set_range(qmin=qmin, qmax=qmax) 432 445 433 def schedule_for_fit(self, value=0, uid=None,fitproblem=None):446 def schedule_for_fit(self, value=0, uid=None): 434 447 """ 435 448 Set the fit problem field to 0 or 1 to schedule that problem to fit. 436 449 Schedule the specified fitproblem or get the fit problem related to 437 450 the current page and set value. 438 439 451 :param value: integer 0 or 1 440 :param fitproblem: fitproblem to schedule or not to fit 441 442 """ 443 if fitproblem !=None: 444 fitproblem.schedule_tofit(value) 445 else: 452 :param uid: the id related to a page contaning fitting information 453 """ 454 if uid in self.page_finder.keys(): 446 455 self.page_finder[uid].schedule_tofit(value) 447 456 … … 539 548 panel. _on_fit_complete() 540 549 541 def set_smearer(self, uid, smearer, qmin=None, qmax=None, draw=True, 542 enable2D=False): 543 """ 544 Get a smear object and store it to a fit problem 545 546 :param smearer: smear object to allow smearing data 547 550 def set_smearer(self, uid, smearer, fid, qmin=None, qmax=None, draw=True, 551 enable_smearer=False): 552 """ 553 Get a smear object and store it to a fit problem of fid as id. If proper 554 flag is enable , will plot the theory with smearing information. 555 556 :param smearer: smear object to allow smearing data of id fid 557 :param enable_smearer: Define whether or not all (data, model) contained 558 in the structure of id uid will be smeared before fitting. 559 :param qmin: the maximum value of the theory plotting range 560 :param qmax: the maximum value of the theory plotting range 561 :param draw: Determine if the theory needs to be plot 548 562 """ 549 563 if uid not in self.page_finder.keys(): 550 msg = "Cannot find ID: %s in page_finder" % str(uid) 551 raise ValueError, msg 552 self.page_finder[uid].set_smearer(smearer) 553 self.page_finder[uid].set_enable2D(enable2D) 564 return 565 self.page_finder[uid].enable_smearing(flag=enable_smearer) 566 self.page_finder[uid].set_smearer(smearer, fid=fid) 554 567 if draw: 555 568 ## draw model 1D with smeared data 556 data = self.page_finder[uid].get_fit_data() 557 model = self.page_finder[uid].get_model() 569 data = self.page_finder[uid].get_fit_data(fid=fid) 570 if data is None: 571 msg = "set_mearer requires at least data.\n" 572 msg += "Got data = %s .\n" % str(data) 573 raise ValueError, msg 574 model = self.page_finder[uid].get_model(fid=fid) 558 575 if model is None: 559 576 return 560 enable1D = True 561 enable2D = self.page_finder[uid].get_enable2D() 562 if enable2D: 563 enable1D = False 564 577 enable1D = issubclass(data.__class__, Data1D) 578 enable2D = issubclass(data.__class__, Data2D) 565 579 ## if user has already selected a model to plot 566 580 ## redraw the model with data smeared 567 smear = self.page_finder[uid].get_smearer( )581 smear = self.page_finder[uid].get_smearer(fid=fid) 568 582 self.draw_model(model=model, data=data, page_id=uid, smearer=smear, 569 583 enable1D=enable1D, enable2D=enable2D, … … 572 586 573 587 def _mac_sleep(self, sec=0.2): 574 575 576 588 """ 589 Give sleep to MAC 590 """ 577 591 if ON_MAC: 578 579 592 time.sleep(sec) 593 580 594 def draw_model(self, model, page_id, data=None, smearer=None, 581 595 enable1D=True, enable2D=False, 582 596 state=None, 583 597 toggle_mode_on=False, 584 qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, 585 qstep=DEFAULT_NPTS, 598 qmin=None, qmax=None, 586 599 update_chisqr=True): 587 600 """ … … 600 613 601 614 """ 602 if data.__class__.__name__ == "Data1D"or not enable2D:615 if issublclass(data.__class__, Data1D) or not enable2D: 603 616 ## draw model 1D with no loaded data 604 617 self._draw_model1D(model=model, … … 611 624 toggle_mode_on=toggle_mode_on, 612 625 state=state, 613 qstep=qstep,614 626 update_chisqr=update_chisqr) 615 627 else: … … 624 636 state=state, 625 637 toggle_mode_on=toggle_mode_on, 626 qstep=qstep,627 638 update_chisqr=update_chisqr) 628 639 629 640 def onFit(self, uid=None): 630 641 """ 631 perform fit 642 Get series of data, model, associates parameters and range and send then 643 to series of fit engines. Fit data and model, display result to 644 corresponding panels. 645 :param uid: id related to the panel currently calling this fit function. 632 646 """ 633 647 ## count the number of fitproblem schedule to fit … … 640 654 if fitproblem_count > 1: 641 655 self._on_change_engine(engine='park') 642 643 656 self.fitproblem_count = fitproblem_count 644 645 from sans.fit.Fitting import Fit646 fitter = Fit(self._fit_engine)647 648 657 if self._fit_engine == "park": 649 658 engineType = "Simultaneous Fit" 650 659 else: 651 660 engineType = "Single Fit" 652 653 661 fitter_list = [] 654 fproblemId = 0655 662 self.current_pg = None 656 663 list_page_id = [] … … 666 673 pars = [] 667 674 templist = [] 668 669 675 page = self.fit_panel.get_page_by_id(page_id) 670 676 templist = page.get_param_list() 671 # missing fit parameters672 #if not templist:673 # return674 # have the list675 677 for element in templist: 676 678 name = str(element[1]) 677 679 pars.append(name) 678 680 #Set Engine (model , data) related to the page on 679 self._fit_helper(value=value, pars=pars, 680 fitter=fitter, 681 fitter_list=fitter_list, 682 fitproblem_id=fproblemId, 683 title=engineType) 681 self._fit_helper(value, pars, fitter_list) 684 682 list_page_id.append(page_id) 685 fproblemId += 1686 683 current_page_id = page_id 687 684 except: 688 #raise689 685 msg= "%s error: %s" % (engineType, sys.exc_value) 690 686 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error", … … 701 697 manager=self, 702 698 improvement_delta=0.1) 703 704 699 self._mac_sleep(0.2) 705 700 ## perform single fit … … 733 728 if self.fitproblem_count != None and self.fitproblem_count > 1: 734 729 calc_fit.ready(2.5) 735 736 730 else: 737 731 time.sleep(0.4) 738 732 739 def remove_plot(self, uid, theory=False):733 def remove_plot(self, uid, fid=None, theory=False): 740 734 """ 741 735 remove model plot when a fit page is closed 742 """ 743 fitproblem = self.page_finder[uid] 744 data = fitproblem.get_fit_data() 745 model = fitproblem.get_model() 746 plot_id = None 747 if model is not None: 748 plot_id = data.id + name 749 if theory: 750 plot_id = data.id 751 group_id = data.group_id 752 wx.PostEvent(self.parent, NewPlotEvent(id=plot_id, 753 group_id=group_id, 754 action='remove')) 736 :param uid: the id related to the fitpage to close 737 :param fid: the id of the fitproblem(data, model, range,etc) 738 """ 739 if uid not in self.page_finder.keys(): 740 return 741 fitproblemList = self.page_finder[uid].get_fit_problem(fid) 742 for fitproblem in fitproblemList: 743 data = fitproblem.get_fit_data() 744 model = fitproblem.get_model() 745 plot_id = None 746 if model is not None: 747 plot_id = data.id + name 748 if theory: 749 plot_id = data.id 750 group_id = data.group_id 751 wx.PostEvent(self.parent, NewPlotEvent(id=plot_id, 752 group_id=group_id, 753 action='remove')) 755 754 756 def store_data(self, uid, data=None, data_list=None, caption=None): 757 """ 758 Helper to save page reference into the plug-in 759 760 :param page: page to store 761 755 def store_data(self, uid, data_list=None, caption=None): 756 """ 757 Recieve a list of data and store them ans well as a caption of 758 the fit page where they come from. 759 :param uid: if related to a fit page 760 :param data_list: list of data to fit 761 :param caption: caption of the window related to these data 762 762 """ 763 763 if data_list is None: 764 764 data_list = [] 765 #create a fitproblem storing all link to data,model,page creation 766 if not uid in self.page_finder.keys(): 767 self.page_finder[uid] = FitProblem() 768 self.page_finder[uid].set_fit_data(data) 769 self.page_finder[uid].set_fit_data_list(data_list) 770 self.page_finder[uid].set_fit_tab_caption(caption) 765 self.page_finder[uid].set_fit_data(data=data_list) 766 if caption is not None: 767 self.page_finder[uid].set_fit_tab_caption(caption=caption) 771 768 772 769 def on_add_new_page(self, event=None): … … 776 773 try: 777 774 page = self.fit_panel.add_empty_page() 778 page_caption = page.window_ name775 page_caption = page.window_caption 779 776 # add data associated to the page created 780 777 if page != None: 781 self.store_data(uid=page.uid, caption=page_caption,782 data=page.get_data())783 778 wx.PostEvent(self.parent, StatusEvent(status="Page Created", 784 779 info="info")) … … 789 784 self.set_top_panel() 790 785 except: 791 raise 792 #msg = "Creating Fit page: %s"%sys.exc_value 793 #wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 794 786 msg = "Creating Fit page: %s"%sys.exc_value 787 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error")) 795 788 796 789 def add_fit_page(self, data): … … 798 791 given a data, ask to the fitting panel to create a new fitting page, 799 792 get this page and store it into the page_finder of this plug-in 793 :param data: is a list of data 800 794 """ 801 795 page = self.fit_panel.set_data(data) 802 page_caption = page.window_ name796 page_caption = page.window_caption 803 797 #append Data1D to the panel containing its theory 804 798 #if theory already plotted 805 799 if page.uid in self.page_finder: 806 theory_data = self.page_finder[page.uid].get_theory_data()807 800 data = page.get_data() 801 theory_data = self.page_finder[page.uid].get_theory_data(data.id) 808 802 if issubclass(data.__class__, Data2D): 809 803 data.group_id = wx.NewId() … … 825 819 new_data=data) 826 820 827 self.store_data(uid=page.uid, data=page.get_data(), 828 data_list=page.get_data_list(), 829 caption=page.window_name) 821 self.store_data(uid=page.uid, data_list=page.get_data_list(), 822 caption=page.window_caption) 830 823 if self.sim_page is not None: 831 824 self.sim_page.draw_page() … … 858 851 event.data.__class__.__name__ == "Data1D": 859 852 self.fit_panel.close_page_with_data(event.data) 860 861 def _add_page_onmenu(self, name, fitproblem=None): 862 """ 863 Add name of a closed page of fitpanel in a menu 864 """ 865 list = self.menu1.GetMenuItems() 866 for item in list: 867 if name == item.GetItemLabel(): 868 self.closed_page_dict[name][1] = fitproblem 869 870 if not name in self.closed_page_dict.keys(): 871 # Post paramters 872 event_id = wx.NewId() 873 self.menu1.Append(event_id, name, "Show %s fit panel" % name) 874 self.closed_page_dict[name]= [event_id, fitproblem] 875 wx.EVT_MENU(self.parent, event_id, self._open_closed_page) 876 877 def _open_closed_page(self, event): 878 """ 879 reopen a closed page 880 """ 881 for name, value in self.closed_page_dict.iteritems(): 882 if event.GetId() in value: 883 uid,fitproblem = value 884 if name !="Model": 885 data= fitproblem.get_fit_data() 886 page = self.fit_panel.add_fit_page(data=data, reset=True) 887 if fitproblem != None: 888 self.page_finder[uid] = fitproblem 889 if self.sim_page != None: 890 self.sim_page.draw_page() 891 892 else: 893 model = fitproblem 894 self.fit_panel.add_model_page(model=model, topmenu=True, 895 reset= True) 896 break 897 853 898 854 def _reset_schedule_problem(self, value=0, uid=None): 899 855 """ … … 906 862 # when uid is given 907 863 else: 908 self.page_finder[uid].schedule_tofit(value) 864 if uid in self.page_finder.keys(): 865 self.page_finder[uid].schedule_tofit(value) 909 866 910 def _fit_setter(self, data, value, fitter, fit_id, pars): 911 """ 912 """ 913 model = value.get_model() 914 smearer = value.get_smearer() 915 qmin, qmax = value.get_range() 916 print "fitter_setter", qmin, qmax 917 #Extra list of parameters and their constraints 918 listOfConstraint = [] 919 920 param = value.get_model_param() 921 if len(param) > 0: 922 for item in param: 923 ## check if constraint 924 if item[0] != None and item[1] != None: 925 listOfConstraint.append((item[0],item[1])) 926 927 #Do the single fit 928 fitter.set_model(deepcopy(model), fit_id, 929 pars, constraints=listOfConstraint) 930 931 fitter.set_data(data=data, id=fit_id, 932 smearer=smearer, qmin=qmin, qmax=qmax) 867 def _fit_helper(self, value, pars, fitter_list): 868 """ 869 Create and set fit engine with series of data and model 870 :param pars: list of fittable parameters 871 :param fitter_list: list of fit engine 872 :param value: structure storing data mapped to their model, range etc.. 873 """ 874 fit_id = 0 875 for fitproblem in value.get_fit_problem(): 876 fitter = Fit(self._fit_engine) 877 data = fitproblem.get_fit_data() 878 model = fitproblem.get_model() 879 smearer = fitproblem.get_smearer() 880 qmin, qmax = fitproblem.get_range() 881 #Extra list of parameters and their constraints 882 listOfConstraint = [] 883 param = fitproblem.get_model_param() 884 if len(param) > 0: 885 for item in param: 886 ## check if constraint 887 if item[0] != None and item[1] != None: 888 listOfConstraint.append((item[0],item[1])) 889 fitter.set_model(model, fit_id, pars, constraints=listOfConstraint) 890 fitter.set_data(data=data, id=fit_id, smearer=smearer, qmin=qmin, 891 qmax=qmax) 892 fitter.select_problem_for_fit(id=fit_id, value=1) 893 fitter_list.append(fitter) 894 fit_id += 1 895 value.clear_model_param() 933 896 934 fitter.select_problem_for_fit(id=fit_id, value=1)935 value.clear_model_param()936 937 938 def _fit_helper(self, pars, value, fitproblem_id, fitter_list,939 fitter=None, title="Single Fit " ):940 """941 helper for fitting942 """943 from sans.fit.Fitting import Fit944 self.fit_id = 0945 data_list = value.get_fit_data_list()946 pointer_to_fitproblem = value.get_pointer_to_fitproblem()947 #Create list of parameters for fitting used948 templist = []949 for single_data in data_list:950 fitter = Fit(self._fit_engine)951 try:952 if single_data.id in pointer_to_fitproblem:953 v = self.page_finder[pointer_to_fitproblem[single_data.id]]954 self._fit_setter(data=single_data, value=v,955 fitter=fitter,956 pars=pars,957 fit_id=self.fit_id)958 else:959 self._fit_setter(data=single_data, value=value,960 fitter=fitter,961 pars=pars,962 fit_id=self.fit_id)963 except:964 raise965 #msg = title + " error: %s" % sys.exc_value966 #wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop"))967 fitter_list.append(fitter)968 self.fit_id += 1969 970 897 def _onSelect(self,event): 971 898 """ … … 992 919 print "update_fit result", result 993 920 994 def _batch_single_fit_complete_helper(self, result, pars, page_id,921 def _batch_single_fit_complete_helper(self, result, pars, page_id, 995 922 elapsed=None): 996 923 """ 997 Fit result are display in batch mode 924 Display fit result in batch 925 :param result: list of objects received fromt fit engines 926 :param pars: list of fitted parameters names 927 :param page_id: list of page ids which called fit function 928 :param elapsed: time spent at the fitting level 998 929 """ 999 930 self._update_fit_button(page_id) … … 1012 943 item = res.stderr[index] 1013 944 batch_result["error on %s" % pars[index]].append(item) 1014 1015 945 pid = page_id[0] 1016 946 self.page_finder[pid].set_result(result=batch_result) 1017 947 self.parent.on_set_batch_result(data=batch_result, 1018 948 name=self.sub_menu) 949 for uid in page_id: 950 cpage = self.fit_panel.get_page_by_id(uid) 951 cpage._on_fit_complete() 1019 952 1020 1021 953 def _single_fit_completed(self, result, pars, page_id, elapsed=None): 1022 954 """ 1023 Display fit result on one page of the notebook. 1024 1025 :param result: result of fit 955 Display fit result on one page of the notebook. 956 :param result: list of object generated when fit ends 1026 957 :param pars: list of names of parameters fitted 1027 :param current_pg: the page where information will be displayed 1028 :param qmin: the minimum value of x to replot the model 1029 :param qmax: the maximum value of x to replot model 1030 958 :param page_id: list of page ids which called fit function 959 :param elapsed: time spent at the fitting level 1031 960 """ 1032 961 self._mac_sleep(0.2) … … 1060 989 1061 990 for uid in page_id: 1062 value = self.page_finder[uid]1063 model = value.get_model()1064 page_id = uid1065 1066 param_name = []1067 for name in pars:1068 param_name.append(name)1069 1070 991 cpage = self.fit_panel.get_page_by_id(uid) 1071 992 # Make sure we got all results 1072 993 #(CallAfter is important to MAC) 1073 wx.CallAfter(cpage.onsetValues, result.fitness, 1074 param_name,result.pvec, result.stderr)994 wx.CallAfter(cpage.onsetValues, result.fitness, pars, 995 result.pvec, result.stderr) 1075 996 cpage._on_fit_complete() 1076 997 if result.stderr == None: … … 1080 1001 msg += "Completed!!!" 1081 1002 wx.PostEvent(self.parent, StatusEvent(status=msg)) 1082 return1083 1003 except ValueError: 1084 1004 self._update_fit_button(page_id) … … 1086 1006 wx.PostEvent(self.parent, StatusEvent(status=msg, info="error", 1087 1007 type="stop")) 1088 return1089 1008 except: 1090 1009 self._update_fit_button(page_id) … … 1094 1013 type="stop")) 1095 1014 raise 1096 return 1097 1098 def _simul_fit_completed(self, result, page_id,pars=None, elapsed=None): 1099 """ 1100 Parameter estimation completed, 1101 display the results to the user 1102 1103 :param alpha: estimated best alpha 1104 :param elapsed: computation time 1105 1106 """ 1015 1016 def _simul_fit_completed(self, result, page_id, pars=None, elapsed=None): 1017 """ 1018 Display result of the fit on related panel(s). 1019 :param result: list of object generated when fit ends 1020 :param pars: list of names of parameters fitted 1021 :param page_id: list of page ids which called fit function 1022 :param elapsed: time spent at the fitting level 1023 """ 1024 result = result 1107 1025 self.fit_thread_list = {} 1108 1026 if page_id is None: … … 1127 1045 1128 1046 for uid in page_id: 1129 value = self.page_finder[uid] 1130 model = value.get_model() 1131 data = value.get_fit_data() 1132 small_param_name = [] 1133 small_out = [] 1134 small_cov = [] 1135 #Separate result in to data corresponding to each page 1136 for p in result.parameters: 1137 model_name, param_name = self.split_string(p.name) 1138 if model.name == model_name: 1139 p_name= model.name+"."+param_name 1140 if p.name == p_name: 1141 if p.value != None and numpy.isfinite(p.value): 1142 small_out.append(p.value) 1143 small_param_name.append(param_name) 1144 small_cov.append(p.stderr) 1047 fpdict = self.page_finder[uid] 1048 for value in ftpdict.itervalues(): 1049 model = value.get_model() 1050 data = value.get_fit_data() 1051 small_param_name = [] 1052 small_out = [] 1053 small_cov = [] 1054 #Separate result in to data corresponding to each page 1055 for p in result.parameters: 1056 model_name, param_name = self.split_string(p.name) 1057 if model.name == model_name: 1058 p_name= model.name+"."+param_name 1059 if p.name == p_name: 1060 if p.value != None and numpy.isfinite(p.value): 1061 small_out.append(p.value) 1062 small_param_name.append(param_name) 1063 small_cov.append(p.stderr) 1145 1064 # Display result on each page 1146 1065 cpage = self.fit_panel.get_page_by_id(uid) … … 1158 1077 type="stop")) 1159 1078 return 1160 1161 1079 except: 1162 1080 self._update_fit_button(page_id) … … 1206 1124 # Set group ID if available 1207 1125 event_id = self.parent.popup_panel(new_panel) 1208 #self.menu3.Append(event_id, new_panel.window_caption,1209 # "Show %s plot panel" % new_panel.window_caption)1210 # Set id to allow us to reference the panel later1211 1212 1126 new_panel.uid = event_id 1213 1127 self.mypanels.append(new_panel) … … 1223 1137 1224 1138 for item in self.parent.panels: 1225 if hasattr(self.parent.panels[item], "uid"):1139 if hasattr(self.parent.panels[item], "uid"): 1226 1140 if self.parent.panels[item].uid ==panel.base.uid: 1227 1141 self.parent.panels[item].onClearSlicer(event) … … 1247 1161 self._fit_engine = engine 1248 1162 ## change menu item state 1249 if engine =="park":1163 if engine == "park": 1250 1164 self.menu1.FindItemById(self.park_id).Check(True) 1251 1165 self.menu1.FindItemById(self.scipy_id).Check(False) … … 1273 1187 qmax = evt.qmax 1274 1188 smearer = evt.smearer 1275 1189 caption = evt.caption 1190 enable_smearer = evt.enable_smearer 1276 1191 if model == None: 1277 1192 return 1278 1279 if self.page_finder[uid].get_model() is None: 1280 model.name = "M" + str(self.index_model) 1281 self.index_model += 1 1282 else: 1283 model.name = self.page_finder[uid].get_model().name 1193 if uid not in self.page_finder.keys(): 1194 return 1284 1195 # save the name containing the data name with the appropriate model 1285 1196 self.page_finder[uid].set_model(model) 1197 self.page_finder[uid].enable_smearing(enable_smearer) 1286 1198 self.page_finder[uid].set_range(qmin=qmin, qmax=qmax) 1199 self.page_finder[uid].set_fit_tab_caption(caption=caption) 1287 1200 if self.sim_page is not None: 1288 1201 self.sim_page.draw_page() 1289 1202 1290 def _update1D(self, x, output):1203 def _update1D(self, x, output): 1291 1204 """ 1292 1205 Update the output of plotting model 1D … … 1294 1207 msg = "Plot updating ... " 1295 1208 wx.PostEvent(self.parent, StatusEvent(status=msg,type="update")) 1296 #self.ready_fit() 1297 1298 1299 def _fill_default_model2D(self, theory, page_id, qmax,qstep, qmin=None): 1300 """ 1301 fill Data2D with default value 1302 1303 :param theory: Data2D to fill 1304 1305 """ 1306 from sans.dataloader.data_info import Detector, Source 1307 1308 detector = Detector() 1309 theory.detector.append(detector) 1310 theory.source= Source() 1311 1312 ## Default values 1313 theory.detector[0].distance= 8000 # mm 1314 theory.source.wavelength= 6 # A 1315 theory.detector[0].pixel_size.x= 5 # mm 1316 theory.detector[0].pixel_size.y= 5 # mm 1317 1318 theory.detector[0].beam_center.x= qmax 1319 theory.detector[0].beam_center.y= qmax 1320 1321 ## create x_bins and y_bins of the model 2D 1322 pixel_width_x = theory.detector[0].pixel_size.x 1323 pixel_width_y = theory.detector[0].pixel_size.y 1324 center_x = theory.detector[0].beam_center.x/pixel_width_x 1325 center_y = theory.detector[0].beam_center.y/pixel_width_y 1326 1327 # theory default: assume the beam 1328 #center is located at the center of sqr detector 1329 xmax = qmax 1330 xmin = -qmax 1331 ymax = qmax 1332 ymin = -qmax 1333 1334 x= numpy.linspace(start= -1*qmax, 1335 stop=qmax, 1336 num=qstep, 1337 endpoint=True) 1338 y = numpy.linspace(start=-1*qmax, 1339 stop= qmax, 1340 num= qstep, 1341 endpoint=True) 1342 1343 ## use data info instead 1344 new_x = numpy.tile(x, (len(y),1)) 1345 new_y = numpy.tile(y, (len(x),1)) 1346 new_y = new_y.swapaxes(0,1) 1347 1348 # all data reuire now in 1d array 1349 qx_data = new_x.flatten() 1350 qy_data = new_y.flatten() 1351 1352 q_data = numpy.sqrt(qx_data*qx_data+qy_data*qy_data) 1353 # set all True (standing for unmasked) as default 1354 mask = numpy.ones(len(qx_data), dtype = bool) 1355 1356 # calculate the range of qx and qy: this way, 1357 # it is a little more independent 1358 x_size = xmax- xmin 1359 y_size = ymax -ymin 1360 1361 # store x and y bin centers in q space 1362 x_bins = x 1363 y_bins = y 1364 # bin size: x- & y-directions 1365 xstep = x_size/len(x_bins-1) 1366 ystep = y_size/len(y_bins-1) 1367 1368 #theory.data = numpy.zeros(len(mask)) 1369 theory.err_data = numpy.ones(len(mask)) 1370 theory.qx_data = qx_data 1371 theory.qy_data = qy_data 1372 theory.q_data = q_data 1373 theory.mask = mask 1374 theory.x_bins = x_bins 1375 theory.y_bins = y_bins 1376 1377 # max and min taking account of the bin sizes 1378 theory.xmin = xmin 1379 theory.xmax = xmax 1380 theory.ymin = ymin 1381 theory.ymax = ymax 1382 theory.group_id = str(page_id) + " Model2D" 1383 theory.id = str(page_id) + " Model2D" 1384 theory.title = "Analytical model 2D " 1385 1209 1386 1210 def _complete1D(self, x,y, page_id, elapsed,index,model, 1387 1211 toggle_mode_on=False,state=None, … … 1394 1218 new_plot.is_data = False 1395 1219 new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 1396 if data != None: 1397 #if model.output_name.lower().count("reflectivity") > 0: 1398 # _yaxis, _yunit = "\\rm{%s}"% model.output_name, \ 1399 # "%s"% model.output_unit 1400 #else: 1401 _yaxis, _yunit = data.get_yaxis() 1402 _xaxis, _xunit = data.get_xaxis() 1403 new_plot.title = data.name 1404 #if the theory is already plotted use the same group id 1405 #to replot 1406 if page_id in self.page_finder: 1407 theory_data = self.page_finder[page_id].get_theory_data() 1408 if theory_data is not None: 1409 data.group_id = theory_data.group_id 1410 #data is plotted before the theory, then take its group_id 1411 #assign to the new theory 1412 new_plot.group_id = data.group_id 1413 1414 else: 1415 _xaxis, _xunit = "\\rm{%s}"% model.input_name, \ 1416 "%s"% model.input_unit 1417 _yaxis, _yunit = "\\rm{%s}"% model.output_name, \ 1418 "%s"% model.output_unit 1419 new_plot.title = "Analytical model 1D " 1420 #find a group id to plot theory without data 1421 new_plot.group_id = str(page_id) + " Model1D" 1422 new_plot.id = str(page_id) + " Model1D" 1423 1220 _yaxis, _yunit = data.get_yaxis() 1221 _xaxis, _xunit = data.get_xaxis() 1222 new_plot.title = data.name 1223 new_plot.group_id = data.group_id 1224 new_plot.id = str(page_id) + "model" 1225 if new_plot.id in self.color_dict: 1226 new_plot.custom_color = self.color_dict[new_plot.id] 1424 1227 #find if this theory was already plotted and replace that plot given 1425 1228 #the same id 1426 1427 theory_data = self.page_finder[page_id].get_theory_data() 1428 if theory_data is not None: 1429 new_plot.id = theory_data.id 1430 1431 new_plot.name = model.name + " ["+ str(model.__class__.__name__)+ "]" 1229 theory_data = self.page_finder[page_id].get_theory_data(fid=data.id) 1230 new_plot.name = model.name + " ["+ str(model.__class__.__name__)+"]" 1432 1231 new_plot.xaxis(_xaxis, _xunit) 1433 1232 new_plot.yaxis(_yaxis, _yunit) 1233 self.page_finder[page_id].set_theory_data(data=new_plot, fid=data.id) 1234 self.parent.update_theory(data_id=data.id, theory=new_plot, 1235 state=state) 1236 current_pg = self.fit_panel.get_page_by_id(page_id) 1237 title = new_plot.title 1238 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1239 title=str(title))) 1240 caption = current_pg.window_caption 1241 self.page_finder[page_id].set_fit_tab_caption(caption=caption) 1242 self.page_finder[page_id].set_theory_data(data=new_plot, 1243 fid=data.id) 1434 1244 if toggle_mode_on: 1435 new_plot.id = str(page_id) + " Model"1436 1245 wx.PostEvent(self.parent, 1437 1246 NewPlotEvent(group_id=str(page_id) + " Model2D", 1438 1247 action="Hide")) 1439 1440 self.page_finder[page_id].set_theory_data(new_plot)1441 if data is None:1442 data_id = None1443 1248 else: 1444 data_id = data.id 1445 1446 self.parent.update_theory(data_id=data_id, 1447 theory=new_plot, 1448 state=state) 1449 1450 current_pg = self.fit_panel.get_page_by_id(page_id) 1451 title = new_plot.title 1452 #print "just set the new plot color" 1453 if new_plot.id in self.color_dict: 1454 new_plot.custom_color = self.color_dict[new_plot.id] 1455 else: 1456 new_plot.custom_color = self.test_model_color 1457 1458 print "Current plot ID: ", new_plot.id 1459 print "Current plot Color: ", new_plot.custom_color 1460 #print "I HAVE JUST ADDED A NEW COLOR/ID ", new_plot.custom_color 1461 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1462 title= str(title))) 1463 1464 self.page_finder[page_id].set_theory_data(new_plot) 1465 1466 if update_chisqr: 1467 wx.PostEvent(current_pg, 1468 Chi2UpdateEvent(output=self._cal_chisqr(data=data, 1469 page_id=page_id, 1470 index=index))) 1471 else: 1472 self._plot_residuals(page_id, data, index) 1249 if update_chisqr: 1250 wx.PostEvent(current_pg, 1251 Chi2UpdateEvent(output=self._cal_chisqr(data=data, 1252 page_id=page_id, 1253 index=index))) 1254 else: 1255 self._plot_residuals(page_id, data, index) 1473 1256 1474 1257 msg = "Computation completed!" 1475 1258 wx.PostEvent( self.parent, StatusEvent(status=msg, type="stop" )) 1476 1477 #self.current_pg.state.theory_data = deepcopy(self.theory_data)1478 1259 except: 1479 1260 raise … … 1497 1278 that can be plot. 1498 1279 """ 1499 err_image = numpy.zeros(numpy.shape(image)) 1500 1501 new_plot= Data2D(image=image, err_image=err_image) 1280 new_plot= Data2D(image=image, err_image=data.err_data) 1502 1281 new_plot.name = model.name 1503 1282 new_plot.title = "Analytical model 2D " 1504 if data is None: 1505 self._fill_default_model2D(theory=new_plot, 1506 qmax=qmax, 1507 page_id=page_id, 1508 qstep=qstep, 1509 qmin= qmin) 1510 1511 else: 1512 new_plot.id = str(page_id) + " Model2D" 1513 new_plot.group_id = str(page_id) + " Model2D" 1514 new_plot.x_bins = data.x_bins 1515 new_plot.y_bins = data.y_bins 1516 new_plot.detector = data.detector 1517 new_plot.source = data.source 1518 new_plot.is_data = False 1519 new_plot.qx_data = data.qx_data 1520 new_plot.qy_data = data.qy_data 1521 new_plot.q_data = data.q_data 1522 #numpy.zeros(len(data.err_data))#data.err_data 1523 new_plot.err_data = err_image 1524 new_plot.mask = data.mask 1525 ## plot boundaries 1526 new_plot.ymin = data.ymin 1527 new_plot.ymax = data.ymax 1528 new_plot.xmin = data.xmin 1529 new_plot.xmax = data.xmax 1530 title = data.title 1531 if len(title) > 1: 1532 new_plot.title = "Model2D for " + data.name 1283 new_plot.id = str(page_id) + "model" 1284 new_plot.group_id = data.group_id 1285 new_plot.detector = data.detector 1286 new_plot.source = data.source 1287 new_plot.is_data = False 1288 new_plot.qx_data = data.qx_data 1289 new_plot.qy_data = data.qy_data 1290 new_plot.q_data = data.q_data 1291 new_plot.mask = data.mask 1292 ## plot boundaries 1293 new_plot.ymin = data.ymin 1294 new_plot.ymax = data.ymax 1295 new_plot.xmin = data.xmin 1296 new_plot.xmax = data.xmax 1297 title = data.title 1298 if len(title) > 1: 1299 new_plot.title = "Model2D for " + data.name 1533 1300 new_plot.is_data = False 1534 1301 new_plot.name = model.name + " ["+ str(model.__class__.__name__)+ "]" 1535 1536 1302 theory_data = deepcopy(new_plot) 1537 1303 theory_data.name = "Unknown" 1538 if toggle_mode_on: 1539 new_plot.id = str(page_id) + " Model" 1540 wx.PostEvent(self.parent, 1541 NewPlotEvent(group_id=str(page_id) + " Model1D", 1542 action="Hide")) 1543 1544 self.page_finder[page_id].set_theory_data(new_plot) 1545 if data is None: 1546 data_id = None 1547 else: 1548 data_id = data.id 1549 self.parent.update_theory(data_id=data_id, 1304 1305 self.page_finder[page_id].set_theory_data(data=theory_data, fid=data.id) 1306 self.parent.update_theory(data_id=data.id, 1550 1307 theory=new_plot, 1551 1308 state=state) 1552 1309 current_pg = self.fit_panel.get_page_by_id(page_id) 1553 1310 title = new_plot.title 1554 1555 1311 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, 1556 1312 title=title)) 1557 self.page_finder[page_id].set_theory_data(new_plot) 1558 # Chisqr in fitpage 1559 if update_chisqr: 1560 wx.PostEvent(current_pg, 1561 Chi2UpdateEvent(output=\ 1562 self._cal_chisqr(data=data, 1563 page_id=page_id, 1564 index=index))) 1313 self.page_finder[page_id].set_theory_data(data=new_plot, fid=data.id) 1314 if toggle_mode_on: 1315 wx.PostEvent(self.parent, 1316 NewPlotEvent(group_id=str(page_id) + " Model1D", 1317 action="Hide")) 1565 1318 else: 1566 self._plot_residuals(page_id, data, index) 1319 # Chisqr in fitpage 1320 if update_chisqr: 1321 wx.PostEvent(current_pg, 1322 Chi2UpdateEvent(output=self._cal_chisqr(data=data, 1323 page_id=page_id, 1324 index=index))) 1325 else: 1326 self._plot_residuals(page_id, data, index) 1567 1327 msg = "Computation completed!" 1568 1328 wx.PostEvent(self.parent, StatusEvent(status=msg, type="stop")) 1569 1329 1570 def _draw_model2D(self, model, page_id, data=None, smearer=None, 1330 def _draw_model2D(self, model, page_id, qmin, 1331 qmax, 1332 data=None, smearer=None, 1571 1333 description=None, enable2D=False, 1572 1334 state=None, 1573 1335 toggle_mode_on=False, 1574 qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, 1575 qstep=DEFAULT_NPTS, 1576 update_chisqr=True): 1336 update_chisqr=True): 1577 1337 """ 1578 1338 draw model in 2D … … 1586 1346 1587 1347 """ 1588 x= numpy.linspace(start=-1*qmax,1589 stop=qmax,1590 num=qstep,1591 endpoint=True)1592 y = numpy.linspace(start= -1*qmax,1593 stop=qmax,1594 num=qstep,1595 endpoint=True)1596 if model is None:1597 msg = "Panel with ID: %s does not contained model" % str(page_id)1598 raise ValueError, msg1599 ## use data info instead1600 if data is not None:1601 ## check if data2D to plot1602 if hasattr(data, "x_bins"):1603 enable2D = True1604 x = data.x_bins1605 y = data.y_bins1606 1607 1348 if not enable2D: 1608 return None , None1349 return None 1609 1350 try: 1610 1351 from model_thread import Calc2D … … 1612 1353 if (self.calc_2D is not None) and self.calc_2D.isrunning(): 1613 1354 self.calc_2D.stop() 1614 self.calc_2D = Calc2D(x=x, 1615 y=y, 1616 model=model, 1355 self.calc_2D = Calc2D(model=model, 1617 1356 data=data, 1618 1357 page_id=page_id, … … 1620 1359 qmin=qmin, 1621 1360 qmax=qmax, 1622 qstep=qstep,1623 1361 toggle_mode_on=toggle_mode_on, 1624 1362 state=state, 1625 1363 completefn=self._complete2D, 1626 #updatefn= self._update2D,1627 1364 update_chisqr=update_chisqr) 1628 1629 1365 self.calc_2D.queue() 1630 1366 … … 1635 1371 #wx.PostEvent(self.parent, StatusEvent(status=msg)) 1636 1372 1637 def _draw_model1D(self, model, page_id, data =None, smearer=None,1638 qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX,1373 def _draw_model1D(self, model, page_id, data, 1374 qmin, qmax, smearer=None, 1639 1375 state=None, 1640 toggle_mode_on=False, 1641 qstep=DEFAULT_NPTS, update_chisqr=True, 1376 toggle_mode_on=False, update_chisqr=True, 1642 1377 enable1D=True): 1643 1378 """ … … 1648 1383 1649 1384 """ 1650 x= numpy.linspace(start=qmin,1651 stop=qmax,1652 num=qstep,1653 endpoint=True1654 )1655 if data is not None:1656 ## check for data2D1657 if hasattr(data,"x_bins"):1658 return1659 x = data.x1660 if qmin == None :1661 qmin == DEFAULT_QMIN1662 1663 if qmax == None:1664 qmax == DEFAULT_QMAX1665 1385 if not enable1D: 1666 1386 return … … 1670 1390 if (self.calc_1D is not None) and self.calc_1D.isrunning(): 1671 1391 self.calc_1D.stop() 1672 self.calc_1D = Calc1D(x=x, 1673 data=data, 1392 self.calc_1D = Calc1D(data=data, 1674 1393 model=model, 1675 1394 page_id=page_id, … … 1682 1401 #updatefn = self._update1D, 1683 1402 update_chisqr=update_chisqr) 1684 1685 1403 self.calc_1D.queue() 1686 1404 except: … … 1688 1406 msg += " %s" % sys.exc_value 1689 1407 wx.PostEvent(self.parent, StatusEvent(status=msg)) 1690 1691 def _cal_chisqr(self, page_id, data=None, index=None): 1408 1409 1410 1411 def _cal_chisqr(self, page_id, data, index=None): 1692 1412 """ 1693 1413 Get handy Chisqr using the output from draw1D and 2D, … … 1696 1416 # default chisqr 1697 1417 chisqr = None 1698 1418 #to compute chisq make sure data has valid data 1699 1419 # return None if data == None 1700 if data == None: return chisqr 1420 if not check_data_validity(data): 1421 return chisqr 1701 1422 1702 1423 # Get data: data I, theory I, and data dI in order … … 1705 1426 index = numpy.ones(len(data.data),ntype=bool) 1706 1427 # get rid of zero error points 1707 index = index & (data.err_data != 0 1428 index = index & (data.err_data != 0) 1708 1429 index = index & (numpy.isfinite(data.data)) 1709 1430 fn = data.data[index] 1710 theory_data = self.page_finder[page_id].get_theory_data( )1431 theory_data = self.page_finder[page_id].get_theory_data(fid=data.id) 1711 1432 gn = theory_data.data[index] 1712 1433 en = data.err_data[index] … … 1723 1444 dy[dy==0] = 1 1724 1445 fn = data.y[index] 1725 theory_data = self.page_finder[page_id].get_theory_data( )1446 theory_data = self.page_finder[page_id].get_theory_data(fid=data.id) 1726 1447 gn = theory_data.y 1727 1448 en = dy[index] 1728 1729 1449 # residual 1730 1450 res = (fn - gn) / en … … 1732 1452 # get chisqr only w/finite 1733 1453 chisqr = numpy.average(residuals * residuals) 1734 1735 1454 self._plot_residuals(page_id, data, index) 1736 1455 return chisqr 1737 1456 1738 1739 1740 1457 def _plot_residuals(self, page_id, data=None, index=None): 1741 1458 """ … … 1746 1463 : Note: this is different from the residuals in cal_chisqr() 1747 1464 """ 1748 if data == None:1749 return1750 1751 1465 # Get data: data I, theory I, and data dI in order 1752 1466 if data.__class__.__name__ == "Data2D": 1753 1467 # build residuals 1754 #print data1755 1468 residuals = Data2D() 1756 1469 #residuals.copy_from_datainfo(data) … … 1759 1472 residuals.data = None 1760 1473 fn = data.data#[index] 1761 theory_data = self.page_finder[page_id].get_theory_data( )1474 theory_data = self.page_finder[page_id].get_theory_data(fid=data.id) 1762 1475 gn = theory_data.data#[index] 1763 1476 en = data.err_data#[index] … … 1774 1487 residuals.mask = data.mask 1775 1488 residuals.scale = 'linear' 1776 #print "print data",residuals1777 1489 # check the lengths 1778 1490 if len(residuals.data) != len(residuals.q_data): 1779 1491 return 1780 1781 1492 else: 1782 1493 # 1 d theory from model_thread is only in the range of index … … 1789 1500 dy[dy==0] = 1 1790 1501 fn = data.y[index] 1791 theory_data = self.page_finder[page_id].get_theory_data( )1502 theory_data = self.page_finder[page_id].get_theory_data(fid=data.id) 1792 1503 gn = theory_data.y 1793 1504 en = dy[index] … … 1804 1515 residuals.xaxis('\\rm{Q} ', 'A^{-1}') 1805 1516 residuals.yaxis('\\rm{Residuals} ', 'normalized') 1806 1807 1517 new_plot = residuals 1808 if data.id == None:1809 data.id = data.name1810 name = data.id1811 1518 new_plot.name = "Residuals for " + str(data.name) 1812 1519 ## allow to highlight data when plotted
Note: See TracChangeset
for help on using the changeset viewer.