Skip to content
Snippets Groups Projects
Select Git revision
  • bae97ff70fc453e5f553740d4ebabfb4da5c5734
  • master default protected
2 results

visualize.py

Blame
  • 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")