Merge remote-tracking branch 'origin/develop'

This commit is contained in:
Jan Kundrát
2019-11-13 19:59:35 +01:00
17 changed files with 1607 additions and 735 deletions

1
.bandit Normal file
View File

@@ -0,0 +1 @@
skips: ['B101']

View File

@@ -2,8 +2,8 @@
"path-request": [ "path-request": [
{ {
"request-id": "0", "request-id": "0",
"source": "Lorient_KMA", "source": "trx Lorient_KMA",
"destination": "Vannes_KBE", "destination": "trx Vannes_KBE",
"src-tp-id": "trx Lorient_KMA", "src-tp-id": "trx Lorient_KMA",
"dst-tp-id": "trx Vannes_KBE", "dst-tp-id": "trx Vannes_KBE",
"path-constraints": { "path-constraints": {
@@ -13,8 +13,8 @@
"trx_mode": null, "trx_mode": null,
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -22,15 +22,12 @@
"output-power": 0.0012589254117941673, "output-power": 0.0012589254117941673,
"path_bandwidth": 100000000000.0 "path_bandwidth": 100000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "1", "request-id": "1",
"source": "Brest_KLA", "source": "trx Brest_KLA",
"destination": "Vannes_KBE", "destination": "trx Vannes_KBE",
"src-tp-id": "trx Brest_KLA", "src-tp-id": "trx Brest_KLA",
"dst-tp-id": "trx Vannes_KBE", "dst-tp-id": "trx Vannes_KBE",
"path-constraints": { "path-constraints": {
@@ -40,8 +37,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -50,66 +47,42 @@
"path_bandwidth": 200000000000.0 "path_bandwidth": 200000000000.0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Brest_KLA", "node-id": "roadm Brest_KLA",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 1, "index": 1,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Lannion_CAS", "node-id": "roadm Lannion_CAS",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 2, "index": 2,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Lorient_KMA", "node-id": "roadm Lorient_KMA",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 3, "index": 3,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Vannes_KBE", "node-id": "roadm Vannes_KBE",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -117,8 +90,8 @@
}, },
{ {
"request-id": "3", "request-id": "3",
"source": "Lannion_CAS", "source": "trx Lannion_CAS",
"destination": "Rennes_STA", "destination": "trx Rennes_STA",
"src-tp-id": "trx Lannion_CAS", "src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx Rennes_STA", "dst-tp-id": "trx Rennes_STA",
"path-constraints": { "path-constraints": {
@@ -128,8 +101,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -137,15 +110,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 60000000000.0 "path_bandwidth": 60000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "4", "request-id": "4",
"source": "Rennes_STA", "source": "trx Rennes_STA",
"destination": "Lannion_CAS", "destination": "trx Lannion_CAS",
"src-tp-id": "trx Rennes_STA", "src-tp-id": "trx Rennes_STA",
"dst-tp-id": "trx Lannion_CAS", "dst-tp-id": "trx Lannion_CAS",
"path-constraints": { "path-constraints": {
@@ -155,8 +125,8 @@
"trx_mode": null, "trx_mode": null,
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 75000000000.0, "spacing": 75000000000.0,
@@ -164,15 +134,12 @@
"output-power": 0.0019952623149688794, "output-power": 0.0019952623149688794,
"path_bandwidth": 150000000000.0 "path_bandwidth": 150000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "5", "request-id": "5",
"source": "Rennes_STA", "source": "trx Rennes_STA",
"destination": "Lannion_CAS", "destination": "trx Lannion_CAS",
"src-tp-id": "trx Rennes_STA", "src-tp-id": "trx Rennes_STA",
"dst-tp-id": "trx Lannion_CAS", "dst-tp-id": "trx Lannion_CAS",
"path-constraints": { "path-constraints": {
@@ -182,8 +149,8 @@
"trx_mode": "mode 2", "trx_mode": "mode 2",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 75000000000.0, "spacing": 75000000000.0,
@@ -191,15 +158,12 @@
"output-power": 0.0019952623149688794, "output-power": 0.0019952623149688794,
"path_bandwidth": 20000000000.0 "path_bandwidth": 20000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "6", "request-id": "6",
"source": "Lannion_CAS", "source": "trx Lannion_CAS",
"destination": "Lorient_KMA", "destination": "trx Lorient_KMA",
"src-tp-id": "trx Lannion_CAS", "src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx Lorient_KMA", "dst-tp-id": "trx Lorient_KMA",
"path-constraints": { "path-constraints": {
@@ -209,8 +173,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -218,15 +182,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "7", "request-id": "7",
"source": "Lannion_CAS", "source": "trx Lannion_CAS",
"destination": "Lorient_KMA", "destination": "trx Lorient_KMA",
"src-tp-id": "trx Lannion_CAS", "src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx Lorient_KMA", "dst-tp-id": "trx Lorient_KMA",
"path-constraints": { "path-constraints": {
@@ -236,8 +197,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -245,15 +206,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 400000000000.0 "path_bandwidth": 400000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "7b", "request-id": "7b",
"source": "Lannion_CAS", "source": "trx Lannion_CAS",
"destination": "Lorient_KMA", "destination": "trx Lorient_KMA",
"src-tp-id": "trx Lannion_CAS", "src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx Lorient_KMA", "dst-tp-id": "trx Lorient_KMA",
"path-constraints": { "path-constraints": {
@@ -263,8 +221,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 75000000000.0, "spacing": 75000000000.0,
@@ -272,9 +230,6 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 400000000000.0 "path_bandwidth": 400000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
} }
], ],
@@ -282,9 +237,8 @@
{ {
"synchronization-id": "3", "synchronization-id": "3",
"svec": { "svec": {
"relaxable": "False", "relaxable": "false",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"3", "3",
"1" "1"
@@ -294,9 +248,8 @@
{ {
"synchronization-id": "4", "synchronization-id": "4",
"svec": { "svec": {
"relaxable": "False", "relaxable": "false",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"4", "4",
"5" "5"

View File

@@ -55,16 +55,18 @@ def requests_from_json(json_data,equipment):
# init all params from request # init all params from request
params = {} params = {}
params['request_id'] = req['request-id'] params['request_id'] = req['request-id']
params['source'] = req['src-tp-id'] params['source'] = req['source']
params['destination'] = req['dst-tp-id'] params['destination'] = req['destination']
params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type'] params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode'] params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
params['format'] = params['trx_mode'] params['format'] = params['trx_mode']
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['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
try :
nd_list = req['explicit-route-objects']['route-object-include-exclude']
except KeyError:
nd_list = []
params['nodes_list'] = [n['num-unnum-hop']['node-id'] for n in nd_list]
params['loose_list'] = [n['num-unnum-hop']['hop-type'] for n in nd_list]
# recover trx physical param (baudrate, ...) from type and mode # recover trx physical param (baudrate, ...) from type and mode
# in trx_mode_params optical power is read from equipment['SI']['default'] and # in trx_mode_params optical power is read from equipment['SI']['default'] and
# nb_channel is computed based on min max frequency and spacing # nb_channel is computed based on min max frequency and spacing
@@ -73,20 +75,24 @@ def requests_from_json(json_data,equipment):
# print(trx_params['min_spacing']) # print(trx_params['min_spacing'])
# optical power might be set differently in the request. if it is indicated then the # optical power might be set differently in the request. if it is indicated then the
# params['power'] is updated # params['power'] is updated
if req['path-constraints']['te-bandwidth']['output-power']: try:
params['power'] = req['path-constraints']['te-bandwidth']['output-power'] if req['path-constraints']['te-bandwidth']['output-power']:
params['power'] = req['path-constraints']['te-bandwidth']['output-power']
except KeyError:
pass
# same process for nb-channel # same process for nb-channel
f_min = params['f_min'] f_min = params['f_min']
f_max_from_si = params['f_max'] f_max_from_si = params['f_max']
if req['path-constraints']['te-bandwidth']['max-nb-of-channel'] is not None : try:
nch = req['path-constraints']['te-bandwidth']['max-nb-of-channel'] if req['path-constraints']['te-bandwidth']['max-nb-of-channel'] is not None:
params['nb_channel'] = nch nch = req['path-constraints']['te-bandwidth']['max-nb-of-channel']
spacing = params['spacing'] params['nb_channel'] = nch
params['f_max'] = f_min + nch*spacing spacing = params['spacing']
else : params['f_max'] = f_min + nch*spacing
else :
params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing'])
except KeyError:
params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing']) params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing'])
consistency_check(params, f_max_from_si) consistency_check(params, f_max_from_si)
try : try :
@@ -122,15 +128,20 @@ def consistency_check(params, f_max_from_si):
def disjunctions_from_json(json_data): def disjunctions_from_json(json_data):
disjunctions_list = [] disjunctions_list = []
try:
temp_test = json_data['synchronization']
except KeyError:
temp_test = []
if temp_test:
for snc in json_data['synchronization']:
params = {}
params['disjunction_id'] = snc['synchronization-id']
params['relaxable'] = snc['svec']['relaxable']
params['link_diverse'] = 'link' in snc['svec']['disjointness']
params['node_diverse'] = 'node' in snc['svec']['disjointness']
params['disjunctions_req'] = snc['svec']['request-id-number']
disjunctions_list.append(Disjunction(**params))
for snc in json_data['synchronization']:
params = {}
params['disjunction_id'] = snc['synchronization-id']
params['relaxable'] = snc['svec']['relaxable']
params['link_diverse'] = snc['svec']['link-diverse']
params['node_diverse'] = snc['svec']['node-diverse']
params['disjunctions_req'] = snc['svec']['request-id-number']
disjunctions_list.append(Disjunction(**params))
return disjunctions_list return disjunctions_list
@@ -205,7 +216,7 @@ def correct_route_list(network, pathreqlist):
# prepares the format of route list of nodes to be consistant # prepares the format of route list of nodes to be consistant
# remove wrong names, remove endpoints # remove wrong names, remove endpoints
# also correct source and destination # also correct source and destination
anytype = [n.uid for n in network.nodes() if not isinstance(n, Transceiver) and not isinstance(n, Fiber)] anytype = [n.uid for n in network.nodes()]
# TODO there is a problem of identification of fibers in case of parallel fibers bitween two adjacent roadms # TODO there is a problem of identification of fibers in case of parallel fibers bitween two adjacent roadms
# so fiber constraint is not supported # so fiber constraint is not supported
transponders = [n.uid for n in network.nodes() if isinstance(n, Transceiver)] transponders = [n.uid for n in network.nodes() if isinstance(n, Transceiver)]
@@ -214,9 +225,11 @@ def correct_route_list(network, pathreqlist):
# replace possibly wrong name with a formated roadm name # replace possibly wrong name with a formated roadm name
# print(n_id) # print(n_id)
if n_id not in anytype : if n_id not in anytype :
# find nodes name that include constraint among all possible names except
# transponders (not yet supported as constraints).
nodes_suggestion = [uid for uid in anytype \ nodes_suggestion = [uid for uid in anytype \
if n_id.lower() in uid.lower()] if n_id.lower() in uid.lower() and uid not in transponders]
if pathreq.loose_list[i] == 'loose': if pathreq.loose_list[i] == 'LOOSE':
if len(nodes_suggestion)>0 : if len(nodes_suggestion)>0 :
new_n = nodes_suggestion[0] new_n = nodes_suggestion[0]
print(f'invalid route node specified:\ print(f'invalid route node specified:\
@@ -257,7 +270,7 @@ def correct_disjn(disjn):
def path_result_json(pathresult): def path_result_json(pathresult):
data = { data = {
'path': [n.json for n in pathresult] 'response': [n.json for n in pathresult]
} }
return data return data

View File

@@ -157,11 +157,13 @@ def main(network, equipment, source, destination, sim_params, req=None):
if len(power_range) == 1: if len(power_range) == 1:
for elem in path: for elem in path:
print(elem) print(elem)
if power_mode: if power_mode:
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f} dBm:') print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f} dBm:')
else:
print(f'\nTransmission results:')
print(f' Final SNR total (0.1 nm): {ansi_escapes.cyan}{mean(destination.snr_01nm):.02f} dB{ansi_escapes.reset}')
else: else:
print(f'\nTransmission results:') print(path[-1])
print(f' Final SNR total (signal bw): {ansi_escapes.cyan}{mean(destination.snr):.02f} dB{ansi_escapes.reset}')
#print(f'\n !!!!!!!!!!!!!!!!! TEST POINT !!!!!!!!!!!!!!!!!!!!!') #print(f'\n !!!!!!!!!!!!!!!!! TEST POINT !!!!!!!!!!!!!!!!!!!!!')
#print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}') #print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}')

View File

@@ -25,7 +25,7 @@ from collections import namedtuple
from gnpy.core.node import Node from gnpy.core.node import Node
from gnpy.core.units import UNITS from gnpy.core.units import UNITS
from gnpy.core.utils import lin2db, db2lin, itufs, itufl, snr_sum from gnpy.core.utils import lin2db, db2lin, arrange_frequencies, snr_sum
from gnpy.core.science_utils import propagate_raman_fiber, _psi from gnpy.core.science_utils import propagate_raman_fiber, _psi
class Transceiver(Node): class Transceiver(Node):
@@ -615,7 +615,7 @@ class Edfa(Node):
self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple
""" """
# TODO|jla: read amplifier actual frequencies from additional params in json # TODO|jla: read amplifier actual frequencies from additional params in json
amplifier_freq = itufl(len(self.params.dgt), self.params.f_min, self.params.f_max) # Hz amplifier_freq = arrange_frequencies(len(self.params.dgt), self.params.f_min, self.params.f_max) # Hz
self.channel_freq = frequencies self.channel_freq = frequencies
self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt) self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt)

View File

@@ -81,9 +81,9 @@ class Path_request:
f'baud_rate:\t{temp} Gbaud', f'baud_rate:\t{temp} Gbaud',
f'bit_rate:\t{temp2} Gb/s', f'bit_rate:\t{temp2} Gb/s',
f'spacing:\t{self.spacing * 1e-9} GHz', f'spacing:\t{self.spacing * 1e-9} GHz',
f'power: \t{round(lin2db(self.power)+30,2)} dBm', f'power: \t{round(lin2db(self.power)+30, 2)} dBm',
f'nb channels: \t{self.nb_channel}', f'nb channels: \t{self.nb_channel}',
f'path_bandwidth: \t{round(self.path_bandwidth * 1e-9,2)} Gbit/s', f'path_bandwidth: \t{round(self.path_bandwidth * 1e-9, 2)} Gbit/s',
f'nodes-list:\t{self.nodes_list}', f'nodes-list:\t{self.nodes_list}',
f'loose-list:\t{self.loose_list}' f'loose-list:\t{self.loose_list}'
'\n']) '\n'])
@@ -97,16 +97,16 @@ class Disjunction:
self.disjunctions_req = params.disjunctions_req self.disjunctions_req = params.disjunctions_req
def __str__(self): def __str__(self):
return '\n\t'.join([f'relaxable: {self.relaxable}', return '\n\t'.join([f'relaxable: {self.relaxable}',
f'link-diverse: {self.link_diverse}', f'link-diverse: {self.link_diverse}',
f'node-diverse: {self.node_diverse}', f'node-diverse: {self.node_diverse}',
f'request-id-numbers: {self.disjunctions_req}'] f'request-id-numbers: {self.disjunctions_req}']
) )
def __repr__(self): def __repr__(self):
return '\n\t'.join([ f'{type(self).__name__} {self.disjunction_id}', return '\n\t'.join([ f'{type(self).__name__} {self.disjunction_id}',
f'relaxable: {self.relaxable}', f'relaxable: {self.relaxable}',
f'link-diverse: {self.link_diverse}', f'link-diverse: {self.link_diverse}',
f'node-diverse: {self.node_diverse}', f'node-diverse: {self.node_diverse}',
f'request-id-numbers: {self.disjunctions_req}' f'request-id-numbers: {self.disjunctions_req}'
'\n']) '\n'])
@@ -115,149 +115,77 @@ class Result_element(Element):
self.path_id = path_request.request_id self.path_id = path_request.request_id
self.path_request = path_request self.path_request = path_request
self.computed_path = computed_path self.computed_path = computed_path
hop_type = []
if len(computed_path)>0 :
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')
else:
# TODO differentiate empty path in case not feasible because of tsp or not feasible because
# ther is no path connecting the nodes (whatever the tsp)
mode = 'not feasible with this transponder'
hop_type = ' - '.join([path_request.tsp,mode])
self.hop_type = hop_type
uid = property(lambda self: repr(self)) uid = property(lambda self: repr(self))
@property @property
def pathresult(self): def pathresult(self):
if not self.computed_path: if not self.computed_path:
return { return {
'path-id': self.path_id, 'response-id': self.path_id,
'path-properties':{ 'no-path': "Response without path information, due to failure performing the path computation"
'path-metric': [ }
{ else:
'metric-type': 'SNR@bandwidth', index = 0
'accumulative-value': 'None' pro_list = []
}, for element in self.computed_path:
{ temp = {
'metric-type': 'SNR@0.1nm', 'path-route-object': {
'accumulative-value': 'None' 'index': index,
}, 'num-unnum-hop': {
{ 'node-id': element.uid,
'metric-type': 'OSNR@bandwidth', 'link-tp-id': element.uid,
'accumulative-value': 'None' # TODO change index in order to insert transponder attribute
}, }
{ }
'metric-type': 'OSNR@0.1nm', }
'accumulative-value': 'None' pro_list.append(temp)
}, index += 1
{ if isinstance(element, Transceiver):
'metric-type': 'reference_power', temp = {
'accumulative-value': self.path_request.power 'path-route-object': {
}, 'index': index,
{ 'transponder' : {
'metric-type': 'path_bandwidth', 'transponder-type' : self.path_request.tsp,
'accumulative-value': self.path_request.path_bandwidth 'transponder-mode' : self.path_request.tsp_mode,
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
},
'path-route-objects': [
{
'path-route-object': {
'index': 0,
'unnumbered-hop': {
'node-id': self.path_request.source,
'link-tp-id': self.path_request.source,
'hop-type': self.hop_type,
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
}
},
{
'path-route-object': {
'index': 1,
'unnumbered-hop': {
'node-id': self.path_request.destination,
'link-tp-id': self.path_request.destination,
'hop-type': self.hop_type,
'direction': 'not used'
},
'label-hop': {
'te-label': {
'generic': 'not used yet',
'direction': 'not used yet'
}
}
} }
} }
] }
} pro_list.append(temp)
} index += 1
else:
return { response = {
'path-id': self.path_id, 'response-id': self.path_id,
'path-properties':{ 'path-properties':{
'path-metric': [ 'path-metric': [
{ {
'metric-type': 'SNR@bandwidth', 'metric-type': 'SNR-bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].snr),2) 'accumulative-value': round(mean(self.computed_path[-1].snr), 2)
},
{
'metric-type': 'SNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].snr+lin2db(self.path_request.baud_rate/12.5e9)),2)
},
{
'metric-type': 'OSNR@bandwidth',
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase),2)
},
{
'metric-type': 'OSNR@0.1nm',
'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm),2)
},
{
'metric-type': 'reference_power',
'accumulative-value': self.path_request.power
},
{
'metric-type': 'path_bandwidth',
'accumulative-value': self.path_request.path_bandwidth
}
],
'path-srlgs': {
'usage': 'not used yet',
'values': 'not used yet'
}, },
'path-route-objects': [ {
{ 'metric-type': 'SNR-0.1nm',
'path-route-object': { 'accumulative-value': round(mean(self.computed_path[-1]. snr + \
'index': self.computed_path.index(n), lin2db(self.path_request.baud_rate/12.5e9)), 2)
'unnumbered-hop': { },
'node-id': n.uid, {
'link-tp-id': n.uid, 'metric-type': 'OSNR-bandwidth',
'hop-type': self.hop_type[self.computed_path.index(n)], 'accumulative-value': round(mean(self.computed_path[-1].osnr_ase), 2)
'direction': 'not used' },
}, {
'label-hop': { 'metric-type': 'OSNR-0.1nm',
'te-label': { 'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm), 2)
'generic': 'not used yet', },
'direction': 'not used yet' {
} 'metric-type': 'reference_power',
} 'accumulative-value': self.path_request.power
} },
} for n in self.computed_path {
] 'metric-type': 'path_bandwidth',
'accumulative-value': self.path_request.path_bandwidth
}
],
'path-route-objects': pro_list
} }
} }
return response
@property @property
def json(self): def json(self):
@@ -304,7 +232,7 @@ def compute_constrained_path(network, req):
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path from {source.uid} to node : {destination.uid} in network topology'+ '\x1b[0m' msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path from {source.uid} to node : {destination.uid} in network topology'+ '\x1b[0m'
logger.critical(msg) logger.critical(msg)
print(msg) print(msg)
total_path = [] total_path = []
else : else :
all_simp_pths = list(all_simple_paths(network,source=source,\ all_simp_pths = list(all_simple_paths(network,source=source,\
target=destination, cutoff=120)) target=destination, cutoff=120))
@@ -319,12 +247,26 @@ def compute_constrained_path(network, req):
candidate.sort(key=lambda x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2))) candidate.sort(key=lambda x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2)))
total_path = candidate[0] total_path = candidate[0]
else: else:
if req.loose_list[req.nodes_list.index(n)] == 'loose': # TODO: better account for individual loose and strict node
print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list} in network topology'+ '\x1b[0m') # to ease: suppose that one strict makes the whole liste strict (except for the
# last node which is the transceiver)
# if all nodes i n node_list are LOOSE constraint, skip the constraints and find
# a path w/o constraints, else there is no possible path
if nodes_list[:-len("STRICT")]:
print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing ' +\
f'{[el.uid for el in nodes_list[:-len("STRICT")]]} in network topology'+ '\x1b[0m')
else:
print(f'\x1b[1;33;40m'+f'User include_node constraints could not be applied ' +\
f'(invalid names specified)'+ '\x1b[0m')
if 'STRICT' not in req.loose_list[:-len('STRICT')]:
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path with user_' +\
f'include node constraints' + '\x1b[0m'
logger.info(msg)
print(f'constraint ignored') print(f'constraint ignored')
total_path = dijkstra_path(network, source, destination, weight = 'weight') total_path = dijkstra_path(network, source, destination, weight = 'weight')
else: else:
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list}.\nNo path computed'+ '\x1b[0m' msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path with user ' +\
f'include node constraints.\nNo path computed'+ '\x1b[0m'
logger.critical(msg) logger.critical(msg)
print(msg) print(msg)
total_path = [] total_path = []
@@ -418,7 +360,7 @@ def propagate_and_optimize_mode(path, req, equipment):
# if mode is unknown : loops on the modes starting from the highest baudrate fiting in the # if mode is unknown : loops on the modes starting from the highest baudrate fiting in the
# step 1: create an ordered list of modes based on baudrate # step 1: create an ordered list of modes based on baudrate
baudrate_to_explore = list(set([m['baud_rate'] for m in equipment['Transceiver'][req.tsp].mode baudrate_to_explore = list(set([m['baud_rate'] for m in equipment['Transceiver'][req.tsp].mode
if float(m['min_spacing'])<= req.spacing])) if float(m['min_spacing'])<= req.spacing]))
# TODO be carefull on limits cases if spacing very close to req spacing eg 50.001 50.000 # TODO be carefull on limits cases if spacing very close to req spacing eg 50.001 50.000
baudrate_to_explore = sorted(baudrate_to_explore, reverse=True) baudrate_to_explore = sorted(baudrate_to_explore, reverse=True)
if baudrate_to_explore : if baudrate_to_explore :
@@ -468,65 +410,91 @@ def jsontocsv(json_data,equipment,fileout):
# and write results in an CSV file # and write results in an CSV file
mywriter = writer(fileout) mywriter = writer(fileout)
mywriter.writerow(('path-id','source','destination','path_bandwidth','Pass?',\ mywriter.writerow(('response-id','source','destination','path_bandwidth','Pass?',\
'nb of tsp pairs','total cost','transponder-type','transponder-mode',\ 'nb of tsp pairs','total cost','transponder-type','transponder-mode',\
'OSNR@0.1nm','SNR@0.1nm','SNR@bandwidth','baud rate (Gbaud)',\ 'OSNR-0.1nm','SNR-0.1nm','SNR-bandwidth','baud rate (Gbaud)',\
'input power (dBm)','path')) 'input power (dBm)','path'))
tspjsondata = equipment['Transceiver'] tspjsondata = equipment['Transceiver']
#print(tspjsondata) #print(tspjsondata)
for p in json_data['path']:
path_id = p['path-id']
source = p['path-properties']['path-route-objects'][0]\
['path-route-object']['unnumbered-hop']['node-id']
destination = p['path-properties']['path-route-objects'][-1]\
['path-route-object']['unnumbered-hop']['node-id']
# selects only roadm nodes
pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id']
for e in p['path-properties']['path-route-objects']
if e['path-route-object']['unnumbered-hop']['node-id'].startswith('roadm') or e['path-route-object']['unnumbered-hop']['node-id'].startswith('Edfa')])
[tsp,mode] = p['path-properties']['path-route-objects'][0]\ for pth_el in json_data['response']:
['path-route-object']['unnumbered-hop']['hop-type'].split(' - ') path_id = pth_el['response-id']
try:
if pth_el['no-path'] :
source = ''
destination = ''
tsp = ''
mode = ''
isok = False
nb_tsp = 0
pthbdbw = ''
rosnr = ''
rsnr = ''
rsnrb = ''
br = ''
pw = ''
total_cost = ''
pth = ''
except KeyError:
source = pth_el['path-properties']['path-route-objects'][0]\
['path-route-object']['num-unnum-hop']['node-id']
destination = pth_el['path-properties']['path-route-objects'][-2]\
['path-route-object']['num-unnum-hop']['node-id']
# selects only roadm nodes
temp = []
for e in pth_el['path-properties']['path-route-objects']:
try :
temp.append(e['path-route-object']['num-unnum-hop']['node-id'])
except KeyError:
pass
pth = ' | '.join(temp)
temp_tsp = pth_el['path-properties']['path-route-objects'][1]\
['path-route-object']['transponder']
tsp = temp_tsp['transponder-type']
mode = temp_tsp['transponder-mode']
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
# loading equipment already tests the existence of tsp type and mode:
if mode !='not feasible with this transponder' :
[minosnr, baud_rate, bit_rate, cost] = next([m['OSNR'] , m['baud_rate'] , m['bit_rate'], m['cost']]
for m in equipment['Transceiver'][tsp].mode if m['format']==mode)
# else:
# [minosnr, baud_rate, bit_rate] = ['','','','']
output_snr = next(e['accumulative-value']
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'SNR-0.1nm')
output_snrbandwidth = next(e['accumulative-value']
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'SNR-bandwidth')
output_osnr = next(e['accumulative-value']
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'OSNR-0.1nm')
output_osnrbandwidth = next(e['accumulative-value']
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'OSNR-bandwidth')
power = next(e['accumulative-value']
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
path_bandwidth = next(e['accumulative-value']
for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'path_bandwidth')
if isinstance(output_snr, str):
isok = False
nb_tsp = 0
pthbdbw = round(path_bandwidth*1e-9,2)
rosnr = ''
rsnr = ''
rsnrb = ''
br = ''
pw = ''
total_cost = ''
else:
isok = output_snr >= minosnr
nb_tsp = ceil(path_bandwidth / bit_rate)
pthbdbw = round(path_bandwidth*1e-9,2)
rosnr = round(output_osnr,2)
rsnr = round(output_snr,2)
rsnrb = round(output_snrbandwidth,2)
br = round(baud_rate*1e-9,2)
pw = round(lin2db(power)+30,2)
total_cost = nb_tsp * cost
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
# loading equipment already tests the existence of tsp type and mode:
if mode !='not feasible with this transponder' :
[minosnr, baud_rate, bit_rate, cost] = next([m['OSNR'] , m['baud_rate'] , m['bit_rate'], m['cost']]
for m in equipment['Transceiver'][tsp].mode if m['format']==mode)
# else:
# [minosnr, baud_rate, bit_rate] = ['','','','']
output_snr = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@0.1nm')
output_snrbandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@bandwidth')
output_osnr = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@0.1nm')
output_osnrbandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@bandwidth')
power = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
path_bandwidth = next(e['accumulative-value']
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'path_bandwidth')
if isinstance(output_snr, str):
isok = False
nb_tsp = 0
pthbdbw = round(path_bandwidth*1e-9,2)
rosnr = ''
rsnr = ''
rsnrb = ''
br = ''
pw = ''
total_cost = ''
else:
isok = output_snr >= minosnr
nb_tsp = ceil(path_bandwidth / bit_rate)
pthbdbw = round(path_bandwidth*1e-9,2)
rosnr = round(output_osnr,2)
rsnr = round(output_snr,2)
rsnrb = round(output_snrbandwidth,2)
br = round(baud_rate*1e-9,2)
pw = round(lin2db(power)+30,2)
total_cost = nb_tsp * cost
mywriter.writerow((path_id, mywriter.writerow((path_id,
source, source,
destination, destination,
@@ -617,7 +585,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
all_simp_pths_reversed = [] all_simp_pths_reversed = []
for pth in all_simp_pths: for pth in all_simp_pths:
all_simp_pths_reversed.append(find_reversed_path(pth,network)) all_simp_pths_reversed.append(find_reversed_path(pth,network))
rqs[pathreq.request_id] = all_simp_pths rqs[pathreq.request_id] = all_simp_pths
temp =[] temp =[]
for p in all_simp_pths : for p in all_simp_pths :
# build a short list representing each roadm+direction with the first item # build a short list representing each roadm+direction with the first item
@@ -759,9 +727,10 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
testispartok = False testispartok = False
#break #break
else: else:
if 'loose' in allpaths[id(p)].req.loose_list: if 'LOOSE' in allpaths[id(p)].req.loose_list:
logger.info(f'Could not apply route constraint'+ logger.info(f'Could not apply route constraint'+
f'{allpaths[id(p)].req.nodes_list} on request {allpaths[id(p)].req.request_id}') f'{allpaths[id(p)].req.nodes_list} on request' +\
f' {allpaths[id(p)].req.request_id}')
else : else :
logger.info(f'removing last solution from candidate paths\n{sol}') logger.info(f'removing last solution from candidate paths\n{sol}')
testispartok = False testispartok = False
@@ -798,7 +767,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
for req in pathreqlist : for req in pathreqlist :
req.nodes_list.append(req.destination) req.nodes_list.append(req.destination)
# we assume that the destination is a strict constraint # we assume that the destination is a strict constraint
req.loose_list.append('strict') req.loose_list.append('STRICT')
if req in pathreqlist_simple: if req in pathreqlist_simple:
path_res_list.append(compute_constrained_path(network, req)) path_res_list.append(compute_constrained_path(network, req))
else: else:
@@ -890,19 +859,19 @@ def compare_reqs(req1,req2,disjlist) :
req1.format == req2.format and \ req1.format == req2.format and \
req1.OSNR == req2.OSNR and \ req1.OSNR == req2.OSNR and \
req1.roll_off == req2.roll_off and \ req1.roll_off == req2.roll_off and \
same_disj : same_disj:
return True return True
else: else:
return False return False
def requests_aggregation(pathreqlist,disjlist) : def requests_aggregation(pathreqlist,disjlist):
# this function aggregates requests so that if several requests # this function aggregates requests so that if several requests
# exist between same source and destination and with same transponder type # exist between same source and destination and with same transponder type
# todo maybe add conditions on mode ??, spacing ... # todo maybe add conditions on mode ??, spacing ...
# currently if undefined takes the default values # currently if undefined takes the default values
local_list = pathreqlist.copy() local_list = pathreqlist.copy()
for req in pathreqlist: for req in pathreqlist:
for r in local_list : for r in local_list:
if req.request_id != r.request_id and compare_reqs(req, r, disjlist): if req.request_id != r.request_id and compare_reqs(req, r, disjlist):
# aggregate # aggregate
r.path_bandwidth += req.path_bandwidth r.path_bandwidth += req.path_bandwidth
@@ -912,12 +881,12 @@ def requests_aggregation(pathreqlist,disjlist) :
local_list.remove(req) local_list.remove(req)
# todo change also disjunction req with new demand # todo change also disjunction req with new demand
for d in disjlist : for d in disjlist:
if req.request_id in d.disjunctions_req : if req.request_id in d.disjunctions_req:
d.disjunctions_req.remove(req.request_id) d.disjunctions_req.remove(req.request_id)
d.disjunctions_req.append(r.request_id) d.disjunctions_req.append(r.request_id)
for d in disjlist : for d in disjlist:
if temp_r_id in d.disjunctions_req : if temp_r_id in d.disjunctions_req:
disjlist.remove(d) disjlist.remove(d)
break break
return local_list, disjlist return local_list, disjlist

View File

@@ -48,8 +48,8 @@ class Request_element(Element):
# excel has automatic number formatting that adds .0 on integer values # excel has automatic number formatting that adds .0 on integer values
# the next lines recover the pure int value, assuming this .0 is unwanted # the next lines recover the pure int value, assuming this .0 is unwanted
self.request_id = correct_xlrd_int_to_str_reading(Request.request_id) self.request_id = correct_xlrd_int_to_str_reading(Request.request_id)
self.source = Request.source self.source = f'trx {Request.source}'
self.destination = Request.destination self.destination = f'trx {Request.destination}'
# TODO: the automatic naming generated by excel parser requires that source and dest name # TODO: the automatic naming generated by excel parser requires that source and dest name
# be a string starting with 'trx' : this is manually added here. # be a string starting with 'trx' : this is manually added here.
self.srctpid = f'trx {Request.source}' self.srctpid = f'trx {Request.source}'
@@ -120,9 +120,9 @@ class Request_element(Element):
# the excel parser applies the same hop-type to all nodes in the route nodes_list. # the excel parser applies the same hop-type to all nodes in the route nodes_list.
# user can change this per node in the generated json # user can change this per node in the generated json
self.loose = 'loose' self.loose = 'LOOSE'
if Request.is_loose == 'no' : if Request.is_loose == 'no' :
self.loose = 'strict' self.loose = 'STRICT'
self.path_bandwidth = None self.path_bandwidth = None
if Request.path_bandwidth is not None: if Request.path_bandwidth is not None:
self.path_bandwidth = Request.path_bandwidth * 1e9 self.path_bandwidth = Request.path_bandwidth * 1e9
@@ -132,6 +132,7 @@ class Request_element(Element):
uid = property(lambda self: repr(self)) uid = property(lambda self: repr(self))
@property @property
def pathrequest(self): def pathrequest(self):
req_dictionnary = { req_dictionnary = {
'request-id':self.request_id, 'request-id':self.request_id,
'source': self.source, 'source': self.source,
@@ -143,35 +144,28 @@ class Request_element(Element):
'technology': 'flexi-grid', 'technology': 'flexi-grid',
'trx_type' : self.trx_type, 'trx_type' : self.trx_type,
'trx_mode' : self.mode, 'trx_mode' : self.mode,
'effective-freq-slot':[{'n': 'null','m': 'null'}] , 'effective-freq-slot':[{'N': 'null', 'M': 'null'}],
'spacing' : self.spacing, 'spacing' : self.spacing,
'max-nb-of-channel' : self.nb_channel, 'max-nb-of-channel' : self.nb_channel,
'output-power' : self.power 'output-power' : self.power
# 'path_bandwidth' : self.path_bandwidth
} }
}, }
'optimizations': { }
'explicit-route-include-objects': [
{ if self.nodes_list:
'index': self.nodes_list.index(node), req_dictionnary['explicit-route-objects'] = {}
'unnumbered-hop':{ temp = {'route-object-include-exclude' : [
'node-id': f'{node}', {'explicit-route-usage': 'route-include-ero',
'link-tp-id': 'link-tp-id is not used', 'index': self.nodes_list.index(node),
'hop-type': f'{self.loose}', 'num-unnum-hop': {
'direction': 'direction is not used' 'node-id': f'{node}',
}, 'link-tp-id': 'link-tp-id is not used',
'label-hop':{ 'hop-type': f'{self.loose}',
'te-label': {
'generic': 'generic is not used',
'direction': 'direction is not used'
}
} }
} }
for node in self.nodes_list for node in self.nodes_list]
] }
req_dictionnary['explicit-route-objects'] = temp
}
}
if self.path_bandwidth is not None: if self.path_bandwidth is not None:
req_dictionnary['path-constraints']['te-bandwidth']['path_bandwidth'] = self.path_bandwidth req_dictionnary['path-constraints']['te-bandwidth']['path_bandwidth'] = self.path_bandwidth
@@ -181,12 +175,13 @@ class Request_element(Element):
if self.disjoint_from : if self.disjoint_from :
return {'synchronization-id':self.request_id, return {'synchronization-id':self.request_id,
'svec': { 'svec': {
'relaxable' : 'False', 'relaxable' : 'false',
'link-diverse': 'True', 'disjointness': 'node link',
'node-diverse': 'True',
'request-id-number': [self.request_id]+ [n for n in self.disjoint_from] 'request-id-number': [self.request_id]+ [n for n in self.disjoint_from]
} }
} }
else:
return None
# TO-DO: avoid multiple entries with same synchronisation vectors # TO-DO: avoid multiple entries with same synchronisation vectors
@property @property
def json(self): def json(self):
@@ -201,11 +196,17 @@ def convert_service_sheet(input_filename, eqpt_filename, output_filename='', fil
output_filename = f'{str(input_filename)[0:len(str(input_filename))-len(str(input_filename.suffixes[0]))]}_services.json' output_filename = f'{str(input_filename)[0:len(str(input_filename))-len(str(input_filename.suffixes[0]))]}_services.json'
# for debug # for debug
# print(json_filename) # print(json_filename)
data = { # if there is no sync vector , do not write any synchronization
'path-request': [n.json[0] for n in req], synchro = [n.json[1] for n in req if n.json[1] is not None]
'synchronization': [n.json[1] for n in req if synchro:
if n.json[1] is not None] data = {
} 'path-request': [n.json[0] for n in req],
'synchronization': synchro
}
else:
data = {
'path-request': [n.json[0] for n in req]
}
with open(output_filename, 'w', encoding='utf-8') as f: with open(output_filename, 'w', encoding='utf-8') as f:
f.write(dumps(data, indent=2, ensure_ascii=False)) f.write(dumps(data, indent=2, ensure_ascii=False))
return data return data

View File

@@ -73,35 +73,19 @@ def c():
return constants.c return constants.c
def itufs(spacing, startf=191.35, stopf=196.10): def arrange_frequencies(length, start, stop):
"""Creates an array of frequencies whose default range is """Create an array of frequencies
191.35-196.10 THz
:param spacing: Frequency spacing in THz
:param starf: Start frequency in THz
:param stopf: Stop frequency in THz
:type spacing: float
:type startf: float
:type stopf: float
:return an array of frequnecies determined by the spacing parameter
:rtype: numpy.ndarray
"""
return np.arange(startf, stopf + spacing / 2, spacing)
def itufl(length, startf=191.35, stopf=196.10):
"""Creates an array of frequencies whose default range is
191.35-196.10 THz
:param length: number of elements :param length: number of elements
:param starf: Start frequency in THz :param star: Start frequency in THz
:param stopf: Stop frequency in THz :param stop: Stop frequency in THz
:type length: integer :type length: integer
:type startf: float :type start: float
:type stopf: float :type stop: float
:return an array of frequnecies determined by the spacing parameter :return an array of frequencies determined by the spacing parameter
:rtype: numpy.ndarray :rtype: numpy.ndarray
""" """
return np.linspace(startf, stopf, length) return np.linspace(start, stop, length)
def h(): def h():
""" """

View File

@@ -1,39 +1,63 @@
{ {
"paths": [ "response": [
{ {
"path": { "response-id": null,
"path-id": null, "path-properties": {
"path-properties": { "path-metric": [
"path-metric": [ {
{ "metric-type": "SNR@bandwidth",
"metric-type": null, "accumulative-value": null
"accumulative-value": null
}
],
"path-srlgs": {
"usage": "not used yet",
"values": ["not used yet"]
}, },
"path-route-objects": [ {
{ "metric-type": "SNR@0.1nm",
"path-route-object": { "accumulative-value": null
"index": null, },
"unnumbered-hop": { {
"node-id": null, "metric-type": "OSNR@bandwidth",
"link-tp-id": null, "accumulative-value": null
"hop-type": null, },
"direction": "not used" {
}, "metric-type": "OSNR@0.1nm",
"label-hop": { "accumulative-value": null
"te-label": { },
"generic": "not used yet", {
"direction": "not used yet" "metric-type": "reference_power",
} "accumulative-value": null
} },
{
"metric-type": "path_bandwidth",
"accumulative-value": null
}
],
"path-route-objects": [
{
"path-route-object": {
"index": 0,
"num-unnum-hop": {
"node-id": null,
"link-tp-id": null
} }
} }
] },
} {
"path-route-object": {
"index": 1,
"transponder": {
"transponder-type": null,
"transponder-mode": null
}
}
},
{
"path-route-object": {
"index": 2,
"num-unnum-hop": {
"node-id": null,
"link-tp-id": null
}
}
}
]
} }
} }
] ]

View File

@@ -2,6 +2,7 @@ alabaster>=0.7.12,<1
matplotlib>=3.1.0,<4 matplotlib>=3.1.0,<4
networkx>=2.3,<3 networkx>=2.3,<3
numpy>=1.16.1,<2 numpy>=1.16.1,<2
pandas==0.24.2
Pygments>=2.4.2,<3 Pygments>=2.4.2,<3
pytest>=4.0.0,<5 pytest>=4.0.0,<5
scipy>=1.3.0,<2 scipy>=1.3.0,<2

View File

@@ -6,6 +6,44 @@
"destination": null, "destination": null,
"src-tp-id": null, "src-tp-id": null,
"dst-tp-id": null, "dst-tp-id": null,
"explicit-route-objects": {
"route-object-include-exclude": [
{
"explicit-route-usage": null,
"index": null,
"num-unnum-hop": {
"node-id": null,
"link-tp-id": null,
"hop-type": null
}
},
{
"explicit-route-usage": null,
"index": null,
"label-hop": {
"N": null,
"M": null
}
},
{
"explicit-route-usage": null,
"index": null,
"transponder": {
"transponder-type": null,
"transponder-mode": null
}
},
{
"explicit-route-usage": null,
"index": null,
"regenerator": {
"regenerator-id": null,
"transponder-type": null,
"transponder-mode": null
}
}
]
},
"path-constraints": { "path-constraints": {
"te-bandwidth": { "te-bandwidth": {
"technology": "flexi-grid", "technology": "flexi-grid",
@@ -22,27 +60,6 @@
"output-power": null, "output-power": null,
"path_bandwidth": null "path_bandwidth": null
} }
},
"optimizations": {
"explicit-route-include-objects": {
"route-object-include-object": [
{
"index": null,
"unnumbered-hop": {
"node-id": null,
"link-tp-id": "link-tp-id is not used",
"hop-type": null,
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
}
]
}
} }
}], }],
"synchronization": [ "synchronization": [
@@ -50,10 +67,9 @@
"synchronization-id": null, "synchronization-id": null,
"svec": { "svec": {
"relaxable": "True", "relaxable": "True",
"link-diverse": "False", "disjointness": "node link",
"node-diverse": "False",
"request-id-number": [ "request-id-number": [
null ] null, null ]
}, },
} }
] ]

Binary file not shown.

View File

@@ -0,0 +1,866 @@
{
"response": [
{
"response-id": "0",
"path-properties": {
"path-metric": [
{
"metric-type": "SNR-bandwidth",
"accumulative-value": 26.75
},
{
"metric-type": "SNR-0.1nm",
"accumulative-value": 30.84
},
{
"metric-type": "OSNR-bandwidth",
"accumulative-value": 26.76
},
{
"metric-type": "OSNR-0.1nm",
"accumulative-value": 30.84
},
{
"metric-type": "reference_power",
"accumulative-value": 0.001
},
{
"metric-type": "path_bandwidth",
"accumulative-value": 100000000000.0
}
],
"path-route-objects": [
{
"path-route-object": {
"index": 0,
"num-unnum-hop": {
"node-id": "trx Lorient_KMA",
"link-tp-id": "trx Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 1,
"transponder": {
"transponder-type": "Voyager",
"transponder-mode": "mode 1"
}
}
},
{
"path-route-object": {
"index": 2,
"num-unnum-hop": {
"node-id": "roadm Lorient_KMA",
"link-tp-id": "roadm Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 3,
"num-unnum-hop": {
"node-id": "Edfa1_roadm Lorient_KMA",
"link-tp-id": "Edfa1_roadm Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 4,
"num-unnum-hop": {
"node-id": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"link-tp-id": "fiber (Lorient_KMA → Vannes_KBE)-F055"
}
}
},
{
"path-route-object": {
"index": 5,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055",
"link-tp-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055"
}
}
},
{
"path-route-object": {
"index": 6,
"num-unnum-hop": {
"node-id": "roadm Vannes_KBE",
"link-tp-id": "roadm Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 7,
"num-unnum-hop": {
"node-id": "trx Vannes_KBE",
"link-tp-id": "trx Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 8,
"transponder": {
"transponder-type": "Voyager",
"transponder-mode": "mode 1"
}
}
}
]
}
},
{
"response-id": "1",
"path-properties": {
"path-metric": [
{
"metric-type": "SNR-bandwidth",
"accumulative-value": 18.03
},
{
"metric-type": "SNR-0.1nm",
"accumulative-value": 22.11
},
{
"metric-type": "OSNR-bandwidth",
"accumulative-value": 18.57
},
{
"metric-type": "OSNR-0.1nm",
"accumulative-value": 22.65
},
{
"metric-type": "reference_power",
"accumulative-value": 0.0012589254117941673
},
{
"metric-type": "path_bandwidth",
"accumulative-value": 0
}
],
"path-route-objects": [
{
"path-route-object": {
"index": 0,
"num-unnum-hop": {
"node-id": "trx Brest_KLA",
"link-tp-id": "trx Brest_KLA"
}
}
},
{
"path-route-object": {
"index": 1,
"transponder": {
"transponder-type": "Voyager",
"transponder-mode": "mode 1"
}
}
},
{
"path-route-object": {
"index": 2,
"num-unnum-hop": {
"node-id": "roadm Brest_KLA",
"link-tp-id": "roadm Brest_KLA"
}
}
},
{
"path-route-object": {
"index": 3,
"num-unnum-hop": {
"node-id": "Edfa0_roadm Brest_KLA",
"link-tp-id": "Edfa0_roadm Brest_KLA"
}
}
},
{
"path-route-object": {
"index": 4,
"num-unnum-hop": {
"node-id": "fiber (Brest_KLA → Morlaix)-F060",
"link-tp-id": "fiber (Brest_KLA → Morlaix)-F060"
}
}
},
{
"path-route-object": {
"index": 5,
"num-unnum-hop": {
"node-id": "east fused spans in Morlaix",
"link-tp-id": "east fused spans in Morlaix"
}
}
},
{
"path-route-object": {
"index": 6,
"num-unnum-hop": {
"node-id": "fiber (Morlaix → Lannion_CAS)-F059",
"link-tp-id": "fiber (Morlaix → Lannion_CAS)-F059"
}
}
},
{
"path-route-object": {
"index": 7,
"num-unnum-hop": {
"node-id": "west edfa in Lannion_CAS to Morlaix",
"link-tp-id": "west edfa in Lannion_CAS to Morlaix"
}
}
},
{
"path-route-object": {
"index": 8,
"num-unnum-hop": {
"node-id": "roadm Lannion_CAS",
"link-tp-id": "roadm Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 9,
"num-unnum-hop": {
"node-id": "east edfa in Lannion_CAS to Corlay",
"link-tp-id": "east edfa in Lannion_CAS to Corlay"
}
}
},
{
"path-route-object": {
"index": 10,
"num-unnum-hop": {
"node-id": "fiber (Lannion_CAS → Corlay)-F061",
"link-tp-id": "fiber (Lannion_CAS → Corlay)-F061"
}
}
},
{
"path-route-object": {
"index": 11,
"num-unnum-hop": {
"node-id": "west fused spans in Corlay",
"link-tp-id": "west fused spans in Corlay"
}
}
},
{
"path-route-object": {
"index": 12,
"num-unnum-hop": {
"node-id": "fiber (Corlay → Loudeac)-F010",
"link-tp-id": "fiber (Corlay → Loudeac)-F010"
}
}
},
{
"path-route-object": {
"index": 13,
"num-unnum-hop": {
"node-id": "west fused spans in Loudeac",
"link-tp-id": "west fused spans in Loudeac"
}
}
},
{
"path-route-object": {
"index": 14,
"num-unnum-hop": {
"node-id": "fiber (Loudeac → Lorient_KMA)-F054",
"link-tp-id": "fiber (Loudeac → Lorient_KMA)-F054"
}
}
},
{
"path-route-object": {
"index": 15,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Loudeac → Lorient_KMA)-F054",
"link-tp-id": "Edfa0_fiber (Loudeac → Lorient_KMA)-F054"
}
}
},
{
"path-route-object": {
"index": 16,
"num-unnum-hop": {
"node-id": "roadm Lorient_KMA",
"link-tp-id": "roadm Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 17,
"num-unnum-hop": {
"node-id": "Edfa1_roadm Lorient_KMA",
"link-tp-id": "Edfa1_roadm Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 18,
"num-unnum-hop": {
"node-id": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"link-tp-id": "fiber (Lorient_KMA → Vannes_KBE)-F055"
}
}
},
{
"path-route-object": {
"index": 19,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055",
"link-tp-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055"
}
}
},
{
"path-route-object": {
"index": 20,
"num-unnum-hop": {
"node-id": "roadm Vannes_KBE",
"link-tp-id": "roadm Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 21,
"num-unnum-hop": {
"node-id": "trx Vannes_KBE",
"link-tp-id": "trx Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 22,
"transponder": {
"transponder-type": "Voyager",
"transponder-mode": "mode 1"
}
}
}
]
}
},
{
"response-id": "3",
"path-properties": {
"path-metric": [
{
"metric-type": "SNR-bandwidth",
"accumulative-value": 21.77
},
{
"metric-type": "SNR-0.1nm",
"accumulative-value": 25.85
},
{
"metric-type": "OSNR-bandwidth",
"accumulative-value": 24.2
},
{
"metric-type": "OSNR-0.1nm",
"accumulative-value": 28.29
},
{
"metric-type": "reference_power",
"accumulative-value": 0.0012589254117941673
},
{
"metric-type": "path_bandwidth",
"accumulative-value": 60000000000.0
}
],
"path-route-objects": [
{
"path-route-object": {
"index": 0,
"num-unnum-hop": {
"node-id": "trx Lannion_CAS",
"link-tp-id": "trx Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 1,
"transponder": {
"transponder-type": "vendorA_trx-type1",
"transponder-mode": "mode 1"
}
}
},
{
"path-route-object": {
"index": 2,
"num-unnum-hop": {
"node-id": "roadm Lannion_CAS",
"link-tp-id": "roadm Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 3,
"num-unnum-hop": {
"node-id": "east edfa in Lannion_CAS to Stbrieuc",
"link-tp-id": "east edfa in Lannion_CAS to Stbrieuc"
}
}
},
{
"path-route-object": {
"index": 4,
"num-unnum-hop": {
"node-id": "fiber (Lannion_CAS → Stbrieuc)-F056",
"link-tp-id": "fiber (Lannion_CAS → Stbrieuc)-F056"
}
}
},
{
"path-route-object": {
"index": 5,
"num-unnum-hop": {
"node-id": "east edfa in Stbrieuc to Rennes_STA",
"link-tp-id": "east edfa in Stbrieuc to Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 6,
"num-unnum-hop": {
"node-id": "fiber (Stbrieuc → Rennes_STA)-F057",
"link-tp-id": "fiber (Stbrieuc → Rennes_STA)-F057"
}
}
},
{
"path-route-object": {
"index": 7,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Stbrieuc → Rennes_STA)-F057",
"link-tp-id": "Edfa0_fiber (Stbrieuc → Rennes_STA)-F057"
}
}
},
{
"path-route-object": {
"index": 8,
"num-unnum-hop": {
"node-id": "roadm Rennes_STA",
"link-tp-id": "roadm Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 9,
"num-unnum-hop": {
"node-id": "trx Rennes_STA",
"link-tp-id": "trx Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 10,
"transponder": {
"transponder-type": "vendorA_trx-type1",
"transponder-mode": "mode 1"
}
}
}
]
}
},
{
"response-id": "4",
"path-properties": {
"path-metric": [
{
"metric-type": "SNR-bandwidth",
"accumulative-value": 15.05
},
{
"metric-type": "SNR-0.1nm",
"accumulative-value": 22.15
},
{
"metric-type": "OSNR-bandwidth",
"accumulative-value": 15.18
},
{
"metric-type": "OSNR-0.1nm",
"accumulative-value": 22.27
},
{
"metric-type": "reference_power",
"accumulative-value": 0.001
},
{
"metric-type": "path_bandwidth",
"accumulative-value": 150000000000.0
}
],
"path-route-objects": [
{
"path-route-object": {
"index": 0,
"num-unnum-hop": {
"node-id": "trx Rennes_STA",
"link-tp-id": "trx Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 1,
"transponder": {
"transponder-type": "vendorA_trx-type1",
"transponder-mode": "mode 2"
}
}
},
{
"path-route-object": {
"index": 2,
"num-unnum-hop": {
"node-id": "roadm Rennes_STA",
"link-tp-id": "roadm Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 3,
"num-unnum-hop": {
"node-id": "Edfa1_roadm Rennes_STA",
"link-tp-id": "Edfa1_roadm Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 4,
"num-unnum-hop": {
"node-id": "fiber (Rennes_STA → Ploermel)-",
"link-tp-id": "fiber (Rennes_STA → Ploermel)-"
}
}
},
{
"path-route-object": {
"index": 5,
"num-unnum-hop": {
"node-id": "east edfa in Ploermel to Vannes_KBE",
"link-tp-id": "east edfa in Ploermel to Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 6,
"num-unnum-hop": {
"node-id": "fiber (Ploermel → Vannes_KBE)-",
"link-tp-id": "fiber (Ploermel → Vannes_KBE)-"
}
}
},
{
"path-route-object": {
"index": 7,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Ploermel → Vannes_KBE)-",
"link-tp-id": "Edfa0_fiber (Ploermel → Vannes_KBE)-"
}
}
},
{
"path-route-object": {
"index": 8,
"num-unnum-hop": {
"node-id": "roadm Vannes_KBE",
"link-tp-id": "roadm Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 9,
"num-unnum-hop": {
"node-id": "Edfa0_roadm Vannes_KBE",
"link-tp-id": "Edfa0_roadm Vannes_KBE"
}
}
},
{
"path-route-object": {
"index": 10,
"num-unnum-hop": {
"node-id": "fiber (Vannes_KBE → Lorient_KMA)-F055",
"link-tp-id": "fiber (Vannes_KBE → Lorient_KMA)-F055"
}
}
},
{
"path-route-object": {
"index": 11,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055",
"link-tp-id": "Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055"
}
}
},
{
"path-route-object": {
"index": 12,
"num-unnum-hop": {
"node-id": "roadm Lorient_KMA",
"link-tp-id": "roadm Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 13,
"num-unnum-hop": {
"node-id": "Edfa0_roadm Lorient_KMA",
"link-tp-id": "Edfa0_roadm Lorient_KMA"
}
}
},
{
"path-route-object": {
"index": 14,
"num-unnum-hop": {
"node-id": "fiber (Lorient_KMA → Loudeac)-F054",
"link-tp-id": "fiber (Lorient_KMA → Loudeac)-F054"
}
}
},
{
"path-route-object": {
"index": 15,
"num-unnum-hop": {
"node-id": "east fused spans in Loudeac",
"link-tp-id": "east fused spans in Loudeac"
}
}
},
{
"path-route-object": {
"index": 16,
"num-unnum-hop": {
"node-id": "fiber (Loudeac → Corlay)-F010",
"link-tp-id": "fiber (Loudeac → Corlay)-F010"
}
}
},
{
"path-route-object": {
"index": 17,
"num-unnum-hop": {
"node-id": "east fused spans in Corlay",
"link-tp-id": "east fused spans in Corlay"
}
}
},
{
"path-route-object": {
"index": 18,
"num-unnum-hop": {
"node-id": "fiber (Corlay → Lannion_CAS)-F061",
"link-tp-id": "fiber (Corlay → Lannion_CAS)-F061"
}
}
},
{
"path-route-object": {
"index": 19,
"num-unnum-hop": {
"node-id": "west edfa in Lannion_CAS to Corlay",
"link-tp-id": "west edfa in Lannion_CAS to Corlay"
}
}
},
{
"path-route-object": {
"index": 20,
"num-unnum-hop": {
"node-id": "roadm Lannion_CAS",
"link-tp-id": "roadm Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 21,
"num-unnum-hop": {
"node-id": "trx Lannion_CAS",
"link-tp-id": "trx Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 22,
"transponder": {
"transponder-type": "vendorA_trx-type1",
"transponder-mode": "mode 2"
}
}
}
]
}
},
{
"response-id": "5",
"path-properties": {
"path-metric": [
{
"metric-type": "SNR-bandwidth",
"accumulative-value": 21.68
},
{
"metric-type": "SNR-0.1nm",
"accumulative-value": 28.77
},
{
"metric-type": "OSNR-bandwidth",
"accumulative-value": 23.7
},
{
"metric-type": "OSNR-0.1nm",
"accumulative-value": 30.79
},
{
"metric-type": "reference_power",
"accumulative-value": 0.0019952623149688794
},
{
"metric-type": "path_bandwidth",
"accumulative-value": 20000000000.0
}
],
"path-route-objects": [
{
"path-route-object": {
"index": 0,
"num-unnum-hop": {
"node-id": "trx Rennes_STA",
"link-tp-id": "trx Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 1,
"transponder": {
"transponder-type": "vendorA_trx-type1",
"transponder-mode": "mode 2"
}
}
},
{
"path-route-object": {
"index": 2,
"num-unnum-hop": {
"node-id": "roadm Rennes_STA",
"link-tp-id": "roadm Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 3,
"num-unnum-hop": {
"node-id": "Edfa0_roadm Rennes_STA",
"link-tp-id": "Edfa0_roadm Rennes_STA"
}
}
},
{
"path-route-object": {
"index": 4,
"num-unnum-hop": {
"node-id": "fiber (Rennes_STA → Stbrieuc)-F057",
"link-tp-id": "fiber (Rennes_STA → Stbrieuc)-F057"
}
}
},
{
"path-route-object": {
"index": 5,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Rennes_STA → Stbrieuc)-F057",
"link-tp-id": "Edfa0_fiber (Rennes_STA → Stbrieuc)-F057"
}
}
},
{
"path-route-object": {
"index": 6,
"num-unnum-hop": {
"node-id": "fiber (Stbrieuc → Lannion_CAS)-F056",
"link-tp-id": "fiber (Stbrieuc → Lannion_CAS)-F056"
}
}
},
{
"path-route-object": {
"index": 7,
"num-unnum-hop": {
"node-id": "Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056",
"link-tp-id": "Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056"
}
}
},
{
"path-route-object": {
"index": 8,
"num-unnum-hop": {
"node-id": "roadm Lannion_CAS",
"link-tp-id": "roadm Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 9,
"num-unnum-hop": {
"node-id": "trx Lannion_CAS",
"link-tp-id": "trx Lannion_CAS"
}
}
},
{
"path-route-object": {
"index": 10,
"transponder": {
"transponder-type": "vendorA_trx-type1",
"transponder-mode": "mode 2"
}
}
}
]
}
},
{
"response-id": "6",
"no-path": "Response without path information, due to failure performing the path computation"
}
]
}

View File

@@ -0,0 +1,7 @@
response-id,source,destination,path_bandwidth,Pass?,nb of tsp pairs,total cost,transponder-type,transponder-mode,OSNR-0.1nm,SNR-0.1nm,SNR-bandwidth,baud rate (Gbaud),input power (dBm),path
0,trx Lorient_KMA,trx Vannes_KBE,100.0,True,1,1,Voyager,mode 1,30.84,30.84,26.75,32.0,0.0,trx Lorient_KMA | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE
1,trx Brest_KLA,trx Vannes_KBE,0.0,True,0,0,Voyager,mode 1,22.65,22.11,18.03,32.0,1.0,trx Brest_KLA | roadm Brest_KLA | Edfa0_roadm Brest_KLA | fiber (Brest_KLA → Morlaix)-F060 | east fused spans in Morlaix | fiber (Morlaix → Lannion_CAS)-F059 | west edfa in Lannion_CAS to Morlaix | roadm Lannion_CAS | east edfa in Lannion_CAS to Corlay | fiber (Lannion_CAS → Corlay)-F061 | west fused spans in Corlay | fiber (Corlay → Loudeac)-F010 | west fused spans in Loudeac | fiber (Loudeac → Lorient_KMA)-F054 | Edfa0_fiber (Loudeac → Lorient_KMA)-F054 | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE
3,trx Lannion_CAS,trx Rennes_STA,60.0,True,1,1,vendorA_trx-type1,mode 1,28.29,25.85,21.77,32.0,1.0,trx Lannion_CAS | roadm Lannion_CAS | east edfa in Lannion_CAS to Stbrieuc | fiber (Lannion_CAS → Stbrieuc)-F056 | east edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Rennes_STA)-F057 | Edfa0_fiber (Stbrieuc → Rennes_STA)-F057 | roadm Rennes_STA | trx Rennes_STA
4,trx Rennes_STA,trx Lannion_CAS,150.0,True,1,1,vendorA_trx-type1,mode 2,22.27,22.15,15.05,64.0,0.0,trx Rennes_STA | roadm Rennes_STA | Edfa1_roadm Rennes_STA | fiber (Rennes_STA → Ploermel)- | east edfa in Ploermel to Vannes_KBE | fiber (Ploermel → Vannes_KBE)- | Edfa0_fiber (Ploermel → Vannes_KBE)- | roadm Vannes_KBE | Edfa0_roadm Vannes_KBE | fiber (Vannes_KBE → Lorient_KMA)-F055 | Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055 | roadm Lorient_KMA | Edfa0_roadm Lorient_KMA | fiber (Lorient_KMA → Loudeac)-F054 | east fused spans in Loudeac | fiber (Loudeac → Corlay)-F010 | east fused spans in Corlay | fiber (Corlay → Lannion_CAS)-F061 | west edfa in Lannion_CAS to Corlay | roadm Lannion_CAS | trx Lannion_CAS
5,trx Rennes_STA,trx Lannion_CAS,20.0,True,1,1,vendorA_trx-type1,mode 2,30.79,28.77,21.68,64.0,3.0,trx Rennes_STA | roadm Rennes_STA | Edfa0_roadm Rennes_STA | fiber (Rennes_STA → Stbrieuc)-F057 | Edfa0_fiber (Rennes_STA → Stbrieuc)-F057 | fiber (Stbrieuc → Lannion_CAS)-F056 | Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056 | roadm Lannion_CAS | trx Lannion_CAS
6,,,,False,0,,,,,,,,,
1 response-id source destination path_bandwidth Pass? nb of tsp pairs total cost transponder-type transponder-mode OSNR-0.1nm SNR-0.1nm SNR-bandwidth baud rate (Gbaud) input power (dBm) path
2 0 trx Lorient_KMA trx Vannes_KBE 100.0 True 1 1 Voyager mode 1 30.84 30.84 26.75 32.0 0.0 trx Lorient_KMA | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE
3 1 trx Brest_KLA trx Vannes_KBE 0.0 True 0 0 Voyager mode 1 22.65 22.11 18.03 32.0 1.0 trx Brest_KLA | roadm Brest_KLA | Edfa0_roadm Brest_KLA | fiber (Brest_KLA → Morlaix)-F060 | east fused spans in Morlaix | fiber (Morlaix → Lannion_CAS)-F059 | west edfa in Lannion_CAS to Morlaix | roadm Lannion_CAS | east edfa in Lannion_CAS to Corlay | fiber (Lannion_CAS → Corlay)-F061 | west fused spans in Corlay | fiber (Corlay → Loudeac)-F010 | west fused spans in Loudeac | fiber (Loudeac → Lorient_KMA)-F054 | Edfa0_fiber (Loudeac → Lorient_KMA)-F054 | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE
4 3 trx Lannion_CAS trx Rennes_STA 60.0 True 1 1 vendorA_trx-type1 mode 1 28.29 25.85 21.77 32.0 1.0 trx Lannion_CAS | roadm Lannion_CAS | east edfa in Lannion_CAS to Stbrieuc | fiber (Lannion_CAS → Stbrieuc)-F056 | east edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Rennes_STA)-F057 | Edfa0_fiber (Stbrieuc → Rennes_STA)-F057 | roadm Rennes_STA | trx Rennes_STA
5 4 trx Rennes_STA trx Lannion_CAS 150.0 True 1 1 vendorA_trx-type1 mode 2 22.27 22.15 15.05 64.0 0.0 trx Rennes_STA | roadm Rennes_STA | Edfa1_roadm Rennes_STA | fiber (Rennes_STA → Ploermel)- | east edfa in Ploermel to Vannes_KBE | fiber (Ploermel → Vannes_KBE)- | Edfa0_fiber (Ploermel → Vannes_KBE)- | roadm Vannes_KBE | Edfa0_roadm Vannes_KBE | fiber (Vannes_KBE → Lorient_KMA)-F055 | Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055 | roadm Lorient_KMA | Edfa0_roadm Lorient_KMA | fiber (Lorient_KMA → Loudeac)-F054 | east fused spans in Loudeac | fiber (Loudeac → Corlay)-F010 | east fused spans in Corlay | fiber (Corlay → Lannion_CAS)-F061 | west edfa in Lannion_CAS to Corlay | roadm Lannion_CAS | trx Lannion_CAS
6 5 trx Rennes_STA trx Lannion_CAS 20.0 True 1 1 vendorA_trx-type1 mode 2 30.79 28.77 21.68 64.0 3.0 trx Rennes_STA | roadm Rennes_STA | Edfa0_roadm Rennes_STA | fiber (Rennes_STA → Stbrieuc)-F057 | Edfa0_fiber (Rennes_STA → Stbrieuc)-F057 | fiber (Stbrieuc → Lannion_CAS)-F056 | Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056 | roadm Lannion_CAS | trx Lannion_CAS
7 6 False 0

View File

@@ -2,8 +2,8 @@
"path-request": [ "path-request": [
{ {
"request-id": "0", "request-id": "0",
"source": "Lorient_KMA", "source": "trx Lorient_KMA",
"destination": "Vannes_KBE", "destination": "trx Vannes_KBE",
"src-tp-id": "trx Lorient_KMA", "src-tp-id": "trx Lorient_KMA",
"dst-tp-id": "trx Vannes_KBE", "dst-tp-id": "trx Vannes_KBE",
"path-constraints": { "path-constraints": {
@@ -13,8 +13,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -22,15 +22,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 100000000000.0 "path_bandwidth": 100000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "1", "request-id": "1",
"source": "Brest_KLA", "source": "trx Brest_KLA",
"destination": "Vannes_KBE", "destination": "trx Vannes_KBE",
"src-tp-id": "trx Brest_KLA", "src-tp-id": "trx Brest_KLA",
"dst-tp-id": "trx Vannes_KBE", "dst-tp-id": "trx Vannes_KBE",
"path-constraints": { "path-constraints": {
@@ -40,8 +37,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -50,66 +47,42 @@
"path_bandwidth": 0 "path_bandwidth": 0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Brest_KLA", "node-id": "roadm Brest_KLA",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 1, "index": 1,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Lannion_CAS", "node-id": "roadm Lannion_CAS",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 2, "index": 2,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Lorient_KMA", "node-id": "roadm Lorient_KMA",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 3, "index": 3,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm Vannes_KBE", "node-id": "roadm Vannes_KBE",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -117,8 +90,8 @@
}, },
{ {
"request-id": "3", "request-id": "3",
"source": "Lannion_CAS", "source": "trx Lannion_CAS",
"destination": "Rennes_STA", "destination": "trx Rennes_STA",
"src-tp-id": "trx Lannion_CAS", "src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx Rennes_STA", "dst-tp-id": "trx Rennes_STA",
"path-constraints": { "path-constraints": {
@@ -128,8 +101,8 @@
"trx_mode": "mode 1", "trx_mode": "mode 1",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 50000000000.0, "spacing": 50000000000.0,
@@ -137,15 +110,12 @@
"output-power": 0.0012589254117941673, "output-power": 0.0012589254117941673,
"path_bandwidth": 60000000000.0 "path_bandwidth": 60000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "4", "request-id": "4",
"source": "Rennes_STA", "source": "trx Rennes_STA",
"destination": "Lannion_CAS", "destination": "trx Lannion_CAS",
"src-tp-id": "trx Rennes_STA", "src-tp-id": "trx Rennes_STA",
"dst-tp-id": "trx Lannion_CAS", "dst-tp-id": "trx Lannion_CAS",
"path-constraints": { "path-constraints": {
@@ -155,8 +125,8 @@
"trx_mode": "mode 2", "trx_mode": "mode 2",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 75000000000.0, "spacing": 75000000000.0,
@@ -164,15 +134,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 150000000000.0 "path_bandwidth": 150000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "5", "request-id": "5",
"source": "Rennes_STA", "source": "trx Rennes_STA",
"destination": "Lannion_CAS", "destination": "trx Lannion_CAS",
"src-tp-id": "trx Rennes_STA", "src-tp-id": "trx Rennes_STA",
"dst-tp-id": "trx Lannion_CAS", "dst-tp-id": "trx Lannion_CAS",
"path-constraints": { "path-constraints": {
@@ -182,8 +149,8 @@
"trx_mode": "mode 2", "trx_mode": "mode 2",
"effective-freq-slot": [ "effective-freq-slot": [
{ {
"n": "null", "N": "null",
"m": "null" "M": "null"
} }
], ],
"spacing": 75000000000.0, "spacing": 75000000000.0,
@@ -191,9 +158,30 @@
"output-power": 0.0019952623149688794, "output-power": 0.0019952623149688794,
"path_bandwidth": 20000000000.0 "path_bandwidth": 20000000000.0
} }
}, }
"optimizations": { },
"explicit-route-include-objects": [] {
"request-id": "6",
"source": "trx Lannion_CAS",
"destination": "trx a",
"src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx a",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "vendorA_trx-type1",
"trx_mode": "mode 2",
"effective-freq-slot": [
{
"N": "null",
"M": "null"
}
],
"spacing": 75000000000.0,
"max-nb-of-channel": null,
"output-power": null,
"path_bandwidth": 100000000000.0
}
} }
} }
], ],
@@ -201,9 +189,8 @@
{ {
"synchronization-id": "3", "synchronization-id": "3",
"svec": { "svec": {
"relaxable": "False", "relaxable": "false",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"3", "3",
"1" "1"
@@ -213,9 +200,8 @@
{ {
"synchronization-id": "4", "synchronization-id": "4",
"svec": { "svec": {
"relaxable": "False", "relaxable": "false",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"4", "4",
"5" "5"

View File

@@ -2,8 +2,8 @@
"path-request": [ "path-request": [
{ {
"request-id": "1", "request-id": "1",
"source": "a", "source": "trx a",
"destination": "g", "destination": "trx g",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx g", "dst-tp-id": "trx g",
"path-constraints": { "path-constraints": {
@@ -22,15 +22,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "2a", "request-id": "2a",
"source": "a", "source": "trx a",
"destination": "h", "destination": "trx h",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx h", "dst-tp-id": "trx h",
"path-constraints": { "path-constraints": {
@@ -49,15 +46,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "3", "request-id": "3",
"source": "f", "source": "trx f",
"destination": "b", "destination": "trx b",
"src-tp-id": "trx f", "src-tp-id": "trx f",
"dst-tp-id": "trx b", "dst-tp-id": "trx b",
"path-constraints": { "path-constraints": {
@@ -76,15 +70,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "ee", "request-id": "ee",
"source": "c", "source": "trx c",
"destination": "f", "destination": "trx f",
"src-tp-id": "trx c", "src-tp-id": "trx c",
"dst-tp-id": "trx f", "dst-tp-id": "trx f",
"path-constraints": { "path-constraints": {
@@ -104,36 +95,23 @@
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm e", "node-id": "roadm e",
"link-tp-id": "link-tp-id is not used", "hop-type": "LOOSE"
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 1, "index": 1,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm g", "node-id": "roadm g",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -141,8 +119,8 @@
}, },
{ {
"request-id": "ff", "request-id": "ff",
"source": "c", "source": "trx c",
"destination": "f", "destination": "trx f",
"src-tp-id": "trx c", "src-tp-id": "trx c",
"dst-tp-id": "trx f", "dst-tp-id": "trx f",
"path-constraints": { "path-constraints": {
@@ -161,15 +139,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "10", "request-id": "10",
"source": "a", "source": "trx a",
"destination": "g", "destination": "trx g",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx g", "dst-tp-id": "trx g",
"path-constraints": { "path-constraints": {
@@ -188,15 +163,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "11", "request-id": "11",
"source": "a", "source": "trx a",
"destination": "h", "destination": "trx h",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx h", "dst-tp-id": "trx h",
"path-constraints": { "path-constraints": {
@@ -216,21 +188,15 @@
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "bb", "node-id": "bb",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -238,8 +204,8 @@
}, },
{ {
"request-id": "12", "request-id": "12",
"source": "f", "source": "trx f",
"destination": "b", "destination": "trx b",
"src-tp-id": "trx f", "src-tp-id": "trx f",
"dst-tp-id": "trx b", "dst-tp-id": "trx b",
"path-constraints": { "path-constraints": {
@@ -259,21 +225,15 @@
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "trx b", "node-id": "trx b",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -281,8 +241,8 @@
}, },
{ {
"request-id": "13", "request-id": "13",
"source": "c", "source": "trx c",
"destination": "f", "destination": "trx f",
"src-tp-id": "trx c", "src-tp-id": "trx c",
"dst-tp-id": "trx f", "dst-tp-id": "trx f",
"path-constraints": { "path-constraints": {
@@ -301,15 +261,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "14", "request-id": "14",
"source": "c", "source": "trx c",
"destination": "f", "destination": "trx f",
"src-tp-id": "trx c", "src-tp-id": "trx c",
"dst-tp-id": "trx f", "dst-tp-id": "trx f",
"path-constraints": { "path-constraints": {
@@ -329,36 +286,23 @@
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm e", "node-id": "roadm e",
"link-tp-id": "link-tp-id is not used", "hop-type": "LOOSE"
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 1, "index": 1,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm g", "node-id": "roadm g",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -366,8 +310,8 @@
}, },
{ {
"request-id": "e:1# /", "request-id": "e:1# /",
"source": "a", "source": "trx a",
"destination": "g", "destination": "trx g",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx g", "dst-tp-id": "trx g",
"path-constraints": { "path-constraints": {
@@ -386,15 +330,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "b-2a", "request-id": "b-2a",
"source": "a", "source": "trx a",
"destination": "h", "destination": "trx h",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx h", "dst-tp-id": "trx h",
"path-constraints": { "path-constraints": {
@@ -413,15 +354,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "3a;?", "request-id": "3a;?",
"source": "f", "source": "trx f",
"destination": "b", "destination": "trx b",
"src-tp-id": "trx f", "src-tp-id": "trx f",
"dst-tp-id": "trx b", "dst-tp-id": "trx b",
"path-constraints": { "path-constraints": {
@@ -440,15 +378,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "ee-s", "request-id": "ee-s",
"source": "c", "source": "trx c",
"destination": "f", "destination": "trx f",
"src-tp-id": "trx c", "src-tp-id": "trx c",
"dst-tp-id": "trx f", "dst-tp-id": "trx f",
"path-constraints": { "path-constraints": {
@@ -468,36 +403,23 @@
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
}, },
"optimizations": { "explicit-route-objects": {
"explicit-route-include-objects": [ "route-object-include-exclude": [
{ {
"explicit-route-usage": "route-include-ero",
"index": 0, "index": 0,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm e", "node-id": "roadm e",
"link-tp-id": "link-tp-id is not used", "hop-type": "LOOSE"
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
}, },
{ {
"explicit-route-usage": "route-include-ero",
"index": 1, "index": 1,
"unnumbered-hop": { "num-unnum-hop": {
"node-id": "roadm g", "node-id": "roadm g",
"link-tp-id": "link-tp-id is not used", "link-tp-id": "link-tp-id is not used",
"hop-type": "loose", "hop-type": "LOOSE"
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
} }
} }
] ]
@@ -505,8 +427,8 @@
}, },
{ {
"request-id": "ff-b", "request-id": "ff-b",
"source": "c", "source": "trx c",
"destination": "f", "destination": "trx f",
"src-tp-id": "trx c", "src-tp-id": "trx c",
"dst-tp-id": "trx f", "dst-tp-id": "trx f",
"path-constraints": { "path-constraints": {
@@ -525,15 +447,12 @@
"output-power": 0.001, "output-power": 0.001,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "10-z", "request-id": "10-z",
"source": "a", "source": "trx a",
"destination": "g", "destination": "trx g",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx g", "dst-tp-id": "trx g",
"path-constraints": { "path-constraints": {
@@ -552,15 +471,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "11 g", "request-id": "11 g",
"source": "a", "source": "trx a",
"destination": "h", "destination": "trx h",
"src-tp-id": "trx a", "src-tp-id": "trx a",
"dst-tp-id": "trx h", "dst-tp-id": "trx h",
"path-constraints": { "path-constraints": {
@@ -579,15 +495,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": 300000000000.0 "path_bandwidth": 300000000000.0
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "12<", "request-id": "12<",
"source": "f", "source": "trx f",
"destination": "b", "destination": "trx b",
"src-tp-id": "trx f", "src-tp-id": "trx f",
"dst-tp-id": "trx b", "dst-tp-id": "trx b",
"path-constraints": { "path-constraints": {
@@ -606,15 +519,12 @@
"output-power": null, "output-power": null,
"path_bandwidth": null "path_bandwidth": null
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
}, },
{ {
"request-id": "12>", "request-id": "12>",
"source": "f", "source": "trx f",
"destination": "b", "destination": "trx b",
"src-tp-id": "trx f", "src-tp-id": "trx f",
"dst-tp-id": "trx b", "dst-tp-id": "trx b",
"path-constraints": { "path-constraints": {
@@ -633,9 +543,6 @@
"output-power": null, "output-power": null,
"path_bandwidth": null "path_bandwidth": null
} }
},
"optimizations": {
"explicit-route-include-objects": []
} }
} }
], ],
@@ -644,8 +551,7 @@
"synchronization-id": "1", "synchronization-id": "1",
"svec": { "svec": {
"relaxable": "False", "relaxable": "False",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"1", "1",
"2a" "2a"
@@ -656,8 +562,7 @@
"synchronization-id": "3", "synchronization-id": "3",
"svec": { "svec": {
"relaxable": "False", "relaxable": "False",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"3", "3",
"1" "1"
@@ -668,8 +573,7 @@
"synchronization-id": "ff", "synchronization-id": "ff",
"svec": { "svec": {
"relaxable": "False", "relaxable": "False",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"ff", "ff",
"13" "13"
@@ -680,8 +584,7 @@
"synchronization-id": "13", "synchronization-id": "13",
"svec": { "svec": {
"relaxable": "False", "relaxable": "False",
"link-diverse": "True", "disjointness": "node link",
"node-diverse": "True",
"request-id-number": [ "request-id-number": [
"13", "13",
"14" "14"

View File

@@ -3,38 +3,48 @@
# @Author: Esther Le Rouzic # @Author: Esther Le Rouzic
# @Date: 2018-06-15 # @Date: 2018-06-15
from gnpy.core.elements import Edfa """ Adding tests to check the parser non regression
import numpy as np convention of naming of test files:
- ..._expected.json for the reference output
tests:
- generation of topology json
- reading of Eqpt sheet w and W/ power mode
- consistency of autodesign
- generation of service list based on service sheet
- writing of results in csv
- writing of results in json (same keys)
"""
from json import load from json import load
from pathlib import Path
from os import unlink
from pandas import read_csv
import pytest import pytest
from gnpy.core import network_from_json
from gnpy.core.elements import Transceiver, Fiber, Edfa
from gnpy.core.utils import lin2db, db2lin
from gnpy.core.info import SpectralInformation, Channel, Power
from gnpy.core.network import save_network, build_network
from tests.compare import compare_networks, compare_services from tests.compare import compare_networks, compare_services
from gnpy.core.utils import lin2db
from gnpy.core.network import save_network, build_network
from gnpy.core.convert import convert_file from gnpy.core.convert import convert_file
from gnpy.core.service_sheet import convert_service_sheet from gnpy.core.service_sheet import convert_service_sheet
from gnpy.core.equipment import load_equipment, automatic_nch from gnpy.core.equipment import load_equipment, automatic_nch
from gnpy.core.network import load_network from gnpy.core.network import load_network
from pathlib import Path from gnpy.core.request import (jsontocsv, requests_aggregation,
import filecmp compute_path_dsjctn, Result_element)
from os import unlink from examples.path_requests_run import (requests_from_json, disjunctions_from_json,
correct_route_list, correct_disjn,
compute_path_with_disjunction)
TEST_DIR = Path(__file__).parent TEST_DIR = Path(__file__).parent
DATA_DIR = TEST_DIR / 'data' DATA_DIR = TEST_DIR / 'data'
eqpt_filename = DATA_DIR / 'eqpt_config.json' eqpt_filename = DATA_DIR / 'eqpt_config.json'
# adding tests to check the parser non regression
# convention of naming of test files:
#
# - ..._expected.json for the reference output
@pytest.mark.parametrize('xls_input,expected_json_output', { @pytest.mark.parametrize('xls_input,expected_json_output', {
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_expected.json', DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_expected.json',
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_expected.json', DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_expected.json',
}.items()) }.items())
def test_excel_json_generation(xls_input, expected_json_output): def test_excel_json_generation(xls_input, expected_json_output):
""" tests generation of topology json
"""
convert_file(xls_input) convert_file(xls_input)
actual_json_output = xls_input.with_suffix('.json') actual_json_output = xls_input.with_suffix('.json')
@@ -55,20 +65,25 @@ def test_excel_json_generation(xls_input, expected_json_output):
# assume xls entries # assume xls entries
# test that the build network gives correct results in gain mode # test that the build network gives correct results in gain mode
#
@pytest.mark.parametrize('xls_input,expected_json_output', { @pytest.mark.parametrize('xls_input,expected_json_output',
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json', {DATA_DIR / 'CORONET_Global_Topology.xls':\
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_auto_design_expected.json', DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
}.items()) DATA_DIR / 'testTopology.xls':\
DATA_DIR / 'testTopology_auto_design_expected.json',
}.items())
def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output): def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output):
""" tests generation of topology json
test that the build network gives correct results in gain mode
"""
equipment = load_equipment(eqpt_filename) equipment = load_equipment(eqpt_filename)
network = load_network(xls_input,equipment) network = load_network(xls_input, equipment)
# in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode) # in order to test the Eqpt sheet and load gain target,
# change the power-mode to False (to be in gain mode)
equipment['Span']['default'].power_mode = False equipment['Span']['default'].power_mode = False
# Build the network once using the default power defined in SI in eqpt config # Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\ p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db) build_network(network, equipment, p_db, p_total_db)
@@ -92,19 +107,23 @@ def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output)
assert not results.connections.different assert not results.connections.different
#test that autodesign creates same file as an input file already autodesigned #test that autodesign creates same file as an input file already autodesigned
@pytest.mark.parametrize('json_input,expected_json_output', { @pytest.mark.parametrize('json_input,expected_json_output',
DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json': DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json', {DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json':\
DATA_DIR / 'testTopology_auto_design_expected.json': DATA_DIR / 'testTopology_auto_design_expected.json', DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
}.items()) DATA_DIR / 'testTopology_auto_design_expected.json':\
DATA_DIR / 'testTopology_auto_design_expected.json',
}.items())
def test_auto_design_generation_fromjson(json_input, expected_json_output): def test_auto_design_generation_fromjson(json_input, expected_json_output):
"""test that autodesign creates same file as an input file already autodesigned
"""
equipment = load_equipment(eqpt_filename) equipment = load_equipment(eqpt_filename)
network = load_network(json_input,equipment) network = load_network(json_input, equipment)
# in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode) # in order to test the Eqpt sheet and load gain target,
# change the power-mode to False (to be in gain mode)
equipment['Span']['default'].power_mode = False equipment['Span']['default'].power_mode = False
# Build the network once using the default power defined in SI in eqpt config # Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\ p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db) build_network(network, equipment, p_db, p_total_db)
@@ -131,8 +150,10 @@ def test_auto_design_generation_fromjson(json_input, expected_json_output):
@pytest.mark.parametrize('xls_input,expected_json_output', { @pytest.mark.parametrize('xls_input,expected_json_output', {
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_services_expected.json', DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_services_expected.json',
}.items()) }.items())
def test_excel_service_json_generation(xls_input, expected_json_output): def test_excel_service_json_generation(xls_input, expected_json_output):
""" test services creation
"""
convert_service_sheet(xls_input, eqpt_filename) convert_service_sheet(xls_input, eqpt_filename)
actual_json_output = f'{str(xls_input)[:-4]}_services.json' actual_json_output = f'{str(xls_input)[:-4]}_services.json'
@@ -150,3 +171,128 @@ def test_excel_service_json_generation(xls_input, expected_json_output):
assert not results.synchronizations.missing assert not results.synchronizations.missing
assert not results.synchronizations.extra assert not results.synchronizations.extra
assert not results.synchronizations.different assert not results.synchronizations.different
# test xls answers creation
@pytest.mark.parametrize('json_input, csv_output', {
DATA_DIR / 'testTopology_response.json': DATA_DIR / 'testTopology_response',
}.items())
def test_csv_response_generation(json_input, csv_output):
""" tests if generated csv is consistant with expected generation
same columns (order not important)
"""
with open(json_input) as jsonfile:
json_data = load(jsonfile)
equipment = load_equipment(eqpt_filename)
csv_filename = str(csv_output)+'.csv'
with open(csv_filename, 'w', encoding='utf-8') as fcsv:
jsontocsv(json_data, equipment, fcsv)
expected_csv_filename = str(csv_output)+'_expected.csv'
# expected header
# csv_header = \
# [
# 'response-id',
# 'source',
# 'destination',
# 'path_bandwidth',
# 'Pass?',
# 'nb of tsp pairs',
# 'total cost',
# 'transponder-type',
# 'transponder-mode',
# 'OSNR-0.1nm',
# 'SNR-0.1nm',
# 'SNR-bandwidth',
# 'baud rate (Gbaud)',
# 'input power (dBm)',
# 'path'
# ]
resp = read_csv(csv_filename)
unlink(csv_filename)
expected_resp = read_csv(expected_csv_filename)
resp_header = list(resp.head(0))
expected_resp_header = list(expected_resp.head(0))
# check that headers are the same
resp_header.sort()
expected_resp_header.sort()
print('headers are differents')
print(resp_header)
print(expected_resp_header)
assert resp_header == expected_resp_header
# for each header checks that the output are as expected
resp.sort_values(by=['response-id'])
expected_resp.sort_values(by=['response-id'])
for column in expected_resp:
assert list(resp[column].fillna('')) == list(expected_resp[column].fillna(''))
print('results are different')
print(list(resp[column]))
print(list(expected_resp[column]))
print(type(list(resp[column])[-1]))
def compare_response(exp_resp, act_resp):
""" False if the keys are different in the nested dicts as well
"""
print(exp_resp)
print(act_resp)
test = True
for key in act_resp.keys():
print(key)
if not key in exp_resp.keys():
print(key)
return False
if isinstance(act_resp[key], dict):
test = compare_response(exp_resp[key], act_resp[key])
if test:
for key in exp_resp.keys():
if not key in act_resp.keys():
print(key)
return False
if isinstance(exp_resp[key], dict):
test = compare_response(exp_resp[key], act_resp[key])
# at this point exp_resp and act_resp have the same keys. Check if their values are the same
for key in act_resp.keys():
if not isinstance(act_resp[key], dict):
if exp_resp[key] != act_resp[key]:
return False
return test
# test json answers creation
@pytest.mark.parametrize('xls_input, expected_response_file', {
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_response.json',
}.items())
def test_json_response_generation(xls_input, expected_response_file):
""" tests if json response is correctly generated for all combinations of requests
"""
data = convert_service_sheet(xls_input, eqpt_filename)
equipment = load_equipment(eqpt_filename)
network = load_network(xls_input, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
rqs = requests_from_json(data, equipment)
rqs = correct_route_list(network, rqs)
dsjn = disjunctions_from_json(data)
dsjn = correct_disjn(dsjn)
rqs, dsjn = requests_aggregation(rqs, dsjn)
pths = compute_path_dsjctn(network, equipment, rqs, dsjn)
propagatedpths = compute_path_with_disjunction(network, equipment, rqs, pths)
result = []
for i, pth in enumerate(propagatedpths):
result.append(Result_element(rqs[i], pth))
temp = {
'response': [n.json for n in result]
}
# load expected result and compare keys
# (not values at this stage)
with open(expected_response_file) as jsonfile:
expected = load(jsonfile)
for i, response in enumerate(temp['response']):
assert compare_response(expected['response'][i], response)