Advertisement
Guest User

Untitled

a guest
May 5th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.29 KB | None | 0 0
  1. # Lab6 Radiometry Code (Python Variant)
  2. # Created By Jesse Jurman
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import math
  6. import cmath
  7. from collections import OrderedDict
  8.  
  9. files = {
  10. 'DSC8364': {
  11. 'dist': 22.0,
  12. 'f#': 8,
  13. 'px/cm': 145.0
  14. },
  15. 'DSC8365': {
  16. 'dist': 35.5,
  17. 'f#': 8,
  18. 'px/cm': 150.0
  19. },
  20. 'DSC8368': {
  21. 'dist': 50.0,
  22. 'f#': 5.8,
  23. 'px/cm': 129.0
  24. }
  25. }
  26.  
  27. # this program takes time, so I'm building a loading bar
  28. def bar( prog, limit, bar_size=80 ):
  29. value = int((prog / limit)*bar_size)
  30. svalue = bar_size - value
  31. print( "[" + "|"*int((prog / limit)*bar_size) + " "*svalue + "]", end="\r" )
  32.  
  33. # function to plot
  34. def simPlot( plotDict, title="Plot", xLabel="x", yLabel="y" ):
  35. # first we need to find the lowest and highest wavelength
  36. angle = list(plotDict.keys())
  37. counts = list(plotDict.values())
  38.  
  39. x = np.array(angle)
  40. y = np.array(counts)
  41.  
  42. # all the matplotlib stuff...
  43. fig = plt.figure()
  44. fig.suptitle(title)
  45. plt.xlabel(xLabel)
  46. plt.ylabel(yLabel)
  47. plt.plot(x, y)
  48. plt.grid(True)
  49.  
  50. # function to plot a given mapping of theta to digital counts
  51. def dictPlot( plotDict, refDict, title="Plot", xLabel="angle (in degrees)", yLabel="digital counts (peak normalize)" ):
  52. # first we need to find the lowest and highest wavelength
  53. angle = list(plotDict.keys())
  54. counts = list(plotDict.values())
  55. ref_counts = list(refDict.values())
  56.  
  57. x = np.array(angle)
  58. y = np.array(counts)
  59. ref_y = np.array(ref_counts)
  60.  
  61. # all the matplotlib stuff...
  62. fig = plt.figure()
  63. fig.suptitle(title)
  64. plt.xlabel(xLabel)
  65. plt.ylabel(yLabel)
  66. if (title.index('vs')):
  67. label1 = title.split('vs')[0]
  68. label2 = title.split('vs')[1]
  69. else:
  70. label1 = "measured data"
  71. label2 = "cos(theta)"
  72. plt.plot(x, y, label=label1)
  73. plt.plot(x, ref_y, label=label2, linestyle='--')
  74. plt.ylim((0.85,1.15))
  75. plt.xlim((-20,20))
  76. plt.grid(True)
  77. plt.legend(loc="best", framealpha=0.5)
  78.  
  79. # takes in a file name, and returns a mapping of pixels to digital counts
  80. def recordingToDict( fileName ):
  81. finalTable = dict()
  82. for line in open(fileName, 'r'):
  83.  
  84. # for the values, we strip leading whitespace, and split by tabs
  85. pixels = float(line.strip().split('\t')[0])
  86. counts = float(line.strip().split('\t')[1])
  87.  
  88. finalTable[ pixels ] = counts
  89.  
  90. return finalTable
  91.  
  92. # quadratic mean error between two curves
  93. # aka Root Mean Square
  94. # function taken from lab
  95. def RMS( curveOne, curveTwo ):
  96. sum = 0
  97. # for every value, subtract the value of x at curveTwo from curveOne
  98. # this assumes that curveOne has the same number of values as curveTwo
  99. for x in curveOne:
  100. sum += (curveOne[ x ] - curveTwo[ x ])**2
  101.  
  102. result = sum / len(curveOne)
  103. result = result ** (0.5)
  104.  
  105. return result
  106.  
  107. # peak normalize
  108. # returns a curve that is peak normalized
  109. # that is to say, all the values have been divided by the
  110. # largest value
  111. def peakNormalize( curve ):
  112. values = list(curve.values())
  113. values.sort()
  114. peak = values[len(values)-1]
  115.  
  116. peak_curve = {}
  117. for pixels in curve:
  118. peak_curve[ pixels ] = curve[ pixels ] / peak
  119.  
  120. return peak_curve
  121.  
  122. # anglize
  123. # returns a curve where the keys are the angles off of the peak
  124. # this depends on a curve, a pixel to cm ratio, and a distance
  125. # if it's not obvious, this is very specialized to the Lab6 analysis
  126. def anglize( curve, pixelToCm, distance ):
  127. values = list(curve.values())
  128. values.sort()
  129. # we're treating the peak value as the center where theta=0
  130. peakDC = values[len(values)-1]
  131.  
  132. # flip the curve, so we can get the corresponding theta..
  133. # taken from StackOverflow
  134. dcToDist = dict(zip(curve.values(), curve.keys()))
  135. peakDist = dcToDist[ peakDC ]
  136.  
  137. angle_curve = dict()
  138. for pixels in curve:
  139. # figure out how many centimeters we are from the center
  140. cmsOff = (pixels - peakDist)/pixelToCm
  141. # get theta
  142. thetaRAD = math.atan( cmsOff / distance )
  143. # turn it into degrees
  144. theta = math.degrees( thetaRAD )
  145.  
  146. angle_curve[ theta ] = curve[ pixels ]
  147.  
  148. # we need to order the theta values if we want the plot to look nice (and not bounce from the ends back-and-forth
  149. ordered_angle_curve = OrderedDict(sorted(angle_curve.items()))
  150.  
  151. return ordered_angle_curve
  152.  
  153. # build reference curve
  154. # takes in a list of thetas, and the n value
  155. def buildRef( thetas, n ):
  156. reference = dict()
  157. for t in thetas:
  158. peak = 1 # because it's normalized!
  159. reference[ t ] = peak * math.cos( math.radians(t) )**n
  160.  
  161. ordered_reference = OrderedDict(sorted(reference.items()))
  162.  
  163. return ordered_reference
  164.  
  165. # create tables for all our recordings
  166. for fileName in files:
  167. files[fileName]['pixel-count'] = recordingToDict( fileName+'.txt' )
  168.  
  169. # do other things with the recordings now
  170. for fileName in files:
  171. curve = files[fileName]['pixel-count']
  172. pixelCm = files[fileName]['px/cm']
  173. distance = files[fileName]['dist']
  174.  
  175. # create peak-normalized plots
  176. peakCurve = peakNormalize( curve )
  177. files[fileName]['peak-pixel-count'] = peakCurve
  178.  
  179. # create angle curves off the center
  180. angleCurve = anglize( peakCurve, pixelCm, distance )
  181. files[fileName]['peak-angle-count'] = angleCurve
  182.  
  183. # finally, find the lowest RMS error
  184. for fileName in files:
  185. print( "processing for " + fileName )
  186. curve = files[fileName]['peak-angle-count']
  187.  
  188. RMSresults = dict()
  189. for n100 in range(100, 900, 10):
  190. n = n100/100.0
  191. bar( n-1, 8 )
  192. ref = buildRef( list(curve.keys()), n )
  193. error = RMS( ref, curve )
  194. RMSresults[ error ] = n
  195.  
  196. ordered_results = OrderedDict(sorted(RMSresults.items(), key=lambda i: i[1]))
  197. simPlot(ordered_results, "Error vs Exponent", "error", "n")
  198. plt.show()
  199.  
  200. # calculate the best fit by sorting the keys (which are our errors)
  201. print("")
  202. rmsSort = list(RMSresults.keys())
  203. rmsSort.sort()
  204.  
  205. rmsBest = rmsSort[0]
  206. print( "RMS Error:\t" + str(rmsBest) )
  207. print( "n value:\t" + str(RMSresults[rmsBest]) )
  208.  
  209. bestRefCurve = buildRef( list(curve.keys()), RMSresults[rmsBest] )
  210. testRefCurve = buildRef( list(curve.keys()), 9 )
  211. dictPlot( curve, bestRefCurve, fileName + " vs cos(theta)^" + str(RMSresults[rmsBest]) )
  212. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement