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

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

work on toggle 1D \2D

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