source: sasview/sansview/perspectives/fitting/fitpanel.py @ 9237df4

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 9237df4 was 9237df4, checked in by Gervaise Alina <gervyh@…>, 14 years ago

some change for danse meeting

  • Property mode set to 100644
File size: 15.9 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        #add default page
171        from hint_fitpage import HintFitPage
172        panel = HintFitPage(self) 
173        self.AddPage(page=panel, caption="Hint")
174        # increment number for model name
175        self.count=0
176        #updating the panel
177        self.Update()
178        self.Center()
179       
180       
181    def onClosePage(self, event):
182        """
183             close page and remove all references to the closed page
184        """
185        selected_page = self.GetPage(self.GetSelection())
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    def _onUndo(self, event ):
396        """
397            return the previous state of a given page is available
398        """
399        page = event.page
400        if page.window_name in self.fit_page_name:
401            if self.fit_page_name[page.window_name].getCurrentPosition()==0:
402                state = None
403            else:
404                state = self.fit_page_name[page.window_name].getPreviousItem()
405                page._redo.Enable(True)
406            page.reset_page(state)
407       
408    def _onRedo(self, event ): 
409        """
410            return the next state available
411        """       
412        page = event.page
413        if page.window_name in self.fit_page_name:
414            length= len(self.fit_page_name[page.window_name])
415            if self.fit_page_name[page.window_name].getCurrentPosition()== length -1:
416                state = None
417                page._redo.Enable(False)
418                page._redo.Enable(True)
419            else:
420                state = self.fit_page_name[page.window_name].getNextItem()
421            page.reset_page(state) 
422               
423    def _help_add_model_page(self,model,page_title="Model", qmin=0.0001, 
424                             qmax=0.13, npts=50,reset= False):
425        """
426            #TODO: fill in description
427           
428            @param qmin: mimimum Q
429            @param qmax: maximum Q
430            @param npts: number of Q points
431        """
432        ## creating object that contaning info about model
433        myinfo = PageInfo(model= model ,name= page_title)
434        myinfo.model_list_box = self.model_list_box.get_list()
435        myinfo.event_owner = self.event_owner
436        myinfo.manager = self.manager
437        myinfo.window_name = page_title
438        myinfo.window_caption = page_title
439     
440        from modelpage import ModelPage
441        panel = ModelPage(self,myinfo)
442       
443        self.AddPage(page=panel, caption=page_title, select=True)
444
445        self.model_page_number=self.GetSelection()
446        self.model_page=self.GetPage(self.GetSelection())
447     
448        ##resetting page
449        if reset:
450            if page_title in self.fit_page_name.keys():
451
452                memento= self.fit_page_name[page_title][0]
453                panel.reset_page(memento)
454        else:
455            self.fit_page_name[page_title]=ListOfState()
456            #self.fit_page_name[page_title]=[]
457            #self.fit_page_name[page_title].insert(0,panel.createMemento())
458       
459 
Note: See TracBrowser for help on using the repository browser.