Skip to content
Snippets Groups Projects
Commit 43212622 authored by Melanie Bruns's avatar Melanie Bruns
Browse files

Merge branch 'feature-#593-energy-graphic' into 'master'

Add postprocessing to visualize energy metrics

See merge request !152
parents 2cfad038 b703d366
No related branches found
No related tags found
1 merge request!152Add postprocessing to visualize energy metrics
Pipeline #
import matplotlib.pyplot as plt
import sys
import re
import matplotlib.ticker as ticker
# Script that translates energy level analysis into plots of percentages of hosts with low or no energy.
# Takes as arguments
# (1) an energy level report file
# (2) path to save the graphic to.
#
# The energy level analysis file should have a format like:
#
# [600]
# 600,p0,0.8116
# ...
# 600,c2999,0.4448
# [1200]
# 1200,p0,0.7556
# ...
# 50400,c2999,0.0000
# Class responsible for summarizing energy data fed into it by time point and host.
class EnergyData:
# Summarized data
timePoints = []
zeroEnergyHosts = []
lowEnergyHosts = []
# Current counters
currentTimePoint = 0
currentTotalHosts = 0
currentZeroEnergyHosts = 0
currentLowEnergyHosts = 0
# Transfers current counters into new elements of the summarizing data vectors.
def updateData(self):
self.timePoints.append(self.currentTimePoint)
self.zeroEnergyHosts.append(self.currentZeroEnergyHosts / self.currentTotalHosts)
self.lowEnergyHosts.append(self.currentLowEnergyHosts / self.currentTotalHosts)
# Resets current counters to 0.
def resetCounters(self):
self.currentTotalHosts = 0
self.currentZeroEnergyHosts = 0
self.currentLowEnergyHosts = 0
# Updates counters with a new energy level at the current time point.
def updateCounters(self, energyLevel):
self.currentTotalHosts += 1
if energyLevel == 0:
self.currentZeroEnergyHosts += 1
elif energyLevel < 0.1:
self.currentLowEnergyHosts += 1
# Draws two functions over the same x values.
# Labels are selected as appropriate for energy analysis.
def drawPlots(x, y_lowEnergy, y_noEnergy):
plt.title('Battery power distribution')
plt.xlabel('Minutes in simulation')
plt.ylabel('Percentage of hosts')
plt.plot(x, y_lowEnergy, '.-', label='Battery 0% < x < 10%')
plt.plot(x, y_noEnergy, '.-', label='No battery left')
plt.legend(loc='upper left')
plt.grid(True)
axes = plt.gca()
axes.set_ylim(ymin=0,ymax=1)
axes.set_xlim(xmin=0)
axes.xaxis.set_major_locator(ticker.IndexLocator(base=60, offset=-10))
# Main function of the script. See script description at the top of the file for further information.
def main(analysisFileName, graphicFileName):
# Read energy level analysis from file
with open(analysisFileName) as analysis_file:
analysis = analysis_file.readlines()
# Traverse analysis line by line to find the number of zero and low energy hosts by time
data = EnergyData()
for line in analysis:
timeMatch = re.match("\[(\d+)\]", line)
energyMatch = re.match("\d+,\D+\d+,(\d+.\d+)", line)
# If the line looks like "[600]", i.e. the report changes to the next time frame, we have to finalize the
# data we collected for the last time point (if there was such) and then reset our counters.
if timeMatch is not None:
if data.currentTimePoint is not 0:
data.updateData()
data.currentTimePoint = float(timeMatch.group(1)) / 60
data.resetCounters()
# Otherwise, if the line looks like '600,p0,0.8116', it is another data point for the current time and we
# should update our counters using the logged energy.
if energyMatch is not None:
data.updateCounters(energyLevel=float(energyMatch.group(1)))
drawPlots(x=data.timePoints, y_lowEnergy=data.lowEnergyHosts, y_noEnergy=data.zeroEnergyHosts)
# Save to file
plt.savefig(graphicFileName)
plt.close()
# Make sure script can be called from command line.
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2])
\ No newline at end of file
......@@ -41,4 +41,8 @@ def getAbsoluteMulticastDelayPath(folder):
# Returns the path to the data sync analysis graphic saved / to be saved in the provided folder.
def getAbsoluteDataAnalysisPath(folder):
return folder + "dataSyncAnalysis.png"
\ No newline at end of file
return folder + "DataSyncAnalysis.png"
# Returns the path to the energy analysis graphic saved / to be saved in the provided folder.
def getAbsoluteEnergyAnalysisPath(folder):
return folder + "EnergyAnalysis.png"
\ No newline at end of file
......@@ -10,6 +10,7 @@ import delayDistributionAnalysis
import broadcastAnalysis
import multicastAnalysis
import dataSyncAnalysis
import energyAnalysis
import reportSummaryPdf
import readFileUtilities
......@@ -103,6 +104,9 @@ delayDistributionAnalysis.main(
dataSyncAnalysis.main(
analysisFileName=reportDir+"realisticScenario_DataSyncReport.txt",
graphicFileName=readFileUtilities.getAbsoluteDataAnalysisPath(imageDirectoryName))
energyAnalysis.main(
analysisFileName=reportDir+"realisticScenario_EnergyLevelReport.txt",
graphicFileName=readFileUtilities.getAbsoluteEnergyAnalysisPath(imageDirectoryName))
print("Successfully created all graphics. Creating pdf...")
......
......@@ -13,14 +13,16 @@ import readFileUtilities
# - BroadcastMessageDelay9.png,
# - MulticastMessageAnalysis.png,
# - MulticastMessageDelay.png, and
# - dataSyncAnalysis.png
# - dataSyncAnalysis.png, and
# - energyAnalysis.png
# into a single pdf in that folder with name allGraphics.pdf.
def main(imageFolderPath):
pdf = FPDF()
pdf.add_page()
pdf.image(readFileUtilities.getAbsoluteTrafficAnalysisPath(imageFolderPath), h=132)
pdf.image(readFileUtilities.getAbsoluteBufferOccupancyAnalysisPath(imageFolderPath), h=132)
pdf.image(readFileUtilities.getAbsoluteTrafficAnalysisPath(imageFolderPath), h=80)
pdf.image(readFileUtilities.getAbsoluteBufferOccupancyAnalysisPath(imageFolderPath), h=92)
pdf.image(readFileUtilities.getAbsoluteEnergyAnalysisPath(imageFolderPath), h=92)
pdf.add_page()
pdf.image(readFileUtilities.getAbsoluteDeliveryRatePath(imageFolderPath), h=132)
pdf.image(readFileUtilities.getAbsoluteOneToOneMessageDelayPath(imageFolderPath), h=132)
......
  • Contributor

    SonarQube analysis reported no issues.

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment