def change_cycle_def( search_word ): # Rewrites cycle column according to first instance of discharge or charge import add_to_rawdata database = user_setup.database all_files = support.find_files(search_word, database) # Finds and returns files as list support.print_files_nr(all_files) # prints files with nr response = support.input_cool( 'yellow', "Which file do you want to change the cycle definition? Write nr: " ) # Response from user file = all_files[int(response)] df_change = access_data.access_cell_data(file.stem) df_change = add_to_rawdata.add_cycle_incr(df_change) response2 = support.input_cool( 'yellow', "Overwrite existing file? (no/any): ") # Response from user if response2.lower() == 'no': new_name = support.input_cool('yellow', 'Write new cell name: ') df_change.to_pickle(database.as_posix() + "/" + new_name) support.print_cool('green', new_name + ' saved to database.') else: df_change.to_pickle(database.as_posix() + "/" + file.stem) support.print_cool('green', 'Updated pickle saved to database.') return
def check_char_mass (found_mass): use_mass = None # value to be returned if found_mass: support.print_cool('blue', 'Found this/these characteristic mass (mg): ', found_mass) response = support.input_cool('yellow', '\nUse this? (enter/no): \n(If multiple masses, will use first) ') if response == 'no': use_mass = support.input_cool('yellow', 'Please write desired mass (mg): ') elif type(found_mass)==list: use_mass = found_mass[0] else: use_mass = found_mass else: use_mass = support.input_cool('yellow', 'No characteristic mass found. Please write desired mass (mg): ') return use_mass
def lanhe(data_url, cell_key, database): # Imports raw data: df = id.import_lanhe(data_url) # Clean up raw data: df = fix.lanhe(df) # Tries to calculate characteristic mass and verifies with user / input from user: try: last_cap_incr = df['cap_incr'].iloc[-1] last_cap_incr_spec = df['cap_incr_spec'].iloc[-1] char_mass = last_cap_incr / last_cap_incr_spec * 1000 char_mass = fix_rawdata.check_char_mass(char_mass) except: char_mass = support.input_cool( 'yellow', 'No characteristic mass found. Please input mass: ') #Add additional variables to pandas # First, need incremental cycle, discharge_incr and charge_incr (have cap_incr) to use AddSpecificCapacity functions: df = add.incremental_cycle_charge_discharge(df) # Then, can add specific incremental capacity (not really necessary, is in fact exported from Lanhe) and cyclebased: df = add.specific_capacity_incremental(df, char_mass) df = add.specific_capacity_cycle(df, char_mass) df = add.diffcap(df) df = add.cell_info(df, char_mass, cell_key) df.to_pickle((database + "/" + cell_key)) # Store data as a Pickle return df
def auto_import(search_word, **kwargs): try: if kwargs['testing'] == True: raw_data = Path(r'..\PyBat2-master\testing') database = Path(r'..\PyBat2-master\testing\database') else: raw_data = user_setup.raw_data except: raw_data = user_setup.raw_data database = user_setup.database all_files = support.search_file( search_word, raw_data ) # Search for cells with a specific name in the raw data folder. response = support.input_cool( 'yellow', 'Do you want to convert these files? yes/no: \n(.mpr and .mgr files will be skipped) ' ) if response.lower() == "yes": for line in all_files: #Loop through all input files. file_name = line.stem #Saves the file name file_path = line.as_posix() #Saves the file path if line.suffix == '.mpr' or line.suffix == '.mgr': continue support.print_cool( 'blue', '-' * 80 + '\nConverting: ' + file_name + line.suffix) response = support.input_cool( 'yellow', 'Do you want to change cell key (what the cell will be saved as)? (yes/any button): ' ) if response == 'yes': file_name = support.input_cool('yellow', 'Write cell key: ') else: None identifier = identify_file(line.suffix, file_path) if identifier == 'biologic': import_cell.biologic(file_path, file_name, database.as_posix()) support.print_cool( 'green', 'Converted from Biologic: ' + file_name + line.suffix) elif identifier == 'vmp3': import_cell.vmp3(file_path, file_name, database.as_posix()) support.print_cool( 'green', 'Converted from VMP3: ' + file_name + line.suffix) elif identifier == 'impedance': import_cell.vmp3(file_path, file_name, database.as_posix()) support.print_cool( 'green', 'Converted from VMP3: ' + file_name + line.suffix) elif identifier == 'lanhe': import_cell.lanhe(file_path, file_name, database.as_posix()) support.print_cool( 'green', 'Converted from Lanhe: ' + file_name + line.suffix) elif identifier == 'maccor': import_cell.maccor(file_path, file_name, database.as_posix()) support.print_cool( 'green', 'Converted from Maccor: ' + file_name + line.suffix) else: support.print_cool('red', 'File not recognized: ' + file_path) elif response.lower() == 'no': support.print_cool('green', 'No files converted') else: support.print_cool('red', 'Input invalid') return
def batch_plot(search_word, **kwargs): import plot_support plots_folder = user_setup.plots database = user_setup.database colors_qual = user_setup.colors_qual # Identifying cells to plot cell_names = [] # Initiates list for cells that will be plotted. cell_paths = [] # Initiates list for paths to cells to be plotted. finished = False # Determines if user is finished with input while finished == False: files = support.find_files(search_word, database) # Finds and returns files as list if len(files) == 1: support.print_cool('green', "Found only one file, using this.") cell_names.append( files[0].stem ) # Saves the cell name (.stem returns last path-element) cell_paths.append(str(files[0])) # Saves the full path to the cell finished = True continue support.print_files_nr(files) # prints files with nr response = support.input_cool( 'yellow', 'Which of these cells do you want to plot? Write corresponding numbers, separated with "+" (Ex: 0+2+3): ' ) c_response = response.split( '+') # Splits string by plus sign and stores new strings in list for i in range(0, len(c_response)): # Loop through all cells to plot. cell_names.append( (files[int(c_response[i])]).stem ) # Saves the cell name (.stem returns last path-element) cell_paths.append(str(files[int( c_response[i])])) # Saves the full path to the cell response2 = support.input_cool('yellow', 'Search for more cells? (yes/any): ') if response2 == 'yes': search_word = support.input_cool('yellow', 'Write new search word: ') else: finished = True for nr in range(0, len(cell_names)): list = access_data.columns(cell_paths[nr], [ 'cycle_nr', 'discharge_spec', 'charge_spec', 'cap_incr_spec', 'potential', 'cycle' ]) df = access_data.access_cell_as_string(cell_names[nr]) cycles, discharge, charge, capacity_incr, potential, cycle_incr = list[ 0][0], list[1][0], list[2][0], list[3][0], list[4][0], list[5][0] CE = [float(ai) / bi * 100 for ai, bi in zip(discharge, charge) ] # Obtaining Coulombic efficiencies fontsize = 10 fig, axs = plt.subplots(3, 2, figsize=(7, 7)) """ Capacity vs cycle nr """ axs[0, 0].scatter(cycles, discharge, color=colors_qual[0]) axs[0, 0].scatter(cycles, charge, marker='D', color=colors_qual[1]) axs[0, 0].set_xlabel('Cycle number', size=fontsize) axs[0, 0].set_ylabel('Capacity (mAh/g)', size=fontsize) axs[0, 0].tick_params(axis='both', which='major', labelsize=fontsize ) # Setting ticks size equally enlarged to fontsize axs[0, 0].tick_params(direction='in') # Ticks pointing inwards. axs[0, 0].legend(['Discharge', 'Charge'], prop={'size': fontsize}) #plt.savefig((str('C:\\Users\hennika\OneDrive - NTNU\PhD\Results\Cycling\Plots\MP1H') + '\\' + 'MP1H_D1_16_100-250mA_capacity-cycle-nr' + '.png'),format='png', dpi=1000) # > 300 DPI is recommended by NTNU in master theses. """ Coulombic efficiency """ axs[0, 1].scatter(cycles, CE, color=colors_qual[0]) axs[0, 1].set_xlabel('Cycle number', size=fontsize) axs[0, 1].set_ylabel('Coulombic efficiency (%)', size=fontsize) axs[0, 1].tick_params(axis='both', which='major', labelsize=fontsize ) # Setting ticks size equally enlarged to fontsize axs[0, 1].tick_params(direction='in') # Ticks pointing inwards. axs[0, 1].legend(['C.E.'], prop={'size': fontsize}) # plt.savefig((str('C:\\Users\hennika\OneDrive - NTNU\PhD\Results\Cycling\Plots\MP1H') + '\\' + 'MP1H_D1_16_100-250mA_capacity-cycle-nr' + '.png'),format='png', dpi=1000) # > 300 DPI is recommended by NTNU in master theses. """ Voltage profiles (all) """ color_list = plot_support.get_colors(cycle_incr, color_scheme='Blues') last_cycle = df['cycle'].as_matrix().astype( int )[-1] # Converts cycle column to int, and get last element (last cycle nr). cycles = range(0, last_cycle, 1) # Makes variable with cycles to plot (all) for i in range(0, last_cycle, 1): # Iterates through all cycles df_cycle_x = df[df['cycle'].astype(float) == cycles[i]] # Make new data frame for given cycle axs[1, 0].scatter(df_cycle_x['cap_incr_spec'].astype(float), df_cycle_x['potential'].astype(float), s=1, c=color_list[i]) axs[1, 0].set_xlabel('Capacity (mAh/g)', size=fontsize) axs[1, 0].set_ylabel('Voltage', size=fontsize) axs[1, 0].tick_params(axis='both', which='major', labelsize=fontsize ) # Setting ticks size equally enlarged to fontsize axs[1, 0].tick_params(direction='in') # Ticks pointing inwards. axs[1, 0].legend(['All cycles'], prop={'size': fontsize}) #axs[1,0].legend(['Voltage profile'], prop={'size': fontsize}) # plt.savefig((str('C:\\Users\hennika\OneDrive - NTNU\PhD\Results\Cycling\Plots\MP1H') + '\\' + 'MP1H_D1_16_100-250mA_capacity-cycle-nr' + '.png'),format='png', dpi=1000) # > 300 DPI is recommended by NTNU in master theses. """ Voltage profiles (selected) """ cycles = [1, 2, 10, 50, 100] # Makes variable with cycles to plot color_list = plot_support.get_colors(cycle_incr, cycles=cycles, color_scheme='Qualitative') for i in range(0, len(cycles), 1): # Iterates through all cycles df_cycle_x = df[df['cycle'].astype(float) == cycles[i]] # Make new data frame for given cycle axs[1, 1].scatter(df_cycle_x['cap_incr_spec'].astype(float), df_cycle_x['potential'].astype(float), s=1, c=color_list[i], label='%s' % cycles[i]) axs[1, 1].set_xlabel('Capacity (mAh/g)', size=fontsize) axs[1, 1].set_ylabel('Voltage', size=fontsize) axs[1, 1].tick_params(axis='both', which='major', labelsize=fontsize ) # Setting ticks size equally enlarged to fontsize axs[1, 1].tick_params(direction='in') # Ticks pointing inwards. axs[1, 1].legend(prop={'size': fontsize}) # plt.savefig((str('C:\\Users\hennika\OneDrive - NTNU\PhD\Results\Cycling\Plots\MP1H') + '\\' + 'MP1H_D1_16_100-250mA_capacity-cycle-nr' + '.png'),format='png', dpi=1000) # > 300 DPI is recommended by NTNU in master theses. """ Differential capacity (selected cycles) """ cycles = [1, 2, 10, 50, 100] # Makes variable with cycles to plot color_list = plot_support.get_colors(cycle_incr, cycles=cycles, color_scheme='Qualitative') for i in range(0, len(cycles), 1): # Iterates through all cycles df_cycle_x = df[df['cycle'].astype(float) == cycles[i]] # Make new data frame for given cycle axs[2, 0].scatter(df_cycle_x['potential_diff_cap'].astype(float), df_cycle_x['diff_cap'].astype(float), s=1, c=color_list[i], label='%s' % cycles[i]) axs[2, 0].set_xlabel('Potential (V)', size=fontsize) axs[2, 0].set_ylabel('Diff. capacity (mAh/g/V)', size=fontsize) axs[2, 0].tick_params(axis='both', which='major', labelsize=fontsize ) # Setting ticks size equally enlarged to fontsize axs[2, 0].tick_params(direction='in') # Ticks pointing inwards. axs[2, 0].legend(prop={'size': fontsize}) # plt.savefig((str('C:\\Users\hennika\OneDrive - NTNU\PhD\Results\Cycling\Plots\MP1H') + '\\' + 'MP1H_D1_16_100-250mA_capacity-cycle-nr' + '.png'),format='png', dpi=1000) # > 300 DPI is recommended by NTNU in master theses. """ Add more here """ axs[2, 1].text(0.35, 0.5, 'Awesome!') fig.tight_layout() # Makes sure everything is within figure """ Saving figures """ from pathlib import Path Path(str(plots_folder) + '\\' + cell_names[nr]).mkdir( parents=True, exist_ok=True ) # Make new folder for cell if it doesn't exist already resolution = 500 extent = axs[0, 0].get_window_extent().transformed( fig.dpi_scale_trans.inverted()) # Collecting subplot to save fig.savefig(str(plots_folder) + '\\' + cell_names[nr] + '\\' + 'capacity_vs_cycles.png', dpi=resolution, bbox_inches=extent.expanded(1.45, 1.5)) # Saving subplot extent = axs[1, 1].get_window_extent().transformed( fig.dpi_scale_trans.inverted()) # Collecting subplot to save fig.savefig(str(plots_folder) + '\\' + cell_names[nr] + '\\' + 'Voltage_profiles_cycle_1-2-10-50-100.png', dpi=resolution, bbox_inches=extent.expanded(1.4, 1.42)) # Saving subplot plt.show() return
def auto_plot(search_word, **kwargs): import plot_support try: if kwargs['testing'] == True: database = Path(r'..\PyBat2-master\testing\database') plots_folder = Path(r'..\PyBat2-master\testing\plots') else: database = Path(r'..\PyBat2-master\testing') plots_folder = user_setup.plots except: plots_folder = user_setup.plots database = user_setup.database # Identifying cells to plot cell_names = [] # Initiates list for cells that will be plotted. cell_paths = [] # Initiates list for paths to cells to be plotted. finished = False # Determines if user is finished with input while finished == False: files = support.find_files(search_word, database) # Finds and returns files as list support.print_files_nr(files) # prints files with nr response = support.input_cool( 'yellow', 'Which of these cells do you want to plot? Write corresponding numbers, separated with "+" (Ex: 0+2+3): ' ) c_response = response.split( '+') # Splits string by plus sign and stores new strings in list for i in range(0, len(c_response)): # Loop through all cells to plot. cell_names.append( (files[int(c_response[i])]).stem ) # Saves the cell name (.stem returns last path-element) cell_paths.append(str(files[int( c_response[i])])) # Saves the full path to the cell response2 = support.input_cool('yellow', 'Search for more cells? (yes/any): ') if response2 == 'yes': search_word = support.input_cool('yellow', 'Write new search word: ') else: finished = True try: # Checks legend and use cellnames if not found. legend_use = kwargs['legend'] except: legend_use = cell_names x1, y1, xlabel, ylabel, xlim, ylim, xticks, yticks, type, markersize, legend_list, legend_loc, legend_color_list, custom_code, custom_code_first, save_path_png, save_path_tiff = plot_support.set_plot_specs( autolegend=legend_use, **kwargs) # Sets specifications for plot pickle_name, df, cycles, color, color_list, legend_color_list, marker, markerfill = plot_support.set_pickle_specs( legend_color_list, pickle1=cell_paths[0], **kwargs) # Sets specifications for first pickle plot_support.AddPickleToPlot( df, cycles, x1, y1, color_list, type, marker, markerfill, markersize, custom_code_first) # Adds this pickle with specifications to plot for nr in range(2, len(cell_names) + 1): # try: next_pickle_response = cell_paths[ nr - 1] # Looks up index in files given by the next cell in the response next_pickle_response_nr = 'pickle' + str(nr) next_pickle_name, next_x, next_y, next_cycles, next_color, next_color_scheme, next_marker, next_markerfill = plot_support.set_next_pickle( nr, override=next_pickle_response, **kwargs) pickle_name, df, cycles, color, color_list, legend_color_list, marker, markerfill = plot_support.set_pickle_specs( legend_color_list, pickle1=next_pickle_name, cycles1=next_cycles, x1=next_x, y1=next_y, color1=next_color, color_scheme1=next_color_scheme, marker1=next_marker, markerfill1=next_markerfill) plot_support.AddPickleToPlot(df, cycles, next_x, next_y, color_list, type, marker, markerfill, markersize) # except: # continue # Script moves to next iteration, checking for yet another pickle. (should not be needed here) plot_support.plot_plot( x1, y1, xlabel, ylabel, xlim, ylim, xticks, yticks, legend_list, legend_color_list, legend_loc, custom_code, save_path_png, save_path_tiff) # Add labels and legend, and shows plot return