def generate_protocol_files_from_csv(csv_filename, output_directory=None): """ Generates a set of protocol files from csv filename input by reading protocol file input corresponding to each line of the csv file. Writes a csv file that. Args: csv_filename (str): CSV containing protocol file parameters. output_directory (str): directory in which to place the output files """ # Read csv file protocol_params_df = pd.read_csv(csv_filename) new_files = [] names = [] result = '' message = {'comment': '', 'error': ''} if output_directory is None: output_directory = PROCEDURE_TEMPLATE_DIR for index, protocol_params in protocol_params_df.iterrows(): template = protocol_params['template'] # Switch for template invocation if template == "EXP.000": procedure = Procedure.from_exp(**protocol_params[ ["cutoff_voltage", "charge_rate", "discharge_rate"]]) elif template == 'diagnosticV2.000': diag_params_df = pd.read_csv( os.path.join(PROCEDURE_TEMPLATE_DIR, "PreDiag_parameters - DP.csv")) diagnostic_params = diag_params_df[ diag_params_df['diagnostic_parameter_set'] == protocol_params['diagnostic_parameter_set']].squeeze() # TODO: should these be separated? procedure = Procedure.from_regcyclev2(protocol_params) procedure.add_procedure_diagcyclev2( protocol_params["capacity_nominal"], diagnostic_params) # TODO: how are these different? elif template in ['diagnosticV3.000', 'diagnosticV4.000']: diag_params_df = pd.read_csv( os.path.join(PROCEDURE_TEMPLATE_DIR, "PreDiag_parameters - DP.csv")) diagnostic_params = diag_params_df[ diag_params_df['diagnostic_parameter_set'] == protocol_params['diagnostic_parameter_set']].squeeze() procedure = Procedure.generate_procedure_regcyclev3( index, protocol_params) procedure.generate_procedure_diagcyclev3( protocol_params["capacity_nominal"], diagnostic_params) else: warnings.warn( "Unsupported file template {}, skipping.".format(template)) result = "error" message = { 'comment': 'Unable to find template: ' + template, 'error': 'Not Found' } continue filename_prefix = '_'.join([ protocol_params["project_name"], '{:06d}'.format(protocol_params["seq_num"]) ]) filename = "{}.000".format(filename_prefix) filename = os.path.join(output_directory, 'procedures', filename) logger.info(filename, extra=s) if not os.path.isfile(filename): procedure.to_file(filename) new_files.append(filename) names.append(filename_prefix + '_') elif '.sdu' in template: logger.warning('Schedule file generation not yet implemented', extra=s) result = "error" message = { 'comment': 'Schedule file generation is not yet implemented', 'error': 'Not Implemented' } # This block of code produces the file containing all of the run file # names produced in this function call. This is to make starting tests easier _, namefile = os.path.split(csv_filename) namefile = namefile.split('_')[0] + '_names_' namefile = namefile + datetime.datetime.now().strftime( "%Y%m%d_%H%M") + '.csv' with open(os.path.join(output_directory, "names", namefile), 'w', newline='') as outputfile: wr = csv.writer(outputfile) for name in names: wr.writerow([name]) outputfile.close() if not result: result = "success" message = { 'comment': 'Generated {} protocols'.format(str(len(new_files))), 'error': '' } return new_files, result, message
def generate_protocol_files_from_csv(csv_filename, output_directory=None): """ Generates a set of protocol files from csv filename input by reading protocol file input corresponding to each line of the csv file. Writes a csv file that. Args: csv_filename (str): CSV containing protocol file parameters. output_directory (str): directory in which to place the output files """ # Read csv file protocol_params_df = pd.read_csv(csv_filename) new_files = [] names = [] result = "" message = {"comment": "", "error": ""} if output_directory is None: output_directory = PROCEDURE_TEMPLATE_DIR for index, protocol_params in protocol_params_df.iterrows(): template = protocol_params["template"] # Filename for the output filename_prefix = "_".join( [ protocol_params["project_name"], "{:06d}".format(protocol_params["seq_num"]), ] ) # Switch for template invocation if template == "EXP.000": protocol = Procedure.from_exp( **protocol_params[["cutoff_voltage", "charge_rate", "discharge_rate"]] ) filename = "{}.000".format(filename_prefix) filename = os.path.join(output_directory, "procedures", filename) elif template == "diagnosticV2.000": diag_params_df = pd.read_csv( os.path.join(PROCEDURE_TEMPLATE_DIR, "PreDiag_parameters - DP.csv") ) diagnostic_params = diag_params_df[ diag_params_df["diagnostic_parameter_set"] == protocol_params["diagnostic_parameter_set"] ].squeeze() # TODO: should these be separated? protocol = Procedure.from_regcyclev2(protocol_params) protocol.add_procedure_diagcyclev2( protocol_params["capacity_nominal"], diagnostic_params ) filename = "{}.000".format(filename_prefix) filename = os.path.join(output_directory, "procedures", filename) # TODO: how are these different? elif template in ["diagnosticV3.000", "diagnosticV4.000"]: diag_params_df = pd.read_csv( os.path.join(PROCEDURE_TEMPLATE_DIR, "PreDiag_parameters - DP.csv") ) diagnostic_params = diag_params_df[ diag_params_df["diagnostic_parameter_set"] == protocol_params["diagnostic_parameter_set"] ].squeeze() protocol = Procedure.generate_procedure_regcyclev3(index, protocol_params) protocol.generate_procedure_diagcyclev3( protocol_params["capacity_nominal"], diagnostic_params ) filename = "{}.000".format(filename_prefix) filename = os.path.join(output_directory, "procedures", filename) elif template == "formationV1.mps": protocol = Settings.from_file(os.path.join(BIOLOGIC_TEMPLATE_DIR, template)) protocol = protocol.formation_protocol_bcs(protocol, protocol_params) filename = "{}.mps".format(filename_prefix) filename = os.path.join(output_directory, "settings", filename) else: warnings.warn("Unsupported file template {}, skipping.".format(template)) result = "error" message = { "comment": "Unable to find template: " + template, "error": "Not Found", } continue logger.info(filename, extra=s) if not os.path.isfile(filename): protocol.to_file(filename) new_files.append(filename) names.append(filename_prefix + "_") elif ".sdu" in template: logger.warning("Schedule file generation not yet implemented", extra=s) result = "error" message = { "comment": "Schedule file generation is not yet implemented", "error": "Not Implemented", } # This block of code produces the file containing all of the run file # names produced in this function call. This is to make starting tests easier _, namefile = os.path.split(csv_filename) namefile = namefile.split("_")[0] + "_names_" namefile = namefile + datetime.datetime.now().strftime("%Y%m%d_%H%M") + ".csv" with open( os.path.join(output_directory, "names", namefile), "w", newline="" ) as outputfile: wr = csv.writer(outputfile) for name in names: wr.writerow([name]) outputfile.close() if not result: result = "success" message = { "comment": "Generated {} protocols".format(str(len(new_files))), "error": "", } return new_files, result, message
def generate_protocol_files_from_csv(csv_filename, output_directory=None): """ Generates a set of protocol files from csv filename input by reading protocol file input corresponding to each line of the csv file. Writes a csv file that. Args: csv_filename (str): CSV containing protocol file parameters. output_directory (str): directory in which to place the output files """ # Read csv file protocol_params_df = pd.read_csv(csv_filename) successfully_generated_files = [] file_generation_failures = [] names = [] result = "" message = {"comment": "", "error": ""} if output_directory is None: output_directory = PROCEDURE_TEMPLATE_DIR for index, protocol_params in protocol_params_df.iterrows(): template = protocol_params["template"] protocol = None # Filename for the output filename_prefix = "_".join( [ protocol_params["project_name"], "{:06d}".format(protocol_params["seq_num"]), ] ) if ".000" in template: # Extension for maccor procedure files template_fullpath = os.path.join(PROCEDURE_TEMPLATE_DIR, template) template_length = template_detection(template_fullpath) if "diagnostic_parameter_set" in protocol_params: # For parameters include diagnostics load those values diag_params_df = pd.read_csv( os.path.join(PROCEDURE_TEMPLATE_DIR, "PreDiag_parameters - DP.csv") ) diagnostic_params = diag_params_df[ diag_params_df["diagnostic_parameter_set"] == protocol_params["diagnostic_parameter_set"] ].squeeze() if template_length == 23 and template == "EXP.000": # length and name for initial procedure files protocol = Procedure.from_exp( **protocol_params[["cutoff_voltage", "charge_rate", "discharge_rate"]] ) elif template_length == 72: # length for V1 and V1 diagnostic templates without ending diagnostics protocol = Procedure.from_regcyclev2(protocol_params) protocol.add_procedure_diagcyclev2( protocol_params["capacity_nominal"], diagnostic_params ) elif template_length == 96: # template length for diagnostic type cycling mwf_dir = os.path.join(output_directory, "mwf_files") if protocol_params["project_name"] == "RapidC": # Project with charging waveform waveform_name = insert_charging_parametersv1(protocol_params, waveform_directory=mwf_dir) protocol = Procedure.generate_procedure_chargingv1(index, protocol_params, waveform_name, template=template_fullpath) elif protocol_params["project_name"] == "Drive": # Project with discharging waveform waveform_name = insert_driving_parametersv1(protocol_params, waveform_directory=mwf_dir) protocol = Procedure.generate_procedure_drivingv1(index, protocol_params, waveform_name, template=template_fullpath) else: # Use the default parameterization for PreDiag/Prediction Diagnostic projects protocol = Procedure.generate_procedure_regcyclev3(index, protocol_params, template=template_fullpath) protocol.generate_procedure_diagcyclev3( protocol_params["capacity_nominal"], diagnostic_params ) else: # Case where its not possible to match the procedure template failure = { "comment": "Unable to find template: " + template, "error": "Not Found", } file_generation_failures.append(failure) warnings.warn("Unsupported file template {}, skipping.".format(template)) result = "error" continue filename = "{}.000".format(filename_prefix) filename = os.path.join(output_directory, "procedures", filename) elif ".mps" in template and template == "formationV1.mps": # biologic settings template and formation project protocol = Settings.from_file(os.path.join(BIOLOGIC_TEMPLATE_DIR, template)) protocol = protocol.formation_protocol_bcs(protocol_params) filename = "{}.mps".format(filename_prefix) filename = os.path.join(output_directory, "settings", filename) elif ".sdu" in template: # No schedule file templates implemented failure = { "comment": "Schedule file generation is not yet implemented", "error": "Not Implemented" } file_generation_failures.append(failure) logger.warning("Schedule file generation not yet implemented", extra=s) result = "error" continue else: # Unable to match to any known template format failure = { "comment": "Unable to find template: " + template, "error": "Not Found", } file_generation_failures.append(failure) warnings.warn("Unsupported file template {}, skipping.".format(template)) result = "error" continue logger.info(filename, extra=s) protocol.to_file(filename) successfully_generated_files.append(filename) names.append(filename_prefix + "_") # This block of code produces the file containing all of the run file # names produced in this function call. This is to make starting tests easier _, namefile = os.path.split(csv_filename) namefile = namefile.split("_")[0] + "_names_" namefile = namefile + datetime.datetime.now().strftime("%Y%m%d_%H%M") + ".csv" names_dir = os.path.join(output_directory, "names") os.makedirs(names_dir, exist_ok=True) with open(os.path.join(names_dir, namefile), "w", newline="") as outputfile: wr = csv.writer(outputfile) for name in names: wr.writerow([name]) outputfile.close() num_generated_files = len(successfully_generated_files) num_generation_failures = len(file_generation_failures) num_files = num_generated_files + num_generation_failures message = { "comment": "Generated {} of {} protocols".format(num_generated_files, num_files), "error": "" } if not result: result = "success" else: message["error"] = "Failed to generate {} of {} protocols".format(num_generation_failures, num_files) logger.error(message["error"]) return successfully_generated_files, file_generation_failures, result, message