bachelor-thesis/tools/consumption.py
2018-09-21 11:45:21 +02:00

283 lines
8.6 KiB
Python
Executable file

#!/usr/bin/env python
import argparse
import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
from rpl import analysis, data
tubspalette = ['#be1e3c', '#ffc82a', '#e16d00', '#711c2f', '#acc13a', '#6d8300', '#00534a', '#66b4d3', '#007a9b', '#003f57', '#8a307f', '#511246', '#4c1830']
phase_names = ['N', 'R', 'H', 'HR', 'HS', 'HSR']
versions = ['Contiki', 'Hardened', 'Hardened with UIDs']
node_positions = {
'm3-59': (0,0),
'm3-57': (0,1),
'm3-53': (0,3),
'm3-51': (0,4),
'm3-49': (0,5),
'm3-47': (0,6),
'm3-95': (1,0),
'm3-93': (1,1),
'm3-91': (1,2),
'm3-89': (1,3),
'm3-87': (1,4),
'm3-85': (1,5),
'm3-83': (1,6),
'm3-133': (2,1),
'm3-131': (2,2),
'm3-127': (2,4),
'm3-123': (2,6),
'm3-161': (3,1),
'm3-159': (3,2),
'm3-157': (3,3),
'm3-155': (3,4),
'm3-153': (3,5),
'm3-151': (3,6),
'm3-204': (4,0),
'm3-202': (4,1),
'm3-200': (4,2),
'm3-198': (4,3),
'm3-196': (4,4),
'm3-194': (4,5),
'm3-192': (4,6),
'm3-230': (5,0),
'm3-228': (5,1),
'm3-226': (5,2),
'm3-224': (5,3),
'm3-222': (5,4),
'm3-220': (5,5),
'm3-218': (5,6),
'm3-256': (6,0),
'm3-254': (6,1),
'm3-252': (6,2),
'm3-250': (6,3),
'm3-248': (6,4),
'm3-246': (6,5),
'm3-244': (6,6)
}
def consumption_network_phases(db, phaselen, out):
consumptions = db.execute('''SELECT phase, (phase - 1)/ 2, SUM(consumption) / ? FROM consumption GROUP BY phase, expid''', (phaselen,))
data = np.array([(phase_names[phase-1], versions[int(reset)], cons) for phase, reset, cons in consumptions],
dtype=[('Phase', 'U3'), ('Version', 'U30'), ('Consumption', 'f')])
sns.boxplot(x='Phase', y='Consumption', hue='Version', data=pd.DataFrame(data))
def consumption_node_phases(db, phaselen, out):
consumptions = db.execute('''
SELECT host, phase, consumption / ?
FROM consumption
''', (phaselen,))
data = np.array(
[(host, phase_names[phase-1], cons) for host, phase, cons in consumptions],
dtype=[('node', 'U6'), ('phase', 'U3'), ('consumption', np.float16)])
sns.boxplot(x='phase', y='consumption', hue='node', data=pd.DataFrame(data))
def restart_energy_consumption(db, out):
consumptions = db.execute('''
SELECT resets.phase, resets.timestamp, SUM(consumption)
FROM resets
JOIN consumption
ON resets.phase = consumption.phase
AND resets.expid = consumption.expid
GROUP BY consumption.phase, consumption.expid
''')
data = np.array(
[(versions[int((phase / 2) - 1)], reset, cons) for phase, reset, cons in consumptions.fetchall()], dtype=[('Phase', 'U20'), ('Reset Time', 'f'), ('Consumption', 'f')]
)
grid = sns.FacetGrid(pd.DataFrame(data), col='Phase')
grid = grid.map(plt.scatter, 'Reset Time', 'Consumption')
def consumption_phases(db):
# NOTE excludes sink node and resetting node
consumptions = db.execute('''
SELECT ps.phase,
SUM(consumption),
(ps.phase - 1) % 2 = 1
FROM consumption AS c
JOIN phases AS ps
ON c.phase = ps.phase AND c.expid = ps.expid
WHERE c.host != 'm3-200' AND c.host != 'm3-157'
GROUP BY ps.expid, ps.phase''')
def _format():
for p, c, m in consumptions:
yield phase_names[p-1], c, m
data = np.array(list(_format()),
dtype=[('phase', 'U3'), ('consumption', 'f'), ('reset', bool)])
return pd.DataFrame(data)
def plot_consumption_phases(db, args):
data = consumption_phases(db)
sns.boxplot(x='reset', y='consumption', hue='phase', hue_order=phase_names, data=data, palette=tubspalette)
def consumption_nodes(db):
consumptions_nodes = db.execute('''
SELECT p.phase, c.host, AVG(c.consumption)
FROM consumption AS c
JOIN phases AS p
ON p.phase = c.phase AND p.expid = c.expid
GROUP BY c.host, p.phase
''')
def _format():
for p, h, c in consumptions_nodes:
host_x, host_y = node_positions[h]
yield phase_names[p-1], int(h[3:]), host_x, host_y, c, ((p - 1) % 2 == 1)
dtypes = [
('phase', 'U3'),
('host', 'd'),
('pos_x', 'd'),
('pos_y', 'd'),
('consumption', 'f'),
('reset', bool)
]
data = np.array(list(_format()), dtype=dtypes)
return pd.DataFrame(data)
def plot_nodes_consumption(db, args):
def phase_heatmap(x, y, val, **kwargs):
data = kwargs.pop('data')
d = data.pivot(index=x, columns=y, values=val)
print(d)
hostnames = data.pivot(index=x, columns=y, values='host')
hostnames.fillna(0)
print(hostnames)
ax = sns.heatmap(d, annot=hostnames, fmt='.0f', **kwargs)
ax.invert_yaxis()
#ax.invert_xaxis()
data = consumption_nodes(db)
fgrid = sns.FacetGrid(data, col='phase', col_wrap=3, col_order=['N', 'H', 'HS', 'R', 'HR', 'HSR'])
fgrid = fgrid.map_dataframe(phase_heatmap, 'pos_y', 'pos_x',
'consumption', cbar=False, square=False,
cmap=sns.light_palette('#711c2f'))
def rank_neighbors_consumption(db):
rnc = db.execute('''
SELECT n.phase, n.host, n.avg_rank, n.avg_neighbors, c.consumption
FROM dag_nodes AS n
JOIN consumption AS c ON c.expid = n.expid AND c.phase = n.phase
JOIN phases AS p ON p.expid = c.expid AND p.phase = c.phase
GROUP BY n.expid, n.phase, n.host
''')
def _format():
for p, h, r, n, c in rnc:
yield phase_names[p-1], h[3:], r, n, c
data = np.array(list(_format()), dtype=[('phase', 'U3'), ('host', 'U10'),
('rank', 'f'), ('neighbors', 'f'),
('consumption', 'f')])
return pd.DataFrame(data)
def plot_rank_neighbors_consumption(db, args):
data = rank_neighbors_consumption(db)
#sns.pairplot(data,
# hue='phase',
# kind='reg',
# diag_kind='hist',
# vars=['rank', 'consumption'],
# markers="+",
# palette=tubspalette)
sns.lmplot(x="rank", y="consumption", hue="phase",
truncate=True, data=data, markers='+')
def consumption_hosts(db, hosts):
qms = '?' * len(hosts)
query = 'SELECT c.phase, c.host, c.consumption FROM consumption AS c JOIN phases AS p ON p.phase = c.phase AND p.expid = c.expid WHERE c.host IN ({})'.format(','.join(qms))
csh = db.execute(query, hosts)
def _format():
for p, h, c in csh:
yield phase_names[p-1], h[3:], c
data = np.array(list(_format()),
dtype=[('phase', 'U3'), ('host', 'U10'), ('consumption', 'f')])
return pd.DataFrame(data)
def plot_consumption_hosts(db, args):
hcons = consumption_hosts(db, args.hosts)
sns.boxplot(x='phase', y='consumption', hue='host', data=hcons)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Process file names.')
subparsers = parser.add_subparsers(help='subcommand')
phases_cmd = subparsers.add_parser('phases')
phases_cmd.add_argument('--database', '-d', type=str, nargs=1, help='a sqlite3 database file', default=['db.sqlite3'])
phases_cmd.add_argument('--out', '-o', type=str, nargs=1, help='output file for the plot')
phases_cmd.set_defaults(func=plot_consumption_phases)
nodes_cmd = subparsers.add_parser('nodes')
nodes_cmd.add_argument('--database', '-d', type=str, nargs=1, help='a sqlite3 database file', default=['db.sqlite3'])
nodes_cmd.add_argument('--out', '-o', type=str, nargs=1, help='output file for the plot')
nodes_cmd.set_defaults(func=plot_nodes_consumption)
rank_neighbors_cmd = subparsers.add_parser('regress')
rank_neighbors_cmd.add_argument('--database', '-d', type=str, nargs=1, help='a sqlite3 database file', default=['db.sqlite3'])
rank_neighbors_cmd.add_argument('--out', '-o', type=str, nargs=1, help='output file for the plot')
rank_neighbors_cmd.set_defaults(func=plot_rank_neighbors_consumption)
hosts_cmd = subparsers.add_parser('hosts')
hosts_cmd.add_argument('--database', '-d', type=str, nargs=1, help='a sqlite3 database file', default=['db.sqlite3'])
hosts_cmd.add_argument('--out', '-o', type=str, nargs=1, help='output file for the plot')
hosts_cmd.add_argument('hosts', type=str, nargs='+', help='hosts to plot')
hosts_cmd.set_defaults(func=plot_consumption_hosts)
plt.figure()
sns.set()
sns.set(font='NexusSerifPro')
sns.set_palette(tubspalette)
args = parser.parse_args()
db = data.init_db(args.database[0])
args.func(db, args)
plt.savefig(args.out[0])