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) json_data = load(f)
network = network_from_json(json_data) 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()} 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()] size = [20 if isinstance(n, Fiber) else 80 for n in network.nodes()]
color = ['green' if isinstance(n, Transceiver) else 'red' color = ['green' if isinstance(n, Transceiver) else 'red'

View File

@@ -1,46 +1,34 @@
#!/usr/bin/env python #!/usr/bin/env python3
from collections import namedtuple
class Coords(namedtuple('Coords', 'latitude longitude')): from core.node import Node
lat = property(lambda self: self.latitude) from core.units import UNITS
long = property(lambda self: self.longitude)
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')): class Transceiver(Node):
def __new__(cls, uid, location): def __init__(self, config):
return super().__new__(cls, uid, Location(**location)) super().__init__(config)
def __call__(self, *spectral_infos): def __call__(self, spectral_info):
return spectral_info.copy() 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')): class Fiber(Node):
UNITS = {'m': 1, 'km': 1e3} def __init__(self, config):
super().__init__(config)
@property metadata = self.config.metadata
def value(self): self.length = metadata.length * UNITS[metadata.units]
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))
def __repr__(self): def __repr__(self):
return f'{type(self).__name__}(uid={self.uid}, length={self.length})' return f'{type(self).__name__}(uid={self.uid}, length={self.length})'
def __call__(self, *spectral_infos): def propagate(self, *carriers):
return spectral_info.copy() 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 def __call__(self, spectral_info):
length = property(lambda self: self.length_.value) carriers = tuple(self.propagate(*spectral_info.carriers))
loc = property(lambda self: self.location) return spectral_info.update(carriers=carriers)
lat = property(lambda self: self.location.latitude)
long = property(lambda self: self.location.longitude)

View File

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