Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2016
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.02 KB | None | 0 0
  1. import matplotlib
  2. matplotlib.use("TkAgg")
  3. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
  4. from matplotlib.figure import Figure
  5. from lmfit.models import ExponentialGaussianModel
  6. from lmfit import Parameters
  7. from tkinter import messagebox
  8. import matplotlib.pyplot as plt
  9. from numpy import loadtxt
  10. import math
  11.  
  12. import tkinter as tk
  13. from tkinter import ttk
  14.  
  15. class PeakFitting(tk.Tk):
  16.  
  17. def __init__(self, *args, **kwargs):
  18.  
  19. tk.Tk.__init__(self, *args, **kwargs)
  20.  
  21. container = tk.Frame(self)
  22. container.pack(side="top", fill="both", expand = True)
  23. container.grid_rowconfigure(0, weight=1)
  24. container.grid_columnconfigure(0, weight=1)
  25.  
  26. self.frames = {}
  27.  
  28. for F in (StartPage, GraphPage):
  29.  
  30. frame = F(container, self)
  31.  
  32. self.frames[F] = frame
  33.  
  34. frame.grid(row=0, column=0, sticky="nsew")
  35.  
  36. self.show_frame(StartPage)
  37.  
  38. def show_frame(self, cont):
  39.  
  40. frame = self.frames[cont]
  41.  
  42. frame.tkraise()
  43.  
  44. def get_page(self, classname):
  45. '''Returns an instance of a page given it's class name as a string'''
  46. for page in self.frames.values():
  47. if str(page.__class__.__name__) == classname:
  48. return page
  49. return None
  50.  
  51. class StartPage(tk.Frame):
  52. def __init__(self, parent, controller):
  53. tk.Frame.__init__(self, parent)
  54.  
  55. self.controller = controller
  56.  
  57. # Setting up frame and widgets
  58. vcmd1 = (self.register(self.__vcmd1), '%P', '%S')
  59. vcmd2 = (self.register(self.__vcmd2), '%P')
  60. vcmd3 = (self.register(self.__vcmd3), '%P', '%S')
  61.  
  62. self.v = tk.IntVar()
  63. self.v.set(1)
  64.  
  65. label_det = tk.Label(self, text="Choose Detector")
  66. self.mcp0 = ttk.Radiobutton(self, text="MCP-0", variable=self.v, value=1, command=self.selected)
  67. self.mcp6 = ttk.Radiobutton(self, text="MCP-6", variable=self.v, value=2, command=self.selected)
  68. self.mpet = ttk.Radiobutton(self, text="MCP-MPET", variable=self.v, value=3, command=self.selected)
  69.  
  70. label_det.grid(row=0, column=0, columnspan=2)
  71. self.mcp0.grid(row=1, columnspan=2)
  72. self.mcp6.grid(row=2, columnspan=2)
  73. self.mpet.grid(row=3, columnspan=2)
  74.  
  75. label_iso = tk.Label(self, text="Isotope A, Element (ex: 133,Cs)")
  76. label_vol = tk.Label(self, text="Beam Energy (eV)")
  77. label_range = tk.Label(self, text="Peak Data Range (ex: 1,10.5)")
  78.  
  79. label_iso.grid(row=4, column=0)
  80. label_vol.grid(row=5, column=0)
  81. label_range.grid(row=6, column=0)
  82.  
  83. self.entry1 = tk.Entry(self, validate="key", validatecommand=vcmd1)
  84. self.entry2 = tk.Entry(self, validate="key", validatecommand=vcmd2)
  85. self.entry3 = tk.Entry(self, validate="key", validatecommand=vcmd3)
  86.  
  87. self.entry1.grid(row=4, column=1)
  88. self.entry2.grid(row=5, column=1)
  89. self.entry3.grid(row=6, column=1)
  90.  
  91. button3 = ttk.Button(self, text="Graph Page",
  92. command=lambda: controller.show_frame(GraphPage))
  93. button3.grid(row=7, columnspan=2)
  94.  
  95. def __vcmd1(self, P, S):
  96. validString = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,1234567890'
  97. if not S in validString:
  98. messagebox.showinfo("Error", "Invalid character input")
  99. return False
  100. if "," in P:
  101. if len(P.split(",")) > 2:
  102. messagebox.showinfo("Error", "Input cannot contain multiple commas")
  103. return False
  104. else:
  105. return True
  106. else:
  107. return True
  108.  
  109. def __vcmd2(self, P):
  110. if P == '':
  111. return True
  112. try:
  113. float(P)
  114. return True
  115. except ValueError:
  116. messagebox.showinfo("Error", "Entry must be an integer or decimal number with '.'")
  117. return False
  118.  
  119. def __vcmd3(self, P, S):
  120. validString = "1234567890.,"
  121. if S not in validString:
  122. messagebox.showinfo("Error", "Invalid character input")
  123. return False
  124. if "," in P:
  125. if len(P.split(",")) > 2:
  126. messagebox.showinfo("Error", "Contain multiple commas")
  127. return False
  128. a = P.split(",")[0]
  129. b = P.split(",")[1]
  130. if a != '' and b != '':
  131. try:
  132. float(a)
  133. float(b)
  134. return True
  135. except ValueError:
  136. messagebox.showinfo("Error", "Expected form: ex. 10,50.5")
  137. return False
  138. else:
  139. return True
  140. else:
  141. return True
  142.  
  143. def selected(self):
  144. if self.v.get() == 1:
  145. self.x = 8.0
  146. elif self.v.get() == 2:
  147. self.x = 3.0
  148. else:
  149. self.x = 9.2
  150. return self.x
  151.  
  152. class GraphPage(StartPage):
  153. def __init__(self, parent, controller):
  154.  
  155. tk.Frame.__init__(self, parent)
  156. self.controller = controller
  157.  
  158. startpage = self.controller.get_page("StartPage")
  159.  
  160. self.iso = startpage.entry1.get()
  161. self.vol = startpage.entry2.get()
  162. self.r = startpage.entry3.get()
  163. self.distance = startpage.selected()
  164.  
  165. dict = {'h': 1, 'he': 2, 'li': 3, 'be': 4, 'b': 5, 'c': 6, 'n': 7, 'o': 8, 'f': 9, 'ne': 10,
  166. 'na': 11, 'mg': 12, 'al': 13, 'si': 14, 'p': 15, 's': 16, 'cl': 17, 'ar': 18,
  167. 'k': 19, 'ca': 20, 'sc': 21, 'ti': 22, 'v': 23, 'cr': 24, 'mn': 25, 'fe': 26, 'co': 27, 'ni': 28,
  168. 'cu': 29, 'zn': 30,
  169. 'ga': 31, 'ge': 31, 'as': 33, 'se': 34, 'br': 35, 'kr': 36, 'rb': 37, 'sr': 38, 'y': 39,
  170. 'zr': 40, 'nb': 41, 'mo': 42, 'tc': 43, 'ru': 44, 'rh': 45, 'pd': 46, 'ag': 47, 'cd': 48,
  171. 'in': 49, 'sn': 50, 'sb': 51, 'te': 52, 'i': 53, 'xe': 54, 'cs': 55, 'ba': 56,
  172. 'la': 57, 'ce': 58, 'pr': 59, 'nd': 60, 'pm': 61, 'sm': 62, 'eu': 63, 'gd': 64, 'tb': 65, 'dy': 66,
  173. 'ho': 67, 'er': 68, 'tm': 69, 'yb': 70, 'lu': 71,
  174. 'hf': 72, 'ta': 73, 'w': 74, 're': 75, 'os': 76, 'ir': 77, 'pt': 78, 'au': 79, 'hg': 80, 'tl': 81,
  175. 'pb': 82, 'bi': 83, 'po': 84, 'at': 85, 'rn': 86,
  176. 'fr': 87, 'ra': 88, 'ac': 89, 'th': 90, 'pa': 91, 'u': 92, 'np': 93, 'pu': 94, 'am': 95, 'cm': 96,
  177. 'bk': 97, 'cf': 98, 'es': 99, 'fm': 100, 'md': 101, 'no': 102, 'lr': 103,
  178. 'rf': 104, 'db': 105, 'sg': 106, 'bh': 107, 'hs': 108, 'mt': 109, 'ds': 110, 'rg': 111, 'cn': 112,
  179. 'uut': 113, 'fl': 114, 'uup': 115, 'lv': 116, 'uus': 117, 'uuo': 118}
  180.  
  181. button1 = ttk.Button(self, text="Back to Home",
  182. command=lambda: controller.show_frame(StartPage))
  183.  
  184. button1.grid()
  185.  
  186. if self.r == "" or self.iso == "" or self.vol == "":
  187. return None
  188.  
  189. r = self.r
  190. tup = tuple(int(x) for x in r.split(","))
  191.  
  192. iso = self.iso.get()
  193. iso_list = []
  194. for e in iso.split(","):
  195. iso_list.append(e)
  196.  
  197. if len(tup) == 2:
  198. if tup[0] > tup[1]:
  199. messagebox.showinfo("Error", "Input data range must be from lower to higher time")
  200. return None
  201.  
  202. f = open("mass.mas12.txt", "r")
  203. i = 0
  204. while (i < 40):
  205. header = f.readline()
  206. i += 1
  207. self.mass = 0
  208.  
  209. # iterate through text file
  210.  
  211. for line in f:
  212. line = line.strip()
  213. columns = line.split()
  214. if (list[0] == columns[3]):
  215. if (list[1].lower() == columns[4].lower()):
  216. if (len(columns) == 15):
  217. self.mass = float(columns[12].replace("#", "")) + float(columns[13].replace("#", "")) / 10e6
  218. else:
  219. self.mass = float(columns[11].replace("#", "")) + float(columns[12].replace("#", "")) / 10e6
  220.  
  221. # Calculation
  222.  
  223. list = []
  224. valid = {}
  225. for q in range(1, 119):
  226. if q < dict[iso_list[1].lower()]:
  227. time = (self.distance * math.sqrt(self.mass * 1.6605402e-27 / (2 * q * 1.6022e-19 * float(self.vol)))) * 10e6
  228. if (time >= float(tup[0])) & (time <= float(tup[1])):
  229. list.append(time)
  230. valid[time] = q
  231.  
  232. # check if charge states of valid time is available for isotope
  233.  
  234. if len(valid) == 0:
  235. messagebox.showinfo("Error", "Change states in range do not exist for given element")
  236. return None
  237.  
  238. # Fit:
  239. # Query data -> get x, y values... somehow
  240. data = loadtxt('20160418_1532_scan_1594_step_1_cup_in.csv')
  241. x = data[:, 0]
  242. y = data[:, 3]
  243.  
  244. mod = None
  245. p = Parameters()
  246. i = 0
  247.  
  248. for time in list:
  249. if mod == None:
  250. mod = ExponentialGaussianModel(prefix='gaussian' + str(i) + '_')
  251. p.add_many(('gaussian' + str(i) + '_center', time, True, time - 2, time + 2),
  252. ('gaussian' + str(i) + '_sigma', 0.15, True, 0),
  253. ('gaussian' + str(i) + '_gamma', 0.95, True, 0, 1),
  254. ('gaussian' + str(i) + '_amplitude', 50, True, 10))
  255. else:
  256. mod = mod + ExponentialGaussianModel(prefix='gaussian' + str(i) + '_')
  257. p.add_many(('gaussian' + str(i) + '_center', time, True, time - 2, time + 2),
  258. ('gaussian' + str(i) + '_sigma', 0.15, True, 0),
  259. ('gaussian' + str(i) + '_gamma', 0.95, True, 0, 1),
  260. ('gaussian' + str(i) + '_amplitude', 50, True, 10))
  261. i = i + 1
  262.  
  263. out = mod.fit(y, p, x=x)
  264. fig = Figure(figsize=(5, 5), dpi=100)
  265. a = fig.add_subplot()
  266. a.plot(x, y)
  267. a.plot(x, out.best_fit, 'r-')
  268.  
  269. canvas = FigureCanvasTkAgg(fig, self)
  270. canvas.show()
  271. canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
  272.  
  273. toolbar = NavigationToolbar2TkAgg(canvas, self)
  274. toolbar.update()
  275. canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
  276.  
  277.  
  278.  
  279.  
  280. app = PeakFitting()
  281. app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement