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

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

focus color (plots) and adjust panel sizes a bit

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