In [37]:
import pandas as pd
import string
from matplotlib import rc
fontsize = 12
# Make default font serif
rc('font', family=b'serif', size=fontsize)
# Hide legend frame, change size, make only one scatter marker show up
rc('legend', borderpad=0.,labelspacing=0.25, fontsize=(fontsize - 1.), frameon=False, numpoints=1)
# Default line width (e.g. for plot()) should be thinner than 1 point
rc('patch', linewidth=0.75)
rc('lines', linewidth=0.75)
In [38]:
k_ref = 1.00020
In [69]:
import re
import os
import numpy as np
import csv
class DenovoProcessor(object):
"""DenovoProcessor class: processes an output file from a Denovo calculation.
It can read a file, print that information to csv, and do some processing
for highlights."""
def __init__(self):
"""Set information we'll use in processing a Denovo output file"""
# Output variables that are in the header / problem specification
self.keys = ['problem_name', 'num cells I', 'num cells J', 'num cells K', 'cells', ' mesh ',
'num_blocks_i', 'num_blocks_j', 'num_z_blocks', 'blocks', 'num_groups',
'num upscatter groups', 'num_sets', 'domains', 'Pn_order', 'azimuthals_octant',
'polars_octant', 'eq_set', 'DoF', ' tolerance', 'L2_tolerance', 'k_tolerance',
'up_tol', 'eigen_solver', 'mg_preconditioner', 'relax_count', 'num_v_cycles',
'relax_weight', 'ml_Pn', 'ml_az', 'ml_oct']
# Information about timing and processor distribution
self.time_keys = ['procs-per-node-x', 'procs-per-node-y', 'walltime']
# iteration information; place holder for iter_dict until set by solver
self.iter_info = np.empty([1,5])
self.k = {'eigenvalue of' : 1}
self.iter_dict = {}
def parse_file(self, out_file):
"""Read the values for the keys from out_file"""
# save file neame for later reporting
self.out_file = out_file
# Initalize values to match keys to None
self.vals = {key: None for key in self.keys}
self.time_vals = {key: None for key in self.time_keys}
# Set flags and keys to use for items with duplicate entries
ml_flag = False
ml_keys = ['Pn_order', 'azimuthals_octant', 'polars_octant']
ml_doubles = {key: None for key in ml_keys}
ml_cnt = 0
up_db = False
e_solver = False
# open the file
if os.path.isfile(self.out_file):
f = open(self.out_file, 'r')
else:
raise IOError('could not find file', self.out_file)
# We will use an iteration count index to make sure we're putting iter info into
# the correct row
iter_count = 0
#try:
# Process the file
for line in f:
# the iteration keys vary by eigen solver. Once we know which solver, set keys.
# We'll use them to map into which column in a list the data needs to be enetered into
if (e_solver == False):
if (self.vals['eigen_solver'] != None):
if self.vals['eigen_solver'] == 'rayleigh_quotient':
self.iter_dict = {'Iterations =' : 4, 'Eigenvalue Iteration ' : 0,
'relative error in k-eff of ' : 2,
'absolute error in k-eff of ' : 3}
elif self.vals['eigen_solver'] == 'power_iteration':
self.iter_dict = {'Iterations =' : 4, 'Eigenvalue iteration ' : 0,
'relative error in k-eff of ' : 2,
'max. rel. error in fissions of ' : 3}
else:
raise IOError('unknown eigenvalue solver', self.vals['eigen_solver'])
e_solver = True # don't reenter this loop
# check for the duplicate items (that are in sub databases)
# before processing everything else
if ml_flag == True:
if ml_cnt != 3:
for ml_key in ml_doubles:
if re.search(ml_key, line):
if ml_doubles[ml_key] == None:
data = line.split(ml_key)
ml_doubles[ml_key] = data[1].strip()
ml_cnt = ml_cnt + 1
# We know that the upscatter tolerance is printed after the regular tolerance
# Thus, if up_db is true this tolerance is the upscatter tolerance. Also, store
# what's currently in tolerance to reset at the end
if up_db == True:
if re.search('tolerance', line):
if self.vals['up_tol'] == None:
data = line.split('tolerance')
self.vals['up_tol'] = data[1].strip()
tol = self.vals[' tolerance']
# Information in the header
for key in self.vals:
# check for things to set the flags
if re.search('multilevel_quad_db', line):
ml_flag = True
if re.search('upscatter_db', line):
up_db = True
# now look for the rest of the keys
if re.search(key, line):
data = line.split(key)
self.vals[key] = data[1].strip()
# Time and CUDA information
for key in self.time_vals:
if re.search(key, line):
data = line.split(key)
num = data[1].strip().split()
self.time_vals[key] = num[0].strip()
# Iteration information
for key in self.iter_dict:
if re.search(key, line):
data = line.split(key)
num = data[1].strip().split()
self.iter_info[iter_count][self.iter_dict[key]] = num[0].strip()
# increment the counter after reading absolute error row, add an empty row
if ((key == 'absolute error in k-eff of ') or (key == 'max. rel. error in fissions of ')):
iter_count = iter_count + 1
self.iter_info = np.vstack((self.iter_info, np.empty([1,5])))
# k; need separately since it's on the same line as iteration #
for key in self.k:
if re.search(key, line):
data = line.split(key)
num = data[1].strip().split()
self.iter_info[iter_count][self.k[key]] = num[0].strip()
f.close()
# calculate things we want in the spreadsheet
self.vals['cells'] = int(self.vals['num cells I']) * int(self.vals['num cells J']) * \
int(self.vals['num cells K'])
self.vals['blocks'] = int(self.vals['num_blocks_i']) * int(self.vals['num_blocks_j'])
self.vals['domains'] = int(self.vals['blocks']) * int(self.vals['num_sets'])
# set doubles
if ml_flag == True:
self.vals['ml_Pn'] = ml_doubles['Pn_order']
self.vals['ml_az'] = ml_doubles['azimuthals_octant']
self.vals['ml_oct'] = ml_doubles['polars_octant']
if up_db == True:
self.vals[' tolerance'] = tol
# the last iteration row gets filled with garbage; don't use it.
self.iter_info = self.iter_info[0:-1]
# print the parsed information to file
def print_csv(self, name):
"""Print the read in data to name.csv"""
# itereation keys we'd like to print since they have nicer names
iter_keys = ['eigen_iters', 'k', 'rel_err_k', 'abs_err_k', 'fxd_iters']
# store filename for printing later
self.csv = name
with open(self.csv+'.csv', 'wb') as csvfile:
# write the header / problem specification information
writer = csv.DictWriter(csvfile, fieldnames = self.keys, dialect='excel',
restval='',extrasaction='ignore')
#if not csv.Sniffer().has_header(csvfile.read(1024)):
writer.writeheader()
writer.writerow(self.vals)
# Now write timing information
writer = csv.DictWriter(csvfile, fieldnames = self.time_keys, dialect='excel',
restval='',extrasaction='ignore')
writer.writeheader()
writer.writerow(self.time_vals)
# And iteration information
# we need a regular writer for the list
writer = csv.writer(csvfile)
writer.writerow(iter_keys)
writer.writerows(self.iter_info)
print "Wrote csv file", self.csv, "\n"
# We want the k on the last iteration, the total number of fixed iters, last rel and abs err
# eigen solver, preconditioner data, wall time
def highlights(self):
"""Print some highlights we care about most"""
# Get total number of inner iterations the last row of iteration information
end_info = self.iter_info[-1]
# sum the total number of inner iterations
total_inner = int(np.sum(self.iter_info, axis=0)[self.iter_dict['Iterations =']])
# print
print "From results file", self.out_file, "\n"
if self.vals['eigen_solver'] == 'rayleigh_quotient':
print "After ", self.time_vals['walltime'], "minutes,", \
self.iter_info[-1][self.iter_dict['Eigenvalue Iteration ']], "eigenvalue iterations, and", \
total_inner, "total inner iterations,"
print "k was", self.iter_info[:][self.k['eigenvalue of']], "with relative error",\
self.iter_info[-1][self.iter_dict['relative error in k-eff of ']], "and absolute error",\
self.iter_info[-1][self.iter_dict['absolute error in k-eff of ']]
elif self.vals['eigen_solver'] == 'power_iteration':
print "After ", self.time_vals['walltime'], "minutes,", \
self.iter_info[-1][self.iter_dict['Eigenvalue iteration ']], "eigenvalue iterations, and", \
total_inner, "total inner iterations,"
print "k was", self.iter_info[-1][self.k['eigenvalue of']], "with relative error",\
self.iter_info[-1][self.iter_dict['relative error in k-eff of ']], "and max. rel. error in fissions",\
self.iter_info[-1][self.iter_dict['max. rel. error in fissions of ']]
else:
raise IOError('unknown eigenvalue solver', self.vals['eigen_solver'])
In [70]:
# Name of the file containing the output we want to process
file_location = '/home/slayer/Dropbox/Research/Calculations/Denovo/bw1484'
# Get a DenovoProcessor
processor = DenovoProcessor()
# Make a list of files to process
files = ['bw1484_m20g8qr612_nosets.out', 'bw1484_m20g8qr612.out', 'bw1484_m20g8qr612_pi.out',
'bw1484_m20g8qr612_w1.1r3v2.out', 'bw1484_small.out']
#files=['bw1484_m20g8qr612_pi.out']
for file_name in files:
full_out_file = os.path.join(file_location, file_name)
# parse the file, and write to csv
processor.__init__()
processor.parse_file(full_out_file)
processor.print_csv(full_out_file[0:-4])
processor.highlights()
print "\n\n-----------------------------\n"
In [ ]: