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

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