otterpy/JFSphoto.py
2020-12-07 14:25:49 +01:00

362 lines
14 KiB
Python

from tkinter.colorchooser import askcolor
from tkinter import 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
####################################### object
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)
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 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 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()
except IOError:
print("By the great otter!","No config.ini file")
def do_math(self):
stati = [("Raw",1),("Raw + Baseline",2),("Transmission",4),("Absorption",3)]
win = tk.Toplevel()
self.center = tk.Frame(win, bg='gray2', width=50, height=40, 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=250, padx=3, pady=3)
self.ctr_right = tk.Frame(self.center, width=200, height=250, 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=100)
self.ax1 = self.fig.add_subplot(111)
t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)
self.ax1.plot(t, s, linewidth=0.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")
toolbar1 = NavigationToolbar2Tk(self.canvas, self.toolbarFrame)
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
win.focus_set()
win.grab_set()
win.wait_window()
def look(self):
self.ax1.clear()
if self.ok.get()==1:
self.df.plot(x = 'nmscale',y = 'p1', color='red',linewidth=0.6,ax=self.ax1)
elif self.ok.get()==2:
self.df.plot(x = 'nmscale',y = 'p1', color='red',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:
right = 0
left = 0
y = self.df['darkline'] - self.df['p1']
b = self.df['baseline']
c = np.zeros(3694, np.float32)
for i in range(0,3694):
if b[i]==0:
c[i] = 1
if (left > 0 and right==0):
right=i
else:
if (left==0):
left=i
c[i] = y[i]/b[i]
self.df['Absorption'] = c
self.df.plot(x = 'nmscale',y = 'Absorption', color='red',linewidth=0.6,ax=self.ax1)
self.ax1.set_xlim([self.nm_left+left*self.nm_step, self.nm_left+right*self.nm_step])
elif self.ok.get()==4:
right = 0
left = 0
y = self.df['darkline'] - self.df['p1']
b = self.df['baseline']
c = np.zeros(3694, np.float32)
for i in range(0,3694):
if b[i]==0:
c[i] = 1
if (left > 0 and right==0):
right=i
else:
if (left==0):
left=i
c[i] = np.log10(b[i]/y[i])
self.df['Transmission'] = c
self.df.plot(x = 'nmscale',y = 'Transmission', color='red',linewidth=0.6,ax=self.ax1)
self.ax1.set_xlim([self.nm_left+left*self.nm_step, self.nm_left+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()