From 64a91256fcc22076c9c74f07022e8780d3d5767c Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Fri, 21 Jun 2024 15:35:24 +0200 Subject: [PATCH] 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 Change-Id: Ida4b2486ebde4f2a1fb21a44458d1fe34a788d1f --- gnpy/core/network.py | 72 +++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/gnpy/core/network.py b/gnpy/core/network.py index ff600ae15..0898d43ee 100644 --- a/gnpy/core/network.py +++ b/gnpy/core/network.py @@ -19,7 +19,7 @@ from gnpy.core.utils import round2float, convert_length, psd2powerdbm, lin2db, watt2dbm, dbm2watt, automatic_nch, \ find_common_range 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 @@ -569,43 +569,53 @@ def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elem power_mode = equipment['Span']['default'].power_mode next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver)) 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 prev_node = this_node node = oms - if isinstance(this_node, elements.Transceiver): - # todo change pref to a ref channel - if equipment['SI']['default'].tx_power_dbm is not None: - this_node_out_power = equipment['SI']['default'].tx_power_dbm - else: - this_node_out_power = pref_ch_db - if isinstance(this_node, elements.Roadm): - # get target power out from ROADM for the reference carrier based on equalization settings - this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid) - # use the target power on this degree - prev_dp = this_node_out_power - pref_ch_db - dp = prev_dp - prev_voa = 0 - voa = 0 - visited_nodes = [] - while not (isinstance(node, elements.Roadm) or isinstance(node, elements.Transceiver)): + # initialize dp and prev_dp with roadm out target or transceiver power. Use design bands. + dp = {} + prev_dp = {} + voa = {} + prev_voa = {} + for band_name, band in _design_bands.items(): + if isinstance(this_node, elements.Transceiver): + # todo change pref to a ref channel + if equipment['SI']['default'].tx_power_dbm is not None: + this_node_out_power = equipment['SI']['default'].tx_power_dbm + else: + this_node_out_power = pref_ch_db + if isinstance(this_node, elements.Roadm): + # get target power out from ROADM for the reference carrier based on equalization settings + this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid) + # 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) - 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): - dp, voa = set_one_amplifier(node, prev_node, next_node, power_mode, prev_voa, prev_dp, - pref_ch_db, pref_total_db, network, equipment, verbose) + band_name, _ = next((n, b) for n, b in _design_bands.items()) + 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): # 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) - if isinstance(node, elements.Multiband_amplifier): - for amp in node.amplifiers.values(): - dp, voa = set_one_amplifier(amp, prev_node, next_node, power_mode, prev_voa, prev_dp, - pref_ch_db, pref_total_db, network, equipment, verbose) - prev_dp = dp - prev_voa = voa + band_name, _ = next((n, b) for n, b in _design_bands.items()) + _ = span_loss(network, node, equipment, input_power=pref_ch_db + dp[band_name]) + elif isinstance(node, elements.Multiband_amplifier): + for band_name, amp in node.amplifiers.items(): + dp[band_name], voa[band_name] = \ + set_one_amplifier(amp, prev_node, next_node, power_mode, + 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 node = next_node