#!/usr/bin/python

import pandas as pd
import numpy as np
import re
import sys
import os
import argparse
import matplotlib
from matplotlib import pyplot as plt
from matplotlib.projections.polar import PolarAxes
from matplotlib.projections import register_projection

"""
Read the stats file produced by the OpenMP runtime
and produce a processed summary

The radar_factory original code was taken from
matplotlib.org/examples/api/radar_chart.html
We added support to handle negative values for radar charts
"""

def radar_factory(num_vars, frame='circle'):
    """Create a radar chart with num_vars axes."""
    # calculate evenly-spaced axis angles
    theta = 2*np.pi * np.linspace(0, 1-1./num_vars, num_vars)
    # rotate theta such that the first axis is at the top
    #theta += np.pi/2

    def draw_poly_frame(self, x0, y0, r):
        # TODO: use transforms to convert (x, y) to (r, theta)
        verts = [(r*np.cos(t) + x0, r*np.sin(t) + y0) for t in theta]
        return plt.Polygon(verts, closed=True, edgecolor='k')

    def draw_circle_frame(self, x0, y0, r):
        return plt.Circle((x0, y0), r)

    frame_dict = {'polygon': draw_poly_frame, 'circle': draw_circle_frame}
    if frame not in frame_dict:
        raise ValueError, 'unknown value for `frame`: %s' % frame

    class RadarAxes(PolarAxes):
        """
        Class for creating a radar chart (a.k.a. a spider or star chart)

        http://en.wikipedia.org/wiki/Radar_chart
        """
        name = 'radar'
        # use 1 line segment to connect specified points
        RESOLUTION = 1
        # define draw_frame method
        draw_frame = frame_dict[frame]

        def fill(self, *args, **kwargs):
            """Override fill so that line is closed by default"""
            closed = kwargs.pop('closed', True)
            return super(RadarAxes, self).fill(closed=closed, *args, **kwargs)

        def plot(self, *args, **kwargs):
            """Override plot so that line is closed by default"""
            lines = super(RadarAxes, self).plot(*args, **kwargs)
            #for line in lines:
            #    self._close_line(line)

        def set_varlabels(self, labels):
            self.set_thetagrids(theta * 180/np.pi, labels,fontsize=14)

        def _gen_axes_patch(self):
            x0, y0 = (0.5, 0.5)
            r = 0.5
            return self.draw_frame(x0, y0, r)

    register_projection(RadarAxes)
    return theta

# Code to read the raw stats
def extractSI(s):
    """Convert a measurement with a range suffix into a suitably scaled value"""
    du     = s.split()
    num    = float(du[0])
    units  = du[1] if len(du) == 2 else ' '
    # http://physics.nist.gov/cuu/Units/prefixes.html
    factor = {'Y':  1e24,
              'Z':  1e21,
              'E':  1e18,
              'P':  1e15,
              'T':  1e12,
              'G':  1e9,
              'M':  1e6,
              'k':  1e3,
              ' ':  1  ,
              'm': -1e3, # Yes, I do mean that, see below for the explanation.
              'u': -1e6,
              'n': -1e9,
              'p': -1e12,
              'f': -1e15,
              'a': -1e18,
              'z': -1e21,
              'y': -1e24}[units[0]]
    # Minor trickery here is an attempt to preserve accuracy by using a single
    # divide, rather than  multiplying by 1/x, which introduces two roundings
    # since 1/10 is not representable perfectly in IEEE floating point. (Not
    # that this really matters, other than for cleanliness, since we're likely
    # reading numbers with at most five decimal digits of precision).
    return  num*factor if factor > 0 else num/-factor

def readData(f):
    line = f.readline()
    fieldnames = [x.strip() for x in line.split(',')]
    line = f.readline().strip()
    data = []
    while line != "":
        if line[0] != '#':
            fields = line.split(',')
            data.append ((fields[0].strip(), [extractSI(v) for v in fields[1:]]))
        line = f.readline().strip()
    # Man, working out this next incantation out was non-trivial!
    # They really want you to be snarfing data in csv or some other
    # format they understand!
    res = pd.DataFrame.from_items(data, columns=fieldnames[1:], orient='index')
    return res

def readTimers(f):
    """Skip lines with leading #"""
    line = f.readline()
    while line[0] == '#':
        line = f.readline()
    line = line.strip()
    if line == "Statistics on exit\n" or "Aggregate for all threads\n":
        line = f.readline()
    return readData(f)

def readCounters(f):
    """This can be just the same!"""
    return readData(f)

def readFile(fname):
    """Read the statistics from the file. Return a dict with keys "timers", "counters" """
    res = {}
    try:
        with open(fname) as f:
            res["timers"]   = readTimers(f)
            res["counters"] = readCounters(f)
            return res
    except (OSError, IOError):
        print "Cannot open " + fname
        return None

def usefulValues(l):
    """I.e. values which are neither null nor zero"""
    return [p and q for (p,q) in zip (pd.notnull(l), l != 0.0)]

def uselessValues(l):
    """I.e. values which are null or zero"""
    return [not p for p in usefulValues(l)]

interestingStats = ("counters", "timers")
statProperties   = {"counters" : ("Count", "Counter Statistics"),
                    "timers"   : ("Time (ticks)", "Timer Statistics")
                   }

def drawChart(data, kind, filebase):
    """Draw a summary bar chart for the requested data frame into the specified file"""
    data["Mean"].plot(kind="bar", logy=True, grid=True, colormap="GnBu",
                      yerr=data["SD"], ecolor="black")
    plt.xlabel("OMP Constructs")
    plt.ylabel(statProperties[kind][0])
    plt.title (statProperties[kind][1])
    plt.tight_layout()
    plt.savefig(filebase+"_"+kind)

def normalizeValues(data, countField, factor):
    """Normalize values into a rate by dividing them all by the given factor"""
    data[[k for k in data.keys() if k != countField]] /= factor


def setRadarFigure(titles):
    """Set the attributes for the radar plots"""
    fig = plt.figure(figsize=(9,9))
    rect = [0.1, 0.1, 0.8, 0.8]
    labels = [0.2, 0.4, 0.6, 0.8, 1, 2, 3, 4, 5, 10]
    matplotlib.rcParams.update({'font.size':13})
    theta = radar_factory(len(titles))
    ax = fig.add_axes(rect, projection='radar')
    ax.set_rgrids(labels)
    ax.set_varlabels(titles)
    ax.text(theta[2], 1, "Linear->Log", horizontalalignment='center', color='green', fontsize=18)
    return {'ax':ax, 'theta':theta}


def drawRadarChart(data, kind, filebase, params, color):
    """Draw the radar plots"""
    tmp_lin = data * 0
    tmp_log = data * 0
    for key in data.keys():
        if data[key] >= 1:
           tmp_log[key] = np.log10(data[key])
        else:
           tmp_lin[key] = (data[key])
    params['ax'].plot(params['theta'], tmp_log, color='b', label=filebase+"_"+kind+"_log")
    params['ax'].plot(params['theta'], tmp_lin, color='r', label=filebase+"_"+kind+"_linear")
    params['ax'].legend(loc='best', bbox_to_anchor=(1.4,1.2))
    params['ax'].set_rlim((0, np.ceil(max(tmp_log))))

def multiAppBarChartSettings(ax, plt, index, width, n, tmp, s):
    ax.set_yscale('log')
    ax.legend()
    ax.set_xticks(index + width * n / 2)
    ax.set_xticklabels(tmp[s]['Total'].keys(), rotation=50, horizontalalignment='right')
    plt.xlabel("OMP Constructs")
    plt.ylabel(statProperties[s][0])
    plt.title(statProperties[s][1])
    plt.tight_layout()

def derivedTimerStats(data):
    stats = {}
    for key in data.keys():
        if key == 'OMP_worker_thread_life':
            totalRuntime = data['OMP_worker_thread_life']
        elif key in ('FOR_static_iterations', 'OMP_PARALLEL_args',
                     'OMP_set_numthreads', 'FOR_dynamic_iterations'):
            break
        else:
            stats[key] = 100 * data[key] / totalRuntime
    return stats

def compPie(data):
    compKeys = {}
    nonCompKeys = {}
    for key in data.keys():
        if key in ('OMP_critical', 'OMP_single', 'OMP_serial',
                   'OMP_parallel', 'OMP_master', 'OMP_task_immediate',
                   'OMP_task_taskwait', 'OMP_task_taskyield', 'OMP_task_taskgroup',
                   'OMP_task_join_bar', 'OMP_task_plain_bar', 'OMP_task_taskyield'):
            compKeys[key] = data[key]
        else:
            nonCompKeys[key] = data[key]
    print "comp keys:", compKeys, "\n\n non comp keys:", nonCompKeys
    return [compKeys, nonCompKeys]

def drawMainPie(data, filebase, colors):
    sizes = [sum(data[0].values()), sum(data[1].values())]
    explode = [0,0]
    labels = ["Compute - " + "%.2f" % sizes[0], "Non Compute - " + "%.2f" % sizes[1]]
    patches = plt.pie(sizes, explode, colors=colors, startangle=90)
    plt.title("Time Division")
    plt.axis('equal')
    plt.legend(patches[0], labels, loc='best', bbox_to_anchor=(-0.1,1), fontsize=16)
    plt.savefig(filebase+"_main_pie", bbox_inches='tight')

def drawSubPie(data, tag, filebase, colors):
    explode = []
    labels = data.keys()
    sizes = data.values()
    total = sum(sizes)
    percent = []
    for i in range(len(sizes)):
        explode.append(0)
        percent.append(100 * sizes[i] / total)
        labels[i] = labels[i] + " - %.2f" % percent[i]
    patches = plt.pie(sizes, explode=explode, colors=colors, startangle=90)
    plt.title(tag+"(Percentage of Total:"+" %.2f" % (sum(data.values()))+")")
    plt.tight_layout()
    plt.axis('equal')
    plt.legend(patches[0], labels, loc='best', bbox_to_anchor=(-0.1,1), fontsize=16)
    plt.savefig(filebase+"_"+tag, bbox_inches='tight')

def main():
    parser = argparse.ArgumentParser(description='''This script takes a list
        of files containing each of which contain output from a stats-gathering
        enabled OpenMP runtime library.  Each stats file is read, parsed, and
        used to produce a summary of the statistics''')
    parser.add_argument('files', nargs='+',
        help='files to parse which contain stats-gathering output')
    command_args = parser.parse_args()
    colors = ['orange', 'b', 'r', 'yellowgreen', 'lightsage', 'lightpink',
              'green', 'purple', 'yellow', 'cyan', 'mediumturquoise',
              'olive']
    stats = {}
    matplotlib.rcParams.update({'font.size':22})
    for s in interestingStats:
        fig, ax = plt.subplots()
        width = 0.45
        n = 0
        index = 0

        for f in command_args.files:
            filebase = os.path.splitext(f)[0]
            tmp = readFile(f)
            data = tmp[s]['Total']
            """preventing repetition by removing rows similar to Total_OMP_work
                as Total_OMP_work['Total'] is same as OMP_work['Total']"""
            if s == 'counters':
                elapsedTime = tmp["timers"]["Mean"]["OMP_worker_thread_life"]
                normalizeValues(tmp["counters"], "SampleCount",
                    elapsedTime / 1.e9)
                """Plotting radar charts"""
                params = setRadarFigure(data.keys())
                chartType = "radar"
                drawRadarChart(data, s, filebase, params, colors[n])
                """radar Charts finish here"""
                plt.savefig(filebase+"_"+s+"_"+chartType, bbox_inches='tight')
            elif s == 'timers':
                print "overheads in "+filebase
                numThreads = tmp[s]['SampleCount']['Total_OMP_parallel']
                for key in data.keys():
                    if key[0:5] == 'Total':
                        del data[key]
                stats[filebase] = derivedTimerStats(data)
                dataSubSet = compPie(stats[filebase])
                drawMainPie(dataSubSet, filebase, colors)
                plt.figure(0)
                drawSubPie(dataSubSet[0], "Computational Time", filebase, colors)
                plt.figure(1)
                drawSubPie(dataSubSet[1], "Non Computational Time", filebase, colors)
                with open('derivedStats_{}.csv'.format(filebase), 'w') as f:
                    f.write('================={}====================\n'.format(filebase))
                    f.write(pd.DataFrame(stats[filebase].items()).to_csv()+'\n')
            n += 1
    plt.close()

if __name__ == "__main__":
    main()
