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

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 e030625 was 2296316, checked in by Jae Cho <jhjcho@…>, 14 years ago

moving features from the branch

  • Property mode set to 100644
File size: 14.2 KB
Line 
1
2import numpy
3import string 
4import wx
5import wx.lib.flatnotebook as fnb
6
7from sans.guiframe.panel_base import PanelBase
8from sans.guiframe.events import PanelOnFocusEvent
9from sans.guiframe.events import StatusEvent
10
11import basepage
12import models
13_BOX_WIDTH = 80
14
15
16class FitPanel(fnb.FlatNotebook, PanelBase):   
17
18    """
19    FitPanel class contains fields allowing to fit  models and  data
20   
21    :note: For Fit to be performed the user should check at least one parameter
22        on fit Panel window.
23       
24    """
25    ## Internal name for the AUI manager
26    window_name = "Fit panel"
27    ## Title to appear on top of the window
28    window_caption = "Fit Panel "
29    CENTER_PANE = True
30   
31    def __init__(self, parent, manager=None, *args, **kwargs):
32        """
33        """
34        fnb.FlatNotebook.__init__(self, parent, -1,
35                    style= wx.aui.AUI_NB_WINDOWLIST_BUTTON|
36                    wx.aui.AUI_NB_DEFAULT_STYLE|
37                    wx.CLIP_CHILDREN)
38        PanelBase.__init__(self, parent)
39        self.SetWindowStyleFlag(style=fnb.FNB_FANCY_TABS)
40        self._manager = manager
41        self.parent = parent
42        self.event_owner = None
43        #dictionary of miodel {model class name, model class}
44        self.menu_mng = models.ModelManager()
45        self.model_list_box = self.menu_mng.get_model_list()
46        #pageClosedEvent = fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING
47        self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING , self.on_close_page)
48         ## save the title of the last page tab added
49        self.fit_page_name = {}
50        ## list of existing fit page
51        self.opened_pages = {}
52        #page of simultaneous fit
53        self.sim_page = None
54        self.fit_engine_type = "scipy"
55        ## get the state of a page
56        self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate)
57        self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo)
58        self.Bind(basepage.EVT_NEXT_STATE, self._onRedo)
59        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.on_page_changing)
60     
61        #add default pages
62        self.add_default_pages()
63
64   
65    def _on_engine_change(self, name='scipy'):
66        """
67        """
68        for panel in self.opened_pages.values():
69            self.set_engine_helper(panel=panel, name=name)
70           
71    def set_engine_helper(self, panel, name='scipy'):
72        """
73        """
74        self.fit_engine_type = name
75        if panel != self.sim_page:
76            panel._on_engine_change(name=self.fit_engine_type)
77               
78    def update_model_list(self):
79        """
80        """
81        temp = self.menu_mng.update()
82        if len(temp):
83            self.model_list_box = temp
84        return temp
85       
86       
87    def get_page_by_id(self, uid): 
88        """
89        """
90        if uid not in self.opened_pages:
91            msg = "Fitpanel cannot find ID: %s in self.opened_pages" % str(uid)
92            raise ValueError, msg
93        else:
94            return self.opened_pages[uid]
95       
96    def on_page_changing(self, event):
97        """
98        """
99        pos = self.GetSelection()
100        if pos != -1:
101            selected_page = self.GetPage(pos)
102            wx.PostEvent(self.parent, PanelOnFocusEvent(panel=selected_page))
103           
104    def on_set_focus(self, event):
105        """
106        """
107        pos = self.GetSelection()
108        if pos != -1:
109            selected_page = self.GetPage(pos)
110            wx.PostEvent(self.parent, PanelOnFocusEvent(panel=selected_page))
111       
112    def get_data(self):
113        """
114        get the data in the current page
115        """
116        pos = self.GetSelection()
117        if pos != -1:
118            selected_page = self.GetPage(pos)
119            return selected_page.get_data()
120   
121    def set_model_state(state):
122        """
123        receive a state to reset the model in the current page
124        """
125        pos = self.GetSelection()
126        if pos != -1:
127            selected_page = self.GetPage(pos)
128            selected_page.set_model_state(state)
129           
130    def get_state(self):
131        """
132         return the state of the current selected page
133        """
134        pos = self.GetSelection()
135        if pos != -1:
136            selected_page = self.GetPage(pos)
137            return selected_page.get_state()
138   
139    def add_default_pages(self):
140        """
141        Add default pages such as a hint page and an empty fit page
142        """
143        pass
144        #add default page
145        #from hint_fitpage import HintFitPage
146        #self.hint_page = HintFitPage(self)
147        #self.AddPage(self.hint_page,"Hint")
148        #self.hint_page.set_manager(self._manager)
149 
150    def close_all(self):
151        """
152        remove all pages, used when a svs file is opened
153        """
154       
155        #get number of pages
156        nop = self.GetPageCount()
157        #use while-loop, for-loop will not do the job well.
158        while (nop>0):
159            #delete the first page until no page exists
160            page = self.GetPage(0)
161            if self._manager.parent.panel_on_focus == page:
162                self._manager.parent.panel_on_focus = None
163            self._close_helper(selected_page=page)
164            self.DeletePage(0)
165            nop = nop - 1
166           
167        ## save the title of the last page tab added
168        self.fit_page_name = {}
169        ## list of existing fit page
170        self.opened_pages = {} 
171         
172    def set_state(self, state):
173        """
174        Restore state of the panel
175        """
176        page_is_opened = False
177        if state is not None:
178            for uid, panel in self.opened_pages.iteritems():
179                #Don't return any panel is the exact same page is created
180                if uid == panel.uid:
181                    # the page is still opened
182                    panel.reset_page(state=state)
183                    panel.save_current_state() 
184                    page_is_opened = True
185            if not page_is_opened:
186                panel = self._manager.add_fit_page(data=state.data)
187                # add data associated to the page created
188                if panel is not None: 
189                    self._manager.store_page(page=panel.uid, data=state.data)
190                    panel.reset_page(state=state)
191                    panel.save_current_state()
192                   
193    def clear_panel(self):
194        """
195        Clear and close all panels, used by guimanager
196        """
197       
198        #close all panels only when svs file opened
199        self.close_all()
200        self._manager.mypanels = []
201       
202                       
203    def on_close_page(self, event=None):
204        """
205        close page and remove all references to the closed page
206        """
207        nbr_page = self.GetPageCount()
208        if nbr_page == 1:
209           
210            event.Veto()
211            return 
212        selected_page = self.GetPage(self.GetSelection())
213        self._close_helper(selected_page=selected_page)
214       
215    def close_page_with_data(self, deleted_data):
216        """
217        close a fit page when its data is completely remove from the graph
218        """
219        if deleted_data is None:
220            return
221        for index in range(self.GetPageCount()):
222            selected_page = self.GetPage(index) 
223            if hasattr(selected_page,"get_data"):
224                data = selected_page.get_data()
225               
226                if data is None:
227                    #the fitpanel exists and only the initial fit page is open
228                    #with no selected data
229                    return
230                if data.name == deleted_data.name:
231                    self._close_helper(selected_page)
232                    self.DeletePage(index)
233                    break
234       
235    def set_manager(self, manager):
236        """
237        set panel manager
238       
239        :param manager: instance of plugin fitting
240       
241        """
242        self._manager = manager
243        for pos in range(self.GetPageCount()):
244            page = self.GetPage(pos)
245            if page is not None:
246                page.set_manager(self._manager)
247
248    def set_model_list(self, dict):
249         """
250         copy a dictionary of model into its own dictionary
251         
252         :param dict: dictionnary made of model name as key and model class
253             as value
254         """
255         self.model_list_box = dict
256       
257    def get_current_page(self):
258        """
259        :return: the current page selected
260       
261        """
262        return self.GetPage(self.GetSelection())
263   
264    def add_sim_page(self):
265        """
266        Add the simultaneous fit page
267        """
268        from simfitpage import SimultaneousFitPage
269        page_finder= self._manager.get_page_finder()
270        self.sim_page = SimultaneousFitPage(self,page_finder=page_finder, id=-1)
271        self.sim_page.uid = wx.NewId()
272        self.AddPage(self.sim_page,"Simultaneous Fit", True)
273        self.sim_page.set_manager(self._manager)
274        return self.sim_page
275       
276 
277    def add_empty_page(self):
278        """
279        add an empty page
280        """
281        from fitpage import FitPage
282        panel = FitPage(parent=self)
283        panel.uid = wx.NewId()
284        panel.populate_box(dict=self.model_list_box)
285        panel.set_manager(self._manager)
286        caption = str(panel.window_name) + " " + str(self._manager.index_model)
287        self.AddPage(panel, caption, select=True)
288        self.opened_pages[panel.uid] = panel
289        self.set_engine_helper(panel=panel)
290        return panel
291   
292    def delete_data(self, data):
293        """
294        Delete the given data
295        """
296        if data is None:
297            return None
298    def set_data(self, data):
299        """
300        Add a fitting page on the notebook contained by fitpanel
301       
302        :param data: data to fit
303       
304        :return panel : page just added for further used. is used by fitting module
305       
306        """
307        if data is None:
308            return None
309        for page in self.opened_pages.values():
310            #check if the selected data existing in the fitpanel
311            pos = self.GetPageIndex(page)
312            if page.get_data() is None:
313                enable2D = page.get_view_mode()
314                if (data.__class__.__name__ == "Data2D" and enable2D)\
315                or (data.__class__.__name__ == "Data1D" and not enable2D):
316                    page.set_data(data)
317                    self.SetPageText(pos, str(data.name))
318                    self.SetSelection(pos)
319                    return page
320               
321            elif page.get_data().id == data.id:
322                msg = "Data already existing in the fitting panel"
323                wx.PostEvent(self._manager.parent, 
324                             StatusEvent(status=msg, info='warning')) 
325                self.SetSelection(pos)
326                return page
327       
328        page = self.add_empty_page()
329        pos = self.GetPageIndex(page)
330        page.set_data(data)
331        self.SetPageText(pos, str(data.name))
332        self.opened_pages[page.uid] = page
333       
334        return page
335       
336    def _onGetstate(self, event):
337        """
338        copy the state of a page
339        """
340        page = event.page
341        if page.uid in self.fit_page_name:
342           self.fit_page_name[page.uid].appendItem(page.createMemento()) 
343           
344    def _onUndo(self, event ):
345        """
346        return the previous state of a given page is available
347        """
348        page = event.page
349        if page.uid in self.fit_page_name:
350            if self.fit_page_name[page.uid].getCurrentPosition()==0:
351                state = None
352            else:
353                state = self.fit_page_name[page.uid].getPreviousItem()
354                page._redo.Enable(True)
355            page.reset_page(state)
356       
357    def _onRedo(self, event): 
358        """
359        return the next state available
360        """       
361        page = event.page
362        if page.uid in self.fit_page_name:
363            length= len(self.fit_page_name[page.uid])
364            if self.fit_page_name[page.uid].getCurrentPosition()== length -1:
365                state = None
366                page._redo.Enable(False)
367                page._redo.Enable(True)
368            else:
369                state =self.fit_page_name[page.uid].getNextItem()
370            page.reset_page(state) 
371                 
372    def _close_helper(self, selected_page):
373        """
374        Delete the given page from the notebook
375        """
376        #remove hint page
377        if selected_page == self.hint_page:
378            return
379        ## removing sim_page
380        if selected_page == self.sim_page :
381            self._manager.sim_page=None 
382            return
383       
384        ## closing other pages
385        state = selected_page.createMemento()
386        page_name = selected_page.window_name
387        page_finder = self._manager.get_page_finder() 
388        fitproblem = None
389        ## removing fit page
390        data = selected_page.get_data()
391        #Don' t remove plot for 2D
392        flag = True
393        if data.__class__.__name__ == 'Data2D':
394            flag = False
395        if selected_page in page_finder:
396            #Delete the name of the page into the list of open page
397            for uid, list in self.opened_pages.iteritems():
398                #Don't return any panel is the exact same page is created
399               
400                if flag and selected_page.uid == uid:
401                    self._manager.remove_plot(uid, theory=False)
402                    break 
403            del page_finder[selected_page]
404        ##remove the check box link to the model name of this page (selected_page)
405        try:
406            self.sim_page.draw_page()
407        except:
408            ## that page is already deleted no need to remove check box on
409            ##non existing page
410            pass
411               
412        #Delete the name of the page into the list of open page
413        for uid, list in self.opened_pages.iteritems():
414            #Don't return any panel is the exact same page is created
415           
416            if selected_page.uid == uid:
417                del self.opened_pages[selected_page.uid]
418                break 
419     
420 
Note: See TracBrowser for help on using the repository browser.