This script is a subset of a larger script where I have the output of many test simulations in the form of CSVs. Each file starts with the model name and includes the number of elements in my file. For example, edge_16elem_out.csv
would be a first-order model (edge) with 16 elements. Another example would be edge3_1024elem_out.csv
. I have created several helper functions and am curious if there are ways to improve this code. I am using Python 2.7.
import pandas as pd
import numpy as np
import glob
import os
import re
def k(x, q=1200, g=1, l=11, k=3, t0=300):
"""Analytic Computation - Equation can be found in ./heat_source_bar.i"""
return ((q - np.exp(-g * l) * x * q * g - np.exp(-g * x) * q) / (k * g)) + t0
def slope(x, y):
"""Computes slope in log-log terms"""
return (y.diff() / x.diff()).fillna(0)
def compute_error(analytic, simulation):
"""Error Computation - calculates a percentage from simulated answer to analytical answer"""
return np.log10(np.abs((analytic - simulation) / analytic))
def get_basename(fp):
"""Fetches basename of a given file path w/ file extension truncated"""
return os.path.splitext(os.path.basename(fp))[0]
def get_model_num(fp):
"""Extracts number of radial elements from given file path
(Ex. edge3_16elem_out.csv will return 16)"""
var = str(get_basename(fp).split('_')[1])
return int(re.search(r'\d+', var).group(0))
def get_model_type(fp, prefix):
"""Helper function to be able to get different model
types by determining model type from file path prefix"""
return filter(lambda x: get_basename(x).startswith(prefix), fp)
def read_assign(fp, model_id):
"""Read in csv and create column assigning model number as column"""
return pd.read_csv(fp).assign(model_id=model_id)
def main():
working_dir = os.path.abspath('.')
file_paths = glob.glob(os.path.join(working_dir, '*_out.csv'))
edge_files = get_model_type(file_paths, 'edge_')
edge_ids = map(get_model_num, edge_files)
edge_sol = (pd.concat(map(read_assign, edge_files, edge_ids))
.sort_values('model_id')
.query('time == 1')
.assign(points = [5.5 for x in range(11)])
.assign(t_sol = lambda x: k(x.points)))
edge_err = (edge_sol
.assign(t_err = compute_error(edge_sol.t_sol, edge_sol.point),
log_model_id = np.log10(1/edge_sol.model_id))
.assign(slope = lambda x: slope(x.log_model_id, x.t_err)))
edge_err.to_csv('edge_err.csv')
if __name__ == '__main__':
main()
```