Gen Event Schedule
==================

::

    """
    Generate Event Schedule
    =======================
    
    This example shows how to generate an event schedule.
    
    In this specific example we create a dumbbell topology, place traffic sources
    on one side and traffic receivers on the other side and we generate requests
    following a Poisson distribution.
    """
    import fnss
    import random
    import networkx as nx
    
    # generate a dumbbell topology with 5 nodes on each bell and 3 nodes on the
    # connecting path
    topology = fnss.dumbbell_topology(5, 3)
    
    # assign constant weight (1) to all links
    fnss.set_weights_constant(topology, 1)
    
    # now extract links located in the edges and links in the core
    # we do this easily using Python list comprehension. Each link in the dumbbell
    # topology has a 'type' attribute which identifies whether it a link of the
    # core path or it is in a bell. 
    # Look at dumbbell_topology documentation for more details.
    
    # this return a dictionary of egdes and value of attribute type
    # This function is provided by the NetworkX library.
    # Since FNSS Topology and DirecteedTopology objects inherit from NetworkX's
    # Graph and DiGraph, respectively, NetworkX functions can be used in FNSS too.
    link_types = nx.get_edge_attributes(topology, 'type')
    core_links = [links for links in link_types if link_types[links] == 'core']
    edge_links = [links for links in link_types 
                  if link_types[links] == 'right_bell' 
                  or link_types[links] == 'left_bell']
    
    # set delay equal to 1 ms in edge links and equal to 2 ms in core links
    fnss.set_delays_constant(topology, 1, 'ms', edge_links)
    fnss.set_delays_constant(topology, 2, 'ms', core_links)
    
    # set capacity of 10 Mbps in edge links and 40 Mbps in core links
    fnss.set_capacities_constant(topology, 10, 'Mbps', edge_links)
    fnss.set_capacities_constant(topology, 40, 'Mbps', core_links)
    
    # Now we deploy a traffic sources on right bell and traffic receivers on left
    # bell
    node_types = nx.get_node_attributes(topology, 'type')
    left_nodes = [nodes for nodes in node_types 
                  if node_types[nodes] == 'left_bell']
    right_nodes = [nodes for nodes in node_types 
                  if node_types[nodes] == 'right_bell']
    
    for node in left_nodes:
        fnss.add_application(topology, node, 'receiver', {})
    
    for node in right_nodes:
        fnss.add_application(topology, node, 'source', {})
        
    # now create a function that generate events
    def rand_request(source_nodes, receiver_nodes):
        source = random.choice(source_nodes)
        receiver = random.choice(receiver_nodes)
        return {'source': source, 'receiver': receiver}
    
    event_schedule = fnss.poisson_process_event_schedule(
                            avg_interval=50,                # 50 ms
                            t_start=0,                      # starts at 0
                            duration= 10*1000,              # 10 sec
                            t_unit='ms',                    # milliseconds
                            event_generator=rand_request,   # event gen function
                            source_nodes=right_nodes,       # rand_request argument
                            receiver_nodes=left_nodes       # rand_request argument
                            )
    # Write topology and event schedule to files
    fnss.write_topology(topology, 'topology.xml')
    fnss.write_event_schedule(event_schedule, 'event_schedule.xml')
    
    
    
    
