Feat: Use a reference channel per OMS instead of total power for design

Correctly uses the oms band and spacing for computing the nb of channel
and total power for design per band.
In order to keep the SI values as reference, introduce a new parameter
in SI to indicate wether to use this feature or not.

If "use_si_channel_count_for_design": true, then the f_min, f_max and spacing
from SI are used for all OMSes
else, the f_min, f_max, spacing defined per OMS (design_bands) is used.

This impacts tests where the artificial C-band boudaries were hardcoded, and
it also has an impact on performances when SI's defined nb of channels is larger
than the one defined per OMS. In this case the design was considering a larger
total power than the one finally propagated which resulted in reduced performance.
This feature now corrects this case (if "use_si_channel_count_for_design": false
which is the default setting). Overall autodesign are thus improved.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I471a2c45200894ca354c90b46b662f42414b48ad

tous les test marche et les jeu de tests aussi.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: If25b47aa10f97301fde7f17daa2a9478aed46db2
This commit is contained in:
EstherLerouzic
2025-02-18 09:05:56 +01:00
parent f447c908bc
commit 56e615c713
31 changed files with 743 additions and 302 deletions

View File

@@ -878,7 +878,7 @@ def filter_edfa_list_based_on_targets(uid: str, edfa_eqpt: dict, power_target: f
def preselect_multiband_amps(uid: str, _amplifiers: dict, prev_node: ELEMENT_TYPES, next_node: ELEMENT_TYPES,
power_mode: bool, prev_voa: dict, prev_dp: dict,
pref_total_db: float, network: DiGraph, equipment: dict, restrictions: List,
pref_total_db: dict, network: DiGraph, equipment: dict, restrictions: List,
_design_bands: dict, deviation_db: dict, tilt_target: dict):
"""Preselects multiband amplifiers eligible based on power, gain, and tilt targets across all bands.
@@ -939,7 +939,7 @@ def preselect_multiband_amps(uid: str, _amplifiers: dict, prev_node: ELEMENT_TYP
# get the target gain, power and tilt based on previous propagation
gain_target, power_target, _tilt_target, _, _, _ = \
compute_gain_power_and_tilt_target(amp, prev_node, next_node, power_mode, prev_voa[band], prev_dp[band],
pref_total_db, network, equipment, deviation_db[band], tilt_target[band])
pref_total_db[band], network, equipment, deviation_db[band], tilt_target[band])
_selection = [a.variety
for a in filter_edfa_list_based_on_targets(uid, edfa_eqpt, power_target, gain_target,
_tilt_target, target_extended_gain)]
@@ -1151,7 +1151,7 @@ def get_node_restrictions(node: Union[elements.Edfa, elements.Multiband_amplifie
def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elements.Transceiver], equipment: dict,
pref_ch_db: float, pref_total_db: float, verbose: bool):
pref_ch_db: float, verbose: bool, reference_channel):
"""Configures the egress amplifiers for a given node in the network.
Go through each link starting from this_node until next Roadm or Transceiver and
@@ -1200,9 +1200,10 @@ def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elem
prev_dp = {}
voa = {}
prev_voa = {}
pref_total_db = {}
for band_name, band in _design_bands.items():
this_node_out_power = None
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:
@@ -1215,6 +1216,9 @@ def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elem
dp[band_name] = prev_dp[band_name]
prev_voa[band_name] = 0
voa[band_name] = 0
nb_channels_per_band = reference_channel.nb_channel if reference_channel.nb_channel \
else automatic_nch(band['f_min'], band['f_max'], band['spacing'])
pref_total_db[band_name] = pref_ch_db + lin2db(nb_channels_per_band)
for node, next_node in oms_nodes:
# go through all nodes in the OMS
@@ -1232,7 +1236,7 @@ def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elem
+ 'and the restrictions (roadm or amplifier restictions)')
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,
pref_ch_db, pref_total_db[band_name],
network, restrictions, equipment, verbose)
elif isinstance(node, elements.RamanFiber):
# this is to record the expected gain in Raman fiber in its .estimated_gain attribute.
@@ -1259,8 +1263,8 @@ def set_egress_amplifier(network: DiGraph, this_node: Union[elements.Roadm, elem
and equipment['Edfa'][n].f_max >= _design_bands[band_name]['f_max']]
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, _restrictions, equipment, verbose,
prev_voa[band_name], prev_dp[band_name], pref_ch_db, pref_total_db[band_name],
network, _restrictions, equipment, verbose,
deviation_db=deviation_db[band_name], tilt_target=tilt_target[band_name])
amps_type_varieties = [a.type_variety for a in node.amplifiers.values()]
try:
@@ -2070,7 +2074,7 @@ def add_missing_fiber_attributes(network: DiGraph, equipment: dict):
add_fiber_padding(network, fibers, default_span_data.padding, equipment)
def build_network(network: DiGraph, equipment: dict, pref_ch_db: float, pref_total_db: float,
def build_network(network: DiGraph, equipment: dict, reference_channel,
set_connector_losses: bool = True, verbose: bool = True):
"""Sets the ROADM equalization targets and amplifier gain and power.
@@ -2111,8 +2115,9 @@ def build_network(network: DiGraph, equipment: dict, pref_ch_db: float, pref_tot
for transceiver in transceivers:
set_per_degree_design_band(transceiver, network, equipment)
# then set amplifiers gain, delta_p and out_voa on each OMS
pref_ch_db = watt2dbm(reference_channel.power)
for roadm in roadms + transceivers:
set_egress_amplifier(network, roadm, equipment, pref_ch_db, pref_total_db, verbose)
set_egress_amplifier(network, roadm, equipment, pref_ch_db, verbose, reference_channel)
for roadm in roadms:
set_roadm_input_powers(network, roadm, equipment, pref_ch_db)
set_roadm_internal_paths(roadm, network)
@@ -2145,10 +2150,9 @@ def design_network(reference_channel, network: DiGraph, equipment: Dict, set_con
------
- The function calculates the reference total power based on the number of channels and their power levels.
"""
pref_ch_db = watt2dbm(reference_channel.power) # reference channel power
# reference total power (limited to C band till C+L autodesign is not solved)
designed_nb_channel = min(reference_channel.nb_channel,
automatic_nch(191.0e12, 196.2e12, reference_channel.spacing))
pref_total_db = pref_ch_db + lin2db(designed_nb_channel)
build_network(network, equipment, pref_ch_db, pref_total_db, set_connector_losses=set_connector_losses,
if verbose:
logger.info(f'\nReference used for design: (Input optical power reference in span = {watt2dbm(reference_channel.power):.2f}dBm\n' # noqa E501
+ f' spacing = {reference_channel.spacing * 1e-9:.3f}GHz\n'
+ f' nb_channels = {reference_channel.nb_channel}')
build_network(network, equipment, reference_channel, set_connector_losses=set_connector_losses,
verbose=verbose)

View File

@@ -357,7 +357,8 @@
"tx_power_dbm": 0,
"roll_off": 0.15,
"tx_osnr": 40,
"sys_margins": 2
"sys_margins": 2,
"use_si_channel_count_for_design": true
}
],
"Transceiver": [

View File

@@ -70,7 +70,8 @@ class _JsonThing:
clean_kwargs = {k: v for k, v in kwargs.items() if v != ''}
for k, v in default_values.items():
setattr(self, k, clean_kwargs.get(k, v))
if k not in clean_kwargs and name != 'Amp' and v is not None and v != []:
disable_warning_keys = ['use_si_channel_count_for_design']
if k not in clean_kwargs and name != 'Amp' and v is not None and v != [] and k not in disable_warning_keys:
# do not show this warning if the default value is None
msg = f'\n\tWARNING missing {k} attribute in eqpt_config.json[{name}]' \
+ f'\n\tdefault value is {k} = {v}\n'
@@ -90,7 +91,8 @@ class SI(_JsonThing):
"roll_off": 0.15,
"tx_osnr": 45,
"sys_margins": 0,
"tx_power_dbm": None # optional value in SI
"tx_power_dbm": None, # optional value in SI
"use_si_channel_count_for_design": False # optional value in SI
}
def __init__(self, **kwargs):

View File

@@ -90,12 +90,12 @@ def designed_network(equipment: dict, network: DiGraph, source: str = None, dest
'format': '',
'path_bandwidth': 0,
'effective_freq_slot': None,
'nb_channel': automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max,
equipment['SI']['default'].spacing),
'nb_channel': None if equipment['SI']['default'].use_si_channel_count_for_design is False
else automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max,
equipment['SI']['default'].spacing),
'power': dbm2watt(equipment['SI']['default'].power_dbm),
'tx_power': None
'tx_power': dbm2watt(equipment['SI']['default'].power_dbm)
}
params['tx_power'] = dbm2watt(equipment['SI']['default'].power_dbm)
if equipment['SI']['default'].tx_power_dbm is not None:
# use SI tx_power if present
params['tx_power'] = dbm2watt(equipment['SI']['default'].tx_power_dbm)
@@ -110,14 +110,14 @@ def designed_network(equipment: dict, network: DiGraph, source: str = None, dest
# use si as reference channel
reference_channel = PathRequest(**params)
# temporary till multiband design feat is available: do not design for L band
reference_channel.nb_channel = min(params['nb_channel'], automatic_nch(191.2e12, 196.0e12, params['spacing']))
if service_req:
# use service_req as reference channel with si tx_power if service_req tx_power is None
if service_req.tx_power is None:
service_req.tx_power = params['tx_power']
reference_channel = service_req
reference_channel = deepcopy(service_req)
if equipment['SI']['default'].use_si_channel_count_for_design is False:
reference_channel.nb_channel = None
design_network(reference_channel, network, equipment, set_connector_losses=True, verbose=True)

View File

@@ -38,13 +38,17 @@ from copy import deepcopy
from csv import writer
from math import ceil
LOGGER = getLogger(__name__)
RequestParams = namedtuple('RequestParams', 'request_id source destination bidir trx_type'
' trx_mode nodes_list loose_list spacing power nb_channel f_min'
' f_max format baud_rate OSNR penalties bit_rate'
' roll_off tx_osnr min_spacing cost path_bandwidth effective_freq_slot'
' equalization_offset_db, tx_power')
DisjunctionParams = namedtuple('DisjunctionParams', 'disjunction_id relaxable link_diverse'
' node_diverse disjunctions_req')
@@ -385,7 +389,6 @@ def propagate(path, req, equipment):
path[-1].calc_penalties(req.penalties)
return si
def propagate_and_optimize_mode(path, req, equipment):
# if mode is unknown : loops on the modes starting from the highest baudrate fiting in the
# step 1: create an ordered list of modes based on baudrate and power offset

View File

@@ -3,6 +3,10 @@ WARNING gnpy.tools.json_io:json_io.py
WARNING missing type_variety attribute in eqpt_config.json[Roadm]
default value is type_variety = default
INFO gnpy.core.network:network.py
Reference used for design: (Input optical power reference in span = 0.00dBm
spacing = 50.000GHz
nb_channels = 76
INFO gnpy.tools.json_io:json_io.py Automatically converting requests from XLS to JSON
INFO gnpy.tools.worker_utils:worker_utils.py List of disjunctions:
[Disjunction 3

View File

@@ -3,6 +3,10 @@ WARNING gnpy.tools.json_io:json_io.py
WARNING missing type_variety attribute in eqpt_config.json[Roadm]
default value is type_variety = default
INFO gnpy.core.network:network.py
Reference used for design: (Input optical power reference in span = 0.00dBm
spacing = 50.000GHz
nb_channels = 76
INFO gnpy.tools.worker_utils:worker_utils.py List of disjunctions:
[]
INFO gnpy.tools.worker_utils:worker_utils.py Aggregating similar requests

View File

@@ -6,6 +6,10 @@ WARNING gnpy.tools.json_io:json_io.py
WARNING gnpy.tools.json_io:json_io.py
Equipment file extra_eqpt_config.json: duplicate equipment entry found: Transceiver-ZR400G
INFO gnpy.core.network:network.py
Reference used for design: (Input optical power reference in span = 0.00dBm
spacing = 50.000GHz
nb_channels = 76
INFO gnpy.tools.worker_utils:worker_utils.py List of disjunctions:
[]
INFO gnpy.tools.worker_utils:worker_utils.py Aggregating similar requests

View File

@@ -4,6 +4,10 @@ WARNING gnpy.tools.json_io:json_io.py
INFO gnpy.tools.cli_examples:cli_examples.py source = 'trx Brest_KLA'
INFO gnpy.tools.cli_examples:cli_examples.py destination = 'trx Rennes_STA'
INFO gnpy.core.network:network.py
Reference used for design: (Input optical power reference in span = 3.00dBm
spacing = 50.000GHz
nb_channels = None
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Lorient_KMA to Loudeac
is beyond all available amplifiers capabilities and/or extended_gain_range:

View File

@@ -0,0 +1,44 @@
WARNING gnpy.tools.json_io:json_io.py
WARNING missing type_variety attribute in eqpt_config.json[Roadm]
default value is type_variety = default
WARNING gnpy.tools.convert:convert.py missing header delta p
WARNING gnpy.tools.convert:convert.py missing header delta p
INFO gnpy.tools.cli_examples:cli_examples.py source = Transceiver(uid='trx Lorient_KMA', osnr_ase_01nm=None, osnr_ase=None, osnr_nli=None, snr=None, chromatic_dispersion=None, pmd=None, pdl=None, latency=None, penalties={})
INFO gnpy.tools.cli_examples:cli_examples.py destination = Transceiver(uid='trx Brest_KLA', osnr_ase_01nm=None, osnr_ase=None, osnr_nli=None, snr=None, chromatic_dispersion=None, pmd=None, pdl=None, latency=None, penalties={})
INFO gnpy.core.network:network.py
Reference used for design: (Input optical power reference in span = 0.00dBm
spacing = 50.000GHz
nb_channels = None
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Lannion_CAS to Stbrieuc
is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 20.0dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Stbrieuc to Rennes_STA
is below user specified amplifier std_medium_gain
min gain: 15dB ; required gain: 12.0dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Lannion_CAS to Morlaix
is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 20.5dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node west edfa in Lannion_CAS to Corlay
is above user specified amplifier test
max flat gain: 25dB ; required gain: 28.0dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Brest_KLA to Quimper
is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 20.0dB. Please check amplifier type.
INFO gnpy.tools.orange_worker_utils:orange_worker_utils.py Power mode is set to True=> it can be modified in eqpt_config.json - Span
INFO gnpy.tools.orange_worker_utils:orange_worker_utils.py Now propagating between trx Lorient_KMA and trx Brest_KLA
INFO gnpy.tools.orange_worker_utils:orange_worker_utils.py
Channels propagating: (Input optical power deviation in span = 0.00dB,
spacing = 50.00GHz,
transceiver output power = 0.00dBm,
nb_channels = 96)

View File

@@ -4,6 +4,10 @@ WARNING gnpy.tools.json_io:json_io.py
INFO gnpy.tools.cli_examples:cli_examples.py source = 'trx Lannion_CAS'
INFO gnpy.tools.cli_examples:cli_examples.py destination = 'trx Lorient_KMA'
INFO gnpy.core.network:network.py
Reference used for design: (Input optical power reference in span = 3.00dBm
spacing = 50.000GHz
nb_channels = None
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Lorient_KMA to Loudeac
is beyond all available amplifiers capabilities and/or extended_gain_range:

View File

@@ -7,7 +7,7 @@ There are 3 fiber spans over 240 km between trx Site_A and trx Site_D
Now propagating between trx Site_A and trx Site_D:
Reference used for design: (Input optical power reference in span = 0.00dBm,
spacing = 50.00GHz
nb_channels = 76)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = cband: 0.00, lband: 0.00dB,
spacing = cband: 50.00, lband: 50.00GHz,
@@ -33,17 +33,17 @@ Roadm roadm Site_A
Multiband_amplifier east edfa in Site_A to Site_B
type_variety: std_medium_gain_multiband
type_variety: std_medium_gain_C type_variety: std_medium_gain_L
effective gain(dB): 20.90 effective gain(dB): 22.19
effective gain(dB): 20.90 effective gain(dB): 22.43
(before att_in and before output VOA) (before att_in and before output VOA)
tilt-target(dB) 0.00 tilt-target(dB) 0.00
noise figure (dB): 6.38 noise figure (dB): 6.19
noise figure (dB): 6.38 noise figure (dB): 6.17
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): -1.08 Power In (dBm): -1.49
Power Out (dBm): 19.83 Power Out (dBm): 20.71
Delta_P (dB): 0.90 Delta_P (dB): 2.19
Power Out (dBm): 19.83 Power Out (dBm): 20.95
Delta_P (dB): 0.90 Delta_P (dB): 2.43
target pch (dBm): 0.90 target pch (dBm): 3.00
actual pch out (dBm): -2.09 actual pch out (dBm): -0.80
actual pch out (dBm): -2.09 actual pch out (dBm): -0.57
output VOA (dB): 3.00 output VOA (dB): 3.00
Fiber fiber (Site_A → Site_B)-
type_variety: SSMF
@@ -53,7 +53,7 @@ Fiber fiber (Site_A → Site_B)-
(includes conn loss (dB) in: 0.00 out: 0.00)
(conn loss out includes EOL margin defined in eqpt_config.json)
reference pch out (dBm): -17.10
actual pch out (dBm): cband: -17.09, lband: -15.80
actual pch out (dBm): cband: -17.09, lband: -15.56
Multiband_amplifier east edfa in Site_B to Site_C
type_variety: std_medium_gain_multiband
type_variety: std_medium_gain_C type_variety: std_medium_gain_L
@@ -63,11 +63,11 @@ Multiband_amplifier east edfa in Site_B to Site_C
noise figure (dB): 7.38 noise figure (dB): 7.38
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): 1.83 Power In (dBm): 2.71
Power Out (dBm): 19.84 Power Out (dBm): 20.72
Delta_P (dB): 0.90 Delta_P (dB): 2.19
Power In (dBm): 1.83 Power In (dBm): 2.95
Power Out (dBm): 19.84 Power Out (dBm): 20.95
Delta_P (dB): 0.90 Delta_P (dB): 2.43
target pch (dBm): 0.90 target pch (dBm): 3.00
actual pch out (dBm): -2.09 actual pch out (dBm): -0.79
actual pch out (dBm): -2.09 actual pch out (dBm): -0.56
output VOA (dB): 3.00 output VOA (dB): 3.00
Fiber fiber (Site_B → Site_C)-
type_variety: SSMF
@@ -77,7 +77,7 @@ Fiber fiber (Site_B → Site_C)-
(includes conn loss (dB) in: 0.00 out: 0.00)
(conn loss out includes EOL margin defined in eqpt_config.json)
reference pch out (dBm): -18.90
actual pch out (dBm): cband: -18.88, lband: -17.59
actual pch out (dBm): cband: -18.88, lband: -17.36
Multiband_amplifier east edfa in Site_C to Site_D
type_variety: std_medium_gain_multiband
type_variety: std_medium_gain_C type_variety: std_medium_gain_L
@@ -87,11 +87,11 @@ Multiband_amplifier east edfa in Site_C to Site_D
noise figure (dB): 6.63 noise figure (dB): 6.63
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): 0.04 Power In (dBm): 0.92
Power Out (dBm): 19.84 Power Out (dBm): 20.72
Delta_P (dB): 0.90 Delta_P (dB): 2.19
Power In (dBm): 0.04 Power In (dBm): 1.16
Power Out (dBm): 19.84 Power Out (dBm): 20.96
Delta_P (dB): 0.90 Delta_P (dB): 2.43
target pch (dBm): 0.90 target pch (dBm): 3.00
actual pch out (dBm): -2.08 actual pch out (dBm): -0.79
actual pch out (dBm): -2.08 actual pch out (dBm): -0.55
output VOA (dB): 3.00 output VOA (dB): 3.00
Fiber fiber (Site_C → Site_D)-
type_variety: SSMF
@@ -101,7 +101,7 @@ Fiber fiber (Site_C → Site_D)-
(includes conn loss (dB) in: 0.00 out: 0.00)
(conn loss out includes EOL margin defined in eqpt_config.json)
reference pch out (dBm): -20.80
actual pch out (dBm): cband: -20.78, lband: -19.49
actual pch out (dBm): cband: -20.78, lband: -19.25
Multiband_amplifier west edfa in Site_D to Site_C
type_variety: std_medium_gain_multiband
type_variety: std_medium_gain_C type_variety: std_medium_gain_L
@@ -111,23 +111,23 @@ Multiband_amplifier west edfa in Site_D to Site_C
noise figure (dB): 6.25 noise figure (dB): 6.25
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): -1.85 Power In (dBm): -0.97
Power Out (dBm): 19.85 Power Out (dBm): 20.73
Delta_P (dB): 0.90 Delta_P (dB): 2.19
Power In (dBm): -1.85 Power In (dBm): -0.74
Power Out (dBm): 19.85 Power Out (dBm): 20.97
Delta_P (dB): 0.90 Delta_P (dB): 2.43
target pch (dBm): 0.90 target pch (dBm): 3.00
actual pch out (dBm): -2.07 actual pch out (dBm): -0.78
actual pch out (dBm): -2.07 actual pch out (dBm): -0.54
output VOA (dB): 3.00 output VOA (dB): 3.00
Roadm roadm Site_D
Type_variety: default
Reference loss (dB): 17.90
Actual loss (dB): cband: 17.93, lband: 19.22
Actual loss (dB): cband: 17.93, lband: 19.46
Reference pch out (dBm): -20.00
Actual pch out (dBm): cband: -20.00, lband: -20.00
Transceiver trx Site_D
GSNR (0.1nm, dB): cband: 24.89, lband: 25.36
GSNR (signal bw, dB): cband: 20.80, lband: 21.28
OSNR ASE (0.1nm, dB): cband: 25.55, lband: 26.51
OSNR ASE (signal bw, dB): cband: 21.47, lband: 22.43
GSNR (0.1nm, dB): cband: 24.87, lband: 25.37
GSNR (signal bw, dB): cband: 20.79, lband: 21.28
OSNR ASE (0.1nm, dB): cband: 25.55, lband: 26.65
OSNR ASE (signal bw, dB): cband: 21.47, lband: 22.57
CD (ps/nm): 4008.00
PMD (ps): 0.62
PDL (dB): 0.00
@@ -139,155 +139,155 @@ Transmission result for input optical power reference in span = 0.00 dBm:
The GSNR per channel at the end of the line is:
Ch. # Channel frequency (THz) Channel power (dBm) OSNR ASE (signal bw, dB) SNR NLI (signal bw, dB) GSNR (signal bw, dB)
1 186.55000 -20.03 22.46 29.10 21.61
2 186.60000 -20.03 22.46 28.59 21.51
3 186.65000 -20.03 22.46 28.36 21.47
4 186.70000 -20.03 22.46 28.22 21.44
5 186.75000 -20.03 22.46 28.12 21.41
6 186.80000 -20.03 22.46 28.04 21.40
7 186.85000 -20.03 22.46 27.98 21.38
8 186.90000 -20.03 22.45 27.92 21.37
9 186.95000 -20.03 22.45 27.88 21.36
10 187.00000 -20.03 22.45 27.84 21.35
11 187.05000 -20.03 22.45 27.80 21.34
12 187.10000 -20.03 22.45 27.77 21.33
13 187.15000 -20.03 22.45 27.74 21.32
14 187.20000 -20.03 22.45 27.71 21.32
15 187.25000 -20.03 22.45 27.69 21.31
16 187.30000 -20.03 22.45 27.67 21.31
17 187.35000 -20.03 22.45 27.65 21.30
18 187.40000 -20.03 22.44 27.63 21.29
19 187.45000 -20.03 22.44 27.61 21.29
20 187.50000 -20.03 22.44 27.60 21.29
21 187.55000 -20.03 22.44 27.58 21.28
22 187.60000 -20.03 22.44 27.57 21.28
23 187.65000 -20.03 22.44 27.55 21.27
24 187.70000 -20.03 22.44 27.54 21.27
25 187.75000 -20.03 22.44 27.53 21.27
26 187.80000 -20.03 22.44 27.52 21.26
27 187.85000 -20.03 22.44 27.51 21.26
28 187.90000 -20.03 22.43 27.50 21.26
29 187.95000 -20.03 22.43 27.49 21.25
30 188.00000 -20.03 22.43 27.48 21.25
31 188.05000 -20.03 22.43 27.47 21.25
32 188.10000 -20.03 22.43 27.47 21.25
33 188.15000 -20.03 22.43 27.46 21.24
34 188.20000 -20.03 22.43 27.45 21.24
35 188.25000 -20.03 22.43 27.45 21.24
36 188.30000 -20.03 22.43 27.44 21.24
37 188.35000 -20.03 22.43 27.44 21.23
38 188.40000 -20.03 22.42 27.43 21.23
39 188.45000 -20.03 22.42 27.43 21.23
40 188.50000 -20.03 22.42 27.43 21.23
41 188.55000 -20.03 22.42 27.42 21.23
42 188.60000 -20.03 22.42 27.42 21.23
43 188.65000 -20.03 22.42 27.42 21.23
44 188.70000 -20.03 22.42 27.42 21.22
45 188.75000 -20.03 22.42 27.42 21.22
46 188.80000 -20.03 22.42 27.42 21.22
47 188.85000 -20.03 22.41 27.42 21.22
48 188.90000 -20.03 22.41 27.42 21.22
49 188.95000 -20.03 22.41 27.42 21.22
50 189.00000 -20.03 22.41 27.43 21.22
51 189.05000 -20.03 22.41 27.43 21.22
52 189.10000 -20.03 22.41 27.44 21.22
53 189.15000 -20.03 22.41 27.44 21.22
54 189.20000 -20.03 22.41 27.45 21.22
55 189.25000 -20.03 22.41 27.46 21.23
56 189.30000 -20.03 22.41 27.46 21.23
57 189.35000 -20.03 22.40 27.47 21.23
58 189.40000 -20.03 22.40 27.49 21.23
59 189.45000 -20.03 22.40 27.50 21.23
60 189.50000 -20.03 22.40 27.51 21.24
61 189.55000 -20.03 22.40 27.53 21.24
62 189.60000 -20.03 22.40 27.55 21.24
63 189.65000 -20.03 22.40 27.58 21.25
64 189.70000 -20.03 22.40 27.60 21.25
65 189.75000 -20.03 22.40 27.63 21.26
66 189.80000 -20.03 22.40 27.67 21.27
67 189.85000 -20.03 22.39 27.72 21.28
68 189.90000 -20.03 22.39 27.78 21.29
69 189.95000 -20.03 22.39 27.86 21.31
70 190.00000 -20.03 22.39 27.97 21.33
71 190.05000 -20.03 22.39 28.21 21.38
72 191.25000 -20.03 21.51 28.66 20.74
73 191.30000 -20.03 21.51 28.96 20.79
74 191.35000 -20.03 21.51 29.16 20.82
75 191.40000 -20.03 21.50 29.32 20.84
76 191.45000 -20.03 21.50 29.51 20.87
77 191.50000 -20.03 21.50 29.75 20.90
78 191.55000 -20.03 21.50 30.22 20.95
79 191.60000 -20.03 21.50 30.96 21.03
80 191.65000 -20.03 21.50 30.46 20.98
81 191.70000 -20.03 21.50 30.23 20.95
82 191.75000 -20.03 21.50 30.08 20.93
83 191.80000 -20.03 21.50 29.97 20.92
84 191.85000 -20.03 21.50 29.88 20.91
85 191.90000 -20.03 21.49 29.81 20.90
86 191.95000 -20.03 21.49 29.75 20.89
87 192.00000 -20.03 21.49 29.70 20.88
88 192.05000 -20.03 21.49 29.65 20.87
89 192.10000 -20.03 21.49 29.61 20.87
90 192.15000 -20.03 21.49 29.57 20.86
91 192.20000 -20.03 21.49 29.54 20.86
92 192.25000 -20.03 21.49 29.50 20.85
93 192.30000 -20.03 21.49 29.47 20.85
94 192.35000 -20.03 21.49 29.44 20.84
95 192.40000 -20.03 21.48 29.42 20.84
96 192.45000 -20.03 21.48 29.39 20.83
97 192.50000 -20.03 21.48 29.37 20.83
98 192.55000 -20.03 21.48 29.35 20.82
99 192.60000 -20.03 21.48 29.33 20.82
100 192.65000 -20.03 21.48 29.31 20.82
101 192.70000 -20.03 21.48 29.29 20.81
102 192.75000 -20.03 21.48 29.27 20.81
103 192.80000 -20.03 21.48 29.25 20.81
104 192.85000 -20.03 21.47 29.23 20.80
105 192.90000 -20.03 21.47 29.22 20.80
106 192.95000 -20.03 21.47 29.20 20.80
107 193.00000 -20.03 21.47 29.18 20.79
108 193.05000 -20.03 21.47 29.17 20.79
109 193.10000 -20.03 21.47 29.16 20.79
110 193.15000 -20.03 21.47 29.14 20.78
111 193.20000 -20.03 21.47 29.13 20.78
112 193.25000 -20.03 21.47 29.12 20.78
113 193.30000 -20.03 21.47 29.10 20.78
114 193.35000 -20.03 21.46 29.09 20.77
115 193.40000 -20.03 21.46 29.08 20.77
116 193.45000 -20.03 21.46 29.07 20.77
117 193.50000 -20.03 21.46 29.06 20.77
118 193.55000 -20.03 21.46 29.05 20.76
119 193.60000 -20.03 21.46 29.04 20.76
120 193.65000 -20.03 21.46 29.03 20.76
121 193.70000 -20.03 21.46 29.02 20.76
122 193.75000 -20.03 21.46 29.01 20.75
123 193.80000 -20.03 21.46 29.00 20.75
124 193.85000 -20.03 21.45 28.99 20.75
125 193.90000 -20.03 21.45 28.99 20.75
126 193.95000 -20.03 21.45 28.98 20.75
127 194.00000 -20.03 21.45 28.97 20.74
128 194.05000 -20.03 21.45 28.97 20.74
129 194.10000 -20.03 21.45 28.96 20.74
130 194.15000 -20.03 21.45 28.96 20.74
131 194.20000 -20.03 21.45 28.96 20.74
132 194.25000 -20.03 21.45 28.95 20.74
133 194.30000 -20.03 21.45 28.95 20.74
134 194.35000 -20.03 21.44 28.95 20.73
135 194.40000 -20.03 21.44 28.95 20.73
136 194.45000 -20.03 21.44 28.95 20.73
137 194.50000 -20.03 21.44 28.96 20.73
138 194.55000 -20.03 21.44 28.96 20.73
139 194.60000 -20.03 21.44 28.97 20.73
140 194.65000 -20.03 21.44 28.98 20.73
141 194.70000 -20.03 21.44 28.99 20.74
142 194.75000 -20.03 21.44 29.01 20.74
143 194.80000 -20.03 21.44 29.04 20.74
144 194.85000 -20.03 21.43 29.07 20.74
145 194.90000 -20.03 21.43 29.12 20.75
146 194.95000 -20.03 21.43 29.18 20.76
147 195.00000 -20.03 21.43 29.28 20.77
148 195.05000 -20.03 21.43 29.44 20.79
149 195.10000 -20.03 21.43 29.84 20.84
1 186.55000 -20.03 22.61 28.68 21.65
2 186.60000 -20.03 22.61 28.16 21.54
3 186.65000 -20.03 22.60 27.93 21.49
4 186.70000 -20.03 22.60 27.79 21.45
5 186.75000 -20.03 22.60 27.68 21.43
6 186.80000 -20.03 22.60 27.60 21.41
7 186.85000 -20.03 22.60 27.54 21.39
8 186.90000 -20.03 22.60 27.48 21.38
9 186.95000 -20.03 22.60 27.44 21.37
10 187.00000 -20.03 22.60 27.40 21.35
11 187.05000 -20.03 22.60 27.36 21.35
12 187.10000 -20.03 22.60 27.33 21.34
13 187.15000 -20.03 22.59 27.30 21.33
14 187.20000 -20.03 22.59 27.27 21.32
15 187.25000 -20.03 22.59 27.25 21.31
16 187.30000 -20.03 22.59 27.22 21.31
17 187.35000 -20.03 22.59 27.20 21.30
18 187.40000 -20.03 22.59 27.18 21.30
19 187.45000 -20.03 22.59 27.17 21.29
20 187.50000 -20.03 22.59 27.15 21.28
21 187.55000 -20.03 22.59 27.13 21.28
22 187.60000 -20.03 22.59 27.12 21.28
23 187.65000 -20.03 22.58 27.11 21.27
24 187.70000 -20.03 22.58 27.09 21.27
25 187.75000 -20.03 22.58 27.08 21.26
26 187.80000 -20.03 22.58 27.07 21.26
27 187.85000 -20.03 22.58 27.06 21.26
28 187.90000 -20.03 22.58 27.05 21.25
29 187.95000 -20.03 22.58 27.04 21.25
30 188.00000 -20.03 22.58 27.03 21.25
31 188.05000 -20.03 22.58 27.02 21.24
32 188.10000 -20.03 22.58 27.02 21.24
33 188.15000 -20.03 22.57 27.01 21.24
34 188.20000 -20.03 22.57 27.00 21.24
35 188.25000 -20.03 22.57 27.00 21.23
36 188.30000 -20.03 22.57 26.99 21.23
37 188.35000 -20.03 22.57 26.99 21.23
38 188.40000 -20.03 22.57 26.98 21.23
39 188.45000 -20.03 22.57 26.98 21.23
40 188.50000 -20.03 22.57 26.98 21.22
41 188.55000 -20.03 22.57 26.97 21.22
42 188.60000 -20.03 22.56 26.97 21.22
43 188.65000 -20.03 22.56 26.97 21.22
44 188.70000 -20.03 22.56 26.97 21.22
45 188.75000 -20.03 22.56 26.97 21.22
46 188.80000 -20.03 22.56 26.97 21.22
47 188.85000 -20.03 22.56 26.97 21.22
48 188.90000 -20.03 22.56 26.97 21.22
49 188.95000 -20.03 22.56 26.98 21.22
50 189.00000 -20.03 22.56 26.98 21.22
51 189.05000 -20.03 22.56 26.98 21.22
52 189.10000 -20.03 22.55 26.99 21.22
53 189.15000 -20.03 22.55 26.99 21.22
54 189.20000 -20.03 22.55 27.00 21.22
55 189.25000 -20.03 22.55 27.01 21.22
56 189.30000 -20.03 22.55 27.02 21.22
57 189.35000 -20.03 22.55 27.03 21.23
58 189.40000 -20.03 22.55 27.04 21.23
59 189.45000 -20.03 22.55 27.05 21.23
60 189.50000 -20.03 22.55 27.07 21.23
61 189.55000 -20.03 22.55 27.09 21.24
62 189.60000 -20.03 22.54 27.11 21.24
63 189.65000 -20.03 22.54 27.13 21.25
64 189.70000 -20.03 22.54 27.16 21.26
65 189.75000 -20.03 22.54 27.20 21.26
66 189.80000 -20.03 22.54 27.24 21.27
67 189.85000 -20.03 22.54 27.29 21.28
68 189.90000 -20.03 22.54 27.35 21.30
69 189.95000 -20.03 22.54 27.44 21.32
70 190.00000 -20.03 22.54 27.56 21.35
71 190.05000 -20.03 22.54 27.83 21.41
72 191.25000 -20.03 21.51 28.37 20.69
73 191.30000 -20.03 21.51 28.71 20.75
74 191.35000 -20.03 21.51 28.92 20.78
75 191.40000 -20.03 21.50 29.11 20.81
76 191.45000 -20.03 21.50 29.30 20.84
77 191.50000 -20.03 21.50 29.54 20.87
78 191.55000 -20.03 21.50 30.00 20.93
79 191.60000 -20.03 21.50 30.90 21.03
80 191.65000 -20.03 21.50 30.40 20.97
81 191.70000 -20.03 21.50 30.17 20.95
82 191.75000 -20.03 21.50 30.03 20.93
83 191.80000 -20.03 21.50 29.92 20.91
84 191.85000 -20.03 21.50 29.83 20.90
85 191.90000 -20.03 21.49 29.76 20.89
86 191.95000 -20.03 21.49 29.70 20.88
87 192.00000 -20.03 21.49 29.65 20.87
88 192.05000 -20.03 21.49 29.60 20.87
89 192.10000 -20.03 21.49 29.56 20.86
90 192.15000 -20.03 21.49 29.52 20.85
91 192.20000 -20.03 21.49 29.49 20.85
92 192.25000 -20.03 21.49 29.45 20.84
93 192.30000 -20.03 21.49 29.42 20.84
94 192.35000 -20.03 21.49 29.40 20.83
95 192.40000 -20.03 21.48 29.37 20.83
96 192.45000 -20.03 21.48 29.34 20.82
97 192.50000 -20.03 21.48 29.32 20.82
98 192.55000 -20.03 21.48 29.30 20.82
99 192.60000 -20.03 21.48 29.27 20.81
100 192.65000 -20.03 21.48 29.25 20.81
101 192.70000 -20.03 21.48 29.23 20.80
102 192.75000 -20.03 21.48 29.22 20.80
103 192.80000 -20.03 21.48 29.20 20.80
104 192.85000 -20.03 21.47 29.18 20.79
105 192.90000 -20.03 21.47 29.16 20.79
106 192.95000 -20.03 21.47 29.15 20.79
107 193.00000 -20.03 21.47 29.13 20.78
108 193.05000 -20.03 21.47 29.12 20.78
109 193.10000 -20.03 21.47 29.10 20.78
110 193.15000 -20.03 21.47 29.09 20.78
111 193.20000 -20.03 21.47 29.07 20.77
112 193.25000 -20.03 21.47 29.06 20.77
113 193.30000 -20.03 21.47 29.05 20.77
114 193.35000 -20.03 21.46 29.03 20.76
115 193.40000 -20.03 21.46 29.02 20.76
116 193.45000 -20.03 21.46 29.01 20.76
117 193.50000 -20.03 21.46 29.00 20.76
118 193.55000 -20.03 21.46 28.99 20.75
119 193.60000 -20.03 21.46 28.98 20.75
120 193.65000 -20.03 21.46 28.97 20.75
121 193.70000 -20.03 21.46 28.96 20.75
122 193.75000 -20.03 21.46 28.95 20.74
123 193.80000 -20.03 21.46 28.94 20.74
124 193.85000 -20.03 21.45 28.93 20.74
125 193.90000 -20.03 21.45 28.92 20.74
126 193.95000 -20.03 21.45 28.91 20.74
127 194.00000 -20.03 21.45 28.91 20.73
128 194.05000 -20.03 21.45 28.90 20.73
129 194.10000 -20.03 21.45 28.89 20.73
130 194.15000 -20.03 21.45 28.89 20.73
131 194.20000 -20.03 21.45 28.88 20.73
132 194.25000 -20.03 21.45 28.88 20.73
133 194.30000 -20.03 21.45 28.88 20.72
134 194.35000 -20.03 21.44 28.87 20.72
135 194.40000 -20.03 21.44 28.87 20.72
136 194.45000 -20.03 21.44 28.87 20.72
137 194.50000 -20.03 21.44 28.88 20.72
138 194.55000 -20.03 21.44 28.88 20.72
139 194.60000 -20.03 21.44 28.89 20.72
140 194.65000 -20.03 21.44 28.90 20.72
141 194.70000 -20.03 21.44 28.91 20.72
142 194.75000 -20.03 21.44 28.92 20.72
143 194.80000 -20.03 21.44 28.95 20.73
144 194.85000 -20.03 21.43 28.98 20.73
145 194.90000 -20.03 21.43 29.02 20.74
146 194.95000 -20.03 21.43 29.08 20.74
147 195.00000 -20.03 21.43 29.17 20.76
148 195.05000 -20.03 21.43 29.33 20.78
149 195.10000 -20.03 21.43 29.71 20.83
(Invalid source node 'Site_A' replaced with trx Site_A)

View File

@@ -6,7 +6,7 @@ There are 6 fiber spans over 500 km between trx_Stockholm and trx_Gothenburg
Now propagating between trx_Stockholm and trx_Gothenburg:
Reference used for design: (Input optical power reference in span = 2.00dBm,
spacing = 50.00GHz
nb_channels = 96)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = 0.00dB,
spacing = 50.00GHz,

View File

@@ -6,7 +6,7 @@ There are 6 fiber spans over 500 km between trx_Stockholm and trx_Gothenburg
Now propagating between trx_Stockholm and trx_Gothenburg:
Reference used for design: (Input optical power reference in span = 2.00dBm,
spacing = 50.00GHz
nb_channels = 96)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = 0.00dB,
spacing = 50.00GHz,

View File

@@ -6,7 +6,7 @@ There are 4 fiber spans over 200 km between trx Brest_KLA and trx Rennes_STA
Now propagating between trx Brest_KLA and trx Rennes_STA:
Reference used for design: (Input optical power reference in span = 3.00dBm,
spacing = 50.00GHz
nb_channels = 95)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = 0.00dB,
spacing = 50.00GHz,

View File

@@ -7,7 +7,7 @@ There are 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Reference used for design: (Input optical power reference in span = 0.00dBm,
spacing = 50.00GHz
nb_channels = 96)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = mode_1: 0.00, mode_2: 0.00dB,
spacing = mode_1: 50.00, mode_2: 75.00GHz,

View File

@@ -7,7 +7,7 @@ There are 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Reference used for design: (Input optical power reference in span = 0.00dBm,
spacing = 50.00GHz
nb_channels = 95)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = mode_1: 0.00, mode_2: 0.00dB,
spacing = mode_1: 50.00, mode_2: 75.00GHz,

View File

@@ -7,7 +7,7 @@ There are 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Reference used for design: (Input optical power reference in span = 0.00dBm,
spacing = 50.00GHz
nb_channels = 95)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = mode_1: 0.00, mode_2: 0.00dB,
spacing = mode_1: 50.00, mode_2: 75.00GHz,

View File

@@ -6,7 +6,7 @@ There are 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Reference used for design: (Input optical power reference in span = 0.00dBm,
spacing = 50.00GHz
nb_channels = 96)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = 0.00dB,
spacing = 50.00GHz,

View File

@@ -6,7 +6,7 @@ There are 3 fiber spans over 130 km between trx Lannion_CAS and trx Lorient_KMA
Now propagating between trx Lannion_CAS and trx Lorient_KMA:
Reference used for design: (Input optical power reference in span = 3.00dBm,
spacing = 50.00GHz
nb_channels = 96)
nb_channels = None)
Channels propagating: (Input optical power deviation in span = 0.00dB,
spacing = 50.00GHz,

View File

@@ -13,6 +13,7 @@ from gnpy.core.utils import automatic_fmax, lin2db, db2lin, merge_amplifier_rest
from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information
from gnpy.core.network import build_network, set_amplifier_voa
from gnpy.tools.json_io import load_network, load_equipment, load_json, _equipment_from_json, network_from_json
from gnpy.topology.request import PathRequest
from pathlib import Path
import pytest
@@ -40,13 +41,47 @@ def bw():
return 45e9
def pathrequest(pch_dbm, p_tot_dbm):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": round(dbm2watt(p_tot_dbm) / dbm2watt(pch_dbm), 0),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
@pytest.fixture()
def setup_edfa_variable_gain():
"""init edfa class by reading test_network.json file
remove all gain and nf ripple"""
equipment = load_equipment(eqpt_library, extra_configs)
network = load_network(test_network, equipment)
build_network(network, equipment, 0, 20)
build_network(network, equipment, pathrequest(0, 20))
edfa = [n for n in network.nodes() if isinstance(n, Edfa)][0]
edfa.gain_ripple = zeros(96)
edfa.interpol_nf_ripple = zeros(96)
@@ -58,7 +93,7 @@ def setup_edfa_fixed_gain():
"""init edfa class by reading the 2nd edfa in test_network.json file"""
equipment = load_equipment(eqpt_library, extra_configs)
network = load_network(test_network, equipment)
build_network(network, equipment, 0, 20)
build_network(network, equipment, pathrequest(0, 20))
edfa = [n for n in network.nodes() if isinstance(n, Edfa)][1]
yield edfa
@@ -68,7 +103,7 @@ def setup_trx():
"""init transceiver class to access snr and osnr calculations"""
equipment = load_equipment(eqpt_library, extra_configs)
network = load_network(test_network, equipment)
build_network(network, equipment, 0, 20)
build_network(network, equipment, pathrequest(0, 20))
trx = [n for n in network.nodes() if isinstance(n, Transceiver)][0]
return trx
@@ -178,7 +213,7 @@ def test_ase_noise(gain, si, setup_trx, bw):
# updating span 1 avoids to overload amp
span.params.length = gain * 1e3 / 0.2
edfa.operational.gain_target = gain
build_network(network, equipment, 0, 20)
build_network(network, equipment, pathrequest(0, 20))
edfa.gain_ripple = zeros(96)
edfa.interpol_nf_ripple = zeros(96)
# propagate in span1 to have si with the correct power level

View File

@@ -20,11 +20,12 @@ from numpy.testing import assert_allclose
import pytest
from gnpy.core.network import build_network
from gnpy.core.utils import automatic_nch, lin2db, watt2dbm
from gnpy.core.utils import automatic_nch, lin2db, watt2dbm, dbm2watt
from gnpy.core.elements import Roadm
from gnpy.topology.request import compute_path_dsjctn, propagate, propagate_and_optimize_mode, correct_json_route_list
from gnpy.tools.json_io import load_network, load_equipment, requests_from_json, load_requests, load_json, \
_equipment_from_json
from gnpy.topology.request import PathRequest
data_dir = Path(__file__).parent.parent / 'tests/data'
@@ -36,6 +37,40 @@ extra_configs = {"std_medium_gain_advanced_config.json": data_dir / "std_medium_
"Juniper-BoosterHG.json": data_dir / "Juniper-BoosterHG.json"}
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels if nb_channels else round(dbm2watt(p_tot_dbm) / dbm2watt(pch_dbm), 0),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
@pytest.mark.parametrize("net", [network_file_name])
@pytest.mark.parametrize("eqpt", [eqpt_library_name])
@pytest.mark.parametrize("serv", [service_file_name])
@@ -52,9 +87,9 @@ def test_automaticmodefeature(net, eqpt, serv, expected_mode):
# spacing, f_min and f_max
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
rqs = requests_from_json(data, equipment)
rqs = correct_json_route_list(network, rqs)
@@ -168,7 +203,7 @@ def test_propagate_and_optimize_mode(caplog):
data['path-request'][1]['path-constraints']['te-bandwidth']['spacing'] = 75e9
assert_allclose(watt2dbm(data['path-request'][1]['path-constraints']['te-bandwidth']['output-power']), 1, rtol=1e-9)
# use the request power for design, or there will be inconsistencies with the gain
build_network(network, equipment, 1, 21)
build_network(network, equipment, pathrequest(1, 21))
rqs = requests_from_json(data, equipment)
rqs = correct_json_route_list(network, rqs)

View File

@@ -17,7 +17,7 @@ import pytest
from gnpy.core.equipment import trx_mode_params
from gnpy.core.network import build_network
from gnpy.core.exceptions import ServiceError, DisjunctionError
from gnpy.core.utils import automatic_nch, lin2db
from gnpy.core.utils import automatic_nch, dbm2watt
from gnpy.core.elements import Roadm
from gnpy.topology.request import (compute_path_dsjctn, isdisjoint, find_reversed_path, PathRequest,
correct_json_route_list, requests_aggregation, Disjunction)
@@ -54,10 +54,37 @@ def test_setup():
# power density : db2linp(ower_dbm': 0)/power_dbm': 0 * nb channels as defined by
# spacing, f_min and f_max
p_db = equipment['SI']['default'].power_dbm
params = {
"power": dbm2watt(p_db),
"tx_power": dbm2watt(p_db),
"nb_channel": automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, PathRequest(**params))
build_oms_list(network, equipment)
return network, equipment

View File

@@ -319,13 +319,48 @@ def test_2low_input_power(target_out, delta_pdb_per_channel, correction):
assert_allclose(watt2dbm(si.signal), target - correction, rtol=1e-5)
def pathrequest(pch_dbm, nb_channels):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels,
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
def net_setup(equipment, deltap=0):
"""common setup for tests: builds network, equipment and oms only once"""
network = load_network(NETWORK_FILENAME, equipment)
spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm + deltap
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels))
build_oms_list(network, equipment)
return network
@@ -540,8 +575,9 @@ def test_equalization(case, deltap, target, mode, slot_width, equalization):
network = network_from_json(json_data, equipment)
spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels))
build_oms_list(network, equipment)
# check that nodes not in roadms have target_pch_out_db not None
pw_roadms = [r for r in network.nodes() if r.uid not in roadms and isinstance(r, Roadm)]
for roadm in pw_roadms:
@@ -869,8 +905,8 @@ def test_tx_power(tx_power_dbm):
network = network_from_json(json_data, equipment)
default_spectrum = equipment['SI']['default']
p_db = default_spectrum.power_dbm
p_total_db = p_db + lin2db(automatic_nch(default_spectrum.f_min, default_spectrum.f_max, default_spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(default_spectrum.f_min, default_spectrum.f_max, default_spectrum.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels))
build_oms_list(network, equipment)
expected_roadm_lannion = {
"uid": "roadm Lannion_CAS",

View File

@@ -17,7 +17,7 @@ from pathlib import Path
from numpy.testing import assert_array_equal, assert_allclose
import pytest
from gnpy.core.utils import lin2db, automatic_nch, dbm2watt
from gnpy.core.utils import automatic_nch, dbm2watt
from gnpy.core.network import build_network
from gnpy.tools.json_io import load_equipment, load_network
from gnpy.core.equipment import trx_mode_params
@@ -32,14 +32,48 @@ EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
def pathrequest(pch_dbm, nb_channels):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels,
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
def net_setup(equipment):
"""Common setup for tests: builds network, equipment
"""
network = load_network(NETWORK_FILENAME, equipment)
spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels))
return network

View File

@@ -19,10 +19,11 @@ from gnpy.core.exceptions import NetworkTopologyError, ConfigurationError
from gnpy.core.network import span_loss, build_network, select_edfa, get_node_restrictions, \
estimate_srs_power_deviation, add_missing_elements_in_network, get_next_node
from gnpy.tools.json_io import load_equipment, load_network, network_from_json, load_json
from gnpy.core.utils import lin2db, watt2dbm, automatic_nch, merge_amplifier_restrictions
from gnpy.core.utils import watt2dbm, automatic_nch, merge_amplifier_restrictions, dbm2watt
from gnpy.core.info import create_input_spectral_information
from gnpy.core.elements import Fiber, Edfa, Roadm, Multiband_amplifier, Transceiver
from gnpy.core.parameters import SimParams, EdfaParams, MultiBandParams
from gnpy.topology.request import PathRequest
TEST_DIR = Path(__file__).parent
@@ -158,6 +159,39 @@ def in_voa_json_data(gain, delta_p, in_voa, out_voa):
}]
}
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels if nb_channels else round(dbm2watt(p_tot_dbm) / dbm2watt(pch_dbm), 0),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
@pytest.mark.parametrize('out_voa', [None, 0, 1, 2])
@pytest.mark.parametrize('in_voa', [None, 0, 1, 2])
@@ -170,8 +204,7 @@ def test_invoa(in_voa, out_voa):
network = network_from_json(json_data, equipment)
# Build the network
p_db = 0
p_total_db = p_db + lin2db(96)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=96))
[edfa1, edfa2] = [n for n in network.nodes() if isinstance(n, Edfa)]
[span0, span1, span2] = [n for n in network.nodes() if isinstance(n, Fiber)]
[tx, rx] = [n for n in network.nodes() if isinstance(n, Transceiver)]
@@ -213,8 +246,7 @@ def test_invoa_gainmode(in_voa, out_voa):
network = network_from_json(json_data, equipment)
# Build the network
p_db = 0
p_total_db = p_db + lin2db(96)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=96))
[edfa1, edfa2] = [n for n in network.nodes() if isinstance(n, Edfa)]
[span0, span1, span2] = [n for n in network.nodes() if isinstance(n, Fiber)]
[tx, rx] = [n for n in network.nodes() if isinstance(n, Transceiver)]
@@ -253,8 +285,7 @@ def test_too_small_gain():
network = network_from_json(json_data, equipment)
# Build the network
p_db = 0
p_total_db = p_db + lin2db(96)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=96))
[edfa1, edfa2] = [n for n in network.nodes() if isinstance(n, Edfa)]
[span0, span1, span2] = [n for n in network.nodes() if isinstance(n, Fiber)]
[tx, rx] = [n for n in network.nodes() if isinstance(n, Transceiver)]
@@ -283,8 +314,7 @@ def test_invoa_nf():
equipment['Span']['default'].power_mode = False
network = network_from_json(json_data, equipment)
p_db = 0
p_total_db = p_db + lin2db(50)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=50))
[edfa1, edfa2] = [n for n in network.nodes() if isinstance(n, Edfa)]
[span0, span1, span2] = [n for n in network.nodes() if isinstance(n, Fiber)]
[tx, rx] = [n for n in network.nodes() if isinstance(n, Transceiver)]
@@ -305,8 +335,7 @@ def test_invoa_nf():
network = network_from_json(json_data, equipment)
# Build the network
p_db = 0
p_total_db = p_db + lin2db(50)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=50))
[edfa1, edfa2] = [n for n in network.nodes() if isinstance(n, Edfa)]
[span0, span1, span2] = [n for n in network.nodes() if isinstance(n, Fiber)]
[tx, rx] = [n for n in network.nodes() if isinstance(n, Transceiver)]
@@ -422,10 +451,10 @@ def test_eol(typ, expected_loss):
equipment['Span']['default'].EOL = 1
network = network_from_json(json_data, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
fibers = [f for f in network.nodes() if isinstance(f, Fiber)]
for i in range(2):
assert fibers[i].loss == expected_loss[i]
@@ -493,7 +522,7 @@ def test_design_non_amplified_link(elem1, elem2, expected_gain, expected_delta_p
edfa.params.out_voa_auto = True
p_total_db = p_db + 20.0
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, p_total_db))
amps = [a for a in network.nodes() if isinstance(a, Edfa)]
for amp in amps:
assert amp.out_voa == expected_voa
@@ -698,9 +727,9 @@ def test_design_band(case, site_type, amplifier_type, expected_design_bands, exp
equipment = load_equipment(EQPT_MULTBAND_FILENAME, EXTRA_CONFIGS)
network = network_from_json(json_data, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
roadm1 = next(n for n in network.nodes() if n.uid == 'roadm SITE1')
assert roadm1.design_bands == expected_design_bands
assert roadm1.per_degree_design_bands['east edfa in SITE1 to ILA1'] == expected_per_degree_design_bands
@@ -827,12 +856,12 @@ def test_multiband(case, site_type, band, expected_gain, expected_tilt, expected
equipment = load_equipment(EQPT_MULTBAND_FILENAME, EXTRA_CONFIGS)
network = network_from_json(json_data, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
if sim_params:
SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
amp2 = next(n for n in network.nodes() if n.uid == 'east edfa in ILA2')
# restore simParams
save_sim_params = {"raman_params": SimParams._shared_dict['raman_params'].to_json(),
@@ -991,14 +1020,14 @@ def test_insert_amp(site_type, expected_type, bands, expected_bands):
equipment = load_equipment(EQPT_MULTBAND_FILENAME, EXTRA_CONFIGS)
network = network_from_json(json_data, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
add_missing_elements_in_network(network, equipment)
if not expected_bands:
with pytest.raises(ConfigurationError):
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
else:
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
roadm1 = next(n for n in network.nodes() if n.uid == 'roadm SITE1')
amp1 = get_next_node(roadm1, network)
assert isinstance(amp1, expected_type)

View File

@@ -26,7 +26,7 @@ from pandas import read_csv
from xlrd import open_workbook
import pytest
from copy import deepcopy
from gnpy.core.utils import automatic_nch, lin2db
from gnpy.core.utils import automatic_nch, dbm2watt
from gnpy.core.network import build_network, add_missing_elements_in_network
from gnpy.core.exceptions import ServiceError, ConfigurationError
from gnpy.topology.request import (jsontocsv, requests_aggregation, compute_path_dsjctn, deduplicate_disjunctions,
@@ -45,6 +45,40 @@ EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels if nb_channels else round(dbm2watt(p_tot_dbm) / dbm2watt(pch_dbm), 0),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
@pytest.mark.parametrize('xls_input,expected_json_output', {
DATA_DIR / 'CORONET_Global_Topology.xlsx': DATA_DIR / 'CORONET_Global_Topology_expected.json',
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_expected.json',
@@ -83,9 +117,9 @@ def test_auto_design_generation_fromxlsgainmode(tmpdir, xls_input, expected_json
# Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
actual_json_output = tmpdir / xls_input.with_name(xls_input.stem + '_auto_design').with_suffix('.json').name
save_network(network, actual_json_output)
actual = load_json(actual_json_output)
@@ -113,10 +147,10 @@ def test_auto_design_generation_fromjson(tmpdir, json_input, power_mode):
# Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
add_missing_elements_in_network(network, equipment)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
actual_json_output = tmpdir / json_input.with_name(json_input.stem + '_auto_design').with_suffix('.json').name
save_network(network, actual_json_output)
actual = load_json(actual_json_output)
@@ -136,9 +170,9 @@ def test_excel_service_json_generation(xls_input, expected_json_output):
network = load_network(DATA_DIR / 'testTopology.xls', equipment)
# Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
from_xls = read_service_sheet(xls_input, equipment, network, network_filename=DATA_DIR / 'testTopology.xls')
assert from_xls == load_json(expected_json_output)
@@ -222,9 +256,9 @@ def test_json_response_generation(xls_input, expected_response_file):
network = load_network(xls_input, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
data = read_service_sheet(xls_input, equipment, network)
# change one of the request with bidir option to cover bidir case as well
@@ -325,8 +359,8 @@ def test_excel_ila_constraints(source, destination, route_list, hoptype, expecte
next(node for node in network.nodes() if node.uid == 'fiber (Quimper → Brest_KLA)-').length = 200000
default_si = equipment['SI']['default']
p_db = default_si.power_dbm
p_total_db = p_db + lin2db(automatic_nch(default_si.f_min, default_si.f_max, default_si.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(default_si.f_min, default_si.f_max, default_si.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
# create params for a xls request based on input (note that this not the same type as PathRequest)
params = {
'request_id': '0',
@@ -377,8 +411,8 @@ def test_excel_ila_constraints2(route_list, hoptype, expected_amp_route):
add_missing_elements_in_network(network, equipment)
default_si = equipment['SI']['default']
p_db = default_si.power_dbm
p_total_db = p_db + lin2db(automatic_nch(default_si.f_min, default_si.f_max, default_si.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(default_si.f_min, default_si.f_max, default_si.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
# create params for a request based on input
params = {
@@ -437,10 +471,10 @@ def test_target_pch_out_db_global(case):
# power density: db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
# spacing, f_min and f_max
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max,
equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max,
equipment['SI']['default'].spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
data = network_to_json(network)
for elem in data['elements']:

View File

@@ -16,8 +16,8 @@ test path computation functions
from pathlib import Path
import pytest
from gnpy.core.network import build_network
from gnpy.core.utils import lin2db, automatic_nch
from gnpy.topology.request import explicit_path
from gnpy.core.utils import automatic_nch, dbm2watt
from gnpy.topology.request import explicit_path, PathRequest
from gnpy.topology.spectrum_assignment import build_oms_list
from gnpy.tools.json_io import load_equipment, load_network, requests_from_json
@@ -32,6 +32,40 @@ EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
def pathrequest(pch_dbm, nb_channels):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels,
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
@pytest.fixture()
def setup_without_oms():
""" common setup for tests: builds network, equipment and oms only once
@@ -39,8 +73,8 @@ def setup_without_oms():
network = load_network(NETWORK_FILENAME, equipment)
spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels))
return network

View File

@@ -19,11 +19,11 @@ import re
from gnpy.core.exceptions import SpectrumError
from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm
from gnpy.core.utils import db2lin
from gnpy.core.utils import db2lin, dbm2watt
from gnpy.core.info import create_input_spectral_information
from gnpy.core.network import build_network
from gnpy.tools.json_io import load_network, load_equipment, network_from_json
from gnpy.topology.request import PathRequest
TEST_DIR = Path(__file__).parent
DATA_DIR = TEST_DIR / 'data'
@@ -41,6 +41,40 @@ def nch_and_spacing(request):
yield request.param
def pathrequest(pch_dbm, p_tot_dbm):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": round(dbm2watt(p_tot_dbm) / dbm2watt(pch_dbm), 0),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
def propagation(input_power, con_in, con_out, dest):
equipment = load_equipment(eqpt_library_name, EXTRA_CONFIGS)
network = load_network(network_file_name, equipment)
@@ -55,7 +89,7 @@ def propagation(input_power, con_in, con_out, dest):
if isinstance(e, Edfa):
e.operational.gain_target = loss + con_in + con_out
build_network(network, equipment, 0, 20)
build_network(network, equipment, pathrequest(0, 20))
transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)}

View File

@@ -37,6 +37,42 @@ EQPT_FILENAME = DATA_DIR / 'eqpt_config.json'
NETWORK_FILE_NAME = DATA_DIR / 'testTopology_expected.json'
EXTRA_CONFIGS = {"std_medium_gain_advanced_config.json": DATA_DIR / "std_medium_gain_advanced_config.json",
"Juniper-BoosterHG.json": DATA_DIR / "Juniper-BoosterHG.json"}
def pathrequest(pch_dbm: float, p_tot_dbm: float = None, nb_channels: int = None):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels if nb_channels else round(dbm2watt(p_tot_dbm) / dbm2watt(pch_dbm), 0),
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
# adding tests to check the roadm restrictions
# mark node_uid amps as fused for testing purpose
@@ -67,10 +103,10 @@ def test_no_amp_feature(node_uid):
# power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
# spacing, f_min and f_max
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
node = next(nd for nd in network.nodes() if nd.uid == node_uid)
next_node = next(network.successors(node))
@@ -179,10 +215,10 @@ def test_restrictions(restrictions, equipment):
# power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
# spacing, f_min and f_max
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
nb_channels = automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)
build_network(network, equipment, p_db, p_total_db)
build_network(network, equipment, pathrequest(p_db, nb_channels=nb_channels))
amp_nodes = [nd for nd in network.nodes()
if isinstance(nd, Edfa) and isinstance(next(network.predecessors(nd)), Roadm)
@@ -246,9 +282,8 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm, roa
network = network_from_json(json_network, equipment)
nb_channel = automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max,
equipment['SI']['default'].spacing)
p_total_db = power_dbm + lin2db(nb_channel)
build_network(network, equipment, power_dbm, p_total_db)
build_network(network, equipment, pathrequest(power_dbm, nb_channels=nb_channel))
params = {'request_id': 0,
'trx_type': '',
@@ -470,10 +505,10 @@ def test_compare_design_propagation_settings(power_dbm, req_power, amp_with_delt
network = network_from_json(json_network, eqpt)
# Build the network once using the default power defined in SI in eqpt config
p_db = power_dbm
p_total_db = p_db + lin2db(automatic_nch(eqpt['SI']['default'].f_min,
eqpt['SI']['default'].f_max,
eqpt['SI']['default'].spacing))
build_network(network, eqpt, p_db, p_total_db, verbose=False)
nb_channels = automatic_nch(eqpt['SI']['default'].f_min,
eqpt['SI']['default'].f_max,
eqpt['SI']['default'].spacing)
build_network(network, eqpt, pathrequest(p_db, nb_channels=nb_channels), verbose=False)
# record network settings before propagating
# propagate on each oms
req_list = create_per_oms_request(network, eqpt, req_power)
@@ -583,7 +618,7 @@ def test_roadm_impairments(roadm, from_degree, to_degree, expected_impairment_id
el['type_variety'] = 'example_detailed_impairments'
equipment = load_equipment(EQPT_FILENAME, EXTRA_CONFIGS)
network = network_from_json(json_data, equipment)
build_network(network, equipment, 0.0, 20.0)
build_network(network, equipment, pathrequest(0.0, 20.0))
roadm = next(n for n in network.nodes() if n.uid == roadm)
assert roadm.get_roadm_path(from_degree, to_degree).path_type == expected_type
assert roadm.get_roadm_path(from_degree, to_degree).impairment_id == expected_impairment_id
@@ -637,7 +672,7 @@ def test_roadm_per_degree_impairments(type_variety, from_degree, to_degree, impa
}]
}
network = network_from_json(json_data, equipment)
build_network(network, equipment, 0.0, 20.0)
build_network(network, equipment, pathrequest(0.0, 20.0))
roadm = next(n for n in network.nodes() if n.uid == 'roadm Lannion_CAS')
assert roadm.get_roadm_path(from_degree, to_degree).path_type == expected_type
assert roadm.get_roadm_path(from_degree, to_degree).impairment_id == impairment_id
@@ -669,7 +704,7 @@ def test_wrong_roadm_per_degree_impairments(from_degree, to_degree, impairment_i
}
network = network_from_json(json_data, equipment)
with pytest.raises(error, match=message):
build_network(network, equipment, 0.0, 20.0)
build_network(network, equipment, pathrequest(0.0, 20.0))
@pytest.mark.parametrize('path_type, type_variety, expected_pmd, expected_pdl, expected_osnr, freq', [

View File

@@ -16,7 +16,7 @@ import json
from math import ceil
import pytest
from gnpy.core.network import build_network
from gnpy.core.utils import lin2db, automatic_nch
from gnpy.core.utils import automatic_nch, dbm2watt
from gnpy.core.elements import Roadm, Transceiver
from gnpy.core.exceptions import ServiceError, SpectrumError
from gnpy.topology.request import compute_path_dsjctn, find_reversed_path, deduplicate_disjunctions, PathRequest
@@ -47,14 +47,48 @@ def equipment():
return equipment
def pathrequest(pch_dbm, nb_channels):
"""create ref channel for defined power settings
"""
params = {
"power": dbm2watt(pch_dbm),
"tx_power": dbm2watt(pch_dbm),
"nb_channel": nb_channels,
'request_id': None,
'trx_type': None,
'trx_mode': None,
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'baud_rate': None,
'bit_rate': None,
'roll_off': None,
'OSNR': None,
'penalties': None,
'path_bandwidth': None,
'effective_freq_slot': None,
'f_min': None,
'f_max': None,
'spacing': None,
'min_spacing': None,
'cost': None,
'equalization_offset_db': None,
'tx_osnr': None
}
return PathRequest(**params)
@pytest.fixture()
def setup(equipment):
"""common setup for tests: builds network, equipment and oms only once"""
network = load_network(NETWORK_FILENAME, equipment)
spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
nb_channels = automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing)
build_network(network, equipment, pathrequest(p_db, nb_channels))
oms_list = build_oms_list(network, equipment)
return network, oms_list