Select Git revision
tlm_parameters-checkpoint.ipynb
help.py 8.24 KiB
import matplotlib.pyplot as plt
import numpy as np
import time
from datetime import datetime
import tkinter as tk
from tkinter import filedialog
import tkinter.messagebox
import copy
import pandas as pd
#Get dataframe from results
def get_dataframe_from_results(dictionary):
# creating a shallow copy
dictionary_copy = copy.copy(dictionary)
for old_key in dictionary_copy.keys():
if old_key[0]=='I':
new_key = old_key+"/A"
else: #V
new_key = old_key + "/V"
dictionary[new_key] = dictionary.pop(old_key)
df = pd.DataFrame(dictionary)
return df
def number_of_points(dict):
try:
diff = dict['stop'].value - dict['start'].value
ratio = abs(diff/dict['step'].value)
points = int(ratio+1)
except ZeroDivisionError:
points = 1
#the programm crashed because for secondary step we had no problem setting start = stop and then it was dividing by zero
if points>128:
points = 128
return points
def check_values(dictionary,function):
valid = True
root = tk.Tk()
root.withdraw()
root.lift() #show window above all other applications
root.attributes("-topmost", True)#window stays above all other applications
if function =='primary':
if abs(dictionary['step'].value) > abs(dictionary['stop'].value-dictionary['start'].value) or dictionary['step'].value==0:#invalid parameter setting
valid = False
tkinter.messagebox.showerror(message="Invalid parameter setting!")
if dictionary['start'].value<dictionary['step'].value and dictionary['step'].value<0: #change polarity
dictionary['step'].value =(-1)*dictionary['step'].value
elif dictionary['start'].value>dictionary['stop'].value and dictionary['step'].value>0:
dictionary['step'].value = (-1)*dictionary['step'].value
else:
pass
if function == 'secondary':
if dictionary['start'].value == dictionary['stop'].value:
pass
elif abs(dictionary['step'].value) > abs(dictionary['stop'].value-dictionary['start'].value) or dictionary['step'].value==0:#invalid parameter setting
valid = False
tkinter.messagebox.showerror(message="Invalid parameter setting!")
if dictionary['start'].value<dictionary['step'].value and dictionary['step'].value<0: #change polarity
dictionary['step'].value =(-1)*dictionary['step'].value
elif dictionary['start'].value>dictionary['stop'].value and dictionary['step'].value>0:
dictionary['step'].value = (-1)*dictionary['step'].value
if function == 'synchronous':
pass
if valid == True:
#check compliance
comp = dictionary['comp'].value
start = dictionary['start'].value
stop = dictionary['stop'].value
if abs(comp)*max(abs(start),abs(stop))>2:
dictionary["comp"].value=np.sign(comp)*2/max(abs(start),abs(stop))
root.destroy()
return valid
def add_widgets_to_list(source_dictionary,target_list):
for widget in source_dictionary.values():
target_list.append(widget)
def change_state(widgets_list):
for widget in widgets_list:
widget.disabled = not widget.disabled
def enable_widgets(widgets_list):
for widget in widgets_list:
widget.disabled = False
def disable_widgets(widgets_list):
for widget in widgets_list:
widget.disabled = True
def information_box(information):
#open dialog and hide the main window
root = tk.Tk()
root.withdraw()
root.lift() #show window above all other applications
root.attributes("-topmost", True)#window stays above all other applications
#display meaagebox
tkinter.messagebox.showinfo(message=information)
root.destroy()
def error_box(information):
#open dialog and hide the main window
root = tk.Tk()
root.withdraw()
root.lift() #show window above all other applications
root.attributes("-topmost", True)#window stays above all other applications
#display meaagebox
tkinter.messagebox.showerror(message=information)
root.destroy()
#normalization factor to is for both normalizations 10**6/width mA/mm = uA/um = 10**(-6)A/um (returned from the tool)
def normalization_factor(width):
factor = 10**6/width
return factor
def save_as_ini(default_filename):
root = tk.Tk()
root.withdraw()
root.lift() #show window above all other applications
root.attributes("-topmost", True)#window stays above all other applications
file = filedialog.asksaveasfilename(defaultextension=".ini", filetypes=[("Ini files","*.ini")],title = "save as ini",initialfile =default_filename)
#check if the file path is correct(.txt)
while file.endswith(".ini") == False:
#open again filedialog with error message box
answer=tk.messagebox.askyesno(message='Do you want to cancel the ini file Save?')
if answer == True:
raise Exception("Ini File Operation aborted!")
else:
file = filedialog.asksaveasfilename(defaultextension=".ini", filetypes=[("Ini files","*.ini")],title = "save as ini",initialfile =default_filename)
root.destroy()
return file
def load_ini():
root = tk.Tk()
root.withdraw()
root.lift() #show window above all other applications
root.attributes("-topmost", True)#window stays above all other applications
file = filedialog.askopenfilename(filetypes=[("Ini files","*.ini")],title ='Select ini file')
while file.endswith(".ini") == False:
#open again filedialog with error message box
answer=tk.messagebox.askyesno(message='Do you want to cancel the ini file load?')
if answer == True:
raise Exception("Ini File Operation aborted!")
else:
file = filedialog.askopenfilename(filetypes=[("Ini files","*.ini")],title = "Select ini file")
root.destroy()
return file
# function to return ratio and offset for synchronous sweep measurement
def calculate_line(VTG,VBG):
ratio = (VBG['stop'].value-VBG['start'].value)/(VTG['stop'].value-VTG['start'].value)
offset = VBG['start'].value-ratio*VTG['start'].value
return ratio,offset
# replot results
def replot_results(replot_dict,df,points,title):
try:
if len(df.columns.tolist())!=0 and replot_dict['check'].value==True: # Measurement is done
fig,ax = plt.subplots(figsize=(10,6))
#Retrieve the columns
x_col = replot_dict['x_variable'].value
y_col = replot_dict['y_variable'].value
#Scale and Absolute Values
if replot_dict['x_scale'].value=='linear':
x = np.array_split(df[x_col],points)
else:
x = np.array_split(df[x_col].abs(),points)
ax.set_xscale('log')
if replot_dict['y_scale'].value=='linear':
y = np.array_split(df[y_col],points)
else:
y = np.array_split(df[y_col].abs(),points)
ax.set_yscale('log')
# check auto limits
if replot_dict['x_auto'].value== False and replot_dict['x_max'].value > replot_dict['x_min'].value:
ax.set_xlim([replot_dict['x_min'].value,replot_dict['x_max'].value])
if replot_dict['y_auto'].value== False and replot_dict['y_max'].value > replot_dict['y_min'].value:
ax.set_ylim([replot_dict['y_min'].value,replot_dict['y_max'].value])
# Now set the label
ax.set_xlabel(x_col)
ax.set_ylabel(y_col)
#And Plot
for i in range(points):
ax.plot(x[i],y[i])
fig.suptitle(title, fontweight ="bold")
fig.show() # Do this interactively to save the figures
except:
information_box("reploting failed please try again")
#check if smu configuration has a double value
def check_configuration(smu_map:dict):
#convert the dictionaries values to a list
map_list = []
for element in smu_map.values():
map_list.append(element.value)
#remove the duplicates by using a set
map_set = set(map_list)
if len(map_set)!= len(map_list): #we have duplicates
raise Exception("You cannot assign a smu to multiple contacts")