From 44c65b71f10ed0bc2468d54e8402339615c78884 Mon Sep 17 00:00:00 2001 From: Kavin Teenakul Date: Fri, 11 Nov 2022 18:28:48 +0100 Subject: [PATCH] update sliders --- PySimpleCV/PySimpleCV | 144 ++++++++++----------------- PySimpleCV/PySimpleCV_main_func.py | 153 +++++++++++++++++++---------- 2 files changed, 151 insertions(+), 146 deletions(-) diff --git a/PySimpleCV/PySimpleCV b/PySimpleCV/PySimpleCV index 4194f41..cea9d92 100755 --- a/PySimpleCV/PySimpleCV +++ b/PySimpleCV/PySimpleCV @@ -5,56 +5,9 @@ from matplotlib.figure import Figure import PySimpleGUI as sg import matplotlib import pandas as pd -matplotlib.use('TkAgg') - -from PySimpleCV_main_func import CV_file2df, get_CV, battery_xls2df, find_seg_start_end - -def get_CV_init(CV_file): - df = CV_file2df(CV_file) - cv_size = df.shape[0] - volt = df[:,0] - current = df[:,1] - return cv_size, volt, current - -def get_Battery_init(bat_file): - df, row_size, time_df, volt_df, current_df, capacity_df, state_df = battery_xls2df(bat_file) - return df, row_size, time_df, volt_df, current_df, capacity_df, state_df -def find_state_seg(state_df): - charge_seq = find_seg_start_end(state_df,'C_CC') - discharge_seq = find_seg_start_end(state_df,'D_CC') - rest_seq = find_seg_start_end(state_df,'R') - return charge_seq, discharge_seq, rest_seq - -def cy_idx_state_end(state_df, cycle_start, cycle_end, charge_seq, discharge_seq): - cycle_index = np.stack((charge_seq[cycle_start-1:cycle_end], discharge_seq[cycle_start-1:cycle_end])) #no need to include rest - cycle_idx_start = np.amin(cycle_index) - cycle_idx_end = np.amax(cycle_index)+1 - return cycle_idx_start, cycle_idx_end - -def get_bat_eff(df, row_size, time_df, volt_df, current_df, capacity_df, state_df, cycle_start, cycle_end, charge_seq, discharge_seq): - # Calculate the area of charge and discharge cycle and find VE for each cycle - VE_lst = [] - CE_lst = [] - for i in range(cycle_start-1,cycle_end): - time_seq_C_CC = time_df[charge_seq[i][0]:charge_seq[i][1]+1] - volt_seq_C_CC = volt_df[charge_seq[i][0]:charge_seq[i][1]+1] - current_seq_C_CC = current_df[charge_seq[i][0]:charge_seq[i][1]+1] - time_seq_D_CC = time_df[discharge_seq[i][0]:discharge_seq[i][1]+1] - volt_seq_D_CC = volt_df[discharge_seq[i][0]:discharge_seq[i][1]+1] - current_seq_D_CC = current_df[discharge_seq[i][0]:discharge_seq[i][1]+1] - int_vt_C = np.trapz(volt_seq_C_CC,time_seq_C_CC) - int_vt_D = np.trapz(volt_seq_D_CC,time_seq_D_CC) - int_ct_C = np.trapz(current_seq_C_CC,time_seq_C_CC) - # During discharge, current is negative, must make to positive - int_ct_D = -(np.trapz(current_seq_D_CC,time_seq_D_CC)) - VE = int_vt_D/int_vt_C - CE = int_ct_D/int_ct_C - VE_lst.append(VE) - CE_lst.append(CE) - VE_arr = np.array(VE_lst) - CE_arr = np.array(CE_lst) - return VE_arr, CE_arr +matplotlib.use('TkAgg') +from PySimpleCV_main_func import get_CV, battery_xls2df, get_CV_init, find_state_seq, get_battery_eff, cy_idx_state_range, CV_file2df def draw_figure(canvas, figure): figure_canvas_agg = FigureCanvasTkAgg(figure, canvas) @@ -92,7 +45,7 @@ bat_layout = [ [sg.Text('Voltage, current, energy efficiency for each row of cycle(%), press ctrl+c to copy')], [sg.Text('To copy to spreadsheet, select space as delimiter and merge delimters.')], [sg.Multiline('',size=(50,5), disabled=True, key = 'output_arr')], - [sg.Text('Cycle start'), sg.Slider(range=(1, 1), size=(60, 10), orientation='h', key='cycle_start', enable_events=True, disabled=False)], + [sg.Text('Cycle start'), sg.Slider(range=(0, 1), size=(60, 10), orientation='h', key='cycle_start', enable_events=True, disabled=False)], [sg.Text('Cycle end'), sg.Slider(range=(1, 1), size=(60, 10), orientation='h', key='cycle_end', enable_events=True, disabled=False)], [sg.Button('Clear plot',key='bat_clear'),sg.Button('Exit', key='exit_2')] ] @@ -144,26 +97,27 @@ while True: continue elif CV_file_new == '': continue - try: - CV_file = CV_file_new - cv_size, volt, current = get_CV_init(CV_file) # Only need the cv_size so set to [0] - window['sl_cut_val'].Update(range=(0,cv_size)) - window['sl_jpa_lns'].Update(range=(0,cv_size)) - window['sl_jpa_lne'].Update(range=(0,cv_size)) - window['sl_jpc_lns'].Update(range=(0,cv_size)) - window['sl_jpc_lne'].Update(range=(0,cv_size)) - window['sl_cut_val'].Update(disabled=False) - window['sl_jpa_lns'].Update(disabled=False) - window['sl_jpa_lne'].Update(disabled=False) - window['sl_jpc_lns'].Update(disabled=False) - window['sl_jpc_lne'].Update(disabled=False) - window['CV_file_use'].Update(CV_file) - ax_cv.grid() - ax_cv.plot(volt, current, '-') - ax_cv.grid() - fig_agg_cv.draw() - except Exception as file_error: - sg.popup(file_error, keep_on_top=True) + # try: + CV_file = CV_file_new + df_CV = CV_file2df(CV_file) + cv_size, volt, current = get_CV_init(df_CV) # Only need the cv_size so set to [0] + window['sl_cut_val'].Update(range=(0,cv_size)) + window['sl_jpa_lns'].Update(range=(0,cv_size)) + window['sl_jpa_lne'].Update(range=(0,cv_size)) + window['sl_jpc_lns'].Update(range=(0,cv_size)) + window['sl_jpc_lne'].Update(range=(0,cv_size)) + window['sl_cut_val'].Update(disabled=False) + window['sl_jpa_lns'].Update(disabled=False) + window['sl_jpa_lne'].Update(disabled=False) + window['sl_jpc_lns'].Update(disabled=False) + window['sl_jpc_lne'].Update(disabled=False) + window['CV_file_use'].Update(CV_file) + ax_cv.grid() + ax_cv.plot(volt, current, '-') + ax_cv.grid() + fig_agg_cv.draw() + # except Exception as file_error: + # sg.popup(file_error, keep_on_top=True) case 'sl_cut_val' | 'sl_jpa_lns' | 'sl_jpa_lne' | 'sl_jpc_lns' | 'sl_jpc_lne' : cut_val = int(values['sl_cut_val']) # Getting the k value from the slider element. jpa_lns = int(values['sl_jpa_lns']) @@ -173,7 +127,7 @@ while True: ax_cv.cla() ax_cv.grid() # Start plotting - volt, current, jpa_ref_ln, jpa_ref, idx_jpa_max, jpa_abs, jpa_base, jpc_ref_ln, jpc_ref, idx_jpc_min, jpc_abs, jpc_base, jpa_lns, jpa_lne, jpc_lns, jpc_lne, jpa, jpc = get_CV(CV_file,cut_val,jpa_lns,jpa_lne,jpc_lns,jpc_lne) + volt, current, jpa_ref_ln, jpa_ref, idx_jpa_max, jpa_abs, jpa_base, jpc_ref_ln, jpc_ref, idx_jpc_min, jpc_abs, jpc_base, jpa_lns, jpa_lne, jpc_lns, jpc_lne, jpa, jpc = get_CV(df_CV,cut_val,jpa_lns,jpa_lne,jpc_lns,jpc_lne) ax_cv.plot(volt, current) ax_cv.set_xlabel("Voltage") ax_cv.set_ylabel("Current") @@ -206,29 +160,30 @@ while True: continue try: bat_file = bat_file_new - df, row_size, time_df, volt_df, current_df, capacity_df, state_df = battery_xls2df(bat_file) + df_bat, row_size, time_df, volt_df, current_df, capacity_df, state_df = battery_xls2df(bat_file) # Sequence information - charge_seq, discharge_seq, rest_seq = find_state_seg(state_df) + charge_seq, discharge_seq, rest_seq = find_state_seq(state_df) tot_cycle_number = np.shape(charge_seq)[0] - VE_arr, CE_arr = get_bat_eff(df, row_size, time_df, volt_df, current_df, capacity_df, state_df, 1, tot_cycle_number, charge_seq, discharge_seq) - EE_arr = VE_arr * CE_arr + VE_arr, CE_arr, EE_arr = get_battery_eff(row_size, time_df, volt_df, current_df, capacity_df, state_df, 1, tot_cycle_number, charge_seq, discharge_seq) window['cycle_end'].Update(disabled=False) window['cycle_start'].Update(disabled=False) - window['cycle_start'].Update(range=(1,tot_cycle_number)) + window['cycle_start'].Update(range=(0,tot_cycle_number-1)) window['cycle_end'].Update(range=(1,tot_cycle_number)) window['bat_file_use'].Update(bat_file) - VE_avg = np.average(VE_arr) - CE_avg = np.average(CE_arr) - EE_avg = VE_avg * CE_avg - df_display=pd.DataFrame([VE_arr*100,CE_arr*100,EE_arr*100]) # Create dataframe to display in multiline output + df_display=pd.DataFrame([VE_arr,CE_arr,EE_arr]) # Create dataframe to display in multiline output df_display=df_display.T df_display.columns = ['Volt', 'Current', 'Energy'] df_display.index = df_display.index + 1 # Start index at 1 for nice looking window['output_arr'].Update(df_display.to_string()) # Make sure to print all lines window['tot_cycle'].Update(tot_cycle_number) - window['output_ve'].Update(np.round(VE_avg*100,3)) - window['output_ce'].Update(np.round(CE_avg*100,3)) - window['output_ee'].Update(np.round(EE_avg*100,3)) + + VE_avg = np.average(VE_arr[0:cycle_end]) + CE_avg = np.average(CE_arr[0:cycle_end]) + EE_avg = np.average(EE_arr[0:cycle_end]) + + window['output_ve'].Update(np.round(VE_avg,3)) + window['output_ce'].Update(np.round(CE_avg,3)) + window['output_ee'].Update(np.round(EE_avg,3)) ax_bat_volt.plot(time_df, volt_df, '-',color='blue') ax_bat_current.plot(time_df, current_df, '--',color='red') ax_bat_volt.grid() @@ -250,16 +205,17 @@ while True: ax_bat_volt.cla() ax_bat_volt.grid() # Start plotting - df, row_size, time_df, volt_df, current_df, capacity_df, state_df = battery_xls2df(bat_file) - charge_seq, discharge_seq, rest_seq = find_state_seg(state_df) - cycle_idx_start, cycle_idx_end = cy_idx_state_end(state_df, cycle_start, cycle_end, charge_seq, discharge_seq) - VE_avg = np.average(VE_arr[cycle_start-1:cycle_end]) - CE_avg = np.average(CE_arr[cycle_start-1:cycle_end]) - EE_avg = VE_avg * CE_avg + df_bat, row_size, time_df, volt_df, current_df, capacity_df, state_df = battery_xls2df(bat_file) + charge_seq, discharge_seq, rest_seq = find_state_seq(state_df) + cycle_idx_range = cy_idx_state_range(state_df, cycle_start, cycle_end, charge_seq, discharge_seq) + + VE_avg = np.average(VE_arr[cycle_start:cycle_end]) + CE_avg = np.average(CE_arr[cycle_start:cycle_end]) + EE_avg = np.average(EE_arr[cycle_start:cycle_end]) ax_bat_volt.plot(time_df, volt_df, '-', color='blue') - left_bound = time_df[cycle_idx_start:cycle_idx_end][0] - right_bound = time_df[cycle_idx_start:cycle_idx_end][-1] + left_bound = time_df[cycle_idx_range][0] + right_bound = time_df[cycle_idx_range][1] ax_bat_volt.set_xlim(left=left_bound,right=right_bound) ax_bat_volt.set_xlabel("Time") ax_bat_volt.set_ylabel("Voltage") @@ -268,8 +224,8 @@ while True: ax_bat_current.plot(time_df, current_df,'--',color='red') ax_bat_current.set_ylabel("Current") - window['output_ve'].Update(np.round(VE_avg*100,3)) - window['output_ce'].Update(np.round(CE_avg*100,3)) - window['output_ee'].Update(np.round(EE_avg*100,3)) + window['output_ve'].Update(np.round(VE_avg,3)) + window['output_ce'].Update(np.round(CE_avg,3)) + window['output_ee'].Update(np.round(EE_avg,3)) fig_agg_bat.draw() window.close() diff --git a/PySimpleCV/PySimpleCV_main_func.py b/PySimpleCV/PySimpleCV_main_func.py index f8dbcf4..072e34d 100644 --- a/PySimpleCV/PySimpleCV_main_func.py +++ b/PySimpleCV/PySimpleCV_main_func.py @@ -1,6 +1,7 @@ import numpy as np import pandas as pd import re + def search_string_in_file(file_name, string_to_search): line_number = 0 list_of_results = [] @@ -13,81 +14,87 @@ def search_string_in_file(file_name, string_to_search): def CV_file2df(CV_file): if CV_file.endswith(".csv"): - df = pd.read_csv(CV_file,usecols=[0,1]) - df = np.array(df) + df_CV = pd.read_csv(CV_file,usecols=[0,1]) + df_CV = np.array(df_CV) elif CV_file.endswith(".txt"): - df = pd.read_table(CV_file, sep='\t', header=None, usecols=[0,1]) - df = np.array(df) + df_CV = pd.read_table(CV_file, sep='\t', header=None, usecols=[0,1]) + df_CV = np.array(df_CV) elif CV_file.endswith(".par"): # Search for line match beginning and end of CV data and give ln number - start_segment = search_string_in_file('example_CV.par', 'Definition=Segment')[0][0] - end_segment = search_string_in_file('example_CV.par', ' jpa_lne: @@ -100,9 +107,9 @@ def get_CV(CV_file,cut_val,jpa_lns,jpa_lne,jpc_lns,jpc_lne): save_val_jpc = jpc_lns jpc_lns = jpc_lne jpc_lne = save_val_jpc - - volt = df[cut_val:,0] # exclude some index to remove artifacts - current = df[cut_val:,1] + # + volt = df_CV[cut_val:,0] # exclude some index to remove artifacts + current = df_CV[cut_val:,1] jpa_lnfit = np.polyfit(volt[jpa_lns:jpa_lne],current[jpa_lns:jpa_lne], 1) idx_jpa_max = np.argmax(current) @@ -124,6 +131,7 @@ def get_CV(CV_file,cut_val,jpa_lns,jpa_lne,jpc_lns,jpc_lne): return volt, current, jpa_ref_ln, jpa_ref, idx_jpa_max, jpa_abs, jpa_base, jpc_ref_ln, jpc_ref, idx_jpc_min, jpc_abs, jpc_base, jpa_lns, jpa_lne, jpc_lns, jpc_lne, jpa, jpc def time2sec(time_raw,delim): + # Take time format such as 1-12:05:24 and convert to seconds time_raw = str(time_raw) time_sp = re.split(delim, time_raw) time_sp = list(map(int, time_sp)) @@ -131,4 +139,45 @@ def time2sec(time_raw,delim): time_sec = time_sp[0]*3600*24 + time_sp[1]*3600 + time_sp[2]*60 + time_sp[3] elif len(time_sp) == 3: time_sec = time_sp[0]*3600 + time_sp[1]*60 + time_sp[2] - return int(time_sec) \ No newline at end of file + return int(time_sec) + +def find_state_seq(state_df): + charge_seq = find_seg_start_end(state_df,'C_CC') + discharge_seq = find_seg_start_end(state_df,'D_CC') + rest_seq = find_seg_start_end(state_df,'R') + return charge_seq, discharge_seq, rest_seq + +def get_battery_eff(row_size, time_df, volt_df, current_df, capacity_df, state_df, cycle_start, cycle_end, charge_seq, discharge_seq): + # Calculate the area of charge and discharge cycle and find VE,CE,EE for each cycle + VE_lst = [] + CE_lst = [] + for i in range(cycle_start-1,cycle_end): + time_seq_C_CC = time_df[charge_seq[i][0]:charge_seq[i][1]+1] + volt_seq_C_CC = volt_df[charge_seq[i][0]:charge_seq[i][1]+1] + current_seq_C_CC = current_df[charge_seq[i][0]:charge_seq[i][1]+1] + time_seq_D_CC = time_df[discharge_seq[i][0]:discharge_seq[i][1]+1] + volt_seq_D_CC = volt_df[discharge_seq[i][0]:discharge_seq[i][1]+1] + current_seq_D_CC = current_df[discharge_seq[i][0]:discharge_seq[i][1]+1] + int_vt_C = np.trapz(volt_seq_C_CC,time_seq_C_CC) + int_vt_D = np.trapz(volt_seq_D_CC,time_seq_D_CC) + int_ct_C = np.trapz(current_seq_C_CC,time_seq_C_CC) + # During discharge, current is negative, must make to positive + int_ct_D = -(np.trapz(current_seq_D_CC,time_seq_D_CC)) + VE = int_vt_D/int_vt_C + CE = int_ct_D/int_ct_C + VE_lst.append(VE) + CE_lst.append(CE) + VE_arr = np.array(VE_lst) * 100 # convert to % + CE_arr = np.array(CE_lst) * 100 + EE_arr = (VE_arr/100 * CE_arr/100)*100 + return VE_arr, CE_arr, EE_arr + +def cy_idx_state_range(state_df, cycle_start, cycle_end, charge_seq, discharge_seq): + # Get index for beginning and end of specify cycle + # Take all start and end of the cycle chosen, select the first and last. + # For plotting purpose + cycle_index = np.stack((charge_seq[cycle_start:cycle_end], discharge_seq[cycle_start:cycle_end])) #no need to include rest + cycle_idx_start = np.amin(cycle_index) + cycle_idx_end = np.amax(cycle_index) + cycle_idx_range = [cycle_idx_start, cycle_idx_end] + return cycle_idx_range \ No newline at end of file