import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from util import *
import warnings
warnings.filterwarnings("ignore")
from datetime import timedelta
import os
# Give data folder name
name = 'GPE7'
# give length of file name
character = 5
#plot start cycle number
cyc_num = 1
cyc_num_end = 1000
file_path = 'Dat/'+name+'/'
files = os.listdir(file_path)
markers = ["o-","v-","^-","<-","s-","p-","P-","*-","h-","H-","+-","x-","X-","D-","d-",
"o-","v-","^-","<-","s-","p-","P-","*-","h-","H-","+-","x-","X-","D-","d-"]
#markers = ["o","v","^","<","s","p","P","*","h","H","+","x","X","D","d","o","v","^","<","s","p","P","*","h","H","+","x","X","D","d",]
import matplotlib.colors as colors
colors_list = list(colors._colors_full_map.values())
SMALL_SIZE = 20
plt.rc('font', size=SMALL_SIZE)
plt.rc('axes', titlesize=SMALL_SIZE)
# defind the folder name for exported figures
batch = name
p = os.getcwd()
cur_fig_path = os.path.join(p, 'Fig')
cur_fig = os.listdir(cur_fig_path)
folder_path = os.path.join(cur_fig_path, batch)
if not os.path.exists(folder_path):
os.mkdir(folder_path)
pro = os.path.join(p, 'ProcessedData')
if not os.path.exists(pro+'/'+batch):
os.mkdir('ProcessedData'+'/'+batch)
cur_fig_path
'/Users/michael/Documents/Projects/NewareDataProcessing/Fig'
pro
'/Users/michael/Documents/Projects/NewareDataProcessing/ProcessedData'
files
['.DS_Store', 'C1538.xls', 'C1532.xls', 'C1526.xls', 'C1535.xls', 'C1536.xls']
files.remove('.DS_Store')
# select the final charging cycles
print("Please select the desired last charging cycles for plotting with an integer number: ")
c1 = int(input())
if not c1:
L = 1
else:
L = c1
# select the final discharging cycles
print("Please select the desired last discharging cycles for plotting with an integer number: ")
c2 = int(input())
if not c2:
D = 1
else:
D = c2
Please select the desired last charging cycles for plotting with an integer number: 100 Please select the desired last discharging cycles for plotting with an integer number: 100
#pd.concat([cell_vol,cell_vol2], axis=0)
def get_min(time_str):
"""Get minutes from time."""
h, m, s = time_str.split(':')
return int(h) * 60 + int(m) + int(s)/60
cap = ['Cycle ID','Cap_Chg(mAh)','Cap_DChg(mAh)','Chg/DChg Efficiency(%)','Charge IR(Ω)','Discharge IR(Ω)']
vol = ['Cycle ID','Step ID','Step Name','Voltage(V)','Current(mA)','Capacity(mAh)' ,'Time(h:min:s.ms)','Realtime']
vol_new = ['Cycle ID', 'Step ID', 'Step Name', 'Voltage(V)', 'Current(mA)',
'Capacity(mAh)', 'Time(h:min:s.ms)', 'Realtime', 'Time', 'RTime']
ocv = ['Cycle ID', 'Step Name', 'Voltage(V)', 'Current(mA)', 'Capacity(mAh)',
'Time(h:min:s.ms)', 'Realtime', 'Time', 'RTime']
IR = ['Cycle ID','Charge IR(Ω)','Discharge IR(Ω)']
df_ocv_final = pd.DataFrame()
df_cap_final = pd.DataFrame()
df_vol_final = pd.DataFrame()
df_ocv_dis_final = pd.DataFrame()
df_ir_final = pd.DataFrame()
df_ocv_u_final = pd.DataFrame()
df_ocv_dis_v_final = pd.DataFrame()
with open('ProcessedData'+'/'+batch+'/'+name+'cells.txt', 'w+') as cellw:
for file in files:
cell_vol = pd.DataFrame()
print("processing files: ", file)
path = file_path +file
apx = file[:character]
# write all cell number and names to a file, data folder name + cells
cellw.write(apx+"\n")
cell_cap = read_file(path,sn=3)
#cell_vol = read_file(path,sn=4)
cell = read_file(path,sn=None)
for i in range(4,len(cell)):
cell_v = read_file(path,sn=i)
cell_vol = pd.concat([cell_vol,cell_v],ignore_index=True)
print(cell_vol.shape)
df_cap = cell_cap[cap]
df_vol = cell_vol[vol]
df_vol['Time'] = df_vol.apply(lambda x: x['Time(h:min:s.ms)'][:-4], axis = 1)
times = df_vol['Time']
#change and update time
#tm1 = [map(int, x.split(':')) for x in times]
#tm2 = [timedelta(hours=x[0], minutes=x[1], seconds=x[2]) for x in tm1]
##
#df_vol['Time'] = pd.to_datetime(df_vol['Time'], format='%H:%M:%S')
df_vol['Time'] = times.apply(lambda x:get_min(x))
df_vol['RTime'] = df_vol.apply(lambda x: x['Realtime'][11:], axis = 1)
df_vol['RTime'] = pd.to_datetime(df_vol['Realtime'], format='%m/%d/%Y %H:%M:%S')
df_vol['RTime'] = (df_vol['RTime'] - df_vol['RTime'][0]).dt.total_seconds()/60
cyc_num_min = 1
cyc_num_max = df_vol.index[-1]
df_cap_d = cycleID_check(df_cap, cyc_num_min,cyc_num_max)
df_vol_d = cycleID_check(df_vol, cyc_num_min,cyc_num_max)
df_cap_d.columns = [s + apx for s in cap]
df_vol_d.columns = [s + apx for s in vol_new]
df_cap_final = pd.concat([df_cap_final,df_cap_d], axis=1)
df_vol_final = pd.concat([df_vol_final,df_vol_d], axis=1)
df_ir = df_cap_d[[s + apx for s in IR]]
df_ir_final = pd.concat([df_ir_final,df_ir], axis=1)
# extract OCV after charging
e = df_vol_d.groupby('Step ID'+ apx).last()
#extra steps at 28, 29 long waiting period 99 hours for OCV check
#e.drop([28,29], inplace=True)
#e.reset_index(inplace=True)
#L = e.index[-1]
#t = e.index[0]
#if t == 1:
# sel = []
#else:
# sel = []
# pouch 100 used t=3, s=5
#created a dict. to apply different dataset
'''
dict1 = {"u":2, "t":3, "v":4, "s":5}
dict2 = {"u":3, "t":4, "v":5, "s":6}
u = 2 # select last ocv when charging
t = 3 # select ocv after charging
v = 4 # select last ocv when discharging
s = 5 # select ocv after discharging
'''
if e['Step Name'+apx][1] =='CCCV_Chg':
u,t,v,s = 1,2,3,4 # when the first row is charging
sel = []
else:
u,t,v,s = 2,3,4,5 # when the first row is rest
sel = [1]
sel_u = []
sel_v = []
sel_s = []
# loop to select all charging cycles OCV, and OCV after rest 10min
while t<4*L+1 and t<e.shape[0]:
sel.append(t)
sel_u.append(u)
t = t + 4
u = u + 4
df_ocv = e.loc[sel]
df_ocv = df_ocv.loc[:,~df_ocv.columns.duplicated()].reset_index(drop=True)
df_ocv_u = e.loc[sel_u]
df_ocv_u = df_ocv_u.loc[:,~df_ocv_u.columns.duplicated()].reset_index(drop=True)
#print(df_ocv.columns)
#df_ocv.reset_index(drop=True)
#df_ocv.columns = [s + file[:5] for s in ocv]
df_ocv_final = pd.concat([df_ocv_final, df_ocv], axis=1)
df_ocv_u_final = pd.concat([df_ocv_u_final, df_ocv_u], axis=1)
# extract OCV after discharging
f = df_vol_d.groupby('Step ID'+ apx).last()
#extra steps at 28, 29 long waiting period 99 hours for OCV check
#f.drop([28,29], inplace=True)
#f.reset_index(inplace=True)
#sel_s = [1] for p100
# loop to select all discharging cycles OCV, and OCV after rest 10min
while s<4*D and s<f.shape[0]:
sel_s.append(s)
sel_v.append(v)
s = s + 4
v = v + 4
df_ocv_dis = f.loc[sel_s]
df_ocv_dis = df_ocv_dis.loc[:,~df_ocv_dis.columns.duplicated()].reset_index(drop=True)
df_ocv_dis=df_ocv_dis.rename(columns = {'Voltage(V)'+apx:'Voltage(V)-d'+apx}) #rename column name
df_ocv_dis_v = f.loc[sel_v]
df_ocv_dis_v = df_ocv_dis_v.loc[:,~df_ocv_dis_v.columns.duplicated()].reset_index(drop=True)
df_ocv_dis_v=df_ocv_dis_v.rename(columns = {'Voltage(V)'+apx:'Voltage(V)-d'+apx}) #rename column name
#print(df_ocv.columns)
#df_ocv.reset_index(drop=True)
#df_ocv.columns = [s + file[:5] for s in ocv]
df_ocv_dis_final = pd.concat([df_ocv_dis_final, df_ocv_dis], axis=1)
df_ocv_dis_v_final = pd.concat([df_ocv_dis_v_final, df_ocv_dis_final], axis=1)
# we then add the series to the dataframe, which holds our parsed CSV file
OCV = df_ocv[['Voltage(V)'+apx]]
Otime = df_ocv[['RTime'+apx]]
Ocycle_ID = df_ocv[['Cycle ID'+apx]]
OCV_dis = df_ocv_dis[['Voltage(V)-d'+apx]]
Otime_dis = df_ocv_dis[['RTime'+apx]]
Ocycle_ID_dis = df_ocv_dis[['Cycle ID'+apx]]
OCV_u = df_ocv_u[['Voltage(V)'+apx]]
OCV_ucycle_ID = df_ocv_u[['Cycle ID'+apx]]
OCV_dis_v = df_ocv_dis_v[['Voltage(V)-d'+apx]]
OCV_dis_vcycle_ID = df_ocv_dis_v[['Cycle ID'+apx]]
Cycle = df_cap_d[['Cycle ID'+apx]]
DischargeCap = df_cap_d[['Cap_DChg(mAh)'+apx]]
ChargeCap = df_cap_d[['Cap_Chg(mAh)'+apx]]
Efficiency = df_cap_d[['Chg/DChg Efficiency(%)'+apx]]
Voltage = df_vol_d[['Voltage(V)'+apx]]
DischargeCap_con = df_vol_d[['Capacity(mAh)'+apx]]
time = df_vol_d[['Time'+apx]]
rtime = df_vol_d[['RTime'+apx]]
plt.figure(figsize=(10,8))
plot_vol_OCV(Ocycle_ID, OCV,name=apx+'-Charge')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-OCV_charge.png")
plot_vol_OCV(Ocycle_ID_dis, OCV_dis,name=apx+'-Discharge')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-OCV_discharge.png")
plot_vol_OCV(OCV_ucycle_ID, OCV_u,name=apx+'-maxChargeVoltage')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-OCV_V_charge.png")
plot_vol_OCV(OCV_dis_vcycle_ID, OCV_dis_v,name=apx+'-minDisChargeVoltage')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-OCV_V_discharge.png")
plot_cyc_cap_charge(Cycle, ChargeCap, Efficiency,name=apx+'Charge')
#plt.axhline(y=0.8*3.5, color='b', linestyle='--',label='80% retention')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-charge Capacity.png")
plot_cyc_cap(Cycle, DischargeCap, Efficiency,name=apx+'Discharge')
#plt.axhline(y=0.8*3.5, color='b', linestyle='--',label='80% retention')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-discharge Capacity.png")
plot_vol_cap(DischargeCap_con, Voltage, name=apx+'Dicharge Capacity')
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-Votage_Capacity.png")
plot_vol_time(rtime, Voltage,name=apx)
plt.savefig("Fig/"+batch+'/'+apx+str(D)+"-cycles-Votage_profile.png")
cellw.close()
df_cap_final.to_csv('ProcessedData'+'/'+batch+'/'+'Cap_final.csv')
df_vol_final.to_csv('ProcessedData'+'/'+batch+'/'+'Vol_final.csv')
df_ocv_final.to_csv('ProcessedData'+'/'+batch+'/'+'OCV-charge-final.csv')
df_ocv_dis_final.to_csv('ProcessedData'+'/'+batch+'/'+'OCV-discharge-final.csv')
df_ir_final.to_csv('ProcessedData'+'/'+batch+'/'+'DCIR-final.csv')
print("Files are processed successfully")
processing files: C1538.xls (57228, 11) processing files: C1532.xls (57225, 11) processing files: C1526.xls (57220, 11) processing files: C1535.xls (57228, 11) processing files: C1536.xls (57221, 11) Files are processed successfully
df_ocv_dis.head()
#sel
#df_ocv_dis_final.head(20)
#read_file(path,sn=3)
#sel_s
print (s,L)
#df_vol_d.groupby('Step ID'+ apx).last().head(10)
#df_vol_d.head(20)
#chage ocv plotting
print("Processing OCV charging all cell data comparison")
df_ocv_c =read_file('ProcessedData'+'/'+batch+'/'+'OCV-charge-final.csv')
#plots use the same cycle number, x value is the same
c = df_ocv_c.columns
Y = [c for c in c if "Voltage" in c]
plt.figure(figsize=(12,8))
for f in range(len(files)):
file = files[f]
sfx = file[:character]
x = df_ocv_c['Cycle ID'+sfx]
y = df_ocv_c['Voltage(V)'+sfx]
plt.plot(x, y,markers[f],label=sfx,color=colors_list[f],markersize=12, linewidth=1)
plt.legend()
plt.xlabel('Cycle ID')
plt.ylabel('Voltage (V)', color='b')
plt.title("OCV after charging rest 10min")
plt.grid(b=True, which='major', linestyle='--')
plt.tight_layout()
plt.savefig("Fig/"+batch+'/'+"Cells-OCV_charge.png", dpi=200)
plt.show()
#charge ocv statistics
print("The statistics of OCV at the begining is")
df_ocv_c[Y].loc[0].T.describe()
df_ocv_c.head()
#import matplotlib
#matplotlib.markers.rcParams
#df_ocv_disC.head(20)
#chage ocv plotting
print("Processing OCV discharging all cell data comparison")
df_ocv_disC =read_file('ProcessedData'+'/'+batch+'/'+'OCV-discharge-final.csv')
#plots use the same cycle number, x value is the same
Y = [c for c in c if "Voltage" in c]
plt.figure(figsize=(12,8))
for f in range(len(files)):
file = files[f]
sfx = file[:character]
x = df_ocv_disC['Cycle ID'+sfx]
y = df_ocv_disC['Voltage(V)'+sfx]
plt.plot(x, y,markers[f],label=sfx,color=colors_list[f],markersize=12, linewidth=1)
plt.legend()
plt.xlabel('Cycle ID')
plt.ylabel('Voltage (V)', color='b')
plt.title("OCV after discharging rest 10min")
plt.grid(b=True, which='major', linestyle='--')
plt.tight_layout()
plt.savefig("Fig/"+batch+'/'+"Cells-OCV_discharge.png", dpi=200)
plt.show()
#charge ocv statistics
print("The statistics of OCV after discharging is")
if len(df_ocv_disC[Y]) != 0:
print(df_ocv_disC[Y].loc[0].T.describe())
else:
print("No data point")
df_ocv_disC[Y].loc[0].T.describe()
df_ocv_disC.head(20)
#Cap_X = ['Cap_Chg(mAh)C1468','Cap_Chg(mAh)C1470','Cap_Chg(mAh)C1472']
df_cap = read_file('ProcessedData'+'/'+batch+'/'+'Cap_final.csv')
c = df_cap.columns
Cap_X = [c for c in c if "Cap_DChg" in c]
#disCap_X = [c for c in c if "Cap_DChg" in c]
d = df_cap[Cap_X]
plt.figure(figsize=(12,8))
for f in range(len(files)):
file = files[f]
sfx = file[:character]
d[sfx+'Cap_retention'] = 100*d[[Cap_X[f]]]/d[[Cap_X[f]]].iloc[1]
x = df_cap['Cycle ID'+sfx][cyc_num:]
y = df_cap['Cap_DChg(mAh)'+sfx][cyc_num:]
plt.plot(x, y,markers[f],label=sfx,color=colors_list[f],markersize=12, linewidth=1)
plt.legend()
plt.xlabel('Cycle ID')
plt.ylabel('Discharge Capacity (mAh)', color='b')
plt.grid(b=True, which='major', linestyle='--')
plt.title(str(cyc_num)+'-'+str(D)+"cycles-Capacity Cycles")
plt.tight_layout()
plt.savefig("Fig/"+batch+'/'+str(cyc_num)+'-'+str(D)+"cycles-Cells-Capacity-Cycle.png", dpi=200)
plt.show()
plt.figure(figsize=(12,8))
for f in range(len(files)):
file = files[f]
sfx = file[:character]
x = df_cap['Cycle ID'+sfx][cyc_num:]
y = d[sfx+'Cap_retention'][cyc_num:]
plt.plot(x, y,markers[f],label=sfx,color=colors_list[f],markersize=12, linewidth=1)
plt.axhline(y=80, color='r', linestyle='--')
plt.legend()
plt.xlabel('Cycle ID')
plt.ylabel('Discharge Capacity Retention (%)', color='b')
plt.grid(b=True, which='major', linestyle='--')
plt.title(str(cyc_num)+'-'+str(D)+"cycles-Capacity Cycles Retention")
plt.tight_layout()
plt.savefig("Fig/"+batch+'/'+str(cyc_num)+'-'+str(D)+"cycles-Cells-Capacity-Cycle-retention.png", dpi=200)
plt.show()
#d[[Cap_X[f]]].iloc[6]
df_ocv_disC.head(10)
#df_Vol.dropna(inplace=True)
id_min = 1
id_max = 5
df_Vol = read_file('ProcessedData'+'/'+batch+'/'+'Vol_final.csv')
c = df_Vol.columns
Time_X = [c for c in c if "RTime" in c]
cycle_ID = [c for c in c if 'Cycle ID' in c]
#df_Vol = read_file('Vol_final.csv')
ch = df_Vol[cycle_ID[-1]].between(id_min,id_max, inclusive=True)
df_Vol = df_Vol[ch]
cycname = "Cycle"+ str(id_min)+'-'+str(id_max)
plt.figure(figsize=(12,8))
for f in range(len(files)):
file = files[f]
sfx = file[:character]
x = df_Vol['RTime'+sfx]
y = df_Vol['Voltage(V)'+sfx]
plt.plot(x, y,markers[f],label=sfx,markersize=8, linewidth=1)
plt.legend()
plt.xlabel('Time (min)')
plt.ylabel('Voltage (V)', color='b')
plt.grid(b=True, which='major', linestyle='--')
plt.title("Voltage Profiles "+cycname)
plt.tight_layout()
plt.savefig("Fig/"+batch+'/'+"Cells-Capacity-Cycle-"+cycname+".png", dpi=200)
plt.show()
#chage ocv plotting
print("Processing Cell IR comparison")
df_ir_final =read_file('ProcessedData'+'/'+batch+'/'+'DCIR-final.csv')
#plots use the same cycle number, x value is the same
ir = df_ir_final.columns
Y = [c for c in c if "IR" in c]
plt.figure(figsize=(12,8))
for f in range(len(files)):
file = files[f]
sfx = file[:character]
x = df_ir_final['Cycle ID'+sfx]
y1 = df_ir_final['Charge IR(Ω)'+sfx]
y2 = df_ir_final['Discharge IR(Ω)'+sfx]
plt.plot(x, y1,label=sfx+'-charge IR',markersize=12, linewidth=1)
plt.plot(x, y2,label=sfx+'-discharge IR',markersize=12, linewidth=1)
plt.legend()
plt.xlabel('Cycle ID')
plt.ylabel('IR (Ohm)', color='b')
plt.title(sfx+"-IR")
plt.grid(b=True, which='major', linestyle='--')
plt.tight_layout()
plt.ylim([0,200])
plt.savefig("Fig/"+batch+'/'+"Cells-IR_charge.png", dpi=200)
plt.show()
#charge ocv statistics
print("The statistics of OCV at the begining is")
df_ir_final[Y].loc[0].T.describe()
df_ir_final.head()
!pip freeze > requirements.txt