#!/usr/bin/env python # ------------------------------------------------------------------------- # Import modules import csv, sys import matplotlib.pyplot as plt import numpy as np import matplotlib.patches as mpatches import matplotlib.pylab as pylab ENTRY_COUNT_PER_LINE = 6 RESULT_RECT_HEIGHT = 1.0/8 # ------------------------------------------------------------------------- # Basic drawing class class Rectangle: def __init__(self, x, y, w, h, color): # w self.xpos = x # |-------------------| self.ypos = y # | | h self.width = w # | | self.height = h # (x,y)---------------| self.color = color # fill color self.alpha = None # transparency level [0,1] def draw(self): """ Draw the rectangle. """ if self.color == (1,1,1): return tmp = self.xpos, self.ypos, p = mpatches.Rectangle(tmp, self.width, self.height, color=self.color, \ alpha=self.alpha) plt.gca().add_patch(p) # ------------------------------------------------------------------------- # Check provided arguments: if len(sys.argv) <= 1: print "ERROR: Not enough arguments provided! See -h for more infos." exit(1) if sys.argv[1] == '-h': print "Displays experiment results for the weather-monitor-experiment." print " CALL-SYNTAX: fsp.plot.py DATA_FILE [USER_TAG_FILE]" print "DATA_FILE is a CSV-file, storing the tab-separated values" print "retrieved by the experiment run. USER_TAG_FILE is an optional" print "CSV-file which can be used to add user-specific marks to the" print "plot." # TODO: be more precise here exit(0) print "Opening and processing \"" + sys.argv[1] + "\"..." file = open(sys.argv[1], "r") dialect = csv.Sniffer().sniff(file.read(1024)) file.seek(0) reader = csv.reader(file, dialect) reader.next() # Move down a line to skip the header if len(sys.argv) >= 3: print "Opening and processing \"" + sys.argv[2] + "\"..." symbolfile = open(sys.argv[2], "r") dialect = csv.Sniffer().sniff(symbolfile.read(1024)) symbolfile.seek(0) symbolreader = csv.reader(symbolfile, dialect) symbolreader.next() # Move down a line to skip the header have_symbols = True else: have_symbols = False fig = plt.figure() xmin = 99999999 xmax = 0 ymin = 99999999 ymax = 0 line_counter = 1 for row in reader: line_counter += 1 # Check if there are at least ENTRY_COUNT_PER_LINE entries per line: if len(row) != ENTRY_COUNT_PER_LINE: print "ERROR: Line " + str(line_counter) + " is invalid (" +\ str(ENTRY_COUNT_PER_LINE) + " entries expected)" sys.exit(1) # Some constants to access the row-entries much easier: IDX_INSTR1 = 0; IDX_INSTR2 = 1; IDX_DATA_ADDRESS = 2; IDX_BITNR = 3; IDX_BITWIDTH = 4; IDX_COLOR = 5; # Update xmin/xmax/ymin/ymax x1 = int(row[IDX_INSTR1]) x2 = int(row[IDX_INSTR2]) + 1 # inclusive width = x2 - x1 if xmin > x1: xmin = x1 if xmax < x2: xmax = x2 y1 = float(row[IDX_DATA_ADDRESS]) + float(row[IDX_BITNR]) / 8.0 height = float(row[IDX_BITWIDTH]) / 8.0 y2 = y1 + height if ymin > y1: ymin = y1 if ymax < y2: ymax = y2 Rectangle(x1, y1, width, height, row[IDX_COLOR]).draw() if line_counter == 50000: # debug stuff pass #break ymin = int(ymin / 1000) * 1000 file.close() plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) plt.ylabel('Data Memory (RAM)') plt.xlabel('Time (Cycles)') # show symbols if have_symbols: # Adding 2nd y-axis for object names ax1 = fig.add_subplot(111) ax2 = ax1.twinx() ax2.set_ylabel('Symbols') # necessary for proper symbol placement plt.ylim(ymin, ymax) ticks = [] symbols = [] IDX_SYMBOL_ADDRESS = 0; IDX_SYMBOL_SIZE = 1; IDX_SYMBOL_NAME = 2; for row in symbolreader: # TODO: somehow plot size as well address = int(row[IDX_SYMBOL_ADDRESS]) size = int(row[IDX_SYMBOL_SIZE]) if (address >= ymin) and (address <= ymax): ticks.append(address) symbols.append(row[IDX_SYMBOL_NAME]) #print "symbol: " + str(address) + " " + str(size) + " " + row[IDX_SYMBOL_NAME] elif (address < ymin) and (address + size >= ymin): ticks.append(ymin) symbols.append("(" + row[IDX_SYMBOL_NAME] + ")") #print "partial symbol: " + str(address) + " " + str(size) + " " + row[IDX_SYMBOL_NAME] else: #print "skipped symbol: " + str(address) + " " + str(size) + " " + row[IDX_SYMBOL_NAME] pass # list of interesting addresses ax2.yaxis.set_ticks(ticks) ax2.yaxis.grid(b=True, color='gray') # create minor ticks centered between major tick marks centered_ticks = [] major_locator = ax2.yaxis.get_major_locator() major_locs = major_locator() for i in range(1,len(major_locs)): y_last,y = major_locs[i-1],major_locs[i] centered_ticks.append(0.5*(y+y_last)) ax2.yaxis.set_ticks(centered_ticks, minor=True) # list of corresponding symbol names ax2.set_yticklabels(symbols, minor=False, rotation=0, rotation_mode='anchor') plt.show() #pylab.savefig('baseline.pdf', bbox_inches='tight')