Files
oopt-gnpy/examples/convert.py
James 58ac717f8d Develop (#14)
* adding rrc filter, temporarily putting it in utilities.py
* added some docstring stuff
* added a simple loss class for fiber and cleaned up some duplicate convenience access properties
* Changed Carrier to Channel to reflect correct nomenclature for multi-carrier/superchannels
* in process fixes for main.py.  adding in amp spacings and spans to convert to start adding additional noded to Coronet network
* some simple additions to utilites
* adding stand alone edfa model
2017-12-06 22:04:24 -05:00

140 lines
5.1 KiB
Python

#!/usr/bin/env python3
from sys import exit
try:
from xlrd import open_workbook
except ModuleNotFoundError:
exit('Required: `pip install xlrd`')
from argparse import ArgumentParser
from collections import namedtuple, Counter
from itertools import chain
from json import dumps
from uuid import uuid4
import math
import numpy as np
Node = namedtuple('Node', 'city state country region latitude longitude')
class Link(namedtuple('Link', 'from_city to_city distance distance_units')):
def __new__(cls, from_city, to_city, distance, distance_units='km'):
return super().__new__(cls, from_city, to_city, distance, distance_units)
def define_span_range(min_span, max_span, nspans):
srange = (max_span - min_span) + min_span*np.random.rand(nspans)
return srange
def amp_spacings(min_span,max_span,length):
nspans = math.ceil(length/100)
spans = define_span_range(min_span, max_span, nspans)
tot = spans.sum()
delta = length -tot
if delta > 0 and delta < 25:
ind = np.where(np.min(spans))
spans[ind] = spans[ind] + delta
elif delta >= 25 and delta < 40:
spans = spans + delta/float(nspans)
elif delta > 40 and delta < 100:
spans = np.append(spans,delta)
elif delta > 100:
spans = np.append(spans, [delta/2, delta/2])
elif delta < 0:
spans = spans + delta/float(nspans)
return list(spans)
def parse_excel(args):
with open_workbook(args.workbook) as wb:
nodes_sheet = wb.sheet_by_name('Nodes')
links_sheet = wb.sheet_by_name('Links')
# sanity check
header = [x.value.strip() for x in nodes_sheet.row(4)]
expected = ['City', 'State', 'Country', 'Region', 'Latitude', 'Longitude']
if header != expected:
raise ValueError(f'Malformed header on Nodes sheet: {header} != {expected}')
nodes = []
for row in all_rows(nodes_sheet, start=5):
nodes.append(Node(*(x.value for x in row)))
# sanity check
header = [x.value.strip() for x in links_sheet.row(4)]
expected = ['Node A', 'Node Z', 'Distance (km)']
if header != expected:
raise ValueError(f'Malformed header on Nodes sheet: {header} != {expected}')
links = []
for row in all_rows(links_sheet, start=5):
links.append(Link(*(x.value for x in row)))
# sanity check
all_cities = Counter(n.city for n in nodes)
if len(all_cities) != len(nodes):
ValueError(f'Duplicate city: {all_cities}')
if any(ln.from_city not in all_cities or
ln.to_city not in all_cities for ln in links):
ValueError(f'Bad link.')
return nodes, links
parser = ArgumentParser()
parser.add_argument('workbook', nargs='?', default='CORONET_Global_Topology.xls')
parser.add_argument('-f', '--filter-region', action='append', default=[])
all_rows = lambda sh, start=0: (sh.row(x) for x in range(start, sh.nrows))
def midpoint(city_a, city_b):
lats = city_a.latitude, city_b.latitude
longs = city_a.longitude, city_b.longitude
return {
'latitude': sum(lats) / 2,
'longitude': sum(longs) / 2,
}
if __name__ == '__main__':
args = parser.parse_args()
nodes, links = parse_excel(args)
if args.filter_region:
nodes = [n for n in nodes if n.region.lower() in args.filter_region]
cities = {n.city for n in nodes}
links = [lnk for lnk in links if lnk.from_city in cities and
lnk.to_city in cities]
cities = {lnk.from_city for lnk in links} | {lnk.to_city for lnk in links}
nodes = [n for n in nodes if n.city in cities]
nodes_by_city = {n.city: n for n in nodes}
data = {
'elements':
[{'uid': x.city,
'metadata': {'location': {'city': x.city,
'region': x.region,
'latitude': x.latitude,
'longitude': x.longitude}},
'type': 'Transceiver'}
for x in nodes] +
[{'uid': f'fiber ({x.from_city}{x.to_city})',
'metadata': {'length': round(x.distance, 3),
'units': x.distance_units,
'location': midpoint(nodes_by_city[x.from_city],
nodes_by_city[x.to_city])},
'type': 'Fiber'}
for x in links],
'connections':
list(chain.from_iterable(zip( # put bidi next to each other
[{'from_node': x.from_city,
'to_node': f'fiber ({x.from_city}{x.to_city})'}
for x in links],
[{'from_node': f'fiber ({x.from_city}{x.to_city})',
'to_node': x.from_city}
for x in links])))
+
list(chain.from_iterable(zip(
[{'from_node': f'fiber ({x.from_city}{x.to_city})',
'to_node': x.to_city}
for x in links],
[{'from_node': x.to_city,
'to_node': f'fiber ({x.from_city}{x.to_city})'}
for x in links])))
}
print(dumps(data, indent=2))