From c6432e2c280ea5426f7ea9011034e92f69848221 Mon Sep 17 00:00:00 2001 From: Jean-Luc Auge Date: Fri, 13 Jul 2018 17:35:39 +0200 Subject: [PATCH] restore power management in transmission main Signed-off-by: Jean-Luc Auge --- examples/eqpt_config.json | 10 +++--- examples/path_requests_run.py | 1 + examples/transmission_main_example.py | 39 ++++++++++++++++------- gnpy/core/equipment.py | 46 +++++++++++++++------------ gnpy/core/network.py | 11 ++++--- gnpy/core/request.py | 33 ++++++++++++------- 6 files changed, 88 insertions(+), 52 deletions(-) diff --git a/examples/eqpt_config.json b/examples/eqpt_config.json index 5c2c6b7c..2fe8321d 100644 --- a/examples/eqpt_config.json +++ b/examples/eqpt_config.json @@ -37,7 +37,7 @@ } ], "Spans":[{ - "power_mode": false, + "power_mode": true, "max_length": 150, "length_units": "km", "max_loss": 28, @@ -52,11 +52,11 @@ }], "SI":[{ "f_min": 191.3e12, - "Nch": 80, + "f_max":196.1e12, "baud_rate": 32e9, - "spacing": 75e9, - "roll_off": 0.15, - "power": 1.2589e-3 + "spacing": 50e9, + "power": 1e-3, + "roll_off": 0.15 }], "Transceiver":[ { diff --git a/examples/path_requests_run.py b/examples/path_requests_run.py index e61ed3c8..cd1d4352 100644 --- a/examples/path_requests_run.py +++ b/examples/path_requests_run.py @@ -60,6 +60,7 @@ def requests_from_json(json_data,equipment): params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type'] params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode'] params['frequency'] = tsp_lib[params['trx_type']].frequency + #TODO Esther try: extra_params = next(m for m in tsp_lib[params['trx_type']].mode if m['format'] == params['trx_mode']) diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index 641e5cd9..286dce85 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -49,21 +49,34 @@ def plot_results(network, path, source, sink): def main(network, equipment, source, sink, req = None): + power_mode = equipment['Spans']['default'].power_mode + print('\n'.join([f'Power mode is set to {power_mode}', + f'=> it can be modified in eqpt_config.json - Spans'])) + + set_roadm_loss(network, equipment, False, 0) build_network(network, equipment=equipment) - - path = compute_constrained_path(network,req) + path = compute_constrained_path(network, req) + if power_mode: + set_edfa_dp(network, path) + spans = [s.length for s in path if isinstance(s, Fiber)] print(f'\nThere are {len(spans)} fiber spans over {sum(spans):.0f}m between {source.uid} and {sink.uid}') print(f'\nNow propagating between {source.uid} and {sink.uid}:') - - for p in range(0, 1): #change range to sweep results across several powers in dBm - req.power = db2lin(p)*1e-3 + + pref_span_db = lin2db(req.power*1e3) + bounds = range(0, 1) #power sweep + + for dp_db in bounds: + p_db = pref_span_db + dp_db + p = db2lin(p_db)*1e-3 + req.power = p print(f'\nPropagating with input power = {lin2db(req.power*1e3):.2f}dBm :') - propagate(path,req,equipment,show=True) - print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :') + propagate(path, req, equipment, show=True) + print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :') return path + parser = ArgumentParser() parser.add_argument('-e', '--equipment', type=Path, default=Path(__file__).parent / 'eqpt_config.json') @@ -137,13 +150,17 @@ if __name__ == '__main__': logger.info(f'sink = {args.sink!r}') params = {} - default_trx_params = {} + params['request_id'] = 0 + params['trx_type'] = '' + params['trx_mode'] = '' params['source'] = source.uid params['destination'] = sink.uid params['nodes_list'] = [sink.uid] - if args.power: params['power'] = db2lin(args.power)*1e-3 - default_trx_params = {'baudrate'=33e9} - trx_params = trx_mode_params(equipment, '', '', default_trx_params) + params['loose_list'] = ['strict'] + params['format'] = '' + trx_params = trx_mode_params(equipment) + if args.power: + trx_params['power'] = db2lin(float(args.power))*1e-3 params.update(trx_params) req = Path_request(**params) path = main(network, equipment, source, sink, req) diff --git a/gnpy/core/equipment.py b/gnpy/core/equipment.py index 9d99b417..3be3d916 100644 --- a/gnpy/core/equipment.py +++ b/gnpy/core/equipment.py @@ -20,7 +20,7 @@ Fiber = namedtuple('Fiber', 'type_variety dispersion gamma') Spans = namedtuple('Spans', 'power_mode max_length length_units max_loss padding EOL con_loss') Transceiver = namedtuple('Transceiver', 'type_variety frequency mode') Roadms = namedtuple('Roadms', 'gain_mode_default_loss power_mode_pref') -SI = namedtuple('SI', 'f_min Nch baud_rate spacing roll_off power') +SI = namedtuple('SI', 'f_min f_max baud_rate spacing roll_off power ') EdfaBase = namedtuple( 'EdfaBase', 'type_variety gain_flatmax gain_min p_max nf_min nf_max' @@ -109,35 +109,41 @@ def edfa_nf(gain, variety_type, equipment): nf_avg = polyval(edfa.nf_fit_coeff, dg) return nf_avg + pad # input VOA = 1 for 1 NF degradation -def trx_mode_params(equipment, trx_type_variety, trx_mode, default_params={}, error_message=false): -"""return the trx and SI parameters from eqpt_config for a given type_variety and mode (ie format)""" + +def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=False): + """return the trx and SI parameters from eqpt_config for a given type_variety and mode (ie format)""" trx_params = {} try: - mode_params = next(mode for trx in equipment['Transceiver'] \ - if trx['type_variety'] == trx_type_variety \ - for mode in trx['mode'] \ + trxs = equipment['Transceiver'] + mode_params = next(mode for trx in trxs \ + if trx == trx_type_variety \ + for mode in trxs[trx].mode \ if mode['format'] == trx_mode) frequency_params = equipment['Transceiver'][trx_type_variety]['frequency'] trx_params = {**mode_params, **frequency_params} + trx_params['spacing'] = automatic_spacing(trx_params['baudrate']) except StopIteration : if error_message: - print f'could not find tsp : {trx_type_variety} with mode: {trx_mode} in eqpt library' + print(f'could not find tsp : {trx_type_variety} with mode: {trx_mode} in eqpt library') exit - else - trx_params['frequency'] = default_params.get('frequency',{'min': 191.35e12, 'max': 196.10e12}) - trx_params['baudrate'] = default_params.get('baudrate', 32e9) - trx_params['OSNR'] = default_params.get('OSNR', 15) - trx_params['bit_rate'] = default_params.get('bit_rate', 100e9) - trx_params['spacing'] = default_params.get('spacing', automatic_spacing(trx_params['baudrate'])) - trx_params['nb_channel'] = default_params.get('spacing', automatic_nch( - trx_params['frequency']['min'], - trx_params['frequency']['max'], - trx_params['spacing'])) + else: + default_si_data = equipment['SI']['default'] + trx_params['frequency'] = {'min': default_si_data.f_min, 'max': default_si_data.f_max} + trx_params['baudrate'] = default_si_data.baud_rate + trx_params['spacing'] = default_si_data.spacing + #TODO remove ugly hard coded defaults: + trx_params['OSNR'] = 15 + trx_params['bit_rate'] = 100 + + trx_params['power'] = default_si_data.power + trx_params['nb_channel'] = automatic_nch(trx_params['frequency']['min'], + trx_params['frequency']['max'], + trx_params['spacing']) return trx_params def automatic_spacing(baud_rate): -"""return the min possible channel spacing for a given baud rate""" - spacing_list = [(38,50), (67,75), (92,100)] #list of possible tuples + """return the min possible channel spacing for a given baud rate""" + spacing_list = [(38e9,50e9), (67e9,75e9), (92e9,100e9)] #list of possible tuples #[(max_baud_rate, spacing_for_this_baudrate)] acceptable_spacing_list = list(filter(lambda x : x[0]>baud_rate, spacing_list)) if len(acceptable_spacing_list) < 1: @@ -148,7 +154,7 @@ def automatic_spacing(baud_rate): return min(acceptable_spacing_list, key=itemgetter(0))[1] def automatic_nch(f_min, f_max, spacing): - return (f_max - fmin)//spacing + return int((f_max - f_min)//spacing) def load_equipment(filename): json_data = load_json(filename) diff --git a/gnpy/core/network.py b/gnpy/core/network.py index 4b5eeaff..08651f4b 100644 --- a/gnpy/core/network.py +++ b/gnpy/core/network.py @@ -76,16 +76,19 @@ def select_edfa(ingress_span_loss, equipment): #chose the amp with the best NF among the acceptable ones: return min(acceptable_edfa_list, key=itemgetter(2))[0] -def set_roadm_loss(path_roadms, power_mode, roadm_loss, default_roadm_loss): - for roadm in path_roadms: +def set_roadm_loss(network, equipment, power_mode, roadm_loss): + roadms = [roadm for roadm in network if isinstance(roadm, Roadm)] + default_roadm_loss = equipment['Roadms']['default'].gain_mode_default_loss + for roadm in roadms: if power_mode: roadm.loss = roadm_loss elif roadm.loss == None: roadm.loss = default_roadm_loss -def set_edfa_dp(network, amps): +def set_edfa_dp(network, path): + path_amps = [amp for amp in path if isinstance(amp, Edfa)] prev_dp = 0 - for amp in amps: + for amp in path_amps: next_node = [n for n in network.successors(amp)][0] prev_node = [n for n in network.predecessors(amp)][0] prev_node_loss = span_loss(network, prev_node) diff --git a/gnpy/core/request.py b/gnpy/core/request.py index 4798b0df..8d9c58b6 100644 --- a/gnpy/core/request.py +++ b/gnpy/core/request.py @@ -34,18 +34,27 @@ from gnpy.core.info import create_input_spectral_information, SpectralInformatio from copy import copy, deepcopy from numpy import log10 -RequestParams = namedtuple('RequestParams','request_id source destination trx_type \ - trx_mode nodes_list loose_list spacing power nb_channel frequency \ - mode baudrate OSNR bit_rate') +RequestParams = namedtuple('RequestParams','request_id source destination trx_type'+ +' trx_mode nodes_list loose_list spacing power nb_channel frequency format baudrate OSNR bit_rate') -class Path_request(RequestParams): - def __new__(cls, request_id=0, source='', destination='', trx_type='', - trx_mode='', nodes_list='', loose_list=['strict'], - spacing=50, power=1e-3, nb_channel=80, frequency={'min': 191.35e12, 'max': 196.10e12}, - mode ='', baudrate=32, OSNR=15, bit_rate=100): - return super().__new__(cls, request_id, source, destination, trx_type, - trx_mode, nodes_list, loose_list, spacing, power, nb_channel, frequency, - mode, baudrate, OSNR, bit_rate) +class Path_request: + def __init__(self, *args, **params): + params = RequestParams(**params) + self.request_id = params.request_id + self.source = params.source + self.destination = params.destination + self.tsp = params.trx_type + self.tsp_mode = params.trx_mode + self.baudrate = params.baudrate + self.nodes_list = params.nodes_list + self.loose_list = params.loose_list + self.spacing = params.spacing + self.power = params.power + self.nb_channel = params.nb_channel + self.frequency = params.frequency + self.format = params.format + self.OSNR = params.OSNR + self.bit_rate = params.bit_rate def __str__(self): return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', @@ -120,10 +129,10 @@ class Result_element(Element): return self.pathresult def compute_constrained_path(network, req): + print('!!!!',req) trx = [n for n in network.nodes() if isinstance(n, Transceiver)] roadm = [n for n in network.nodes() if isinstance(n, Roadm)] edfa = [n for n in network.nodes() if isinstance(n, Edfa)] - source = next(el for el in trx if el.uid == req.source) # start the path with its source total_path = [source]