From d01be7002e989a7f86ba8b1abbdd8b2d56efc662 Mon Sep 17 00:00:00 2001 From: Britta Heymann <britta_hey@web.de> Date: Thu, 5 Oct 2017 10:08:35 +0200 Subject: [PATCH] Refactor evaluation scripts into multiple methods s.t. they can be combined in different ways. --- toolkit/reportSummary/broadcastAnalysis.py | 56 +++++++++---------- .../delayDistributionAnalysis.py | 52 +++++++++++------ toolkit/reportSummary/multicastAnalysis.py | 46 +++++++-------- .../reportSummary/privateMessageAnalysis.py | 18 ++++-- 4 files changed, 102 insertions(+), 70 deletions(-) diff --git a/toolkit/reportSummary/broadcastAnalysis.py b/toolkit/reportSummary/broadcastAnalysis.py index bc616e59..07759e99 100644 --- a/toolkit/reportSummary/broadcastAnalysis.py +++ b/toolkit/reportSummary/broadcastAnalysis.py @@ -30,6 +30,29 @@ def findLinesConcerningPriority(all_lines, priority): nextPriorityLine = findNextLineContaining(all_lines, correctPriorityLine + 1, "prio") return all_lines[correctPriorityLine:nextPriorityLine] +def parseBroadcastAnalysis(filename, priority): + """Parses a broadcast analysis file for the specified priority and returns (in that order) the time points, the + average number of reached people, and the minimum number of reached people. + """ + # Read broadcast analysis from file + with open(filename) as analysis_file: + analysis = analysis_file.readlines() + relevantLines = findLinesConcerningPriority(analysis, priority) + + # Interpret lines to find minimum and average number of reached people over time + timePoints = [] + minimum = [] + average = [] + for line in relevantLines: + match = re.match("(\d+)\s+(\d+.\d+)\s+(\d+)", line) + if match is None: + continue + timePoints.append(float(match.group(1)) / 60) + average.append(float(match.group(2))) + minimum.append(int(match.group(3))) + + return timePoints, average, minimum + # Draws two functions over the same x values. # Labels are selected as appropriate for broadcast analysis. def drawPlots(x, y_minimum, y_average, priority): @@ -45,40 +68,17 @@ def drawPlots(x, y_minimum, y_average, priority): axes.set_ylim(ymin = 0) axes.xaxis.set_major_locator(ticker.IndexLocator(base=60, offset=-5)) - -def plotAnalysis(lines, priority, figure, plotNumber): - # Interpret lines to find minimum and average number of reached people over time - timePoints = [] - minimum = [] - average = [] - for line in lines: - match = re.match("(\d+)\s+(\d+.\d+)\s+(\d+)", line) - if match is None: - continue - timePoints.append(float(match.group(1)) / 60) - average.append(float(match.group(2))) - minimum.append(int(match.group(3))) - - # Draw plots. - figure.add_subplot(1, 3, plotNumber) - drawPlots(timePoints, minimum, average, priority) - # Main function of the script. See script description at the top of the file for further information. def main(analysisFileName, graphicFileName): - # Read broadcast analysis from file - with open(analysisFileName) as analysis_file: - analysis = analysis_file.readlines() - # Only look at priorities 2, 5 and 9 - prio2Analysis = findLinesConcerningPriority(analysis, 2) - prio5Analysis = findLinesConcerningPriority(analysis, 5) - prio9Analysis = findLinesConcerningPriority(analysis, 9) + priorities = [2, 5, 9] # Draw plots for all those priorities. fig = plt.figure(figsize=(16, 4)) - plotAnalysis(prio2Analysis, 2, fig, 1) - plotAnalysis(prio5Analysis, 5, fig, 2) - plotAnalysis(prio9Analysis, 9, fig, 3) + for idx, priority in enumerate(priorities): + timePoints, average, minimum = parseBroadcastAnalysis(analysisFileName, priority) + fig.add_subplot(1, 3, idx + 1) + drawPlots(timePoints, minimum, average, priority) # Save to file plt.tight_layout() diff --git a/toolkit/reportSummary/delayDistributionAnalysis.py b/toolkit/reportSummary/delayDistributionAnalysis.py index 035ea834..df68989a 100644 --- a/toolkit/reportSummary/delayDistributionAnalysis.py +++ b/toolkit/reportSummary/delayDistributionAnalysis.py @@ -29,10 +29,13 @@ from readFileUtilities import findNextLineContaining messageTypeIntro = "Delay distribution for delivered messages of type {}:" priorityIntro = "For priority {}:" -# Main function of the script. See script description at the top of the file for further information. -def main(analysisFileName, messageType, messagePrio, graphicFileName): +def parseDelayAnalysis(fileName, messageType, messagePrio): + """Parses a delay analysis file for information about the provided message type and priority and + returns (in that order) the different delay classes (identified by max delay), the percentage of delivered messages + delivered in those intervals, and the cumulative percentages. + """ # Read delay analysis from file - with open(analysisFileName) as analysis_file: + with open(fileName) as analysis_file: analysis = analysis_file.readlines() # Only look at text for correct type @@ -46,9 +49,9 @@ def main(analysisFileName, messageType, messagePrio, graphicFileName): analysis = analysis[correctPriorityLine:nextPriorityLine] # Find data both for bar chart and cumulative chart - bins = [] - vals = [] - cumulative = {} + delayClasses = [] + percentageDelivered = [] + cumulativePercentages = {} sumOfPercentages = 0 for line in analysis: match = re.match(".*<\s*(\d+):\s*(\d+.\d+)%", line) @@ -56,23 +59,25 @@ def main(analysisFileName, messageType, messagePrio, graphicFileName): continue maxDelay = int(match.group(1)) / 60 percentage = float(match.group(2)) - bins.append(maxDelay) - vals.append(percentage) + delayClasses.append(maxDelay) + percentageDelivered.append(percentage) sumOfPercentages += percentage - cumulative[maxDelay] = sumOfPercentages + cumulativePercentages[maxDelay] = sumOfPercentages - # Plot bar chart - plt.subplot(2,1,1) - plt.title('Delay distribution of delivered {} messages\nPriority {}'.format(messageType, messagePrio)) - plt.bar(bins, vals) + return delayClasses, percentageDelivered, cumulativePercentages + +def plotDelayDistribution(title, delayClasses, percentageDelivered): + """Plots a delay distribution as a bar chart.""" + plt.title(title) + plt.bar(delayClasses, percentageDelivered) plt.ylabel('Percentage of messages') plt.grid(True) axes = plt.gca() axes.set_xlim(xmin = 0) - # Directly below, plot cumulative chart - plt.subplot(2,1,2) - plt.plot(bins, [cumulative[bin] for bin in bins]) +def plotCumulativeDelay(delayClasses, cumulativePercentages): + """Plots a cumulative delay chart.""" + plt.plot(delayClasses, [cumulativePercentages[delayClass] for delayClass in delayClasses]) plt.xlabel('Delay in minutes') plt.ylabel('Cumulative percentage') plt.grid(True) @@ -80,6 +85,21 @@ def main(analysisFileName, messageType, messagePrio, graphicFileName): axes.set_xlim(xmin = 0) axes.set_ylim(ymin = 0) +# Main function of the script. See script description at the top of the file for further information. +def main(analysisFileName, messageType, messagePrio, graphicFileName): + delayClasses, percentageDelivered, cumulativePercentages = parseDelayAnalysis(analysisFileName, messageType, messagePrio) + + # Plot bar chart + plt.subplot(2,1,1) + plotDelayDistribution( + title='Delay distribution of delivered {} messages\nPriority {}'.format(messageType, messagePrio), + delayClasses=delayClasses, + percentageDelivered=percentageDelivered) + + # Directly below, plot cumulative chart + plt.subplot(2,1,2) + plotCumulativeDelay(delayClasses, cumulativePercentages) + # Save to file plt.savefig(graphicFileName, dpi = 300) plt.close() diff --git a/toolkit/reportSummary/multicastAnalysis.py b/toolkit/reportSummary/multicastAnalysis.py index 3f375019..8e0be53b 100644 --- a/toolkit/reportSummary/multicastAnalysis.py +++ b/toolkit/reportSummary/multicastAnalysis.py @@ -15,25 +15,13 @@ import re # 600 0.0 0.0164942207497068 0.0 0.01223002342392 # 900 0.0 0.0340330430435976 0.0 0.024223002342392 -# Draws two functions over the same x values. -# Labels are selected as appropiate for multicast analysis. -def drawPlots(x, y_minimum, y_average, y_minForAll, y_avgForAll): - plt.title('Multicast delivery rates') - plt.xlabel('Minutes since message creation') - plt.ylabel('Delivery rate') - plt.plot(x, y_minimum, '.-', label='Minimum for existent messages') - plt.plot(x, y_average, '.-', label='Average for existent messages') - #Currently not plotted as both minima are constantly zero and if the ever get higher it will be more noticably in - #the minimum delivery ratio for existent messages, two overlaying graphs make viewers search for the 'missing' one - #plt.plot(x, y_minForAll, '.-', label='Minimum for all messages ever created') - plt.plot(x, y_avgForAll, '.-', label='Average for all messages ever created') - plt.legend(loc='upper left') - plt.grid(True) - -# Main function of the script. See script description at the top of the file for further information. -def main(analysisFileName, graphicFileName): +def parseMulticastAnalysis(filename): + """Parses a multicast analysis file and returns (in that order) the time points, the minimum delivery rates for + existing messages, the average delivery rates for existing messages, and the average delivery rates over all + messages ever created. + """ # Read multicast analysis from file - with open(analysisFileName) as analysis_file: + with open(filename) as analysis_file: analysis = analysis_file.readlines() # Skip first line which only contains explanation. analysis = analysis[1:] @@ -41,7 +29,6 @@ def main(analysisFileName, graphicFileName): # Interpret lines to find minimum and average delivery rates over time timePoints = [] minimum = [] - minimumForAll = [] average = [] averageForAll = [] for line in analysis: @@ -51,11 +38,26 @@ def main(analysisFileName, graphicFileName): timePoints.append(float(match.group(1)) / 60) minimum.append(float(match.group(2))) average.append(float(match.group(3))) - minimumForAll.append(float(match.group(4))) averageForAll.append(float(match.group(5))) - # Draw plots. - drawPlots(timePoints, minimum, average, minimumForAll, averageForAll) + return timePoints, minimum, average, averageForAll + +# Draws two functions over the same x values. +# Labels are selected as appropiate for multicast analysis. +def drawPlots(x, y_minimum, y_average, y_avgForAll): + plt.title('Multicast delivery rates') + plt.xlabel('Minutes since message creation') + plt.ylabel('Delivery rate') + plt.plot(x, y_minimum, '.-', label='Minimum for existent messages') + plt.plot(x, y_average, '.-', label='Average for existent messages') + plt.plot(x, y_avgForAll, '.-', label='Average for all messages ever created') + plt.legend(loc='upper left') + plt.grid(True) + +# Main function of the script. See script description at the top of the file for further information. +def main(analysisFileName, graphicFileName): + timePoints, minimum, average, averageForAll = parseMulticastAnalysis(analysisFileName) + drawPlots(timePoints, minimum, average, averageForAll) # Save to file plt.savefig(graphicFileName) diff --git a/toolkit/reportSummary/privateMessageAnalysis.py b/toolkit/reportSummary/privateMessageAnalysis.py index e327f502..21431ee3 100644 --- a/toolkit/reportSummary/privateMessageAnalysis.py +++ b/toolkit/reportSummary/privateMessageAnalysis.py @@ -26,16 +26,21 @@ def getValueFromString(string): return float(match.group(2)) return int(match.group(2)) -# Main function of the script. See script description at the top of the file for further information. -def main(analysisFileName, graphicFileName): - # Read delivery probability from file - with open(analysisFileName) as analysis_file: +def parseDeliveryProbabilityReport(fileName): + """Parses a delivery probability report file and returns (in that order) the number of created messages, + the number of delivered messages, and the delivery probability. + """ + with open(fileName) as analysis_file: analysis = analysis_file.readlines() created = getValueFromString(analysis[2]) delivered = getValueFromString(analysis[3]) delivery_prob = getValueFromString(analysis[4]) + return created, delivered, delivery_prob + +def createDeliveryPieChart(created, delivered, delivery_prob): + """Creates a graphical presentation of delivery probability.""" values=[delivery_prob, 1-delivery_prob] labels=["delivered:\n{p:.1f}% ({t})".format(p=delivery_prob*100, t=delivered), "not delivered:\n{p:.1f}% ({t})".format(p=(1-delivery_prob)*100, t=(created-delivered))] @@ -49,6 +54,11 @@ def main(analysisFileName, graphicFileName): plt.figtext(0.6, 0.05, 'Total created messages: %d' % created) plt.title("Message delivery ratio for one-to-one messages") +# Main function of the script. See script description at the top of the file for further information. +def main(analysisFileName, graphicFileName): + created, delivered, delivery_prob = parseDeliveryProbabilityReport(analysisFileName) + createDeliveryPieChart(created, delivered, delivery_prob) + # Save to file plt.savefig(graphicFileName) plt.close() -- GitLab