source: sasview/sansview/perspectives/fitting/fitpanel.py @ 5901bb9

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 5901bb9 was 4e78f56, checked in by Gervaise Alina <gervyh@…>, 13 years ago

add save project function

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