source: sasview/sansview/perspectives/fitting/fitpanel.py @ 71bd773

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 71bd773 was 66ff250, checked in by Gervaise Alina <gervyh@…>, 14 years ago

working on fit stop

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