Source code for model_package.Calibrate.build_calibration_map

#!python
import argparse
import pathlib
import sys
import yaml

import numpy
import pandas

import calibration_tools


[docs] def ignored_elements_calibration_map(output_file, best_parameters_yml_no_BCs, boundary_csv, previous_calibration_map): '''Create a yaml file to map calibration results for interior and boundary elements :params str output_file: The name of the output yaml file :params str best_parameters_yml_no_BCs: A yaml file containing the 'best' calibration using the kernel density estimate for elements not on the boundary :params str boundary_csv: A csv file containing list of boundary elements :params str previous_calibration_map: A csv file containing a previous calibration map for all elements to be modified :returns: Write ``output_file`` ''' previous_parameter_df = pandas.read_csv(previous_calibration_map) boundary_elements_df = pandas.read_csv(boundary_csv) boundary_elements = list(boundary_elements_df['boundary_elements'].values) # if all elements are on boundary, overwrite name of best_parameters_yml_no_BCs to be best_parameters_yml if len(list(previous_parameter_df.index)) == len(boundary_elements): print('It looks like all elements are on the boundary! Forcing best_parameters_yml_no_BCs to be best_parameters_yml') best_parameters_yml_no_BCs = f'{best_parameters_yml_no_BCs.split("_no_BCs")[0]}.yml' # Unpack best_parameters_yml_no_BCs temp_dict = {} best_params, best_parameter_ordering = calibration_tools.parse_fparams_file(best_parameters_yml_no_BCs, material_type='plastic') for param, param_name in zip(best_params, best_parameter_ordering): temp_dict[param_name] = param temp_dict['obj_func_value'] = 0.0 # Build new parameter dictionary headers = list(previous_parameter_df.columns) headers.remove('element') for index in previous_parameter_df.index: if int(previous_parameter_df.loc[index]['element'] in boundary_elements): element_id = int(previous_parameter_df.loc[index]['element']) for column in headers: #previous_parameter_df.loc[index][column] = temp_dict[column] previous_parameter_df.at[index, column] = temp_dict[column] # DataFrame and output previous_parameter_df['element'] = previous_parameter_df['element'].astype(int) previous_parameter_df = previous_parameter_df.sort_values(by='element') previous_parameter_df.to_csv(output_file, header=True, sep=',', index=False) return 0
[docs] def full_csv_calibration_map(output_file, calibrated_elements, calibrated_files, material_type): '''Create a file mapping calibration results for each macroscale element :params str output_file: The name of the output file :params list calibrated_elements: A list of elements with associated calibration files :params list calibrated_files: A list of files containing calibration results :param str material_type: The material type: 'elastic', 'plastic', or 'full_plastic' :returns: Write ``output_file`` ''' # set up header _, parameter_header = calibration_tools.parse_fparams_file(calibrated_files[0], material_type) header = ['element'] + parameter_header # unpack values out_params = [] for element, file in zip(calibrated_elements, calibrated_files): parameters, _ = calibration_tools.parse_fparams_file(file, material_type) if len(out_params) == 0: out_params = numpy.hstack([float(element), parameters]) else: out_params = numpy.vstack([out_params, numpy.hstack([float(element), parameters])]) # handle single domain case if len(numpy.shape(out_params)) == 1: out_params = out_params.reshape((1, -1)) # DataFrame and output df = pandas.DataFrame(out_params, columns=header) df['element'] = df['element'].astype(int) df = df.sort_values(by='element') df.to_csv(output_file, header=True, sep=',', index=False) return 0
[docs] def trim_csv_file_for_tardigrade(output_file, input_file): '''Remove 'element' and 'obj_func_value' columns from a csv file containing calibration results :params str output_file: The name of the output csv file :params str input_csv: An input, previously generated csv file to be trimmed for Tardigrade :returns: Write ``output_file`` ''' df = pandas.read_csv(input_file) headers = list(df.columns) if 'element' in headers: df = df.drop('element', axis=1) if 'obj_func_value' in headers: df = df.drop('obj_func_value', axis=1) df.to_csv(output_file, header=False, sep=',', index=False) return 0
[docs] def build_calibration_map(output_file, calibrated_elements=None, calibrated_files=None, map_type='full_csv', material_type=None, best_parameters_yml_no_BCs=None, boundary_csv=None, previous_calibration_map=None, input_csv=None): '''Create a file mapping calibration results for each macroscale element :params str output_file: The name of the output csv file :params list calibrated_elements: A list of elements with associated calibration files :params list calibrated_files: A list of files containing calibration results :params str map_type: The type of calibration map to generate. 'full_csv' (default) to create a csv file containing material parameters mapped for every element. 'ignore_boundary_yaml' to create a yaml file containing names of yaml files containing material parameters for every element. :param str material_type: The material type: 'elastic', 'plastic', or 'full_plastic' :params str best_parameters_yml_no_BCs: A yaml file containing the 'best' calibration using the kernel density estimate for elements not on the boundary :params str boundary_csv: A csv file containing list of boundary elements :params str previous_calibration_map: A csv file containing a previous calibration map for all elements to be modified :params str input_csv: An input, previously generated csv file using 'map_type=full_csv' to be trimmed for Tardigrade :returns: Call full_csv_calibration_map function if map_type='full_csv', call ignored_elements_calibration_map function if map_type='ignore_boundary_yaml', or call trim_csv_file_for_tardigrade if map_type='trim_for_tardigrade' ''' if map_type == 'full_csv': assert calibrated_elements != None, "List of calibrated elements must be provided!" assert calibrated_files != None, "List of calibration files must be provided!" assert len(calibrated_elements) == len(calibrated_files), "Length of calibrated_elements must equal calibrated_files!" assert material_type != None, "material_type must be specified!" full_csv_calibration_map(output_file, calibrated_elements, calibrated_files, material_type) elif map_type == 'ignore_boundary_yaml': assert best_parameters_yml_no_BCs != None, "best_parameters_yml_no_BCs must be provided!" assert boundary_csv != None, "boundary_csv must be provided!" assert previous_calibration_map != None, "previous_calibration_map must be provided!" ignored_elements_calibration_map(output_file, best_parameters_yml_no_BCs, boundary_csv, previous_calibration_map) elif map_type == 'trim_for_tardigrade': assert input_csv != None, "input_csv must be specified!" trim_csv_file_for_tardigrade(output_file, input_csv) else: raise NameError('Specify a valid map_type!') return 0
def get_parser(): script_name = pathlib.Path(__file__) prog = f"python {script_name.name} " cli_description = "Create a file mapping calibration results for each macroscale element" parser=argparse.ArgumentParser(description=cli_description, prog=prog) parser.add_argument('--output-file', type=str, required=True, help="The name of the output csv file") parser.add_argument('--calibrated-elements', nargs="+", required=False, help="A list of elements with associated calibration files") parser.add_argument('--calibrated-files', nargs="+", required=False, help="A list of files containing calibration results") parser.add_argument('--map-type', type=str, required=False, default="full_csv", help="The type of calibration map to generate. 'full_csv' (default) to create a csv\ file containing material parameters mapped for every element.\ 'ignore_boundary_yaml' to create a new calibration map with boundary element parameters\ swapped with best_parameters_yml_no_BCs.\ 'trim_for_tardigrade' to modify a previously generated csv file for Tardigrade") parser.add_argument('--material-type', type=str, required=False, default=None, help="The material type: 'elastic', 'plastic', or 'full_plastic'") parser.add_argument('--best-parameters-yml-no-BCs', type=str, required=False, default=None, help="A yaml file containing the 'best' calibration using the kernel density estimate for elements not on the boundary") parser.add_argument('--boundary-csv', type=str, required=False, default=None, help="A csv file containing list of boundary elements") parser.add_argument('--previous-calibration-map', type=str, required=False, default=None, help="A csv file containing a previous calibration map for all elements to be modified") parser.add_argument('--input-csv', type=str, required=False, default=None, help="An input, previously generated csv file using 'map_type=full_csv' to be trimmed for Tardigrade") return parser if __name__ == '__main__': parser = get_parser() args, unknown = parser.parse_known_args() sys.exit(build_calibration_map(output_file=args.output_file, calibrated_elements=args.calibrated_elements, calibrated_files=args.calibrated_files, map_type=args.map_type, material_type=args.material_type, best_parameters_yml_no_BCs=args.best_parameters_yml_no_BCs, boundary_csv=args.boundary_csv, previous_calibration_map=args.previous_calibration_map, input_csv=args.input_csv, ))