diff --git a/hp4155/memristor (Version 4.0)/help.py b/hp4155/memristor (Version 4.0)/help.py index c8560119cb55cf35231537fde39a8a5b8cb3861b..f90780baa8ec701d9aa5e2108493432fbe0f0aae 100644 --- a/hp4155/memristor (Version 4.0)/help.py +++ b/hp4155/memristor (Version 4.0)/help.py @@ -105,7 +105,10 @@ def regular_contact_check(device): """ R=contact_check(i,j,device) resistances[f"{i}-{j}"] = R - return resistances + + #convert dictionary to df + df = pd.DataFrame(resistances.items(), columns=['SMU pair', 'Resistance (Ohm)']) + return df def EBL(device): # EBL are SMUs 1-4 and 2-3 @@ -113,17 +116,21 @@ def EBL(device): for i,j in zip(range(1,3),range(4,2,-1)): #loop simultaneously 1-4,2-3 pairs R = contact_check(i,j,device) resistances[f"{i}-{j}"] = R - return resistances + + #convert dictionary to df + df = pd.DataFrame(resistances.items(), columns=['SMU pair', 'Resistance (Ohm)']) + return df def OL(device): # OL smu 3-4,1-2 resistances= {} for i,j in zip(range(3,0,-2),range(4,1,-2)): #loop simultaneously 3-4 , 1-2 pairs R = contact_check(i,j,device) - resistances[f"{i}-{j}"] = R - return resistances + resistances[f"{i}-{j}"] = R - + #convert dictionary to df + df = pd.DataFrame(resistances.items(), columns=['SMU pair', 'Resistance (Ohm)']) + return df #double sweep from start to stop and then from start to stop def sweep(start,stop,step,comp,integration,device): #step cannot be negative @@ -352,9 +359,16 @@ def create_retention_data_frame(x,y): #write results to file -def write_to_file(file,title,df): - with open(file,'a') as f: - f.write(title) +def write_to_file(file,title:list,df): + #append escape character after each element + index = 1 + while index <= len(title): + title.insert(index,"\n") + index = index+2 + + #write to file + with open(file,'a') as f: + f.writelines(title) f.write("\n") f.write(df.to_string()) f.write("\n\n") @@ -487,21 +501,6 @@ def upload_results(source_file,target_file,target_file_dir): filename = os.path.basename(target_file) target_file =os.path.join(target_file_dir,filename) #and then try again - - -def save_contact_check(R,file): #save contact check to file - """ - Parameters: - -Resistances list - -File to save - """ - - with open(file,'a') as f: - f.write("Contact Check Results:\n") - - df = pd.DataFrame(R.items(), columns=['SMU pair', 'Resistance (Ohm)']) - f.write(df.to_string()) - f.write("\n\n") diff --git a/hp4155/memristor (Version 4.0)/help_pulse.py b/hp4155/memristor (Version 4.0)/help_pulse.py index dac0bb619e6e5c0ece49eeeb5a7c0bd252e2265e..522c6e6fac1ebc203fd46a9bc0169c4a7c7702a6 100644 --- a/hp4155/memristor (Version 4.0)/help_pulse.py +++ b/hp4155/memristor (Version 4.0)/help_pulse.py @@ -36,7 +36,7 @@ def check_pulse(dictionary): #sweep pulse measurement -def sweep_meas(dict,device): +def sweep_meas(dictionary,device): smu_v = device.smu_dict() smu_ground = device.smu_dict() parameters = device.var1_dict() @@ -55,14 +55,14 @@ def sweep_meas(dict,device): ) parameters.update( mode ='SING', - start = dict['start'].value, - stop = dict['stop'].value, - step = dict["stop"].value-dict["start"].value)/(dict["pulses"].value-1, #define the number of steps given specific pulses - comp = dict["comp"].value, + start = dictionary['start'].value, + stop = dictionary['stop'].value, + step = (dictionary["stop"].value-dictionary["start"].value)/(dictionary["pulses"].value-1), #define the number of steps given specific pulses + comp = dictionary['comp'].value, pcomp = 0, - base = dict["base"].value, - width = dict["width"].value, - period= dict["period"].value + base = dictionary["base"].value, + width = dictionary["width"].value, + period= dictionary["period"].value ) device.smu_disable(1) device.smu_disable(3) @@ -81,7 +81,7 @@ def sweep_meas(dict,device): device.setup_pulse(parameters) - device.integration_time(dict["integration"].value) + device.integration_time(dictionary["integration"].value) t0 = time.time() device.single_measurement() @@ -98,7 +98,7 @@ def sweep_meas(dict,device): R_i = np.divide(V_i,I_i) - expected_time = dict["period"].value*dict["pulses"].value + expected_time = dictionary["period"].value*dictionary["pulses"].value times = (elapsed_time,expected_time) values = (V_i,I_i,R_i) @@ -157,7 +157,7 @@ def save_sweep(folder,sample_dict,values,times,sweep_dict): f.write(df.to_string()) f.write("\n\n\n") -def constant_meas(dict,device): +def constant_meas(dictionary,device): smu_v = device.smu_dict() smu_ground = device.smu_dict() sweep_params = device.var1_dict() @@ -185,17 +185,17 @@ def constant_meas(dict,device): mode ='SING', start = 0, stop = 10, - step = 10/(dict["pulses"].value-1, #define the number of steps given specific pulses + step = 10/(dictionary["pulses"].value-1), #define the number of steps given specific pulses comp = 0.1, pcomp = 0, - base = dict["base"].value, - width = dict["width"].value, - period= dict["period"].value + base = dictionary["base"].value, + width = dictionary["width"].value, + period= dictionary["period"].value ) #the constant smu cons = { - 'value':dict["voltage"].value, - 'comp':dict["comp"].value + 'value':dictionary["voltage"].value, + 'comp':dictionary["comp"].value } device.measurement_mode("SWE") @@ -217,7 +217,7 @@ def constant_meas(dict,device): device.range_mode(3,"AUTO") - device.integration_time(dict["integration"].value) + device.integration_time(dictionary["integration"].value) device.variables_to_save(['@INDEX','V2','I2','R']) @@ -236,7 +236,7 @@ def constant_meas(dict,device): R_i = device.return_values('R') - expected_time = dict["period"].value*dict["pulses"].value + expected_time = dictionary["period"].value*dictionary["pulses"].value times = (elapsed_time,expected_time) values = (V_i,I_i,R_i) diff --git a/hp4155/memristor (Version 4.0)/memristor.py b/hp4155/memristor (Version 4.0)/memristor.py index 657ec6c443ec96916144c95d5e0ca72fb3c0109a..a42129e8b83fa53ccf0bf7d6929132d0f9c9413d 100644 --- a/hp4155/memristor (Version 4.0)/memristor.py +++ b/hp4155/memristor (Version 4.0)/memristor.py @@ -197,18 +197,22 @@ def on_contact_check_clicked(b): with output: clear_output(wait = True) change_state(all_widgets) + device.inst.lock_excl() filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" file = os.path.join(folder,filename) R = regular_contact_check(device) - save_contact_check(R,temp_file) + date = str(datetime.today().replace(microsecond=0)) + title = [f"Full Contact Check ({qcc_select.value}) at {date}"] + write_to_file(temp_file,title,R) #upload results temp_file,file,folder=upload_results(temp_file,file,folder) information_box("Contact Check Completed") + device.inst.unlock() change_state(all_widgets) @@ -217,29 +221,34 @@ def on_qcc_clicked(b): with output: clear_output(wait = True) change_state(all_widgets) + device.inst.lock_excl() filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" file = os.path.join(folder,filename) - - + device.inst.lock_excl() + if qcc_select.value == 'EBL': R = EBL(device) else: # OL - R = OL(device) + R = OL(device) #df - save_contact_check(R,temp_file) + date = str(datetime.today().replace(microsecond=0)) + title = [f"Quick Contact Check ({qcc_select.value}) at {date}"] + write_to_file(temp_file,title,R) #upload results temp_file,file,folder=upload_results(temp_file,file,folder) information_box("Quick Contact Check Completed") + device.inst.unlock() + change_state(all_widgets) def on_set_button_clicked(b): - global first,folder,file,temp_file + global folder,temp_file with output: #disable buttons change_state(all_widgets) @@ -247,8 +256,6 @@ def on_set_button_clicked(b): filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" file = os.path.join(folder,filename) - device = setup_memristor() - #lock the device device.inst.lock_excl() @@ -268,17 +275,18 @@ def on_set_button_clicked(b): V12,I12 = sweep(0,Vset.value,step.value,CC_vset.value,integration_time.value,device) plot_sweep(V12,I12,'SET') df = create_data_frame(V12,I12) - print(df) + display(df) if sampling.value == True: #do sampling set after set process(10mV) R_mean_after = sampling_check(0.01,device) print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} Ohm") first_sampling = False - - title = f"SET Memristor:"+"\n\n"+f"Set Voltage={Vset.value}V"+"\n"+f"current compliance={CC_vset.value}A"+"\n" + + date = str(datetime.today().replace(microsecond=0)) + title = [f"SET Memristor at {date}",f"Set Voltage={Vset.value}V",f"current compliance={CC_vset.value}A"] if sampling.value == True: - title = title + f"R(Ohm) Before/After"+"\n"+f"{R_mean_before} {R_mean_after}"+"\n" + title.extend([f"R(Ohm) Before/After",f"{R_mean_before} {R_mean_after}"]) write_to_file(temp_file,title,df) #upload results @@ -289,8 +297,6 @@ def on_set_button_clicked(b): #unlock device device.inst.unlock() - - del device change_state(all_widgets) @@ -298,7 +304,6 @@ def on_reset_button_clicked(b): global folder,temp_file with output: change_state(all_widgets) - device = setup_memristor() filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" file = os.path.join(folder,filename) @@ -322,25 +327,28 @@ def on_reset_button_clicked(b): V34,I34 = sweep(0,Vreset.value,step.value,CC_vreset.value,integration_time.value,device) plot_sweep(V34,I34,'RESET') df = create_data_frame(V34,I34) - print(df) + display(df) if sampling.value == True: #do sampling set after reset process(100mV) R_mean_after = sampling_check(-0.01,device) print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} Ohm") first_sampling = False - - title =f"RESET Memristor:"+"\n\n"+f"Reset Voltage={Vreset.value}V"+"\n"+f"current compliance={CC_vreset.value}A"+"\n" + + date = str(datetime.today().replace(microsecond=0)) + title =[f"RESET Memristor at {date}",f"Reset Voltage={Vreset.value}V",f"current compliance={CC_vreset.value}A"] if sampling.value == True: - title = title + f"R(Ohm) Before/After"+"\n"+f"{R_mean_before} {R_mean_after}"+"\n" + title.extend([f"R(Ohm) Before/After",f"{R_mean_before} {R_mean_after}"]) write_to_file(temp_file,title,df) #Quick Contact Check after reset Process if auto_qcc.value == True: if qcc_select.value == 'EBL': - R=EBL() + R=EBL(device) else: # OL - R=OL() - save_contact_check(R,temp_file) + R=OL(device) + + title = [f"Automatic Quick Contact Check({qcc_select.value}) after Reset"] + write_to_file(temp_file,title,R) #upload results temp_file,file,folder=upload_results(temp_file,file,folder) @@ -351,8 +359,6 @@ def on_reset_button_clicked(b): #unlock device device.inst.unlock() - del device - change_state(all_widgets) def on_full_button_clicked(b): @@ -363,8 +369,6 @@ def on_full_button_clicked(b): filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" file = os.path.join(folder,filename) - device= setup_memristor() - # lock device device.inst.lock_excl() @@ -372,31 +376,11 @@ def on_full_button_clicked(b): #check values valid = check_values(step.value,Vset.value,Vreset.value) - - #during first button press - if first == True and valid == True: - #disable checkboxes, text fields etc. - change_state(information) - filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" - file = os.path.join(folder,filename) - #write header to temp_file - write_header(temp_file,sample_series,field,DUT) - first = False #set first to false irrelvant if it is in the if statement or not - + date = str(datetime.today().replace(microsecond=0)) if valid == True: with open(temp_file,'a') as f: - f.write(f"{number.value} full sweeps with parameters:") - f.write("\n") - f.write(f"Set Voltage = {Vset.value}V") - f.write("\n") - f.write(f"Current compliance set = {CC_vset.value}A") - f.write("\n") - f.write(f"Reset Voltage = {Vreset.value}V") - f.write("\n") - f.write(f"Current compliance reset = {CC_vreset.value}A") - f.write("\n\n") - + header =[f"{number.value} full sweeps with parameters:",f"Set Voltage = {Vset.value}V",f"Current compliance set = {CC_vset.value}A",f"Reset Voltage = {Vreset.value}V",f"Current compliance reset = {CC_vreset.value}A"] plt.figure().clear() fig, (ax1, ax2) = plt.subplots(2,sharex=True,figsize=(8,6)) #the plots share the same x axis @@ -434,9 +418,9 @@ def on_full_button_clicked(b): #Quick Contact Check after reset Process if auto_qcc.value == True: if qcc_select.value == 'EBL': - R = EBL() + R = EBL(device) else: # OL - R = OL() + R = OL(device) #no reason to do check at the end because the next loop will do that(not anymore) more sampling checks @@ -452,15 +436,19 @@ def on_full_button_clicked(b): #create data frame and save to file df = create_data_frame(V,I) - f.write(f"{i+1} Iteration") - f.write("\n") + if i == 0 : + header.extend([f"{i+1} Iteration"]) + title = header.copy() + else: + title = [f"{i+1} Iteration"] if sampling.value == True: - f.write(f"R(Ohm) INIT/SET/RESET"+"\n"+f"{R_mean_init} {R_mean_set} {R_mean_reset}"+"\n") - f.write(df.to_string()) - f.write("\n\n") + title.extend([f"R(Ohm) INIT/SET/RESET",f"{R_mean_init} {R_mean_set} {R_mean_reset}"]) + write_to_file(temp_file,title,df) + if auto_qcc.value == True: - save_contact_check(R,temp_file) + title= [f"Quick Contact Check({qcc_select.value}) after Reset"] + write_to_file(temp_file,title,R) #plot results @@ -472,7 +460,7 @@ def on_full_button_clicked(b): clear_output() display(fig) #plt.show() - print(df) + display(df) #check for loop termination if stop == True: @@ -508,14 +496,13 @@ def on_full_button_clicked(b): #unlock the device device.inst.unlock() - del device change_state(all_widgets) #new_folder clicked def on_new_folder_button_clicked(b): - global folder,file,first + global folder with output: change_state(all_widgets) @@ -524,12 +511,11 @@ def on_new_folder_button_clicked(b): change_state(all_widgets) def on_retention_button_clicked(b): - global first,folder,file,temp_file + global folder,temp_file with output: change_state(all_widgets) - device = setup_memristor() device.inst.lock_excl() @@ -542,7 +528,8 @@ def on_retention_button_clicked(b): t,R=retention(Vretention.value,period.value,duration.value,device) plot_retention(t,R) df=create_retention_data_frame(t,R) - title =f"Retention Memristor:"+"\n\n"+f"Voltage={Vretention.value}V"+"\n"+f"period={period.value}s"+"\n"+f"duration={duration.value}s"+"\n" + date = str(datetime.today().replace(microsecond=0)) + title =[f"Retention Memristor at {date}",f"Voltage={Vretention.value}V",f"period={period.value}s",f"duration={duration.value}s"] write_to_file(temp_file,title,df) #upload results @@ -551,8 +538,6 @@ def on_retention_button_clicked(b): information_box("Measurement finished!") device.inst.unlock() - - del device change_state(all_widgets) diff --git a/hp4155/memristor (Version 4.0)/memristor_buttons.ipynb b/hp4155/memristor (Version 4.0)/memristor_buttons.ipynb index 401a656da1e768e91d368de3f70899a4c0dacfd4..35144fd932d90c50c0415d4c3491613b50724fcd 100644 --- a/hp4155/memristor (Version 4.0)/memristor_buttons.ipynb +++ b/hp4155/memristor (Version 4.0)/memristor_buttons.ipynb @@ -3,13 +3,13 @@ { "cell_type": "code", "execution_count": 1, - "id": "df99f5a2-80af-4892-8633-33177239e444", + "id": "7611a98c-c1cf-46cb-bdd9-fd3dc6a1f53c", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "45a61bab685e4422bbe94514a2439059", + "model_id": "e907a7767009491da92ac730cb310874", "version_major": 2, "version_minor": 0 }, @@ -23,7 +23,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "11da2c8be6de4612a31f3a065e50bc66", + "model_id": "3ebd085796c54e8daaac92ddf5309393", "version_major": 2, "version_minor": 0 }, @@ -37,7 +37,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "0d1ba2ede27742c3aa2cd2b8ec3f50c8", + "model_id": "90dc92bfe8374348bc680caf722f494e", "version_major": 2, "version_minor": 0 },