From 92d185d128839e0ab591aa3237b4a065cc89ba74 Mon Sep 17 00:00:00 2001
From: unknown <asoalexandros@gmail.com>
Date: Mon, 25 Nov 2024 13:06:06 +0100
Subject: [PATCH] changes memrsistor 1-6

---
 hp4155/memristor (Version 4.0)/help.py      | 168 +++++++++++++++++---
 hp4155/memristor (Version 4.0)/memristor.py | 117 +++++++++++---
 2 files changed, 239 insertions(+), 46 deletions(-)

diff --git a/hp4155/memristor (Version 4.0)/help.py b/hp4155/memristor (Version 4.0)/help.py
index 96851a5..4421447 100644
--- a/hp4155/memristor (Version 4.0)/help.py	
+++ b/hp4155/memristor (Version 4.0)/help.py	
@@ -30,9 +30,11 @@ import os
 
 
 #these are the quick sampling checks 
-def test_contacts():
+def regular_contact_check():
     device = module.HP4155a('GPIB0::17::INSTR')
 
+    resistances = {}
+
     smu = [1,2,3,4]
     for i in range(1,4): # iterate through smus 1-4
         for j in range(4,i,-1): 
@@ -82,12 +84,128 @@ def test_contacts():
             V = device.return_data(f'V{i}')
             I = device.return_data(f'I{i}')
             R = V[0]/I[0]
-            print(f"R{i}{j}:{R} Ohm")
+            print(f"R{i}{j}:{'{:.2e}'.format(R)} Ohm")
+            resitances[f"{i}-{j}"] = R
             #print(f"Contact check of smu{i} and smu{j} failed!")
     
     del device
+    return resistances
+
+def EBL():
+    # EBL are SMUs 1-4 and 2-3
+    device = module.HP4155a('GPIB0::17::INSTR')
+    resistances = {}
+
+    for i,j in zip(range(1,3),range(4,2,-1)): #loop simultaneously 1-4,2-3 pairs
+        device.reset()
+    
+        device.measurement_mode('SAMP')
+        device.sampling_mode('LIN')
+        device.number_of_points(1)
+        device.integration_time('MED')
+        device.initial_interval(2e-3)
+        device.filter_status('OFF')
+        #remove total sampling time
+        device.auto_sampling_time('ON')
+        
+        #disable vmus and vsus
+        device.disable_vsu(1)
+        device.disable_vsu(2)
+        device.disable_vmu(1)
+        device.disable_vmu(2)
+    
+        
+    
+        device.smu_mode_meas(i,'V') #one smu is measuring
+        device.smu_mode_meas(j,'COMM') #one smu is ground
+    
+        #set voltage and compliance
+        device.constant_smu_sampling(i,0.01)
+        device.constant_smu_comp(i,'MAX')
+    
+        #smus to remove
+        smu_disable = smu.copy()
+        smu_disable.remove(i)
+        smu_disable.remove(j)
+    
+        for number in smu_disable:
+             device.smu_disable_sweep(number)
+    
+        device.display_variable('X','@TIME')
+        device.display_variable('Y1',f'I{i}')
+        device.single_measurement()
+        while device.operation_completed() == False:
+            time.sleep(2)
+                   
+        device.autoscaling()
+        V = device.return_data(f'V{i}')
+        I = device.return_data(f'I{i}')
+        R = V[0]/I[0]
+        print(f"R{i}{j}:{'{:.2e}'.format(R)} Ohm")
+        resitances[f"{i}-{j}"] = R
+        
+    del device
+    return resistances
+    
+
+def OL():
+    # OL smu 3-4,1-2
+
+    device = module.HP4155a('GPIB0::17::INSTR')
+    resistances= {}
+
+    for i,j in zip(range(3,0,-2),range(4,1,-2)): #loop simultaneously 3-4 , 1-2 pairs
+        device.reset()
+    
+        device.measurement_mode('SAMP')
+        device.sampling_mode('LIN')
+        device.number_of_points(1)
+        device.integration_time('MED')
+        device.initial_interval(2e-3)
+        device.filter_status('OFF')
+        #remove total sampling time
+        device.auto_sampling_time('ON')
+        
+        #disable vmus and vsus
+        device.disable_vsu(1)
+        device.disable_vsu(2)
+        device.disable_vmu(1)
+        device.disable_vmu(2)
+    
+        
+    
+        device.smu_mode_meas(i,'V') #one smu is measuring
+        device.smu_mode_meas(j,'COMM') #one smu is ground
     
+        #set voltage and compliance
+        device.constant_smu_sampling(i,0.01)
+        device.constant_smu_comp(i,'MAX')
+    
+        #smus to remove
+        smu_disable = smu.copy()
+        smu_disable.remove(i)
+        smu_disable.remove(j)
+    
+        for number in smu_disable:
+             device.smu_disable_sweep(number)
+    
+        device.display_variable('X','@TIME')
+        device.display_variable('Y1',f'I{i}')
+        device.single_measurement()
+        while device.operation_completed() == False:
+            time.sleep(2)
+                   
+        device.autoscaling()
+        V = device.return_data(f'V{i}')
+        I = device.return_data(f'I{i}')
+        R = V[0]/I[0]
+        print(f"R{i}{j}:{'{:.2e}'.format(R)} Ohm")
+        resitances[f"{i}-{j}"] = R
+        
+    del device
+    return resistances
 
+    
 
 #double sweep from start to stop and then from start to stop
 def sweep(start,stop,step,comp,integration,device):
@@ -146,6 +264,7 @@ def sweep(start,stop,step,comp,integration,device):
 
 #sampling check
 def sampling_check(voltage,device):
+    # red color code red = '\033[91m'
     
     device.measurement_mode('SAMP')
     
@@ -158,7 +277,7 @@ def sampling_check(voltage,device):
 
     device.sampling_mode('LIN')
     device.number_of_points(5)
-    device.integration_time('MED')
+    device.integration_time('LONG')
     device.initial_interval(2e-3)
     device.filter_status('OFF')
 
@@ -370,26 +489,6 @@ def choose_folder():
     root.destroy()
     return folder
 
-
-
-#create or append to file a new measurement(now locally) we dont need that anymore!!!
-def create_remote_file(sample_series,field,DUT,folder):
-    filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
-    file=os.path.join(folder,filename)#the whole file with location
-    date = str(datetime.today().replace(microsecond=0))
-    
-    #check loop (once the return is called the function is over)
-    while True:
-        try:#you cannot write in every directory
-            with open(file,'a') as f:
-                title = f"Memristor Measurement"+"\n\n"+f"Sample series:{sample_series.value}" +"\n"+f"field:{field.value}"+"\n"+f"DUT:{DUT.value}"+"\n"+f"Date:{date}"+"\n\n"
-                f.write(title)
-            return file
-        except:
-            information_box(f"You cannot write in the directory: {folder}!")
-            #again
-            folder=choose_folder()
-            file=os.path.join(folder,filename)#the whole file with location
         
 
 #write the header
@@ -440,4 +539,25 @@ def setup_memristor():
     # R user function
     device.user_function('R','OHM','V2/I2')
 
-    return device            
\ No newline at end of file
+    return device
+
+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("\n\nContact Check Results:\n")
+
+        df = pd.DataFrame(R.items(), columns=['SMU pair', 'Resistance (Ohm)'])
+        f.write(df.to_string())
+        f.write("\n\n")
+    
+
+        
+
+        
+        
+    
\ No newline at end of file
diff --git a/hp4155/memristor (Version 4.0)/memristor.py b/hp4155/memristor (Version 4.0)/memristor.py
index 9b4fc48..094bba7 100644
--- a/hp4155/memristor (Version 4.0)/memristor.py	
+++ b/hp4155/memristor (Version 4.0)/memristor.py	
@@ -87,6 +87,8 @@ full=widgets.Button(description='FULL SWEEP')
 number = widgets.BoundedIntText(value=1,min=1,max=sys.maxsize,step=1,description='full sweeps:',disabled=False) #number of measuremts for the full sweep
 retention_button=widgets.Button(description='RETENTION')
 contact_check =  widgets.Button(description = 'CONTACT CHECK')
+qcc = widgets.Button(description = 'QUICK CONTACT CHECK')
+qcc_select = widgets.RadioButtons(description = 'QCC type:',options = ['EBL','OL'])
 
 
 #parameter boxes
@@ -149,6 +151,12 @@ duration=widgets.BoundedFloatText(
     description='Duration(s):',
 )
 
+auto_qcc = widgets.Checkbox(
+    description = 'Auto QCC after Reset:',
+    style = {'description_width': 'initial'},
+    value = True
+)
+
 #align a button with a checkbox or integer bounded texts horizontaly
 line1 = widgets.HBox([set,Vset,CC_vset])
 line2 = widgets.HBox([reset,Vreset,CC_vreset])
@@ -162,8 +170,8 @@ output = widgets.Output()
 
 #help lists for changing state of the buttons
 information = [sample_series,field,DUT]
-buttons = [set,reset,full,new,new_folder,retention_button,contact_check]
-parameters = [Vset,CC_vset,Vreset,CC_vreset,step,integration_time,number,sampling,Vretention,period,duration]
+buttons = [set,reset,full,new,new_folder,retention_button,contact_check,qcc,qcc_select]
+parameters = [Vset,CC_vset,Vreset,CC_vreset,step,integration_time,number,sampling,Vretention,period,duration,auto_qcc]
 
 #choose folder directory
 folder=choose_folder()
@@ -171,10 +179,9 @@ folder=choose_folder()
 
 #display all at the end
 display(all_text_boxes)
-print()
 
-display(contact_check)
-print()
+hbox = widgets.HBox([contact_check,qcc,qcc_select]) #HBox wirth contact checks
+display(hbox)
 
 cons_widgets,cons_dict = constant_pulse()
 sweep_widgets,sweep_dict = sweep_pulse()
@@ -199,19 +206,73 @@ add_widgets_to_list(sweep_dict,all_widgets)
 """ the above is what happens when the programm starts all the rest have to be written into button trigger functions"""
 
 def on_contact_check_clicked(b):
+    global first,folder,file,temp_file
     with output:
+        global first,folder,file,temp_file
         clear_output(wait = True)
         change_state(all_widgets)
         change_state(buttons)
         change_state(parameters)
 
-        test_contacts()
+        #during first button press
+        if first == True:
+            change_state(information)#disable all widgets that are relevant about the information of the sample
+            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
+
+        R = regular_contact_check()
+
+        save_contact_check(R,temp_file)
+
+
+        #upload results
+        temp_file,file,folder=upload_results(temp_file,file,folder)
 
         information_box("Contact Check Completed")
 
         change_state(all_widgets)
         change_state(buttons)
         change_state(parameters)
+
+def on_qcc_clicked(b):
+    global first,folder,file,temp_file
+    with output:
+        global first,folder,file,temp_file
+        clear_output(wait = True)
+        change_state(all_widgets)
+        change_state(buttons)
+        change_state(parameters)
+
+        #during first button press
+        if first == True:
+            change_state(information)#disable all widgets that are relevant about the information of the sample
+            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
+
+
+        if qcc_select.value == 'EBL':
+            R = EBL()
+        else: # OL
+            R = OL()
+
+        save_contact_check(R,temp_file)
+
+
+        #upload results
+        temp_file,file,folder=upload_results(temp_file,file,folder)
+
+        information_box("Quick Contact Check Completed")
+
+        change_state(all_widgets)
+        change_state(buttons)
+        change_state(parameters)
+        
         
 def on_set_button_clicked(b):
     global first,folder,file,temp_file
@@ -242,9 +303,8 @@ def on_set_button_clicked(b):
 
         if valid == True:
             if sampling.value == True: #do sampling set before set process(100mV)
-                R_mean_before = sampling_check(0.1,device)
-                R_mean_before = round(R_mean_before,1)#round 1 decimal point
-                print(f"Average Resistance(Sampling Check):{R_mean_before:e} Ohm")
+                R_mean_before = sampling_check(-0.01,device)
+                print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_before)} Ohm")
                 first_sampling = False
                
             #execute measurement,plot results and save them
@@ -256,8 +316,7 @@ def on_set_button_clicked(b):
 
             if sampling.value == True: #do sampling set after set process(10mV)
                 R_mean_after = sampling_check(0.01,device)
-                R_mean_after = round(R_mean_after,1)
-                print(f"Average Resistance(Sampling Check):{R_mean_after:e} Ohm")
+                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"
@@ -310,8 +369,7 @@ def on_reset_button_clicked(b):
         if valid == True:
             if sampling.value == True: #do sampling set before reset process(10mV)
                 R_mean_before = sampling_check(0.01,device)
-                R_mean_before = round(R_mean_before,1)#round 1 decimal point
-                print(f"Average Resistance(Sampling Check):{R_mean_before:e} Ohm")
+                print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_before)} Ohm")
                 first_sampling = False
             
             #execute measurement,plot results and save them
@@ -321,15 +379,22 @@ def on_reset_button_clicked(b):
             print(df)
             
             if sampling.value == True: #do sampling set after reset process(100mV)
-                R_mean_after = sampling_check(0.1,device)
-                R_mean_after = round(R_mean_after,1)
-                print(f"Average Resistance(Sampling Check):{R_mean_after:e} Ohm")
+                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"
             if sampling.value == True:
                 title = title + f"R(Ohm)  Before/After"+"\n"+f"{R_mean_before}  {R_mean_after}"+"\n"
             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()
+                else: # OL
+                    R=OL()
+                save_contact_check(R,temp_file)
             
             #upload results
             temp_file,file,folder=upload_results(temp_file,file,folder)
@@ -409,26 +474,30 @@ def on_full_button_clicked(b):
                 #execute number of measurements
                 for i in range(number.value):#here it is easier to implement the sampling checks
                     if sampling.value == True: #before set(100mv)
-                        R_mean_init = sampling_check(0.1,device)
-                        R_mean_init = round(R_mean_init,1)
+                        R_mean_init = sampling_check(-0.01,device)
                         resistances.append(R_mean_init)
                         
                     V12,I12 = sweep(0,Vset.value,step.value,CC_vset.value,integration_time.value,device) #set
                     
-                    #after set/before set
+                    #after set/before reset
                     if sampling.value == True: #before set(10mv)
                         R_mean_set = sampling_check(0.01,device)
-                        R_mean_set = round(R_mean_set,1)
                         resistances.append(R_mean_set)
                     
                     V34,I34 = sweep(0,Vreset.value,step.value,CC_vreset.value,integration_time.value,device) #reset
 
+                    #Quick Contact Check after reset Process 
+                    if auto_qcc.value == True:
+                        if qcc_select.value == 'EBL':
+                            R = EBL()
+                        else: # OL
+                            R = OL()
+
                     #no reason to do check at the end because the next loop will do that(not anymore) more sampling checks
 
                     #after reset
                     if sampling.value == True:#-0.1V
-                        R_mean_reset = sampling_check(-0.1,device)
-                        R_mean_reset = round(R_mean_reset,1)
+                        R_mean_reset = sampling_check(-0.01,device)
                         resistances.append(R_mean_reset)
 
 
@@ -445,6 +514,9 @@ def on_full_button_clicked(b):
                     f.write(df.to_string())
                     f.write("\n\n")
 
+                    if auto_qcc.value == True:
+                        save_contact_check(R,temp_file)
+
 
                     #plot results
                     ax1.plot(V,I)
@@ -641,3 +713,4 @@ new.on_click(on_new_sample_button_clicked)
 new_folder.on_click(on_new_folder_button_clicked)
 retention_button.on_click(on_retention_button_clicked)
 contact_check.on_click(on_contact_check_clicked)
+qcc.on_click(on_qcc_clicked)
-- 
GitLab