import os
import time
time_record = time.strftime("%Y-%m-%d %H-%M-%S")
all_folder_list = []
temperature = '25C'
picMerge = False # 如果有多组数据,是否放在一起显示
# =============================================================================
'''下面两项记录点数和wafer ID,需要匹配实际情况'''
Idsat_vop_multify = 1 # IDsat多少倍
waferListfordict = ['A0A1021.04_ISN30_CV_W23_','A0A1021.04_ISN30_CV_W24_','A0A1021.04_ISN30_CV_W25_'] # 测了哪几片
sitePerWafer = 2 # 每片wafer对应几个点
allsite = [i for i in range(1,sitePerWafer+1)]
#allsite = [i for i in range(1,len(waferListfordict)*sitePerWafer+1)]
def siteSort(waferListfordict,sitePerWafer):
site_waferList = dict()
siteToAppend = 1
waferNO = 0
for wafer in waferListfordict:
for i in range(sitePerWafer):
site_waferList[siteToAppend] = waferListfordict[waferNO]
siteToAppend+=1
waferNO += 1
return site_waferList
site_waferList = siteSort(waferListfordict,sitePerWafer)
_putvalue = False # 是否需要把值显示到图片上
if not _putvalue and picMerge is True:
putvalue = False if len(allsite) == 1 else True
elif _putvalue:
putvalue = True
else:
putvalue = False
'''初始化输出值文件的参数列表'''
BV_list = [0]
Idsat_list = [0]
Id_mid_list = [0]
Id_rise_list = [0]
Vtlin_list = [0]
Idlin_list = [0]
Rsp_list = [0]
Id_off_list = [0]
Vtgm_list = [0]
#def search_rename(file_path):
#
#
# global all_folder_list
#
# files = os.listdir()
#
#
# if len(files):#如果不是空文件夹
#
#
# all_folder_list.append(file_path)
#
# for file in files:
#
# if '.' in file and '.23' not in file:
#
## files.pop(files.index(file))
# pass
#
# else:
#
# os.chdir(file_path + '\\' + file)
# search_rename(os.getcwd())
#
# os.chdir(file_path)
# else:#如果是空文件夹
# pass
#import pyautogui
#import random
#def moveRel():
# pyautogui.FAILSAFE = False
# x = random.randint(-100,100)
# y = random.randint(-100,100)
# pyautogui.moveRel(x,y)
import sys
import pandas as pd
import numpy as np
from numpy import diff
import xlsxwriter
import shutil
#import tkinter as tk
#import tkinter.filedialog
#from matplotlib.pyplot import FuncFormatter
#import random
# 使用该魔法,不用写plt.show(),以及可以边写边运行
import matplotlib.pyplot as plt
#plt.rcParams['font.sans-serif']=['Times New Roman'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
fonts = 'Arial'
fig_size = (5/0.618,5)
outputFileDir = os.getcwd()
#创建选择窗口
#window = tk.Tk()
#window.title("MyWindow")
#window.geometry("1000x100")
##定义一个label
#var = tk.StringVar()
#l = tk.Label(window,
# textvariable=var,
# bg='green',
# font=('Arial', 12),
# width=100,
# height=2
# )
#l.pack()
#字符显示
#on_hit = False
#file_name = ""
#图片格式修改
def ax_style(ax):
ax.grid(True, linestyle='-.') # 网格
ax.tick_params(axis='x',labelcolor='k', labelsize='medium', width=3)
ax.tick_params(axis='y',labelcolor='k', labelsize='medium', width=2)
ax = plt.gca() # 获取当前图像的坐标轴信息
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.xticks(fontsize=15, family =fonts)
plt.yticks(fontsize=15, family =fonts)
def plot_curve_BV(Vd, Id, mos_type, abs_ioff_volts, Width=23.4, lgd_basic="lgd"): # 用数据画图
df = pd.concat([Vd,Id],axis=1)
df.rename(columns={Vd.name:"Vd", Id.name:"Id"}, inplace=True)
if mos_type == "N":
mode = 1
if mos_type == "P":
mode = -1
df = mode*df
df.Vd = df.Vd
# df = df.loc[df.Id>-1E-11].loc[df.Id<1]
df = df.loc[df.Id>-1E-11]
a = len(df)-1
for i in range(len(df)-1):
if df.iloc[i].Id - df.iloc[i+1].Id > 1E-8 and df.iloc[i+1].Id < 1E-8: # Id掉下去的情形
a = i
break
if a != len(df)-1: # Id掉下去的情形
BV = mode * df.iloc[a].Vd # 如果电流没有达到,就取最大值
# df = df.iloc[:a]
if a == len(df)-1: # Id没有掉下去的情形
BV = mode * df[df.Id <= 1E-8 * Width].Vd.iloc[-1] # 同正常点测的读值
# BV_curve_Vdmax = mode *(BV + 5)
# df = df.loc[df.Vd <= BV_curve_Vdmax]
if BV == 80 and max(df.Id) >= 5E-11: # BV 掉下去的情形
BV = mode * df.loc[df.Id==max(df.Id)].Vd.iloc[-1]
# df = df.iloc[:a]
df = df.loc[df.Vd>-1000].loc[df.Vd<1000]
print(BV)
BV_list.append(BV) ########################################
Id_off_list.append(mode * 1E12 * df.loc[df.Vd<=abs_ioff_volts].iloc[-1].Id/Width)
if putvalue:
lgd = lgd_basic + " BV=" + str(BV)
else:
lgd = "BV"
df = df.loc[df.Vd<100]
df = abs(df)
df = df.loc[df.Id > 4E-13]
# df['Id'] = df['Id'] - min(df['Id'])*0.1 +random.randint(1,6)*5E-14
plt.plot(df.Vd, df.Id, linewidth=3, linestyle='--', marker='o', markersize=5, label=lgd)
def BV_curve_plot(folder_name,strip_name, sites):
fig, ax1 = plt.subplots(nrows=1, ncols=1,sharex=True,figsize=fig_size)
os.chdir(folder_org)
os.chdir(strip_name)
for file_name in os.listdir(folder_name):
if "BV" in file_name and ".cv" in file_name:
tk_name,Vop,mos_type,Width,length,title_name,wafer,pitch = file_name_split(file_name)
abs_ioff_volts = 1.1*float(Vop.replace(' ','').replace('V','').replace('D','.').strip(' '))
print(tk_name,Vop,mos_type,Width,title_name,wafer)
print(file_name)
os.chdir(folder_org)
os.chdir(strip_name)
os.chdir(folder_name)
for site_n in sites:
Vd, Id, VG = auto_data_n(file_name, site_n)
if putvalue:
lgdt = site_waferList[site_n] +' s' + str(site_n)+' '
plot_curve_BV(Vd, Id, mos_type, abs_ioff_volts, Width=Width, lgd_basic= lgdt)
else:
plot_curve_BV(Vd, Id, mos_type, abs_ioff_volts, Width=Width, lgd_basic='')
print("plot BV curve")
#绘图格式修改
ax_style(ax1)
plt.yscale('log')
plt.legend(loc='upper left')
'''
loc : int or string or pair of floats, default: 'upper right'
The location of the legend. Possible codes are:
=============== =============
Location String Location Code
=============== =============
'best' 0
'upper right' 1
'upper left' 2
'lower left' 3
'lower right' 4
'right' 5
'center left' 6
'center right' 7
'lower center' 8
'upper center' 9
'center' 10
=============== =============
'''
ax1.set_ylabel('Id(A)', family =fonts, fontsize=16, fontweight='bold')
ax1.set_xlabel('Vd(V)', family =fonts, fontsize=16, fontweight='bold')
# title = wafer + " " + title_name + " BV"
title = title_name + " BV" + " " + temperature
plt.title(title, family =fonts, fontsize=16, fontweight='bold') #标题
plt.ylim(0,1E-2)
fig_output = title_name + f' BV{sites}.jpg'
fig.savefig(fig_output, bbox_inches="tight", pad_inches=0.1, dpi=180)
return fig_output
def plot_curve_IDVD(Vd, Id, mos_type,Vop, Width, lgd_basic="lgd"):
df = pd.concat([Vd,Id],axis=1)
df.rename(columns={Vd.name:"Vd", Id.name:"Id"}, inplace=True)
if mos_type == "N":
mode = 1
if mos_type == "P":
mode = -1
df = mode*df
# df = df.loc[df.Id>-1E-12].loc[df.Id<1]
lgd = lgd_basic
df = df.loc[df.Vd<100].loc[df.Id<1].loc[df.Id>-1]
# if "0V" not in lgd and "1V" not in lgd:
# df = df.loc[df.Id>1E-10]
# Idsat = df.loc[df.Vd<=Vop].iloc[-1].Id/Width
# lgd = lgd + " Vdmax=" + str(df.loc[df.Vd==max(df.Vd)].Vd.iloc[-1]) #ESOA
plt.plot(df.Vd, df.Id/Width*1E6, linewidth=3, linestyle='--', marker='o', markersize=5, label=lgd)
#def formatnum(x,pos):
# return '$%.1f$x$10^{-2}$' % (x*100)
#formatter = FuncFormatter(formatnum)
def IDVD_curve_plot(folder_name,strip_name, sites): # IVn表示需要作几个点的图
IDVD_list = []
fig, ax1 = plt.subplots(nrows=1, ncols=1,sharex=True,figsize=fig_size)
os.chdir(folder_org)
os.chdir(strip_name)
for file_name in os.listdir(folder_name):
if "IDVD" in file_name and ".cv" in file_name:
IDVD_list.append(file_name)
for file_name in IDVD_list:
if '5D5' in file_name:
IDVD_list.remove(file_name)
IDVD_list.append(file_name)
if 'VG6' in file_name: # 去掉6V的点 添加6V的点
IDVD_list.remove(file_name)
IDVD_list.append(file_name)
if "VG-1" in IDVD_list[0] and "VG-2" in IDVD_list[1]:
IDVD_list[0] ,IDVD_list[1] = IDVD_list[1] ,IDVD_list[0]
if "VG0D6" in IDVD_list[0] and "VG0" in IDVD_list[1]:
IDVD_list[0] ,IDVD_list[1] = IDVD_list[1] ,IDVD_list[0]
if "VG1D4" in IDVD_list[2] and "VG1D8" in IDVD_list[3] and "VG1" in IDVD_list[4]:
IDVD_list[2] ,IDVD_list[3] ,IDVD_list[4] = IDVD_list[4] ,IDVD_list[2] ,IDVD_list[3]
for file_name in IDVD_list:
print(file_name)
tk_name,Vop,mos_type,Width,length,title_name,wafer,pitch = file_name_split(file_name)
if mos_type == "N":
mode = 1
elif mos_type == "P":
mode = -1
os.chdir(folder_org)
os.chdir(strip_name)
os.chdir(folder_name)
lgd = file_name.split("_")[1].replace("VG","Vg=").replace('D','.') + "V"
for site_n in sites:
Vd, Id, VG = auto_data_n(file_name, site_n)
if VG==5 or VG==-5:
'''这一段目的是把IDSAT放到图片上'''
if 'VG5' in file_name and 'VG5D' not in file_name:
if len(sites) == 1:
df = pd.concat([Vd,Id],axis=1)
# print(Vop)
Vop = int(float(Vop.replace(' ','').replace('V','').replace('D','.').strip(' ')))
# print(Vop)
Idsat = format(df.loc[df.VD<=Vop].iloc[-1].ID/Width * 1E6,'.1f')
Idsat_list.append(float(Idsat))
elif putvalue is True:
try:
# print(Vop)
df = pd.concat([Vd,Id],axis=1)
Vop = int(float(Vop.replace(' ','').replace('V','').replace('D','.').strip(' ')))
# print(Vop)
Idsat = mode * df.loc[df.VD<=Vop*Idsat_vop_multify].iloc[-1].ID/Width * 1E6
# print(Idsat)
Vd, Id, VG = auto_data_n(file_name, site_n)
lgd += " Idsat=" + str(format(Idsat, '.1f'))
except:
pass
else:
pass
''''''
if VG==1.8 or VG==-1.8:
'''这一段目的是把IDSAT放到图片上'''
if 'VG1D8' in file_name:
if len(sites) == 1:
df = pd.concat([Vd,Id],axis=1)
# print(Vop)
Vop = int(float(Vop.replace(' ','').replace('V','').replace('D','.').strip(' ')))
# print(Vop)
Idsat = format(df.loc[df.VD<=Vop].iloc[-1].ID/Width * 1E6,'.1f')
Idsat_list.append(float(Idsat))
elif putvalue is True:
try:
# print(Vop)
df = pd.concat([Vd,Id],axis=1)
Vop = int(float(Vop.replace(' ','').replace('V','').replace('D','.').strip(' ')))
# print(Vop)
Idsat = mode * df.loc[df.VD<=Vop].iloc[-1].ID/Width * 1E6
# print(Idsat)
Vd, Id, VG = auto_data_n(file_name, site_n)
lgd += " Idsat=" + str(format(Idsat, '.1f'))
except:
pass
else:
pass
''''''
if putvalue is True:
lgdt = site_waferList[site_n] +' s' + str(site_n)+ ' '+ lgd
plot_curve_IDVD(Vd, Id, mos_type,Vop, Width=Width, lgd_basic=lgdt)
else:
plot_curve_IDVD(Vd, Id, mos_type,Vop, Width=Width, lgd_basic=lgd)
#绘图格式修改
# ax1.yaxis.get_major_formatter().set_powerlimits((0,1))#设置科学计数法y坐标,不需要纵坐标除以W时打开
ax_style(ax1)
# plt.yscale('log')
plt.legend(loc='upper left')
ax1.set_ylabel('Id(uA/um)', family =fonts, fontsize=16, fontweight='bold')
ax1.set_xlabel('Vd(V)', family =fonts, fontsize=16, fontweight='bold')
# title = wafer + " " + title_name + " IDVD"
# title = title_name + " IDVD"
title = title_name + " IDVD" + " " + temperature
# title = title_name + " eSOA" + " " + temperature #ESOA
plt.title(title, family =fonts, fontsize=16, fontweight='bold') #标题
# plt.gca().yaxis.set_major_formatter(formatter)
fig_output = title_name + f' IDVD{sites}.jpg'
fig.savefig(fig_output, bbox_inches="tight", pad_inches=0.1, dpi=180)
'''设置坐标轴字体'''
# plt.tick_params(labelsize = 16)
# labels = ax1.get_xticklabels() + ax1.get_yticklabels()
# [labels.set_fontmname('Times New Roman') for label in labels]
#
return fig_output
def VTGM(x,y,mode,num = 3):
dx = x[1]-x[0]
dy = list(diff(y)/dx)
dy_max = dy.index(max(dy))
x_new = x[dy_max-num:dy_max+num+1]
x0 = x_new[num]
y_new = y[dy_max-num:dy_max+num+1]
y0 = y_new[num]
# plt.plot(x,y)
# plt.plot(x_new,y_new,linewidth=10)
# plt.xlim(-1.5,0)
_x = np.array(x_new)
_y = np.array(y_new)
f1 = np.polyfit(_x, _y, 1) # 进行一次拟合
p0 = np.poly1d(f1)
k = p0.deriv(1) # 对拟合曲线求导,返回斜率
k = list(k)[0] # 转换为数字
vtgm = x0-(y0/k)-0.05*mode
# print(vtgm)
return vtgm
def plot_curve_IDVG(Vg, Id, Vd, mos_type, Width, length, pitch, lgd_basic="lgd",sites=allsite):
df = pd.concat([Vg,Id],axis=1) # 横向拼接
df.rename(columns={Vg.name:"Vg", Id.name:"Id"}, inplace=True)
if mos_type == "N":
mode = 1
if mos_type == "P":
mode = -1
df = mode*df
df = df.loc[df.Id>-1E-12].loc[df.Id<1]
lgd = lgd_basic
if Vd==0.1 or Vd==-0.1:
Vtgm = VTGM(x=list(Vg),y=list(Id),mode=mode,num = 3)
Vtlin = float(df.loc[df.Id<Width*1E-7/length].iloc[-1].Vg)
Idlin = float(df.loc[df.Vg<=5].iloc[-1].Id*1E6/Width)
if len(sites) == 1:
Rsp = 0.1/Idlin*float(pitch)*1000
Vtgm = format(Vtgm,'.3f')
Vtlin = format(Vtlin*mode,'.3f')
print(Vtlin)
Rsp = format(float(Rsp),'.2f')
Idlin = format(Idlin*mode,'.3f')
Vtlin_list.append(float(Vtlin))
Idlin_list.append(float(Idlin))
Rsp_list.append(float(Rsp))
Vtgm_list.append(float(Vtgm))
if putvalue is True:
lgd = lgd_basic + " Vtlin= " + str(format(Vtlin, '.3f')) + " Idlin= " + str(format(Idlin, '.3f') + " uA/um")
else:
lgd = "VD=0.1V"
else:
lgd = "VD=VDD"
plt.plot(df.Vg, df.Id, linewidth=3, linestyle='--', marker='o', markersize=5, label=lgd)
xul = 0
def IDVG_curve_plot(folder_name,strip_name, sites):
global xul
fig, ax1 = plt.subplots(nrows=1, ncols=1,sharex=True,figsize=fig_size)
os.chdir(folder_org)
os.chdir(strip_name)
for file_name in os.listdir(folder_name):
if "IDVG" in file_name and ".cv" in file_name:
# print(file_name)
tk_name,Vop,mos_type,Width,length,title_name,wafer,pitch = file_name_split(file_name)
# if "0D1" in file_name:
# Vd=0.1
# else:
# Vd=np.nan
os.chdir(folder_org)
os.chdir(strip_name)
os.chdir(folder_name)
for site_n in sites:
Vg, Id, Vd = auto_data_n(file_name, site_n, x="Vg", y="ID")
xul = 5.5
if putvalue is True:
lgdt = site_waferList[site_n] +' s' + str(site_n)+ ' '
plot_curve_IDVG(Vg, Id, Vd, mos_type, Width=Width, length=length, pitch=pitch, lgd_basic=lgdt,sites=sites)
else:
plot_curve_IDVG(Vg, Id, Vd, mos_type, Width=Width, length=length, pitch=pitch, lgd_basic="",sites=sites)
#绘图格式修改
ax_style(ax1)
plt.yscale('log')
plt.legend(loc='upper left')
ax1.set_ylabel('Id(A)', family =fonts, fontsize=16, fontweight='bold')
ax1.set_xlabel('Vg(V)', family =fonts, fontsize=16, fontweight='bold')
# title = wafer + " " + title_name + " IDVG"
# title = title_name + " IDVG"
title = title_name + " IDVG" + " " + temperature
plt.title(title, family =fonts, fontsize=16, fontweight='bold') #标题
if xul<=2.5:
plt.xlim(xmin=-0.2,xmax=xul+0.2)
else:
plt.xlim(xmin=-0.5,xmax=xul+0.5)
if "N5V_N" in title or "N5V_D" in title or "Depletion" in title:
plt.xlim(xmin=-2,xmax=xul+0.5)
fig_output = title_name + f' IDVG{sites}.jpg'
fig.savefig(fig_output, bbox_inches="tight", pad_inches=0.1, dpi=180)
return fig_output
def auto_data_n(file_name, site_n, x="VD", y="ID"):
i = 1
test_start_lines = []
test_end_lines = []
test_blank_lines = []
VGD_lines = []
f = open(file_name)
for line in f:
if "<TEST_DATA>" in line:
test_start_lines.append(i)
if "\n" is line:
test_blank_lines.append(i)
if "</TEST_END>" in line:
test_end_lines.append(i)
if "VD=" in line or "VG=" in line:
VGD_lines.append(i)
i+=1
f.close()
n=site_n-1
rows_start = test_start_lines[n]
rows_end = test_end_lines[n]
VGD_line = VGD_lines[n]
for num in test_blank_lines:
if num < test_start_lines[n]:
rows_start-=1
rows_end-=1
VGD_line-=1
df = pd.read_table(file_name, header=rows_start, sep=",",nrows=rows_end-rows_start-2)
df_VGD = pd.read_table(file_name, header=VGD_line-1, sep=",",nrows=0)
VGD = float(list(df_VGD.columns)[0].replace("VD=","").replace("VG=","").replace('"',""))
return df[x],df[y],VGD
def file_name_split(file_name):
# tk_name = "_".join(file_name.replace(".cv","").split("_")[-2:])
# file_name = file_name.split("_iso")[0]
# file_name = file_name.split("_Drain")[0]
tk_name = file_name.split("_")[-2]
# tk_name = file_name.split("_")[-2] + "_" +file_name.split("_")[-1].replace(".cv","")
# print(tk_name)
os.chdir(os.path.dirname(sys.argv[0]))
if os.path.isfile('./output.xls') == True:
df = pd.read_excel('./output.xls', header=0)
Vop = " " + str(df.loc[df.TK == tk_name].Volts.iloc[0]) + "V"
mos_type = df.loc[df.TK == tk_name].mos_type.iloc[0]
Width = df.loc[df.TK == tk_name].width.iloc[0]
length = df.loc[df.TK == tk_name].length.iloc[0]
title_name = df.loc[df.TK == tk_name].title.iloc[0]
wafer = df.loc[df.TK == tk_name].wafer.iloc[0]
pitch = df.loc[df.TK == tk_name].pitch.iloc[0]
# print (tk_name,Vop,mos_type,Width,title_name,wafer)
return tk_name,Vop,mos_type,Width,length,title_name,wafer,pitch
else:
raise TypeError
def device_name_read(foldeName):
os.chdir(os.path.dirname(sys.argv[0]))
if os.path.isfile('./output.xls') == True:
df = pd.read_excel('./output.xls', header=0)
title_name = df.loc[df.TK == foldeName].title.iloc[0]
print("device_name_read: ", title_name)
return title_name
def read_Targ(Device):
tk_name = str(Device)
os.chdir(os.path.dirname(sys.argv[0]))
if os.path.isfile('./output.xls') == True:
df = pd.read_excel('./output.xls', header=0)
BV_Targ = df.loc[df.TK == tk_name].BV_Targ.iloc[0]
IDS_Targ = df.loc[df.TK == tk_name].IDS_Targ.iloc[0]
IDL_Targ = df.loc[df.TK == tk_name].IDL_Targ.iloc[0]
VTGM_Targ = df.loc[df.TK == tk_name].VTGM_Targ.iloc[0]
VTL_Targ = df.loc[df.TK == tk_name].VTL_Targ.iloc[0]
RSP_Targ = df.loc[df.TK == tk_name].RSP_Targ.iloc[0]
return BV_Targ,IDS_Targ,IDL_Targ,VTGM_Targ,VTL_Targ,RSP_Targ
else:
raise TypeError
def moveFile(path):
# import shutil
original_path = str(path)
os.chdir(original_path)
all_files = os.listdir()
for file in all_files:
if ".cv" in file:
for strip_name in waferListfordict:
try:
os.mkdir(original_path + '\\' + strip_name)
except:
pass
if strip_name in file:
nameList = file.split('_')#把每个文件名字分开
tk_name = nameList[-2]
try:
os.mkdir(original_path + '\\' + strip_name + '\\'+ tk_name)
except:
pass
try:
shutil.move(original_path + '\\' + file, original_path + '\\' + strip_name + '\\'+ tk_name + '\\' + file.replace(strip_name,""))
print(file, "remove done!")
except:
pass
print('文件归类完成!!!')
#def hit_me():
# global on_hit
## global file_name
# global time
# global BV_list,Idsat_list,Id_mid_list,Id_rise_list,Vtlin_list,Idlin_list,Rsp_list,Id_off_list
def xlscol(num):
if not isinstance(num,int):
raise IndexError
elif num < 0:
raise OSError
elif num == 0:
return ''
else:
return xlscol(num // 26) + str(chr(64 + num % 26))
#if on_hit == False:
folder_org = str(input('请输入目标文件夹地址: '))
moveFile(folder_org)
#raise TypeError
def SortByOutputList(DeviceDirList): # 定义一个按output文件里的顺序对文件夹名进行排序的函数,代入all_folder_list
FolderDirDict = dict() # 文件夹路径生成字典
dfs = pd.read_excel(outputFileDir + './output.xls', header=0) # 导入output列表
for folderDir in DeviceDirList:
Device = folderDir.split('\\')[-1] # 因为这里的文件名包含路径,需要截取最后一段
FolderDirDict[folderDir] = dfs[dfs.TK==Device].index.tolist()[0] # 识别第一次出现对应dut的位置编号
device_list_dir = list(dict(sorted(FolderDirDict.items(),key=lambda x: x[1],reverse=False))) # 按键值排序后重新生成列表,防止一条TK超过9个时的排序错误问题
return device_list_dir
#绘图
def all_folder_list(strip_name):
all_folder_list = []
for file in os.listdir(folder_org + '\\' + strip_name):
if os.path.isfile(folder_org + '\\' + strip_name + '\\' + file) is False: # 生成文件夹列表
all_folder_list.append(file)
print(all_folder_list)
return all_folder_list
wookbookSum = xlsxwriter.Workbook(folder_org + '\\' + 'pic summary' + ' ' + time_record + '.xlsx')
indexNum = indexNumSum = 1
colNum = colNumSum = 14
def drawing(sitelist,strip_name,foldeName):
global BV_list,Idsat_list,Id_mid_list,Id_rise_list,Vtlin_list,Idlin_list,Rsp_list,Id_off_list,Vtgm_list,colNum,colNumSum,indexNumSum
if "AT00" not in foldeName and "pictures summary" not in foldeName and "" in foldeName:
try:
sites = sitelist
print("BV_curve_plot")
fig_output_BV = BV_curve_plot(folder_name,strip_name, sites)
print("BV_curve_plot OK")
except:
pass
try:
sites = sitelist
print("IDVD_curve_plot")
fig_output_IDVD1 = IDVD_curve_plot(folder_name,strip_name, sites)
print("IDVD_curve_plot OK")
except:
pass
try:
sites = sitelist
print("IDVG_curve_plot")
fig_output_IDVG = IDVG_curve_plot(folder_name,strip_name, sites)
print("IDVG_curve_plot OK")
except:
pass
try: # 读值导出
os.chdir(cwd)
wookbook = xlsxwriter.Workbook(cwd + '\\' + f' test_data_pics{sitelist}.xlsx')
wooksheet = wookbook.add_worksheet("pics")
image_width = 64
image_height = 15
cell_width = 64/2.8
cell_height = 20/2.8
x_scale = cell_width/image_width
y_scale = cell_height/image_height
try:
s1 = pd.Series({'Item':'BVDS',"Unit":'V','Value':BV_list[-1]})
s2 = pd.Series({'Item':'Idsat'+"_Vop*"+str(Idsat_vop_multify),"Unit":'uA/um','Value':Idsat_list[-1]})
# s3 = pd.Series({'Item':'Delta_Id',"Unit":'uA/um','Value':Id_rise_list[-1]*1E6})
s4 = pd.Series({'Item':'Ioff',"Unit":'pA/um','Value':Id_off_list[-1]})
s5 = pd.Series({'Item':'VT_Lin',"Unit":'V','Value':Vtlin_list[-1]})
s6 = pd.Series({'Item':'Idlin',"Unit":'uA/um','Value':Idlin_list[-1]})
s7 = pd.Series({'Item':'Rsp',"Unit":'mohm*mm2','Value':Rsp_list[-1]})
s8 = pd.Series({'Item':'VTGM',"Unit":'V','Value':Vtgm_list[-1]})
df = pd.DataFrame({})
for i in [s5, s6, s2, s7, s8, s4, s1]:
df = df.append(i,ignore_index=True)
Device = folder_name.split('\\')[-1]
df.index.name = Device
# print(Device)
df['Target'] = np.nan
try: # 读取output预设的各参数Target放到输出的表格里
BV_Targ,IDS_Targ,IDL_Targ,VTGM_Targ,VTL_Targ,RSP_Targ = read_Targ(Device)
df['Target'].loc[df['Item']=='BVDS'] = BV_Targ
df['Target'].loc[df['Item']=='Idsat'+"_Vop*"+str(Idsat_vop_multify)] = IDS_Targ
df['Target'].loc[df['Item']=='VTGM'] = VTGM_Targ
df['Target'].loc[df['Item']=='VT_Lin'] = VTL_Targ
df['Target'].loc[df['Item']=='Idlin'] = IDL_Targ
df['Target'].loc[df['Item']=='Rsp'] = RSP_Targ
df['Target'].loc[df['Item']=='Ioff'] = "\\"
except:
pass
os.chdir(folder_name)
df.to_excel(cwd + '\\' + f'test_data_summary{sitelist}.xlsx',sheet_name="sheet1")
# os.startfile(folder_name + './'+ 'test_data_summary.xlsx')
except:
pass
try:
# colCode = xlscol(colNum)
wooksheet.insert_image("A" + str(indexNum), cwd + '\\' + fig_output_BV,{"x_scale":x_scale,"y_scale":y_scale})
wooksheetSum.insert_image("A" + str(indexNumSum), cwd + '\\' + fig_output_BV,{"x_scale":x_scale,"y_scale":y_scale})
# colNum += 4
# colNumSum += 4
except:
pass
try:
wooksheet.insert_image("E" + str(indexNum), cwd + '\\' + fig_output_IDVD1,{"x_scale":x_scale,"y_scale":y_scale})
wooksheetSum.insert_image("E" + str(indexNumSum), cwd + '\\' + fig_output_IDVD1,{"x_scale":x_scale,"y_scale":y_scale})
# colNum += 4
# colNumSum += 4
except:
pass
# try:
# wooksheet.insert_image(xlscol(colNum) +str(indexNum),'./' + fig_output_IDVD2,{"x_scale":x_scale,"y_scale":y_scale})
# colNum += 4
# colNumSum += 4
# except:
# pass
try:
wooksheet.insert_image("I" + str(indexNum), cwd + '\\' + fig_output_IDVG,{"x_scale":x_scale,"y_scale":y_scale})
wooksheetSum.insert_image("I" + str(indexNumSum), cwd + '\\' + fig_output_IDVG,{"x_scale":x_scale,"y_scale":y_scale})
# colNum += 4
# colNumSum += 4
except:
pass
# colNum = 1
# os.startfile(folder_name + ' test_data_pics.xlsx')
'''在总表里插入读值列表'''
try:
deviceName = device_name_read(foldeName)
wooksheetSum.write(indexNumSum-1,colNumSum-1, deviceName) # 写入器件名
except:
print(foldeName + '在output文件里没有对应的器件名')
wooksheetSum.write(indexNumSum,colNumSum-1, df.index.name) # 写入器件TK名
for i in range(len(df.index)): # 行标题
wooksheetSum.write(i + indexNumSum+1, colNumSum-1, df.index[i])
for j in range(len(df.columns)): # 列标题
wooksheetSum.write(indexNumSum, j + colNumSum, df.columns[j])
for index in range(len(df.index)): # 行
for column in range(len(df.columns)): # 列
wooksheetSum.write(index + indexNumSum+1, column + colNumSum, df.iloc[index,column])
# colNumSum = 1 # 重新赋值,开始发放下一张图
indexNumSum += 12
wookbook.close()
'''完成一个结构清空数据库存'''
BV_list = [0]
Idsat_list = [0]
Id_mid_list = [0]
Id_rise_list = [0]
Vtlin_list = [0]
Idlin_list = [0]
Rsp_list = [0]
Id_off_list = [0]
Vtgm_list = [0]
except:
# colNumSum = 1 # 重新赋值,开始发放下一张图
indexNumSum += 12
pass
if picMerge is True:
for folder_name in all_folder_list:
# moveRel()
os.chdir(folder_name)
cwd = os.getcwd()
folderName = folder_name.split('\\')[-1]
drawing(allsite,folderName)
else:
for strip_name in waferListfordict:
print(os.getcwd(),strip_name)
for s in allsite:
single = []
single.append(s)
print('正在处理site:' + str(single))
os.chdir(folder_org)
all_folder_list = os.listdir(strip_name)
print("all folder",all_folder_list)
wooksheetSum = wookbookSum.add_worksheet(strip_name.split("_")[-2] + '_s'+str(s))
for folder_name in all_folder_list:
try:
# moveRel()
os.chdir(folder_org)
os.chdir(strip_name)
os.chdir(folder_name)
cwd = os.getcwd()
print("cwd",cwd)
drawing(single,strip_name,folderName)
except:
pass
indexNumSum = 1 #对于summary表格每一页重新排序
wookbookSum.close()