diff --git a/hp4194/cv.py b/hp4194/cv.py index 06260fb245417b70015513d231f9479b3430a66b..7f346b54f3eec5326dae27a1fb0a70b2e3c7db0c 100644 --- a/hp4194/cv.py +++ b/hp4194/cv.py @@ -1,6 +1,9 @@ from interface import * import control import matplotlib.pyplot as plt +from help import * +import time +from IPython.display import clear_output #connect to device @@ -8,37 +11,34 @@ device = control.hp4194() device.write('reset') #create interface +sample,sample_dict = probendaten() messparameter,messparameter_dict = messparameter() sweep_parameter,sweep_parameter_dict = sweep_parameter() -control_panel,measure,calibrate,clear_graphs,view=control_panel() - +control_panel,measure,clear_graphs,view=control_panel() +#set up interface out = widgets.Output() - hbox1 = widgets.HBox([sample,control_panel]) display(hbox1) hbox2=widgets.HBox([messparameter,sweep_parameter]) display(hbox2) display(out) -def add_widgets_to_list(source_dictionary,target_list): - for widget in source_dictionary.values(): - target_list.append(widget) - +#add widgets to a list for disabling them all_widgets = [measure,calibrate,clear_graphs] add_widgets_to_list(view,all_widgets) add_widgets_to_list(sweep_parameter_dict,all_widgets) add_widgets_to_list(messparameter_dict,all_widgets) -def change_state(widgets_list): - for widget in widgets_list: - widget.disabled = not widget.disabled - -def on_calibrate_clicked(b): +def on_measure_clicked(b): with out: + clear_output() change_state(all_widgets) + if check_values(messparameter_dict,sweep_parameter_dict) == False: + information('Invalid Voltage Settings or Observation of non-existent data points!') + change_state(all_widgets) device.write('reset') # perform an open calibration @@ -68,11 +68,99 @@ def on_calibrate_clicked(b): device.set_parameter('set_delay_apperture',sweep_parameter_dict['d_apperture'].value) device.set_parameter('aver_num',sweep_parameter_dict['averaging'].value) - device.write('open_cal_on') #data saved in registers OG and OB - device.write('start_open_cal') - device.wait() + # Now that we have set the frequency values ask user for calibration + answer = ask_for_calibration() + if answer == True : #perform an open calibration + device.write('open_cal_on') #data saved in registers OG and OB + device.write('start_open_cal') + device.wait() + + # open the file dialog + default_filename = f"{sample_dict['wafer'].value}_{sample_dict['sample'].value}_{sample_dict['field'].value}_CV.txt" + file = save_file(default_filename) + + #now perform the measurement + device.write('autoscale_A') # Autoscale A + device.write('autoscale_B') # Autoscale B + + # create the numpy list with the biases + # create the arrays with frequency, G and B + frequency = [] + G = [] + B = [] + + num_of_points = abs(messparameter_dict["stop"].value-messparameter_dict["start"].value)/abs(messparameter_dict["step"].value) + 1 + + biases = np.linspace(messparameter_dict["start"].value,messparameter_dict["stop"].value,num_of_points,endpoint = True) + + for bias in biases: + device.set_parameter('set_bias', bias) #set the bias + device.write('start_sweep') #start the measurement + device.wait() #wait for completition + + # read the registers + + current_freq = device.read_register('reg_sweep') + current_G = device.read_register('reg_A') + current_B = device.read_register('reg_B') + + time.sleep(messparameter_dict["sleep"].value) + + # Do A test plot + fig,ax1 = plt.subplots() + + color = 'b' + ax1.set_xlabel('Frequency (Hz)') + ax1.set_ylabel('G (S)', color=color) + ax1.plot(current_freq,current_G , color=color) + ax1.tick_params(axis='y', labelcolor=color) + + ax2 = ax1.twinx() + color = 'y' + ax2.set_ylabel('B (S)', color=color) # we already handled the x-label with ax1 + ax2.plot(current_freq,current_B, color=color) + ax2.tick_params(axis='y', labelcolor=color) + + fig.suptitle(f"Results for Bias = {bias}V") + fig.tight_layout() + display(fig) + + if messparameter_dict["hysteris"].value == True: + reversed_biases = reversed_array(biases) + for bias in reversed_biases: + device.set_parameter('set_bias', bias) #set the bias + device.write('start_sweep') #start the measurement + device.wait() #wait for completition + + # read the registers + + current_freq = device.read_register('reg_sweep') + current_G = device.read_register('reg_A') + current_B = device.read_register('reg_B') + + time.sleep(messparameter_dict["sleep"].value) + + # Do A test plot + fig,ax1 = plt.subplots() + + color = 'b' + ax1.set_xlabel('Frequency (Hz)') + ax1.set_ylabel('G (S)', color=color) + ax1.plot(current_freq,current_G , color=color) + ax1.tick_params(axis='y', labelcolor=color) + + ax2 = ax1.twinx() + color = 'y' + ax2.set_ylabel('B (S)', color=color) # we already handled the x-label with ax1 + ax2.plot(current_freq,current_B, color=color) + ax2.tick_params(axis='y', labelcolor=color) + + fig.suptitle(f"Results for Bias = {bias}V") + fig.tight_layout() + display(fig) + - change_state(all_widgets) - \ No newline at end of file + +measure.on_click(on_measure_clicked) \ No newline at end of file diff --git a/hp4194/help.py b/hp4194/help.py new file mode 100644 index 0000000000000000000000000000000000000000..f3aae65b5eba8abbbaf0be3ae0afa172ba67d81c --- /dev/null +++ b/hp4194/help.py @@ -0,0 +1,88 @@ +import ipywidgets as widgets +import tkinter as tk +from tkinter import filedialog +import tkinter.messagebox + + +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 ask_for_calibration(): + root = tk.Tk() + root.withdraw() + root.lift() #show window above all other applications + + root.attributes("-topmost", True)#window stays above all other applications + + answer=tk.messagebox.askyesno(message='Do you want to calibarate?') + + root.destroy() + return answer + +def save_file(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=".txt", filetypes=[("Txt files","*.txt")],title = "save results",initialfile =default_filename) + + while file.endswith(".txt") == False: + file = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Txt files","*.txt")],title = "save results",initialfile =default_filename) + + root.destroy() + return file + +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 check_values(voltage:dict,freq:dict): + + if abs(voltage["step"].value) > abs(voltage["stop"].value-voltage["start"].value) or voltage["step"].value == 0: + return False + + #Invert Polarity if nesaccary + if voltage["stop"].value > voltage["start"].value and voltage["step"].value < 0: + voltage["step"].value = -voltage["step"].value + elif voltage["stop"].value < voltage["start"].value and voltage["step"].value > 0: + voltage["step"].value = -voltage["step"].value + else: + pass + + # Now lets check for correct plots + + # calculate the number of points for voltage + voltage_points = abs(voltage["stop"].value-voltage["start"].value)/abs(voltage["step"].value) + 1 + + if voltage["v_point"].value > voltage_points and voltage["hysterisis"].value == False: + return False + elif voltage["v_point"].value > 2*voltage_points and voltage["hysterisis"].value == True: + return False: + + # prove that we check a valld frequency point + if voltage["f_point"].value > freq['nop'].value: + return False + return True + +# create array for hysteris and remove the last element +def reversed_array(arr): + arr = arr[np.arange(arr.size - 1)] + reversed_arr = arr[::-1] + return reversed_array \ No newline at end of file diff --git a/hp4194/interface.py b/hp4194/interface.py index bff1280a6fcea77abca5b685f4d6b03ae4217dfc..276ea3006badb456fe3cc15a1c3cebf7dfde5024 100644 --- a/hp4194/interface.py +++ b/hp4194/interface.py @@ -128,8 +128,7 @@ def control_panel(): width = 'auto' control_panel = GridspecLayout(6,2) - control_panel[0,0] = widgets.Button(description = "Start Measurement",layout=Layout(height='auto', width = width)) - control_panel[0,1] = widgets.Button(description = "Start Calibration",layout=Layout(height='auto', width = width)) + control_panel[0,:] = widgets.Button(description = "Start Measurement",layout=Layout(height='auto', width = width)) control_panel[1,0] = widgets.Label("V-Point",layout=Layout(height='auto', width = width)) control_panel[1,1] = widgets.Label("f-Point",layout=Layout(height='auto', width = width)) @@ -141,8 +140,7 @@ def control_panel(): control_panel[4,0] = widgets.Text(disabled = True,layout=Layout(height='auto', width = width)) control_panel[4,1] = widgets.Checkbox(description = 'Clear Graphs',value = True,indent = False,layout=Layout(height='auto', width = width)) - measure = control_panel[0,0] - calibrate = control_panel[0,1] + measure = control_panel[0,:] clear_graphs = control_panel[4,1] view = { @@ -151,7 +149,7 @@ def control_panel(): 'v-value':control_panel[4,0] } - return control_panel,measure,calibrate,clear_graphs,view + return control_panel,measure,clear_graphs,view diff --git a/hp4194/test_interface.ipynb b/hp4194/test_interface.ipynb index 2da6bbc3c037e45a5915ac4fb3915dd430b6f552..c5d3a572d6888518b1940c27254bf8b813caa50d 100644 --- a/hp4194/test_interface.ipynb +++ b/hp4194/test_interface.ipynb @@ -18,8 +18,7 @@ "metadata": {}, "outputs": [], "source": [ - "sample,sample_dict = probendaten()\n", - "\n" + "sample,sample_dict = probendaten()" ] }, { @@ -49,7 +48,7 @@ "metadata": {}, "outputs": [], "source": [ - "control_panel,measure,calibrate,clear_graphs,view=control_panel()" + "control_panel,measure,clear_graphs,view=control_panel()" ] }, { @@ -71,7 +70,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9d5320c4d8714f21907d8a2845d1361b", + "model_id": "bc379301efdf4d56bd004f2afe75775b", "version_major": 2, "version_minor": 0 }, @@ -85,7 +84,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "0283052d535f40f3b9d71d12950bcf7f", + "model_id": "b8557efc4dc24cfcb28322f9b5a0c6fb", "version_major": 2, "version_minor": 0 }, @@ -99,7 +98,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f9b54cce2db34bf0b214703d0e08d560", + "model_id": "5bf5530eb11e41f494b3507550783893", "version_major": 2, "version_minor": 0 },