source: sasview/sansview/perspectives/fitting/fitpanel.py @ afab469

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 afab469 was 3244cbe1, checked in by Gervaise Alina <gervyh@…>, 15 years ago

add media folder , reverse fit_panel for now

  • Property mode set to 100644
File size: 17.4 KB
Line 
1
2import numpy
3import string 
4import wx
5import wx.aui
6import wx.lib
7from wx.aui import AuiNotebook
8
9
10import basepage
11
12_BOX_WIDTH = 80
13
14
15class StateIterator(object):
16    """
17        Contains all saved state of a given page.
18        Provide position of the current state of a page, the first save state
19        and the last state for a given page.
20        Allow easy undo or redo for a given page 
21    """
22    def __init__(self):
23        self._current=0
24       
25   
26    def __iter__(self):
27        return self
28   
29   
30    def first(self):
31        self._current =0
32        return self._current
33   
34    def next(self, max ):
35        if self._current < max:
36            self._current += 1
37        return self._current
38   
39    def previous(self):
40        if self._current > 0:
41            self._current = self._current -1
42        return self._current
43   
44    def currentPosition(self):
45        return self._current
46   
47    def setPosition(self, value):
48        if value >=0:
49            self._current = int(value)
50       
51       
52   
53 
54class ListOfState(list):     
55    def __init__(self, *args, **kw):
56        list.__init__(self, *args, **kw)
57        self.iterator = StateIterator()
58       
59    def appendItem(self, x):
60        self.append(x)
61        self.iterator.setPosition(value= len(self)-1)
62       
63    def removeItem(self, x):
64        self.iterator.previous()
65        self.remove(x)
66       
67    def getPreviousItem(self):
68        position = self.iterator.previous()
69       
70        if position < 0:
71            return None
72        else:
73            return self[position]
74       
75    def getNextItem(self):
76        position = self.iterator.next(max= len(self)-1)
77        if position >= len(self):
78            return None
79        else:
80            return self[position]
81       
82    def getCurrentItem(self):
83        postion = self.iterator.currentPosition()
84        if postion >= 0 and position < len(self):
85            return self[postion]
86        else:
87            return None
88       
89    def getCurrentPosition(self):
90        return self.iterator.currentPosition()
91       
92
93       
94       
95       
96class PageInfo(object):
97    """
98        this class contains the minimum numbers of data members
99        a fitpage or model page need to be initialized.
100    """
101    data = None
102    model =  None
103    manager = None
104    event_owner= None
105    model_list_box = None
106    name = None
107    ## Internal name for the AUI manager
108    window_name = "Page"
109    ## Title to appear on top of the window
110    window_caption = "Page"
111   
112    def __init__(self, model=None,data=None, manager=None,
113                  event_owner=None,model_list_box=None , name=None):
114        """
115            Initialize data members
116        """
117        self.data = data
118        self.model= model
119        self.manager= manager
120        self.event_owner= event_owner
121        self.model_list_box = model_list_box
122        self.name=None
123        self.window_name = "Page"
124        self.window_caption = "Page"
125   
126class FitPanel(AuiNotebook):   
127
128    """
129        FitPanel class contains fields allowing to fit  models and  data
130        @note: For Fit to be performed the user should check at least one parameter
131        on fit Panel window.
132       
133    """
134    ## Internal name for the AUI manager
135    window_name = "Fit panel"
136    ## Title to appear on top of the window
137    window_caption = "Fit Panel "
138    CENTER_PANE = True
139   
140    def __init__(self, parent, *args, **kwargs):
141        AuiNotebook.__init__(self,parent,-1,
142                    style= wx.aui.AUI_NB_WINDOWLIST_BUTTON|
143                    wx.aui.AUI_NB_DEFAULT_STYLE|
144                    wx.CLIP_CHILDREN)
145   
146        self.manager=None
147        self.parent=parent
148        self.event_owner=None
149       
150        pageClosedEvent = wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE
151        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.onClosePage)
152       
153        #dictionary of miodel {model class name, model class}
154        self.model_list_box={}
155        ##dictionary of page info
156        self.page_info_dict={}
157        ## save the title of the last page tab added
158        self.fit_page_name={}
159        ## list of existing fit page
160        self.list_fitpage_name=[]
161   
162        #model page info
163        self.model_page_number = None
164        ## fit page number for model plot
165        self.fit_page1D_number = None
166        self.fit_page2D_number = None
167        self.model_page = None
168        self.sim_page = None
169        self.default_page = None
170        self.check_first_data = False
171        ## get the state of a page
172        self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate)
173        self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo)
174        self.Bind(basepage.EVT_NEXT_STATE, self._onRedo)
175       
176        #add default page
177        from hint_fitpage import HintFitPage
178        self.hint_page = HintFitPage(self) 
179        self.AddPage(page=self.hint_page, caption="Hint")
180        #Add the first fit page
181        self.default_page = self.add_fit_page(data=None)
182       
183        # increment number for model name
184        self.count=0
185        #updating the panel
186        self.Update()
187        self.Center()
188       
189       
190    def onClosePage(self, event):
191        """
192             close page and remove all references to the closed page
193        """
194        nbr_page = self.GetPageCount()
195        if nbr_page == 1:
196            event.Veto()
197            return 
198        selected_page = self.GetPage(self.GetSelection())
199        #remove default page
200        if selected_page == self.default_page:
201            self.default_page = None
202            return 
203        #remove hint page
204        if selected_page == self.hint_page:
205            return
206        ## removing sim_page
207        if selected_page == self.sim_page :
208            self.manager.sim_page=None 
209            return
210       
211        ## closing other pages
212        state = selected_page.createMemento()
213        page_name = selected_page.window_name
214        page_finder = self.manager.get_page_finder() 
215        fitproblem = None
216        ## removing model page
217        if selected_page == self.model_page:
218            #fitproblem = selected_page.model.clone()
219            self.model_page = None
220            self.count =0
221            ## page on menu
222            #self.manager._add_page_onmenu(page_name, fitproblem)
223        else:
224            if selected_page in page_finder:
225       
226                #fitproblem= page_finder[selected_page].clone()
227                if self.GetPageIndex(selected_page)==self.fit_page1D_number:
228                    self.fit_page1D_number=None
229                if self.GetPageIndex(selected_page)==self.fit_page2D_number:
230                    self.fit_page2D_number=None
231                ## page on menu
232                #self.manager._add_page_onmenu(page_name, fitproblem)
233                del page_finder[selected_page]
234            ##remove the check box link to the model name of this page (selected_page)
235            try:
236                self.sim_page.draw_page()
237            except:
238                ## that page is already deleted no need to remove check box on
239                ##non existing page
240                pass
241               
242        #Delete the name of the page into the list of open page
243        if selected_page.window_name in self.list_fitpage_name:
244            self.list_fitpage_name.remove(selected_page.window_name)
245           
246       
247    def set_manager(self, manager):
248        """
249             set panel manager
250             @param manager: instance of plugin fitting
251        """
252        self.manager = manager
253
254       
255    def set_owner(self,owner):
256        """
257            set and owner for fitpanel
258            @param owner: the class responsible of plotting
259        """
260        self.event_owner = owner
261   
262    def set_model_list(self, dict):
263         """
264             copy a dictionary of model into its own dictionary
265             @param dict: dictionnary made of model name as key and model class
266             as value
267         """
268         self.model_list_box = dict
269       
270 
271    def get_current_page(self):
272        """
273            @return the current page selected
274        """
275        return self.GetPage(self.GetSelection() )
276   
277    def add_sim_page(self):
278        """
279            Add the simultaneous fit page
280        """
281        from simfitpage import SimultaneousFitPage
282        page_finder= self.manager.get_page_finder()
283        self.sim_page = SimultaneousFitPage(self,page_finder=page_finder, id=-1)
284       
285        self.AddPage(self.sim_page,caption="Simultaneous Fit",select=True)
286        self.sim_page.set_manager(self.manager)
287        return self.sim_page
288       
289       
290    def add_fit_page( self,data=None, reset=False ):
291        """
292            Add a fitting page on the notebook contained by fitpanel
293            @param data: data to fit
294            @return panel : page just added for further used. is used by fitting module
295        """   
296        if data is not None:
297            if data.is_data:
298                name = data.name
299            else:
300                if data.__class__.__name__=="Data2D":
301                    name = 'Model 2D Fit'
302                else:
303                    name = 'Model 1D Fit'
304            myinfo = PageInfo( data=data, name=name )
305            myinfo.model_list_box = self.model_list_box.get_list()
306            myinfo.event_owner = self.event_owner
307            myinfo.manager = self.manager
308            myinfo.window_name = name
309            myinfo.window_caption = name
310       
311        else :
312            name = "Fit Page" 
313            myinfo = PageInfo( data=data, name=name )
314       
315        if not name in self.list_fitpage_name:
316            # the first data loading
317            if not self.check_first_data and self.default_page is not None:
318                page_number = self.GetPageIndex(self.default_page)
319                self.SetPageText(page_number , name)
320                self.default_page.set_data(data)
321                self.default_page.set_page_info(page_info=myinfo)
322                self.default_page.initialize_combox()
323                if  data is not None:
324                    self.check_first_data = True
325                panel = self.default_page
326            else:
327                #if not name in self.fit_page_name :
328                from fitpage import FitPage
329                panel = FitPage(parent=self, page_info=myinfo)
330               
331                self.AddPage(page=panel, caption=name, select=True)
332                if name == 'Model 1D Fit':
333                    self.fit_page1D_number= self.GetPageIndex(panel)
334                if name =='Model 2D Fit':
335                    self.fit_page2D_number= self.GetPageIndex(panel)
336                   
337                self.list_fitpage_name.append(name)
338                if data is not None:
339                    if reset:
340                        if name in self.fit_page_name.keys():
341                            memento= self.fit_page_name[name][0]
342                            panel.reset_page(memento)
343                        else:
344                            self.fit_page_name[name]=ListOfState()
345                   
346                    #self.fit_page_name[name].appendItem(panel.createMemento())
347            #GetPage(self, page_idx)
348            return panel
349        elif name =='Model 1D Fit':
350            if self.fit_page1D_number!=None:
351                panel =self.GetPage(self.fit_page1D_number) 
352                #self.fit_page_name[name]=[]
353                self.fit_page_name[name]= ListOfState()
354                #self.fit_page_name[name].insert(0,panel.createMemento())
355                #self.fit_page_name[name].append(panel.createMemento())
356                return panel
357            return None
358        elif name =='Model 2D Fit':
359            if self.fit_page2D_number!=None:
360                panel =self.GetPage(self.fit_page2D_number) 
361                self.fit_page_name[name]=ListOfState()
362                #self.fit_page_name[name].append(panel.createMemento())
363                return panel
364            return None
365        return None
366       
367   
368    def add_model_page(self,model,page_title="Model", qmin=0.0001, qmax=0.13,
369                        npts=50, topmenu=False, reset=False):
370        """
371            Add a model page only one  to display any model selected from the menu or the page combo box.
372            when this page is closed than the user will be able to open a new one
373           
374            @param model: the model for which paramters will be changed
375            @param page_title: the name of the page
376            @param page_info: contains info about the state of the page
377            @param qmin: mimimum Q
378            @param qmax: maximum Q
379            @param npts: number of Q points
380        """
381        if topmenu==True:
382            ##first time to open model page
383            if self.count==0 :
384                #if not page_title in self.list_fitpage_name :
385                self._help_add_model_page(model=model, page_title=page_title,
386                                qmin=qmin, qmax=qmax, npts=npts, reset=reset)
387                self.count +=1
388            else:
389                self.model_page.select_model(model)
390                self.fit_page_name[page_title]=ListOfState()
391                #self.fit_page_name[page_title].insert(0,self.model_page.createMemento())
392     
393     
394     
395    def _close_fitpage(self,data):
396        """
397            close a fit page when its data is completely remove from the graph
398        """
399        name = data.name
400        for index in range(self.GetPageCount()):
401            if self.GetPageText(index)== name:
402                selected_page = self.GetPage(index) 
403   
404                if index ==self.fit_page1D_number:
405                    self.fit_page1D_number=None
406                if index ==self.fit_page2D_number:
407                    self.fit_page2D_number=None
408                if selected_page in self.manager.page_finder:
409                    del self.manager.page_finder[selected_page]
410                ##remove the check box link to the model name of this page (selected_page)
411                try:
412                    self.sim_page.draw_page()
413                except:
414                    ## that page is already deleted no need to remove check box on
415                    ##non existing page
416                    pass
417               
418                #Delete the name of the page into the list of open page
419                if selected_page.window_name in self.list_fitpage_name:
420                    self.list_fitpage_name.remove(selected_page.window_name)
421                self.DeletePage(index)
422                break
423       
424       
425    def  _onGetstate(self, event):
426        """
427            copy the state of a page
428        """
429        page= event.page
430        if page.window_name in self.fit_page_name:
431            self.fit_page_name[page.window_name].appendItem(page.createMemento()) 
432           
433    def _onUndo(self, event ):
434        """
435            return the previous state of a given page is available
436        """
437        page = event.page
438        if page.window_name in self.fit_page_name:
439            if self.fit_page_name[page.window_name].getCurrentPosition()==0:
440                state = None
441            else:
442                state = self.fit_page_name[page.window_name].getPreviousItem()
443                page._redo.Enable(True)
444            page.reset_page(state)
445       
446    def _onRedo(self, event ): 
447        """
448            return the next state available
449        """       
450        page = event.page
451        if page.window_name in self.fit_page_name:
452            length= len(self.fit_page_name[page.window_name])
453            if self.fit_page_name[page.window_name].getCurrentPosition()== length -1:
454                state = None
455                page._redo.Enable(False)
456                page._redo.Enable(True)
457            else:
458                state = self.fit_page_name[page.window_name].getNextItem()
459            page.reset_page(state) 
460               
461    def _help_add_model_page(self,model,page_title="Model", qmin=0.0001, 
462                             qmax=0.13, npts=50,reset= False):
463        """
464            #TODO: fill in description
465           
466            @param qmin: mimimum Q
467            @param qmax: maximum Q
468            @param npts: number of Q points
469        """
470        ## creating object that contaning info about model
471        myinfo = PageInfo(model= model ,name= page_title)
472        myinfo.model_list_box = self.model_list_box.get_list()
473        myinfo.event_owner = self.event_owner
474        myinfo.manager = self.manager
475        myinfo.window_name = page_title
476        myinfo.window_caption = page_title
477     
478        from modelpage import ModelPage
479        panel = ModelPage(self,myinfo)
480       
481        self.AddPage(page=panel, caption=page_title, select=True)
482
483        self.model_page_number=self.GetSelection()
484        self.model_page=self.GetPage(self.GetSelection())
485     
486        ##resetting page
487        if reset:
488            if page_title in self.fit_page_name.keys():
489
490                memento= self.fit_page_name[page_title][0]
491                panel.reset_page(memento)
492        else:
493            self.fit_page_name[page_title]=ListOfState()
494            #self.fit_page_name[page_title]=[]
495            #self.fit_page_name[page_title].insert(0,panel.createMemento())
496       
497 
Note: See TracBrowser for help on using the repository browser.