Skip to content
Snippets Groups Projects
shed.py 2.2 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

from pydtn import Network, RandomTraffic, Node, EpidemicNode
Jarrod Pas's avatar
Jarrod Pas committed
from pydtn.community import BubbleNode, HCBFNode, LouvainCommunity
Jarrod Pas's avatar
Jarrod Pas committed
import pydtn.shed as shed
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
    trace_metadata = shed.read_meta_file(simulation.trace)
    trace = shed.shed_trace(simulation.trace)
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
        'community': LouvainCommunity(epoch),
    }
    nodes = {
Jarrod Pas's avatar
Jarrod Pas committed
        node_id: simulation.node_type(**node_options)
        for node_id in range(trace_metadata['nodes'])
Jarrod Pas's avatar
Jarrod Pas committed
    traffic_options = {
        'seed': seed,
        'start': epoch,
        'speed': 30 * 60,  # 1 packet every 30 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."""
    trace = args['shed']
Jarrod Pas's avatar
Jarrod Pas committed
    pool = Pool()
Jarrod Pas's avatar
Jarrod Pas committed
    simulations = []
Jarrod Pas's avatar
Jarrod Pas committed

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


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')
    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:])))