import tkinter as tk import tkinter.messagebox import pandas as pd import matplotlib.pyplot as plt from IPython.display import clear_output from datetime import datetime # Check the functionalities of smus VAR1,VAR2 and VARD def check_sweep_func(smus:list,func:str): for i, smu in enumerate(smus): if smu["func"] == func: return True return False # Check if there is a pulsed smu for sweep smu def check_sweep_pulse(smus:list): for smu in smus: if "PULSE" in smu["mode"]: return True: return False # Check if there any constant smus and return their numbers def check_sweep_cons(smus:list): cons_smu_numbers = [] for i,smu in enumerate(smus): if smu['func']=='CONS' and smu['mode']!='COMM': # Non Grounded SMUs cons_smu_numbers.append(i+1) # for the actual number of smus return cons_smu_numbers # Setup the axes in tool def setup_axes(axes_info:list,device): axes_plot = ['X','Y1','Y2'] for ax_plot,ax_info in zip(axes_plot,axes_info): if ax_plot == 'Y2' and ax_info['name'] == "": # Y2 axis can be empty pass else: device.display_variable(ax_plot,ax_info['name']) device.axis_scale(ax_plot,ax_info['scale']) device.display_variable_min_max(ax_plot,'MIN',ax_info['min']) device.display_variable_min_max(ax_plot,'MAX',ax_info['max']) # Setup the variables to be saved def save_variables(axes,variables,device): # condition number one: the plotted variables need to be saved in the file # Sticter policy with exceptions # Retrieve the names of the variables variable_names =[] for variable in variables: variable_names.append(variable['name']) # Retrieve the axes names (variable) axes_names=[] for i,ax in enumerate(axes): if i != 2 and ax['name']!="" # Y2 axis can be left empty axes_names.append(ax['name']) # Now Check if axes names are in the variable names for ax_name in axes_names: if ax_name not in variable_names: raise Exception("Plotted Variables should be saved!") # Now save the variables variable_names =[] for variable in variables: variable_names.append(variable['name']) # Send the command to tool device.variables_to_save(variable_names) # Now this should work 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() 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() # We plot results: but we will play with the axes! def plot_results(values,device): # Get the names of the plotted variables x_var = device.get_axis_variable('X') y1_var = device.get_axis_variable('Y1') y2_var = device.get_axis_variable('Y2') # we will check for the empty # Get the scales of the plotted variables x_scale = device.get_axis_scale('X') # we will check the response too y1_scale = device.get_axis_scale('Y1') y2_scale = device.get_axis_scale('Y2') # Find the values that will be plotted for key, results in value.items(): if x_var in key: # check if the substring is contained x_values = results.copy() # This is a list x_label = key elif y1_var in key: y1_values = results.copy() y1_label = key elif y2_var in key and y2_var != None: y2_values = results.copy() y2_label = key # Now lets do the plot fig,ax1 = plt.subplots() ax1.set_xlabel(x_label) ax1.set_ylabel(y1_label,color = 'y') # Yellow Color ax1.set_xscale(x_scale) ax1.set_yscale(y1_scale) ax1.scatter(x_values,y1_values,color='y') ax1.tick_params(axis ='y', labelcolor ='y',which='both') if y2_var!= None: # Adding Twin Axes # Blue color ax2 = ax1.twinx() ax2.set_ylabel(y2_label,color = 'b') ax2.set_yscale(y2_scale) ax2.scatter(x_values,y2_values,color='b') ax2.tick_params(axis ='y', labelcolor ='b',which='both') display(fig) # The checks will be corrected later def create_file(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=".txt", filetypes=[("Text files","*.txt")],title = "save results path",initialfile =filename) #check if the file path is correct(.txt) while file.endswith(".txt") == False: #open again filedialog with error message box tk.messagebox.showerror(message='invalid filename!') file = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files","*.txt")],title = "save results path",initialfile =filename) root.destroy() return file # sampling help functions def check_cons_smu_samp(smus:list): cons_smu_numbers = [] for i,smu in enumerate(smus): if smu['mode']!='COMM': # Non Grounded SMUs cons_smu_numbers.append(i+1) # for the actual number of smus return cons_smu_numbers