mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-02 11:07:57 +00:00
Major correction on mode optimization behaviour + small fixes
- this version handles special cases: if no baudrate satisfies the spacing , if no mode satisfies the OSNR threshold from transponders - template of service corrected wih the novel path_bandwidth - some ideas TODO added for testing Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
This commit is contained in:
@@ -180,21 +180,10 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
# TODO change all these req, dsjct, res lists into dict !
|
||||
path_res_list = []
|
||||
|
||||
|
||||
# # Build the network once using the default power defined in SI in eqpt config
|
||||
# # power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
|
||||
# # spacing, f_min and f_max
|
||||
# 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)
|
||||
# TODO : get the designed power to set it when it is not an input
|
||||
# pathreq.power to be adapted
|
||||
for i,pathreq in enumerate(pathreqlist):
|
||||
|
||||
# use the power specified in requests but might be different from the one specified for design
|
||||
# TODO: set the power as an optional parameter for requests definition
|
||||
# the power is an optional parameter for requests definition
|
||||
# if optional, use the one defines in eqt_config.json
|
||||
p_db = lin2db(pathreq.power*1e3)
|
||||
p_total_db = p_db + lin2db(pathreq.nb_channel)
|
||||
@@ -211,13 +200,18 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
|
||||
total_path = propagate(total_path,pathreq,equipment, show=False)
|
||||
else:
|
||||
total_path,mode = propagate_and_optimize_mode(total_path,pathreq,equipment, show=False)
|
||||
pathreq.baud_rate = mode['baud_rate']
|
||||
pathreq.tsp_mode = mode['format']
|
||||
pathreq.format = mode['format']
|
||||
pathreq.OSNR = mode['OSNR']
|
||||
pathreq.bit_rate = mode['bit_rate']
|
||||
else:
|
||||
total_path = []
|
||||
# if no baudrate satisfies spacing, no mode is returned and an empty path is returned
|
||||
# a warning is shown in the propagate_and_optimize_mode
|
||||
if mode is not None :
|
||||
# propagate_and_optimize_mode function returns the mode with the highest bitrate
|
||||
# that passes. if no mode passes, then it returns an empty path
|
||||
pathreq.baud_rate = mode['baud_rate']
|
||||
pathreq.tsp_mode = mode['format']
|
||||
pathreq.format = mode['format']
|
||||
pathreq.OSNR = mode['OSNR']
|
||||
pathreq.bit_rate = mode['bit_rate']
|
||||
else :
|
||||
total_path = []
|
||||
# we record the last tranceiver object in order to have th whole
|
||||
# information about spectrum. Important Note: since transceivers
|
||||
# attached to roadms are actually logical elements to simulate
|
||||
@@ -301,7 +295,7 @@ if __name__ == '__main__':
|
||||
network = load_network(args.network_filename,equipment)
|
||||
|
||||
# Build the network once using the default power defined in SI in eqpt config
|
||||
# power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
|
||||
# TODO power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
|
||||
# spacing, f_min and f_max
|
||||
p_db = equipment['SI']['default'].power_dbm
|
||||
|
||||
|
||||
@@ -121,7 +121,9 @@ class Result_element(Element):
|
||||
else:
|
||||
hop_type.append('not recorded')
|
||||
else:
|
||||
mode = 'no mode'
|
||||
# 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))
|
||||
@@ -400,28 +402,42 @@ def propagate_and_optimize_mode(path, req, equipment, show=False):
|
||||
baudrate_to_explore = list(set([m['baud_rate'] for m in equipment['Transceiver'][req.tsp].mode
|
||||
if float(m['baud_rate'])+12.5e9< req.spacing]))
|
||||
baudrate_to_explore = sorted(baudrate_to_explore, reverse=True)
|
||||
found_a_feasible_mode = False
|
||||
for b in baudrate_to_explore :
|
||||
modes_to_explore = [m for m in equipment['Transceiver'][req.tsp].mode
|
||||
if m['baud_rate'] == b]
|
||||
modes_to_explore = sorted(modes_to_explore,
|
||||
key = lambda x: x['bit_rate'], reverse=True)
|
||||
# step2 : computes propagation for each baudrate: stop and select the first that passes
|
||||
found_a_feasible_mode = False
|
||||
# TODO : the case of roll of is not included: for now use SI one
|
||||
si = create_input_spectral_information(
|
||||
req.frequency['min'], equipment['SI']['default'].roll_off,
|
||||
b, req.power, req.spacing, req.nb_channel)
|
||||
for el in path:
|
||||
si = el(si)
|
||||
if show :
|
||||
print(el)
|
||||
for m in modes_to_explore :
|
||||
if round(mean(path[-1].snr+lin2db(b/(12.5e9))),2) > m['OSNR'] :
|
||||
found_a_feasible_mode = True
|
||||
return path, m
|
||||
# if no feasible path were found
|
||||
return found_a_feasible_mode
|
||||
if baudrate_to_explore :
|
||||
# at least 1 baudrate can be tested wrt spacing
|
||||
for b in baudrate_to_explore :
|
||||
modes_to_explore = [m for m in equipment['Transceiver'][req.tsp].mode
|
||||
if m['baud_rate'] == b]
|
||||
modes_to_explore = sorted(modes_to_explore,
|
||||
key = lambda x: x['bit_rate'], reverse=True)
|
||||
# step2 : computes propagation for each baudrate: stop and select the first that passes
|
||||
found_a_feasible_mode = False
|
||||
# TODO : the case of roll of is not included: for now use SI one
|
||||
# TODO : if the loop in mode optimization does not have a feasible path, then bugs
|
||||
si = create_input_spectral_information(
|
||||
req.frequency['min'], equipment['SI']['default'].roll_off,
|
||||
b, req.power, req.spacing, req.nb_channel)
|
||||
for el in path:
|
||||
si = el(si)
|
||||
if show :
|
||||
print(el)
|
||||
for m in modes_to_explore :
|
||||
if round(mean(path[-1].snr+lin2db(b/(12.5e9))),2) > m['OSNR'] :
|
||||
found_a_feasible_mode = True
|
||||
return path, m
|
||||
else:
|
||||
mode = m
|
||||
# only get to this point if no budrate/mode staisfies OSNR requirement
|
||||
# returns the last propagated path and mode
|
||||
msg = f'Warning! Request {req.request_id}: no mode satisfies path SNR requirement.\n'
|
||||
print(msg)
|
||||
logger.info(msg)
|
||||
return [],None
|
||||
else :
|
||||
# no baudrate satisfying spacing
|
||||
msg = f'Warning! Request {req.request_id}: no baudrate satisfies spacing requirement.\n'
|
||||
print(msg)
|
||||
logger.info(msg)
|
||||
return path, None
|
||||
|
||||
|
||||
def jsontocsv(json_data,equipment,fileout):
|
||||
@@ -453,7 +469,7 @@ def jsontocsv(json_data,equipment,fileout):
|
||||
|
||||
# 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 !='no 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:
|
||||
@@ -471,9 +487,9 @@ def jsontocsv(json_data,equipment,fileout):
|
||||
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 = ''
|
||||
nb_tsp = ''
|
||||
pthbdbw = ''
|
||||
isok = False
|
||||
nb_tsp = 0
|
||||
pthbdbw = round(path_bandwidth*1e-9,2)
|
||||
rosnr = ''
|
||||
rsnr = ''
|
||||
rsnrb = ''
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
],
|
||||
"spacing": null,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null
|
||||
"output-power": null,
|
||||
"path_bandwidth": null
|
||||
}
|
||||
},
|
||||
"optimizations": {
|
||||
|
||||
@@ -97,3 +97,11 @@ def test_does_not_loop_back(net,eqpt,serv):
|
||||
break
|
||||
|
||||
assert test
|
||||
|
||||
# TODO : test that identical requests are correctly agregated
|
||||
# and reproduce disjunction vector as well as route constraints
|
||||
# check that requests with different parameters are not aggregated
|
||||
|
||||
# check that the total agregated bandwidth is the same after aggregation
|
||||
|
||||
#
|
||||
Reference in New Issue
Block a user