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)

BW1484 Core I Output


In [38]:
k_ref = 1.00020

Denovo ouput file processor


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'])



Process a bunch of files


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"


Wrote csv file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612_nosets 

From results file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612_nosets.out 

After  21630 minutes, 3.0 eigenvalue iterations, and 46 total inner iterations,
k was [  2.           0.09167725   9.957958     0.9129182   22.        ] with relative error 0.01725755 and absolute error 0.01733686


-----------------------------

Wrote csv file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612 

From results file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612.out 

After  21612 minutes, 4.0 eigenvalue iterations, and 148 total inner iterations,
k was [  2.           0.08774086  10.44698      0.9166266   23.        ] with relative error 0.003971347 and absolute error 0.00405822


-----------------------------

Wrote csv file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612_pi 

From results file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612_pi.out 

After  21607 minutes, 5.0 eigenvalue iterations, and 375 total inner iterations,
k was 1.0238926044 with relative error 0.003272098 and max. rel. error in fissions 2176.228


-----------------------------

Wrote csv file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612_w1.1r3v2 

From results file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_m20g8qr612_w1.1r3v2.out 

After  21626 minutes, 5.0 eigenvalue iterations, and 147 total inner iterations,
k was [  2.           0.11964619   7.406432     0.8861514   19.        ] with relative error 0.0007715661 and absolute error 0.0007918378


-----------------------------

Wrote csv file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_small 

From results file /home/slayer/Dropbox/Research/Calculations/Denovo/bw1484/bw1484_small.out 

After  7211 minutes, 59.0 eigenvalue iterations, and 2679 total inner iterations,
k was [  2.           0.06380217  14.90793      0.951158    24.        ] with relative error 0.01693561 and absolute error 0.01748288


-----------------------------


In [ ]: