source: sans/utils/bt5/bt5plot2/BT5DataSet.py @ 655

Last change on this file since 655 was 654, checked in by ajj, 12 years ago

Fixes to handle errorbars

File size: 12.7 KB
Line 
1import usans
2import math
3
4
5class BT5DataSet:
6   
7    def __init__(self, fn=None):
8
9        self.fileName = fn
10        self.plot = None
11        self.detdata = {}
12        self.metadata = {}
13        self.alignvals = {}
14        self.alignvalstring = ''
15        self.scanmot = ''
16
17        if (self.fileName != None):
18            self.getBT5DataFromFile(self.fileName)
19       
20       
21    def getBT5DataFromFile(self,fileName):
22        '''
23        Takes a filename and returns a dictionary of the detector values
24        keyed by varying value (usually A2 or A5)
25        '''
26   
27        if usans.isBT5Data(fileName) == 1:
28   
29            motlist = []
30   
31            #print "File: ",fileName   
32            inputfile = open(fileName, "r")
33   
34            inputdata = inputfile.readlines()
35   
36            mdtmp = inputdata[0].replace("'", "")
37            mdtmp = mdtmp.split()
38       
39            #Sundry metadata about run settings
40            (self.metadata['filename'], self.metadata['datetime'],
41             self.metadata['mon'], self.metadata['prefactor'],
42             self.metadata['base'], self.metadata['numpnts'],
43             self.metadata['type']) = (mdtmp[0], ' '.join(mdtmp[1:5]), float(mdtmp[6]), int(mdtmp[7]), mdtmp[8], int(mdtmp[9]), mdtmp[10])
44       
45            #Comment string
46            self.metadata['title'] = inputdata[2].strip()
47       
48            #Start, step and end values for motors 1-6
49            motlist.append(inputdata[5].split()[1:])
50            motlist.append(inputdata[6].split()[1:])
51            motlist.append(inputdata[7].split()[1:])
52            motlist.append(inputdata[8].split()[1:])
53            motlist.append(inputdata[9].split()[1:])
54            motlist.append(inputdata[10].split()[1:]) 
55            self.metadata['motorvals'] = motlist
56       
57            self.scanmot = inputdata[12].split()[0]
58       
59            for index in range(13, len(inputdata), 2):
60                self.detdata[float(inputdata[index].split()[0])] = inputdata[index + 1].split(',')   
61   
62            for key in self.detdata.keys():
63                for val in range(0, len(self.detdata[key])):
64                    self.detdata[key][val] = int(self.detdata[key][val])
65   
66            inputfile.close()
67                   
68   
69   
70    def printDetectorData(self):
71        '''
72        Print the contents of the file in a formatted fashion
73   
74        Takes a dictionary of data as provided by getBT5DataFromFile() and prints out the contents
75        in a formatted fashion
76        '''
77        motorvals = self.detdata.keys()
78        motorvals.sort(cmp=numeric_compare)
79   
80        for motorval in motorvals:
81            str = repr(motorval) + ":"
82            str += "\tMon: " + repr(detdata[motorval][0])
83            str += "\tDet 1-5: " + repr(detdata[motorval][2])
84            str += "\t" + repr(detdata[motorval][1])
85            str += "\t" + repr(detdata[motorval][4])
86            str += "\t" + repr(detdata[motorval][5])
87            str += "\t" + repr(detdata[motorval][6])
88            str += "\tTrans: " + repr(detdata[motorval][3])
89            print str
90   
91        return 0
92   
93    def calcAlignVals(self,mv):
94        '''
95        Return the values we record in the logbook for a given motor position
96   
97        Takes a dictionary as provided by getBT5DataFromFile and returns a dictionary with
98        keys Central, Trans and Sum
99        '''
100        motorval = float(mv)
101       
102        self.alignvals['Central'] = self.detdata[motorval][1]
103        self.alignvals['Trans'] = self.detdata[motorval][3]
104        self.alignvals['Sum'] = self.detdata[motorval][1] + self.detdata[motorval][2] + self.detdata[motorval][4] + self.detdata[motorval][5] + self.detdata[motorval][6]     
105        self.alignvals['Monitor'] = self.detdata[motorval][0]
106        self.alignvals['Sum/Monitor'] = float(self.alignvals['Sum'])/float(self.alignvals['Monitor'])
107       
108        self.alignvalstring = self.scanmot+": %5.2f" % motorval 
109        self.alignvalstring += "   #4: "+repr(self.alignvals['Central'])
110        self.alignvalstring += "   Trans: "+repr(self.alignvals['Trans'])
111        self.alignvalstring += "\nSum: "+repr(self.alignvals['Sum'])
112        self.alignvalstring += "   MCR: "+repr(self.alignvals['Monitor'])
113        self.alignvalstring += "   Sum/MCR: %5.3f" % self.alignvals['Sum/Monitor']
114   
115    def maxDetCount(self, detector):
116        '''
117        Return the maximum value and corresponding motor position for a given detector
118       
119        Takes a dictionary as provided by getBT5DataFromFile() and returns a dictionary with
120        keys Position and Value
121        '''   
122        maxpos = ''
123        maxval = 0
124        result = {}
125   
126        mvals = self.detdata.keys()
127        det = {'1':2, '2':1, '3':4, '4':5, '5':6}[repr(detector)]
128   
129        for mval in mvals:
130            if self.detdata[mval][det] > maxval:
131                maxval = data[mval][det]       
132                maxpos = mval
133       
134        result['Position'] = maxpos
135        result['Value'] = maxval
136   
137        return result
138   
139    def plot_dataset(self,axes,plottype=None,yerrorbars=True):
140        '''
141        Takes a matplotlib axes object and plots bt5 dataset on it.
142        '''
143        data = self.detdata
144        metadata = self.metadata
145
146        if type is None:
147            plottype = 'rate'
148                                       
149        if plottype == 'total':
150            #generate totals
151            xdata = []
152            ydata = [] 
153            yerror = []   
154             
155            mvals = data.keys()
156            mvals.sort(usans.numeric_compare)
157            for mval in mvals:
158                xdata.append(mval)
159                ydata.append(data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6])
160                if (ydata[len(ydata)-1] == 0):
161                    yerror.append(0)
162                else:
163                    yerror.append(math.sqrt(ydata[len(ydata)-1]))
164           
165            axes.set_ylabel("Counts")
166            if yerrorbars == True:
167                self.plot = axes.errorbar(xdata,ydata,yerror,None,'bo', picker=5)
168            else:
169                self.plot = axes.errorbar(xdata,ydata,None,None,'bo', picker=5)
170               
171        elif plottype == 'rate':
172            # generate countrate
173            xdata = []
174            ydata = []
175            yerror = []
176           
177            mvals = data.keys()
178            mvals.sort(usans.numeric_compare)
179            for mval in mvals:
180                xdata.append(mval)
181             
182            if metadata['base'] == 'TIME':
183                #Counting in TIME base, so normalize by seconds
184                cnttime = metadata['mon']
185                for mval in mvals:
186                    ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6]) / cnttime)
187                    if (ydata[len(ydata)-1] == 0):
188                        yerror.append(0)
189                    else:
190                        yerror.append(math.sqrt(ydata[len(ydata)-1])/math.sqrt(cnttime))
191                    axes.set_ylabel("Counts/second")
192            else:
193                #Must be counting in monitor base so normalize by monitor
194                moncts = metadata['mon']
195                for mval in mvals:
196                    ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6]) / cnttime)
197                    if (ydata[len(ydata)-1] == 0):
198                        yerror.append(0)
199                    else:
200                        yerror.append(math.sqrt(ydata[len(ydata)-1])/math.sqrt(cnttime))
201                    axes.set_ylabel("Counts/Monitor Count")
202           
203            if yerrorbars == True:
204                self.plot = axes.errorbar(xdata,ydata,yerror,None,'bo', picker=5)
205            else:
206                self.plot = axes.errorbar(xdata,ydata,None,None,'bo', picker=5)
207
208            print xdata
209            print ydata
210            print yerror
211               
212        elif plottype == 'trans':
213            xdata = []
214            ydata = []
215            yerror = []
216             
217            mvals = data.keys()
218            mvals.sort(usans.numeric_compare)
219            for mval in mvals:
220                xdata.append(mval)
221                ydata.append(data[mval][3])
222                if (ydata[len(ydata)-1] == 0):
223                    yerror.append(0)
224                else:
225                    yerror.append(math.sqrt(ydata[len(ydata)-1]))
226
227            axes.set_ylabel("Transmission Detector Counts")
228            if yerrorbars == True:
229                self.plot = axes.errorbar(xdata,ydata,yerror,None,'bo', picker=5)
230            else:
231                self.plot = axes.errorbar(xdata,ydata,None,None,'bo', picker=5)
232           
233         
234        elif plottype == 'mon':
235            xdata = []
236            ydata = []
237            yerror = []
238           
239            mvals = data.keys()
240            mvals.sort(usans.numeric_compare)
241            for mval in mvals:
242                xdata.append(mval)
243                ydata.append(data[mval][0])
244                yerror.append(math.sqrt(ydata[len(ydata)-1]))
245               
246            axes.set_ylabel("Monitor Counts")
247            if yerrorbars == True:
248                self.plot = axes.errorbar(xdata,ydata,yerror,None,'bo', picker=5)
249            else:
250                self.plot = axes.errorbar(xdata,ydata,None,None,'bo', picker=5)
251             
252        elif plottype == 'split':
253            xdata = []
254            ydata1 = []
255            ydata2 = []
256            ydata3 = []
257            ydata4 = []
258            ydata5 = []
259            yerror1 = []
260            yerror2 = []
261            yerror3 = []
262            yerror4 = []
263            yerror5 = []
264             
265            mvals = data.keys()
266            mvals.sort(usans.numeric_compare)
267            for mval in mvals:
268                xdata.append(mval)
269                ydata1.append(data[mval][1])   
270                yerror1.append(math.sqrt(ydata1[len(ydata1)-1]))
271                ydata2.append(data[mval][2])   
272                yerror2.append(math.sqrt(ydata2[len(ydata2)-1]))
273                ydata3.append(data[mval][4])
274                yerror3.append(math.sqrt(ydata3[len(ydata3)-1]))
275                ydata4.append(data[mval][5]) 
276                yerror4.append(math.sqrt(ydata4[len(ydata4)-1]))
277                ydata5.append(data[mval][6]) 
278                yerror5.append(math.sqrt(ydata5[len(ydata5)-1]))
279           
280            axes.set_ylabel("Counts")   
281            if yerrorbars == True:
282                self.plot = (axes.errorbar(xdata,ydata1,yerror1,None, 'o'),
283                             axes.errorbar(xdata,ydata2,yerror2,None, 'o'),
284                             axes.errorbar(xdata,ydata3,yerror3,None, 'o'),
285                             axes.errorbar(xdata,ydata4,yerror4,None, 'o'),
286                             axes.errorbar(xdata,ydata5,yerror5,None, 'o')) 
287            else:
288                self.plot = (axes.errorbar(xdata,ydata1,None,None, 'o'),
289                             axes.errorbar(xdata,ydata2,None,None, 'o'),
290                             axes.errorbar(xdata,ydata3,None,None, 'o'),
291                             axes.errorbar(xdata,ydata4,None,None, 'o'),
292                             axes.errorbar(xdata,ydata5,None,None, 'o')) 
293           
294        elif plottype == 'nrate':
295            # generate countrate
296                        # produce monitor normalized  plot
297            xdata = []
298            ydata = []
299            yerror = []
300           
301            mvals = data.keys()
302            mvals.sort(usans.numeric_compare)
303            for mval in mvals:
304                xdata.append(mval)
305             
306            #Always normalize by appropriate monitor counts
307            for mval in mvals:
308                 ydata.append((data[mval][1] + data[mval][2] + data[mval][4] + data[mval][5] + data[mval][6]) / (data[mval][0]/1e6))
309                 if (ydata[len(ydata)-1] == 0):
310                     yerror.append(0)
311                 else:
312                     yerror.append(math.sqrt(ydata[len(ydata)-1])/math.sqrt(data[mval][0]/1e6))
313
314            axes.set_ylabel("Counts / (10^6 Monitor Counts)")
315            if yerrorbars == True:
316                self.plot = axes.errorbar(xdata,ydata,yerror,None,'bo', picker=5)
317            else:
318                self.plot = axes.errorbar(xdata,ydata,None,None,'bo', picker=5)
319 
320 
321
322           
323    def remove_plot(self):
324
325        #Is it a plot with errorbars?
326        if type(self.plot[0]) is tuple:
327            #split plot
328            for splot in self.plot:
329                splot[0].remove()
330                for linec in splot[1]:
331                    linec.remove()
332                for linec in splot[2]:
333                    linec.remove()
334        else:
335            #normal plot
336            for line in self.plot[0:1]:
337                axes = line.get_axes()
338                axes.lines.remove(line)
339            for linec in self.plot[1]:
340                linec.remove()
341            for linec in self.plot[2]:
342                linec.remove()
Note: See TracBrowser for help on using the repository browser.