def __init__(self, topology, log_dir, scenario_id):
     """
     Constructor
     """
     # create logging objects
     # for running on clay or EE lab, open logging files in /tmp
     # and then (compress it) and move it to home. This is to avoid frequent
     # NFS writes, so I write on tmp which is on local drive and copy to home
     # (NFS) only when the simulation is over.
     # Compression may be needed on EE lab machine because there is a 5 GB
     # quota that might be exceeded by logs
     self.log_dir = log_dir
     self.scenario_id = scenario_id
     self.link_logger = LinkLogger(path.join(log_dir, 'RESULTS_%s_LINK.txt' % scenario_id))
     self.cache_logger = CacheLogger(path.join(log_dir, 'RESULTS_%s_CACHE.txt' % scenario_id))
     self.delay_logger = DelayLogger(path.join(log_dir, 'RESULTS_%s_DELAY.txt' % scenario_id))
     self.topology = topology
     # calc shortest paths
     self.shortest_path = nx.all_pairs_dijkstra_path(topology, weight='weight')
     # get location of caches and content sources
     self.content_location = {}   # dict of location of contents keyed by content ID
     self.cache_size = {}         # dict of cache sizes keyed by node
     # Link type: internal or external
     self.link_type = dict([((u,v), topology.edge[u][v]['type'])
                            for u in topology.edge
                            for v in topology.edge[u]])
     for node in topology.nodes_iter():
         stack_name, stack_props = get_stack(topology, node)
         if stack_name == 'cache':
             self.cache_size[node] = stack_props['size']
         elif stack_name == 'source':
             contents = stack_props['contents']
             for content in contents:
                 self.content_location[content] = node
     # create actual cache objects
     self.caches = dict([(node, Cache(self.cache_size[node])) for node in self.cache_size])