source: sasview/sansview/perspectives/fitting/fitpanel.py @ 8d78399

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 8d78399 was f20767b, checked in by Jae Cho <jhjcho@…>, 15 years ago

Working on 'Save(keep)' option. Still more to do on adding comments, on checkbox for array dispersion, and on bugs as being found.

  • Property mode set to 100644
File size: 15.8 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 sim_page
183        if selected_page == self.sim_page:
184            self.manager.sim_page=None 
185            return
186       
187        ## closing other pages
188        state = selected_page.createMemento()
189        page_name = selected_page.window_name
190        page_finder = self.manager.get_page_finder() 
191        fitproblem = None
192        ## removing model page
193        if selected_page == self.model_page:
194            fitproblem = selected_page.model.clone()
195            self.model_page = None
196            self.count =0
197            ## page on menu
198            self.manager._add_page_onmenu(page_name, fitproblem)
199        else:
200            if selected_page in page_finder:
201       
202                fitproblem= page_finder[selected_page].clone()
203                if self.GetPageIndex(selected_page)==self.fit_page1D_number:
204                    self.fit_page1D_number=None
205                if self.GetPageIndex(selected_page)==self.fit_page2D_number:
206                    self.fit_page2D_number=None
207                ## page on menu
208                self.manager._add_page_onmenu(page_name, fitproblem)
209                del page_finder[selected_page]
210            ##remove the check box link to the model name of this page (selected_page)
211            try:
212                self.sim_page.draw_page()
213            except:
214                ## that page is already deleted no need to remove check box on
215                ##non existing page
216                pass
217               
218        #Delete the name of the page into the list of open page
219        if selected_page.window_name in self.list_fitpage_name:
220            self.list_fitpage_name.remove(selected_page.window_name)
221           
222       
223    def set_manager(self, manager):
224        """
225             set panel manager
226             @param manager: instance of plugin fitting
227        """
228        self.manager = manager
229
230       
231    def set_owner(self,owner):
232        """
233            set and owner for fitpanel
234            @param owner: the class responsible of plotting
235        """
236        self.event_owner = owner
237   
238    def set_model_list(self,dict):
239         """
240             copy a dictionary of model into its own dictionary
241             @param dict: dictionnary made of model name as key and model class
242             as value
243         """
244         self.model_list_box = dict
245       
246 
247    def get_current_page(self):
248        """
249            @return the current page selected
250        """
251        return self.GetPage(self.GetSelection() )
252   
253    def add_sim_page(self):
254        """
255            Add the simultaneous fit page
256        """
257        from simfitpage import SimultaneousFitPage
258        page_finder= self.manager.get_page_finder()
259        self.sim_page = SimultaneousFitPage(self,page_finder=page_finder, id=-1)
260       
261        self.AddPage(self.sim_page,caption="Simultaneous Fit",select=True)
262        self.sim_page.set_manager(self.manager)
263        return self.sim_page
264       
265    def add_fit_page( self,data, reset=False ):
266        """
267            Add a fitting page on the notebook contained by fitpanel
268            @param data: data to fit
269            @return panel : page just added for further used. is used by fitting module
270        """     
271        if data.is_data:
272            name = data.name
273        else:
274            if data.__class__.__name__=="Data2D":
275                name = 'Model 2D Fit'
276            else:
277                name = 'Model 1D Fit'
278        if not name in self.list_fitpage_name:
279            myinfo = PageInfo( data=data, name=name )
280            myinfo.model_list_box = self.model_list_box.get_list()
281            myinfo.event_owner = self.event_owner
282            myinfo.manager = self.manager
283            myinfo.window_name = name
284            myinfo.window_caption = name
285       
286            #if not name in self.fit_page_name :
287            from fitpage import FitPage
288            panel = FitPage(parent= self, page_info=myinfo)
289           
290            self.AddPage(page=panel, caption=name, select=True)
291            if name == 'Model 1D Fit':
292                self.fit_page1D_number= self.GetPageIndex(panel)
293            if name =='Model 2D Fit':
294                self.fit_page2D_number= self.GetPageIndex(panel)
295               
296            self.list_fitpage_name.append(name)
297            if reset:
298                if name in self.fit_page_name.keys():
299                    memento= self.fit_page_name[name][0]
300                    panel.reset_page(memento)
301            else:
302                self.fit_page_name[name]=ListOfState()
303               
304                #self.fit_page_name[name].appendItem(panel.createMemento())
305            #GetPage(self, page_idx)
306            return panel
307        elif name =='Model 1D Fit':
308            if self.fit_page1D_number!=None:
309                panel =self.GetPage(self.fit_page1D_number) 
310                #self.fit_page_name[name]=[]
311                self.fit_page_name[name]= ListOfState()
312                #self.fit_page_name[name].insert(0,panel.createMemento())
313                #self.fit_page_name[name].append(panel.createMemento())
314                return panel
315            return None
316        elif name =='Model 2D Fit':
317            if self.fit_page2D_number!=None:
318                panel =self.GetPage(self.fit_page2D_number) 
319                self.fit_page_name[name]=ListOfState()
320                #self.fit_page_name[name].append(panel.createMemento())
321                return panel
322            return None
323        return None
324       
325   
326    def add_model_page(self,model,page_title="Model", qmin=0.0001, qmax=0.13,
327                        npts=50, topmenu=False, reset=False):
328        """
329            Add a model page only one  to display any model selected from the menu or the page combo box.
330            when this page is closed than the user will be able to open a new one
331           
332            @param model: the model for which paramters will be changed
333            @param page_title: the name of the page
334            @param page_info: contains info about the state of the page
335            @param qmin: mimimum Q
336            @param qmax: maximum Q
337            @param npts: number of Q points
338        """
339        if topmenu==True:
340            ##first time to open model page
341            if self.count==0 :
342                #if not page_title in self.list_fitpage_name :
343                self._help_add_model_page(model=model, page_title=page_title,
344                                qmin=qmin, qmax=qmax, npts=npts, reset=reset)
345                self.count +=1
346            else:
347                self.model_page.select_model(model)
348                self.fit_page_name[page_title]=ListOfState()
349                #self.fit_page_name[page_title].insert(0,self.model_page.createMemento())
350     
351     
352     
353    def _close_fitpage(self,data):
354        """
355            close a fit page when its data is completely remove from the graph
356        """
357        name = data.name
358        for index in range(self.GetPageCount()):
359            if self.GetPageText(index)== name:
360                selected_page = self.GetPage(index) 
361   
362                if index ==self.fit_page1D_number:
363                    self.fit_page1D_number=None
364                if index ==self.fit_page2D_number:
365                    self.fit_page2D_number=None
366                if selected_page in self.manager.page_finder:
367                    del self.manager.page_finder[selected_page]
368                ##remove the check box link to the model name of this page (selected_page)
369                try:
370                    self.sim_page.draw_page()
371                except:
372                    ## that page is already deleted no need to remove check box on
373                    ##non existing page
374                    pass
375               
376                #Delete the name of the page into the list of open page
377                if selected_page.window_name in self.list_fitpage_name:
378                    self.list_fitpage_name.remove(selected_page.window_name)
379                self.DeletePage(index)
380                break
381       
382       
383    def  _onGetstate(self, event):
384        """
385            copy the state of a page
386        """
387        page= event.page
388        if page.window_name in self.fit_page_name:
389            self.fit_page_name[page.window_name].appendItem(page.createMemento()) 
390           
391    def _onUndo(self, event ):
392        """
393            return the previous state of a given page is available
394        """
395        page = event.page
396        if page.window_name in self.fit_page_name:
397            if self.fit_page_name[page.window_name].getCurrentPosition()==0:
398                state = None
399            else:
400                state = self.fit_page_name[page.window_name].getPreviousItem()
401                page._redo.Enable(True)
402            page.reset_page(state)
403       
404    def _onRedo(self, event ): 
405        """
406            return the next state available
407        """       
408        page = event.page
409        if page.window_name in self.fit_page_name:
410            length= len(self.fit_page_name[page.window_name])
411            if self.fit_page_name[page.window_name].getCurrentPosition()== length -1:
412                state = None
413                page._redo.Enable(False)
414                page._redo.Enable(True)
415            else:
416                state = self.fit_page_name[page.window_name].getNextItem()
417            page.reset_page(state) 
418               
419    def _help_add_model_page(self,model,page_title="Model", qmin=0.0001, 
420                             qmax=0.13, npts=50,reset= False):
421        """
422            #TODO: fill in description
423           
424            @param qmin: mimimum Q
425            @param qmax: maximum Q
426            @param npts: number of Q points
427        """
428        ## creating object that contaning info about model
429        myinfo = PageInfo(model= model ,name= page_title)
430        myinfo.model_list_box = self.model_list_box.get_list()
431        myinfo.event_owner = self.event_owner
432        myinfo.manager = self.manager
433        myinfo.window_name = page_title
434        myinfo.window_caption = page_title
435     
436        from modelpage import ModelPage
437        panel = ModelPage(self,myinfo)
438       
439        self.AddPage(page=panel, caption=page_title, select=True)
440
441        self.model_page_number=self.GetSelection()
442        self.model_page=self.GetPage(self.GetSelection())
443     
444        ##resetting page
445        if reset:
446            if page_title in self.fit_page_name.keys():
447
448                memento= self.fit_page_name[page_title][0]
449                panel.reset_page(memento)
450        else:
451            self.fit_page_name[page_title]=ListOfState()
452            #self.fit_page_name[page_title]=[]
453            #self.fit_page_name[page_title].insert(0,panel.createMemento())
454       
455 
Note: See TracBrowser for help on using the repository browser.