Merge pull request #6 from giladg-FB/develop

adding base node class
This commit is contained in:
James
2017-12-05 22:40:43 -05:00
committed by GitHub
5 changed files with 80 additions and 44 deletions

View File

@@ -18,7 +18,7 @@ def main(args):
json_data = load(f)
network = network_from_json(json_data)
pos = {n: (n.long, n.lat) for n in network.nodes()}
pos = {n: (n.lng, n.lat) for n in network.nodes()}
labels_pos = {n: (long-.5, lat-.5) for n, (long, lat) in pos.items()}
size = [20 if isinstance(n, Fiber) else 80 for n in network.nodes()]
color = ['green' if isinstance(n, Transceiver) else 'red'

View File

@@ -1,46 +1,34 @@
#!/usr/bin/env python
from collections import namedtuple
#!/usr/bin/env python3
class Coords(namedtuple('Coords', 'latitude longitude')):
lat = property(lambda self: self.latitude)
long = property(lambda self: self.longitude)
from core.node import Node
from core.units import UNITS
class Location(namedtuple('Location', 'city region coords')):
def __new__(cls, city, region, **kwargs):
return super().__new__(cls, city, region, Coords(**kwargs))
class Transceiver(namedtuple('Transceiver', 'uid location')):
def __new__(cls, uid, location):
return super().__new__(cls, uid, Location(**location))
class Transceiver(Node):
def __init__(self, config):
super().__init__(config)
def __call__(self, *spectral_infos):
return spectral_info.copy()
def __call__(self, spectral_info):
return spectral_info
# convenience access
loc = property(lambda self: self.location)
lat = property(lambda self: self.location.coords.latitude)
long = property(lambda self: self.location.coords.longitude)
class Length(namedtuple('Length', 'quantity units')):
UNITS = {'m': 1, 'km': 1e3}
@property
def value(self):
return self.quantity * self.UNITS[self.units]
val = value
class Fiber(namedtuple('Fiber', 'uid length_ location')):
def __new__(cls, uid, length, units, location):
return super().__new__(cls, uid, Length(length, units), Coords(**location))
class Fiber(Node):
def __init__(self, config):
super().__init__(config)
metadata = self.config.metadata
self.length = metadata.length * UNITS[metadata.units]
def __repr__(self):
return f'{type(self).__name__}(uid={self.uid}, length={self.length})'
def __call__(self, *spectral_infos):
return spectral_info.copy()
def propagate(self, *carriers):
for carrier in carriers:
power = carrier.power
power = power._replace(signal=0.5 * power.signal * .5,
nonlinear_interference=2 * power.nli,
amplified_spontaneous_emission=2 * power.ase)
yield carrier._replace(power=power)
# convenience access
length = property(lambda self: self.length_.value)
loc = property(lambda self: self.location)
lat = property(lambda self: self.location.latitude)
long = property(lambda self: self.location.longitude)
def __call__(self, spectral_info):
carriers = tuple(self.propagate(*spectral_info.carriers))
return spectral_info.update(carriers=carriers)

View File

@@ -2,22 +2,21 @@
from networkx import DiGraph
from . import elements
from core import elements
def network_from_json(json_data):
# NOTE|dutc: we could use the following, but it would tie our data format
# too closely to the graph library
# from networkx import node_link_graph
g = DiGraph()
for el_config in json_data['elements']:
g.add_node(getattr(elements, el_config['type'])(el_config))
nodes = {}
for el in json_data['elements']:
el = getattr(elements, el['type'])(el['uid'], **el['metadata'])
g.add_node(el)
nodes[el.uid] = el
nodes = {k.uid: k for k in g.nodes()}
for cx in json_data['connections']:
from_node, to_node = nodes[cx['from_node']], nodes[cx['to_node']]
g.add_edge(from_node, to_node)
from_node, to_node = cx['from_node'], cx['to_node']
g.add_edge(nodes[from_node], nodes[to_node])
return g

47
core/node.py Normal file
View File

@@ -0,0 +1,47 @@
#! /bin/usr/python3
from uuid import uuid4
# helpers
class ConfigStruct:
def __init__(self, **entries):
if entries is None:
return None
for k, v in entries.items():
setattr(self, k, ConfigStruct(**v) if isinstance(v, dict) else v)
def __repr__(self):
return f'{self.__dict__}'
class Node:
def __init__(self, config=None):
self.config = ConfigStruct(**config)
if self.config is None or not hasattr(self.config, 'uid'):
self.uid = uuid4()
else:
self.uid = self.config.uid
@property
def coords(self):
return tuple(self.lng, self.lat)
@property
def location(self):
return self.config.metadata.location
@property
def loc(self): # Aliases .location
return self.location
@property
def lng(self):
return self.config.metadata.location.longitude
@property
def lat(self):
return self.config.metadata.location.latitude

2
core/units.py Normal file
View File

@@ -0,0 +1,2 @@
UNITS = {'m': 1,
'km': 1e3}