Commit before breaking everything
[matches/honours.git] / research / TCS / process.py~
1 #!/usr/bin/python -u
2
3 #
4 # @file process.py
5 # @purpose Process TCS data
6 #               Takes S(E) = dI/dE
7 # @author Sam Moore
8 # @date August 2012
9 #
10
11 import sys
12 import os
13 import re # Regular expressions - for removing comments
14 import odict #ordered dictionary
15 import copy
16
17 import Gnuplot, Gnuplot.funcutils
18 import string
19
20 gnuplot = Gnuplot.Gnuplot()
21
22 def Reset():
23         gnuplot = Gnuplot.Gnuplot()
24
25 def FindDataFiles(directory=".", depth=1, result=None):
26         if result == None:
27                 result = []
28         
29         for f in os.listdir(directory):
30                 if os.path.isdir(directory+"/"+str(f)):
31                         if depth > 1:
32                                 result += FindDataFiles(directory+"/"+str(f), depth-1, result)
33                         continue
34                 s = f.split(".")
35                 if (len(s) == 2 and s[1] == "dat"):
36                         result.append(directory+"/"+str(f))
37
38         return result
39
40 def BaseName(f):
41         a = f.split("/")
42         return a[len(a)-1]
43         
44
45 def DirectoryName(f, start=0,back=1):
46         a = f.split("/")
47         return string.join(a[start:(len(a)-back)], "/")
48
49 def GetData(filename):
50         input_file = open(filename, "r")
51         data = []
52         for line in input_file:
53                 line = re.sub("#.*", "", line).strip("\r\n ")
54                 if len(line) == 0:
55                         continue
56                 data.append(map(lambda e : float(e), line.split("\t")))
57         return data
58
59 def DoNothing(data):
60         return data
61
62 def AverageAllDataSets(directory=".", function=DoNothing):
63         dirs = {}
64         for f in os.listdir(directory):
65                 if os.path.isdir(directory+"/"+str(f)) == True:
66                         data_set = []
67                         for datafile in os.listdir(directory+"/"+str(f)):
68                                 if datafile.split(".")[1] == "dat":
69                                         data_set.append(GetData(f))
70
71                         avg = Average(data_set)
72                         dirs.update({f : avg})
73         return dirs
74
75 def GetDataSets(directory="."):
76         data_sets = []
77         for f in os.listdir(directory):
78                 if os.path.isdir(directory+"/"+str(f)) == False:
79                         if (len(f.split(".")) > 1 and f.split(".")[1] == "dat"):
80                                 d = GetData(directory+"/"+str(f))
81                                 if len(d) > 0:
82                                         data_sets.append(d)
83         return data_sets        
84
85
86
87 def Derivative(data, a=1, b=2, sigma=None,step=1):
88         result = [[]]
89         n = 0
90         dI = [0,0]
91         dE = [0,0]
92         
93         for i in range(0, len(data),step):
94                 result[len(result)-1] = [d for d in data[i]]
95                 if (i >= step):
96                         dE[0] = data[i][a] - data[i-step][a]
97                         dI[0] = data[i][b] - data[i-step][b]
98                 else:
99                         dI[0] = None
100
101                 if (i < len(data)-step):
102                         dE[1] = data[i+step][a] - data[i][a]
103                         dI[1] = data[i+step][b] - data[i][b]
104                 else:
105                         dI[1] = None            
106
107                 if sigma != None:
108                         #print str(data[i]) + " ["+str(sigma)+"] = " + str(data[i][int(abs(sigma))])
109                         if sigma < 0:
110                                 if dI[0] != None: dI[0] -= 0.5*data[i][int(abs(sigma))]
111                                 if dI[1] != None: dI[1] -= 0.5*data[i][int(abs(sigma))]
112                         else:
113                                 if dI[0] != None: dI[0] += 0.5*data[i][int(abs(sigma))]
114                                 if dI[1] != None: dI[1] += 0.5*data[i][int(abs(sigma))]
115
116                 deltaE = 0.0
117                 deltaI = 0.0
118                 count = 0
119                 if dI[0] != None:
120                         deltaE += dE[0]
121                         deltaI += dI[0]
122                         count += 1
123                 if dI[1] != None:
124                         deltaE += dE[1]
125                         deltaI += dI[1]
126                         count += 1
127
128                 deltaI /= float(count)
129                 deltaE /= float(count)
130
131
132                 if (deltaE != 0):       
133                         result[len(result)-1][b] = (deltaI / deltaE)
134                 else:
135                         result[len(result)-1][b] = 0.0
136                 result.append([])
137                         
138         return result[0:len(result)-1]
139
140 def MaxNormalise(data, u=1):    
141         result = copy.deepcopy(data)
142         if (len(data) <= 0):
143                 return result
144         maxval = max(data, key = lambda e : e[u])[u]
145
146         for d in result:
147                 d[u] = d[u] / maxval
148                 
149         return result
150         
151 def Average(data_sets, u=1): 
152         avg = odict.odict()
153         for t in data_sets:
154                 for p in t:
155                         if p[u] in avg:
156                                 #print "Already have " + str(p[u])
157                                 avg[p[u]][1] += 1
158                                 for i in range(0, len(p)):
159                                         avg[p[u]][0][i] += p[i]
160                         else:
161                                 #print "Create key for " + str(p[u])
162                                 avg.update({p[u] : [p, 1]})
163
164         for a in avg.keys():
165                 for i in range(0, len(avg[a][0])):
166                         avg[a][0][i] /= float(avg[a][1])
167         return map(lambda e : e[1][0], sorted(avg.items(), key = lambda e : e[0]))
168
169 def FullWidthAtHalfMax(data, u=1):
170         maxval = max(data, key = lambda e : e[u])
171         peak = data.index(maxval)
172         maxval = maxval[0]
173         lhs = None
174         rhs = None
175         for i in range(1, len(data)/2):
176                 if lhs == None:
177                         if (peak-i > 0 and data[peak-i] < 0.50*maxval):
178                                 lhs = data[peak-i][u]
179                 if rhs == None:
180                         if (peak+i < len(data) and data[peak+i] < 0.50*maxval):
181                                 rhs = peak+i
182                 if lhs != None and rhs != None:
183                         break
184         if rhs == None or lhs == None:
185                 return abs(data[len(data)-1][0] - data[0][0])
186         else:
187                 return abs(rhs - lhs)
188
189 def SaveData(filename, data):
190         out = open(filename, "w", 0)
191         for a in data:
192                 for i in range(0, len(a)):
193                         out.write(str(a[i]))
194                         if (i < len(a) - 1):
195                                 out.write("\t")
196                         out.write("\n")
197
198 def CalibrateData(data, ammeter_scale=1e-6):
199         for i in range(0, len(data)):
200                 data[i][1] = 16.8 * float(data[i][1]) / 4000.0
201                 data[i][2] = ammeter_scale * 0.170 * float(data[i][2]) / 268.0
202                 data[i][3] = ammeter_scale * 0.170 * float(data[i][3]) / 268.0
203         return data
204
205 def ShowTCS(filename, calibrate=True, normalise=False, show_error=False, plot=gnuplot.plot,w="lp", step=1, output=None, title=""):
206         if type(filename) == type(""): 
207                 data = GetData(filename)
208         else:
209                 data = filename
210                 filename = "tcs data"
211
212         if (title == ""):
213                 title = BaseName(filename)
214
215         if (len(data) <= 0):
216                 return data
217
218         if calibrate: 
219                 data = CalibrateData(data)
220                 units = ["V", "uA / V"]
221         else:
222                 units = ["DAC counts", "ADC counts / DAC counts"]
223
224         if not normalise:
225                 gnuplot("set ylabel \"dI(E)/dE ("+str(units[1])+")\"")
226         else:
227                 data = MaxNormalise(data)
228                 gnuplot("set ylabel \"dI(E)/dE (normalised)\"")
229
230         if (output != None and type(output) == type("")):
231                 gnuplot("set term png size 640,480")
232                 gnuplot("set output \""+str(output)+"\"")
233
234         gnuplot("set title \"Total Current Spectrum S(E)\"")
235         gnuplot("set xlabel \"U ("+str(units[0])+")\"")
236
237
238         d = Derivative(data, 1, 2, step=step)
239         
240         plot(Gnuplot.Data(d, using="2:3", with_=w,title=title))
241         if (show_error):
242                 error1 = Derivative(data, 1, 2, -3,step=step)
243                 error2 = Derivative(data, 1, 2, +3,step=step)
244                 gnuplot.replot(Gnuplot.Data(error1, using="2:3", with_=w,title="-sigma/2"))
245                 gnuplot.replot(Gnuplot.Data(error2, using="2:3", with_=w, title="+sigma/2"))
246
247         gnuplot("set term wxt")
248         return data
249
250 def ShowData(filename,calibrate=True, normalise=False, show_error=False, plot=gnuplot.plot,w="lp", step=1, output=None, title=""):
251         if type(filename) == type(""): 
252                 data = GetData(filename)
253         else:
254                 data = filename
255                 filename = "raw data"
256
257         if (title == ""):
258                 title = BaseName(filename)
259
260         if len(data) <= 0:
261                 return data
262         if calibrate: 
263                 data = CalibrateData(data)
264                 units = ["V", "uA"]
265         else:
266                 units = ["DAC counts", "ADC counts"]
267
268         if not normalise:
269                 gnuplot("set ylabel \"I(E) ("+str(units[1])+")\"")
270         else:
271                 data = MaxNormalise(data)
272                 gnuplot("set ylabel \"I(E) (normalised)\"")
273
274         if (output != None and type(output) == type("")):
275                 gnuplot("set term png size 640,480")
276                 gnuplot("set output \""+str(output)+"\"")
277
278         gnuplot("set title \"Sample Current I(E)\"")
279         gnuplot("set xlabel \"U ("+str(units[0])+")\"")
280
281
282         #d = Derivative(data, 1, 2, step=step)
283         
284         plot(Gnuplot.Data(data, using="2:3", with_=w,title=title))
285         if (show_error):
286                 error1 = copy.deepcopy(data)
287                 error2 = copy.deepcopy(data)
288                 for i in range(len(data)):
289                         #print str(data[i])
290                         error1[i][2] -= 0.50*float(data[i][3])
291                         error2[i][2] += 0.50*float(data[i][3])
292                 gnuplot.replot(Gnuplot.Data(error1, using="2:3", with_=w,title="Error : Low bound"))
293                 gnuplot.replot(Gnuplot.Data(error2, using="2:3", with_=w, title="Error : Upper bound"))
294                 
295         gnuplot("set term wxt")
296         return data
297
298 def main():     
299         if (len(sys.argv) < 2):
300                 sys.stderr.write(sys.argv[0] + " - Require arguments (filename)\n")
301                 return 1
302
303         tcs = []
304         gnuplot("set style data lp")
305         gnuplot("set key outside right")
306         #gnuplot("set title \"Au on Si (50min 3.5A 3-6 e-8mbar)\"")
307         #gnuplot("set xlabel \"E (DAC Counts)\"")
308         #gnuplot("set ylabel \"S(E) (ADC/DAC Counts)\"")
309         #gnuplot("set term postscript colour")
310         #gnuplot("set output \"test.eps\"")
311         for i in range(1, len(sys.argv)):
312                 tcs.append(Derivative(GetData(sys.argv[i]), 1, 2))
313                 #tcs.append(GetTCS(GetData(sys.argv[i])))
314                 if (len(tcs[i-1]) > 0):
315                         gnuplot.replot(Gnuplot.Data(tcs[i-1], title=sys.argv[i], with_="lp"))
316
317         # Now average the data
318         
319
320         
321         avg = Average(tcs)
322         for a in avg:
323                 sys.stdout.write(str(a[0]) + "\t" + str(a[1]) + "\t" + str(a[1]) + "\n")
324         gnuplot.replot(Gnuplot.Data(avg, title="Average", with_="l lw 2"))
325         
326         sys.stdout.write("Save averaged data as (blank for no save): ")
327         filename = sys.stdin.readline().strip(" \r\n\t")
328         if (filename != ""):
329                 SaveData(filename, avg)
330                 
331         return 0
332
333
334 if __name__ == "__main__":
335         sys.exit(main())

UCC git Repository :: git.ucc.asn.au