1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#! /usr/bin/env python 2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# 3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# btt_plot.py: Generate matplotlib plots for BTT generate data files 4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# 5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# (C) Copyright 2009 Hewlett-Packard Development Company, L.P. 6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# 7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# This program is free software; you can redistribute it and/or modify 8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# it under the terms of the GNU General Public License as published by 9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# the Free Software Foundation; either version 2 of the License, or 10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# (at your option) any later version. 11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# 12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# This program is distributed in the hope that it will be useful, 13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# but WITHOUT ANY WARRANTY; without even the implied warranty of 14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# GNU General Public License for more details. 16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# 17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# You should have received a copy of the GNU General Public License 18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# along with this program; if not, write to the Free Software 19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# 21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat""" 23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatbtt_plot.py: Generate matplotlib plots for BTT generated data files 24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San MehatFiles handled: 26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat AQD - Average Queue Depth Running average of queue depths 27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat BNOS - Block numbers accessed Markers for each block 29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat Q2D - Queue to Issue latencies Running averages 31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat D2C - Issue to Complete latencies Running averages 32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat Q2C - Queue to Complete latencies Running averages 33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San MehatUsage: 35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat btt_plot_aqd.py equivalent to: btt_plot.py -t aqd <type>=aqd 36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat btt_plot_bnos.py equivalent to: btt_plot.py -t bnos <type>=bnos 37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat btt_plot_q2d.py equivalent to: btt_plot.py -t q2d <type>=q2d 38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat btt_plot_d2c.py equivalent to: btt_plot.py -t d2c <type>=d2c 39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat btt_plot_q2c.py equivalent to: btt_plot.py -t q2c <type>=q2c 40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San MehatArguments: 42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat [ -A | --generate-all ] Default: False 43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat [ -L | --no-legend ] Default: Legend table produced 44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat [ -o <file> | --output=<file> ] Default: <type>.png 45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat [ -T <string> | --title=<string> ] Default: Based upon <type> 46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat [ -v | --verbose ] Default: False 47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat <data-files...> 48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat The -A (--generate-all) argument is different: when this is specified, 50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat an attempt is made to generate default plots for all 5 types (aqd, bnos, 51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat q2d, d2c and q2c). It will find files with the appropriate suffix for 52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat each type ('aqd.dat' for example). If such files are found, a plot for 53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat that type will be made. The output file name will be the default for 54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat each type. The -L (--no-legend) option will be obeyed for all plots, 55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat but the -o (--output) and -T (--title) options will be ignored. 56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat""" 57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat__author__ = 'Alan D. Brunelle <alan.brunelle@hp.com>' 59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport matplotlib 63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatmatplotlib.use('Agg') 64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport getopt, glob, os, sys 65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatimport matplotlib.pyplot as plt 66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatplot_size = [10.9, 8.4] # inches... 68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatadd_legend = True 70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatgenerate_all = False 71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatoutput_file = None 72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehattitle_str = None 73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehattype = None 74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatverbose = False 75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehattypes = [ 'aqd', 'q2d', 'd2c', 'q2c', 'bnos' ] 77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatprogs = [ 'btt_plot_%s.py' % t for t in types ] 78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatget_base = lambda file: file[file.find('_')+1:file.rfind('_')] 80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef fatal(msg): 83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Generate fatal error message and exit""" 84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat print >>sys.stderr, 'FATAL: %s' % msg 86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sys.exit(1) 87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#---------------------------------------------------------------------- 89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef get_data(files): 90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Retrieve data from files provided. 91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat Returns a database containing: 93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 'min_x', 'max_x' - Minimum and maximum X values found 94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 'min_y', 'max_y' - Minimum and maximum Y values found 95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 'x', 'y' - X & Y value arrays 96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 'ax', 'ay' - Running average over X & Y -- 97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if > 10 values provided... 98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """ 99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #-------------------------------------------------------------- 100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def check(mn, mx, v): 101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Returns new min, max, and float value for those passed in""" 102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat v = float(v) 104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if mn == None or v < mn: mn = v 105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if mx == None or v > mx: mx = v 106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return mn, mx, v 107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #-------------------------------------------------------------- 109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def avg(xs, ys): 110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Computes running average for Xs and Ys""" 111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #------------------------------------------------------ 113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def _avg(vals): 114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Computes average for array of values passed""" 115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total = 0.0 117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for val in vals: 118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat total += val 119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return total / len(vals) 120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #------------------------------------------------------ 122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if len(xs) < 1000: 123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return xs, ys 124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat axs = [xs[0]] 126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ays = [ys[0]] 127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat _xs = [xs[0]] 128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat _ys = [ys[0]] 129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat x_range = (xs[-1] - xs[0]) / 100 131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for idx in range(1, len(ys)): 132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (xs[idx] - _xs[0]) > x_range: 133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat axs.append(_avg(_xs)) 134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ays.append(_avg(_ys)) 135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat del _xs, _ys 136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat _xs = [xs[idx]] 138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat _ys = [ys[idx]] 139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat _xs.append(xs[idx]) 141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat _ys.append(ys[idx]) 142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if len(_xs) > 1: 144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat axs.append(_avg(_xs)) 145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ays.append(_avg(_ys)) 146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return axs, ays 148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #-------------------------------------------------------------- 150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat global verbose 151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db = {} 153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat min_x = max_x = min_y = max_y = None 154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for file in files: 155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if not os.path.exists(file): 156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal('%s not found' % file) 157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif verbose: 158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat print 'Processing %s' % file 159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat xs = [] 161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ys = [] 162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for line in open(file, 'r'): 163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat f = line.rstrip().split(None) 164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if line.find('#') == 0 or len(f) < 2: 165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue 166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (min_x, max_x, x) = check(min_x, max_x, f[0]) 167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (min_y, max_y, y) = check(min_y, max_y, f[1]) 168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat xs.append(x) 169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ys.append(y) 170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db[file] = {'x':xs, 'y':ys} 172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if len(xs) > 10: 173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db[file]['ax'], db[file]['ay'] = avg(xs, ys) 174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db[file]['ax'] = db[file]['ay'] = None 176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db['min_x'] = min_x 178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db['max_x'] = max_x 179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db['min_y'] = min_y 180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat db['max_y'] = max_y 181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return db 182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#---------------------------------------------------------------------- 184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef parse_args(args): 185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Parse command line arguments. 186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat Returns list of (data) files that need to be processed -- /unless/ 188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat the -A (--generate-all) option is passed, in which case superfluous 189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat data files are ignored... 190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """ 191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat global add_legend, output_file, title_str, type, verbose 193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat global generate_all 194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat prog = args[0][args[0].rfind('/')+1:] 196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if prog == 'btt_plot.py': 197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pass 198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif not prog in progs: 199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal('%s not a valid command name' % prog) 200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat type = prog[prog.rfind('_')+1:prog.rfind('.py')] 202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat s_opts = 'ALo:t:T:v' 204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat l_opts = [ 'generate-all', 'type', 'no-legend', 'output', 'title', 205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 'verbose' ] 206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat try: 208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (opts, args) = getopt.getopt(args[1:], s_opts, l_opts) 209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat except getopt.error, msg: 210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat print >>sys.stderr, msg 211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(__doc__) 212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (o, a) in opts: 214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if o in ('-A', '--generate-all'): 215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat generate_all = True 216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif o in ('-L', '--no-legend'): 217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_legend = False 218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif o in ('-o', '--output'): 219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_file = a 220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif o in ('-t', '--type'): 221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if not a in types: 222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal('Type %s not supported' % a) 223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat type = a 224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif o in ('-T', '--title'): 225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = a 226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif o in ('-v', '--verbose'): 227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat verbose = True 228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if type == None and not generate_all: 230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal('Need type of data files to process - (-t <type>)') 231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return args 233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef gen_title(fig, type, title_str): 236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Sets the title for the figure based upon the type /or/ user title""" 237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if title_str != None: 239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pass 240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif type == 'aqd': 241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = 'Average Queue Depth' 242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif type == 'bnos': 243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = 'Block Numbers Accessed' 244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif type == 'q2d': 245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = 'Queue (Q) To Issue (D) Average Latencies' 246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif type == 'd2c': 247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = 'Issue (D) To Complete (C) Average Latencies' 248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif type == 'q2c': 249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = 'Queue (Q) To Complete (C) Average Latencies' 250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title = fig.text(.5, .95, title_str, horizontalalignment='center') 252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title.set_fontsize('large') 253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef gen_labels(db, ax, type): 256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Generate X & Y 'axis'""" 257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #---------------------------------------------------------------------- 259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def gen_ylabel(ax, type): 260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Set the Y axis label based upon the type""" 261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if type == 'aqd': 263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat str = 'Number of Requests Queued' 264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif type == 'bnos': 265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat str = 'Block Number' 266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat str = 'Seconds' 268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.set_ylabel(str) 269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #---------------------------------------------------------------------- 271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat xdelta = 0.1 * (db['max_x'] - db['min_x']) 272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ydelta = 0.1 * (db['max_y'] - db['min_y']) 273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.set_xlim(db['min_x'] - xdelta, db['max_x'] + xdelta) 275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.set_ylim(db['min_y'] - ydelta, db['max_y'] + ydelta) 276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.set_xlabel('Runtime (seconds)') 277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.grid(True) 278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat gen_ylabel(ax, type) 279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef generate_output(type, db): 282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Generate the output plot based upon the type and database""" 283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #---------------------------------------------------------------------- 285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def color(idx, style): 286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Returns a color/symbol type based upon the index passed.""" 287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat colors = [ 'b', 'g', 'r', 'c', 'm', 'y', 'k' ] 289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat l_styles = [ '-', ':', '--', '-.' ] 290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat m_styles = [ 'o', '+', '.', ',', 's', 'v', 'x', '<', '>' ] 291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat color = colors[idx % len(colors)] 293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if style == 'line': 294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat style = l_styles[(idx / len(l_styles)) % len(l_styles)] 295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif style == 'marker': 296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat style = m_styles[(idx / len(m_styles)) % len(m_styles)] 297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return '%s%s' % (color, style) 299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #---------------------------------------------------------------------- 301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def gen_legends(a, legends): 302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat leg = ax.legend(legends, 'best', shadow=True) 303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat frame = leg.get_frame() 304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat frame.set_facecolor('0.80') 305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for t in leg.get_texts(): 306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat t.set_fontsize('xx-small') 307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat #---------------------------------------------------------------------- 309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat global add_legend, output_file, title_str, verbose 310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if output_file != None: 312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ofile = output_file 313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ofile = '%s.png' % type 315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if verbose: 317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat print 'Generating plot into %s' % ofile 318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fig = plt.figure(figsize=plot_size) 320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax = fig.add_subplot(111) 321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat gen_title(fig, type, title_str) 323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat gen_labels(db, ax, type) 324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat idx = 0 326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if add_legend: 327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat legends = [] 328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat legends = None 330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat keys = [] 332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for file in db.iterkeys(): 333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if not file in ['min_x', 'max_x', 'min_y', 'max_y']: 334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat keys.append(file) 335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat keys.sort() 337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for file in keys: 338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dat = db[file] 339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if type == 'bnos': 340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.plot(dat['x'], dat['y'], color(idx, 'marker'), 341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat markersize=1) 342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif dat['ax'] == None: 343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue # Don't add legend 344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ax.plot(dat['ax'], dat['ay'], color(idx, 'line'), 346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat linewidth=1.0) 347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if add_legend: 348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat legends.append(get_base(file)) 349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat idx += 1 350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if add_legend and len(legends) > 0: 352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat gen_legends(ax, legends) 353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat plt.savefig(ofile) 354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatdef get_files(type): 357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat """Returns the list of files for the -A option based upon type""" 358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if type == 'bnos': 360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat files = [] 361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for fn in glob.glob('*c.dat'): 362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for t in [ 'q2q', 'd2d', 'q2c', 'd2c' ]: 363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if fn.find(t) >= 0: 364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break 365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat files.append(fn) 367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat files = glob.glob('*%s.dat' % type) 369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return files 370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#------------------------------------------------------------------------------ 372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatif __name__ == '__main__': 373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat files = parse_args(sys.argv) 374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if generate_all: 376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_file = title_str = type = None 377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for t in types: 378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat files = get_files(t) 379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if len(files) == 0: 380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue 381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif t != 'bnos': 382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat generate_output(t, get_data(files)) 383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue 384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for file in files: 386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat base = get_base(file) 387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat title_str = 'Block Numbers Accessed: %s' % base 388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat output_file = 'bnos_%s.png' % base 389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat generate_output(t, get_data([file])) 390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat elif len(files) < 1: 391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal('Need data files to process') 392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else: 393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat generate_output(type, get_data(files)) 394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sys.exit(0) 395