mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-01 18:47:48 +00:00
restore power management in transmission main
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
This commit is contained in:
@@ -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":[
|
||||
{
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user