restore power management in transmission main

Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
This commit is contained in:
Jean-Luc Auge
2018-07-13 17:35:39 +02:00
parent 4a756bf2a9
commit c6432e2c28
6 changed files with 88 additions and 52 deletions

View File

@@ -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":[
{

View File

@@ -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'])

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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]