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

Last change on this file since 443 was 443, checked in by ajj, 14 years ago

Handle plot removal, deal with rescaling on plot removal.

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