diff --git a/hp4155/Custom_SMU/lib/help.py b/hp4155/Custom_SMU/lib/help.py index dcdeef37d5389d80075932bd263f8d7ad66767ee..cf28e8ccad5cab4ea4b2e264a81a3db001870f59 100644 --- a/hp4155/Custom_SMU/lib/help.py +++ b/hp4155/Custom_SMU/lib/help.py @@ -1,5 +1,8 @@ import tkinter as tk import tkinter.messagebox +import pandas as pd +import matplotlib.pyplot as plt +from IPython.display import clear_output # Check the functionalities of smus VAR1,VAR2 and VARD def check_sweep_func(smus:list,func:str): @@ -37,30 +40,10 @@ def setup_axes(axes_info:list,device): device.display_variable_min_max(ax_plot,'MAX',ax_info['max']) -# Find unit of a variable -def find_unit(variable,smus,user_functions): - - #firstly search over the names of the smus - - for smu in smus: - if variable == smu['vname']: - return 'V' - elif variable== smu['iname']: - return 'A' - else: - pass - - # Secondly search over the user functions - for user_function in user_functions: - if variable == user_function['name']: - return user_function['unit'] - - return "" - # Setup the variables to be saved -def save_variables(smus,user_functions,axes,variables,device): - +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 =[] @@ -69,28 +52,24 @@ def save_variables(smus,user_functions,axes,variables,device): # Retrieve the axes names (variable) axes_names=[] - for ax in axes: - axes_names.append(ax['name']) + 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: - index = 7 if ax_name not in variable_names: - variables[index]['name'] = ax_name - variables[index]['unit'] = find_unit(ax_name,smus,user_functions) - index = index-1 + raise Exception("Plotted Variables should be saved!") # Now save the variables variable_names =[] for variable in variables: - if variable['name'] != "": # Empty - variable_names.append(variable['name']) + variable_names.append(variable['name']) # Send the command to tool device.variables_to_save(variable_names) - # Return the new variables dictionary - return variables + # Now this should work def error_box(information): #open dialog and hide the main window @@ -116,5 +95,75 @@ def information_box(information): 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 + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/hp4155/Custom_SMU/main.py b/hp4155/Custom_SMU/main.py index 310667cc5bdf05da801624bb72163c9961f74c63..89ee2652623f38540058f7737723242cdef5c772 100644 --- a/hp4155/Custom_SMU/main.py +++ b/hp4155/Custom_SMU/main.py @@ -72,13 +72,14 @@ def on_start_clicked(b): user_functions = [] #iterate over the rows for i in range(1,7): - user_functions.append( - create_dict( - name = second_page[i,0].value, - unit=second_page[i,1].value, - expression = second_page[i,2].value + if second_page[i,0]!="": # do not save user functions without names + user_functions.append( + create_dict( + name = second_page[i,0].value, + unit=second_page[i,1].value, + expression = second_page[i,2].value + ) ) - ) # Page 3 @@ -132,12 +133,13 @@ def on_start_clicked(b): # Page 5 variables = [] for i in range(8): - variables.append( - create_dict( - name = fifth_page[6+i,0].value, - unit =fifth_page[6+i,1].value + if fifth_page[6+i,0].value!="": # do not save empty rows + variables.append( + create_dict( + name = fifth_page[6+i,0].value, + unit =fifth_page[6+i,1].value + ) ) - ) # Now execute measurement @@ -180,13 +182,13 @@ def on_start_clicked(b): # Now set the axes setup_axes(axes,device) - # Set the variables to be saved - variables = save_variables(smus,user_functions,axes,variables,device) - - # Modify the fifth page for user - for i in range(8): - fifth_page[6+i,0].value = variables[i]['name'] - fifth_page[6+i,1].value = variables[i]['unit'] + # Set the variables to be saved (This function has an exemption) + try: + save_variables(axes,variables,device) + except Exception as e: + error_box(e) + change_state(first_page,second_page,third_page,fourth_page,fifth_page) + return # Start the measurement @@ -202,10 +204,22 @@ def on_start_clicked(b): error_box(message) change_state(first_page,second_page,third_page,fourth_page,fifth_page) return - + + + # Get the data from the device + # These are correcly defined and include the plotted ones + values = {} + for variable in variables: + key = f"{variable['name']} ({variable['unit']})" + values[key] = device.return_data(variable['name']) + + plot_results(values,device) + + # Save results + df = pd.Dataframe(values) - + # Sampling Measurement Mode elif measurement_mode=='SAMPLING': @@ -218,10 +232,6 @@ def on_start_clicked(b): filter=third_page[17,0].value ) duration = third_page[13,0].value - - - - start.on_click(on_start_clicked) diff --git a/hp4155/hp4155a.py b/hp4155/hp4155a.py index 6847323a1e7e37e05c9522533d0501d1f496227f..b0352fb6d7700a6c2b03b7876c570b5bbc57bd41 100644 --- a/hp4155/hp4155a.py +++ b/hp4155/hp4155a.py @@ -219,6 +219,11 @@ class HP4155a(object): command = f":PAGE:DISP:GRAP:{axis}:NAME?" var_name = self.inst.query(command) return var_name.rstrip() #remove \n + + def get_axis_scale(self,axis): + command = f":PAGE:DISP:GRAP:{axis}:SCAL?" + scale = self.inst.query(command) + return scale.rstrip() def autoscaling(self): self.inst.write(":PAGE:GLIS:SCAL:AUTO ONCE")