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

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 5612152 was 5612152, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

sansview: modified the application to pass a welcome panel class to the gui manager instead of making it part of the fit perspective.

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