diff --git a/hp4155/ADU for double gate devices-test/double_gate_ADU.py b/hp4155/ADU for double gate devices-test/double_gate_ADU.py index 8f445058ce95a2149a7bd269503f6a47905e9663..f598a0cda01d24a1b9bb122f2288fea98a6f5ac1 100644 --- a/hp4155/ADU for double gate devices-test/double_gate_ADU.py +++ b/hp4155/ADU for double gate devices-test/double_gate_ADU.py @@ -7,6 +7,7 @@ from interface import * from help import * from measurements import * import configparser +import quick # Create the grids #create the information grid @@ -60,12 +61,13 @@ tab.titles = titles display(tab) button = widgets.Button(description ='Start Measurement') +quick_button = widgets.Button(description = 'Quick Measurement') output = widgets.Output() export_ini_button = widgets.Button(description = 'Export as ini') import_ini_button = widgets.Button(description='Import from ini') -all_widgets =[transfer_gates,output_gates,button,transfer_check,integration_transfer,output_check,integration_output,gatediode_check,integration_gatediode,terminal,export_ini_button,import_ini_button] +all_widgets =[transfer_gates,output_gates,button,transfer_check,integration_transfer,output_check,integration_output,gatediode_check,integration_gatediode,terminal,export_ini_button,import_ini_button,quick_button] add_widgets_to_list(sample,all_widgets) add_widgets_to_list(smu_map,all_widgets) @@ -77,7 +79,7 @@ add_widgets_to_list(Vtg_output,all_widgets) add_widgets_to_list(Vbg_output,all_widgets) add_widgets_to_list(Vg_gatediode,all_widgets) -line = widgets.HBox([button,import_ini_button,export_ini_button]) +line = widgets.HBox([button,quick_button,import_ini_button,export_ini_button]) display(line,output) device = hp4155a.HP4155a('GPIB0::17::INSTR') @@ -447,7 +449,374 @@ def on_start_clicked(b): information_box("Measurement finished!") enable_widgets(all_widgets) - + + +def on_quick_clicked(b): + with output: + clear_output() + #disable all widgets + disable_widgets(all_widgets) + + #additional code to check smu configuration fast without modifing a lot of code + try: + check_configuration(smu_map) + except Exception as e: + error_box(e) + enable_widgets(all_widgets) + return + + Setup(device) #setup the device + + #for all measurements the same (copy the interface with values for parameter setting) + map = smu_map.copy() + for key,value in map.items(): + map[key]= value.value + + sample_copy = sample.copy() + for key,value in sample_copy.items(): + sample_copy[key]=value.value + + smu_s = device.smu_dict() + smu_s.update(vname ='VS',iname = 'IS',mode = 'COMM',func='CONS') #Source smu is always grounded + + if transfer_check.value == True: + plot = plot_transfer.copy() + for key,value in plot.items(): + plot[key] = value.value + + points = number_of_points(Vds_transfer) + + var2=device.var2_dict() #Vds_output is always used in tranfer curve with the same config + var2.update( + start=Vds_transfer['start'].value, + step=Vds_transfer['step'].value, + points=points, + comp=Vds_transfer['comp'].value, + pcomp=Vds_transfer['pcomp'].value, + stop = Vds_transfer['stop'].value #not important for setting VAR2 only parameters in file + ) + + # also drain smu is the same + smu_d = device.smu_dict() + smu_d.update(vname='VDS',iname='ID',mode = 'V',func = 'VAR2') + match transfer_gates.value: + case 'VTG' if check_values(Vtg_transfer,'primary') and check_values(Vds_transfer,'secondary'): + smu_t = device.smu_dict() + smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1') + smu_b = device.smu_dict() + smu_b.update(vname = 'VBG',iname='IBG',mode = 'COMM',func = 'CONS') + + var1 = device.var1_dict() + var1.update( + mode=Vtg_transfer['hyst'].value, + start=Vtg_transfer['start'].value, + stop=Vtg_transfer['stop'].value, + step=Vtg_transfer['step'].value, + comp =Vtg_transfer['comp'].value, + pcomp=Vtg_transfer['pcomp'].value + ) + #define the final dict + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_D": smu_d, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "VAR2":var2, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_transfer.value, + } + #measure (later) + quick.Transfer_VTG(device,meas_dict) + + case 'VBG' if check_values(Vbg_transfer,'primary') and check_values(Vds_transfer,'secondary'): + smu_t = device.smu_dict() + smu_t.update(vname = 'VTG',iname='ITG',mode = 'COMM',func='CONS') + smu_b = device.smu_dict() + smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VAR1') + + var1 = device.var1_dict() + var1.update( + mode=Vbg_transfer['hyst'].value, + start=Vbg_transfer['start'].value, + stop=Vbg_transfer['stop'].value, + step=Vbg_transfer['step'].value, + comp =Vbg_transfer['comp'].value, + pcomp=Vbg_transfer['pcomp'].value + ) + + #define the final dict + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_D": smu_d, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "VAR2":var2, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_transfer.value, + } + #measure (later) + quick.Transfer_VBG(device,meas_dict) + + + case 'BOTH' if check_values(Vbg_transfer,'synchronous') and check_values(Vds_transfer,'secondary') and check_values(Vtg_transfer,'primary'): + smu_t = device.smu_dict() + smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1') + smu_b = device.smu_dict() + smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VARD') + + var1 = device.var1_dict() + var1.update( + mode=Vtg_transfer['hyst'].value, + start=Vtg_transfer['start'].value, + stop=Vtg_transfer['stop'].value, + step=Vtg_transfer['step'].value, + comp =Vtg_transfer['comp'].value, + pcomp=Vtg_transfer['pcomp'].value + ) + + #calculate parameters for VARD + ratio,offset = calculate_line(Vtg_transfer,Vbg_transfer) + + # update VBG step + Vbg_transfer["step"].value = Decimal(str(ratio)) * Decimal(str(Vtg_transfer["step"].value)) + + + vard = device.vard_dict() + vard.update( + offset = offset, + ratio = ratio, + comp = Vbg_transfer["comp"].value, + pcomp = Vbg_transfer["pcomp"].value, + start = Vbg_transfer["start"].value, + step = Vbg_transfer['step'].value, + stop = Vbg_transfer['stop'].value, + ) + + #define the final dict + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_D": smu_d, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "VAR2":var2, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_transfer.value, + "VARD":vard + } + + #measure (later) + quick.Transfer_BOTH(device,meas_dict) + case _ : + information_box("Transfer Measurement skipped due to invalid parameters") + + if output_check.value == True: + smu_d = device.smu_dict() + smu_d.update(vname='VDS',iname='ID',mode = 'V',func = 'VAR1') + + var1 = device.var1_dict() + var1.update( + mode=Vds_output['hyst'].value, + start=Vds_output['start'].value, + stop=Vds_output['stop'].value, + step=Vds_output['step'].value, + comp =Vds_output['comp'].value, + pcomp=Vds_output['pcomp'].value + ) + + plot = plot_output.copy() + for key,value in plot.items(): + plot[key] = value.value + + match output_gates.value: + case 'VTG' if check_values(Vds_output,'primary') and check_values(Vtg_output,'secondary'): + smu_t=device.smu_dict() + smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR2') + + smu_b= device.smu_dict() + smu_b.update(vname='VBG',iname='IBG',mode = 'COMM',func='CONS') + + points = number_of_points(Vtg_output) + + var2=device.var2_dict() + var2.update( + start=Vtg_output['start'].value, + step=Vtg_output['step'].value, + points=points, + comp=Vtg_output['comp'].value, + pcomp=Vtg_output['pcomp'].value, + stop = Vtg_output['stop'].value + ) + + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_D": smu_d, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "VAR2":var2, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_output.value, + } + + #measure later + quick.Output_VTG(device,meas_dict) + + case 'VBG' if check_values(Vds_output,'primary') and check_values(Vbg_output,'secondary'): + smu_t=device.smu_dict() + smu_t.update(vname ='VTG',iname = 'ITG',mode = 'COMM',func='CONS') + + smu_b= device.smu_dict() + smu_b.update(vname='VBG',iname='IBG',mode = 'V',func = 'VAR2') + + points = number_of_points(Vbg_output) + + var2=device.var2_dict() + var2.update( + start=Vbg_output['start'].value, + step=Vbg_output['step'].value, + points=points, + comp=Vbg_output['comp'].value, + pcomp=Vbg_output['pcomp'].value, + stop = Vbg_output['stop'].value + ) + + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_D": smu_d, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "VAR2":var2, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_output.value, + } + + #measure later + quick.Output_VBG(device,meas_dict) + + + case 'BOTH' if check_values(Vds_output,'primary') and check_values(Vtg_output,'secondary') and check_values(Vbg_output,'secondary'): + smu_t=device.smu_dict() + smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR2') + + smu_b= device.smu_dict() + smu_b.update(vname='VBG',iname='IBG',mode = 'V',func = 'CONS') + + points = number_of_points(Vtg_output) + + var2=device.var2_dict() + var2.update( + start=Vtg_output['start'].value, + step=Vtg_output['step'].value, + points=points, + comp=Vtg_output['comp'].value, + pcomp=Vtg_output['pcomp'].value, + stop = Vtg_output['stop'].value + ) + + points_VBG = number_of_points(Vbg_output) + values_VBG = np.linspace(Vbg_output["start"].value,Vbg_output["stop"].value,num = points_VBG,endpoint= True) + + #there is not such unit we create it with a loop + var3 = { + "start":Vbg_output['start'].value, + "step":Vbg_output['step'].value, + "points":points_VBG, + "comp":Vbg_output['comp'].value, + "stop" : Vbg_output['stop'].value, + "values" : values_VBG + } + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_D": smu_d, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "VAR2":var2, + "VAR3":var3, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_output.value, + } + + #measure later + quick.Output_BOTH(device,meas_dict) + + case _ : + information_box("Output Measurement skipped due to invalid parameters") + + + if gatediode_check.value == True: + #drain is disabled + device.smu_disable(map['D']) + + # VAR1 is set with the same interface + var1 = device.var1_dict() + var1.update( + mode=Vg_gatediode['hyst'].value, + start=Vg_gatediode['start'].value, + stop=Vg_gatediode['stop'].value, + step=Vg_gatediode['step'].value, + comp =Vg_gatediode['comp'].value, + pcomp=Vg_gatediode['pcomp'].value + ) + + plot = plot_gatediode.copy() + for key,value in plot.items(): + plot[key] = value.value + + match terminal.value: + case 'VTG' if check_values(Vg_gatediode,'primary'): + smu_t=device.smu_dict() + smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR1') + + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_T":smu_t, + "SMU_S":smu_s, + "VAR1":var1, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_gatediode.value, + } + #measure later + quick.Gatediode_VTG(device,meas_dict) + + case 'VBG' if check_values(Vg_gatediode,'primary'): + smu_b=device.smu_dict() + smu_b.update(vname ='VBG',iname = 'IBG',mode = 'V',func='VAR1') + + meas_dict = { + "SAMPLE":sample_copy, + "MAP" : map, + "SMU_B":smu_b, + "SMU_S":smu_s, + "VAR1":var1, + "PLOT": plot, # plot in the tool + "INTEGRATION": integration_gatediode.value, + } + #measure later + quick.Gatediode_VBG(device,meas_dict) + + case _ : + information_box("Gatediode Measurement skipped due to invalid parameters") + + information_box("Measurement finished!") + enable_widgets(all_widgets) def on_export_ini_clicked(b): with output: @@ -603,6 +972,7 @@ def on_import_ini_clicked(b): button.on_click(on_start_clicked) +quick_button.on_click(on_quick_clicked) import_ini_button.on_click(on_import_ini_clicked) export_ini_button.on_click(on_export_ini_clicked) diff --git a/hp4155/ADU for double gate devices-test/lib/quick.py b/hp4155/ADU for double gate devices-test/lib/quick.py new file mode 100644 index 0000000000000000000000000000000000000000..fa4b489a848582252d3258da87d76c98a9293a94 --- /dev/null +++ b/hp4155/ADU for double gate devices-test/lib/quick.py @@ -0,0 +1,769 @@ +# New measurements file for ADU + +# The new measurements will have the smus configuration as a parameter and written from the interface + +import sys +sys.path.insert(0, '..') #append parent directory + +import hp4155a +from help import * +from decimal import Decimal + +import os + +def Setup(device): + device.reset() + + #setup sweep measurement mode + device.measurement_mode('SWE') + + #disable all irrelevant units + device.disable_not_smu() + +# Transfer only VTG +def Transfer_VTG(device,params): + # calculate normalization factor + + norm = normalization_factor(params["SAMPLE"]["width"]) + try: + device.setup_smu(params["MAP"]['TG'],params["SMU_T"]) + device.setup_smu(params["MAP"]['D'],params["SMU_D"]) + device.setup_smu(params["MAP"]['BG'],params["SMU_B"]) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + device.setup_var1(params["VAR1"]) + device.setup_var2(params["VAR2"]) + + device.integration_time(params["INTEGRATION"]) + + variables_list =["VTG","ITG","VDS","ID"] + device.variables_to_save(variables_list) + + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + + device.single_measurement() + while device.operation_completed()==False: + pass + + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + # Append the normalized current + df["IDmm/uA/um"]= (df["ID/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["ITGmm/uA/um"]= (df["ITG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_TOP_GATE_U.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Transfer Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gate:VTG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VTG from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + f.write(f"VDS from {params['VAR2']['start']}V to {params['VAR2']['stop']}V with step {params['VAR2']['step']}V"+"\n") + + if params['VAR1']['pcomp']==0: + f.write(f"Top Gate Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Top Gate Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + if params['VAR2']['pcomp'] == 0: + f.write(f"Drain Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Drain Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') + +# Transfer only VBG +def Transfer_VBG(device,params): + try: + device.setup_smu(params["MAP"]['TG'],params["SMU_T"]) + device.setup_smu(params["MAP"]['D'],params["SMU_D"]) + device.setup_smu(params["MAP"]['BG'],params["SMU_B"]) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + + device.setup_var1(params["VAR1"]) + device.setup_var2(params["VAR2"]) + + device.integration_time(params["INTEGRATION"]) + + + variables_list =["VBG","IBG","VDS","ID"] + device.variables_to_save(variables_list) + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + device.single_measurement() + while device.operation_completed()==False: + pass + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + + except Exception as e: + error_box(e) + return + # calculate normalization factor + norm = normalization_factor(params["SAMPLE"]["width"]) + + # Append the normalized current + df["IDmm/uA/um"]= (df["ID/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["IBGmm/uA/um"]= (df["IBG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_BACK_GATE_U.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Transfer Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gate:VBG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VBG from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + f.write(f"VDS from {params['VAR2']['start']}V to {params['VAR2']['stop']}V with step {params['VAR2']['step']}V"+"\n") + + #calculate the values + if params['VAR1']['pcomp']==0: + f.write(f"Back Gate Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Back Gate Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + if params['VAR2']['pcomp'] == 0: + f.write(f"Drain Current Compliance/A:{params['VAR2']['comp']}"+"\n") + else: + f.write(f"Drain Power Compliance/A:{params['VAR2']['pcomp']}"+"\n") + + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') + + +def Transfer_BOTH(device,params): + try: + smu_t = device.smu_dict() + smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1') + + smu_b = device.smu_dict() + smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VARD') + + device.setup_smu(params["MAP"]['TG'],params["SMU_T"]) + device.setup_smu(params["MAP"]['D'],params["SMU_D"]) + device.setup_smu(params["MAP"]['BG'],params["SMU_B"]) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + + device.setup_var1(params["VAR1"]) + device.setup_var2(params["VAR2"]) + device.setup_vard(params["VARD"]) + + device.integration_time(params["INTEGRATION"]) + + variables_list =["VBG","IBG","VDS","ID","VTG","ITG"] + device.variables_to_save(variables_list) + + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + + device.single_measurement() + while device.operation_completed()==False: + pass + + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + # calculate normalization factor + norm = normalization_factor(params["SAMPLE"]["width"]) + + # Append the normalized current + df["IDmm/uA/um"]= (df["ID/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["IBGmm/uA/um"]= (df["IBG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["ITGmm/uA/um"]= (df["ITG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_BOTH_GATES_U.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Transfer Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gates:VBG,VTG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VBG from {params['VARD']['start']}V to {params['VARD']['stop']}V with step {params['VARD']['step']}V"+"\n") + f.write(f"VTG from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + f.write(f"VDS from {params['VAR2']['start']}V to {params['VAR2']['stop']}V with step {params['VAR2']['step']}V"+"\n") + + #calculate thes + if params['VARD']['pcomp']==0: + f.write(f"Back Gate Current Compliance/A:{params['VARD']['comp']}"+"\n") + else: + f.write(f"Back Gate Power Compliance/A:{params['VARD']['pcomp']}"+"\n") + + if params['VAR1']['pcomp']==0: + f.write(f"Top Gate Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Top Gate Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + if params['VAR2']['pcomp'] == 0: + f.write(f"Drain Current Compliance/A:{params['VAR2']['comp']}"+"\n") + else: + f.write(f"Drain Power Compliance/A:{params['VAR2']['pcomp']}"+"\n") + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') +# Output with VTG +def Output_VTG(device,params): + try: + device.setup_smu(params['MAP']['TG'],params["SMU_T"]) + device.setup_smu(params['MAP']['D'],params["SMU_D"]) + device.setup_smu(params['MAP']['BG'],params["SMU_B"]) + device.setup_smu(params['MAP']['S'],params["SMU_S"]) + + device.setup_var1(params["VAR1"]) + device.setup_var2(params["VAR2"]) + + device.integration_time(params["INTEGRATION"]) + + variables_list = ['VDS','ID','VTG','ITG'] + device.variables_to_save(variables_list) + + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + device.single_measurement() + + while device.operation_completed()==False: + pass + + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + norm = normalization_factor(params['SAMPLE']["width"]) + + # Append the normalized current + df["IDmm/uA/um"]= (df["ID/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["ITGmm/uA/um"]= (df["ITG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_TOP_GATE_A.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Output Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gate:VTG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VTG from {params['VAR2']['start']}V to {params['VAR2']['stop']}V with step {params['VAR2']['step']}V"+"\n") + f.write(f"VDS from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + + #calculate the values + if params['VAR2']['pcomp']==0: + f.write(f"Top Gate Current Compliance/A:{params['VAR2']['comp']}"+"\n") + else: + f.write(f"Top Gate Power Compliance/A:{params['VAR2']['pcomp']}"+"\n") + + if params['VAR1']['pcomp'] == 0: + f.write(f"Drain Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Drain Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') + + +#Output VBG +def Output_VBG(device,params): + try: + device.setup_smu(params["MAP"]['TG'],params["SMU_T"]) + device.setup_smu(params["MAP"]['D'],params["SMU_D"]) + device.setup_smu(params["MAP"]['BG'],params["SMU_B"]) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + + device.setup_var1(params["VAR1"]) + device.setup_var2(params["VAR2"]) + + device.integration_time(params["INTEGRATION"]) + + variables_list = ['VDS','ID','VBG','IBG'] + device.variables_to_save(variables_list) + + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + + device.single_measurement() + + while device.operation_completed()==False: + pass + + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + + # calculate normalization factor + norm = normalization_factor(params["SAMPLE"]["width"]) + + # Append the normalized current + df["IDmm/uA/um"]= (df["ID/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["IBGmm/uA/um"]= (df["IBG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_BACK_GATE_A.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Output Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gate:VBG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VBG from {params['VAR2']['start']}V to {params['VAR2']['stop']}V with step {params['VAR2']['step']}V"+"\n") + f.write(f"VDS from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + + #calculate the values + if params['VAR2']['pcomp']==0: + f.write(f"Back Gate Current Compliance/A:{params['VAR2']['comp']}"+"\n") + else: + f.write(f"Back Gate Power Compliance/A:{params['VAR2']['pcomp']}"+"\n") + + if params['VAR1']['pcomp'] == 0: + f.write(f"Drain Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Drain Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + df.to_csv(file,sep=" ",mode='a') + +# Output both +def Output_BOTH(device,params): + try: + device.setup_smu(params["MAP"]['TG'],params["SMU_T"]) + device.setup_smu(params["MAP"]['D'],params["SMU_D"]) + device.setup_smu(params["MAP"]['BG'],params["SMU_B"]) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + + device.setup_var1(params["VAR1"]) + device.setup_var2(params["VAR2"]) + + + device.integration_time(params["INTEGRATION"]) + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + + variables_list = ['VDS','ID','VBG','IBG','VTG','ITG'] + device.variables_to_save(variables_list) + + for i , value in enumerate(params["VAR3"]['values']): + cons = device.cons_smu_dict() + cons.update(comp = params['VAR3']['comp'],value = value) + device.setup_cons_smu(params['MAP']['BG'],cons) + + if i == 0: + device.single_measurement() + else: + device.append_measurement() + + while device.operation_completed()==False: + pass + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + + # calculate normalization factor + norm = normalization_factor(params["SAMPLE"]["width"]) + + # Append the normalized current + df["IDmm/uA/um"]= (df["ID/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["IBGmm/uA/um"]= (df["IBG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + df["ITGmm/uA/um"]= (df["ITG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_BOTH_GATES_A.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Output Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gates:VBG,VTG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VBG from {params['VAR3']['start']}V to {params['VAR3']['stop']}V with step {params['VAR3']['step']}V"+"\n") + f.write(f"VTG from {params['VAR2']['start']}V to {params['VAR2']['stop']}V with step {params['VAR2']['step']}V"+"\n") + f.write(f"VDS from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + + + #calculate the values + f.write(f"Back Gate Current Compliance/A:{params['VAR3']['comp']}"+"\n") + + if params['VAR2']['pcomp']==0: + f.write(f"Top Gate Current Compliance/A:{params['VAR2']['comp']}"+"\n") + else: + f.write(f"Top Gate Power Compliance/A:{params['VAR2']['pcomp']}"+"\n") + + + if params['VAR1']['pcomp'] == 0: + f.write(f"Drain Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Drain Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') + +def Gatediode_VTG(device,params): + try: + device.setup_smu(params["MAP"]['TG'],params["SMU_T"]) + device.smu_disable(params["MAP"]['BG']) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + device.setup_var1(params["VAR1"]) + + device.integration_time(params["INTEGRATION"]) + + variables_list = ['VTG','ITG'] + device.variables_to_save(variables_list) + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + + device.single_measurement() + + while device.operation_completed()==False: + pass + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + # calculate normalization factor + norm = normalization_factor(params['SAMPLE']["width"]) + + # Append the normalized current + df["ITGmm/uA/um"]= (df["ITG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_TOP_GATE_D.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Gatediode Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gate:VTG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VTG from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + + #calculate the values + if params['VAR1']['pcomp']==0: + f.write(f"Top Gate Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Top Gate Power Compliance/A:{params['VAR1']['pcomp'].value}"+"\n") + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') + + +def Gatediode_VBG(device,params): + try: + device.setup_smu(params["MAP"]['BG'],params["SMU_B"]) + device.smu_disable(params["MAP"]['TG']) + device.setup_smu(params["MAP"]['S'],params["SMU_S"]) + + device.setup_var1(params["VAR1"]) + + device.integration_time(params["INTEGRATION"]) + + variables_list = ['VBG','IBG'] + device.variables_to_save(variables_list) + + try: + plotted_variables = graph_tool(params,device) + except Exception as e: + error_box(e) + return + + + device.single_measurement() + while device.operation_completed()==False: + pass + + device.error_occured() + + values = dict([(variable,device.return_values(variable)) for variable in variables_list]) + df = get_dataframe_from_results(values) + except Exception as e: + error_box(e) + return + + # plot results + + # calculate normalization factor + norm = normalization_factor(params["SAMPLE"]["width"]) + + # Append the normalized current + df["IBGmm/uA/um"]= (df["IBG/A"].apply(lambda x: Decimal(str(x))*Decimal(str(norm)))).astype('float') + + # Save the results + default_filename = f"{params['SAMPLE']['sample']}_{params['SAMPLE']['field']}_{params['SAMPLE']['device']}_BACK_GATE_D.txt" + + 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 =default_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 =default_filename) + + root.destroy() + + with open(file,'w') as f: + date = str(datetime.today().replace(microsecond=0)) + f.write(f"Gatediode Curve at {date}"+"\n") + f.write(f"Series:{params['SAMPLE']['processing_number']}"+"\n") + f.write(f"Sample:{params['SAMPLE']['sample']}"+"\n") + f.write(f"Field:{params['SAMPLE']['field']}"+"\n") + f.write(f"Device:{params['SAMPLE']['device']}"+"\n") + f.write(f"Device Width/um:{params['SAMPLE']['width']}"+"\n") + f.write("Sweeping Gate:VBG"+"\n\n") + + f.write('Parameters\n') + f.write(f"VBG from {params['VAR1']['start']}V to {params['VAR1']['stop']}V with step {params['VAR1']['step']}V"+"\n") + + #calculate the values + if params['VAR1']['pcomp']==0: + f.write(f"Back Gate Current Compliance/A:{params['VAR1']['comp']}"+"\n") + else: + f.write(f"Back Gate Power Compliance/A:{params['VAR1']['pcomp']}"+"\n") + + f.write(f"Integration Time:{params['INTEGRATION']}"+"\n") + + f.write("\nResults\n") + + df.to_csv(file,sep=" ",mode='a') \ No newline at end of file diff --git a/hp4155/memristor (Version 4.1)/memristor.py b/hp4155/memristor (Version 4.1)/memristor.py index 83c2d6b056615cb301ad0f3c89fa20eb6169d169..af681660e359fc27e931b9ae591a29b5da7d6be0 100644 --- a/hp4155/memristor (Version 4.1)/memristor.py +++ b/hp4155/memristor (Version 4.1)/memristor.py @@ -308,7 +308,7 @@ def on_set_button_clicked(b): plot_sweep(V12,I12,'SET') df = create_data_frame(V12,I12) if voltmeter.value == True: - df["V3-V1 (V)"] = np.array(device.return_values("VMEAS")) + df["(V3-V1)(V)"] = np.array(device.return_values("VMEAS")) display(df) @@ -358,7 +358,7 @@ def on_reset_button_clicked(b): plot_sweep(V34,I34,'RESET') df = create_data_frame(V34,I34) if voltmeter.value == True: - df["V3-V1 (V)"] = np.array(device.return_values("VMEAS")) + df["(V3-V1)(V)"] = np.array(device.return_values("VMEAS")) display(df) if sampling.value == True: #do sampling set after reset process(100mV) @@ -489,7 +489,7 @@ def on_full_button_clicked(b): #create data frame and save to file df = create_data_frame(V,I) if voltmeter.value == True: - df["V3-V1 (V)"] = V_meas + df["(V3-V1)(V)"] = V_meas display(df) if i == 0 : header.extend([f"{i+1} Iteration"])