otterpy/JFSphoto.py
2020-12-30 10:48:14 +01:00

961 lines
38 KiB
Python

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 matplotlib.backend_bases import key_press_handler
from tkinter import ttk
import CCDpanelsetup as panel
from sklearn.metrics import r2_score
from JFShelp import *
####################################### object
class Messurement(object):
### nr -> na
def __init__(self,name,data):
split = data.split(',')
self.id = split[0]
self.name = name +' '+str(split[0])
self.conc = float(split[1])
self.absorbanz = float(split[2])
self.SH = int(split[3])
self.ICG = int(split[4])
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(self.name,s))
def __str__(self):
return self.name
def save(self):
s = self.id+','+self.nm+','+self.units+','+self.absorbanz+','+self.step+','+self.final
for p in self.messures:
s = s+'|'+str(p.id)+','+str(p.conc)+','+str(p.absorbanz)+','+str(p.SH)+','+str(p.ICG)
return s
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(self.name,s))
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()
self.baseline_limit = 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)
self.akt_point=0
self.akt_nm = 0
self.log = True
######### jfs methods
self.methods = []
######### get icons
self.bulbOn = get_icon_image('bulb-on.jpg')
self.bulbOff = get_icon_image('bulb-off.jpg')
def do_calibrate(self):
win = tk.Toplevel()
win.geometry("450x200+200+200")
#center_window([500,300],None)
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,sticky='w')
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,sticky='w')
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,sticky='w')
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="Calibrate",command=self.calibrate,state=tk.DISABLED,padx=10)
self.bt3.grid(row=4,column=0,sticky='w')
############ limit for the baseline the baseline starts and ends at a higher intensisity depending on
# the spectrum of the light source
self.lab10 = tk.Label(win,text="threshold for the baseline").grid(row=5,column=0,columnspan=2, sticky="w")
self.en3 = tk.Entry(win,textvariable=self.baseline_limit, width= 10).grid(row=5,column=2)
############ Save Load config
self.bt4 = tk.Button(win,text="Load Config",command=self.conf_read,padx=10).grid(row=6,column=0,sticky='w')
self.bt5 = tk.Button(win,text="Save Config",command=self.conf_write,padx=10).grid(row=6,column=1,sticky='w')
############ Help
self.bt5 = tk.Button(win,text="Help me",command=lambda roots = win ,helpfor=0: jfshelpme(roots,helpfor),padx=10).grid(row=7,column=0,sticky='w')
########### 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
self.df['darkline']=self.darkData16
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] < int(self.baseline_limit.get())) :
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)
self.df['baseline']=self.baseData16
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)
self.df['nmscale']=self.nmData16
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))
config.set('main','baseline_limit',str(self.baseline_limit.get()))
if ('methods') in lis:
config.remove_section('methods')
with open('config.ini','w') as f:
f.seek(0)
config.write(f)
f.truncate()
config.read('config.ini')
lis = config.sections()
if ('methods') not in lis:
config.add_section('methods')
for p in self.methods:
config.set('methods',p.get_name(),p.save())
print(p.get_name())
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()
self.baseline_limit.set(int(config.get('main','baseline_limit',fallback='20')))
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 draw_slice(self):
self.ax2.clear()
self.ax3.clear()
if self.akt_point > 0:
x=[]
y=[]
for xx in self.col_list:
x.append(int(xx))
if self.ok.get() < 3:
yy = self.df.iloc[self.akt_point][xx]
elif self.ok.get()==3:
yy = self.df.iloc[self.akt_point][xx+'_abs']
elif self.ok.get()==4:
yy = self.df.iloc[self.akt_point][xx+'_trans']
y.append(yy)
self.ax2.plot(x, y, linewidth=0.6)
self.ax2.set_title(f'{round(self.akt_nm,2)} [nm]')
if self.log == True:
self.ax3.set_title(f'{round(self.akt_nm,2)} [nm] log')
self.ax3.set_yscale('log')
else:
y1 = np.array(y)
y = 1 / y1
self.ax3.set_title(f'{round(self.akt_nm,2)} [nm] 1/A')
self.ax3.plot(x, y, linewidth=0.6)
self.canvas.draw()
def do_math(self,panel):
def onclick(event):
#print('%s click: button=%d, xdata=%f, ydata=%f' %('double' if event.dblclick else 'single', event.button,
# event.xdata, event.ydata))
if event.button == 3:
self.akt_nm=0
self.akt_point=0
else:
self.akt_nm = event.xdata
self.akt_point = int((self.akt_nm - self.nm_left)*(1/self.nm_step))
self.draw_slice()
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, self.canvas, self.toolbar1)
stati = [("Raw",1),("Raw + Baseline",2),("Transmission",4),("Absorbanz",3)]
self.proji3d = False
def toggle():
if self.kbtn.config('relief')[-1] == 'sunken':
self.kbtn.config(relief='raised')
#self.do_2dprint()
self.proji3d=False
else:
self.kbtn.config(relief='sunken')
#self.do_3dprint()
self.proji3d=True
self.look()
def togglelog():
if self.kbtm.config('relief')[-1] == 'sunken':
self.kbtm.config(relief='raised')
#self.do_2dprint()
self.log=True
else:
self.kbtm.config(relief='sunken')
#self.do_3dprint()
self.log=False
self.look()
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.rcParams.update({'font.size': 5})
plt.rc('legend',fontsize=5)
self.ax1 = self.fig.add_subplot(2,3,(1,5))
self.ax2 = self.fig.add_subplot(2,3,3)
self.ax3 = self.fig.add_subplot(2,3,6)
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)
self.canvas.mpl_connect("key_press_event", on_key_press)
self.canvas.mpl_connect('button_press_event', onclick)
#### 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="ln[A] 1/[A]",command=togglelog,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 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 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
# self.ax1 = self.fig.gca(projection='3d')
# for xx in self.col_list:
# self.df.plot(y = 'nmscale',x = xx, zs= int(xx), linewidth=0.6,ax=self.ax1)
def look(self):
self.draw_slice()
self.ax1.clear()
if self.proji3d==True:
self.ax1 = self.fig.add_subplot(2,3,(1,5),projection='3d')
#self.ax1 = self.fig.gca(projection='3d')
else:
self.ax1 = self.fig.add_subplot(2,3,(1,5))
if self.ok.get()==1:
for xx in self.col_list:
if self.proji3d==True:
self.ax1.set_ylabel('points')
self.df.plot(x= 'nmscale',y = xx, zs= int(xx), linewidth=0.6,ax=self.ax1)
else:
self.df.plot(x = 'nmscale',y = xx, linewidth=0.6,ax=self.ax1)
elif self.ok.get()==2:
for xx in self.col_list:
if self.proji3d==True:
self.df.plot(x= 'nmscale',y = xx, zs= int(xx), linewidth=0.6,ax=self.ax1)
else:
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:
if self.proji3d==True:
self.df.plot(x= 'nmscale',y = xx+'_abs', zs= int(xx), linewidth=0.6,ax=self.ax1)
else:
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:
if self.proji3d==True:
self.df.plot(x= 'nmscale',y = xx+'_trans', zs= int(xx), linewidth=0.6,ax=self.ax1)
else:
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 check_requirement(self):
ok = True
if self.nm_checked.get() == 0:
ok = False
tk.messagebox.showerror('[nm]','You need to check calibration [nm]\n or first calibrate the instrument')
else:
s=''
s1=''
if (self.darkline_checked.get()==0):
s = ' Please take a darkline messurement first \n'
if (self.baseline_checked.get()==0):
s1 = ' Please take a baseline messurement first \n'
if (len(s1)>0 or len(s)>0):
ok = False
tk.messagebox.showerror('ToDos',s+s1)
return ok
def do_methods(self,panel):
def get_duration():
if panel.tint.get().split()[4]=='ms':
f = float(panel.tint.get().split()[3])
elif panel.tint.get().split()[4] == 's':
f = float(panel.tint.get().split()[3])*1000
elif panel.tint.get().split()[4] == 'min':
f = float(panel.tint.get().split()[3]) * 60000
x = int(panel.AVGscale.get())*f
if x < 1000:
x = 1000
return x
font = {'family': 'serif',
'color': 'darkred',
'weight': 'normal',
'size': 8,
}
def get_messurement(name):
# get selected and save values
#name = tree. val=selection()[0]
# get parent for nm
x = name.split(' ')
nm = tree.item(x[0])["values"][1]
## nm -> point
p = int((nm - self.nm_left)*(1/self.nm_step))
self.df['m1'] = config.rxData16
d = self.df.iloc[p]['darkline']
b = self.df.iloc[p]['baseline']
w = self.df.iloc[p]["m1"]
return np.log10(b/(d-w))
def waitfor(x,name,val):
# self.df['m1'] = config.rxData16
# d = self.df.iloc[p]['darkline']
# b = self.df.iloc[p]['baseline']
# w = self.df.iloc[p]["m1"]
# val[3]= np.log10(b/(d-w))
val[3] = get_messurement(name)
val[4]= panel.SHvalue.get()
val[5]= panel.ICGvalue.get()
tree.item(x, text=name,values=val)
def cb(event):
if self.check_requirement() == True:
panel.bcollect.invoke()
# get selected and save values
name = tree.selection()[0]
val= tree.item(name)["values"]
# get parent for nm
x = name.split(' ')
#nm = tree.item(x[0])["values"][1]
## nm -> point
#p = int((nm - self.nm_left)*(1/self.nm_step))
#print(f'nm {nm} point {p}')
s1 = str(val[2])+' '+tree.item(x[0])["values"][2]
s = 'Is a Cuvet for '+x[0]+' in concentration\n of '+s1+' in the photometer ? '
if tk.messagebox.askokcancel(title='Messurement', message=s):
panel.bcollect.invoke()
#panel.after(get_duration(),waitfor(x,name,val,p))
panel.after(get_duration(),waitfor(x,name,val))
def cb2(event):
y = []
x = []
name = tree.selection()
l6.config(text=name[0])
for child in tree.get_children(name):
x.append(float(tree.item(child)["values"][2]))
y.append(float(tree.item(child)["values"][3]))
ax1.clear()
model = np.polyfit(x,y,1)
predict = np.poly1d(model)
x_range = np.linspace(x[0],x[-1])
y_range = predict(x_range)
ax1.plot(x_range,y_range,linewidth=0.6)
ax1.plot(x, y, '+')
ax1.set_title(f'{name[0]}',fontdict=font)
ax1.text(x[0], 1, f'A vs {tree.item(name)["values"][2]}',fontdict=font)
ax1.text(x[0], 0.9, f'y = {round(model[0],3)}x + {round(model[1],3)}',fontdict=font)
ax1.text(x[0], 0.8, f'R ={round(r2_score(y,predict(x)),3)}',fontdict=font)
#ax1.text(x[0], 0.9, r'Omega: {s} $\Omega$', {'color': 'b', 'fontsize': 8})
canvas.draw()
win = tk.Toplevel()
lf = tk.LabelFrame(win,text='Methods')
lf.grid(column=0,row=0,sticky='w')
tree = ttk.Treeview(lf)
tree.tag_bind('cb','<<TreeviewSelect>>',cb)
tree.tag_bind('cb2','<<TreeviewSelect>>',cb2)
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("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='interval/SH',anchor=tk.W)
tree.heading("last",text='last conc/ICG',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),tags=('cb2'))
for b in a.messures:
tree.insert(a.name,'end',b.name,text=b.name,values=(b.id,'',b.conc,b.absorbanz,b.SH,b.ICG),tags=('cb'))
def save_tree():
for child in tree.get_children():
name = child
s= ",".join(str(x) for x in tree.item(child)["values"])
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)
self.conf_write()
def add_method():
tree.insert("",'end',e1.get(),text=e1.get(),values=(e2.get(),e3.get(),e4.get(),e7.get(),e5.get(),e6.get()),tags=('cb2'))
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),0.0,0,0),tags=('cb'))
s= ",".join(str(x) for x in tree.item(e1.get())["values"])
for items in tree.get_children(e1.get()):
ss = ",".join(str(x) for x in tree.item(items)["values"] if len(str(x))>0)
s = s +'|'+ss
self.methods.append(Methods(e1.get(),s))
def del_method():
curItem = tree.focus()
name =tree.item(curItem,"text")
if tk.messagebox.askyesno(title='Delete', message='You you really want to delete '+name ):
tree.delete(curItem)
for p in self.methods:
if p.name == name:
self.methods.remove(p)
def waitfor_darkline():
panel.bcollect.invoke()
if (self.do_save_darkline(config.rxData16)==1):
panel.jfsdark_check.config(state=tk.NORMAL)
def waitfor_baseline():
panel.bcollect.invoke()
base = self.darkData16-config.rxData16
if (self.do_save_baseline(base)==1):
panel.jfsbase_check.config(state=tk.NORMAL)
def do_zero_messurement():
#print(l6['text'])
if l6['text'].find('Select') >= 0:
tk.messagebox.showerror(title='Sorry',message='Select Method first')
else:
for child in tree.get_children(l6['text']):
sh =int(tree.item(child)["values"][4])
icg =int(tree.item(child)["values"][5])
break
panel.SHvalue.set(sh)
panel.ICGvalue.set(icg)
if tk.messagebox.askokcancel(title='Darkline', message='Insert the empty Cuvet\nturn lightsource [off]'):
panel.bcollect.invoke()
panel.after(1000,waitfor_darkline)
## messure Darkline
if tk.messagebox.askokcancel(title='Baseline', message= 'Leave the empty Cuvet\nturn lightsource [on]'):
panel.bcollect.invoke()
panel.after(1000,waitfor_baseline)
def do_messurement():
panel.bcollect.invoke()
if tk.messagebox.askokcancel(title='Messurements', message= 'Sample Cuvet inside \n lightsource [on]'):
panel.bcollect.invoke()
x=[]
y=[]
for child in tree.get_children(l6['text']):
x.append(float(tree.item(child)["values"][2]))
y.append(float(tree.item(child)["values"][3]))
model = np.polyfit(x,y,1)
a = get_messurement(l6['text'])
#print(a)
#a = model[0]* c +model[1]
c = (a - model[1])/model[0]
l8.config(text=str(round(c,3))+' '+tree.item(l6['text'])['values'][2])
#### Tree
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')
lb2 = tk.Button(lf1,text='Delete Method',command=del_method)
lb2.grid(column=1,row=6,sticky='w')
lb3 = tk.Button(lf1,text='Save Methods',command=save_tree)
lb3.grid(column=0,row=7,sticky='w')
#### canvas
fig = plt.Figure(figsize=(4,2),dpi=100)
plt.rcParams.update({'font.size': 5})
ax1 = fig.add_subplot(111)
canvas = FigureCanvasTkAgg(fig, master = win )
canvas.get_tk_widget().grid(column=1,row=0,sticky='nesw')
#### test output
t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)
ax1.plot(t, s, linewidth=0.6)
canvas.draw()
#### do messurements
lf3 = tk.LabelFrame(win,text='Do messurements')
lf3.grid(column=1,row=1,sticky='nw')
l6 = tk.Label(lf3,text='Select Messurement')
l6.grid(column=0,row=0,sticky='w')
lmb1=tk.Button(lf3,text='Zero Messurements',command=do_zero_messurement)
lmb1.grid(column=0,row=1,sticky='w')
lmb2=tk.Button(lf3,text='Messurement',command=do_messurement)
lmb2.grid(column=0,row=2,sticky='w')
l7 = tk.Label(lf3,text='Result :',width=12)
l7.grid(column=1,row=1,sticky='e')
l8 = tk.Label(lf3,text='empty',width=12)
l8.grid(column=1,row=2,sticky='e')
#### go on
load_tree()
win.focus_set()
win.grab_set()
win.wait_window()