Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import matplotlib
- matplotlib.use("TkAgg")
- from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
- from matplotlib.figure import Figure
- from lmfit.models import ExponentialGaussianModel
- from lmfit import Parameters
- from tkinter import messagebox
- import matplotlib.pyplot as plt
- from numpy import loadtxt
- import math
- import tkinter as tk
- from tkinter import ttk
- class PeakFitting(tk.Tk):
- def __init__(self, *args, **kwargs):
- tk.Tk.__init__(self, *args, **kwargs)
- container = tk.Frame(self)
- container.pack(side="top", fill="both", expand = True)
- container.grid_rowconfigure(0, weight=1)
- container.grid_columnconfigure(0, weight=1)
- self.frames = {}
- for F in (StartPage, GraphPage):
- frame = F(container, self)
- self.frames[F] = frame
- frame.grid(row=0, column=0, sticky="nsew")
- self.show_frame(StartPage)
- def show_frame(self, cont):
- frame = self.frames[cont]
- frame.tkraise()
- def get_page(self, classname):
- '''Returns an instance of a page given it's class name as a string'''
- for page in self.frames.values():
- if str(page.__class__.__name__) == classname:
- return page
- return None
- class StartPage(tk.Frame):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- # Setting up frame and widgets
- vcmd1 = (self.register(self.__vcmd1), '%P', '%S')
- vcmd2 = (self.register(self.__vcmd2), '%P')
- vcmd3 = (self.register(self.__vcmd3), '%P', '%S')
- self.v = tk.IntVar()
- self.v.set(1)
- label_det = tk.Label(self, text="Choose Detector")
- self.mcp0 = ttk.Radiobutton(self, text="MCP-0", variable=self.v, value=1, command=self.selected)
- self.mcp6 = ttk.Radiobutton(self, text="MCP-6", variable=self.v, value=2, command=self.selected)
- self.mpet = ttk.Radiobutton(self, text="MCP-MPET", variable=self.v, value=3, command=self.selected)
- label_det.grid(row=0, column=0, columnspan=2)
- self.mcp0.grid(row=1, columnspan=2)
- self.mcp6.grid(row=2, columnspan=2)
- self.mpet.grid(row=3, columnspan=2)
- label_iso = tk.Label(self, text="Isotope A, Element (ex: 133,Cs)")
- label_vol = tk.Label(self, text="Beam Energy (eV)")
- label_range = tk.Label(self, text="Peak Data Range (ex: 1,10.5)")
- label_iso.grid(row=4, column=0)
- label_vol.grid(row=5, column=0)
- label_range.grid(row=6, column=0)
- self.entry1 = tk.Entry(self, validate="key", validatecommand=vcmd1)
- self.entry2 = tk.Entry(self, validate="key", validatecommand=vcmd2)
- self.entry3 = tk.Entry(self, validate="key", validatecommand=vcmd3)
- self.entry1.grid(row=4, column=1)
- self.entry2.grid(row=5, column=1)
- self.entry3.grid(row=6, column=1)
- button3 = ttk.Button(self, text="Graph Page",
- command=lambda: controller.show_frame(GraphPage))
- button3.grid(row=7, columnspan=2)
- def __vcmd1(self, P, S):
- validString = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,1234567890'
- if not S in validString:
- messagebox.showinfo("Error", "Invalid character input")
- return False
- if "," in P:
- if len(P.split(",")) > 2:
- messagebox.showinfo("Error", "Input cannot contain multiple commas")
- return False
- else:
- return True
- else:
- return True
- def __vcmd2(self, P):
- if P == '':
- return True
- try:
- float(P)
- return True
- except ValueError:
- messagebox.showinfo("Error", "Entry must be an integer or decimal number with '.'")
- return False
- def __vcmd3(self, P, S):
- validString = "1234567890.,"
- if S not in validString:
- messagebox.showinfo("Error", "Invalid character input")
- return False
- if "," in P:
- if len(P.split(",")) > 2:
- messagebox.showinfo("Error", "Contain multiple commas")
- return False
- a = P.split(",")[0]
- b = P.split(",")[1]
- if a != '' and b != '':
- try:
- float(a)
- float(b)
- return True
- except ValueError:
- messagebox.showinfo("Error", "Expected form: ex. 10,50.5")
- return False
- else:
- return True
- else:
- return True
- def selected(self):
- if self.v.get() == 1:
- self.x = 8.0
- elif self.v.get() == 2:
- self.x = 3.0
- else:
- self.x = 9.2
- return self.x
- class GraphPage(StartPage):
- def __init__(self, parent, controller):
- tk.Frame.__init__(self, parent)
- self.controller = controller
- startpage = self.controller.get_page("StartPage")
- self.iso = startpage.entry1.get()
- self.vol = startpage.entry2.get()
- self.r = startpage.entry3.get()
- self.distance = startpage.selected()
- dict = {'h': 1, 'he': 2, 'li': 3, 'be': 4, 'b': 5, 'c': 6, 'n': 7, 'o': 8, 'f': 9, 'ne': 10,
- 'na': 11, 'mg': 12, 'al': 13, 'si': 14, 'p': 15, 's': 16, 'cl': 17, 'ar': 18,
- 'k': 19, 'ca': 20, 'sc': 21, 'ti': 22, 'v': 23, 'cr': 24, 'mn': 25, 'fe': 26, 'co': 27, 'ni': 28,
- 'cu': 29, 'zn': 30,
- 'ga': 31, 'ge': 31, 'as': 33, 'se': 34, 'br': 35, 'kr': 36, 'rb': 37, 'sr': 38, 'y': 39,
- 'zr': 40, 'nb': 41, 'mo': 42, 'tc': 43, 'ru': 44, 'rh': 45, 'pd': 46, 'ag': 47, 'cd': 48,
- 'in': 49, 'sn': 50, 'sb': 51, 'te': 52, 'i': 53, 'xe': 54, 'cs': 55, 'ba': 56,
- 'la': 57, 'ce': 58, 'pr': 59, 'nd': 60, 'pm': 61, 'sm': 62, 'eu': 63, 'gd': 64, 'tb': 65, 'dy': 66,
- 'ho': 67, 'er': 68, 'tm': 69, 'yb': 70, 'lu': 71,
- 'hf': 72, 'ta': 73, 'w': 74, 're': 75, 'os': 76, 'ir': 77, 'pt': 78, 'au': 79, 'hg': 80, 'tl': 81,
- 'pb': 82, 'bi': 83, 'po': 84, 'at': 85, 'rn': 86,
- 'fr': 87, 'ra': 88, 'ac': 89, 'th': 90, 'pa': 91, 'u': 92, 'np': 93, 'pu': 94, 'am': 95, 'cm': 96,
- 'bk': 97, 'cf': 98, 'es': 99, 'fm': 100, 'md': 101, 'no': 102, 'lr': 103,
- 'rf': 104, 'db': 105, 'sg': 106, 'bh': 107, 'hs': 108, 'mt': 109, 'ds': 110, 'rg': 111, 'cn': 112,
- 'uut': 113, 'fl': 114, 'uup': 115, 'lv': 116, 'uus': 117, 'uuo': 118}
- button1 = ttk.Button(self, text="Back to Home",
- command=lambda: controller.show_frame(StartPage))
- button1.grid()
- if self.r == "" or self.iso == "" or self.vol == "":
- return None
- r = self.r
- tup = tuple(int(x) for x in r.split(","))
- iso = self.iso.get()
- iso_list = []
- for e in iso.split(","):
- iso_list.append(e)
- if len(tup) == 2:
- if tup[0] > tup[1]:
- messagebox.showinfo("Error", "Input data range must be from lower to higher time")
- return None
- f = open("mass.mas12.txt", "r")
- i = 0
- while (i < 40):
- header = f.readline()
- i += 1
- self.mass = 0
- # iterate through text file
- for line in f:
- line = line.strip()
- columns = line.split()
- if (list[0] == columns[3]):
- if (list[1].lower() == columns[4].lower()):
- if (len(columns) == 15):
- self.mass = float(columns[12].replace("#", "")) + float(columns[13].replace("#", "")) / 10e6
- else:
- self.mass = float(columns[11].replace("#", "")) + float(columns[12].replace("#", "")) / 10e6
- # Calculation
- list = []
- valid = {}
- for q in range(1, 119):
- if q < dict[iso_list[1].lower()]:
- time = (self.distance * math.sqrt(self.mass * 1.6605402e-27 / (2 * q * 1.6022e-19 * float(self.vol)))) * 10e6
- if (time >= float(tup[0])) & (time <= float(tup[1])):
- list.append(time)
- valid[time] = q
- # check if charge states of valid time is available for isotope
- if len(valid) == 0:
- messagebox.showinfo("Error", "Change states in range do not exist for given element")
- return None
- # Fit:
- # Query data -> get x, y values... somehow
- data = loadtxt('20160418_1532_scan_1594_step_1_cup_in.csv')
- x = data[:, 0]
- y = data[:, 3]
- mod = None
- p = Parameters()
- i = 0
- for time in list:
- if mod == None:
- mod = ExponentialGaussianModel(prefix='gaussian' + str(i) + '_')
- p.add_many(('gaussian' + str(i) + '_center', time, True, time - 2, time + 2),
- ('gaussian' + str(i) + '_sigma', 0.15, True, 0),
- ('gaussian' + str(i) + '_gamma', 0.95, True, 0, 1),
- ('gaussian' + str(i) + '_amplitude', 50, True, 10))
- else:
- mod = mod + ExponentialGaussianModel(prefix='gaussian' + str(i) + '_')
- p.add_many(('gaussian' + str(i) + '_center', time, True, time - 2, time + 2),
- ('gaussian' + str(i) + '_sigma', 0.15, True, 0),
- ('gaussian' + str(i) + '_gamma', 0.95, True, 0, 1),
- ('gaussian' + str(i) + '_amplitude', 50, True, 10))
- i = i + 1
- out = mod.fit(y, p, x=x)
- fig = Figure(figsize=(5, 5), dpi=100)
- a = fig.add_subplot()
- a.plot(x, y)
- a.plot(x, out.best_fit, 'r-')
- canvas = FigureCanvasTkAgg(fig, self)
- canvas.show()
- canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
- toolbar = NavigationToolbar2TkAgg(canvas, self)
- toolbar.update()
- canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
- app = PeakFitting()
- app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement