Propagate power per band during autodesign

Target setting computation is done going through each element of the OMS
and computing resulting delta power after each amplifier element. In order
to account for different delta power per band (multi band autodesign), the
computation must be made per band. The previous introduction of a standard
name for bands ("CBAND", "LBAND") ensures a stable key to index these
delta power computation.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ida4b2486ebde4f2a1fb21a44458d1fe34a788d1f
This commit is contained in:
EstherLerouzic
2024-06-21 15:35:24 +02:00
committed by Esther Le Rouzic
parent bdcffc2a5e
commit 64a91256fc

View File

@@ -19,7 +19,7 @@ from gnpy.core.exceptions import ConfigurationError, NetworkTopologyError
from gnpy.core.utils import round2float, convert_length, psd2powerdbm, lin2db, watt2dbm, dbm2watt, automatic_nch, \ from gnpy.core.utils import round2float, convert_length, psd2powerdbm, lin2db, watt2dbm, dbm2watt, automatic_nch, \
find_common_range find_common_range
from gnpy.core.info import ReferenceCarrier, create_input_spectral_information from gnpy.core.info import ReferenceCarrier, create_input_spectral_information
from gnpy.core.parameters import SimParams, EdfaParams from gnpy.core.parameters import SimParams, EdfaParams, find_band_name, FrequencyBand
from gnpy.core.science_utils import RamanSolver from gnpy.core.science_utils import RamanSolver
@@ -569,43 +569,53 @@ def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elem
power_mode = equipment['Span']['default'].power_mode power_mode = equipment['Span']['default'].power_mode
next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver)) next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver))
for oms in next_oms: for oms in next_oms:
_design_bands = {find_band_name(FrequencyBand(f_min=e["f_min"], f_max=e["f_max"])): e
for e in this_node.per_degree_design_bands[oms.uid]}
oms_nodes = get_oms_edge_list(oms, network)
# go through all the OMS departing from the ROADM # go through all the OMS departing from the ROADM
prev_node = this_node prev_node = this_node
node = oms node = oms
if isinstance(this_node, elements.Transceiver): # initialize dp and prev_dp with roadm out target or transceiver power. Use design bands.
# todo change pref to a ref channel dp = {}
if equipment['SI']['default'].tx_power_dbm is not None: prev_dp = {}
this_node_out_power = equipment['SI']['default'].tx_power_dbm voa = {}
else: prev_voa = {}
this_node_out_power = pref_ch_db for band_name, band in _design_bands.items():
if isinstance(this_node, elements.Roadm): if isinstance(this_node, elements.Transceiver):
# get target power out from ROADM for the reference carrier based on equalization settings # todo change pref to a ref channel
this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid) if equipment['SI']['default'].tx_power_dbm is not None:
# use the target power on this degree this_node_out_power = equipment['SI']['default'].tx_power_dbm
prev_dp = this_node_out_power - pref_ch_db else:
dp = prev_dp this_node_out_power = pref_ch_db
prev_voa = 0 if isinstance(this_node, elements.Roadm):
voa = 0 # get target power out from ROADM for the reference carrier based on equalization settings
visited_nodes = [] this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid)
while not (isinstance(node, elements.Roadm) or isinstance(node, elements.Transceiver)): # use the target power on this degree
prev_dp[band_name] = this_node_out_power - pref_ch_db
dp[band_name] = prev_dp[band_name]
prev_voa[band_name] = 0
voa[band_name] = 0
for node, next_node in oms_nodes:
# go through all nodes in the OMS (loop until next Roadm instance) # go through all nodes in the OMS (loop until next Roadm instance)
next_node = get_next_node(node, network)
visited_nodes.append(node)
if next_node in visited_nodes:
raise NetworkTopologyError(f'Loop detected for {type(node).__name__} {node.uid}, '
+ 'please check network topology')
if isinstance(node, elements.Edfa): if isinstance(node, elements.Edfa):
dp, voa = set_one_amplifier(node, prev_node, next_node, power_mode, prev_voa, prev_dp, band_name, _ = next((n, b) for n, b in _design_bands.items())
pref_ch_db, pref_total_db, network, equipment, verbose) dp[band_name], voa[band_name] = set_one_amplifier(node, prev_node, next_node, power_mode,
prev_voa[band_name], prev_dp[band_name],
pref_ch_db, pref_total_db,
network, equipment, verbose)
elif isinstance(node, elements.RamanFiber): elif isinstance(node, elements.RamanFiber):
# this is to record the expected gain in Raman fiber in its .estimated_gain attribute. # this is to record the expected gain in Raman fiber in its .estimated_gain attribute.
_ = span_loss(network, node, equipment, input_power=pref_ch_db + dp) band_name, _ = next((n, b) for n, b in _design_bands.items())
if isinstance(node, elements.Multiband_amplifier): _ = span_loss(network, node, equipment, input_power=pref_ch_db + dp[band_name])
for amp in node.amplifiers.values(): elif isinstance(node, elements.Multiband_amplifier):
dp, voa = set_one_amplifier(amp, prev_node, next_node, power_mode, prev_voa, prev_dp, for band_name, amp in node.amplifiers.items():
pref_ch_db, pref_total_db, network, equipment, verbose) dp[band_name], voa[band_name] = \
prev_dp = dp set_one_amplifier(amp, prev_node, next_node, power_mode,
prev_voa = voa prev_voa[band_name], prev_dp[band_name],
pref_ch_db, pref_total_db, network, equipment, verbose)
prev_dp.update(**dp)
prev_voa.update(**voa)
prev_node = node prev_node = node
node = next_node node = next_node