source: sasview/sansguiframe/src/sans/guiframe/data_processor.py @ 87e2f81

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

make sure residuals are plot one at the time for 2D

  • Property mode set to 100644
File size: 43.5 KB
Line 
1"""
2Implement grid used to store data
3"""
4import wx
5import numpy
6import math
7import re
8import os
9import sys
10import copy
11from wx.lib.scrolledpanel import ScrolledPanel
12import  wx.grid as  Grid
13import wx.aui
14from wx.aui import AuiNotebook as nb
15from sans.guiframe.panel_base import PanelBase
16import wx.lib.sheet as sheet
17
18from sans.guiframe.events import NewPlotEvent
19from sans.guiframe.events import StatusEvent 
20from sans.guiframe.dataFitting import Data1D
21
22FUNC_DICT = {"sqrt": "math.sqrt",
23             "pow": "math.sqrt"}
24
25class BatchCell:
26    """
27    Object describing a cell in  the grid.
28   
29    """
30    def __init__(self):
31        self.label = ""
32        self.value = None
33        self.col = -1
34        self.row = -1
35        self.object = []
36       
37
38def parse_string(sentence, list):
39    """
40    Return a dictionary of column label and index or row selected
41    :param sentence: String to parse
42    :param list: list of columns label
43    """
44    toks = []
45    p2 = re.compile(r'\d+')
46    p = re.compile(r'[\+\-\*\%\/]')
47    labels = p.split(sentence)
48    col_dict = {}
49    for elt in labels:
50        rang = None
51        temp_arr = []
52        for label in  list:
53            label_pos =  elt.find(label)
54            if label_pos != -1:
55                if elt.count(',') > 0:
56                    new_temp = []
57                    temp = elt.split(label)
58                    for item in temp:
59                        range_pos = item.find(":")
60                        if range_pos != -1:
61                            rang = p2.findall(item)
62                            for i in xrange(int(rang[0]), int(rang[1])+1 ):
63                                new_temp.append(i)
64                    temp_arr += new_temp
65                else:
66                    temp = elt.split(label)
67                    for item in temp:
68                        range_pos = item.find(":")
69                        if range_pos != -1:
70                            rang = p2.findall(item)
71                            for i in xrange(int(rang[0]), int(rang[1])+1 ):
72                                temp_arr.append(i)
73                col_dict[elt] = (label, temp_arr)
74    return col_dict
75
76         
77         
78class SPanel(ScrolledPanel):
79    def __init__(self, parent, *args, **kwds):
80        ScrolledPanel.__init__(self, parent , *args, **kwds)
81        self.SetupScrolling() 
82       
83class GridPage(sheet.CSheet):
84    """
85    """
86    def __init__(self, parent, panel=None):
87        """
88        """
89        sheet.CSheet.__init__(self, parent)
90       
91        self.AdjustScrollbars()
92        #self.SetLabelBackgroundColour('#DBD4D4')
93        self.parent = parent
94        self.panel = panel
95        self.col_names = []
96        self.data_inputs = {}
97        self.data_outputs = {}
98        self.data = None
99        self.details = ""
100        self.file_name = None
101        self._cols = 50
102        self._rows = 51
103        self.last_selected_row = -1
104        self.last_selected_col = -1
105        col_with = 30
106        row_height = 20
107        self.max_row_touse = 0
108        self.axis_value = []
109        self.axis_label = ""
110        self.selected_cells = []
111        self.selected_cols = []
112        self.selected_rows = []
113        self.plottable_cells = []
114        self.plottable_flag = False
115        self.SetColMinimalAcceptableWidth(col_with)
116        self.SetRowMinimalAcceptableHeight(row_height)
117        self.SetNumberRows(self._cols)
118        self.SetNumberCols(self._rows)
119        self.AutoSize()
120        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.on_left_click)
121        self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.on_right_click)
122        self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.on_selected_cell)
123        self.Bind(wx.grid.EVT_GRID_CMD_CELL_CHANGE, self.on_edit_cell)
124       
125    def on_edit_cell(self, event):
126        """
127        """
128        row, col = event.GetRow(), event.GetCol()
129        if row > self.max_row_touse:
130            self.max_row_touse = row
131        event.Skip()
132       
133    def on_selected_cell(self, event):
134        """
135        Handler catching cell selection
136        """
137        flag = event.CmdDown() or event.ControlDown()
138        row, col = event.GetRow(), event.GetCol()
139        cell = (row, col)
140        event.Skip()
141        if not flag:
142            self.selected_cells = []
143            self.axis_value = []
144            self.axis_label = ""
145        if col >= 0:
146             self.axis_label = self.GetCellValue(0, col)
147        if cell not in self.selected_cells:
148            if row > 0:
149                self.selected_cells.append(cell)
150        else:
151            if flag:
152                self.selected_cells.remove(cell)
153        self.axis_value = []
154        for cell_row, cell_col in self.selected_cells:
155            if cell_row > 0 and cell_row < self.max_row_touse:
156                self.axis_value.append(self.GetCellValue(cell_row, cell_col))
157       
158   
159               
160    def on_left_click(self, event):
161        """
162        Catch the left click on label mouse event
163        """
164        event.Skip()
165        flag = event.CmdDown() or event.ControlDown()
166        col = event.GetCol()
167        row = event.GetRow()
168        if not flag:
169            self.selected_cols = []
170            self.selected_rows = []
171            self.selected_cells = []
172            self.axis_label = ""
173            self.plottable_list = []
174            self.plottable_cells = []
175            self.plottable_flag = False
176       
177        self.last_selected_col = col
178        self.last_selected_row = row
179        if row != -1 and row not in self.selected_rows:
180             self.selected_rows.append(row)
181             
182        if col != -1:
183            for row in range(1, self.GetNumberRows()+ 1):
184                cell = (row, col)
185                if row > 0 and row < self.max_row_touse:
186                    if cell not in self.selected_cells:
187                        self.selected_cells.append(cell)
188            self.selected_cols.append(col)
189            self.axis_value = []
190            for cell_row, cell_col in self.selected_cells:
191                self.axis_value.append(self.GetCellValue(cell_row, cell_col))
192            self.axis_label = self.GetCellValue(0, col)
193       
194           
195           
196           
197           
198       
199
200    def on_right_click(self, event):
201        """
202        Catch the right click mouse
203        """
204       
205        col = event.GetCol()
206        self.selected_cols = []
207        self.selected_cols.append(col)
208        # Slicer plot popup menu
209        slicerpop = wx.Menu()
210        col_label_menu  = wx.Menu()
211        slicerpop.AppendSubMenu(col_label_menu , 
212                                 '&Insert Column', 'Insert Column')
213        col_name = [self.GetCellValue(0, c) 
214                        for c in range(self.GetNumberCols())]
215        row = 0
216        label = self.GetCellValue(row, col)
217        self.insert_col_menu(col_label_menu, label, self)
218        id = wx.NewId()   
219        hint = 'Remove selected column %s'
220        slicerpop.Append(id, '&Remove Column', hint)
221        wx.EVT_MENU(self, id, self.on_remove_column)
222       
223        pos = wx.GetMousePosition()
224        pos = self.ScreenToClient(pos)
225        self.PopupMenu(slicerpop, pos)
226        event.Skip()
227       
228    def insert_col_menu(self, menu, label, window):
229        """
230        """
231        id = wx.NewId()
232        title = "Empty"
233        hint = 'Insert empty column before %s' % str(label)
234        menu.Append(id, title, hint)
235        wx.EVT_MENU(window, id, self.on_insert_column)
236        col_name = [self.GetCellValue(0, col) 
237                        for col in range(self.GetNumberCols())]
238        for c_name in self.data.keys():
239            if c_name not in col_name:
240                id = wx.NewId()
241                hint = "Insert %s column before the " % str(c_name)
242                hint += " %s column" % str(label)
243                menu.Append(id, '&%s' % str(c_name), hint)
244                wx.EVT_MENU(window, id, self.on_insert_column)
245           
246               
247    def on_remove_column(self, event=None):
248        """
249        """
250        if self.selected_cols is not None or len(self.selected_cols) > 0:
251            col = self.selected_cols[0]
252            self.remove_column(col=col, numCols=1)
253           
254    def remove_column(self, col, numCols=1):
255        """
256        Remove column to the current grid
257        """
258        # add data to the grid   
259        row = 0
260        col_name = self.GetCellValue(row, col)
261        self.data[col_name] = []
262        for row in range(1, self.GetNumberRows() + 1):
263            if row < self.max_row_touse:
264                value = self.GetCellValue(row, col)
265                self.data[col_name].append(value)
266                for k , value_list in self.data.iteritems():
267                    if k != col_name:
268                        length = len(value_list)
269                        if length < self.max_row_touse:
270                            diff = self.max_row_touse - length
271                            for i in range(diff):
272                                self.data[k].append("")
273        self.DeleteCols(pos=col, numCols=numCols, updateLabels=True)
274           
275    def on_insert_column(self, event):
276        """
277        """
278        if self.selected_cols is not None or len(self.selected_cols) > 0:
279            col = self.selected_cols[0]
280            # add data to the grid   
281            row = 0
282            id = event.GetId()
283            col_name = event.GetEventObject().GetLabelText(id)
284            self.insert_column(col=col, col_name=col_name)
285            if  not issubclass(event.GetEventObject().__class__ , wx.Menu):
286                col += 1
287                self.selected_cols[0] += 1
288           
289    def insert_column(self, col, col_name):
290        """
291        """ 
292         
293        row = 0
294        self.InsertCols(pos=col, numCols=1, updateLabels=True)
295        if col_name.strip() != "Empty":
296            self.SetCellValue(row, col, str(col_name.strip()))
297        if col_name in self.data.keys():
298            value_list = self.data[col_name]
299            cell_row =  1
300            for value in value_list:
301                self.SetCellValue(cell_row, col, str(value))
302                cell_row += 1
303       
304       
305    def on_set_x_axis(self, event):
306        """
307        """
308        self.panel.set_xaxis(x=self.axis_value, label=self.axis_label)
309   
310    def on_set_y_axis(self, event):
311        """
312        """
313        self.panel.set_yaxis(y=self.axis_value, label=self.axis_label)     
314           
315    def set_data(self, data_inputs, data_outputs, details, file_name):
316        """
317        Add data to the grid
318        :param data_inputs: data to use from the context menu of the grid
319        :param data_ouputs: default columns deplayed
320        """
321        self.file_name = file_name
322        self.details = details
323       
324        if data_outputs is None:
325            data_outputs = {}
326        self.data_outputs = data_outputs
327        if data_inputs is None:
328            data_inputs = {}
329        self.data_inputs = data_inputs
330        self.data = {}
331        for item in (self.data_outputs, self.data_inputs):
332            self.data.update(item)
333        if  len(self.data_outputs) > 0:
334            self._cols = self.GetNumberCols()
335            self._rows = self.GetNumberRows()
336            self.col_names = self.data_outputs.keys()
337            self.col_names.sort() 
338            nbr_user_cols = len(self.col_names)
339            #Add more columns to the grid if necessary
340            if nbr_user_cols > self._cols:
341                new_col_nbr = nbr_user_cols -  self._cols
342                self.AppendCols(new_col_nbr, True)
343            #Add more rows to the grid if necessary 
344            nbr_user_row = len(self.data_outputs.values())
345            if nbr_user_row > self._rows + 1:
346                new_row_nbr =  nbr_user_row - self._rows
347                self.AppendRows(new_row_nbr, True)
348            # add data to the grid   
349            row = 0
350            col = 0
351            cell_col = 0
352            for col_name in  self.col_names:
353                # use the first row of the grid to add user defined labels
354                self.SetCellValue(row, col, str(col_name))
355                col += 1
356                cell_row =  1
357                value_list = self.data_outputs[col_name]
358               
359                for value in value_list:
360                    label = value
361                    if issubclass(value.__class__, BatchCell):
362                        label = value.label
363                    self.SetCellValue(cell_row, cell_col, str(label))
364                    cell_row += 1
365                cell_col += 1
366                if cell_row > self.max_row_touse:
367                    self.max_row_touse = cell_row
368                   
369    def get_grid_view(self):
370        """
371        Return value contained in the grid
372        """
373        grid_view = {}
374        for col in xrange(self.GetNumberCols()):
375            label = self.GetCellValue(row=0, col=col) 
376            label = label.strip()
377            if label != "":
378                grid_view[label] = []
379                for row in range(1, self.max_row_touse+1):
380                    value = self.GetCellValue(row=row, col=col)
381                    if value != "":
382                        grid_view[label].append(value) 
383                    else:
384                        grid_view[label].append(None) 
385        return grid_view
386   
387class Notebook(nb, PanelBase):
388    """
389    ## Internal name for the AUI manager
390    window_name = "Fit panel"
391    ## Title to appear on top of the window
392    """
393    window_caption = "Notebook "
394   
395    def __init__(self, parent, manager=None, data=None, *args, **kwargs):
396        """
397        """
398        nb.__init__(self, parent, -1,
399                    style=wx.aui.AUI_NB_WINDOWLIST_BUTTON| 
400                    wx.aui.AUI_BUTTON_DOWN|
401                    wx.aui.AUI_NB_DEFAULT_STYLE|
402                    wx.CLIP_CHILDREN)
403        PanelBase.__init__(self, parent)
404        self.enable_close_button()
405        self.parent = parent
406        self.manager = manager
407        self.data = data
408        #add empty page
409        self.add_empty_page()
410       
411        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.on_close_page)
412   
413    def add_empty_page(self):
414        """
415        """
416        grid = GridPage(self, panel=self.parent)
417        self.AddPage(grid, "", True)
418        pos = self.GetPageIndex(grid)
419        title = "Batch " + str(self.GetPageCount())
420        self.SetPageText(pos, title)
421        self.SetSelection(pos)
422        return grid , pos
423       
424    def enable_close_button(self):
425        """
426        display the close button on tab for more than 1 tabs else remove the
427        close button
428        """
429        if self.GetPageCount() <= 1:
430            style = self.GetWindowStyleFlag() 
431            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
432            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB == flag:
433                style = style & ~wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
434                self.SetWindowStyle(style)
435        else:
436            style = self.GetWindowStyleFlag()
437            flag = wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
438            if style & wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB != flag:
439                style |= wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
440                self.SetWindowStyle(style)
441             
442    def on_edit_axis(self):
443        """
444        Return the select cell of a given selected column
445        """
446        pos = self.GetSelection()
447        grid = self.GetPage(pos)
448        if len(grid.selected_cols) > 1:
449            msg = "Edit axis doesn't understand this selection.\n"
450            msg += "Please select only one column"
451            raise ValueError, msg
452        if len(grid.selected_cols) == 1:
453            col = grid.selected_cols[0]
454            if len(grid.selected_cells) > 0:
455                cell_row, cell_col = grid.selected_cells[0]
456                if cell_col  != col:
457                    msg = "Edit axis doesn't understand this selection.\n"
458                    msg += "Please select element of the same col"
459                    raise ValueError, msg
460        return grid.selected_cells
461       
462   
463    def get_column_labels(self):
464        """
465        return dictionary of columns labels of the current page
466        """
467        pos = self.GetSelection()
468        grid = self.GetPage(pos)
469        labels = {}
470        row = 0
471        for col in range(grid.GetNumberCols()):
472            label = grid.GetCellValue(row, col)
473            if label.strip() != "" :
474                labels[label.strip()] = col
475        return labels
476       
477    def create_axis_label(self, cell_list):
478        """
479        Receive a list of cells and  create a string presenting the selected
480        cells.
481        :param cell_list: list of tuple
482       
483        """
484        pos = self.GetSelection()
485        grid = self.GetPage(pos)
486        label = ""
487        col_name = ""
488        def create_label(col_name,  row_min=None, row_max=None):
489            """
490            """
491            result = ""
492            if row_min is not  None or row_max is not None:
493                if row_min is None:
494                    result = str(row_max) + "]"
495                elif row_max is None:
496                     result = str(col_name) + "[" + str(row_min) + ":"
497                else:
498                    result = str(col_name) +  "[" + str(row_min) + ":"
499                    result += str(col_name) + str(row_max) + "]"
500            return result
501           
502        if len(cell_list) > 0:
503            if len(cell_list) == 1:
504                 row_min, col  = cell_list[0]   
505                 col_name = grid.GetCellValue(0, col)
506                 label = create_label(col_name, row_min+1 , row_min+1)
507                 return  label,  col_name
508            else:
509                temp_list = copy.deepcopy(cell_list)
510                temp_list.sort()
511                length = len(temp_list)
512                row_min, col  = temp_list[0]   
513                row_max, _  = temp_list[length-1]
514                col_name = grid.GetCellValue(0, col)
515                index = 0
516                for row in xrange(row_min, row_max +1):
517                    if index > 0 and index < len(temp_list):
518                        new_row, _ = temp_list[index]
519                        if row != new_row:
520                            temp_list.insert(index, (None, None))
521                            if index -1 >=0:
522                                new_row, _ = temp_list[index-1]
523                                label += create_label(col_name, None, new_row +1)
524                                label += ","
525                            if index + 1 < len(temp_list):
526                                new_row, _ = temp_list[index + 1]
527                                label += create_label(col_name, new_row+1, None)
528                    if index == 0:
529                        label += create_label(col_name,  row_min+1, None)
530                    elif index == len(temp_list)-1:
531                        label += create_label(col_name, None, row_max+1)
532                    index += 1
533                return label, col_name
534   
535    def on_close_page(self, event):
536        """
537        close the page
538        """
539        if self.GetPageCount() == 1:
540            event.Veto()
541        self.enable_close_button()
542       
543    def set_data(self, data_inputs, data_outputs, details="", file_name=None):
544        if data_outputs is None or data_outputs == {}:
545            return
546       
547        for pos in range(self.GetPageCount()):
548            grid = self.GetPage(pos)
549            if grid.data is None:
550                #Found empty page
551                grid.set_data(data_inputs=data_inputs, 
552                              data_outputs=data_outputs,
553                              details=details,
554                              file_name=file_name) 
555                self.SetSelection(pos) 
556                return
557               
558        grid, pos = self.add_empty_page()
559        grid.set_data(data_inputs=data_inputs, 
560                      data_outputs=data_outputs,
561                      file_name=file_name,
562                      details=details)
563   
564    def add_column(self):
565        """
566        Append a new column to the grid
567        """
568        pos = self.GetSelection()
569        grid = self.GetPage(pos)
570        grid.AppendCols(1, True)
571       
572   
573
574
575
576class GridPanel(SPanel):
577    def __init__(self, parent, data_inputs=None,
578                 data_outputs=None, *args, **kwds):
579        SPanel.__init__(self, parent , *args, **kwds)
580       
581        self.vbox = wx.BoxSizer(wx.VERTICAL)
582       
583        self.plotting_sizer = wx.FlexGridSizer(3, 7, 10, 5)
584        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
585        self.grid_sizer = wx.BoxSizer(wx.HORIZONTAL)
586        self.vbox.AddMany([(self.grid_sizer, 1, wx.EXPAND, 0),
587                           (wx.StaticLine(self, -1), 0, wx.EXPAND, 0),
588                           (self.plotting_sizer),
589                           (self.button_sizer)])
590        self.parent = parent
591        self._data_inputs = data_inputs
592        self._data_outputs = data_outputs
593        self.x = []
594        self.= []
595        self.x_axis_label = None
596        self.y_axis_label = None
597        self.x_axis_title = None
598        self.y_axis_title = None
599        self.x_axis_unit = None
600        self.y_axis_unit = None
601        self.view_button = None
602        self.plot_button = None
603        self.notebook = None
604        self.layout_grid()
605        self.layout_plotting_area()
606        self.SetSizer(self.vbox)
607 
608    def set_xaxis(self, label="", x=None):
609        """
610        """
611        if x is None:
612            x = []
613        self.x = x
614        self.x_axis_label.SetValue("%s[:]" % str(label))
615        self.x_axis_title.SetValue(str(label))
616       
617    def set_yaxis(self, label="", y=None):
618        """
619        """
620        if y is None:
621            y = []
622        self.y = y
623        self.y_axis_label.SetValue("%s[:]" % str(label))
624        self.y_axis_title.SetValue(str(label))
625       
626    def get_plot_axis(self, col, list):
627        """
628       
629        """
630        axis = []
631        pos = self.notebook.GetSelection()
632        grid = self.notebook.GetPage(pos)
633        for row in list:
634            label = grid.GetCellValue(0, col)
635            value = grid.GetCellValue(row - 1, col).strip()
636            if value != "":
637                if label.lower().strip() == "data":
638                    axis.append(float(row - 1))
639                else:
640                    try:
641                        axis.append(float(value))
642                    except:
643                        msg = "Invalid data in row %s column %s" % (str(row),
644                                                                    str(col))
645                        wx.PostEvent(self.parent.parent, 
646                             StatusEvent(status=msg, info="error")) 
647            else:
648                axis.append(None) 
649        return axis
650   
651    def on_save_column(self, parent):
652        """
653        """
654        pos = self.notebook.GetSelection()
655        grid = self.notebook.GetPage(pos)
656        if parent is not None and  self.data is not None:
657            parent.write_batch_tofile(data=grid.data, 
658                                               file_name=path,
659                                               details=self.details)
660       
661    def on_view(self, event):
662        """
663        Get object represented buy the given cell and plot them.
664        """
665        pos = self.notebook.GetSelection()
666        grid = self.notebook.GetPage(pos)
667        title = self.notebook.GetPageText(pos)
668       
669       
670        group_id = wx.NewId()
671        for cell in grid.selected_cells:
672            row, col = cell
673            label_row = 0
674            label = grid.GetCellValue(label_row, col)
675            if label in grid.data:
676                values = grid.data[label]
677                value = values[row -1]
678                if issubclass(value.__class__, BatchCell):
679                    for new_plot in value.object:
680                        if new_plot is None:
681                            msg = "Row %s , " % str(row)
682                            msg += "Column %s doesn't have a view" % str(label)
683                            #raise ValueError, msg
684                            wx.PostEvent(self.parent.parent, 
685                                 StatusEvent(status=msg, info="error")) 
686                            return
687                        if issubclass(new_plot.__class__, Data1D):
688                            new_plot.group_id = group_id
689                            new_plot.list_group_id .append(group_id)
690                        else:
691                            if label.lower() in ["data", "chi2"]:
692                                if len(grid.selected_cells) != 1:
693                                    msg = "Can only view one"
694                                    msg += " selected data at once"
695                                    wx.PostEvent(self.parent.parent, 
696                                                 StatusEvent(status=msg,
697                                                              info="error")) 
698                                    return
699                               
700                        wx.PostEvent(self.parent.parent, 
701                                     NewPlotEvent(plot=new_plot, 
702                                  group_id=str(new_plot.group_id),
703                                   title =title)) 
704                else:
705                   
706                    msg = "Row %s , " % str(row)
707                    msg += "Column %s doesn't have a view" % str(label)
708                    #raise ValueError, msg
709                    wx.PostEvent(self.parent.parent, 
710                         StatusEvent(status=msg, info="error")) 
711                    return
712   
713       
714     
715   
716    def on_plot(self, event):
717        """
718        Evaluate the contains of textcrtl and plot result
719        """ 
720        pos = self.notebook.GetSelection()
721        grid = self.notebook.GetPage(pos)
722        column_names = {}
723        if grid is not None:
724            column_names = self.notebook.get_column_labels()
725        #evalue x
726        sentence = self.x_axis_label.GetValue()
727        if sentence.strip() == "":
728            msg = "select value for x axis"
729            raise ValueError, msg
730        dict = parse_string(sentence, column_names.keys())
731        for tok, (col_name, list) in dict.iteritems():
732            col = column_names[col_name]
733            xaxis = self.get_plot_axis(col, list)
734            sentence = sentence.replace(tok, 
735                                        "numpy.array(%s)" % str(xaxis))
736        for key, value in FUNC_DICT.iteritems():
737            sentence = sentence.replace(key.lower(), value)
738        x = eval(sentence)
739        #evaluate y
740        sentence = self.y_axis_label.GetValue()
741        if sentence.strip() == "":
742            msg = "select value for y axis"
743            raise ValueError, msg
744        dict = parse_string(sentence, column_names.keys())
745        for tok, (col_name, list) in dict.iteritems():
746            col = column_names[col_name]
747            yaxis = self.get_plot_axis(col, list)
748            sentence = sentence.replace(tok, 
749                                        "numpy.array(%s)" % str(yaxis))
750        for key, value in FUNC_DICT.iteritems():
751            sentence = sentence.replace(key, value)
752        y = eval(sentence)
753        #plotting
754        new_plot = Data1D(x=x, y=y)
755        new_plot.id =  wx.NewId()
756        new_plot.group_id = wx.NewId()
757        title = "%s vs %s" % (self.y_axis_title.GetValue(), 
758                              self.x_axis_title.GetValue())
759        new_plot.xaxis(self.x_axis_title.GetValue(), self.x_axis_unit.GetValue())
760        new_plot.yaxis(self.y_axis_title.GetValue(), self.y_axis_unit.GetValue())
761        try:
762            title = self.notebook.GetPageText(pos)
763            new_plot.name = title
764            wx.PostEvent(self.parent.parent, 
765                             NewPlotEvent(plot=new_plot, 
766                        group_id=str(new_plot.group_id), title =title))   
767        except:
768             wx.PostEvent(self.parent.parent, 
769                             StatusEvent(status=msg, info="error")) 
770       
771    def layout_grid(self):
772        """
773        Draw the area related to the grid
774        """
775        self.notebook = Notebook(parent=self)
776        self.notebook.set_data(self._data_inputs, self._data_outputs)
777        self.grid_sizer.Add(self.notebook, 1, wx.EXPAND, 0)
778       
779    def layout_plotting_area(self):
780        """
781        Draw area containing options to plot
782        """
783       
784        self.x_axis_title = wx.TextCtrl(self, -1)
785        self.y_axis_title = wx.TextCtrl(self, -1)
786        self.x_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
787        self.y_axis_label = wx.TextCtrl(self, -1, size=(200, -1))
788        self.x_axis_add = wx.Button(self, -1, "Add")
789        self.x_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
790                            id=self.x_axis_add.GetId())
791        self.y_axis_add = wx.Button(self, -1, "Add")
792        self.y_axis_add.Bind(event=wx.EVT_BUTTON, handler=self.on_edit_axis, 
793                            id=self.y_axis_add.GetId())
794        self.x_axis_unit = wx.TextCtrl(self, -1)
795        self.y_axis_unit = wx.TextCtrl(self, -1)
796        self.view_button = wx.Button(self, -1, "View")
797        wx.EVT_BUTTON(self, self.view_button.GetId(), self.on_view)
798        self.plot_button = wx.Button(self, -1, "Plot")
799        self.button_sizer.AddMany( [ (500, 30),
800                                (self.view_button, 0, wx.RIGHT|wx.BOTTOM, 10),
801                                (self.plot_button, 0, wx.RIGHT|wx.BOTTOM, 10)])
802       
803        wx.EVT_BUTTON(self, self.plot_button.GetId(), self.on_plot)
804        self.plotting_sizer.AddMany([
805                    (wx.StaticText(self, -1, "x-axis label"), 1,
806                      wx.TOP|wx.BOTTOM|wx.LEFT, 10),
807                    (self.x_axis_label, 1, wx.TOP|wx.BOTTOM, 10),
808                    (self.x_axis_add, 1, wx.TOP|wx.BOTTOM|wx.RIGHT, 10),
809                    (wx.StaticText(self, -1, "x-axis title"), 1, 
810                     wx.TOP|wx.BOTTOM|wx.LEFT, 10),
811                    (self.x_axis_title, 1, wx.TOP|wx.BOTTOM, 10),
812                    (wx.StaticText(self, -1 , "unit"), 1, 
813                     wx.TOP|wx.BOTTOM, 10),
814                    (self.x_axis_unit, 1, wx.TOP|wx.BOTTOM, 10),
815                    (wx.StaticText(self, -1, "y-axis label"), 1, 
816                     wx.BOTTOM|wx.LEFT, 10),
817                    (self.y_axis_label, wx.BOTTOM, 10),
818                    (self.y_axis_add, 1, wx.BOTTOM|wx.RIGHT, 10),
819                    (wx.StaticText(self, -1, "y-axis title"), 1, 
820                     wx.BOTTOM|wx.LEFT, 10),
821                    (self.y_axis_title,  wx.BOTTOM, 10),
822                    (wx.StaticText(self, -1 , "unit"), 1, wx.BOTTOM, 10),
823                    (self.y_axis_unit, 1, wx.BOTTOM, 10),
824                      (-1, -1),
825                      (-1, -1),
826                      (-1, -1),
827                      (-1, -1),
828                      (-1, -1),
829                      (-1, -1),
830                      (-1, 1)])
831   
832    def on_edit_axis(self, event):
833        """
834        Get the selected column on  the visible grid and set values for axis
835        """
836        cell_list = self.notebook.on_edit_axis()
837        label, title = self.create_axis_label(cell_list)
838        tcrtl = event.GetEventObject()
839        if tcrtl == self.x_axis_add:
840            self.edit_axis_helper(self.x_axis_label, self.x_axis_title,
841                                   label, title)
842        elif tcrtl == self.y_axis_add:
843            self.edit_axis_helper(self.y_axis_label, self.y_axis_title,
844                                   label, title)
845           
846    def create_axis_label(self, cell_list):
847        """
848        Receive a list of cells and  create a string presenting the selected
849        cells.
850        :param cell_list: list of tuple
851       
852        """
853        if self.notebook is not None:
854            return self.notebook.create_axis_label(cell_list)
855   
856    def edit_axis_helper(self, tcrtl_label, tcrtl_title, label, title):
857        """
858        get controls to modify
859        """
860        tcrtl_label.SetValue(str(label))
861        tcrtl_title.SetValue(str(title))
862       
863    def add_column(self):
864        """
865        """
866        if self.notebook is not None:
867            self.notebook.add_column()
868       
869    def on_remove_column(self):
870        """
871        """
872        if self.notebook is not None:
873            self.notebook.on_remove_column()
874       
875       
876class GridFrame(wx.Frame):
877    def __init__(self, parent=None, data_inputs=None, data_outputs=None, id=-1, 
878                 title="Batch Results", size=(700, 400)):
879        wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
880        self.parent = parent
881        self.panel = GridPanel(self, data_inputs, data_outputs)
882        menubar = wx.MenuBar()
883        self.SetMenuBar(menubar)
884       
885        self.curr_col = None
886        self.curr_grid = None
887        self.curr_col_name = ""
888        file = wx.Menu()
889        menubar.Append(file, "&File")
890       
891        hint = "Open file containing batch results"
892        open_menu = file.Append(wx.NewId(), 'Open ', hint)
893        wx.EVT_MENU(self, open_menu.GetId(), self.on_open)
894       
895        hint = "Open the the current grid into excel"
896        open_excel_menu = file.Append(wx.NewId(), 'Open with Excel', hint)
897        wx.EVT_MENU(self, open_excel_menu.GetId(), self.open_with_excel)
898        file.AppendSeparator()
899        save_menu = file.Append(wx.NewId(), 'Save As', 'Save into File')
900        wx.EVT_MENU(self, save_menu.GetId(), self.on_save_page)
901       
902        self.edit = wx.Menu()
903        hint = "Insert column before the selected column"
904        self.insert_before_menu = wx.Menu()
905        self.insert_sub_menu = self.edit.AppendSubMenu(self.insert_before_menu, 
906                                                      'Insert Before', hint)
907 
908        hint = "Remove the selected column"
909        self.remove_menu = self.edit.Append(-1, 'Remove Column', hint)
910        wx.EVT_MENU(self, self.remove_menu.GetId(), self.on_remove_column)
911       
912        self.Bind(wx.EVT_MENU_OPEN, self.on_menu_open)
913        menubar.Append(self.edit, "&Edit")
914        self.Bind(wx.EVT_CLOSE, self.on_close)
915       
916    def GetLabelText(self, id):
917        """
918        """
919        for item in self.insert_before_menu.GetMenuItems():
920            m_id = item.GetId() 
921            if m_id == id:
922                return item.GetLabel() 
923   
924    def on_remove_column(self, event):
925        """
926        """
927        pos = self.panel.notebook.GetSelection()
928        grid = self.panel.notebook.GetPage(pos)
929        grid.on_remove_column(event=None)
930       
931    def on_menu_open(self, event):
932        """
933       
934        """
935        if self.edit == event.GetMenu():
936            #get the selected column
937            pos = self.panel.notebook.GetSelection()
938            grid = self.panel.notebook.GetPage(pos)
939            col_list = grid.GetSelectedCols()
940            if len(col_list) > 0:
941                self.remove_menu.Enable(True)
942            else:
943                self.remove_menu.Enable(False)
944            if len(col_list)== 0 or len(col_list) > 1:
945                self.insert_sub_menu.Enable(False)
946               
947                label = "Insert Column Before"
948                self.insert_sub_menu.SetText(label)
949            else:
950                self.insert_sub_menu.Enable(True)
951               
952                col = col_list[0]
953                #GetColLabelValue(self, col)
954                col_name = grid.GetCellValue(row=0, col=col)
955                label = "Insert Column Before " + str(col_name)
956                self.insert_sub_menu.SetText(label)
957                for item in self.insert_before_menu.GetMenuItems():
958                    self.insert_before_menu.DeleteItem(item)
959                grid.insert_col_menu(menu=self.insert_before_menu, 
960                                     label=col_name, window=self)
961        event.Skip()
962       
963 
964       
965    def on_save_page(self, event):
966        """
967        """
968        if self.parent is not None:
969            pos = self.panel.notebook.GetSelection()
970            grid = self.panel.notebook.GetPage(pos)
971            reader, ext = os.path.splitext(grid.file_name)
972            path = None
973            if self.parent is not None: 
974                location = os.path.dirname(grid.file_name)
975                dlg = wx.FileDialog(self, "Save Project file",
976                            location, grid.file_name, ext, wx.SAVE)
977                path = None
978                if dlg.ShowModal() == wx.ID_OK:
979                    path = dlg.GetPath()
980                dlg.Destroy()
981                if path != None:
982                    if self.parent is not None:
983                        data = grid.get_grid_view()
984                        self.parent.write_batch_tofile(data=data, 
985                                               file_name=path,
986                                               details=grid.details)
987   
988    def on_open(self, event):
989        """
990        Open file containg batch result
991        """
992        if self.parent is not None:
993            self.parent.on_read_batch_tofile(event)
994           
995    def open_with_excel(self, event):
996        """
997        open excel and display batch result in Excel
998        """
999        if self.parent is not None:
1000            pos = self.panel.notebook.GetSelection()
1001            grid = self.panel.notebook.GetPage(pos)
1002            data = grid.get_grid_view()
1003            self.parent.open_with_externalapp(data=data,
1004                                               file_name=grid.file_name, 
1005                                               details=grid.details)
1006           
1007    def on_close(self, event):
1008        """
1009        """
1010        self.Hide()
1011       
1012   
1013    def on_append_column(self, event):
1014        """
1015        Append a new column to the grid
1016        """
1017        self.panel.add_column()
1018       
1019    def set_data(self, data_inputs, data_outputs, details="", file_name=None):
1020        """
1021        """
1022       
1023        self.panel.notebook.set_data(data_inputs=data_inputs, 
1024                            file_name=file_name,
1025                            details=details,
1026                            data_outputs=data_outputs)
1027     
1028     
1029class BatchOutputFrame(wx.Frame):
1030    """
1031    Allow to select where the result of batch will be displayed or stored
1032    """
1033    def __init__(self, parent, data_inputs, data_outputs, file_name="",
1034                 details="", *args, **kwds):
1035        """
1036        :param parent: Window instantiating this dialog
1037        :param result: result to display in a grid or export to an external
1038                application.
1039        """
1040        #kwds['style'] = wx.CAPTION|wx.SYSTEM_MENU
1041        wx.Frame.__init__(self, parent, *args, **kwds)
1042        self.parent = parent
1043        self.panel = wx.Panel(self)
1044        self.file_name = file_name
1045        self.details = details
1046        self.data_inputs = data_inputs
1047        self.data_outputs = data_outputs
1048        self.data = {}
1049        for item in (self.data_outputs, self.data_inputs):
1050            self.data.update(item)
1051        self.flag = 1
1052        self.SetSize((300, 200))
1053        self.local_app_selected = None
1054        self.external_app_selected = None
1055        self.save_to_file = None
1056        self._do_layout()
1057   
1058    def _do_layout(self):
1059        """
1060        Draw the content of the current dialog window
1061        """
1062        vbox = wx.BoxSizer(wx.VERTICAL)
1063        box_description = wx.StaticBox(self.panel, -1, str("Batch Outputs"))
1064        hint_sizer = wx.StaticBoxSizer(box_description, wx.VERTICAL)
1065        selection_sizer = wx.GridBagSizer(5, 5)
1066        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
1067        text = "Open with %s" % self.parent.application_name
1068        self.local_app_selected = wx.RadioButton(self.panel, -1, text,
1069                                                style=wx.RB_GROUP)
1070        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
1071                    id=self.local_app_selected.GetId())
1072        text = "Open with Excel"
1073        self.external_app_selected  = wx.RadioButton(self.panel, -1, text)
1074        self.Bind(wx.EVT_RADIOBUTTON, self.onselect,
1075                    id=self.external_app_selected.GetId())
1076        text = "Save to File"
1077        self.save_to_file = wx.CheckBox(self.panel, -1, text)
1078        self.Bind(wx.EVT_CHECKBOX, self.onselect,
1079                    id=self.save_to_file.GetId())
1080        self.local_app_selected.SetValue(True)
1081        self.external_app_selected.SetValue(False)
1082        self.save_to_file.SetValue(False)
1083        button_close = wx.Button(self.panel, -1, "Close")
1084        button_close.Bind(wx.EVT_BUTTON, id=button_close.GetId(),
1085                           handler=self.on_close)
1086        button_apply = wx.Button(self.panel, -1, "Apply")
1087        button_apply.Bind(wx.EVT_BUTTON, id=button_apply.GetId(),
1088                        handler=self.on_apply)
1089        button_apply.SetFocus()
1090        hint = ""
1091        hint_sizer.Add(wx.StaticText(self.panel, -1, hint))
1092        hint_sizer.Add(selection_sizer)
1093        #draw area containing radio buttons
1094        ix = 0
1095        iy = 0
1096        selection_sizer.Add(self.local_app_selected, (iy, ix),
1097                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1098        iy += 1
1099        selection_sizer.Add(self.external_app_selected, (iy, ix),
1100                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1101        iy += 1
1102        selection_sizer.Add(self.save_to_file, (iy, ix),
1103                           (1, 1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1104        #contruction the sizer contaning button
1105        button_sizer.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
1106
1107        button_sizer.Add(button_close, 0,
1108                        wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
1109        button_sizer.Add(button_apply, 0,
1110                                wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
1111        vbox.Add(hint_sizer,  0, wx.EXPAND|wx.ALL, 10)
1112        vbox.Add(wx.StaticLine(self.panel, -1),  0, wx.EXPAND, 0)
1113        vbox.Add(button_sizer, 0 , wx.TOP|wx.BOTTOM, 10)
1114        self.SetSizer(vbox)
1115       
1116    def on_apply(self, event):
1117        """
1118        Get the user selection and display output to the selected application
1119        """
1120        if self.flag == 1:
1121            self.parent.open_with_localapp(data_inputs=self.data_inputs,
1122                                            data_outputs=self.data_outputs)
1123        elif self.flag == 2:
1124            self.parent.open_with_externalapp(data=self.data, 
1125                                           file_name=self.file_name,
1126                                           details=self.details)
1127    def on_close(self, event):
1128        """
1129        close the Window
1130        """
1131        self.Close()
1132       
1133    def onselect(self, event=None):
1134        """
1135        Receive event and display data into third party application
1136        or save data to file.
1137       
1138        """
1139        if self.save_to_file.GetValue():
1140            reader, ext = os.path.splitext(self.file_name)
1141            path = None
1142            location = os.getcwd()
1143            if self.parent is not None: 
1144                location = os.path.dirname(self.file_name)
1145                dlg = wx.FileDialog(self, "Save Project file",
1146                            location, self.file_name, ext, wx.SAVE)
1147                path = None
1148                if dlg.ShowModal() == wx.ID_OK:
1149                    path = dlg.GetPath()
1150                dlg.Destroy()
1151                if path != None:
1152                    if self.parent is not None and  self.data is not None:
1153                        self.parent.write_batch_tofile(data=self.data, 
1154                                               file_name=path,
1155                                               details=self.details)
1156        if self.local_app_selected.GetValue():
1157            self.flag = 1
1158        else:
1159            self.flag = 2
1160        return self.flag
1161   
1162 
1163       
1164if __name__ == "__main__":
1165    app = wx.App()
1166   
1167    try:
1168        data = {}
1169        j = 0
1170        for i in range(4):
1171            j += 1
1172            data["index"+str(i)] = [i/j, i*j, i, i+j]
1173       
1174        data_input =  copy.deepcopy(data)   
1175        data_input["index5"] = [10,20,40, 50]
1176        frame = GridFrame(data_outputs=data, data_inputs=data_input)
1177        frame.Show(True)
1178    except:
1179        print sys.exc_value
1180       
1181    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.