fixed merge conflict

This commit is contained in:
James Powell
2018-07-10 10:27:24 -04:00
13 changed files with 1569 additions and 533 deletions

View File

@@ -205,7 +205,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -221,7 +223,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -237,7 +241,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -253,7 +259,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -269,7 +277,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -285,7 +295,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -301,7 +313,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -317,7 +331,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -333,7 +349,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -349,7 +367,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -365,7 +385,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -381,7 +403,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -397,7 +421,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -413,7 +439,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -429,7 +457,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -445,7 +475,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
}
],

Binary file not shown.

View File

@@ -31,6 +31,7 @@ from gnpy.core.equipment import load_equipment
from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power
from gnpy.core.request import Path_request, Result_element, compute_constrained_path, propagate
from copy import copy, deepcopy
from numpy import log10
@@ -46,125 +47,34 @@ parser.add_argument('-v', '--verbose', action='count')
parser.add_argument('-o', '--output', default=None)
class Path_request():
def __init__(self,jsondata,tspjsondata):
self.request_id = jsondata['request-id']
self.source = jsondata['src-tp-id']
self.destination = jsondata['dst-tp-id']
# retrieving baudrate out of transponder type and mode (format)
self.tsp = jsondata['path-constraints']['te-bandwidth']['trx_type']
self.tsp_mode = jsondata['path-constraints']['te-bandwidth']['trx_mode']
# for debug
# print(tsp)
try:
baudrate = next(m['baudrate']
for t in tspjsondata if t['type_variety'] == self.tsp
for m in t['mode'] if m['format'] == self.tsp_mode)
except StopIteration:
msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library'
logger.critical(msg)
raise ValueError(msg)
self.baudrate = baudrate
nodes_list = jsondata['optimizations']['explicit-route-include-objects']
self.nodes_list = [n['unnumbered-hop']['node-id'] for n in nodes_list]
# create a list for individual loose capability for each node ...
# even if convert_service_sheet fills it with the same value
self.loose_list = [n['unnumbered-hop']['hop-type'] for n in nodes_list]
self.spacing = jsondata['path-constraints']['te-bandwidth']['spacing']
self.power = jsondata['path-constraints']['te-bandwidth']['output-power']
self.nb_channel = jsondata['path-constraints']['te-bandwidth']['max-nb-of-channel']
def __str__(self):
return '\n\t'.join([ f'{type(self).__name__} {self.request_id}',
f'source: {self.source}',
f'destination: {self.destination}'])
def __repr__(self):
return '\n\t'.join([ f'{type(self).__name__} {self.request_id}',
f'source: {self.source}',
f'destination: {self.destination}',
f'trx type: {self.tsp}',
f'baudrate: {self.baudrate}',
f'spacing: {self.spacing}',
f'power: {self.power}'
'\n'])
class Result_element(Element):
def __init__(self,path_request,computed_path):
self.path_id = int(path_request.request_id)
self.path_request = path_request
self.computed_path = computed_path
hop_type = []
for e in computed_path :
if isinstance(e, Transceiver) :
hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode]))
else:
hop_type.append('not recorded')
self.hop_type = hop_type
uid = property(lambda self: repr(self))
@property
def pathresult(self):
return {
'path-id': self.path_id,
'path-properties':{
'path-metric': [
{
'metric-type': 'SNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].snr),2)
},
{
'metric-type': 'SNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].snr+10*log10(self.path_request.baudrate/12.5)),2)
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
},
'path-route-objects': [
{
'path-route-object': {
'index': self.computed_path.index(n),
'unnumbered-hop': {
'node-id': n.uid,
'link-tp-id': n.uid,
'hop-type': self.hop_type[self.computed_path.index(n)],
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
}
} for n in self.computed_path
]
}
}
@property
def json(self):
return self.pathresult
def load_SI(filename):
with open(filename) as f:
json_data = loads(f.read())
return json_data['SI'][0]
def load_Transceiver(filename):
with open(filename) as f:
json_data = loads(f.read())
return json_data['Transceiver']
def requests_from_json(json_data,eqpt_filename):
def requests_from_json(json_data,equipment):
requests_list = []
tspjsondata = load_Transceiver(eqpt_filename)
tsp_lib = equipment['Transceiver']
for req in json_data['path-request']:
#print(f'{req}')
requests_list.append(Path_request(req,tspjsondata))
params = {}
params['request_id'] = req['request-id']
params['source'] = req['src-tp-id']
params['destination'] = req['dst-tp-id']
params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
params['frequency'] = tsp_lib[params['trx_type']].frequency
try:
extra_params = next(m
for m in tsp_lib[params['trx_type']].mode if m['format'] == params['trx_mode'])
except StopIteration :
msg = f'could not find tsp : {params["trx_type"]} with mode: {params["trx_mode"]} in eqpt library'
raise ValueError(msg)
nd_list = req['optimizations']['explicit-route-include-objects']
params['nodes_list'] = [n['unnumbered-hop']['node-id'] for n in nd_list]
params['loose_list'] = [n['unnumbered-hop']['hop-type'] for n in nd_list]
params['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
params['power'] = req['path-constraints']['te-bandwidth']['output-power']
params['nb_channel'] = req['path-constraints']['te-bandwidth']['max-nb-of-channel']
params.update(extra_params)
requests_list.append(Path_request(**params))
return requests_list
@@ -179,65 +89,22 @@ def load_requests(filename,eqpt_filename):
return json_data
def compute_path(network, pathreqlist):
# temporary : repeats calls from transmission_main_example
# to be merged when ready
path_res_list = []
trx = [n for n in network.nodes() if isinstance(n, Transceiver)]
roadm = [n for n in network.nodes() if isinstance(n, Roadm)]
edfa = [n for n in network.nodes() if isinstance(n, Edfa)]
# TODO include also fused in the element check : too difficult because of direction
# fused = [n for n in network.nodes() if isinstance(n, Fused)]
sidata = load_SI(args.eqpt_filename)
for pathreq in pathreqlist:
pathreq.nodes_list.append(pathreq.destination)
#we assume that the destination is a strict constraint
pathreq.loose_list.append('strict')
print(f'Computing path from {pathreq.source} to {pathreq.destination}')
print(f'with explicit path: {pathreq.nodes_list}')
total_path = compute_constrained_path(network, pathreq)
source = next(el for el in trx if el.uid == pathreq.source)
# start the path with its source
total_path = [source]
for n in pathreq.nodes_list:
# print(n)
try :
node = next(el for el in trx if el.uid == n)
except StopIteration:
try:
node = next(el for el in roadm if el.uid == f'roadm {n}')
except StopIteration:
try:
node = next(el for el in edfa
if el.uid.startswith(f'egress edfa in {n}'))
except StopIteration:
msg = f'could not find node : {n} in network topology: \
not a trx, roadm, edfa or fused element'
logger.critical(msg)
raise ValueError(msg)
# extend path list without repeating source -> skip first element in the list
try:
total_path.extend(dijkstra_path(network, source, node)[1:])
source = node
except NetworkXNoPath:
# for debug
# print(pathreq.loose_list)
# print(pathreq.nodes_list.index(n))
if pathreq.loose_list[pathreq.nodes_list.index(n)] == 'loose':
print(f'could not find a path from {source.uid} to loose node : {n} in network topology')
print(f'node {n} is skipped')
else:
msg = f'could not find a path from {source.uid} to node : {n} in network topology'
logger.critical(msg)
raise ValueError(msg)
# for debug
# print(f'{pathreq.baudrate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}')
si = create_input_spectral_information(
sidata['f_min'], sidata['roll_off'],
pathreq.baudrate, pathreq.power, pathreq.spacing, pathreq.nb_channel)
for el in total_path:
si = el(si)
# print(el)
total_path = propagate(total_path,pathreq,equipment, show=False)
# we record the last tranceiver object in order to have th whole
# information about spectrum. Important Note: since transceivers
# attached to roadms are actually logical elements to simulate
@@ -246,7 +113,6 @@ def compute_path(network, pathreqlist):
# we use deepcopy: to ensure each propagation is recorded and not
# overwritten
# path_res_list.append(deepcopy(destination))
path_res_list.append(deepcopy(total_path))
return path_res_list
@@ -267,7 +133,7 @@ if __name__ == '__main__':
equipment = load_equipment(args.eqpt_filename)
network = load_network(args.network_filename,equipment)
build_network(network, equipment=equipment)
pths = requests_from_json(data, args.eqpt_filename)
pths = requests_from_json(data, equipment)
print(pths)
test = compute_path(network,pths)

View File

@@ -20,7 +20,8 @@ from networkx import (draw_networkx_nodes, draw_networkx_edges,
from gnpy.core import load_network, build_network
from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm
from gnpy.core.info import SpectralInformation, Channel, Power
from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power
from gnpy.core.request import Path_request, RequestParams, compute_constrained_path, propagate
logger = getLogger(__name__)
@@ -48,26 +49,19 @@ def plot_results(network, path, source, sink):
show()
def main(network, equipment, source, sink):
def main(network, equipment, source, sink, req = None):
build_network(network, equipment=equipment)
path = dijkstra_path(network, source, sink)
path = compute_constrained_path(network,req)
spans = [s.length for s in path if isinstance(s, Fiber)]
print(f'\nThere are {len(spans)} fiber spans over {sum(spans):.0f}m between {source.uid} and {sink.uid}')
print(f'\nNow propagating between {source.uid} and {sink.uid}:')
for p in range(0, 1): #change range to sweep results across several powers in dBm
p=db2lin(p)*1e-3
spacing = 0.05 # THz
si = SpectralInformation() # SI units: W, Hz
si = si.update(carriers=[
Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0))
for f in range(1,97)
])
print(f'\nPorpagating with input power = {lin2db(p*1e3):.2f}dBm :')
for el in path:
si = el(si)
print(el) #remove this line when sweeping across several powers
print(f'\nTransmission result for input power = {lin2db(p*1e3):.2f}dBm :')
req.power = db2lin(p)*1e-3
print(f'\nPropagating with input power = {lin2db(req.power*1e3):.2f}dBm :')
propagate(path,req,equipment,show=True)
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :')
print(sink)
return path
@@ -91,7 +85,7 @@ if __name__ == '__main__':
# logger.info(equipment)
network = load_network(args.filename, equipment)
print(network)
# print(network)
transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)}
@@ -135,7 +129,29 @@ if __name__ == '__main__':
logger.info(f'source = {args.source!r}')
logger.info(f'sink = {args.sink!r}')
path = main(network, equipment, source, sink)
params = {}
params['request_id'] = 0
params['source'] = source.uid
params['destination'] = sink.uid
params['trx_type'] = 'vendorA_trx-type1'
params['trx_mode'] = 'PS_SP64_1'
params['nodes_list'] = [sink.uid]
params['loose_list'] = ['strict']
params['spacing'] = 50e9
params['power'] = 0
params['nb_channel'] = 97
params['frequency'] = equipment['Transceiver'][params['trx_type']].frequency
try:
extra_params = next(m
for m in equipment['Transceiver'][params['trx_type']].mode
if m['format'] == params['trx_mode'])
except StopIteration :
msg = f'could not find tsp : {params} with mode: {params} in eqpt library'
raise ValueError(msg)
params.update(extra_params)
req = Path_request(**params)
path = main(network, equipment, source, sink,req)
if args.plot:
plot_results(network, path, source, sink)

View File

@@ -156,7 +156,9 @@ def convert_file(input_filename, filter_region=[]):
'type_variety': x.east_fiber,
'params': {'length': round(x.east_distance, 3),
'length_units': x.distance_units,
'loss_coef': x.east_lineic}
'loss_coef': x.east_lineic,
'connector_loss_in':x.east_con_in,
'connector_loss_out':x.east_con_out}
}
for x in links] +
[{'uid': f'fiber ({x.to_city}{x.from_city})-{x.west_cable}',
@@ -166,7 +168,9 @@ def convert_file(input_filename, filter_region=[]):
'type_variety': x.west_fiber,
'params': {'length': round(x.west_distance, 3),
'length_units': x.distance_units,
'loss_coef': x.west_lineic}
'loss_coef': x.west_lineic,
'connector_loss_in':x.west_con_in,
'connector_loss_out':x.west_con_out}
} # missing ILA construction
for x in links] +
[{'uid': f'egress edfa in {e.from_city} to {e.to_city}',

View File

@@ -143,17 +143,23 @@ class Fused(Node):
carriers = tuple(self.propagate(*spectral_info.carriers))
return spectral_info.update(carriers=carriers)
FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_units dispersion gamma')
FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_units connector_loss_in connector_loss_out dispersion gamma')
class Fiber(Node):
def __init__(self, *args, params=None, **kwargs):
if params is None:
params = {}
if 'connector_loss_in' not in params :
# test added to ensure backward compatibility in case loss was not in the json
params['connector_loss_in'] = 0.0
params['connector_loss_out'] = 0.0
super().__init__(*args, params=FiberParams(**params), **kwargs)
self.type_variety = self.params.type_variety
self.length = self.params.length * UNITS[self.params.length_units] # in m
self.loss_coef = self.params.loss_coef * 1e-3 # lineic loss dB/m
self.lin_loss_coef = self.params.loss_coef / (20 * log10(exp(1)))
self.connector_loss_in = self.params.connector_loss_in
self.connector_loss_out = self.params.connector_loss_out
self.dispersion = self.params.dispersion # s/m/m
self.gamma = self.params.gamma # 1/W/m
# TODO|jla: discuss factor 2 in the linear lineic attenuation
@@ -166,12 +172,13 @@ class Fiber(Node):
return '\n'.join([f'{type(self).__name__} {self.uid}',
f' type_variety: {self.type_variety}',
f' length (m): {self.length:.2f}',
f' loss (dB): {self.loss:.2f}'])
f' loss (dB): {self.loss:.2f}',
f' (includes conn loss (dB) in: {self.connector_loss_in:.2f} out: {self.connector_loss_out:.2f})'])
@property
def loss(self):
# dB loss: useful for polymorphism (roadm, fiber, att)
return self.loss_coef * self.length
return self.loss_coef * self.length + self.connector_loss_in + self.connector_loss_out
@property
def passive(self):
@@ -251,12 +258,29 @@ class Fiber(Node):
return carrier_nli
def propagate(self, *carriers):
# apply connector_att_in on all carriers before computing gn analytics premiere partie pas bonne
attenuation = db2lin(self.connector_loss_in)
chan = []
for carrier in carriers:
pwr = carrier.power
pwr = pwr._replace(signal=pwr.signal/attenuation,
nonlinear_interference=pwr.nli/attenuation,
amplified_spontaneous_emission=pwr.ase/attenuation)
carrier = carrier._replace(power=pwr)
chan.append(carrier)
carriers = tuple(f for f in chan)
# propagate in the fiber and apply attenuation out
attenuation = db2lin(self.connector_loss_out)
for carrier in carriers:
pwr = carrier.power
carrier_nli = self._gn_analytic(carrier, *carriers)
pwr = pwr._replace(signal=pwr.signal/self.lin_attenuation,
nonlinear_interference=(pwr.nli+carrier_nli)/self.lin_attenuation,
amplified_spontaneous_emission=pwr.ase/self.lin_attenuation)
pwr = pwr._replace(signal=pwr.signal/self.lin_attenuation/attenuation,
nonlinear_interference=(pwr.nli+carrier_nli)/self.lin_attenuation/attenuation,
amplified_spontaneous_emission=pwr.ase/self.lin_attenuation/attenuation)
yield carrier._replace(power=pwr)
def __call__(self, spectral_info):

View File

@@ -11,6 +11,8 @@ This module contains classes for modelling SpectralInformation.
from collections import namedtuple
from numpy import array
from gnpy.core.utils import lin2db
from json import loads
from gnpy.core.utils import load_json
class ConvenienceAccess:

183
gnpy/core/request.py Normal file
View File

@@ -0,0 +1,183 @@
#!/usr/bin/env python3
# TelecomInfraProject/gnpy/examples
# Module name : path_requests_run.py
# Version :
# License : BSD 3-Clause Licence
# Copyright (c) 2018, Telecom Infra Project
"""
@author: esther.lerouzic
@author: jeanluc-auge
read json request file in accordance with:
Yang model for requesting Path Computation
draft-ietf-teas-yang-path-computation-01.txt.
and returns path results in terms of path and feasibility
"""
from sys import exit
from argparse import ArgumentParser
from pathlib import Path
from collections import namedtuple
from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO
from json import dumps, loads
from networkx import (draw_networkx_nodes, draw_networkx_edges,
draw_networkx_labels, dijkstra_path, NetworkXNoPath)
from numpy import mean
from examples.convert_service_sheet import convert_service_sheet, Request_element, Element
from gnpy.core.utils import load_json
from gnpy.core.network import load_network, build_network
from gnpy.core.equipment import load_equipment
from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power
from copy import copy, deepcopy
from numpy import log10
RequestParams = namedtuple('RequestParams','request_id source destination trx_type'+
' trx_mode nodes_list loose_list spacing power nb_channel frequency format baudrate OSNR bit_rate')
class Path_request:
def __init__(self, *args, **params):
params = RequestParams(**params)
self.request_id = params.request_id
self.source = params.source
self.destination = params.destination
self.tsp = params.trx_type
self.tsp_mode = params.trx_mode
self.baudrate = params.baudrate
self.nodes_list = params.nodes_list
self.loose_list = params.loose_list
self.spacing = params.spacing
self.power = params.power
self.nb_channel = params.nb_channel
self.frequency = params.frequency
self.format = params.format
self.OSNR = params.OSNR
self.bit_rate = params.bit_rate
def __str__(self):
return '\n\t'.join([ f'{type(self).__name__} {self.request_id}',
f'source: {self.source}',
f'destination: {self.destination}'])
def __repr__(self):
return '\n\t'.join([ f'{type(self).__name__} {self.request_id}',
f'source: {self.source}',
f'destination: {self.destination}',
f'trx type: {self.tsp}',
f'baudrate: {self.baudrate}',
f'spacing: {self.spacing}',
f'power: {self.power}'
'\n'])
class Result_element(Element):
def __init__(self,path_request,computed_path):
self.path_id = int(path_request.request_id)
self.path_request = path_request
self.computed_path = computed_path
hop_type = []
for e in computed_path :
if isinstance(e, Transceiver) :
hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode]))
else:
hop_type.append('not recorded')
self.hop_type = hop_type
uid = property(lambda self: repr(self))
@property
def pathresult(self):
return {
'path-id': self.path_id,
'path-properties':{
'path-metric': [
{
'metric-type': 'SNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].snr),2)
},
{
'metric-type': 'SNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].snr+10*log10(self.path_request.baudrate/12.5)),2)
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
},
'path-route-objects': [
{
'path-route-object': {
'index': self.computed_path.index(n),
'unnumbered-hop': {
'node-id': n.uid,
'link-tp-id': n.uid,
'hop-type': self.hop_type[self.computed_path.index(n)],
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
}
} for n in self.computed_path
]
}
}
@property
def json(self):
return self.pathresult
def compute_constrained_path(network, req):
trx = [n for n in network.nodes() if isinstance(n, Transceiver)]
roadm = [n for n in network.nodes() if isinstance(n, Roadm)]
edfa = [n for n in network.nodes() if isinstance(n, Edfa)]
source = next(el for el in trx if el.uid == req.source)
# start the path with its source
total_path = [source]
for n in req.nodes_list:
# print(n)
try :
node = next(el for el in trx if el.uid == n)
except StopIteration:
try:
node = next(el for el in roadm if el.uid == f'roadm {n}')
except StopIteration:
try:
node = next(el for el in edfa
if el.uid.startswith(f'egress edfa in {n}'))
except StopIteration:
msg = f'could not find node : {n} in network topology: \
not a trx, roadm, edfa or fused element'
logger.critical(msg)
raise ValueError(msg)
# extend path list without repeating source -> skip first element in the list
try:
total_path.extend(dijkstra_path(network, source, node)[1:])
source = node
except NetworkXNoPath:
# for debug
# print(req.loose_list)
# print(req.nodes_list.index(n))
if req.loose_list[req.nodes_list.index(n)] == 'loose':
print(f'could not find a path from {source.uid} to loose node : {n} in network topology')
print(f'node {n} is skipped')
else:
msg = f'could not find a path from {source.uid} to node : {n} in network topology'
logger.critical(msg)
raise ValueError(msg)
return total_path
def propagate(path,req,equipment, show=False):
default_si_data = equipment['SI']['default']
si = create_input_spectral_information(
req.frequency['min'], default_si_data.roll_off,
req.baudrate, req.power, req.spacing, req.nb_channel)
for el in path:
si = el(si)
if show :
print(el)
return path

261
tests/LinkforTest.json Normal file
View File

@@ -0,0 +1,261 @@
{
"elements": [
{
"uid": "trx A",
"metadata": {
"location": {
"city": "A",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx B",
"metadata": {
"location": {
"city": "B",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx F",
"metadata": {
"location": {
"city": "F",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "fiber (A \u2192 B)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"connector_loss_in": 1.00,
"connector_loss_out": 1.00
}
},
{
"uid": "fiber (B \u2192 C)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"connector_loss_in": 1.00,
"connector_loss_out": 1.00
}
},
{
"uid": "fiber (C \u2192 D)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"connector_loss_in": 1.00,
"connector_loss_out": 1.00
}
},
{
"uid": "fiber (D \u2192 E)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"connector_loss_in": 1.00,
"connector_loss_out": 1.00
}
},
{
"uid": "fiber (E \u2192 F)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"connector_loss_in": 1.00,
"connector_loss_out": 1.00
}
},
{
"uid": "Edfa1",
"type": "Edfa",
"type_variety": "std_medium_gain",
"operational": {
"gain_target": 18,
"tilt_target": 0
},
"metadata": {
"location": {
"region": "",
"latitude": 2,
"longitude": 0
}
}
},
{
"uid": "Edfa2",
"type": "Edfa",
"type_variety": "std_medium_gain",
"operational": {
"gain_target": 18,
"tilt_target": 0
},
"metadata": {
"location": {
"region": "",
"latitude": 2,
"longitude": 0
}
}
},
{
"uid": "Edfa3",
"type": "Edfa",
"type_variety": "std_medium_gain",
"operational": {
"gain_target": 18,
"tilt_target": 0
},
"metadata": {
"location": {
"region": "",
"latitude": 2,
"longitude": 0
}
}
},
{
"uid": "Edfa4",
"type": "Edfa",
"type_variety": "std_medium_gain",
"operational": {
"gain_target": 18,
"tilt_target": 0
},
"metadata": {
"location": {
"region": "",
"latitude": 2,
"longitude": 0
}
}
},
{
"uid": "Edfa5",
"type": "Edfa",
"type_variety": "std_medium_gain",
"operational": {
"gain_target": 18,
"tilt_target": 0
},
"metadata": {
"location": {
"region": "",
"latitude": 2,
"longitude": 0
}
}
}
],
"connections": [
{
"from_node": "fiber (A \u2192 B)-",
"to_node": "Edfa1"
},
{
"from_node": "Edfa1",
"to_node": "fiber (B \u2192 C)-"
},
{
"from_node": "fiber (B \u2192 C)-",
"to_node": "Edfa2"
},
{
"from_node": "Edfa2",
"to_node": "fiber (C \u2192 D)-"
},
{
"from_node": "fiber (C \u2192 D)-",
"to_node": "Edfa3"
},
{
"from_node": "Edfa3",
"to_node": "fiber (D \u2192 E)-"
},
{
"from_node": "fiber (D \u2192 E)-",
"to_node": "Edfa4"
},
{
"from_node": "Edfa4",
"to_node": "fiber (E \u2192 F)-"
},
{
"from_node": "fiber (E \u2192 F)-",
"to_node": "Edfa5"
},
{
"from_node": "Edfa5",
"to_node": "trx F"
},
{
"from_node": "trx A",
"to_node": "fiber (A \u2192 B)-"
},
{
"from_node": "Edfa1",
"to_node": "trx B"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -181,7 +181,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -197,7 +199,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -213,7 +217,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -229,7 +235,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -245,7 +253,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -261,7 +271,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -277,7 +289,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -293,7 +307,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -309,7 +325,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -325,7 +343,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -341,7 +361,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -357,7 +379,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -373,7 +397,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -389,7 +415,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -405,7 +433,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -421,7 +451,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{

View File

@@ -253,7 +253,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -269,7 +271,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -285,7 +289,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -301,7 +307,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -317,7 +325,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -333,7 +343,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -349,7 +361,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -365,7 +379,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -381,7 +397,9 @@
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -397,7 +415,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -413,7 +433,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -429,7 +451,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -445,7 +469,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -461,7 +487,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -477,7 +505,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -493,7 +523,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -509,7 +541,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -525,7 +559,9 @@
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{

View File

@@ -253,7 +253,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -269,7 +271,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -285,7 +289,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -301,7 +307,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -317,7 +325,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -333,7 +343,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -349,7 +361,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -365,7 +379,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -381,7 +397,9 @@
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -397,7 +415,9 @@
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -413,7 +433,9 @@
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -429,7 +451,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -445,7 +469,9 @@
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -461,7 +487,9 @@
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -477,7 +505,9 @@
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -493,7 +523,9 @@
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -509,7 +541,9 @@
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
},
{
@@ -525,7 +559,9 @@
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2
"loss_coef": 0.2,
"connector_loss_in": 0.5,
"connector_loss_out": 0.5
}
}
],