utils.py 5.01 KB
Newer Older
1
import networkx as nx
2
3
4
5
6
import sys
if (sys.version_info > (3, 0)):
    import http.client as httplib
else:
    import httplib
7
8
9
10

def reciprocity(G):
    """Calculate reciprocity of graph, i.e. the ratio of the edges in
    one direction that have and edge going in the other direction."""
11
    return sum([G.has_edge(e[1], e[0])
12
    for e in G.edges]) / float(G.number_of_edges())
13
14
15
16
17
18
19
20
21
22
23
24
25

def short_names(names):
   labels = {}
   for n in names:
      mainlabel = n[0:3]
      if n[2] == '-':
         mainlabel = n[0:2]
      if n[-2:].startswith('w'):
         labels[n] = (mainlabel + n[-1])
      else:
         labels[n] = mainlabel
   return labels

26
def edge_labels(edges, edgegroups=[], suppress_default=True):
27
28
29
30
31
   labels = []

   i = 0

   edgedone = {}
32
33

   for (u,v,w) in edges:
34
35
36
37
      for el, type in edgegroups:
         for (s,t,x) in el:
            if (u,v) == (s,t):
               if not (u,v) in edgedone:
Morten Knutsen's avatar
Morten Knutsen committed
38
                  metric = int(x['weight'])
39
                  m = str(metric)
40
                  if metric == 10 and suppress_default:
41
                      m = ""
42
43
                  if type.endswith("opath") and x['weight'] != w['weight']:
                     m = "%s (%s)" % (str(int(x['weight'])), str(int(w['weight'])))
44
45
46
47
48
49
50
51
52
53
54
                  l = (i, m, type.startswith('main'))
                  labels.append((i, m, type.startswith('main')))
                  edgedone[(u,v)] = l
                  i = i + 1
      if (u,v) not in edgedone:
         labels.append((i, "", False))
         i = i + 1

   try:
      assert len(edges) == len(labels)
   except:
55
      print("Assertion fail: %s != %s" % (len(edges), len(labels)))
56
57
58
59
60

   return labels


def cap2str(capacity):
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    """Capacity to Human Readable string convertion

    Converts the given Capacity in Kbit to human readable representation,
    It will return a one digit decimal precition and omitts the decimal 
    if its zero
    """
    if capacity < 1000: 
        s, i = "K", float(capacity) 
    elif capacity < 1000000: 
        s, i = "M", round(float(capacity)/1000.0, 1) 
    elif capacity < 1000000000: 
        s, i = "G", round(float(capacity)/1000000.0, 1) 
    elif capacity < 1000000000000: 
        s, i = "T", round(float(capacity)/1000000000.0,1) 
    else: 
        s, i = "E", round(float(capacity)/1000000000000.0,1)
         

    if i % 1 == 0: 
        return "{:0.0f}{}bit/s".format(i, s) 
    else: 
        return "{:0.1f}{}bit/s".format(i, s) 
83

84
def read_linkloads(G, host, url):
85

86
    conn = httplib.HTTPConnection(host)
87
    conn.request("GET", url)
88
89
    r1 = conn.getresponse()
    if r1.status != 200:
90
        conn.close()
91
92
93
        return {}
    data1 = r1.read()
    if not data1:
94
        conn.close()
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        return {}
    conn.close()

    loads_by_descr = {}

    retloads = {}

    for line in data1.split('\n'):
        if not line: continue
        tokens = line.split()
        descr = tokens[0].strip()
        avg_in = int(tokens[3].strip())
        avg_out = int(tokens[4].strip())

        loads_by_descr[descr] = (avg_out, avg_in)

111
    for (u,v,edgedata) in G.edges(data=True):
112
113
114
115
116
117
118
        if not 'l' in edgedata: continue
        label = edgedata['l']
        if label in loads_by_descr:
            retloads[(u,v)] = loads_by_descr[label]

    sanitized_loads = {}
    for (u,v) in retloads:
119
120
121
122
123
        if (v,u) in retloads:
            if retloads[(v,u)][1] > retloads[(u,v)][0]:
                sanitized_loads[(u,v)] = retloads[(v,u)][1]
            else:
                sanitized_loads[(u,v)] = retloads[(u,v)][0]
124
125
        else:
            sanitized_loads[(u,v)] = retloads[(u,v)][0]
126
            sanitized_loads[(v,u)] = retloads[(u,v)][1]
127
128
129
130
131
132
133

    return sanitized_loads


def calc_ratio(G, loads, u, v, discard_inverse=False, no_diff=False, exclude_edges=[]):
  sum = 0
  totload = loads[(u,v)]
134
135
136
  #for (u1,v1,d) in [(v2, u2, d2) for (u2, v2, d2) in G.edges(data=True) if u2 == u]:
  for neighbor in G[u]:
      if (neighbor,u) in exclude_edges:
137
138
          #totload -= loads[(u1,v1)] * calc_ratio(G, loads, u,v)
          continue
139
      if discard_inverse and (neighbor,u) == (v,u): continue
140
141
142
143
      if not (neighbor,u) in loads:
          sum += 0.0
      else:
          sum += float(loads[(neighbor,u)])
144
145
146
147
148
149
150
151
152
153
  ee = []
  #if discard_inverse: ee += [(v,u)]
  ndiff = node_diff_in_out(G, loads, u, False, ee)
  if not no_diff:
      if ndiff < 0:
          sum += -ndiff
  if sum == 0:
     return 0
  ratio = totload / float(sum)
  if ratio < 0:
154
155
      print("Assertion failed for ratio (%s, %s): %s" \
          % (u, v, ratio))
156
157
158
159
160
161
162
163
  if ratio > 1:
      ratio = 1
  return ratio

def node_diff_in_out(G, loads, node, inverse=False, exclude_edges=[]):
   sum_out = 0
   sum_in = 0

164
165
   for neighbor in G[node]:
      if (node,neighbor) not in exclude_edges:
166
167
168
169
         if (node,neighbor) not in loads:
             sum_out += 0.0
         else:
             sum_out += loads[(node,neighbor)]
170
      if (neighbor,node) not in exclude_edges:
171
172
173
174
         if (neighbor,node) not in loads:
             sum_in += 0.0
         else:
             sum_in += loads[(neighbor,node)]
175
176
177

   if inverse:
      return sum_in - sum_out
178

179
180
   return sum_out - sum_in