Skip to content
Snippets Groups Projects
shed.py 2.71 KiB
Newer Older
Jarrod Pas's avatar
Jarrod Pas committed
"""Example to run a batch of simlations on SHED data."""

__author__ = 'Jarrod Pas <j.pas@usask.ca>'

Jarrod Pas's avatar
Jarrod Pas committed
import sys
from argparse import ArgumentParser
Jarrod Pas's avatar
Jarrod Pas committed
from collections import namedtuple
Jarrod Pas's avatar
Jarrod Pas committed
from multiprocessing import Pool
Jarrod Pas's avatar
Jarrod Pas committed
from os import path
from pprint import pprint
Jarrod Pas's avatar
Jarrod Pas committed
from pydtn import Network, RandomTraffic, Node, EpidemicNode, CSVTrace
from pydtn.community import BubbleKCliqueNode, BubbleLouvainNode
from pydtn.community import HCBFKCliqueNode, HCBFLouvainNode
from pydtn.community import  HCBFAGKmeansNode, BubbleAGKmeansNode
Jarrod Pas's avatar
Jarrod Pas committed
Simulation = namedtuple('Simulation', ['trace', 'node_type', 'seed'])
Jarrod Pas's avatar
Jarrod Pas committed
def run_simulation(simulation):
    """Run a simulation."""
    seed = simulation.seed
Jarrod Pas's avatar
Jarrod Pas committed
    csv = path.join(simulation.trace, 'contact.csv')
    metadata = path.join(simulation.trace, 'metadata.json')
    trace = CSVTrace(csv, metadata=metadata)
Jarrod Pas's avatar
Jarrod Pas committed
    epoch = 7*24*60*60  # 7 days
Jarrod Pas's avatar
Jarrod Pas committed
    node_type = simulation.node_type
Jarrod Pas's avatar
Jarrod Pas committed
    node_options = {
        'tick_rate': 5 * 60,  # 5 mins
Jarrod Pas's avatar
Jarrod Pas committed
        'epoch': epoch,
        'k': 3,
Jarrod Pas's avatar
Jarrod Pas committed
    }
    nodes = {
Jarrod Pas's avatar
Jarrod Pas committed
        node_id: simulation.node_type(**node_options)
Jarrod Pas's avatar
Jarrod Pas committed
        for node_id in range(trace.nodes)
Jarrod Pas's avatar
Jarrod Pas committed
    traffic_options = {
        'seed': seed,
        'start': epoch,
Jarrod Pas's avatar
Jarrod Pas committed
        'step': 60 * 60,  # 1 packet every 1 mins
    traffic = RandomTraffic(nodes, **traffic_options)
Jarrod Pas's avatar
Jarrod Pas committed

    network = Network(nodes, traffic=traffic, trace=trace)
    network.run()

    stats = {
Jarrod Pas's avatar
Jarrod Pas committed
        'trace': simulation.trace,
Jarrod Pas's avatar
Jarrod Pas committed
        'node_type': node_type.__name__,
        'seed': seed,
    }
    stats.update(network.stats_summary)
Jarrod Pas's avatar
Jarrod Pas committed

    # return stats because we can't pickle the network as it is a generator.
Jarrod Pas's avatar
Jarrod Pas committed
    return stats


def main(args):
Jarrod Pas's avatar
Jarrod Pas committed
    """Run simulation for each seed in args."""
Jarrod Pas's avatar
Jarrod Pas committed
    log = pprint if args['pretty'] else print
Jarrod Pas's avatar
Jarrod Pas committed
    pool = Pool()
Jarrod Pas's avatar
Jarrod Pas committed
    simulations = []
Jarrod Pas's avatar
Jarrod Pas committed

    trace = args['shed']
Jarrod Pas's avatar
Jarrod Pas committed
    node_types = [
        Node,
        EpidemicNode,
        BubbleAGKmeansNode,
        HCBFAGKmeansNode,
        BubbleLouvainNode,
        HCBFLouvainNode,
        BubbleKCliqueNode,
        HCBFKCliqueNode,
Jarrod Pas's avatar
Jarrod Pas committed

    for seed in args['seeds']:
Jarrod Pas's avatar
Jarrod Pas committed
        for node_type in node_types:
Jarrod Pas's avatar
Jarrod Pas committed
            sim = Simulation(trace=trace, node_type=node_type, seed=seed)
            simulations.append(sim)
    for stats in pool.imap_unordered(run_simulation, simulations):
Jarrod Pas's avatar
Jarrod Pas committed
        log(stats)
Jarrod Pas's avatar
Jarrod Pas committed


def parse_args(args):
Jarrod Pas's avatar
Jarrod Pas committed
    """Parse arguments."""
Jarrod Pas's avatar
Jarrod Pas committed
    parser = ArgumentParser()

    parser.add_argument('shed')
Jarrod Pas's avatar
Jarrod Pas committed
    parser.add_argument('--pretty', action='store_true')
Jarrod Pas's avatar
Jarrod Pas committed
    parser.add_argument('--seeds', '-s',
                        metavar='SEED', type=int, nargs='+', default=[None])

    args = parser.parse_args(args)
    return vars(args)


if __name__ == '__main__':
    exit(main(parse_args(sys.argv[1:])))