source: sans/utils/bt5/bt5plot2/bt5plot2 @ 463

Last change on this file since 463 was 462, checked in by ajj, 14 years ago
  • Property svn:executable set to *
File size: 10.7 KB
Line 
1#!/usr/bin/env python
2
3import sys
4import os
5import matplotlib
6import numpy
7matplotlib.use('GTK')
8
9from matplotlib.figure import Figure
10from matplotlib.axes import Subplot
11from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar
12
13import usans
14
15try:
16    import pygtk
17    pygtk.require("2.0")
18   
19except:
20    pass
21
22try:
23    import gtk
24    import gtk.glade
25except:
26    sys.exit(1)
27
28
29
30class appGui:
31   
32    TARGETS = [('STRING', gtk.TARGET_SAME_APP, 0)]
33   
34    def __init__(self):
35       
36        gladefile = "bt5plot2.glade"
37        self.windowname = "win_Main"
38        self.wTree = gtk.glade.XML(gladefile, self.windowname)
39
40        event_dic = {"on_win_Main_destroy" : gtk.main_quit,
41                     "on_quit1_activate" : gtk.main_quit,
42                     "on_set_data_dir1_activate" : self.setdatadir,
43                     "on_xaxis_loglin_activate" : self.handle_xaxis_loglin,
44                     "on_yaxis_loglin_activate" : self.handle_yaxis_loglin,
45                     "on_plot_type_activate" : self.handle_plot_type_change}
46    #                 "on_tv_plotlist_key_press_event" : self.handle_plotlist_keypress}
47
48        #This is a bit clunky, but never mind.
49        #Set default plottype to rate. Glade definition sets that as default active button in menu
50        self.plottype = 'rate'
51       
52        self.wTree.signal_autoconnect(event_dic)
53
54        # Set up file list
55        self.filelistview = self.wTree.get_widget("tv_filelist")
56       
57        self.filelist = gtk.ListStore(str, 'gboolean', object, object, object)
58        self.filelist.set_sort_column_id(0, gtk.SORT_ASCENDING)
59        self.filelistview.set_model(self.filelist)
60
61        self.cellrenderertoggle = gtk.CellRendererToggle()
62        self.cellrenderertoggle.set_property('activatable', True)
63        self.cellrenderertoggle.connect("toggled", self.handle_plot_toggle, self.filelist)
64   
65        self.AddFileListColumns()
66
67        #fill the file list
68        self.FillFileList(self.GetDirList())
69
70        # Set up graphing widget to display xpeek data
71        self.figure = Figure(figsize=(4, 4), dpi=72)
72        self.axis = self.figure.add_subplot(111)
73        self.axis.set_yscale('log')
74        self.axis.set_aspect('auto')
75        self.axis.set_autoscale_on('True')
76        self.axis.set_xlabel('Motor position')
77        self.axis.set_ylabel('Counts')
78        self.axis.grid(True)
79       
80        self.canvas = FigureCanvasGTK(self.figure)
81        self.figure.canvas.mpl_connect('pick_event',self.handle_plot_click)
82        self.canvas.show()
83       
84        self.plotView = self.wTree.get_widget("hbox1")
85        self.plotView.pack_start(self.canvas, True, True)   
86       
87        self.metadataView = self.wTree.get_widget("tv_metadata")
88        self.mdlist = gtk.ListStore(str,str)
89       
90       
91        #self.filelistview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
92                #                                  self.TARGETS,
93                #                                   gtk.gdk.ACTION_COPY)
94
95        #self.filelistview.connect("drag_data_get", self.dnd_data_getdata)
96       
97       
98    def AddFileListColumns(self):
99        """This function adds a column to the list view.
100        First it create the gtk.TreeViewColumn and then set
101        some needed properties"""
102                       
103        column = gtk.TreeViewColumn('Filename', gtk.CellRendererText()
104            , text=0)
105        column.set_resizable(True)       
106        column.set_sort_column_id(0)
107        self.filelistview.append_column(column)
108
109        column = gtk.TreeViewColumn('', self.cellrenderertoggle, active=1)
110        self.filelistview.append_column(column)
111        return
112       
113    def GetDirList(self):
114        dirlist = os.listdir(os.getcwd())
115       
116        bt5list = [ x for x in dirlist if x.find('.bt5') > 0]
117       
118        return bt5list
119       
120   
121    def FillFileList(self, filenames):
122        self.filelist.clear()
123        for filename in filenames:
124            data,metadata = usans.getBT5DataFromFile(filename)
125            if data != 0:
126                self.filelist.append([filename, 0, (data,metadata), 0, 0])
127        return
128           
129
130    def setdatadir(self, widget):
131        chooser = gtk.FileChooserDialog(title="Select Data Directory", action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
132                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
133        chooser.set_default_response(gtk.RESPONSE_OK)
134        chooser.set_current_folder(os.getcwd())
135        response = chooser.run()
136        if response == gtk.RESPONSE_OK:
137            os.chdir(chooser.get_filename())
138            self.FillFileList(self.GetDirList())
139        chooser.destroy()
140
141    def handle_plot_toggle(self, cell, path, model):
142        model[path][1] = not model[path][1]
143
144        if model[path][1]:
145            #add plot
146            self.add_plot(model, path)
147        else:
148            #remove plot
149            self.remove_plot(model, path)
150        return
151
152    def add_plot(self, model, path):
153       
154        self.make_plottable_dataset(model, path, self.plottype)
155
156        if self.plottype == 'split':
157                model[path][4] = self.axis.plot(model[path][3][0],model[path][3][1], 'o',
158                                                                                         model[path][3][0],model[path][3][2], 'o',
159                                                                                         model[path][3][0],model[path][3][3], 'o',
160                                                                                         model[path][3][0],model[path][3][4], 'o',
161                                                                                         model[path][3][0],model[path][3][5], 'o')
162        else:
163            model[path][4] = self.axis.plot(model[path][3][0],model[path][3][1], 'bo', picker=5)
164       
165        self.rescale_and_redraw()
166        #self.canvas.draw()
167        return
168
169    def make_plottable_dataset(self, model, path, type):
170         
171         data,metadata = model[path][2]
172         
173         if type == 'total':
174             #generate totals
175             xdata = []
176             ydata = []     
177             
178             mvals = data.keys()
179             mvals.sort(usans.numeric_compare)
180             for mval in mvals:
181                 xdata.append(mval)
182                 ydata.append(data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])
183             
184             model[path][3] = [xdata, ydata]
185             
186         elif type == 'rate':
187             # generate countrate
188             xdata = []
189             ydata = []
190             
191             mvals = data.keys()
192             mvals.sort(usans.numeric_compare)
193             for mval in mvals:
194                 xdata.append(mval)
195             
196             if metadata['base'] == 'TIME':
197                #Counting in TIME base, so normalize by seconds
198                cnttime = metadata['mon']
199                for mval in mvals:
200                        ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])/cnttime)
201             else:
202                #Must be counting in monitor base so normalize by monitor
203                moncts = metadata['mon']
204                for mval in mvals:
205                        ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])/cnttime)
206             
207             model[path][3] = [xdata, ydata]
208             
209         elif type == 'trans':
210             xdata = []
211             ydata = []
212             
213             mvals = data.keys()
214             mvals.sort(usans.numeric_compare)
215             for mval in mvals:
216                 xdata.append(mval)
217                 ydata.append(data[mval][3])
218             
219             model[path][3] = [xdata, ydata]             
220         
221         elif type == 'mon':
222             xdata = []
223             ydata = []
224             
225             mvals = data.keys()
226             mvals.sort(usans.numeric_compare)
227             for mval in mvals:
228                 xdata.append(mval)
229                 ydata.append(data[mval][0])
230             
231             model[path][3] = [xdata, ydata]             
232             
233         elif type == 'split':
234             xdata = []
235             ydata1 = []
236             ydata2 = []
237             ydata3 = []
238             ydata4 = []
239             ydata5 = []
240             
241             mvals = data.keys()
242             mvals.sort(usans.numeric_compare)
243             for mval in mvals:
244                 xdata.append(mval)
245                 ydata1.append(data[mval][1])   
246                 ydata2.append(data[mval][2])   
247                 ydata3.append(data[mval][4])   
248                 ydata4.append(data[mval][5])   
249                 ydata5.append(data[mval][6])   
250
251             model[path][3] = [xdata,ydata1,ydata2,ydata3,ydata4,ydata5]
252         else:
253                pass
254             
255         return
256
257    def remove_plot(self, model, path):
258
259        for line in model[path][4]:
260                self.axis.lines.remove(line)
261       
262        if (len(self.axis.lines) > 0):
263                self.rescale_and_redraw()
264        else:
265                self.canvas.draw()     
266
267        return
268
269    def handle_xaxis_loglin(self, widget):
270
271
272        if (self.axis.get_xscale() == "log"):
273            self.axis.set_xscale('linear')
274        else:
275            self.axis.set_xscale('log')       
276
277
278        self.rescale_and_redraw()
279       
280        return   
281
282    def handle_yaxis_loglin(self, widget):
283
284
285        if (self.axis.get_yscale() == "log"):
286            self.axis.set_yscale('linear')
287        else:
288            self.axis.set_yscale('log')       
289
290        self.rescale_and_redraw()
291        return
292       
293    def handle_plot_type_change(self,widget):
294               
295        if widget.get_active():
296                self.plottype = widget.get_name().split('_')[1]
297                #print self.plottype
298               
299        return
300       
301    def rescale_and_redraw(self):
302
303        xdata = []
304        ydata = []
305
306        for line in self.axis.lines:
307                if self.axis.get_xscale() == 'log':
308                        xdata.extend([xval for xval in line.get_xdata() if xval > 0])
309                else:
310                        xdata.extend(line.get_xdata())
311                if self.axis.get_yscale() == 'log':
312                        ydata.extend([xval for xval in line.get_ydata() if xval > 0])
313                else:
314                        ydata.extend(line.get_ydata())
315     
316        #set limits
317        xmin = float(min(xdata))
318        xmax = float(max(xdata))
319        ymin = float(min(ydata))
320        ymax = float(max(ydata))       
321
322        #adjust for size of markers (sort of)
323        xmin = xmin - 0.1*abs(xmin)
324        xmax = xmax + 0.1*abs(xmax)
325        ymin = ymin - 0.1*abs(ymin)
326        ymax = ymax + 0.1*abs(ymax)
327               
328        self.axis.set_xlim(xmin,xmax)
329        self.axis.set_ylim(ymin,ymax)
330       
331        #self.axis.autoscale_view()
332        self.canvas.draw()
333
334        return
335
336    def handle_plot_click(self,event):
337        if isinstance(event.artist, matplotlib.lines.Line2D):
338            pickedline = event.artist
339            xdata = pickedline.get_xdata()
340            ydata = pickedline.get_ydata()
341            ind = event.ind
342            print 'Plot Click: ',zip(numpy.take(xdata,ind), numpy.take(ydata,ind))
343
344app = appGui()
345gtk.main()
Note: See TracBrowser for help on using the repository browser.