source: sasview/sansguiframe/src/sans/guiframe/data_processor.py @ 7ad194fa

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

working on data processor

  • Property mode set to 100644
File size: 16.8 KB
Line 
1"""
2Implement grid used to store data
3"""
4import wx
5import numpy
6import sys
7import copy
8from wx.lib.scrolledpanel import ScrolledPanel
9import  wx.grid as  Grid
10import wx.aui
11from wx.aui import AuiNotebook as nb
12from sans.guiframe.panel_base import PanelBase
13import wx.lib.sheet as sheet
14
15from sans.guiframe.events import NewPlotEvent
16from sans.guiframe.events import StatusEvent 
17from sans.guiframe.dataFitting import Data1D
18
19
20class GridPage(sheet.CSheet):
21    """
22    """
23    def __init__(self, parent, panel=None):
24        """
25        """
26        sheet.CSheet.__init__(self, parent)
27        self.SetLabelBackgroundColour('#DBD4D4')
28        self.AutoSize()
29        self.panel = panel
30        self.col_names = []
31        self._cols = 50
32        self._rows = 51
33        col_with = 30
34        row_height = 20
35        self.axis_value = []
36        self.axis_label = ""
37        self.selected_cells = []
38        self.selected_cols = []
39        self.SetColMinimalAcceptableWidth(col_with)
40        self.SetRowMinimalAcceptableHeight(row_height)
41        self.SetNumberRows(self._cols)
42        self.SetNumberCols(self._rows)
43        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.on_left_click)
44        self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.on_right_click)
45        self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.on_selected_cell)
46       
47    def on_selected_cell(self, event):
48        """
49        Handler catching cell selection
50        """
51        flag = event.CmdDown() or event.ControlDown()
52        cell = (event.GetRow(), event.GetCol())
53        if not flag:
54            self.selected_cells = []
55        if cell in self.selected_cells:
56            self.selected_cells.remove(cell)
57        else:
58            self.selected_cells.append(cell)
59        event.Skip()
60     
61    def on_left_click(self, event):
62        """
63        Catch the left click on label mouse event
64        """
65        flag = event.CmdDown() or event.ControlDown()
66        col = event.GetCol()
67        if not flag:
68            self.selected_cols  = []
69        if col not in self.selected_cols:
70            self.selected_cols.append(col)
71        event.Skip()
72       
73    def on_right_click(self, event):
74        """
75        Catch the right click mouse
76        """
77        col = event.GetCol()
78        if col != -1 and len(self.col_names) > col:
79            label = self.col_names[int(col)]
80            self.axis_label = label
81            if label in self.data.keys():
82                col_val = self.data[label]
83                self.axis_value = col_val
84        # Slicer plot popup menu
85        slicerpop = wx.Menu()
86        id = wx.NewId()
87        slicerpop.Append(id, '&Set X axis', 'Set X axis')
88        wx.EVT_MENU(self, id, self.on_set_x_axis)
89       
90        id = wx.NewId()
91        slicerpop.Append(id, '&Set Y axis', 'Set Y axis')
92        wx.EVT_MENU(self, id, self.on_set_y_axis)
93        pos = event.GetPosition()
94        pos = self.ScreenToClient(pos)
95        self.PopupMenu(slicerpop, pos)
96       
97    def on_set_x_axis(self, event):
98        """
99        """
100        self.panel.set_xaxis(x=self.axis_value, label=self.axis_label)
101   
102    def on_set_y_axis(self, event):
103        """
104        """
105        self.panel.set_yaxis(y=self.axis_value, label=self.axis_label)     
106           
107    def set_data(self, data):
108        """
109        Add data to the grid
110        """
111        if data is None:
112            data = {}
113        if  len(data) > 0:
114            self._cols = self.GetNumberCols()
115            self._rows = self.GetNumberRows()
116            self.data = data
117            self.col_names = data.keys()
118            self.col_names.sort() 
119            nbr_user_cols = len(self.col_names)
120            #Add more columns to the grid if necessary
121            if nbr_user_cols > self._cols:
122                new_col_nbr = nbr_user_cols -  self._cols
123                self.AppendCols(new_col_nbr, True)
124            #Add more rows to the grid if necessary 
125            nbr_user_row = len(self.data.values())
126            if nbr_user_row > self._rows + 1:
127                new_row_nbr =  nbr_user_row - self._rows
128                self.AppendRows(new_row_nbr, True)
129            # add data to the grid   
130            label_row = 0
131            for index  in range(nbr_user_cols):
132                # use the first row of the grid to add user defined labels
133                self.SetCellValue(label_row, index, str(self.col_names[index]))
134            col = 0
135            for value_list in self.data.values():
136                for row in range(1, len(value_list)):
137                    self.SetCellValue(row, col, str(value_list[row]))
138                col += 1
139            self.AutoSize()
140           
141
142class Notebook(nb, PanelBase):
143    """
144    ## Internal name for the AUI manager
145    window_name = "Fit panel"
146    ## Title to appear on top of the window
147    """
148    window_caption = "Notebook "
149   
150    def __init__(self, parent, manager=None, data=None, *args, **kwargs):
151        """
152        """
153        nb.__init__(self, parent, -1,
154                    style= wx.aui.AUI_BUTTON_DOWN|
155                    wx.aui.AUI_NB_WINDOWLIST_BUTTON|
156                    wx.aui.AUI_NB_DEFAULT_STYLE|
157                    wx.CLIP_CHILDREN)
158        PanelBase.__init__(self, parent)
159        self.enable_close_button()
160        self.parent = parent
161        self.manager = manager
162        self.data = data
163        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_page)
164   
165    def enable_close_button(self):
166        """
167        display the close button on tab for more than 1 tabs else remove the
168        close button
169        """
170        if self.GetPageCount() <= 1:
171            style = self.GetWindowStyleFlag() 
172            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
173            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB == flag:
174                style = style & ~wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
175                self.SetWindowStyle(style)
176        else:
177            style = self.GetWindowStyleFlag()
178            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
179            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB != flag:
180                style |= wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
181                self.SetWindowStyle(style)
182             
183    def on_edit_axis(self):
184        """
185        Return the select cell of a given selected column
186        """
187        pos = self.GetSelection()
188        grid = self.GetPage(pos)
189        if len(grid.selected_cols) > 1:
190            msg = "Edit axis doesn't understand this selection.\n"
191            msg += "Please select only one column"
192            raise ValueError, msg
193        list_of_cells = []
194        if len(grid.selected_cols) == 1:
195            col = grid.selected_cols[0]
196            if len(grid.selected_cells) > 0:
197                cell_row, cell_col = grid.selected_cells[0]
198                if cell_col  != col:
199                    msg = "Edit axis doesn't understand this selection.\n"
200                    msg += "Please select element of the same col"
201                    raise ValueError, msg
202            for row in range(grid.GetNumberRows()):
203                list_of_cells.append((row + 1 , col))
204            for item in grid.selected_cells:
205                if item in list_of_cells:
206                    list_of_cells.remove(item)
207        elif len(grid.selected_cols) == 0:
208            list_of_cells = [(row + 1, col) for row, col in grid.selected_cells]
209        return list_of_cells
210   
211    def create_axis_label(self, cell_list):
212        """
213        Receive a list of cells and  create a string presenting the selected
214        cells.
215        :param cell_list: list of tuple
216       
217        """
218        pos = self.GetSelection()
219        grid = self.GetPage(pos)
220        label = ""
221        col_name = ""
222        if len(cell_list) > 0:
223            temp_list = copy.deepcopy(cell_list)
224            temp_list.sort()
225            temp = []
226            for item in temp_list:
227                if item[0] <= 1:
228                    temp.append(item)
229            for element in temp:
230                temp_list.remove(element)
231            row_min, _  = temp_list[0]   
232            row_max = row_min
233            label += str(col_name) + "[" + str(row_min) + ":"
234            print "temp_list", temp_list
235            for index in xrange(len(temp_list)):
236                prev = index - 1
237                row, _ = temp_list[index]
238                if row > row_max + 1 :
239                    if prev > 0:
240                        row_max, _ = temp_list[prev]
241                        label += str(row_max) + "]" + ","
242                        row_min = row
243                        label  += "[" + str(row_min) + ":"
244                row_max = row
245               
246                if (index == len(temp_list)- 1):
247                    label +=  str(row_max) + "]"
248                    print "here"
249        print "label ", label             
250        return label
251   
252    def on_close_page(self, event):
253        """
254        close the page
255        """
256        if self.GetPageCount() == 1:
257            event.Veto()
258        self.enable_close_button()
259       
260    def set_data(self, data):
261        if data is None:
262            return
263           
264        grid = GridPage(self, panel=self.parent)
265        grid.set_data(data) 
266        self.AddPage(grid, "")
267        pos = self.GetPageIndex(grid)
268        title = "Batch " + str(self.GetPageCount())
269        self.SetPageText(pos, title)
270       
271    def add_column(self):
272        """
273        Append a new column to the grid
274        """
275        pos = self.GetSelection()
276        grid = self.GetPage(pos)
277        grid.AppendCols(1, True)
278       
279    def on_remove_column(self):
280        """
281        Remove column to the current grid
282        """
283        pos = self.GetSelection()
284        grid = self.GetPage(pos)
285        cols_pos = grid.GetSelectedCols() 
286        for cpos in cols_pos:
287            grid.DeleteCols(cpos)
288         
289         
290class SPanel(ScrolledPanel):
291    def __init__(self, parent, *args, **kwds):
292        ScrolledPanel.__init__(self, parent , *args, **kwds)
293        self.SetupScrolling() 
294
295
296class GridPanel(SPanel):
297    def __init__(self, parent,data=None, *args, **kwds):
298        SPanel.__init__(self, parent , *args, **kwds)
299        self.vbox = wx.BoxSizer(wx.VERTICAL)
300       
301        self.plotting_sizer = wx.FlexGridSizer(3, 7, 10, 5)
302        self.grid_sizer = wx.BoxSizer(wx.HORIZONTAL)
303        self.vbox.AddMany([(self.grid_sizer, 1, wx.EXPAND, 0),
304                           (wx.StaticLine(self, -1), 0, wx.EXPAND, 0),
305                           (self.plotting_sizer)])
306        self.parent = parent
307        self._data = data
308        self.x = []
309        self.= []
310        self.x_axis_label = None
311        self.y_axis_label = None
312        self.x_axis_value = None
313        self.y_axis_value = None
314        self.x_axis_unit = None
315        self.y_axis_unit = None
316        self.plot_button = None
317        self.grid = None
318        self.layout_grid()
319        self.layout_plotting_area()
320        self.SetSizer(self.vbox)
321       
322    def set_data(self, data):
323        """
324        """
325        if self.grid is not None:
326            self.grid.set_data(data)
327       
328    def set_xaxis(self, label="", x=None) :
329        if x is None:
330            x = []
331        self.x = x
332        self.x_axis_value.SetValue("%s[:]" % str(label))
333        self.x_axis_label.SetValue(str(label))
334       
335    def set_yaxis(self, label="", y=None) :
336        if y is None:
337            y = []
338        self.y = y
339        self.y_axis_value.SetValue("%s[:]" % str(label))
340        self.y_axis_label.SetValue(str(label))
341       
342    def on_plot(self, event):
343        """
344        plotting
345        """ 
346        new_plot = Data1D(x=self.x, y=self.y)
347        new_plot.id =  wx.NewId()
348        new_plot.group_id = wx.NewId()
349        title = "%s vs %s" % (self.y_axis_label.GetValue(), self.x_axis_label.GetValue())
350        new_plot.xaxis(self.x_axis_label.GetValue(), self.x_axis_unit.GetValue())
351        new_plot.yaxis(self.y_axis_label.GetValue(), self.y_axis_unit.GetValue())
352        wx.PostEvent(self.parent.parent, 
353                             NewPlotEvent(plot=new_plot, 
354                        group_id=str(new_plot.group_id), title ="batch"))   
355    def layout_grid(self):
356        """
357        Draw the area related to the grid
358        """
359        self.grid = Notebook(parent=self)
360        self.grid.set_data(self._data)
361        self.grid_sizer.Add(self.grid, 1, wx.EXPAND, 0)
362       
363    def layout_plotting_area(self):
364        """
365        Draw area containing options to plot
366        """
367        self.x_axis_label = wx.TextCtrl(self, -1)
368        self.y_axis_label = wx.TextCtrl(self, -1)
369        self.x_axis_value = wx.TextCtrl(self, -1, size=(200, -1))
370        self.y_axis_value = wx.TextCtrl(self, -1, size=(200, -1))
371        self.x_axis_add = wx.Button(self, -1, "Add")
372        self.x_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
373                            id=self.x_axis_add.GetId())
374        self.y_axis_add = wx.Button(self, -1, "Add")
375        self.y_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
376                            id=self.y_axis_add.GetId())
377        self.x_axis_unit = wx.TextCtrl(self, -1)
378        self.y_axis_unit = wx.TextCtrl(self, -1)
379        self.plot_button = wx.Button(self, -1, "Plot")
380        wx.EVT_BUTTON(self, self.plot_button.GetId(), self.on_plot)
381        self.plotting_sizer.AddMany([
382                    (wx.StaticText(self, -1, "x-axis label"), 1, wx.LEFT, 10),
383                    (self.x_axis_label, wx.TOP|wx.BOTTOM|wx.LEFT, 10),
384                    (wx.StaticText(self, -1, "x-axis value"), 1, wx.LEFT, 10),
385                    (self.x_axis_value, wx.TOP|wx.BOTTOM|wx.LEFT, 10),
386                    (self.x_axis_add, 1, wx.LEFT|wx.RIGHT, 0),
387                    (wx.StaticText(self, -1 , "unit"), 1, wx.LEFT|wx.RIGHT, 0),
388                    (self.x_axis_unit, 0, wx.LEFT, 0),
389                    (wx.StaticText(self, -1, "y-axis label"), 1, wx.LEFT, 10),
390                    (self.y_axis_label,  wx.TOP|wx.BOTTOM|wx.LEFT, 10),
391                    (wx.StaticText(self, -1, "y-axis value"), 1, wx.LEFT, 10),
392                    (self.y_axis_value, wx.TOP|wx.BOTTOM|wx.LEFT, 10),
393                    (self.y_axis_add, 1, wx.LEFT|wx.RIGHT, 0),
394                    (wx.StaticText(self, -1 , "unit"), 1, wx.LEFT|wx.RIGHT, 0),
395                    (self.y_axis_unit, 0, wx.LEFT, 0),
396                      (-1, -1),
397                      (-1, -1),
398                      (-1, -1),
399                      (-1, -1),
400                      (-1, -1),
401                      (-1, -1),
402                      (self.plot_button, 1, wx.LEFT, 0)])
403   
404    def on_edit_axis(self, event):
405        """
406        Get the selected column on  the visible grid and set values for axis
407        """
408        cell_list = self.grid.on_edit_axis()
409        self.create_axis_label(cell_list)
410       
411    def create_axis_label(self, cell_list):
412        """
413        Receive a list of cells and  create a string presenting the selected
414        cells.
415        :param cell_list: list of tuple
416       
417        """
418        if self.grid is not None:
419            return self.grid.create_axis_label(cell_list)
420   
421    def edit_axis_helper(self, tcrtl_label, tcrtl_value):
422        """
423        """
424    def add_column(self):
425        """
426        """
427        if self.grid is not None:
428            self.grid.add_column()
429       
430    def on_remove_column(self):
431        """
432        """
433        if self.grid is not None:
434            self.grid.on_remove_column()
435       
436       
437class GridFrame(wx.Frame):
438    def __init__(self, parent=None, data=None, id=-1, 
439                 title="Batch Results", size=(700, 400)):
440        wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
441        self.parent = parent
442        self.panel = GridPanel(self, data)
443        menubar = wx.MenuBar()
444        self.SetMenuBar(menubar)
445        edit = wx.Menu()
446        menubar.Append(edit, "&Edit")
447        self.Bind(wx.EVT_CLOSE, self.on_close)
448       
449        add_col_menu = edit.Append(wx.NewId(), 'Add Column', 'Add column')
450        wx.EVT_MENU(self, add_col_menu.GetId(), self.on_add_column)
451        remove_col_menu = edit.Append(wx.NewId(), 'Remove Column', 
452                                      'Remove Column')
453        wx.EVT_MENU(self, remove_col_menu.GetId(), self.on_remove_column)
454
455    def on_close(self, event):
456        """
457        """
458        self.Hide()
459       
460    def on_remove_column(self, event):
461        """
462        Remove the selected column to the grid
463        """
464        self.panel.on_remove_column()
465       
466    def on_add_column(self, event):
467        """
468        Append a new column to the grid
469        """
470        self.panel.add_column()
471       
472    def set_data(self, data):
473        """
474        """
475        self.panel.set_data(data)
476     
477     
478if __name__ == "__main__":
479    app = wx.App()
480   
481    try:
482        data = {}
483        j = 0
484        for i in range(4):
485            j += 1
486            data["index"+str(i)] = [i/j, i*j, i, i+j]
487           
488        frame = GridFrame(data=data)
489        frame.Show(True)
490    except:
491        print sys.exc_value
492       
493    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.