source: sasview/sansview/perspectives/fitting/fitting.py @ 3dc83be

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 3dc83be was 3dc83be, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

Fix model change bug. Models can now be selected from the top menu or the model page menu with the same result. The 2D plot, if enabled, will also be correctly updated.

  • Property mode set to 100644
File size: 31.5 KB
RevLine 
[d89f09b]1import os,os.path, re
2import sys, wx, logging
[0550752]3import string, numpy, math
[d89f09b]4
[3b19ac9]5from copy import deepcopy
[dc317d1]6from danse.common.plottools.plottables import Data1D, Theory1D,Data2D
[6f73a08]7from danse.common.plottools.PlotPanel import PlotPanel
[d89f09b]8from sans.guicomm.events import NewPlotEvent, StatusEvent 
[568e1a5]9from sans.guicomm.events import EVT_SLICER_PARS
10
[6f73a08]11from sans.fit.AbstractFitEngine import Model,Data,FitData1D,FitData2D
[d89f09b]12from fitproblem import FitProblem
13from fitpanel import FitPanel
[e9b4cc4]14from fit_thread import FitThread
[2dbb681]15import models,modelpage
[e1a310f]16import fitpage1D,fitpage2D
[dabb633]17import park
[d250f7d]18DEFAULT_BEAM = 0.005
[cfc68540]19DEFAULT_QMIN = 0.0
20DEFAULT_QMAX = 0.15
21DEFAULT_NPTS = 40
[e9b4cc4]22import time
23import thread
24print "main",thread.get_ident()
25
[d89f09b]26class Plugin:
27    """
[dabb633]28        Fitting plugin is used to perform fit
[d89f09b]29    """
30    def __init__(self):
31        ## Plug-in name
32        self.sub_menu = "Fitting"
33       
34        ## Reference to the parent window
35        self.parent = None
36        self.menu_mng = models.ModelManager()
37        ## List of panels for the simulation perspective (names)
38        self.perspective = []
[568e1a5]39        self.mypanels=[]
[e9b4cc4]40        self.calc_thread = None
41        self.done = False
[d89f09b]42        # Start with a good default
43        self.elapsed = 0.022
44        self.fitter  = None
45       
46        #Flag to let the plug-in know that it is running standalone
47        self.standalone=True
48        ## Fit engine
[3b19ac9]49        self._fit_engine = 'scipy'
[b2c3225]50        self.enable_model2D=False
[d89f09b]51        # Log startup
52        logging.info("Fitting plug-in started")   
53
54    def populate_menu(self, id, owner):
55        """
56            Create a menu for the Fitting plug-in
57            @param id: id to create a menu
58            @param owner: owner of menu
59            @ return : list of information to populate the main menu
60        """
61        #Menu for fitting
62        self.menu1 = wx.Menu()
63        id1 = wx.NewId()
64        self.menu1.Append(id1, '&Show fit panel')
65        wx.EVT_MENU(owner, id1, self.on_perspective)
[3b19ac9]66        id3 = wx.NewId()
[442895f]67        self.menu1.AppendCheckItem(id3, "park") 
[3b19ac9]68        wx.EVT_MENU(owner, id3, self._onset_engine)
[d89f09b]69       
70        #menu for model
71        menu2 = wx.Menu()
[f39511b]72   
[d89f09b]73        self.menu_mng.populate_menu(menu2, owner)
74        id2 = wx.NewId()
75        owner.Bind(models.EVT_MODEL,self._on_model_menu)
[2dbb681]76        #owner.Bind(modelpage.EVT_MODEL,self._on_model_menu)
[d89f09b]77        self.fit_panel.set_owner(owner)
78        self.fit_panel.set_model_list(self.menu_mng.get_model_list())
[bcd6d51]79        owner.Bind(fitpage1D.EVT_MODEL_BOX,self._on_model_panel)
[e1a310f]80        owner.Bind(fitpage2D.EVT_MODEL_BOX,self._on_model_panel)
[3b19ac9]81        #create  menubar items
[d89f09b]82        return [(id, self.menu1, "Fitting"),(id2, menu2, "Model")]
83   
84   
85    def help(self, evt):
86        """
87            Show a general help dialog.
88            TODO: replace the text with a nice image
89        """
[d7d143b0]90        from helpDialog import  HelpWindow
91        dialog = HelpWindow(None, -1, 'HelpWindow')
92        if dialog.ShowModal() == wx.ID_OK:
93            pass
94        dialog.Destroy()
95       
[d89f09b]96   
97    def get_context_menu(self, graph=None):
98        """
99            Get the context menu items available for P(r)
100            @param graph: the Graph object to which we attach the context menu
101            @return: a list of menu items with call-back function
102        """
103        self.graph=graph
104        for item in graph.plottables:
[693ab78]105            if item.__class__.__name__ is "Data2D":
[2dbb681]106                return [["Select data  for Fitting",\
107                          "Dialog with fitting parameters ", self._onSelect]] 
[6f73a08]108            else:
[693ab78]109                if item.name==graph.selected_plottable and\
110                 item.__class__.__name__ is  "Data1D":
[2dbb681]111                    return [["Select data  for Fitting", \
112                             "Dialog with fitting parameters ", self._onSelect]] 
[d89f09b]113        return []   
114
115
116    def get_panels(self, parent):
117        """
118            Create and return a list of panel objects
119        """
120        self.parent = parent
121        # Creation of the fit panel
122        self.fit_panel = FitPanel(self.parent, -1)
123        #Set the manager forthe main panel
124        self.fit_panel.set_manager(self)
125        # List of windows used for the perspective
126        self.perspective = []
127        self.perspective.append(self.fit_panel.window_name)
128        # take care of saving  data, model and page associated with each other
[3b19ac9]129        self.page_finder = {}
130        #index number to create random model name
131        self.index_model = 0
[568e1a5]132        self.parent.Bind(EVT_SLICER_PARS, self._on_slicer_event)
[3b19ac9]133        #create the fitting panel
[568e1a5]134        #return [self.fit_panel]
135        self.mypanels.append(self.fit_panel)
136        return self.mypanels
137    def _on_slicer_event(self, event):
138        print "slicer event ", event.panel
139        new_panel = event.panel
140        # Set group ID if available
141        event_id = self.parent.popup_panel(new_panel)
142        #self.menu.Append(event_id, new_panel.window_caption,
143        #                 "Show %s plot panel" % new_panel.window_caption)
144        # Set UID to allow us to reference the panel later
145        new_panel.uid = event_id
146       
147        self.mypanels.append(new_panel) 
148        return       
[d23544dc]149    def _on_show_panel(self, event):
150        print "_on_show_panel: fitting"
[d89f09b]151     
152    def get_perspective(self):
153        """
154            Get the list of panel names for this perspective
155        """
156        return self.perspective
157   
158   
159    def on_perspective(self, event):
160        """
161            Call back function for the perspective menu item.
162            We notify the parent window that the perspective
163            has changed.
164        """
165        self.parent.set_perspective(self.perspective)
166   
167   
168    def post_init(self):
169        """
170            Post initialization call back to close the loose ends
171            [Somehow openGL needs this call]
172        """
173        self.parent.set_perspective(self.perspective)
174       
175       
176    def _onSelect(self,event):
177        """
178            when Select data to fit a new page is created .Its reference is
179            added to self.page_finder
180        """
181        self.panel = event.GetEventObject()
182        for item in self.panel.graph.plottables:
[693ab78]183            if item.name == self.panel.graph.selected_plottable or\
184                 item.__class__.__name__ is "Data2D":
[3b19ac9]185                #find a name for the page created for notebook
[d89f09b]186                try:
[6bcdad1]187                    page, model_name = self.fit_panel.add_fit_page(item)
[3b19ac9]188                    # add data associated to the page created
[bcd6d51]189                   
[6f73a08]190                    if page !=None:   
[caa1226]191                       
[6f73a08]192                        #create a fitproblem storing all link to data,model,page creation
193                        self.page_finder[page]= FitProblem()
[6bcdad1]194                        self.page_finder[page].save_model_name(model_name) 
[bcd6d51]195                        self.page_finder[page].add_data(item)
[d89f09b]196                except:
[6f73a08]197                    wx.PostEvent(self.parent, StatusEvent(status="Creating Fit page: %s"\
198                    %sys.exc_value))
[948add7]199    def schedule_for_fit(self,value=0,fitproblem =None): 
200        """
201       
202        """   
203        if fitproblem !=None:
204            fitproblem.schedule_tofit(value)
205        else:
206            current_pg=self.fit_panel.get_current_page() 
207            for page, val in self.page_finder.iteritems():
208                if page ==current_pg :
209                    val.schedule_tofit(value)
210                    break
211                     
[d89f09b]212                   
213    def get_page_finder(self):
214        """ @return self.page_finder used also by simfitpage.py""" 
215        return self.page_finder
216   
217   
[3b19ac9]218    def set_page_finder(self,modelname,names,values):
[d89f09b]219        """
220             Used by simfitpage.py to reset a parameter given the string constrainst.
221             @param modelname: the name ot the model for with the parameter has to reset
222             @param value: can be a string in this case.
[3b19ac9]223             @param names: the paramter name
[d89f09b]224             @note: expecting park used for fit.
225        """ 
226        sim_page=self.fit_panel.get_page(0)
227        for page, value in self.page_finder.iteritems():
228            if page != sim_page:
229                list=value.get_model()
230                model=list[0]
[bcd6d51]231                #print "fitting",model.name,modelname
[d89f09b]232                if model.name== modelname:
[3b19ac9]233                    value.set_model_param(names,values)
[d89f09b]234                    break
235
236   
237                           
238    def split_string(self,item): 
239        """
[3b19ac9]240            receive a word containing dot and split it. used to split parameterset
241            name into model name and parameter name example:
242            paramaterset (item) = M1.A
243            @return model_name =M1 , parameter name =A
[d89f09b]244        """
245        if string.find(item,".")!=-1:
246            param_names= re.split("\.",item)
247            model_name=param_names[0]
248            param_name=param_names[1] 
249            return model_name,param_name
250       
[e9b4cc4]251   
252    def _single_fit_completed(self,result,pars,cpage,qmin,qmax,elapsed,ymin=None, ymax=None):
[d89f09b]253        """
[3b19ac9]254            Display fit result on one page of the notebook.
255            @param result: result of fit
256            @param pars: list of names of parameters fitted
257            @param current_pg: the page where information will be displayed
258            @param qmin: the minimum value of x to replot the model
259            @param qmax: the maximum value of x to replot model
[d89f09b]260         
261        """
[e9b4cc4]262        #self.done = True
263        #wx.PostEvent(self.parent, StatusEvent(status="Fitting Completed: %g" % elapsed))
[d89f09b]264        try:
265            for page, value in self.page_finder.iteritems():
[948add7]266                if page==cpage :
[6f73a08]267                    #fitdata = value.get_data()
[d89f09b]268                    list = value.get_model()
269                    model= list[0]
270                    break
271            i = 0
[442895f]272#            print "fitting: single fit pars ", pars
[d89f09b]273            for name in pars:
274                if result.pvec.__class__==numpy.float64:
[1b07935d]275                    model.setParam(name,result.pvec)
[d89f09b]276                else:
[1b07935d]277                    model.setParam(name,result.pvec[i])
[442895f]278#                    print "fitting: single fit", name, result.pvec[i]
[d89f09b]279                    i += 1
[442895f]280#            print "fitting result : chisqr",result.fitness
281#            print "fitting result : pvec",result.pvec
282#            print "fitting result : stderr",result.stderr
283           
[948add7]284            cpage.onsetValues(result.fitness, result.pvec,result.stderr)
[9d31a8b]285            self.plot_helper(currpage=cpage,qmin=qmin,qmax=qmax,ymin=ymin, ymax=ymax)
[d89f09b]286        except:
[442895f]287            raise
[060b857]288            wx.PostEvent(self.parent, StatusEvent(status="Fitting error: %s" % sys.exc_value))
[d89f09b]289           
290       
[e9b4cc4]291    def _simul_fit_completed(self,result,qmin,qmax, elapsed,pars=None,cpage=None, ymin=None, ymax=None):
[d89f09b]292        """
293            Parameter estimation completed,
294            display the results to the user
295            @param alpha: estimated best alpha
296            @param elapsed: computation time
297        """
[e9b4cc4]298        wx.PostEvent(self.parent, StatusEvent(status="Fitting Completed: %g" % elapsed))
[d89f09b]299        try:
300            for page, value in self.page_finder.iteritems():
[948add7]301                if value.get_scheduled()==1:
[6f73a08]302                    #fitdata = value.get_data()
[3b19ac9]303                    list = value.get_model()
304                    model= list[0]
305                   
306                    small_out = []
307                    small_cov = []
308                    i = 0
309                    #Separate result in to data corresponding to each page
310                    for p in result.parameters:
311                        model_name,param_name = self.split_string(p.name) 
312                        if model.name == model_name:
313                            small_out.append(p.value )
314                            small_cov.append(p.stderr)
315                            model.setParam(param_name,p.value) 
316                    # Display result on each page
317                    page.onsetValues(result.fitness, small_out,small_cov)
318                    #Replot model
[9d31a8b]319                    self.plot_helper(currpage= page,qmin= qmin,qmax= qmax,ymin=ymin, ymax=ymax) 
[d89f09b]320        except:
321             wx.PostEvent(self.parent, StatusEvent(status="Fitting error: %s" % sys.exc_value))
322           
[e9b4cc4]323 
[9d31a8b]324    def _on_single_fit(self,id=None,qmin=None,qmax=None,ymin=None,ymax=None):
[d89f09b]325        """
326            perform fit for the  current page  and return chisqr,out and cov
327            @param engineName: type of fit to be performed
328            @param id: unique id corresponding to a fit problem(model, set of data)
329            @param model: model to fit
330           
331        """
[948add7]332        #print "in single fitting"
[d89f09b]333        #set an engine to perform fit
334        from sans.fit.Fitting import Fit
335        self.fitter= Fit(self._fit_engine)
[3b19ac9]336        #Setting an id to store model and data in fit engine
[d89f09b]337        if id==None:
338            id=0
[3b19ac9]339        self.id = id
[948add7]340        page_fitted=None
341        fit_problem=None
[3b19ac9]342        #Get information (model , data) related to the page on
343        #with the fit will be perform
[57f3320]344        #current_pg=self.fit_panel.get_current_page()
345        #simul_pg=self.fit_panel.get_page(0)
[948add7]346           
[d89f09b]347        for page, value in self.page_finder.iteritems():
[948add7]348            if  value.get_scheduled() ==1 :
[9d31a8b]349                metadata = value.get_data()
[d89f09b]350                list=value.get_model()
351                model=list[0]
[08b9c6c8]352                smearer= value.get_smearer()
[3b19ac9]353                #Create list of parameters for fitting used
[d89f09b]354                pars=[]
355                templist=[]
356                try:
[948add7]357                    #templist=current_pg.get_param_list()
358                    templist=page.get_param_list()
359                    for element in templist:
360                        pars.append(str(element[0].GetLabelText()))
361                    pars.sort()
362                    #Do the single fit
[3b19ac9]363                    self.fitter.set_model(Model(model), self.id, pars) 
[b710eb7]364                   
[08b9c6c8]365                    self.fitter.set_data(metadata,self.id,smearer, qmin,qmax)
[948add7]366                    self.fitter.select_problem_for_fit(Uid=self.id,value=value.get_scheduled())
367                    page_fitted=page
368                    self.id+=1
369                    self.schedule_for_fit( 0,value) 
[d89f09b]370                except:
[948add7]371                    wx.PostEvent(self.parent, StatusEvent(status="Fitting error: %s" % sys.exc_value))
[d89f09b]372                    return
[948add7]373                # make sure to keep an alphabetic order
374                #of parameter names in the list     
375        try:
[e9b4cc4]376            # If a thread is already started, stop it
377            if self.calc_thread != None and self.calc_thread.isrunning():
378                self.calc_thread.stop()
379                   
380            self.calc_thread =FitThread(parent =self.parent,
381                                        fn= self.fitter,
382                                        pars= pars,
383                                        cpage= page_fitted,
384                                       qmin=qmin,
385                                       qmax=qmax,
386                                       ymin= ymin,
387                                       ymax= ymax,
388                                       completefn=self._single_fit_completed,
389                                       updatefn=None)
390            self.calc_thread.queue()
391            self.calc_thread.ready(2.5)
392            #while not self.done:
393                #print "when here"
394             #   time.sleep(1)
395           
396           
[948add7]397        except:
[6f73a08]398            raise
[948add7]399            wx.PostEvent(self.parent, StatusEvent(status="Single Fit error: %s" % sys.exc_value))
400            return
[d89f09b]401         
[9d31a8b]402    def _on_simul_fit(self, id=None,qmin=None,qmax=None, ymin=None, ymax=None):
[d89f09b]403        """
404            perform fit for all the pages selected on simpage and return chisqr,out and cov
405            @param engineName: type of fit to be performed
406            @param id: unique id corresponding to a fit problem(model, set of data)
407             in park_integration
408            @param model: model to fit
409           
410        """
411        #set an engine to perform fit
412        from sans.fit.Fitting import Fit
413        self.fitter= Fit(self._fit_engine)
[3b19ac9]414       
[d89f09b]415        #Setting an id to store model and data
416        if id==None:
417             id = 0
418        self.id = id
[3b19ac9]419       
[d89f09b]420        for page, value in self.page_finder.iteritems():
421            try:
[948add7]422                if value.get_scheduled()==1:
[9d31a8b]423                    metadata = value.get_data()
[3b19ac9]424                    list = value.get_model()
425                    model= list[0]
[d89f09b]426                    #Create dictionary of parameters for fitting used
427                    pars = []
428                    templist = []
[3b19ac9]429                    templist = page.get_param_list()
[d89f09b]430                    for element in templist:
431                        try:
432                            name = str(element[0].GetLabelText())
433                            pars.append(name)
434                        except:
435                            wx.PostEvent(self.parent, StatusEvent(status="Fitting error: %s" % sys.exc_value))
436                            return
[00561739]437                    new_model=Model(model)
[8e81af0]438                    param=value.get_model_param()
439                   
440                    if len(param)>0:
441                        for item in param:
442                            param_value = item[1]
443                            param_name = item[0]
444                            #print "fitting ", param,param_name, param_value
445                           
446                            #new_model.set( model.getParam(param_name[0])= param_value)
447                            #new_model.set( exec"%s=%s"%(param_name[0], param_value))
448                            #new_model.set( exec "%s"%(param_nam) = param_value)
449                            new_model.parameterset[ param_name].set( param_value )
450                           
[948add7]451                    self.fitter.set_model(new_model, self.id, pars) 
[9d31a8b]452                    self.fitter.set_data(metadata,self.id,qmin,qmax,ymin,ymax)
[948add7]453                    self.fitter.select_problem_for_fit(Uid=self.id,value=value.get_scheduled())
[3b19ac9]454                    self.id += 1 
[d89f09b]455            except:
[3b19ac9]456                wx.PostEvent(self.parent, StatusEvent(status="Fitting error: %s" % sys.exc_value))
457                return 
[dabb633]458        #Do the simultaneous fit
[d89f09b]459        try:
[e9b4cc4]460            # If a thread is already started, stop it
461            if self.calc_thread != None and self.calc_thread.isrunning():
462                self.calc_thread.stop()
463                   
464            self.calc_thread =FitThread(parent =self.parent,
465                                        fn= self.fitter,
466                                       qmin=qmin,
467                                       qmax=qmax,
468                                       ymin= ymin,
469                                       ymax= ymax,
470                                       completefn= self._simul_fit_completed,
471                                       updatefn=None)
472            self.calc_thread.queue()
473            self.calc_thread.ready(2.5)
474           
[d89f09b]475        except:
476            wx.PostEvent(self.parent, StatusEvent(status="Simultaneous Fitting error: %s" % sys.exc_value))
477            return
[3b19ac9]478       
479       
480    def _onset_engine(self,event):
481        """ set engine to scipy"""
482        if self._fit_engine== 'park':
483            self._on_change_engine('scipy')
484        else:
485            self._on_change_engine('park')
486        wx.PostEvent(self.parent, StatusEvent(status="Engine set to: %s" % self._fit_engine))
487 
488   
[d89f09b]489    def _on_change_engine(self, engine='park'):
490        """
491            Allow to select the type of engine to perform fit
492            @param engine: the key work of the engine
493        """
494        self._fit_engine = engine
495   
496   
497    def _on_model_panel(self, evt):
498        """
499            react to model selection on any combo box or model menu.plot the model 
500        """
[e1a310f]501       
[d89f09b]502        model = evt.model
503        name = evt.name
504        sim_page=self.fit_panel.get_page(0)
505        current_pg = self.fit_panel.get_current_page() 
[6bcdad1]506        selected_page = self.fit_panel.get_selected_page()
[d89f09b]507        if current_pg != sim_page:
508            current_pg.set_panel(model)
[6bcdad1]509            model.name = self.page_finder[current_pg].get_name()
[d89f09b]510            try:
[bcd6d51]511                metadata=self.page_finder[current_pg].get_data()
[6bcdad1]512                M_name=model.name+"= "+name+"("+metadata.group_id+")"
[d89f09b]513            except:
[6bcdad1]514                M_name=model.name+"= "+name
515            #model.name="M"+str(self.index_model)
[d89f09b]516            self.index_model += 1 
[6bcdad1]517            # save model name
[442895f]518           
[6bcdad1]519            # save the name containing the data name with the appropriate model
[1b07935d]520            self.page_finder[current_pg].set_model(model,M_name)
[d89f09b]521            self.plot_helper(currpage= current_pg,qmin= None,qmax= None)
522            sim_page.add_model(self.page_finder)
523       
[08b9c6c8]524    def  set_smearer(self,smearer):     
525         current_pg=self.fit_panel.get_current_page()
526         self.page_finder[current_pg].set_smearer(smearer)
527         
[d89f09b]528    def redraw_model(self,qmin= None,qmax= None):
529        """
530            Draw a theory according to model changes or data range.
531            @param qmin: the minimum value plotted for theory
532            @param qmax: the maximum value plotted for theory
533        """
534        current_pg=self.fit_panel.get_current_page()
535        for page, value in self.page_finder.iteritems():
536            if page ==current_pg :
537                break 
538        self.plot_helper(currpage=page,qmin= qmin,qmax= qmax)
539       
[e9b4cc4]540    def plot_helper(self,currpage, fitModel=None, qmin=None,qmax=None,ymin=None,ymax=None):
[d89f09b]541        """
542            Plot a theory given a model and data
543            @param model: the model from where the theory is derived
544            @param currpage: page in a dictionary referring to some data
545        """
546        if self.fit_panel.get_page_count() >1:
547            for page in self.page_finder.iterkeys():
548                if  page==currpage : 
[bcd6d51]549                    data=self.page_finder[page].get_data()
550                    list=self.page_finder[page].get_model()
551                    model=list[0]
[d89f09b]552                    break 
[6f73a08]553           
[693ab78]554            if data!=None and data.__class__.__name__ != 'Data2D':
[d89f09b]555                theory = Theory1D(x=[], y=[])
[6bcdad1]556                theory.name = model.name
[d89f09b]557                theory.group_id = data.group_id
[6bcdad1]558                theory.id = "Model"
[d89f09b]559                x_name, x_units = data.get_xaxis() 
560                y_name, y_units = data.get_yaxis() 
561                theory.xaxis(x_name, x_units)
562                theory.yaxis(y_name, y_units)
563                if qmin == None :
564                   qmin = min(data.x)
565                if qmax == None :
566                    qmax = max(data.x)
567                try:
568                    tempx = qmin
[1b07935d]569                    tempy = model.run(qmin)
[d89f09b]570                    theory.x.append(tempx)
571                    theory.y.append(tempy)
572                except :
573                        wx.PostEvent(self.parent, StatusEvent(status="fitting \
574                        skipping point x %g %s" %(qmin, sys.exc_value)))
575                           
576                for i in range(len(data.x)):
577                    try:
578                        if data.x[i]> qmin and data.x[i]< qmax:
579                            tempx = data.x[i]
[1b07935d]580                            tempy = model.run(tempx)
[d89f09b]581                            theory.x.append(tempx) 
582                            theory.y.append(tempy)
[04edd0d]583                           
[d89f09b]584                    except:
585                        wx.PostEvent(self.parent, StatusEvent(status="fitting \
586                        skipping point x %g %s" %(data.x[i], sys.exc_value)))   
587                try:
588                    tempx = qmax
[1b07935d]589                    tempy = model.run(qmax)
[d89f09b]590                    theory.x.append(tempx)
591                    theory.y.append(tempy)
592                except:
[00561739]593                    wx.PostEvent(self.parent, StatusEvent(status="fitting \
594                        skipping point x %g %s" %(qmax, sys.exc_value)))
[04edd0d]595               
[6f73a08]596            else:
[dc317d1]597                theory=Data2D(data.data, data.err_data)
[6bcdad1]598                theory.name= model.name
599                theory.id= "Model"
600                theory.group_id= "Model"+data.name
[6f73a08]601                theory.x_bins= data.x_bins
602                theory.y_bins= data.y_bins
603                tempy=[]
[9d31a8b]604                if qmin==None:
605                    qmin=data.xmin
606                if qmax==None:
[4274c0e]607                    qmax=data.xmax
[9d31a8b]608                if ymin==None:
609                    ymin=data.ymin
610                if ymax==None:
[4274c0e]611                    ymax=data.ymax
[a890be6]612                   
[57668f8]613                theory.data = numpy.zeros((len(data.y_bins),len(data.x_bins)))
[44bbf6a]614                for i in range(len(data.y_bins)):
615                    if data.y_bins[i]>= ymin and data.y_bins[i]<= ymax:
616                        for j in range(len(data.x_bins)):
617                            if data.x_bins[i]>= qmin and data.x_bins[i]<= qmax:
[57668f8]618                                theory.data[j][i]=model.runXY([data.x_bins[j],data.y_bins[i]])
[44bbf6a]619               
620                #print "fitting : plot_helper:", theory.image
[6f73a08]621                #print data.image
[2dbb681]622                #print "fitting : plot_helper:",theory.image
[1f62278]623                theory.detector= data.detector
624                theory.source= data.source
[6f73a08]625                theory.zmin= data.zmin
626                theory.zmax= data.zmax
[4274c0e]627                theory.xmin= qmin
628                theory.xmax= qmax
629                theory.ymin= ymin
630                theory.ymax= ymax
[04edd0d]631       
[6bcdad1]632        wx.PostEvent(self.parent, NewPlotEvent(plot=theory,
633                                                title="Analytical model %s"%str(data.name)))
[6f73a08]634       
635       
[d89f09b]636    def _on_model_menu(self, evt):
637        """
638            Plot a theory from a model selected from the menu
639        """
[86c1832]640        name = evt.model.__name__
641        if hasattr(evt.model, "name"):
642            name = evt.model.name
[b2c3225]643        model=evt.model()
[2dbb681]644        description=model.description
[3dc83be]645       
646        # Create a model page. If a new page is created, the model
647        # will be plotted automatically. If a page already exists,
648        # the content will be updated and the plot refreshed
649        self.fit_panel.add_model_page(model,description,name,topmenu=True)
[1b07935d]650       
[cfc68540]651    def draw_model(self,model,name ,description=None,enable1D=True, enable2D=False,
652                   qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep=DEFAULT_NPTS):
[3b19ac9]653        """
654             draw model with default data value
655        """
[d74d751]656        self._draw_model2D(model=model,
657                           description=model.description,
658                           enable2D= enable2D,
659                           qmin=qmin,
660                           qmax=qmax,
[c48a26a]661                           qstep=qstep)
[86c1832]662        self._draw_model1D(model,name,model.description, enable1D,qmin,qmax, qstep)
[cfc68540]663             
664    def _draw_model1D(self,model,name,description=None, enable1D=True,
665                      qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep=DEFAULT_NPTS):
[e5a9e32]666       
[d250f7d]667        if enable1D:
[d15c0202]668            x=  numpy.linspace(start= qmin,
669                               stop= qmax,
670                               num= qstep,
671                               endpoint=True
672                               )     
[f39511b]673            xlen= len(x)
674            y = numpy.zeros(xlen)
[d250f7d]675            if not enable1D:
[f39511b]676                for i in range(xlen):
677                    y[i] = model.run(x[i])
[d15c0202]678               
[f39511b]679                try:
680                    new_plot = Theory1D(x, y)
[86c1832]681                    new_plot.name = name
[f39511b]682                    new_plot.xaxis("\\rm{Q}", 'A^{-1}')
683                    new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
[6bcdad1]684                    new_plot.id = "Model"
685                    new_plot.group_id ="Model"
[f39511b]686                    wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="Analytical model 1D"))
687                   
688                except:
689                    raise
690            else:
691                for i in range(xlen):
692                    y[i] = model.run(x[i])
[d15c0202]693                #print x, y   
[f39511b]694                try:
695                    new_plot = Theory1D(x, y)
[86c1832]696                    new_plot.name = name
[f39511b]697                    new_plot.xaxis("\\rm{Q}", 'A^{-1}')
698                    new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
[6bcdad1]699                    new_plot.id ="Model"
700                    new_plot.group_id ="Model"
[3dc83be]701                   
702                    # Pass the reset flag to let the plotting event handler
703                    # know that we are replacing the whole plot
[6bcdad1]704                    wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,
[3dc83be]705                                     title="Analytical model 1D ", reset=True ))
[f39511b]706                   
707                except:
708                    raise
[e9b4cc4]709    def update(self, output,time):
710        pass
[20be946]711   
712    def complete(self, output, elapsed, model, qmin, qmax):
[e9b4cc4]713       
[20be946]714        wx.PostEvent(self.parent, StatusEvent(status="Calc \
715        complete in %g sec" % elapsed))
[d15c0202]716        #print "complete",output, model,qmin, qmax
[20be946]717        data = output
718        theory= Data2D(data)
[d15c0202]719        #print data.detector
720        #theory.detector= data.detector
721        from DataLoader.data_info import Detector, Source
722       
723        detector = Detector()
724        theory.detector=[]
725        theory.detector.append(detector)
726           
727        theory.detector[0].pixel_size.x= 5.0
728        theory.detector[0].pixel_size.y= 5.0
729        theory.source= Source()
730        theory.source.wavelength= 8.4
731        theory.detector[0].beam_center.x= 0
732        theory.detector[0].beam_center.y= 0
733        theory.detector[0].distance= 13705.0
734       
[20be946]735        theory.name= model.name
736        theory.group_id ="Model"
737        theory.id ="Model"
[d15c0202]738        theory.xmin= -qmax
[20be946]739        theory.xmax= qmax
[d15c0202]740        theory.ymin= -qmax
[20be946]741        theory.ymax= qmax
[d15c0202]742        print "model draw comptele xmax",theory.xmax
[20be946]743        wx.PostEvent(self.parent, NewPlotEvent(plot=theory,
[3dc83be]744                         title="Analytical model 2D %s" %str(model.name), reset=True))
[20be946]745         
746       
747         
[cfc68540]748    def _draw_model2D(self,model,description=None, enable2D=False,
749                      qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep=DEFAULT_NPTS):
[d15c0202]750       
751        x=  numpy.linspace(start= -1*qmax,
752                               stop= qmax,
753                               num= qstep,
754                               endpoint=True ) 
755        y = numpy.linspace(start= -1*qmax,
756                               stop= qmax,
757                               num= qstep,
758                               endpoint=True )
759       
[dc317d1]760        lx = len(x)
[1c5b068]761        #print x
[dc317d1]762        data=numpy.zeros([len(x),len(y)])
[20be946]763        self.model= model
[dc317d1]764        if enable2D:
[20be946]765            from model_thread import Calc2D
[d15c0202]766            self.calc_thread = Calc2D(parent =self.parent,x=x,
767                                       y=y,model= self.model, 
768                                       qmin=qmin,
769                                       qmax=qmax,
[20be946]770                            completefn=self.complete,
[e9b4cc4]771                            updatefn=None)
[20be946]772            self.calc_thread.queue()
773            self.calc_thread.ready(2.5)
774           
[db709e4]775   
[d89f09b]776if __name__ == "__main__":
777    i = Plugin()
778   
779   
780   
781   
Note: See TracBrowser for help on using the repository browser.