162 lines
12 KiB
Python
162 lines
12 KiB
Python
# Copyright (c) 2019 Esben Rossel
|
|
# All rights reserved.
|
|
#
|
|
# Author: Esben Rossel <esbenrossel@gmail.com>
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
# SUCH DAMAGE.
|
|
|
|
import os
|
|
import tkinter as tk
|
|
from tkinter.constants import END
|
|
from PIL import Image,ImageTk
|
|
|
|
def center_window(size, window) :
|
|
window_width = size[0] #Fetches the width you gave as arg. Alternatively window.winfo_width can be used if width is not to be fixed by you.
|
|
window_height = size[1] #Fetches the height you gave as arg. Alternatively window.winfo_height can be used if height is not to be fixed by you.
|
|
if window==None:
|
|
window_x = 200
|
|
window_y = 200
|
|
else:
|
|
window_x = int((window.winfo_screenwidth() / 2) - (window_width / 2)) #Calculates the x for the window to be in the centre
|
|
window_y = int((window.winfo_screenheight() / 2) - (window_height / 2)) #Calculates the y for the window to be in the centre
|
|
|
|
window_geometry = str(window_width) + 'x' + str(window_height) + '+' + str(window_x) + '+' + str(window_y) #Creates a geometric string argument
|
|
window.geometry(window_geometry) #Sets the geometry accordingly.
|
|
return
|
|
|
|
|
|
def get_icon_image(xx):
|
|
directory_path = os.path.dirname(__file__)
|
|
file_path = os.path.join(directory_path, 'images\\')
|
|
image =Image.open(file_path+xx)
|
|
photo = ImageTk.PhotoImage(image)
|
|
return photo
|
|
|
|
|
|
|
|
def jfshelpme(win,helpfor):
|
|
top = tk.Toplevel(win)
|
|
scrolling = tk.Scrollbar(top)
|
|
scrolling.pack(side=tk.RIGHT, fill=tk.Y)
|
|
|
|
frame = tk.Frame(top)
|
|
frame.pack()
|
|
text = tk.Text(frame, height=30, width=100, wrap=tk.WORD)
|
|
text.pack(side=tk.LEFT, fill=tk.Y)
|
|
scrolling.config(command=text.yview)
|
|
text.config(yscrollcommand=scrolling.set)
|
|
|
|
photoImg = get_icon_image('nm405.gif')
|
|
photoImg2= get_icon_image('methods.gif')
|
|
photoImg3= get_icon_image('kinetics.gif')
|
|
photoImg4= get_icon_image('xenon.gif')
|
|
|
|
text.tag_configure('it', font=('Arial', 10, 'italic'))
|
|
text.tag_configure('h1', font=('Verdana', 16, 'bold'))
|
|
text.tag_configure('h2', font=('Verdana', 12, 'bold'))
|
|
text.tag_configure('h3', font=('Verdana', 10, 'bold'))
|
|
|
|
if (helpfor == 0): #do you need help with the device?
|
|
text.image_create(tk.END,image=photoImg)
|
|
text.insert(tk.END, " Calibration\n", 'h1')
|
|
text.insert(tk.END, "\nTo calibrate the Instrument we need two laserpointer of different colors und known wavelength.\nFor example a blue [405nm] and red [650nm] one.\n")
|
|
text.insert(tk.END, "1) First take two messurements with your device und save the files with the [Save] button under a comprehensible name (e.g. 405nm.data) \n")
|
|
text.insert(tk.END, "2) Open the calibration dialog and insert the wavelength in [nm] and afterwards select the respective file. <first peak> stands for the lower and <second peak> for the higher wavelength.\n")
|
|
text.insert(tk.END, "3) Now you can use the [Calibrate] button to calibrate the instrument and [Save Config] will the store the configuration.\n")
|
|
text.insert(tk.END,"\nAfter this procedure you can switch the [nm] scale on and use other option:\n")
|
|
text.insert(tk.END,'\nMethods\n','h2')
|
|
text.insert(tk.END,"\nAs a Photometer to messure the transmittance or absorbance depending on the concentration of colored compounds.\n\n")
|
|
text.image_create(tk.END,image=photoImg2)
|
|
text.insert(tk.END,"\n\nKinetic\n",'h2')
|
|
text.insert(tk.END,"\nThe instrument can messure in specific intervalls over time the change in absorbance. From this data it is possible to determine the rate of the reaction.\n")
|
|
text.image_create(tk.END,image=photoImg3)
|
|
text.insert(tk.END,"\n Baseline\n",'h1')
|
|
text.insert(tk.END,"\nIn order to messure the absorption of a compound in the cuvette, you have to messure the intensity of the the light passing through the reference cell.\n")
|
|
text.insert(tk.END,"The intensity of the light at a specific wavelength depends on the kind of lightsource. The spectrum of a tungstone lamp is different from a LED etc.\n")
|
|
text.insert(tk.END,"\nTo make things easy: the value <threshold for the baseline> cuts off the beginning and the end where the lightsource is not strong enought to give reasonable results ")
|
|
text.image_create(tk.END,image=photoImg4)
|
|
text.insert(tk.END,"\nFor example xenon-lamp as a source. If the value of the threshold is set to 100 (green), the baseline will start at 380nm and end at 510nm\n")
|
|
text.insert(tk.END,"If the value of the threshold is set to 50 (red), the baseline will start at 370nm and end at 695nm. The baseline determines the range of messurement\n")
|
|
|
|
elif (helpfor == 1): #do you need help with the device?
|
|
text.image_create(tk.END,image=photoImg)
|
|
text.insert(tk.END, " Calibration\n", 'h1')
|
|
text.insert(tk.END, "\nTo calibrate the Instrument we need two laserpointer of different colors und known wavelength.\nFor example a blue [405nm] and red [650nm] one.\n")
|
|
text.insert(tk.END, "1) First take two messurements with your device und save the files with the [Save] button under a comprehensible name (e.g. 405nm.data) \n")
|
|
text.insert(tk.END, "2) Open the calibration dialog and insert the wavelength in [nm] and afterwards select the respective file. <first peak> stands for the lower and <second peak> for the higher wavelength.\n")
|
|
text.insert(tk.END, "3) Now you can use the [Calibrate] button to calibrate the instrument and [Save Config] will the store the configuration.\n")
|
|
text.insert(tk.END,"\nAfter this procedure you can switch the [nm] scale on and use other option:\n")
|
|
text.insert(tk.END,'\nMethods\n','h2')
|
|
text.insert(tk.END,"\nAs a Photometer to messure the transmittance or absorbance depending on the concentration of colored compounds.\n\n")
|
|
text.image_create(tk.END,image=photoImg2)
|
|
text.insert(tk.END,"\n\nKinetic\n",'h2')
|
|
text.insert(tk.END,"\nThe instrument can messure in specific intervalls over time the change in absorbance. From this data it is possible to determine the rate of the reaction.\n")
|
|
text.image_create(tk.END,image=photoImg3)
|
|
elif (helpfor == 2):
|
|
text.insert(tk.END," Dark spectrum\n",'h1')
|
|
text.insert(tk.END,"\nPlease turn off the lightsource and take a messurement with the actual parameter. Afterwards save this spektrum of the dark noise\n")
|
|
text.insert(tk.END,"\nClick the checkbutton of [Darkline] to proceed")
|
|
elif (helpfor == 3):
|
|
text.insert(tk.END," Zero solution \n",'h1')
|
|
text.insert(tk.END,"\nIn order to messure the absorbance or transmittance of a sample, you need to messure a zero solution first\n")
|
|
text.insert(tk.END,"\n1) Check the darkline checkbutton\n2) Turn on the lightsource and insert a cuvette with a solution without a compound -> \'zero solution\'\n")
|
|
text.insert(tk.END,"3) Save the messurement with [save Base]. This will also cut the range of messurement depending of the lightsoure -> Baseline\n" )
|
|
text.insert(tk.END,"4) Click the checkbutton of [Baseline] to proceed\n")
|
|
text.insert(tk.END,"Now you can messure the absorbance or transmittance of different compounds by using the radiobuttons \n")
|
|
text.insert(tk.END,"\nWith the Dialog [Calibration] you can change the range of the lightsource\n\n")
|
|
text.insert(tk.END,"\n Baseline\n",'h2')
|
|
text.insert(tk.END,"\nIn order to messure the absorption of a compound in the cuvette, you have to messure the intensity of the the light passing through the reference cell.\n")
|
|
text.insert(tk.END,"The intensity of the light at a specific wavelength depends on the kind of lightsource. The spectrum of a tungstone lamp is different from a LED etc.\n")
|
|
text.insert(tk.END,"\nTo make things easy: the value <threshold for the baseline> cuts off the beginning and the end where the lightsource is not strong enought to give reasonable results ")
|
|
text.image_create(tk.END,image=photoImg4)
|
|
text.insert(tk.END,"\nFor example xenon-lamp as a source. If the value of the threshold is set to 100 (green), the baseline will start at 380nm and end at 510nm\n")
|
|
text.insert(tk.END,"If the value of the threshold is set to 50 (red), the baseline will start at 370nm and end at 695nm. The baseline determines the range of messurement\n")
|
|
elif (helpfor == 4):
|
|
text.insert(tk.END," Load / Save \n",'h1')
|
|
text.insert(tk.END,"\nThese Buttons save und load the photometer data of the absorbance of a compound. The baseline of the lightsource and the dark spectrum of the instrument will also be saved\n")
|
|
text.insert(tk.END,"\nThis will not work with with simple spetra saves over the [Save] button")
|
|
elif (helpfor == 5):
|
|
text.image_create(tk.END,image=photoImg3)
|
|
text.insert(tk.END,"\nKinetic\n",'h1')
|
|
text.insert(tk.END,"\nTo run kinetic messurements with this photometer, make sure that:\n")
|
|
text.insert(tk.END,"1) The instrument is calibrated\n2) A dark spektrum is taken/saved [save Dark]\n3) A zero solution is messured a saved [save Base].\n\n")
|
|
text.insert(tk.END,"If all parameters a ok. Adjust the numbers of repetitions and the time between the messurement in the dialog.\nThe [start Kinetic] Button will start the process.\n")
|
|
text.insert(tk.END,"When the messurement is finished the [Math] Dialog appears and the data can be saved and inspected.\n")
|
|
elif (helpfor == 6):
|
|
#text.image_create(tk.END,image=photoImg3)
|
|
text.insert(tk.END,"\nMath on Kinetics\n",'h1')
|
|
elif (helpfor == 7):
|
|
text.image_create(tk.END,image=photoImg2)
|
|
text.insert(tk.END," Methods\n",'h1')
|
|
text.insert(tk.END,"\nIn this part of the programm it is possible to determine the concentration of a compound with the spectrometer.\n")
|
|
text.insert(tk.END,"1) Try out concentration of the compount,ICG,SH,lightsource etc. that works fine and give an absorbance of approx 1.\nCheck [nm], [Darkline] and [Baseline]\n")
|
|
text.insert(tk.END,"2) Dilute the solution for the standard curve.\nFor example if the last concentration in 30mmol and 5 solution are made. You have to prepare 6mmol,12mmol,18mmol,24mmol and 30mmol.\n")
|
|
text.insert(tk.END,"3) Complete the dialog <Edit the method> and [add Method]. The method will appear in the methods window, with a line for each concentration.\n")
|
|
text.insert(tk.END,"4) Now insert the cuvette with the specific concentration and select the line.\nThe messurement takes place and the absorbance will be stored\n")
|
|
text.insert(tk.END,"5) If everything is ok, you can save the method and it's values.\n")
|
|
text.insert(tk.END,"\nThe fitting curve is determined by numpy's polyfit and the r2_score and displayed.\n")
|
|
text.insert(tk.END,"\nAfterwards an unknown concentration of a compound can be determined over the dialog <Do messurements>")
|
|
### at the end
|
|
text.config(state=tk.DISABLED)
|
|
top.focus_set()
|
|
top.grab_set()
|
|
top.wait_window() |