Skip to content
Snippets Groups Projects
Commit 84efb32b authored by Alexandros Asonitis's avatar Alexandros Asonitis
Browse files

pn diode released

parent cd666306
No related branches found
No related tags found
No related merge requests found
import sys
sys.path.insert(0, './lib')
sys.path.insert(0, '..') #append parent directory
import hp4155a
from interface import *
from help import *
sample = sample_information_interface()
parameters_1 = parameters_interface(0,0.02,10,"First Measurement")
parameters_2 = parameters_interface(0,-0.5,-100,"Second Measurement")
button = widgets.Button(description ='Start Measurement')
output = widgets.Output()
display(button,output)
all_widgets = [button]
add_widgets_to_list(sample,all_widgets)
add_widgets_to_list(parameters_1,all_widgets)
add_widgets_to_list(parameters_2,all_widgets)
device = hp4155a.HP4155a('GPIB0::17::INSTR')
setup(device)
def on_button_clicked(b):
with output:
clear_output(wait = True)
change_state(all_widgets)
area=circle_area(sample['radius'].value)
valid = check_values(parameters_1) and check_values(parameters_2)
if valid == True:
df = measure(parameters_1,parameters_2,area,device)
plot_results(df['VS'],df['ABSNOR'])
filename = f"pn_diode_{sample['field'].value}.txt"
file = create_file(filename)
save_to_file(df,sample,parameters_1,parameters_2,file)
change_state(all_widgets)
button.on_click(on_button_clicked)
\ No newline at end of file
%% Cell type:code id:1b607685-438c-466e-9671-140ae6c8d9f9 tags:
``` python
%run diode.py
```
%% Output
%% Cell type:code id:5bc60dda-f423-4cdc-bc39-3404a8cfa1df tags:
``` python
```
hp4155/pn_Diode/lib/diode_smu_configuration.png

6.88 KiB

import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg',force = True)
import numpy as np
import time
from datetime import datetime
import tkinter as tk
from tkinter import filedialog
import tkinter.messagebox
import pandas as pd
#returns area in cm^2
def circle_area(radius):
#input is in um
radius = radius*10**(-6) #m^2
area = np.pi*radius**2 # m^2
area = area * 10**4 # cm^2
return area
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
#saving functions : save parameters and dataframe to txt
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
answer = tk.messagebox.askyesno(message = "Do you want to cancel the file operation?")
if answer == True:
file = None
break
file = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files","*.txt")],title = "save results path",initialfile =filename)
root.destroy()
return file
def check_values(parameters):
valid = True
root = tk.Tk()
root.withdraw()
root.lift() #show window above all other applications
root.attributes("-topmost", True)#window stays above all other applications
#get better variable names
start = parameters['start']
stop = parameters['stop']
step = parameters['step']
#check values
if abs(step.value) > abs(stop.value-start.value) or step.value==0:#invalid parameter setting
valid = False
tkinter.messagebox.showerror(message="Invalid parameter setting!")
if start.value<stop.value and step.value<0: #change polarity
step.value =(-1)*step.value
elif start.value>stop.value and step.value>0:
step.value = (-1)*step.value
else:
pass
root.destroy()
return valid
#Setup The device for diode measurement
def setup(device):
device.reset()
#setup sweep measurement mode
device.measurement_mode('SWE')
#disable all irrelevant units
device.disable_not_smu()
#disable smu 2 and 4
device.smu_disable(2)
device.smu_disable(4)
smu1 = device.smu_dict()
smu1.update(vname ='VGND',iname = 'IGND',mode = 'COMM',func='CONS')
smu3 = device.smu_dict()
smu3.update(vname='VS',iname='IS',mode ='V',func='VAR1')
device.setup_smu(1,smu1)
device.setup_smu(3,smu3)
def measure(parameters_1,parameters_2,area,device):
#del all user functions
device.del_user_functions()
#define user functions
device.user_function("AREA",'CM^2',str(area))
device.user_function("INORM",'A/CM^2','IS/AREA')
device.user_function("ABSNOR","A/CM^2","ABS(INORM)")
device.user_function("ABSRAW",'A','ABS(IS)')
var1 = device.var1_dict()
var1.update(
mode = parameters_1['hyst'].value,
start = parameters_1['start'].value,
stop = parameters_1['stop'].value,
step = parameters_1['step'].value,
comp = parameters_1['comp'].value,
pcomp = 0
)
device.setup_var1(var1)
device.integration_time(parameters_1['integration'].value)
#display
device.display_variable('X','VS')
device.display_variable('Y1','ABSNOR')
device.axis_scale('Y1','LOG')
if parameters_1['start'].value < parameters_1['stop'].value:
device.display_variable_min_max('X','MIN',parameters_1['start'].value)
device.display_variable_min_max('X','MAX',parameters_1['stop'].value)
else:
device.display_variable_min_max('X','MAX',parameters_1['start'].value)
device.display_variable_min_max('X','MIN',parameters_1['stop'].value)
if parameters_1['comp'].value !=0:
device.display_variable_min_max('Y1','MIN',0)
device.display_variable_min_max('Y1','MAX',abs(parameters_1['comp'].value)/area)
variables_list = ['VS','IS','ABSRAW','INORM','ABSNOR']# look at the tool
device.variables_to_save(variables_list)
device.single_measurement()
while device.operation_completed() == False:
pass
device.autoscaling()
# Start Second measurement
var1.update(
mode = parameters_2['hyst'].value,
start = parameters_2['start'].value,
stop = parameters_2['stop'].value,
step = parameters_2['step'].value,
comp = parameters_2['comp'].value,
pcomp = 0
)
device.setup_var1(var1)
device.integration_time(parameters_2['integration'].value)
if parameters_2['start'].value < parameters_2['stop'].value:
device.display_variable_min_max('X','MIN',parameters_2['start'].value)
device.display_variable_min_max('X','MAX',parameters_2['stop'].value)
else:
device.display_variable_min_max('X','MAX',parameters_2['start'].value)
device.display_variable_min_max('X','MIN',parameters_2['stop'].value)
if parameters_2['comp'].value !=0:
device.display_variable_min_max('Y1','MIN',0)
device.display_variable_min_max('Y1','MAX',abs(parameters_2['comp'].value)/area)
device.append_measurement()
while device.operation_completed() == False:
pass
device.autoscaling()
values = dict([(variable,device.return_values(variable)) for variable in variables_list])
df = pd.DataFrame(values)
df = df.sort_values(by='VS')
return df
def plot_results(x,y):
fig, ax1 = plt.subplots()
color = 'tab:red'
ax1.set_xlabel('Voltage (V)')
ax1.set_ylabel('Current density $(A/{cm}^2)$')
ax1.set_yscale('log')
ax1.plot(x,y, color = color)
ax1.grid(True,linestyle = '--',axis = 'y',color ="k",linewidth = 0.5)
ax1.axvline(linestyle='--',color = 'k',linewidth =0.5)
fig.suptitle('Diode Plot', fontweight ="bold")
fig.tight_layout()
wm = plt.get_current_fig_manager()
wm.window.state('zoomed')
plt.show(block = True)
#also for file
def save_to_file(df,sample,parameters_1,parameters_2,file):
if file != None:
with open(file,'w') as f:
date = str(datetime.today().replace(microsecond=0))
f.write(f"Diode Measurement at {date}"+"\n")
f.write(f"Series:{sample['processing_number'].value}"+"\n")
f.write(f"Sample:{sample['sample'].value}"+"\n")
f.write(f"Field:{sample['field'].value}"+"\n")
f.write(f"Radius/um:{sample['radius'].value}"+"\n\n")
f.write('Parameters of first Measurement\n')
f.write(f"V from {parameters_1['start'].value}V to {parameters_1['stop'].value}V with step {parameters_1['step'].value}V"+"\n")
f.write(f"I Compliance/A:{parameters_1['comp'].value}"+"\n")
f.write(f"Integration Time:{parameters_1['integration'].value}"+"\n")
f.write('\nParameters of second Measurement\n')
f.write(f"V from {parameters_2['start'].value}V to {parameters_2['stop'].value}V with step {parameters_2['step'].value}V"+"\n")
f.write(f"I Compliance/A:{parameters_2['comp'].value}"+"\n")
f.write(f"Integration Time:{parameters_2['integration'].value}"+"\n")
f.write("\nResults\n")
#create pandas dataframe
#df =df.drop(columns=['ABSNOR'])
df =df.rename(columns={'VS':'VS/V','IS':'IRAW/A','ABSRAW':'ABSRAW/A','INORM':'INORM/A/CM^2','ABSNOR':'ABSNOR/A/CM^2'})
df.to_csv(file,sep= " ",mode = 'a')
\ No newline at end of file
import ipywidgets as widgets
from ipywidgets import GridspecLayout,Layout
from IPython.display import clear_output,display
import sys
import os
style = {'description_width': 'initial'}
def parameters_interface(start,step,stop,title):
grid = GridspecLayout(5,4)
grid[0,:]=widgets.Label(title,layout=Layout(height='auto', width='auto'))
grid[0,:].style.font_weight='bold'
#first line
grid[1,0]=widgets.Label("Start(V)",layout=Layout(height='auto', width='auto'))
grid[1,1]=widgets.Label("Step(V)",layout=Layout(height='auto', width='auto'))
grid[1,2]=widgets.Label("Stop(V)",layout=Layout(height='auto', width='auto'))
#second line
grid[2,0]=widgets.BoundedFloatText(value=start,min=-100,max=100,step=1,layout=Layout(height='auto', width='auto'))
grid[2,1]=widgets.BoundedFloatText(value=step,min=-200,max=200,step=1,layout=Layout(height='auto', width='auto'))
grid[2,2]=widgets.BoundedFloatText(value=stop,min=-100,max=100,step=1,layout=Layout(height='auto', width='auto'))
#third line
grid[3,0]=widgets.Label("Compliance(A)",layout=Layout(height='auto', width='auto'))
grid[3,1] =widgets.Label("Integration Time",layout=Layout(height='auto', width='auto'))#mind the gap
grid[3,2] =widgets.Label("Hysterisis",layout=Layout(height='auto', width='auto'))#mind the gap
#fourth line
grid[4,0]=widgets.BoundedFloatText(value=0.01,min=-0.1,max=0.1,step=0.01,layout=Layout(height='auto', width='auto'))
grid[4,1]=widgets.Dropdown(options=["SHORt","MEDium","LONG"],value="MEDium",style =style,layout=Layout(height='auto', width='auto'))
grid[4,2]=widgets.Dropdown(options=['SINGle','DOUBle'],value='SINGle',layout=Layout(height='auto', width='auto'))#mind the gap
parameters = {
'start': grid[2,0],
'step': grid[2,1],
'stop': grid[2,2],
'comp': grid[4,0],
'hyst':grid[4,2],
'integration':grid[4,1]
}
display(grid)
return parameters
def sample_information_interface():
sample_information=widgets.Label("Sample Information",layout=Layout(height='auto', width='auto'))
sample_information.style.font_weight='bold'
information_grid=GridspecLayout(3,2)
for i in range(3):
for j in range(2):
if i ==2 and j == 1:
pass
elif i == 2 and j == 0: #look at the tool for diode area
information_grid[i,j]=widgets.BoundedFloatText(
value=50,
min=1,
max=200,step=1,
layout=Layout(height='auto', width='auto')
)
else:
information_grid[i,j]=widgets.Text(layout=Layout(height='auto', width='auto'))
information_grid[0,0].description = "Processing-Nr:"
information_grid[1,0].description = "Sample:"
information_grid[2,0].description = "Radius(um):"
information_grid[0,1].description = "Field(XYY):"
information_grid[1,1].description = "Device:"
information_grid[1,1].disabled = True
for i in range(3):
for j in range(2):
try:
information_grid[i,j].style = style
except:
pass
image_title = widgets.Label("SMU Configuration",layout=Layout(height='auto', width='auto'))
image_title.style.font_weight='bold'
filename = os.getcwd()+r"\lib\diode_smu_configuration.png"
#print(filename)
file = open(filename, "rb")
image = file.read()
image_widget =widgets.Image(
value = image,
format='png',
width='auto',
height='auto',
)
vbox1 =widgets.VBox([sample_information,information_grid])
vbox2 =widgets.VBox([image_title,image_widget])
display(widgets.HBox([vbox1,vbox2]))
information = {
'processing_number': information_grid[0,0],
'sample' : information_grid[1,0],
'field': information_grid[0,1],
'radius': information_grid[2,0],
}
return information
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment