from tkinter.colorchooser import askcolor from tkinter import Variable, filedialog from tkinter import messagebox import tkinter as tk import csv import numpy as np from configparser import ConfigParser import pandas as pd import config import matplotlib.pyplot as plt #matplotlib.use("TkAgg") from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk from matplotlib.figure import Figure from numpy import arange, sin, pi,cos import fnmatch import time from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter from mpl_toolkits.mplot3d import Axes3D from tkinter import ttk import CCDpanelsetup as panel ####################################### object class Messurement(object): def __init__(self,data,step): split = data.split(',') self.name = 'Messure '+str(split[0]) self.absorbanz = split[1] self.conc = float(split[0])*float(step) class Methods(object) : ### absorbanz später für E / mymol oder so def __init__(self,name,data): self.messures = list() self.name = name split = data.split('|') first = True for s in split: if first==True: first= False m = s.split(',') self.id =m[0] self.nm = m[1] self.units = m[2] self.absorbanz =m[3] self.step = m[4] self.final = m[5] else: self.messures.append(Messurement(s,float(self.final)/float(self.step))) def __str__(self): return self.name def update(self,data): self.messures.clear() split = data.split('|') first = True for s in split: if first==True: first= False m = s.split(',') self.id =m[0] self.nm = m[1] self.units = m[2] self.absorbanz =m[3] self.step = m[4] self.final = m[5] else: self.messures.append(Messurement(s,float(self.final)/float(self.step))) def get_name(self): return(self.name) class Jfsphoto (object): def __init__(self): self.nm = 0 self.nmi = 0 self.nm2 = 0 self.nm2i = 0 self.nm_left = 0 self.nm_right = 0 self.nm_step = 0 self.tnm_left = tk.StringVar() self.tnm_right = tk.StringVar() self.tnm_step = tk.StringVar() self.nmData16 = np.zeros(3694, np.uint16) ########## nm scale checkButton default nm-scale is off self.nm_checked = tk.IntVar() self.nm_checked.set(0) ########## darkline self.darkData16 = np.zeros(3694, np.float32) self.darkline_checked = tk.IntVar() self.darkline_checked.set(0) ########## baseline of the lightsource transmission or absorption self.baseData16 = np.zeros(3694, np.float32) self.baseline_checked = tk.IntVar() self.baseline_checked.set(0) self.baseline_start=0 self.baseline_end=0 self.abs_trans= tk.IntVar() ########## set to transition self.abs_trans.set(1) ########## dataframe to load and save photometer data self.pandas_count = 0 self.df = pd.DataFrame() ######### jfs math self.ok = tk.IntVar() self.ok.set(0) ######### jfs methods self.methods = [] def do_calibrate(self): win = tk.Toplevel() win.geometry("450x200+100+100") self.lab1 = tk.Label(win, text='Please enter filenames and nm of the peaks').grid(row=0,column=0,columnspan=6) ########## first peak self.tnm = tk.StringVar() self.tnm.set(str(self.nm)) self.tnmi = tk.StringVar() self.tnmi.set(str(self.nmi)) self.lab2 = tk.Label(win,text='first Peak nm').grid(row=1,column=0) self.en1 = tk.Entry(win,textvariable=self.tnm, width= 10).grid(row=1,column=1) self.bt1 = tk.Button(win,text="select File",command=lambda: self.openfile(1)).grid(row=1,column=2) self.lnm = tk.Label(win,textvariable =self.tnm).grid(row=1,column=3) self.lnm = tk.Label(win,text =" nm by index ").grid(row=1,column=4) self.lmi = tk.Label(win,textvariable=self.tnmi).grid(row=1,column=5) ########## second peak self.tnm2 = tk.StringVar() self.tnm2.set(str(self.nm2)) self.tnm2i = tk.StringVar() self.tnm2i.set(str(self.nm2i)) self.lab3 = tk.Label(win,text='second Peak nm').grid(row=2,column=0) self.en2 = tk.Entry(win,textvariable=self.tnm2, width= 10).grid(row=2,column=1) self.bt2 = tk.Button(win,text="select File",command=lambda: self.openfile(2)).grid(row=2,column=2) self.lnm2 = tk.Label(win,textvariable =self.tnm2).grid(row=2,column=3) self.lnm2 = tk.Label(win,text =" nm by index ").grid(row=2,column=4) self.lm2i = tk.Label(win,textvariable=self.tnm2i).grid(row=2,column=5) ########### calibration self.tnm_left.set(str(self.nm_left)) self.tnm_right.set(str(self.nm_right)) self.tnm_step.set(str(self.nm_step)) self.lab4 = tk.Label(win,text="left border [nm]").grid(row=3,column=0) self.lab5 = tk.Label(win,textvariable=self.tnm_left).grid(row=3,column=1) self.lab6 = tk.Label(win,text="right border [nm]").grid(row=3,column=2) self.lab7 = tk.Label(win,textvariable=self.tnm_right).grid(row=3,column=3) self.lab8 = tk.Label(win,text="[nm]/point").grid(row=3,column=4) self.lab9 = tk.Label(win,textvariable=self.tnm_step).grid(row=3,column=5) self.bt3 = tk.Button(win,text="Calibrieren",command=self.calibrate,state=tk.DISABLED) self.bt3.grid(row=4,column=0) self.bt4 = tk.Button(win,text="Load Config",command=self.conf_read).grid(row=4,column=1) self.bt5 = tk.Button(win,text="Save Config",command=self.conf_write).grid(row=4,column=2) ########### dialog modal win.focus_set() win.grab_set() win.wait_window() def do_msg(self,txt): self.mroot = tk.Tk() self.mroot.minsize(100,50) self.mroot.title(" Info ") self.label = tk.Label(self.mroot, text=txt,bg="yellow",fg="blue") self.label.pack() self.button = tk.Button(self.mroot, text='OK', width=25, command=self.mroot.destroy) self.button.pack() self.mroot.mainloop() ############ Darkline def do_save_darkline(self,dark): x = np.min(dark) if (x < 3700): self.do_msg(" This is not a Darkline ") return 0 else : self.darkData16 = dark*1.0 return 1 def get_darkline_checked(self): return self.darkline_checked.get() ############ Baseline depends on the capacity of the light source block spektralrange if the intensity is to low def do_save_baseline(self,base): ### no margin at all doIt = True #### no left margin left = True x = np.max(base) if (x < 500): self.do_msg(" This is not a Baseine \n Is the Lightsouce switch on ? ") return 0 else: for i in range(0,3694): if (base[i] < 200) : if doIt: if left: self.baseline_start = i else: self.baseline_end = i doIt = False self.baseData16[i] = 0 else: ## 300 should be in the ini file job! if (base[i] > 300): left = False self.baseData16[i] = base[i]*1.0 #print(self.baseline_start," ",self.baseline_end) return 1 def get_baseline_checked(self): return self.baseline_checked.get() ############ Calibration and Load/Save Configuration Part 2 def checkit(self): self.nm = int(self.tnm.get()) self.nmi = int(self.tnmi.get()) self.nm2 = int(self.tnm2.get()) self.nm2i = int(self.tnm2i.get()) if ((self.nm > 0) & (self.nmi > 0) & (self.nm2 > 0) & (self.nm2i > 0)): self.bt3.config(state = tk.NORMAL) def calibrate(self): self.nm_step = round((self.nm2 - self.nm)/(self.nm2i-self.nmi),5) self.nm_left = round(self.nm-(self.nm_step*self.nmi),0) self.nm_right = round(self.nm2 + self.nm_step*(3694-self.nm2i),0) self.tnm_left.set(str(self.nm_left)) self.tnm_right.set(str(self.nm_right)) self.tnm_step.set(str(self.nm_step)) def nm_scale_ok(self): if ((self.nm_left > 0) & (self.nm_right > 0)): return 1 else: return 0 def get_nm_checked(self): if (self.nm_scale_ok()): return self.nm_checked.get() else: return 0 def set_nm_scale(self): if (self.nm_scale_ok): self.nmData16 = np.linspace(self.nm_left,self.nm_right,3694) def get_nm_scale(self): self.set_nm_scale() return self.nmData16 def add_kinetic(self,name): self.df[str(name)]=config.rxData16 toc = time.perf_counter() print(f"{name} time {toc :0.4f} sec") def start_kinetic(self): self.col_list = list(self.df.columns.values.tolist()) ##### delete remaining _trans and _abs ##filtered = fnmatch.filter(self.col_list,'*_*') self.df.drop(self.col_list,axis=1,inplace=True) toc = time.perf_counter() print(f"start time {toc :0.4f} sec") def save_pandas(self): filename = filedialog.asksaveasfilename(defaultextension=".csv", title="Save file as") try: self.df['baseline']=self.baseData16 self.df['darkline']=self.darkData16 self.df['nmscale']=self.nmData16 self.df['p1']=config.rxData16 self.df.to_csv(filename) except IOError: messagebox.showerror("By the great otter!","There's a problem saving the file.") def save_kinetics(self): filename = filedialog.asksaveasfilename(defaultextension=".csv", title="Save file as") try: self.df.to_csv(filename) except IOError: messagebox.showerror("By the great otter!","There's a problem saving the file.") def load_kinetics(self): filename = filedialog.askopenfilename(defaultextension=".csv", title="Open file ") try: self.listbox.delete(0,tk.END) self.df = pd.read_csv(filename,index_col=0) self.calculate() self.show_first_look() except IOError: messagebox.showerror("By the great otter!","There's a problem loding the file.") def load_pandas(self): filename = filedialog.askopenfilename(defaultextension=".csv", title="Open file ") try: self.df = pd.read_csv(filename,index_col=0) config.rxData16=self.df['p1'].copy() self.do_save_baseline(self.df['baseline']) self.do_save_darkline(self.df['darkline']) self.baseline_checked.set(1) self.darkline_checked.set(1) self.nm_checked.set(1) except IOError: messagebox.showerror("By the great otter!","There's a problem saving the file.") def openfile(self,xx): rxData16 = np.zeros(3694, np.uint16) filename = filedialog.askopenfilename(defaultextension=".dat", title="Open file") line_count = 0 try: with open(filename) as csvfile: readCSV = csv.reader(csvfile, delimiter=' ') for row in readCSV: if (line_count == 3): self.SHsent = int(row[1]) self.ICGsent = int(row[6]) if (line_count > 3): rxData16[line_count-4] = int(row[1]) line_count += 1 if (xx==1): self.nmi = np.argmin(rxData16) self.tnmi.set(str(self.nmi)) if (xx==2): self.nm2i = np.argmin(rxData16) self.tnm2i.set(str(self.nm2i)) self.checkit() except IOError: messagebox.showerror("By the great otter!","There's a problem opening the file.") def reset_settings(self): self.baseline_checked.set(0) self.darkline_checked.set(0) self.nm_checked.set(0) def conf_write(self): config = ConfigParser() config.read('config.ini') lis = config.sections() if ('main' not in lis): config.add_section('main') config.set('main','nm_left',str(self.nm_left)) config.set('main','nm_right',str(self.nm_right)) config.set('main','nm_step',str(self.nm_step)) with open('config.ini','w') as f: config.write(f) def conf_read(self): config = ConfigParser() try: config.read('config.ini') self.nm_left = float(config.get('main','nm_left',fallback='0')) self.tnm_left.set(config.get('main','nm_left',fallback='0')) self.nm_right = float(config.get('main','nm_right',fallback='0')) self.tnm_right.set(config.get('main','nm_right',fallback='0')) self.nm_step = float(config.get('main','nm_step',fallback='0')) self.tnm_step.set(config.get('main','nm_step',fallback='0')) self.set_nm_scale() if 'methods' in config.sections(): for i in config['methods']: s = config.get('methods',i) #print(i,s) self.methods.append(Methods(i,s)) except IOError: print("By the great otter!","No config.ini file") def do_math(self,panel): #print(panel.SHvalue.get()) #panel.bcollect.invoke() stati = [("Raw",1),("Raw + Baseline",2),("Transmission",4),("Absorbanz",3)] def toggle(): if self.kbtn.config('relief')[-1] == 'sunken': self.kbtn.config(relief='raised') self.do_2dprint() else: self.kbtn.config(relief='sunken') self.do_3dprint() win = tk.Toplevel() self.center = tk.Frame(win, bg='gray2', width=800, height=400, padx=3, pady=3) self.center.grid_rowconfigure(0, weight=1) self.center.grid_columnconfigure(1, weight=1) self.center.grid(row=1, sticky="nsew") self.ctr_mid = tk.Frame(self.center, width=250, height=300, padx=3, pady=3) self.ctr_right = tk.Frame(self.center, width=200, height=300, padx=3, pady=3) self.ctr_mid.grid(row=0, column=0, sticky="nsew") self.ctr_right.grid(row=0, column=1, sticky="ns") self.fig = plt.Figure(figsize=(8,4),dpi=120) plt.rc('legend',fontsize=8) self.ax1 = self.fig.add_subplot(111) self.canvas = FigureCanvasTkAgg(self.fig, master = self.ctr_mid) self.canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, expand = 1) self.toolbarFrame = tk.Frame(master=self.center,padx=5,pady=5) self.toolbarFrame.grid(row=1,columnspan=2, sticky="w") self.toolbar1 = NavigationToolbar2Tk(self.canvas, self.toolbarFrame) #### Buttons n = 0 for txt,val in stati: tk.Radiobutton(master=self.ctr_right,text=txt,variable=self.ok,command=self.look,value=val,padx=5,pady=5).grid(row=n,column=0,sticky="w") n=n+1 self.listbox = tk.Listbox(master=self.ctr_right,selectmode = "multiple") self.listbox.grid(row=7,column=0,sticky='w') self.kbtn1 = tk.Button(master=self.ctr_right,text="show selected",command=self.show_selected,width=15) self.kbtn1.grid(row=14,column=0,sticky="w") self.kbtn = tk.Button(master=self.ctr_right,text="Load Kinetic / Data",command=self.load_kinetics,width=15) self.kbtn.grid(row=15,column=0,sticky="w") self.kbtn = tk.Button(master=self.ctr_right,text="Save Kinetic / Data",command=self.save_kinetics,width=15) self.kbtn.grid(row=16,column=0,sticky="w") self.kbtn = tk.Button(master=self.ctr_right,text="3 D Print",command=toggle,width=15,relief='raised') self.kbtn.grid(row=17,column=0,sticky="w") self.kbtm = tk.Button(master=self.ctr_right,text="Methods",command=lambda JFSphoto=Jfsphoto: self.do_methods(panel),width=15) self.kbtm.grid(row=18,column=0,sticky="w") if self.calculate() : self.show_first_look() else: t = arange(0.0, 3.0, 0.01) s = sin(2*pi*t) self.ax1.plot(t, s, linewidth=0.6) win.focus_set() win.grab_set() win.wait_window() def do_2dprint(self): self.ax1 = self.fig.add_subplot(111) self.look() def do_3dprint(self): self.ax1 = self.fig.gca(projection='3d') for xx in self.col_list: self.df.plot(x = 'nmscale',y = xx, zs= int(xx), linewidth=0.6,ax=self.ax1) self.canvas.draw() def show_selected(self): self.col_list = [self.listbox.get(i) for i in self.listbox.curselection()] self.look() def calculate(self): self.ok.set(0) if 'baseline' in self.df.columns: self.get_kin_list() self.do_get_range() for xx in self.col_list: self.do_absorbanz(xx) for xx in self.col_list: self.do_transmission(xx) return True else: return False def get_kin_list(self): self.col_list = list(self.df.columns.values.tolist()) ##### delete remaining _trans and _abs filtered = fnmatch.filter(self.col_list,'*_*') self.df.drop(filtered,axis=1,inplace=True) self.col_list = list(self.df.columns.values.tolist()) self.col_list.remove('baseline') self.col_list.remove('darkline') self.col_list.remove('nmscale') def show_first_look(self): self.ax1.clear() for xx in self.col_list: self.df.plot(x = 'nmscale',y = xx, linewidth=0.6,ax=self.ax1) self.listbox.insert(tk.END, xx) self.ok.set(1) self.canvas.draw() # def kini(self): # self.load_kinetics("kini.dat") # self.calculate() # self.show_first_look() def do_get_range(self): self.right = 0 self.left = 0 #### count for random not zero values in the start of the baseline count = 0 b = self.df['baseline'] for i in range(0,3694): if b[i]==0: if (self.left > 0 and self.right==0): self.right=i else: count += 1 if (self.left==0 and count > 5): self.left=i def do_absorbanz(self,xx): y = self.df['darkline'] - self.df[xx] b = self.df['baseline'] c = np.zeros(3694, np.float32) for i in range(0,3694): if b[i]==0: c[i] = 1 else: #c[i] = y[i]/b[i] c[i] = np.log10(b[i]/y[i]) self.df[xx+'_abs'] = c def do_transmission(self,xx): y = self.df['darkline'] - self.df[xx] b = self.df['baseline'] c = np.zeros(3694, np.float32) for i in range(0,3694): if b[i]==0: c[i] = 1 else: c[i] = y[i]/b[i] #c[i] = np.log10(b[i]/y[i]) self.df[xx+'_trans'] = c def look(self): self.ax1.clear() if self.ok.get()==1: for xx in self.col_list: self.df.plot(x = 'nmscale',y = xx, linewidth=0.6,ax=self.ax1) elif self.ok.get()==2: for xx in self.col_list: self.df.plot(x = 'nmscale',y = xx, linewidth=0.6,ax=self.ax1) self.df.plot(x = 'nmscale',y = 'baseline', color='blue',linewidth=0.6,ax=self.ax1) self.df.plot(x = 'nmscale',y = 'darkline', color='black',linewidth=0.6,ax=self.ax1) elif self.ok.get()==3: for xx in self.col_list: self.df.plot(x = 'nmscale',y = xx+'_abs', linewidth=0.6,ax=self.ax1) self.ax1.set_xlim([self.nm_left+self.left*self.nm_step, self.nm_left+self.right*self.nm_step]) elif self.ok.get()==4: for xx in self.col_list: self.df.plot(x = 'nmscale',y = xx+'_trans',linewidth=0.6,ax=self.ax1) self.ax1.set_xlim([self.nm_left+self.left*self.nm_step, self.nm_left+self.right*self.nm_step]) else: t = arange(0.0, 3.0, 0.01) s = sin(2*pi*t) self.ax1.plot(t, s, linewidth=0.6) self.canvas.draw() def do_methods(self,panel): print(panel.SHvalue.get()) win = tk.Toplevel() tree = ttk.Treeview(win) tree.grid(column=0,row=0) tree["columns"]=('id','nm','konz','absorbanz','interval','last') tree.column("#0",width=100,minwidth=100,stretch=tk.NO) #tree.column("name",width=50,minwidth=50,stretch=tk.NO) tree.column("id",width=20,minwidth=20,stretch=tk.NO) tree.column("nm",width=40,minwidth=40,stretch=tk.NO) tree.column("konz",width=60,minwidth=60,stretch=tk.NO) tree.column("absorbanz",width=60,minwidth=60,stretch=tk.NO) tree.column("interval",width=60,minwidth=60,stretch=tk.NO) tree.column("last",width=80,minwidth=80,stretch=tk.NO) tree.heading("#0",text='Methode',anchor=tk.W) tree.heading("id",text='ID',anchor=tk.W) tree.heading("nm",text='[nm]',anchor=tk.W) tree.heading("konz",text='conc',anchor=tk.W) tree.heading("absorbanz",text="Absorbanz",anchor=tk.W) tree.heading("interval",text='intervall',anchor=tk.W) tree.heading("last",text='last conc',anchor=tk.W) einheiten = ['Mol','mmol','mymol'] e1 = tk.StringVar() e2 = tk.IntVar() e3 = tk.IntVar() e4 = tk.StringVar() e4.set(einheiten[2]) e5 = tk.IntVar() e6 = tk.IntVar() e7 = tk.StringVar() e7.set('0.0') def load_tree(): for a in self.methods: tree.insert("",'end',a.name,text=a.name,values=(a.id,a.nm,a.units,a.absorbanz,a.step,a.final)) for b in a.messures: tree.insert(a.name,'end',b.name,text=b.name,values=('','',b.conc,b.absorbanz)) def save_tree(): name = e1.get() data = str(e2.get())+','+str(e3.get())+','+e4.get()+','+str(e5.get())+','+str(e6.get()) old = [p.get_name() for p in self.methods] print(old) for child in tree.get_children(): name = child s= ",".join(str(x) for x in tree.item(child)["values"]) #print(s) for items in tree.get_children(child): ss = ",".join(str(x) for x in tree.item(items)["values"] if len(str(x))>0) s = s +'|'+ss for p in self.methods: if p.get_name() == name: p.update(s) print('update') break else: self.methods.append(Methods(name,s)) print('append') break def add_method(): tree.insert("",'end',e1.get(),text=e1.get(),values=(e2.get(),e3.get(),e4.get(),e7.get(),e5.get(),e6.get())) stp = e6.get()/e5.get() for i in range(1,e5.get()+1): na = e1.get()+' '+str(i) tree.insert(e1.get(),'end',na,text= na ,values=(i,'',stp * (i))) lf1 = tk.LabelFrame(win,text='Edit the method') lf1.grid(column=0,row=1,sticky='w') l1 = tk.Label(lf1,text='Name of the Method') l1.grid(column=0,row=0,sticky='w') le1 =tk.Entry(lf1,textvariable=e1,width=20) le1.grid(column=1,row=0,sticky='w') l2 = tk.Label(lf1,text='ID of the Method') l2.grid(column=0,row=1,sticky='w') le2 =tk.Entry(lf1,textvariable=e2,width=5) le2.grid(column=1,row=1,sticky='w') l3 = tk.Label(lf1,text='Enter wavelength') l3.grid(column=0,row=2,sticky='w') le3 =tk.Entry(lf1,textvariable=e3,width=5) le3.grid(column=1,row=2,sticky='w') l4 = tk.Label(lf1,text='Unit of Concentration') l4.grid(column=0,row=3,sticky='w') le4 =tk.OptionMenu(lf1,e4,*einheiten) le4.grid(column=1,row=3,sticky='w') l5 = tk.Label(lf1,text='Numbers of samples') l5.grid(column=0,row=4,sticky='w') le5 =tk.Entry(lf1,textvariable=e5,width=5) le5.grid(column=1,row=4,sticky='w') l6 = tk.Label(lf1,text='Last Sampel Concentration') l6.grid(column=0,row=5,sticky='w') le6 =tk.Entry(lf1,textvariable=e6,width=5) le6.grid(column=1,row=5,sticky='w') lb1 = tk.Button(lf1,text='Add Method',command=add_method) lb1.grid(column=0,row=6,sticky='w') lb1 = tk.Button(lf1,text='Save Methods',command=save_tree) lb1.grid(column=1,row=6,sticky='w') load_tree() # def cb(event): # print(tree.selection()) # #panel.bcollect.invoke() # tree.tag_bind('cb','<>',cb) # tree.insert('', 'end', 'widgets', text='Widgets',tags=('cb')) # tree.insert('', 0, 'apps', text='Applications',tags=('cb')) # tree['columns'] = ('size', 'modified') # tree.column('size', width=50, anchor='center') # tree.heading('size', text='Size') # tree.heading('modified', text='Modified') # tree.set('widgets', 'size', '12KB') # tree.set('widgets', 'modified', 'Last week') # tree.insert('', 'end', text='Canvas', values=('25KB Today'),tags=('cb')) # tree.insert('apps', 'end', text='Browser', values=('115KB Yesterday'),tags=('cb')) win.focus_set() win.grab_set() win.wait_window()